Friday, September 24, 2010

WSDL-First development with Visual Studio

This is how I implemented the WSDL-First approach when creating a WCF service with Visual Studio.

An example of a simple WSDL:

<?xml version="1.0" encoding="utf-8"?>
<definitions
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://www.myweb.com/ws/"
  xmlns:s="http://www.w3.org/2001/XMLSchema"
  xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
  targetNamespace="http://www.myweb.com/ws/"
  xmlns="http://schemas.xmlsoap.org/wsdl/">
  <types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://www.myweb.com/ws/">
      <s:element name="DoSomething">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="param1" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="param2" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="DoSomethingResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="DoSomethingResult" type="tns:TheDTO" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:complexType name="TheDTO">
        <s:complexContent mixed="false">
          <s:extension base="tns:BaseDTO">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="Att1" type="s:string" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:complexType name="BaseDTO" abstract="true">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="BaseAtt1" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="BaseAtt2" type="s:string" />
        </s:sequence>
      </s:complexType>
    </s:schema>
  </types>
  <message name="DoSomethingSoapIn">
    <part name="parameters" element="tns:DoSomething" />
  </message>
  <message name="DoSomethingSoapOut">
    <part name="parameters" element="tns:DoSomethingResponse" />
  </message>
  <portType name="IService">
    <operation name="DoSomething">
      <documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Do something.</documentation>
      <input message="tns:DoSomethingSoapIn" />
      <output message="tns:DoSomethingSoapOut" />
    </operation>
  </portType>
  <binding name="TheServiceSoap" type="tns:IService">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <operation name="DoSomething">
      <input>
        <soap:body use="literal" />
      </input>
      <output>
        <soap:body use="literal" />
      </output>
    </operation>
  </binding>
  <service name="TheService">
    <port binding="tns:TheServiceSoap" name="TheServicePort"/>
  </service>
</definitions>

Tip: It can be useful to download a WSDL-template to start with, instead of writing it from scratch.
Use the svcutil utility to save the WSDL-file exported from a service:

> svcutil /t:metadata http://localhost:8731/TheService/Service/

I added a Pre-Build command that reads my WSDL-file and creates an interface file in preferred language, in my case C#:

svcutil /language:C# /n:*,TheService /out:$(ProjectDir)IService.cs $(ProjectDir)\TheService.wsdl

The IService.cs will be regenerated each time I initiates a build so I adds the implementation of the interface in a separate file, Service.cs.

using System;
namespace TheService
{
    using System.ServiceModel;

    [ServiceBehavior(Namespace = "http://www.myweb.com/ws/")]
    public class Service : IService
    {
        public TheDTO DoSomething(string param1, string param2)
        {
            throw new NotImplementedException();
        }
    }
}

It is preferable to store the WSDL file separately in the VCS, then you can redesign both server and clients without affecting the functionality, as long as they use the same version of the WSDL file.

 

The WSDL can now be used to create service clients.
For example, to create a .NET client, use the svcutil utility to create the service proxy code:

> svcutil TheService.wsdl

The svcutil utility creates a Service.cs that you include in the client project, and then the service can be invoked as if it were a local object.

var myService = new ServiceClient();

TheDTO result = myService.DoSomething("A", "B");

Wednesday, January 20, 2010

Subversion authentication problem in Hudson

I tried to move a TeamCity .NET project to Hudson.
Build script is written in NAnt so I only needed to change the TeamCity environment properties to the Hudson equivalents.

But I run into the same authentication problem as with TeamCity described in earlier post:

ERROR: Failed to update https://<removed>/svn/MyProject/trunk org.tmatesoft.svn.core.SVNCancelException: svn: authentication cancelled

Hudson uses the SvnKit as well so I was pretty sure what the cause was, the Java NTLM implementation.

After adding the property -Dsvnkit.http.ntlm=jna to the Hudson configuration file, hudson.xml, and restarting the Hudson Windows service, everything worked perfectly!

Wednesday, October 21, 2009

Using secure Subversion from TeamCity

I have installed TeamCity (5.0 EAP version) on a Windows 2003 server. Both the Tomcat web server and the build agent are started as windows services.

The Subversion server is installed on a Linux server with Apache Tomcat web server. The Subversion server is protected with HTTPS.

When I tried to connect to the SVN-server through TeamCity, I always received the authentication error:

svn: Authentication required for '<https://<server name>:443>'

And the strange thing is that it worked fine if I used the SvnKit command tool, with the same user. So it was no certificate problem.

Searching the Internet for solutions always ended up with suggestions to change the svnkit.http.methods parameter.
But it had no effect on My problem. I was sure that NTLM authentication should be used, and from version 4.0.2 of TeamCity, the NTLM protocol is used by default.

Finally, I found out that SvnKit includes two NTLM implementations, the default is pure Java. But its also possible to use the native NTLM through the JNA library.

I added the svnkit.http.ntlm=jna parameter and suddenly the SVN connection was successful!!!
So much pain for this small window :-)

image 

JNA is included in the TeamCity Windows build agent package, so its not even necessary to install it on the server.

The SvnKit parameter must be defined in two places, for the build agent and for the web server:

1. The build agent properties file, i.e. <install path>TeamCity\buildAgent\launcher\conf\wrapper.conf:

# TeamCity agent JVM parameters
wrapper.app.parameter.2=-ea
wrapper.app.parameter.3=-Xmx512m
# The next line can be removed (and the rest of the lines renumbered) to prevent memory dumps on OutOfMemoryErrors
wrapper.app.parameter.4=-XX:+HeapDumpOnOutOfMemoryError
# Preventing process exiting on user log off
wrapper.app.parameter.5=-Xrs
# Uncomment the next line (insert the number instead of "N" and renumber the rest of the lines) to improve JVM performance
# wrapper.app.parameter.N=-server
wrapper.app.parameter.6=-Dlog4j.configuration=file:../conf/teamcity-agent-log4j.xml
wrapper.app.parameter.7=-Dsvnkit.http.ntlm=jna
wrapper.app.parameter.8=-Dteamcity_logs=../logs/
wrapper.app.parameter.9=jetbrains.buildServer.agent.AgentMain
# TeamCity agent parameters
wrapper.app.parameter.10=-file
wrapper.app.parameter.11=../conf/buildAgent.properties

2. Configure the Tomcat web server.

Open the configuration window with <install path>TeamCity\bin\tomcat6w.exe //ES//TeamCity.

Add the SvnKit parameter in the Java tab – Java Options:

image

Restart both services to get the new parameter initiated.