Migrating WCF as Azure worker role - azure-worker-roles

I have a WCF Service Library which is run as a windows service. I would like to migrate this service as Azure worker role. When I right click on a WCF project, I typically see the option "Add Windows Azure Deployment Project". With my WCF library, I do not see this option. In that case, how do I migrate the WCF service library to Azure as worker role? Any help would be greatly appreciated.
Below is the app.config for my WCF service library.
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IHealthService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" algorithmSuite="Default" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:9017/monitor/health/service.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IHealthService"
contract="HealthService.IHealthService" name="NetTcpBinding_IHealthService" />
</client>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>

In this case, I would like to suggest you to manually create a worker role project, add a reference to the service library project, and then host the service inside the worker role. The service host code is similar to what you get for a normal console/Windows Service host. But please obtain the address via code. In addition, you can refer to http://msdn.microsoft.com/en-us/WAZPlatformTrainingCourse_WindowsAzureRoleCommunicationVS2010Lab for a complete tutorial.
Best Regards,
Ming Xu.

The Add Windows Azure Deployment Project option only appears if the project type is a WebApplication or WCF Application. You have to host your WCF library in a WebApplication and then the option will appear (or even better host it directly in a Windows Azure WebRole project).
If you really want to host your WCF library in a WorkerRole I suggest you do what Ming Xu has explained. But normally you host your WCF services in WebRoles on Windows Azure. So I hope you have a special need that explains why you want to use WorkerRoles.
I hope that helps.

Related

WIX: Install Services using runner and multible dlls

I'm working on a Wix installer which should install multiple Services based on the same runner. This a some dlls which will be loaded by the runner. With sc.exe this works fine on my test system. Now my question, can I use standard Wix ServiceInstall for this? I have only one runner.exe and I'm not sure how to write this in the XML. Or would a Custom Action be the right way?
Thanks!!
The ServiceInstall and ServiceControl elements don't come after the file element per say but they are children on the Component element. They target the keypath of the component which happens to be the File element. You can easily have multiple services defined in a single component pointing to the same executable.
<Component Id="c1" Guid="dbc1b8dd-14e1-380f-5793-4a746fa0c5c5">
<File Id="f1" Source="$(var.SourceDir)\TestService.exe" KeyPath="yes" />
<ServiceInstall Id="si1" Name="TestService1" DisplayName="TestService1 Service" Description="TestService1 Service" ErrorControl="normal" Start="auto" Type="ownProcess" />
<ServiceControl Id="sc1" Name="TestService1" Start="install" Stop="both" Remove="both" Wait="yes" />
<ServiceInstall Id="si2" Name="TestService2" DisplayName="TestService2 Service" Description="TestService Service" ErrorControl="normal" Start="auto" Type="ownProcess" />
<ServiceControl Id="sc2" Name="TestService2" Start="install" Stop="both" Remove="both" Wait="yes" />
</Component>
To have each service behave differently you'll have to write code in your service to access ServiceBase.ServiceName (this.ServiceName in the OnStart method likely). From here you can dynamically load different classes from different assemblies.

Self Hosted (console) WCF configuration

i had a WCF server running through a Console application, it will run as an azure service so i don't to host it in ISS.
I belived it work well and share datas to my web app through ajax request. But when i maked a service that recieve a filestream, i realized that my binding configuration is not used at all. My WCF work same without binding section.
My probleme concerne especially the key "maxReceivedMessageSize" because default value limit me to 8Ko request and it is a problem for uploading file.
Bindings section (that i can comment) :
<webHttpBinding>
<binding name="MyBindingConfig" crossDomainScriptAccessEnabled="true" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" transferMode="Buffered">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None" />
</binding>
</webHttpBinding>
Services section :
<service name="MyData.Service.MyDataServiceRestFull">
<endpoint binding="webHttpBinding"
contract="MyData.Service.IMyDataServiceRestFull" bindingName="MyBindingConfig" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9997/MyDataServer"/>
</baseAddresses>
</host>
</service>
Note that i tryed with basicHttpBinding and i had same issue.
The problem is that you're incorrectly referring to your binding in your <endpoint/> element. You're using the bindingName attribute, when you should be using the bindingConfiguration attribute:
<endpoint binding="webHttpBinding"
contract="MyData.Service.IMyDataServiceRestFull"
bindingConfiguration="MyBindingConfig" />

