Tuesday, November 18, 2008

WCF MSMQ Integration Binding Configurations


WCF service is just as normal:



public interface IGMOWCFTrace
{
[OperationContract(IsOneWay = true, Action = "*")]
void WriteLine(MsmqMessage gmoLogMsmq);
}



host = new ServiceHost(typeof(GMO.XIPCommon.Logging.GMOWCFTraceService));



and Service config need to specify msmq and exactlyOnce=false for non-transactinal queue.



<system.serviceModel>
<services>
<service
name="GMO.XIPCommon.Logging.GMOWCFTraceService" >
<endpoint address="msmq.formatname:DIRECT=OS:.\private$\Logging"
binding="msmqIntegrationBinding"
bindingConfiguration="LoggingProcessorBinding"
contract="GMO.XIPCommon.Logging.IGMOWCFTrace">
</endpoint>
</service>
</services>
<bindings>
<msmqIntegrationBinding>
<binding name="LoggingProcessorBinding" exactlyOnce="false" >
<security mode="None" />
</binding>
</msmqIntegrationBinding>
</bindings>
</system.serviceModel>




WCF client has MSMQ code and optionally WCF Code:



public override void WriteLine(object o)
{
Message msg = new Message();
msg.Body = (GMO.XIPCommon.Logging.GMO_LOG_DataContract)o;
loggingQueue.Send(msg);
}



Note Client Configuration can optionally have WCF serviceModel to hint WCF services start processing. This is not absolutely needed but some of my test showed logging
stuck in MSMQ until a call is made to WCF Services:



<system.serviceModel>
<client>
<endpoint name="LoggingEndpoint"
address="msmq.formatname:DIRECT=OS:.\private$\Logging"
binding="msmqIntegrationBinding"
bindingConfiguration="LoggingBinding"
contract="GMO.XIPCommon.Logging.IGMOWCFTrace">
</endpoint>
</client>

<bindings>
<msmqIntegrationBinding>
<binding name="LoggingBinding" exactlyOnce="false" >
<security mode="None" />
</binding>
</msmqIntegrationBinding>
</bindings>
</system.serviceModel>



In other words, MSMQ integration need both MSMQ Code and WCF client code.


Wednesday, November 12, 2008

Sql Query Notification setup code

  
string cs = "Server=vcgmo;Initial Catalog=AdventureWorks; User Id=sa; password=xxxxxx;";
SqlConnection cn;

SqlDependency.Start(cs);
cn = new SqlConnection(cs);
cn.Open();

SqlDataReader r;
SqlCommand cmd;
SqlDependency sd;
SqlDataAdapter ad;

cmd = new SqlCommand("[dbo].[uspTest]", cn);
sd = new SqlDependency(cmd);
sd.OnChange += new OnChangeEventHandler(sd_OnChange);
r = cmd.ExecuteReader();

SqlDependency.Stop(cs);

void sd_OnChange(object sender, SqlNotificationEventArgs e) { }


Note: To enable SQL Notification, must run

ALTER DATABASE [DatabaeName] SET ENABLE_BROKER;

in the Database

Wednesday, November 5, 2008

Call C++ Open MP from C# code



static OMPCommon.TestCallback cb = new OMPCommon.TestCallback(Test);
static void Main(string[] args)
{
OMPCommon.Helper.UseOMP(cb);
Console.ReadLine();
}
static void Test(int i)
{
Console.WriteLine(i);
Thread.Sleep(5000);
}

// Set VS2008 C++ project Properties -->Configure --> C/C++ Language --> Support OpenMP
#include <omp.h>
#pragma once

using namespace System;

namespace OMPCommon {


public delegate void TestCallback(int i);
public ref class Helper
{
public:
static void UseOMP(TestCallback^ cb)
{
omp_set_num_threads(10);
#pragma omp parallel for
for (int i=0;i<20; i++)
{
cb(i);
}
}
};
}



Convert System.String to bstr



GMOBlotter::GMOBlotter(String^ TraderName, String^ TraderPassword, String^ XIPDBServer)
{
::bstr_t trader, pwd, server;
trader.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(TraderName).ToPointer()));
pwd.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(TraderPassword).ToPointer()));
server.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(XIPDBServer).ToPointer()));
::MxEnumReturnCode ret;
ret=pMxgXOM->Login(trader, pwd, server, L"GMO_INTRADAY",::MxeEncryptionMethodNone);
};

Wednesday, October 15, 2008

VBS for NT services installation


