List of AQs

  1. Under what circumstances do we enable checking of certificate revocation list in the call to sslStream.AuthenticateAsClient()?
  2. When trying to open an SSL (HTTPS) connection using WCF, received the following exception: “could not establish trust relationship for the ssl/tls secure channel”. What causes this? [ Certificate signing authority is not a trusted root authority in the client’s certificate store]

BCD Converter


using System;
using System.Collections.Generic;
// Note: Uses the Unpack() method found in
// https://github.com/thevinnie/UnpackDecimal/blob/master/SSISTask/UnpackDecimal/UnpackDecimal.cs
namespace Utils.Conversions
{
/// <summary>
/// Handles Binary Coded Decimal conversions
/// </summary>
/// <remarks>
/// Eg. for handling amount in dollars & cents:
/// var converter = new BcdConverter(2);
/// var bcd = converter.PackAmount(10.23M);
/// var amount = converter.UnpackAmount(bcd);
/// </remarks>
public class BcdConverter
{
int _precision;
public BcdConverter(int precision)
{
_precision = precision;
}
public string PackAmount(decimal amount)
{
return PackAmount(amount, _precision);
}
public string PackAmount(decimal amount, int precision)
{
Stack<byte> bcd = new Stack<byte>(10);
long value = StripDecimalPoint(amount);
byte currentByte;
if (value < 0)
{
currentByte = 0x0d;
value = -value;
}
else
{
currentByte = 0x0c;
}
bool byteComplete = false;
while (value != 0)
{
if (byteComplete)
currentByte = (byte)(value % 10);
else
currentByte |= (byte)((value % 10) << 4);
value /= 10;
byteComplete = !byteComplete;
if (byteComplete)
bcd.Push(currentByte);
}
if (!byteComplete)
bcd.Push(currentByte);
int nibbles = precision + 2 + 1; //precision + 2 decimals + 1 sign
var bcdLength = nibbles % 2 == 0 ? nibbles / 2 : (nibbles + 1) / 2; // even number of bytes
// ensure that the resulting bcd string be of fixed length, independent of the value
// i.e., 10.00 or 10000.00 should be converted into BCD strings of same length
// (length is determined by precision)
if (bcd.Count < bcdLength)
{
var padding = bcdLength – bcd.Count;
for (var i = 0; i < padding; i++)
{
bcd.Push((byte)0);
}
}
if (bcd.Count > bcdLength)
throw new ArgumentOutOfRangeException("amount", amount + " – precision is greater than allowed, namely, " + precision);
return new string(bcd.ToArray().Select(x => (char)x).ToArray());
}
public Decimal UnpackAmount(string bcd)
{
byte[] inp = bcd.Select(c => (byte)c).ToArray();
long lo = 0;
long mid = 0;
long hi = 0;
bool isNegative;
// this nybble stores only the sign, not a digit.
// "C" hex is positive, "D" hex is negative, and "F" hex is unsigned.
switch (nibble(inp, 0))
{
case 0x0D:
isNegative = true;
break;
case 0x0F:
case 0x0C:
isNegative = false;
break;
default:
throw new Exception("Bad sign nibble");
}
long intermediate;
long carry;
long digit;
for (int j = inp.Length * 2 – 1; j > 0; j–)
{
// multiply by 10
intermediate = lo * 10;
lo = intermediate & 0xffffffff;
carry = intermediate >> 32;
intermediate = mid * 10 + carry;
mid = intermediate & 0xffffffff;
carry = intermediate >> 32;
intermediate = hi * 10 + carry;
hi = intermediate & 0xffffffff;
carry = intermediate >> 32;
// By limiting input length to 14, we ensure overflow will never occur
digit = nibble(inp, j);
if (digit > 9)
{
throw new Exception("Bad digit");
}
intermediate = lo + digit;
lo = intermediate & 0xffffffff;
carry = intermediate >> 32;
if (carry > 0)
{
intermediate = mid + carry;
mid = intermediate & 0xffffffff;
carry = intermediate >> 32;
if (carry > 0)
{
intermediate = hi + carry;
hi = intermediate & 0xffffffff;
carry = intermediate >> 32;
// carry should never be non-zero. Back up with validation
}
}
}
return new Decimal((int)lo, (int)mid, (int)hi, isNegative, 2);
}
private long StripDecimalPoint(decimal amount)
{
return Convert.ToInt64(amount * 100);
}
private int nibble(byte[] inp, int nibbleNo)
{
int b = inp[inp.Length – 1 – nibbleNo / 2];
return (nibbleNo % 2 == 0) ? (b & 0x0000000F) : (b >> 4);
}
}
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

Memento pattern – An example


public class CAMemberServiceCredit
{
public string MemberSeparator { get; private set; }
// ReoccurCharge 1 in the format stored in database
public string ReoccurChrg1 { get; private set; }
// ReoccurCharge 2 in the format stored in database
public string ReoccurChrg2 { get; private set; }
// ReoccurCharge 3 in the format stored in database
public string ReoccurChrg3 { get; private set; }
private static readonly BcdConverter _bcdConverter = new BcdConverter(precision: 5);
#region parsed fields
public string Code1
{
get
{
if (string.IsNullOrWhiteSpace(ReoccurChrg1) || ReoccurChrg1.Length != 6)
throw new InvalidOperationException("ReoccuChrg1 is not in correct format: '" + ReoccurChrg1 + "'");
return ReoccurChrg1.Substring(0, 2);
}
set
{
if (string.IsNullOrWhiteSpace(ReoccurChrg1) || ReoccurChrg1.Length != 6)
throw new InvalidOperationException("ReoccurChrg1 is not in correct format: '" + ReoccurChrg1 + "'");
if (string.IsNullOrWhiteSpace(value) || value.Length != 2)
throw new InvalidOperationException("Invalid value: '" + value + "'");
ReoccurChrg1 = value + ReoccurChrg1.Substring(2, 4);
}
}
public string Code2
{
get
{
if (string.IsNullOrWhiteSpace(ReoccurChrg2) || ReoccurChrg2.Length != 6)
throw new InvalidOperationException("ReoccuChrg1 is not in correct format: '" + ReoccurChrg2 + "'");
return ReoccurChrg2.Substring(0, 2);
}
set
{
if (string.IsNullOrWhiteSpace(ReoccurChrg2) || ReoccurChrg2.Length != 6)
throw new InvalidOperationException("ReoccurChrg2 is not in correct format: '" + ReoccurChrg2 + "'");
if (string.IsNullOrWhiteSpace(value) || value.Length != 2)
throw new InvalidOperationException("Invalid value: '" + value + "'");
ReoccurChrg2 = value + ReoccurChrg2.Substring(2, 4);
}
}
public string Code3
{
get
{
if (string.IsNullOrWhiteSpace(ReoccurChrg3) || ReoccurChrg3.Length != 6)
throw new InvalidOperationException("ReoccuChrg1 is not in correct format: '" + ReoccurChrg3 + "'");
return ReoccurChrg3.Substring(0, 2);
}
set
{
if (string.IsNullOrWhiteSpace(ReoccurChrg3) || ReoccurChrg3.Length != 6)
throw new InvalidOperationException("ReoccurChrg3 is not in correct format: '" + ReoccurChrg3 + "'");
if (string.IsNullOrWhiteSpace(value) || value.Length != 2)
throw new InvalidOperationException("Invalid value: '" + value + "'");
ReoccurChrg3 = value + ReoccurChrg3.Substring(2, 4);
}
}
public decimal ReoccurAmt1
{
get
{
if (string.IsNullOrWhiteSpace(ReoccurChrg1) || ReoccurChrg1.Length != 6)
throw new InvalidOperationException("ReoccuChrg1 is not in correct format: '" + ReoccurChrg1 + "'");
return _bcdConverter.UnpackAmount(ReoccurChrg1.Substring(2, 4));
}
set
{
if (string.IsNullOrWhiteSpace(ReoccurChrg1) || ReoccurChrg1.Length != 6)
throw new InvalidOperationException("ReoccurChrg1 is not in correct format: '" + ReoccurChrg1 + "'");
ReoccurChrg1 = Code1 + _bcdConverter.PackAmount(value);
if (ReoccurChrg1.Length != 6)
throw new InvalidOperationException("ReoccurChrg1 length has to be 6. It is: " + ReoccurChrg1.Length);
}
}
public decimal ReoccurAmt2
{
get
{
if (string.IsNullOrWhiteSpace(ReoccurChrg1) || ReoccurChrg1.Length != 6)
throw new InvalidOperationException("ReoccurChrg1 is not in correct format: '" + ReoccurChrg1 + "'");
return _bcdConverter.UnpackAmount(ReoccurChrg2.Substring(2, 4));
}
set
{
if (string.IsNullOrWhiteSpace(ReoccurChrg1) || ReoccurChrg1.Length != 6)
throw new InvalidOperationException("ReoccurChrg1 is not in correct format: '" + ReoccurChrg1 + "'");
ReoccurChrg2 = Code2 + _bcdConverter.PackAmount(value);
}
}
public decimal ReoccurAmt3
{
get
{
if (string.IsNullOrWhiteSpace(ReoccurChrg3) || ReoccurChrg3.Length != 6)
throw new InvalidOperationException("ReoccurChrg3 is not in correct format: '" + ReoccurChrg3 + "'");
return _bcdConverter.UnpackAmount(ReoccurChrg3.Substring(2, 4));
}
set
{
if (string.IsNullOrWhiteSpace(ReoccurChrg3) || ReoccurChrg3.Length != 6)
throw new InvalidOperationException("ReoccurChrg3 is not in correct format: '" + ReoccurChrg3 + "'");
ReoccurChrg3 = Code3 + _bcdConverter.PackAmount(value);
}
}
#endregion
public CAAuditEntry RecordPaymentForPastDues(decimal amount, string chargeCode)
{
Debug.Assert(string.IsNullOrWhiteSpace(chargeCode) == false);
CAMemberServicePaymentMemento memento = new CAMemberServicePaymentMemento(this);
if (amount == 0)
return null;
if (amount < 0)
throw new ArgumentOutOfRangeException("Negative credits cannot be posted to MemberDetl: " + amount);
// Note: Amount should be deducted
if (chargeCode == Code1)
{
ReoccurAmt1 -= amount;
}
else if (chargeCode == Code2)
{
ReoccurAmt2 -= amount;
}
else if (chargeCode == Code3)
{
ReoccurAmt3 -= amount;
}
else if (Code1 == "00" && ReoccurAmt1 == 0)
{
ReoccurAmt1 = amount;
Code1 = chargeCode;
}
else if (Code2 == "00" && ReoccurAmt2 == 0)
{
ReoccurAmt2 = amount;
Code2 = chargeCode;
}
else if (Code3 == "00" && ReoccurAmt3 == 0)
{
ReoccurAmt3 = amount;
Code3 = chargeCode;
}
else
{
throw new InvalidOperationException(string.Format(
"Cannot credit ${0} to MemberSeparator {1} " +
" because all three ReoccurChrg fields are populated with other charges. Namely, {0}, {1}, {2}",
Code1,
Code2,
Code3));
}
return memento.GetAuditEntryForChanges(this);
}
private class CAMemberServicePaymentMemento
{
private CAMemberServiceCredit _original;
public CAMemberServicePaymentMemento(CAMemberServiceCredit original)
{
_original = original.MemberwiseClone() as CAMemberServiceCredit;
}
public CAAuditEntry GetAuditEntryForChanges(CAMemberServiceCredit modified)
{
if (_original.MemberSeparator != modified.MemberSeparator)
throw new InvalidOperationException(
string.Format("Cannot audit entries related to different member seps. Original:{0} modified:{1}",
_original.MemberSeparator,
modified.MemberSeparator));
var entry = CAAuditEntry.CreateNewAuditEntryForPastDuesRecovery(_original.MemberSeparator);
if (_original.ReoccurChrg1 != modified.ReoccurChrg1)
{
entry.CAField = ReOccurCharge.REOCCURCHG_001.Description();
entry.OldValue = _original.ReoccurChrg1;
entry.NewValue = modified.ReoccurChrg1;
}
else if (_original.ReoccurChrg2 != modified.ReoccurChrg2)
{
entry.CAField = ReOccurCharge.REOCCURCHG_002.Description();
entry.OldValue = _original.ReoccurChrg2;
entry.NewValue = modified.ReoccurChrg2;
}
else if (_original.ReoccurChrg3 != modified.ReoccurChrg3)
{
entry.CAField = ReOccurCharge.REOCCURCHG_003.Description();
entry.OldValue = _original.ReoccurChrg3;
entry.NewValue = modified.ReoccurChrg3;
}
return entry.CAField == null ? null : entry;
}
}
public override string ToString()
{
return string.Format("MemberSeparator: {0} ReoccurChrg1: {1} ReoccurChrg2:{2} ReoccurChrg3:{3} ", MemberSeparator, ReoccurChrg1, ReoccurChrg2, ReoccurChrg3);
}
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

Code review – be specific

self.UpdateMemberDetails = function( memberDetails) {

};

Code reviewer: “are you not following best practices?”