Service Fabric Multiple service instances with config override

Our service fabric application includes a stateless service that exposes an HTTP endpoint through OwinCommunicationListener.
The ServiceManifest.Xml for this service specifies the service endpoint <Endpoint Name="ServiceEndpoint" Type="Input" Protocol="http" Port="8090" />
The stateless service can then be accessed via a browser on http://localhost:8090/
What we are trying to do is instantiate multiple instances of this service on different endpoints in the same Service Fabric application through the ApplicationManifest.
The ServiceManifestImport imports our service package and allows configuration overrides at the application level. We're not able to override the ServiceEndpoint this way, only the values in Settings.xml
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="FooServicePkg" ServiceManifestVersion="1.0.0" >
<ConfigOverrides Name="Config">
<Settings>
<SectionName Name="MySettings">
<Parameter Name="MySetting" Value="SomeValue">
</Settings>
</ConfigOverrides>
</ServiceManifestImport>
We can create named instances of the service by specifying multiple Service nodes under DefaultServices
<DefaultServices>
<Service Name="FooInstanceA">
<StatelessService ServiceTypeName="FooType" InstanceCount="1" />
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="FooInstanceB">
<StatelessService ServiceTypeName="FooType" InstanceCount="1" />
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
Is it possible to specify configuration overrides per instance of a service through configuration?
I tried to make the service instances listen on a specific port by using their service name to work out which port so FooInstanceA listens on port 8090 and FooInstanceB listens on 8091.
Clearly Service Fabric is doing some magic during deployment because when FooInstanceB listens on a port other than the one specified on the ServiceEndpoint configuration the service is not accessible.
The first reason is the DACL is not set on the endpoint, this is resolved by running;
netsh http add urlacl http://+:8091/ user=everyone listen=yes
This allows the services to come up and show healthy in the Service Fabric Explorer, however the FooInstanceB is responding with an HTTP 503 error when we access with http://localhost:8091/
How can we get the service instances listening on different ports?
I hope that's clear, thank you.
Not a lot of great options to accomplish this. Here are some ideas:
Create multiple application instances instead of multiple services of the same type within an app. That would allow you to use the app parameters to configure the behavior of the particular service.
Create multiple config packages within your service type. Each config package would be intended for one of the service instances. Determining which config package a service instance is assigned to would need to be dynamic, maybe based on the service instance's name? Not a great option, of course, since it couples the service definition with the number of instances that will be created.
A custom configuration implementation. Maybe have your service expose an endpoint that allows you to configure it post-deployment. Or have the service call some other management service that provides its configuration at activation time.
You can also let Service Fabric assign the ports automatically and then use the reverse proxy that comes with Service Fabric.
I think its a very good idea to have a url rewriting service in front of a SF cluster .
This can give you multiple end points and do url rewriting , firewalls/ black listing , https etc .
Other way is to package the service as a lib or in Nuget and create the N services you need with different service manifests.
I've managed to do this using ApplicationParameter xml files and choose the right one during deployment in VSTS.
This, for example, is my Cloud.xml which I use for deployment to my test environment. The trick is the Name parameter on the second line. I've specified the port using this documentation: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-how-to-specify-port-number-using-parameters
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/DotNetCoreTest" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Web1_InstanceCount" Value="2" />
<Parameter Name="ServiceEndpoint_PortNumber" Value="8909" />
</Parameters>
</Application>
This is the xml file for Staging: Staging.xml
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/DotNetCoreStaging" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Web1_InstanceCount" Value="2" />
<Parameter Name="ServiceEndpoint_PortNumber" Value="8910" />
</Parameters>
</Application>
Using the Traefik Reverse Proxy as described here I can use a hostname to reach my service.
In VSTS I'm using a tokenizer to replace both the host name in the ServiceManifest and replacing the ApplicationTypeName in the ApplicationManifest during deployment.
This is my ServiceManifest:
<ServiceTypes>
<!-- This is the name of your ServiceType.
This name must match the string used in RegisterServiceType call in Program.cs. -->
<StatelessServiceType ServiceTypeName="Web1Type">
<Extensions>
<Extension Name="Traefik">
<Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
<Label Key="traefik.frontend.rule.hostname">Host: #{HostName}#</Label>
<Label Key="traefik.expose">true</Label>
<Label Key="traefik.frontend.passHostHeader">true</Label>
</Labels>
</Extension>
</Extensions>
</StatelessServiceType>
</ServiceTypes>

