Tuesday, July 7, 2015

Create a WCF listener for Service Bus

0)      Add nuget package reference to ServiceBus.v1_1 (at the time of writing this).

1)      Your ServiceContract should look this this –
[ServiceContract]
    public interface IService1
    {

        [OperationContract(IsOneWay = true, Action = "*"), ReceiveContextEnabled(ManualControl = true)]
        void AccountingReader(Message message);

        // TODO: Add your service operations here
    }
ManualControl is true means that when the message is received from the ServiceBus, We have to manually invoke receiveContext.Complete(); to remove it from the queue or topic.

2)      Your Web config should look this this –
a)      One key point - When working in Windows 7 (non server machine, or When not in corpnet), use SAS to authentication as windows STS does not seem to work.
b)      Second , in case of any issue, use – WCF tracing.

<system.serviceModel>  
    <extensions>
      <!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
      <behaviorExtensions>
        <add name="connectionStatusBehavior" type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="serviceRegistrySettings" type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </behaviorExtensions>
      <bindingElementExtensions>
        <add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="tcpRelayTransport" type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="httpRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="httpsRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="onewayRelayTransport" type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </bindingElementExtensions>
      <bindingExtensions>
        <add name="basicHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="ws2007HttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="netOnewayRelayBinding" type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="netEventRelayBinding" type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </bindingExtensions>
    </extensions>
    <bindings>     
      <customBinding>
        <binding name="messagingBinding" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:03:00" sendTimeout="00:03:00">
          <textMessageEncoding messageVersion="None">
            <readerQuotas maxStringContentLength="2147483647" />
          </textMessageEncoding>
          <!--<binaryMessageEncoding/>-->
          <netMessagingTransport />
        </binding>
      </customBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="securityBehavior">
          <transportClientEndpointBehavior>
            <tokenProvider>
              <!--VV Imp. When working in Windows 7 (non server machine), use SAS to authentication as windows STS does not seem to work-->
              <sharedAccessSignature keyName="RootManageSharedAccessKey" key="gqlUNxI0+lNzJopR0gaJOt8LLOn3jELsRepjBSij7T4=" />
              <!--<windowsAuthentication>
                <stsUris>
                  <stsUri value="https://VM-WEB-AZURE/ServiceBusDefaultNamespace"/>               
                </stsUris>
              </windowsAuthentication>-->
            </tokenProvider>
          </transportClientEndpointBehavior>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <!--To avoid disclosing metadata information, set the values below to false before deployment-->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <!--To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information-->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
      <add binding="netMessagingBinding" scheme="sb" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" minFreeMemoryPercentageToActivateService="0" multipleSiteBindingsEnabled="true" />
    <services>
      <service name="ReceiveFromWSSB.Service1">

        <endpoint name="myEndPoint" listenUri="sb://VM-WEB-AZURE/ServiceBusDefaultNamespace/as400/subscriptions/AllAS400"
                  address="sb://VM-WEB-AZURE/ServiceBusDefaultNamespace/as400" binding="customBinding"
                  bindingConfiguration="messagingBinding" contract="ReceiveFromWSSB.IService1" behaviorConfiguration="securityBehavior"/>

     
      </service>
    </services>


  </system.serviceModel>
3)      Your Service implementation should look like this  -

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
    public class Service1 : IService1
    {
         public void AccountingReader(Message message)
        {


4)  Push some messages to the Service Bus Topic or Queue through code or through SB Explorer as shown below – 


WCF Sessions (and its dependency on bindings) demo


To find the instance id of the WCF instance (for monitoring purpose) use the following code –snippet

public class Service1 : IService1
    {
        private string instanceId = "";

        public Service1()
        {
            instanceId = Guid.NewGuid().ToString();
        }
        public string GetData(int value)
        {
Trace.WriteLine(String.Concat("Current WCF Instance Id is : ", instanceId));
File.AppendAllText(@"C:\Temp\logs.txt", "Current WCF Instance Id is : " + instanceId);
            return string.Format("You entered: {0}", value);
        }

You will get a different GUID printed each time if the call is per-call
By default, its per-session, but you might get different GUIDs if the binding does not support session (example basicHttpBinding). Test it by opening the WCfTestClient tool.
If you try to enforce session in the contract by specifying  -
[ServiceContract(SessionMode = SessionMode.Required)]
    public interface IService1

You will get an error when you try to add a reference to the service (if the binding is still basicHttpBinding).
The above method is a good way to test the service instance creation and its dependency on binding.

Friday, July 3, 2015

Garbage collection and Finalization in .NET



Garbage Collection and Finalization

When an object is instantiated, it goes Managed heap. There are also 2 special queues where the objects might go depending on certain conditions -

Finalization Queue - When an object is instantiated, if it has finalize method implemented ( as Destructor - ~ClassName), an entry is done in the Finalization queue as
well, in addition to the Managed heap.

F-Reachable Queue

During GC scan, when the garbage is found (no application roots present after traversing - Check second diagram below) , it checks its presence in Finalization queue.
If found in Finalization queue, it moves them to F-Reachable queue.
If not found in Finalization queue, it is collected.


If an object makes its way to the F-Reachable queue, its NOT garbage. Another special thread runs which clears the F-Reachable queue.

Once it clears the F-Reachable queue, the next time GC runs. It would remove those object from managed heap. (as no entry of them is present in Finalization queue AND F-Reachable queue).

======Optimization in GC (Generation based garbage collection)=======

Assumption - NEWER OBJECTS HAVE LESSER LIFELINE (OLDER OBJECTS HAVE LONGER LIFELINE)

1) First time, objects are added to the managed heap, its in GEN 0.
2) GC runs using the above complex steps and collects some garbage objects. Those objects which survived (not garbage) are moved to GEN 1. Some new objects might be added during this time to the managed heap. It will be in GEN 0.
3)Next GC run happens - surviving objects (not garbage) GEN numbers are increased. GEN 1 are in GEN 2. and earlier GEN 0 are now in GEN 1. In the meantime, some new objects might be added to the managed heap. It will be in GEN 0. (Will look like third image below).
4)During collection, GC only scans GEN 0 instead of entire heap (based on the above assumption). Hence the optimization.


Some diagrams for illustration –

Need of Garbage collection here





Not Reachable by Application Roots, Found Garbage (Grey colored objects) –




Depiction of Generations in objects