  • There is a sneer behind this comment.
  • Aims to put the reviewee into a defensive mode.
  • It does not describe what is wrong with this line of code; nor does it suggest a best practice to follow.
  • Reviewer obviously has a practice in mind.  But instead of talking about that practice, she moves on to the programmer’s habits, attitudes towards code.

What have I learnt about code reviews from this anti-pattern?

  • Avoid anything that insults or puts the reviewee into a defensive mode.
  • Describe what is wrong and suggest a specific solution, or two.
  • Do not make any assumptions or conjectures about the programmer’s attitude or skills.
  • Ask yourself: What value is my comment adding here?

Good examples,

 if (service.MemberLocation > 3 && service.IsActive && service.Amount > 0 && service.MemberServiceHistoryDetail.DueDate < dueDate)

Code Reviewer: Please format lengthy if-conditions by placing each term of the condition on a separate line.  The code that spills beyond the edge of the screen here is critical to the understanding of the business logic.  For example,

 if (service.MemberLocation > 3 &&
service.IsActive &&
service.Amount > 0 &&
service.MemberServiceHistoryDetail.DueDate < dueDate)

A bootcamp for architects

Curriculum

  • Computer science
    • Algorithms
    • Data structures
    • OS concepts and principles
    • Distributed processing
    • Network protocols
  • Design
    • Principles
    • Patterns
    • Framework design
    • ER modeling
  • Architecture
    • Structuring
    • Styles and patterns
      • SPA
      • Message oriented architecture
    • Performance engineering
    • Scalability engineering
    • Security engineering
    • Documenting architectures
    • Product line architecture
    • Model driven architecture
    • Component based architecture
    • ATAM – Arch. tradeoff analysis method
  • Infrastructure
    • Computer hardware
    • Clustering
    • Network
      • Load balancing
      • DNS
  • Software engineering
    • Estimation
    • SDLC – phase transition
    • Methods
    • Reuse
    • Building reference architectures
    • Conducting and reporting POCs
    • Code generation
  • Communications
    • Graphical notations
    • Documenting architecture
    • Identifying stakeholders
  • Management
    • Scheduling
    • Project planning
    • Monitoring
    • Designing org structures
    • Risk management
  • Technology
    • Mainstream programming languages
    • Scripting languages
    • Template engines
    • Databases – RDBMS & NoSQL
  • Platforms
    • Unix
    • Linux
    • Mobile
    • Web
    • .NET
    • Windows
  • New developments
    • Data science

Course design