How to call WCF service from .NET class library

I have a WCF web service built in .NET 4.0 that is configured to require a username/password on each call and uses a Server certificate in the behaviour to encrypt the request. It currently uses wsHttpBinding. I have a .NET 4 utility app that lets me call the methods on this WCF web service just fine.
I need to call this service from a .NET 2.0 class library. The library is in VS 2010 but targetting .NET 2.0 - I would like to simply switch to .NET 4.0 but can't for political reasons and time constraints. So therefore wsHttpBinding and the server certificate as used now are out of the question from what I've read so far.
From reading bits and pieces I did the following:
Changed the binding to use
basicHttpBinding
Removed mention of the server certificate from the behaviours
Installed and
enabled WSE on the class library
project.
Try to use on the WCF web service methods in .NET 2.0 winforms app - epic fail!!
It doesn't matter how I seem to configure the binding at the server end HTTPS is just not acceptible; the only way to get it to let me call it at all is do use security mode of "None", grrrghhh! That of course allows me to call it but then the username/password details are not supplied and never get set on the WCF service and hence when it eventually tries to save it fails because the user ID is 0.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="false"/>
<services>
<service name="MyService.NameHere" behaviorConfiguration="NameOfMyConfigHere">
<endpoint binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="DirectoryServices.IDirectorySubmitService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehaviourName">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicBinding" maxReceivedMessageSize="5242880">
<readerQuotas maxStringContentLength="5242880"/>
<security mode="None">
<transport clientCredentialType="Basic" proxyCredentialType="Basic" />
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
If anyone could help me figure out the correct magic mumbo to put in I would be most appreciated.
All I want to do is call a WCF web method supplying a username/password and have it use SSL to encrypt. The service is running on IIS. The client is a winforms app.
The .NET 2.0 Framework does not include WCF (which was introduced in 3.0), so I don't see how you will achieve this easily. You might have to tell the politicians to bite the bullet and migrate to .NET 4.0.

Enabling html PUT method on IIS 7.5

I'm doing a iCal Service to allow sync between Calendar instances and runs fantastic on localhost (under VS2010 Web Server)
But now That I hosted on a Windows 2008 R2 (IIS 7.5.7600) I couldn't create not even update an event :-o
Thunderbird always said
So I rush into Fiddler and found out the problem
a 405 error
That says PUT is not allowed :(
How can I enabled this method? Application Pool? WebSite definition? IIS Settings?
We just need to remove the WebDav Service
Control Panel > Program and Features > Turn Windows features on or off
then navigate to Server Manager > Roles > Web Server (IIS) and wait until Roles Services come up.
Then Remove Role Service and Remove WebDAV Publishing
You need to restart the Server to finalize this action.
I hope it helps someone
You can do it from configuration file.
<system.webServer>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness64"
responseBufferLimit="0" />
</handlers>
</system.webServer>
Source: http://www.asp.net/web-api/overview/testing-and-debugging/troubleshooting-http-405-errors-after-publishing-web-api-applications