Install/Uninstall by Name:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colListOfServices = objWMIService.ExecQuery _
("SELECT * FROM Win32_Service WHERE Name = 'IA DB Logging'")
For Each objService in colListOfServices
objService.StopService()
objService.Delete()
Next

Install by source exe
DIM objShell
set objShell = wscript.createObject("wscript.shell")
iReturn = objShell.Run("C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\installUtil IACalcDaemon.exe")

Friday, October 10, 2008

C++ code for XIP Allocation


#import "C:\Program Files\Macgregor\XIP\Common\XIP\TypeLibs\MxXOM.tlb" no_namespace named_guids
#import "C:\Program Files\Macgregor\XIP\Common\XIP\TypeLibs\Xip.tlb" no_namespace named_guids exclude("_IMxXOMEvents","IMxComponentInfo","MxEnumMsgCode","MxEnumObjectType","MxEnumReturnCode","MxEnumBoolean","MxEnumXOMAction","MxEnumRefreshEventType")
#import "C:\Program Files\Macgregor\XIP\Common\XIP\TypeLibs\MxOrderGenerator.tlb" no_namespace named_guids exclude("_IMxXOMEvents","IMxComponentInfo","MxEnumMsgCode","MxEnumObjectType","MxEnumReturnCode","MxEnumBoolean","MxEnumXOMAction","MxEnumRefreshEventType","MxEnumEncryptionMethod","IMxComponentInfo_701")

IMxgXOMPtr pMxgXOM(__uuidof(MxgXOM));

GMOBlotter::GMOBlotter(String^ TraderName, String^ TraderPassword, String^ XIPDBServer)
{
::bstr_t trader, pwd, server;
trader.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(TraderName).ToPointer()));
pwd.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(TraderPassword).ToPointer()));
server.Attach(static_cast(System::Runtime::InteropServices::Marshal::StringToBSTR(XIPDBServer).ToPointer()));
::MxEnumReturnCode ret;
ret=pMxgXOM->Login(trader, pwd, server, L"GMO_INTRADAY",::MxeEncryptionMethodNone);
};

int GMOBlotter::Recalc(int TickNum)
{
::MxEnumReturnCode ret;
::HRESULT h;
IMxXOMAcctsAllocPtr pAcctsAlloc;
::CoInitialize(NULL);

try
{

IDispatchPtr pDis =pMxgXOM->GetCollection(L"TradeOrders");
IMxXOMOrdersPtr pOrd=NULL;
h=pDis->QueryInterface(::IID_IMxXOMOrders,(void **) &pOrd);
IMxXOMOrder3Ptr pTOrd;
VARIANT* v= new VARIANT();
h=pOrd->Item(TickNum,v);
v->pdispVal->QueryInterface(::IID_IMxXOMOrder2,(void**) &pTOrd);


h=pTOrd->GetAcctsAlloc()->QueryInterface(::IID_IMxXOMAcctsAlloc,(void**) &pAcctsAlloc);

ret=pAcctsAlloc->BeginProcessing();
// ret=pAcctsAlloc->Recalc();
pAcctsAlloc->raw_BeginProcessing(&ret);
h=pAcctsAlloc->raw_Recalc(&ret);
if (ret!=::MxeOK)
String^ error="Error";

}
catch (System::Runtime::InteropServices::COMException^ cex)
{
String^ err="";
return -1;
}
catch (...)
{
String^ err="";
return -1;
}
finally
{
pAcctsAlloc->raw_EndProcessing(::MxeProcessActionSave,&ret);
// ret=pAcctsAlloc->EndProcessing(::MxeProcessActionSave);
}
if (ret!=::MxeOK) return -1;
return 0;
};

Thursday, September 11, 2008

TFS Branching and Merging draft Guideline


Branch and Merge is a core concept in TFS to facilate Source Control and release
management. There are various approach to these topics. But here are brain-dump
while encountering practical issues using TFS ( Team Fundation server).

(1) Agile Development Directory Structure representing Team, products, solutions,
major branch

Trading System
CRD
XIP
GMO.XIP
Branches
2008
2009
Trunk


(2) Each branch represent a weekly release version. and Trunk should not be released.
This will allows us to support different usage of XIP solution for different
business cases and still support common core.
If CMMI are used, then the structure could be based on version number not related to Dates

(3) For non-release related feature (eg. new helper function or bug fixes), a
feature branches should be used for the changes. In other words, Trunk can only be
changed through merge back from branches.

(4) Branching should be off Tip Revision (Latest Version), rather than a label since TFS needs
to duplicated files on branching and we have to use duplicated directory structure, which in
itself already acts like Label.