  • Principles
  • Case studies
  • Examples

 

  • Assignments
  • Problems
  • Exercises
  • Assessment
    • Quizzes
    • Exams

 

 

Configuration – Outline

Introduction

  • The problem that it solves – or its importance or value of configuration
  • Important but is neglected
  • Configuration hell

Features

  • Simple scenarios: key=value pairs (untyped)
  • Store and retrieve typed values
    • Primitives (int, date, etc)
    • Complex types (POJOs or POCOs)
    • Arrays
    • Maps
  • Inheritance and hierarchy
  • Expressiveness (DSLs)
  • Management
    • Dynamically specify configuration to use at runtime
    • Include other config
    • Centralization of configuration
    • Organization
    • Documentation – single and multi-line comments
    • Versioning
    • Abstract configuration sources or media
    • Persistence of modified configuration
    • Detection of changes and dynamic reloading

Examples of configuration

  • Unix/Linux .rc files (or scripts?)
  • Apache
  • Sendmail
  • ini
  • XML
  • Windows Registry
  • Apache or squid config

Storage

  • Settings or property files
  • XML files
  • database
  • App.config and Web.config
  • JNDI

Trends

  • Convention over configuration
  • Fluent vs XML configuration
  • Service Locators and registries
  • Configuration worksheet

Holy wars

  • File vs database
  • Configuring end user applications vs systems applications
  • Configuration files vs DSLs

Misc topics

  • Deployment and configuration
  • Re-loading config files
  • Abstracting configuration sources
  • IOC containers and configuration
  • Configuring the shell environment

Configuration Frameworks

  • Nini
  • .NET – System.Configuration
  • java
    • java.utils.properties
    • Commons.Configuration
  • IOC containers
    • Spring – org.springframework.beans and org.springframework.context
    • Unity
  • XML serialization
    • Java: org.simpleframework.xml

 

Configuration – bibliography

 

[Off topic]

http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java?rq=1

http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons?rq=1

 

hand-roll a configuration

From the Jargon File – hand-roll:

To perform a normally automated software installation or configuration process by hand; implies that the normal process failed due to bugs in the configurator or was defeated by something exceptional in the local environment. “The worst thing about being a gateway between four different nets is having to hand-roll a new sendmail configuration every time any of them upgrades.”