Author Archives: purpleblob

Hosting more than one service using CXF and Jetty

This is a logical “next post” to Hosting a CXF SOAP webservice in an existing Jetty instance.

Let’s look at what’s need to host more than one service using CXF from a running instance of Jetty.

Changes to our SOAP Service

We’re going to do this by hosting our original HelloWorld service (from the previous post) with a single line change and alongside it we’ll create a REST service.

So in the AppConfig from the previous post, rename getService to getSoapServer (or whatever you like) and the code should look like this

@Bean @DependsOn( "cxf" )
public Server getSoapServer() {
   JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
   factory.setServiceBean(new HelloWorldImpl());
   factory.setAddress("/soap");
   return factory.create();
}

Apart from the method name change, we’ve added a setAddress call with a relative path. If you recall from the previous post our Jetty server will run on port 9000, i.e. http://localhost:9000 but now our SOAP service will be on http://localhost:9000/soap/HelloWorld?wsdl.

Adding a REST Service

Update the pom.xml with the following, in the properties we’ll add

<json.version>1.1.0-M1</json.version>
<glassfish.version>1.0.4</glassfish.version>

and these dependencies

<dependency>
   <groupId>javax.json</groupId>
   <artifactId>javax.json-api</artifactId>
   <version>${json.version}</version>
</dependency>

<dependency>
   <groupId>org.apache.cxf</groupId>
   <artifactId>cxf-rt-frontend-jaxrs</artifactId>
   <version>${cxf.version}</version>
</dependency>

<dependency>
   <groupId>org.apache.cxf</groupId>
   <artifactId>cxf-rt-rs-extension-providers</artifactId>
   <version>${cxf.version}</version>
</dependency>

<dependency>
   <groupId>org.glassfish</groupId>
   <artifactId>javax.json</artifactId>
   <version>${glassfish.version}</version>
</dependency>

Next we’ll create a simple REST service (I’ll actually duplicate the one from here).

So create a new Java class, mine’s named PeopleService and here’s the code

package com.putridparrot.core;

import javax.json.JsonArray;
import javax.json.Json;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/people")
public class PeopleService {
    @Produces({"application/json"})
    @GET
    public JsonArray getPeople() {
        return Json.createArrayBuilder()
                .add(Json.createObjectBuilder()
                        .add("firstName", "Brian")
                        .add("lastName", "Kernighan "))
                .add(Json.createObjectBuilder()
                        .add("firstName", "Dennis")
                        .add("lastName", "Ritchie "))
                .add(Json.createObjectBuilder()
                        .add("firstName", "Bjarne")
                        .add("lastName", "Stroustrup"))
                .build();
    }
}

within AppConfig, place the following

@Bean @DependsOn( "cxf" )
public Server getRestServer() {
   JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
   factory.setServiceBean(new PeopleService());
   factory.setProvider(new JsrJsonpProvider());
   factory.setAddress("/rest");
   return factory.create();
}

if you run the App.main, you should be able to navigate to http://localhost:9000/soap/HelloWorld?wsdl to get the SOAP service’s wsdl and http://localhost:9000/rest/people to get the results of the PeopleService call.

Just to complete the picture – the PeopleService is given a path to the REST calls. We’re simply returning JSON and so we annotate with the @Produces line. As we’re only support a GET call to this service we annotate @GET. Within the getPeople method we build up a JSON document and that’s all there is to it.

Hosting a CXF SOAP webservice in an existing Jetty instance

In the previous post we looked at creating a web service, exposing SOAP and running in a CXF created instance of Jetty, but what if you already have an application with an existing instance of Jetty running. All you want to do is drop a SOAP capable service into this instance.

Like most of the things I’ve discovered working with CXF (and Spring), it’s not that difficult, once you know how. It’s the finding out “how” that seems more difficult :)

First off, much credit goes to this post Embedded Jetty and Apache CXF: Secure REST Services With Spring Security or more specifically the source code for this post, here.

I’m not interested (at this time) in security, so we’ll ignore that and just concern ourselves with injecting a service into an instance of Jetty created by the application itself (not by CXF).

First up, let’s create our pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.putridparrot.core</groupId>
  <artifactId>cxfws</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>cxfws</name>
  <url>http://maven.apache.org</url>

  <properties>
    <cxf.version>3.0.1</cxf.version>
    <spring.version>4.1.0.RELEASE</spring.version>
    <jetty.version>9.4.2.v20170220</jetty.version>
  </properties>

  <dependencies>

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <version>${cxf.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-server</artifactId>
      <version>${jetty.version}</version>
    </dependency>

    <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-servlet</artifactId>
      <version>${jetty.version}</version>
    </dependency>
  </dependencies>
</project>

As usual, run mavn install to grab the dependencies.

Now create the usual folder structure for our source, /src/main/java and within this your package folders, i.e. com/putridparrot/core.

We’re going to create four files, two of which we’ve used in previous posts, HelloWorld and HelloWorldImpl, I’ll include those here first just for completeness

HelloWorld.java

package com.putridparrot.core;

import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public interface HelloWorld {
    String reply(@WebParam(name="text") String text);
}

HelloWorldImpl.java

package com.putridparrot.core;

import javax.jws.WebParam;
import javax.jws.WebService;

@WebService(endpointInterface = "com.putridparrot.core.HelloWorld", serviceName="HelloWorld")
public class HelloWorldImpl implements HelloWorld {
    public String reply(@WebParam(name = "text") String text) {
        return "Hello " + text;
    }
}

As per the example from the referenced post Embedded Jetty and Apache CXF: Secure REST Services With Spring Security we’re going to create the configuration in code, so create AppConfig.java and place the following in this file

package com.putridparrot.core;

import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

@Configuration
public class AppConfig {
    @Bean( destroyMethod = "shutdown" )
    public SpringBus cxf() {
        return new SpringBus();
    }

    @Bean @DependsOn( "cxf" )
    public Server getServer() {
        JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
        factory.setServiceBean(getService());
        return factory.create();
    }

    @Bean
    public HelloWorldImpl getService() {
        return new HelloWorldImpl();
    }
}

Finally create App.java and place the following inside it

package com.putridparrot.core;

import org.apache.cxf.transport.servlet.CXFServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

public class App {
    public static void main( String[] args ) throws Exception {

        Server server = new Server( 9000 );

        ServletHolder servletHolder = new ServletHolder( new CXFServlet() );
        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath( "/" );
        context.addServlet( servletHolder, "/*" );
        context.addEventListener( new ContextLoaderListener() );

        context.setInitParameter( "contextClass", AnnotationConfigWebApplicationContext.class.getName() );
        context.setInitParameter( "contextConfigLocation", AppConfig.class.getName() );

        server.setHandler( context );
        server.start();
        server.join();

        System.in.read();

        System.exit(0);
    }
}

Once this is built, run App.main and you should be able to use your web browser to navigate to http://localhost:9000/HelloWorld?wsdl and see the wsdl definitions for this service.

Great, but what’s it all doing?

Let’s start with the App.main method. The server variable is our Jetty instance. So really the only thing we’re interested here is which port have we assigned the instance to and the server.setHandler method call. This is where we embed our servlet context into the Jetty engine. From what I can understand, this basically allows us a way to intercept calls and pass to our specific servlet, in this case (ultimately) our CXFServlet.

The ServletHolder, as the name suggests, holds the servlet object that we want to use and will be added to the ServletContextHandler. As you can see this is where the bulk of the code is. The setContextPath call sets up the root level path of our context, i.e. changing to context.setContextPath( “/ws” ) means our webservice will now be located off of the ws path, thus http://localhost:9000/ws/HelloWorld?wsdl.

When we call addServlet we can, in essence, extend the root path further, so for example context.addServlet( servletHolder, “/services/*” ) will simply moved the servlet to your root path/services.

We add the spring ContextLoaderListener to the ServletContext and this is where we can setup the parameters required for spring to bring in our webservices etc.

The ContextLoaderListener “Create a new ContextLoaderListener that will create a web application context based on the “contextClass” and “contextConfigLocation” servlet context-params.” we’ll need to supplied the contextClass and contextConfigLocation parameters and that’s exactly what we do in the two setInitParameter lines of code.

The contextClass is going to use the web annotations (hence our webservices are annotated) and the contextConfigLocation will use our AppConfig class (instead of a config. file).

Configuration class

The AppConfig class supplies the configuration for the ContextLoaderListener and is first annotated with the Configuration, although removing this seemed to have no effect. What does have a big effect is the requirement for a bean named cxf – if this is missing you’ll get the following exception


Exception in thread “main” org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘cxf’ is defined

In our case we return a SpringBus

Next up we supply a getServer bean which depends on the cxf bean – this simply means the cxf bean should be created before the getServer bean. This code creates the web service implementation (we could have created a REST implementation using JAXRSServerFactoryBean). Within this code we set the factory bean to use the web service supplied via our getService method (which above is marked as a bean but needn’t be). The we simply return the result of the create method and we’re done.

Writing the Hello World CXF webservice

Before I get into this post, I’m well aware that SOAP hasn’t been the cool kid on the block in terms of web service messaging for a while, but I’m looking at updating an old application’s webservice from a framework which is no longer supported on an older version of Java to a supported framework. So we need to keep everything working using SOAP.

Following these steps, we can get a service up and running in next to no time (ofcourse it took me far longer than “no time” to find out how to do this :)).

  • Create yourself a folder for your project, mine’s cxftest
  • Within your project’s folder create a Maven pom.xml to grab all our required dependencies we’ll require – here’s the pom
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.putridparrot.core</groupId>
      <artifactId>cxftest</artifactId>
      <packaging>jar</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>cxftest</name>
      <url>http://maven.apache.org</url>
    
      <properties>
        <cxf.version>2.2.3</cxf.version>
      </properties>
    
      <dependencies>
    
        <dependency>
          <groupId>org.apache.cxf</groupId>
          <artifactId>cxf-rt-frontend-jaxws</artifactId>
          <version>${cxf.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.apache.cxf</groupId>
          <artifactId>cxf-rt-transports-http</artifactId>
          <version>${cxf.version}</version>
        </dependency>
    
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    </project>
    
  • We’re going to do everything from scratch here, but continue with the layout that Maven might generate for us, so off of your project’s folder create src/main/java/putridparrot/core
  • Now add three files, App.java, HelloWorld.java and HelloWorldImpl.java
  • Paste the following code into HelloWorld.java
    package com.putridparrot.core;
    
    import javax.jws.WebParam;
    import javax.jws.WebService;
    
    @WebService
    public interface HelloWorld {
        String reply(@WebParam(name="text") String text);
    }
    
  • Now let’s paste the following into the HelloWorldImpl
    package com.putridparrot.core;
    
    import javax.jws.WebParam;
    import javax.jws.WebService;
    
    @WebService(endpointInterface = "com.putridparrot.core.HelloWorld", serviceName="HelloWorld")
    public class HelloWorldImpl implements HelloWorld {
        public String reply(@WebParam(name = "text") String text) {
            return "Hello " + text;
        }
    }
    
  • Finally paste the following into App.java
    package com.putridparrot.core;
    
    import javax.xml.ws.Endpoint;
    import java.io.IOException;
    
    public class App {
       public static void main( String[] args ) 
          throws IOException, InterruptedException  {
    
       HelloWorldImpl impl = new HelloWorldImpl();
       String address = "http://localhost:9000/HelloWorld";
       Endpoint.publish(address, impl);
    
       // hold the service open
       System.in.read();
    
       System.exit(0);
    }
    

As you’ve probably noticed, we’re not using Spring to create our webservice (the HelloWorldImpl) and thus there’s no spring configuration or the likes. This really is a bare bones implementation to get us started.

Now if you run this you should be able to use the URL http://localhost:9000/HelloWorld?wsdl to grab the definition meta data. Hence from a C# client you can use wsdl.exe or using Visual Studio’s Add Service reference to generate C# classes to use this service.

Alternate code to start the server

In the above we used Endpoint to create the server, the alternative is to use the JaxWsServerFactoryBean, here’s the code

JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(HelloWorld.class);
factory.setAddress("http://localhost:9000/HelloWorld");
factory.create();

Beanify it

Okay, so we’ve proved the service works at this point, but we really don’t want to hardcode the service like this, so it’s type to turn it into a Spring bean.

First off let’s add to our pom.xml file, you’ll need the following added to the properties element

<spring.version>3.0.5.RELEASE</spring.version>

and then the following dependencies need to be added

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot</artifactId>
      <version>1.5.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
      <version>1.5.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>2.2.2</version>
    </dependency>

and we’re going to use Jetty as the HTTP server, so also add the following dependency

<dependency>
   <groupId>org.apache.cxf</groupId>
   <artifactId>cxf-rt-transports-http-jetty</artifactId>
   <version>${cxf.version}</version>
</dependency>

Obviously you’ll need to run mvn install to get the dependencies updated.

Next we need to create our beans file, within this we’ll actually create a server/endpoint which will be executed. So create a resources folder off of src/main in your project’s folder and add an XML file, mine’s named cxf.xml – within this file we can use one of either of these configurations

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-extension-http.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-http-jetty.xml" />

    <jaxws:server id="helloWorld"  serviceClass="com.putridparrot.core.HelloWorld" address="http://localhost:9000/HelloWorld">
        <jaxws:serviceBean>
            <bean class="com.putridparrot.core.HelloWorldImpl"/>
        </jaxws:serviceBean>
    </jaxws:server>
</beans>

or using an Endpoint we can use the following

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-extension-http.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-http-jetty.xml" />

 <jaxws:endpoint id="helloWorld" implementor="com.putridparrot.core.HelloWorldImpl"
                    address="http://localhost:9000/HelloWorld">
        <jaxws:features>
            <bean class="org.apache.cxf.feature.LoggingFeature"/>
        </jaxws:features>
    </jaxws:endpoint>
</beans>

You can change the address to address=”/HelloWorld” if you are using the default port etc. Otherwise to remove this will require looking into overriding Jetty’s port etc. (which is outside the scope of this post).

Finally we need to have the main method wire everything up, so within main we should have the following

new ClassPathXmlApplicationContext("cxf.xml");

// stop the server shutting down
System.in.read();
System.exit(0);

How does yield return work in .NET

A while back I had a chat with somebody who seemed very interested in what the IL code for certain C#/.NET language features might look like – whilst it’s something I did have an interest in during the early days of .NET, it’s not something I had looked into since then, so it made me interested to take a look again.

One specific language feature of interest was “what would the IL for yield return look like”.

This is what I found…

Here’s a stupidly simple piece of C# code that we’re going to use. We’ll generate the binary then decompile it and view the IL etc.

public IEnumerable<string> Get()
{
   yield return "A";
}

Using JetBrains dotPeek (ILDASM, Reflector or ILSpy can ofcourse be used to do generate the IL etc.). So the IL created for the above method looks like this

.method public hidebysig instance 
   class [mscorlib]System.Collections.Generic.IEnumerable`1<string> 
      Get() cil managed 
{
   .custom instance void  [mscorlib]System.Runtime.CompilerServices.IteratorStateMachineAttribute::.ctor(class [mscorlib]System.Type) 
   = (
      01 00 1b 54 65 73 74 59 69 65 6c 64 2e 50 72 6f // ...TestYield.Pro
      67 72 61 6d 2b 3c 47 65 74 3e 64 5f 5f 31 00 00 // gram+<Get>d__1..
      )
   // MetadataClassType(TestYield.Program+<Get>d__1)
   .maxstack 8

   IL_0000: ldc.i4.s     -2 // 0xfe
   IL_0002: newobj       instance void TestYield.Program/'<Get>d__1'::.ctor(int32)
   IL_0007: dup          
   IL_0008: ldarg.0      // this
   IL_0009: stfld        class TestYield.Program TestYield.Program/'<Get>d__1'::'<>4__this'
   IL_000e: ret          
} // end of method Program::Get

If we ignore the IteratorStateMachineAttribute and jump straight to the CIL code label IL_0002 it’s probably quite obvious (even if you do not know anything about IL) that this is creating a new instance of some type, which appears to be an inner class (within the Program class) named <Get>d__1. The preceeding ldc.i4.s instruction simply pushes an Int32 value onto the stack, in this instance that’s the value -2.

Note: IteratorStateMachineAttribute expects a Type argument which is the state machine type that’s generated by the compiler.

Now I could display the IL for this new type and we could walk through that, but it’d be much easier viewing some C# equivalent source to get some more readable representation of this. So I got dotPeek to generate the source for this type (from the IL).

First let’s see what changes are made by the compiler to the Get() method we wrote

[IteratorStateMachine(typeof (Program.<Get>d__1))]
public IEnumerable<string> Get()
{
   Program.<Get>d__1 getD1 = new Program.<Get>d__1(-2);
   getD1.<>__this = this;
   return (IEnumerable<string>) getD1;
}

You can now see the newobj in it’s C# form, creating the <Get>d__1 object with a ctor argument of -2 which is assigned as an initial state.

Now let’s look at this lt;Get>d__1 generated code

[CompilerGenerated]
private sealed class <Get>d__1 : 
    IEnumerable<string>, IEnumerable, 
    IEnumerator<string>, IDisposable, 
    IEnumerator
{
   private int <>1__state;
   private string <>2__current;
   private int <>l__initialThreadId;
   public Program <>4__this;

   string IEnumerator<string>.Current
   {
      [DebuggerHidden] get
      {
         return this.<>2__current;
      }
   }

   object IEnumerator.Current
   {
      [DebuggerHidden] get
      {
         return (object) this.<>2__current;
      }
   }

   [DebuggerHidden]
   public <Get>d__1(int <>1__state)
   {
      base..ctor();
      this.<>1__state = param0;
      this.<>l__initialThreadId = Environment.CurrentManagedThreadId;
   }

   [DebuggerHidden]
   void IDisposable.Dispose()
   {
   }

   bool IEnumerator.MoveNext()
   {
      switch (this.<>1__state)
      {
         case 0:
            this.<>1__state = -1;
            this.<>2__current = "A";
            this.<>1__state = 1;
            return true;
          case 1:
            this.<>1__state = -1;
            return false;
          default:
            return false;
      }
   }

   [DebuggerHidden]
   void IEnumerator.Reset()
   {
      throw new NotSupportedException();
   }

   [DebuggerHidden]
   IEnumerator<string> IEnumerable<string>.GetEnumerator()
   {
      Program.<Get>d__1 getD1;
      if (this.<>1__state == -2 && 
          this.<>l__initialThreadId == Environment.CurrentManagedThreadId)
      {
          this.<>1__state = 0;
          getD1 = this;
      }
      else
      {
          getD1 = new Program.<Get>d__1(0);
          getD1.<>4__this = this.<>4__this;
      }
      return (IEnumerator<string>) getD1;
   }

   [DebuggerHidden]
   IEnumerator IEnumerable.GetEnumerator()
   {
      return (IEnumerator) this.System.Collections.Generic.IEnumerable<System.String>.GetEnumerator();
    }
}

As you can see, yield causes the compiler to create enumerable implementation for just that one of code.

Using spring annotations

In a previous post I implemented a simple bean and created the SpringBeans configuration file, but spring can also be used with annotations (attributes to us .NET people).

So let’s take the previous posts code and amend it to use annotations.

  • Remove or comment out the contents of SpringBeans.xml
  • Change the HelloWorld bean to look like this
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class HelloWorld {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void output() {
            System.out.println("Bean says " + name);
        }
    }
    
  • Change the main method to look like this
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public static void main( String[] args )
    {
       AnnotationConfigApplicationContext context =
          new AnnotationConfigApplicationContext(IocConfiguration.class);
    
       HelloWorld obj = (HelloWorld) context.getBean("helloBean");
       obj.output();
    }
    
  • We still need a way to define how our beans are going to be created. We’re going to do this via a class, which we’ll name IocConfiguration (the name is unimportant), here’s the class
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class IocConfiguration {
    
        @Bean(name = "helloBean")
        public HelloWorld getHelloWorld() {
            HelloWorld o = new HelloWorld();
            o.setName("Hello World");
            return o;
        }
    }
    
  • Now before you can using the @Configuration you’ll need to update the Maven pom.xml to download cglib, so add the following dependency
        <dependency>
          <groupId>cglib</groupId>
          <artifactId>cglib</artifactId>
          <version>2.2.2</version>
        </dependency>
    
  • Run mvn install and now build and run the application.

Creating a simple spring bean

I’m going to create the standard Hello World spring bean. To start with, let’s use Maven to create a simple “default” set of files and from this we’ll start coding our bean.

To start with, run the following Maven command

mvn archetype:generate -DgroupId=com.putridparrot.core -DartifactId=SpringStarter -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Now open the pom.xml and before the dependencies element add the following

<properties>
   <spring.version>3.0.5.RELEASE</spring.version>
</properties>

and within the dependencies element add the following

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
</dependency>

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
</dependency>

Back to the command line, run (from the folder where your pom.xml is located)

mvn install

This command will run the pom.xml and install the spring framework dependencies.

Let’s add a bean

Beans are simply classes which are managed by the spring framework, so let’s create the obligatory HelloWorld bean

package com.putridparrot.core;

public class HelloWorld {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void output() {
        System.out.println("Bean says " + name);
    }
}

Now we’ll need to change the main method generated by Maven to look like this

ApplicationContext context = 
   new ClassPathXmlApplicationContext(
      "SpringBeans.xml");

HelloWorld obj = (HelloWorld) context.getBean("helloBean");
obj.output();   

You’ll also need the following imports

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

Spring is an IoC container and it will use (in this instance) a configuration file to define the objects (beans) to be created when an identifier (helloBean) is used.

You’ll notice that we’re telling spring to use the SpringBeans.xml file, which we haven’t yet created. In your main folder create a resources folder and within this add create the file SpringBeans.xml. It should look like this

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="helloBean" class="com.putridparrot.core.HelloWorld">
        <property name="name" value="Hello World" />
    </bean>
</beans>

So in the above we create the identifier helloBean, as stated previously, when we ask for an object with this identifier spring will supply a com.putridparrot.core.HelloWorld instance. We also supply a property value which is injected to the setName method (Java doesn’t support properties like C# so name is translated to setName). Thus, the value Hello Worldoutput method to see whether it all worked.

Proto.Actor Remoting

I’m now going to take a look at what’s required to implement a remote Proto.Actor and a “client” to interact with it. I’m going to stick to the standard Greet class, as shown in my previous post, but we’re going to generate the Greet class from a .proto (protocol buffers) definition file.

So before we get into the client/server code, let’s create the Greet.proto file, here’s it is

syntax = "proto3";

package messages;
option csharp_namespace = "Messages";

message Greet {
   string Who = 1;
}

The Greet message will generate a Greet type with a property name Who. So once you’ve created this file, you’ll need to use protoc.exe with the following command line

protoc.exe –csharp_out=. Greet.proto

This will generate the Greet.cs file, which I will not bother to show here.

Next up, we’ll reuse our GreetActor class from the previous post, recreated below

public class GreetingActor : IActor
{
   public Task ReceiveAsync(IContext context)
   {
      var greet = context.Message as Greet;
      if (greet != null)
      {
         Console.WriteLine("[Thread {0}] Greeting {1}",
            Thread.CurrentThread.ManagedThreadId,
            greet.Who);
      }
      return Actor.Done;
   }
}

As we know, strictly speaking Akka.net and also Proto.Actor do not adhere to a client/server architecture but remote objects are created in a peer to peer architecture. For the sake of this post we will create two separate projects, one named Server the other Client, just for simplicity.

Creating our server

  • Create a Console application, named something like ProtoActorServer
  • Using Nuget add the Proto.Actor and Proto.Remote packages
  • Add or link to the Greet.cs file generated by protoc
  • Add or link to the GreetActor.cs file from above
  • In Program.cs add the following using clauses
    using Messages;
    using Proto;
    using Proto.Remote;
    
  • In the Main method add the following code
    Serialization.RegisterFileDescriptor(GreetReflection.Descriptor);
    RemotingSystem.Start("127.0.0.1", 12000);
    
    var props = Actor.FromProducer(() => new GreetingActor());
    Actor.SpawnNamed(props, "remote");
    
    // just to keep the app. open
    Console.ReadLine();
    

Creating our client

As we know, this is going to basically be very similar to the server is set-up, but there are differences in the code, but I’ll still list all the steps for completeness

  • Create a Console application, named something like ProtoActorClient
  • Using Nuget add the Proto.Actor and Proto.Remote packages
  • Add or link to the Greet.cs file generated by protoc
  • Add or link to the GreetActor.cs file from above
  • In Program.cs add the following using clauses
    using Messages;
    using Proto;
    using Proto.Remote;
    
  • In the Main method add the following code
    Serialization.RegisterFileDescriptor(GreetReflection.Descriptor);
    RemotingSystem.Start("127.0.0.1", 12001);
    
    var remote = new PID("127.0.0.1:12000", "remote");
    remote.Tell(new Greet { Who = "Hello World" });;
    
    // just to keep the app. open
    Console.ReadLine();
    

If you now run the ProtoActorServer and then the ProtoActorClient you should see the Greeting Hello World message displayed on the server console via it’s GreetingActor.

Disclaimer

At the time of writing this I’ve not yet seen documentation to suggest I’m doing everything 100% by the Proto.Actor book, so to speak, I’ve based this code on previous use of protobuf and Akka.net as well as a couple of examples from the Proto.Actor git repos. If I find I’m doing anything incorrectly, I will update this page.

Proto.Actor first look

No sooner had I started looking to use Akka.net, than I find out about Proto.Actor (via .NET Rocks). From my understanding this comes from some of the same guys involved in Akka.net and currently supports .NET and the language Go.

One of my previous posts covered Getting started with Akka.net. Let’s take that post and rewrite the code using the Proto.Actor library, just to see what the differences are.

  • Create a Console application
  • Using Nuget, add the Proto.Actor package
  • Create a class named Greet, this will be used as the payload for wrapping our data that we shall pass to our Actor object. Here’s the code
    public class Greet
    {
       public Greet(string who)
       {
          Who = who;
       }
     
       public string Who { get; private set; }
    }
    
  • Create a new class named GreetingActor. This is our Actor object that does something and will accept objects of type Greet, the code should look like this
    public class GreetingActor : IActor
    {
       public Task ReceiveAsync(IContext context)
       {
          var greet = context.Message as Greet;
          if (greet != null)
          {
             Console.WriteLine("[Thread {0}] Greeting {1}",
                    Thread.CurrentThread.ManagedThreadId,
                    greet.Who);
          }
          return Actor.Done;
       }
    }
    

    So here’s the first difference, code-wise. We are implementing the IActor interface and our code goes in the ReceiveAsync method as opposed the Akka.net code which went in the constructor. Also we have to check the type in the context Message as opposed to using the Akka.net Receive<> generic to differentiate our types. Obviously with the latest C# 7 features we can use type matching, but I’m running this on C# 6 so the standard as operator is used.

  • Finally we want to create an instance of an actor and send a message to it via the Tell method, so our Main method should look like this
    var props = Actor.FromProducer(() => new GreetingActor());
    var greeter = Actor.Spawn(props);
    greeter.Tell(new Greet("Hello World"));
    
    // to stop the console closing 
    // before the message is received
    Console.ReadLine();
    

    This differs from Akka.net in the way we create the greeter but it’s the same number of lines of code and equally simple.

So in the code above we create the Greet class for our message type (in essence) and obviously the GreetingActor listens for Greet messages. In the Main method we create a Props instance from the Actor system using FromProducer (which acts as a factory type pattern) then using the Actor.Spawn we actually create an instance of each actor we want in our system.

The Tell line in the Main method is the same as Akka.net, in that we send a message to the greeter Actor via the Tell method and at some point the GreatingActor will receive this message and write it’s text to the Console and that’s it.

Using NBench for performance testing

Introduction

NBench is a performance testing framework which we can run from our unit tests to profile method performance and (hopefully) ensure any refactoring or other changes will highlight possible performance issues instantly (well at least when the unit tests are run which after all should be on every check-in).

So what we want to do is write some performance based unit test around a method, possibly the method is currently slow and we want to refactor it or it’s a critical point where performance must exceed a certain level, i.e. the method call must complete in less than n ms.

Note: Libraries such as NUnit already have a capability for profiling the amount of time the test takes to complete, but NBench offers this and a lot more besides.

We can write a performance test around our code which will fail if the method takes longer than expected to complete.

NBench is much more than just a stopwatch/timer though. We can benchmark memory usage, GC’s and counters.

Getting Started

My current priority is classic performance testing, i.e. how fast is this method. So let’s start by writing some code and some tests using NBench for this and see how things fit together.

  • Create a Class Library project
  • Add the Nuget package – i.e. Install-Package NBench
  • From the Package Manager Console, also run Install-Package NBench.Runner

Note: NBench.Runner is a simple command line runner, which we’ll use initially to test our code.

Let’s create a “Simple” Cache class to run our tests on.

public class SimpleCache<T>
{
   private readonly List<T> cache = new List<T>();

   public void Add(T item)
   {
      if(!Contains(item))
         cache.Add(item);
   }

   public bool Contains(T item)
   {
      return cache.Contains(item);
   }
}

Next, let’s write our first NBench performance test, here’s the code we’ll test, which is not an optimal solution to the requirements of writing a cache.

public class CacheTest
{
    private SimpleCache<string> cache = new SimpleCache<string>();

    [PerfBenchmark(NumberOfIterations = 1, 
       RunMode = RunMode.Throughput, 
       TestMode = TestMode.Test, 
       SkipWarmups = true)]
    [ElapsedTimeAssertion(MaxTimeMilliseconds = 2000)]
    public void Add_Benchmark_Performance()
    {
       for (var i = 0; i < 100000; i++)
       {
          cache.Add(i.ToString());
       }
    }
}

We need to mark our test with the PerfBenchmark attribute. This in itself doesn’t measure anything, it’s more about telling the runner what to do with the method it’s annotating. So we need to declare some measurements. We’re only currently interested in the elapsed time of the method under test, so we’re using the ElapsedTimeAssertionAttribute and stating that our method should take no longer than 2000 ms to complete.

We can run multiple iterations of the method and the result is the average of the runs. This is especially useful if we’re trying to look at GC’s etc. but for this example we’re just going to run the test once.

The use of TestMode.Test will work like a unit tests, i.e. PASS/FAIL, for information on the other attribute properties, see the NBench github page.

Upon running this code using the NBench.Runner.exe, I get a FAIL (as I expected) this method is a lot slower than I expect it to be with this number of items being added.

So let’s leave the test as it is an see if we can refactor the code. Here’s a quick an dirty version of the cache using a Dictionary

public class SimpleCache<T>
{
   private readonly Dictionary<T, T> cache = new Dictionary<T, T>();

   public void Add(T item)
   {
      if (!Contains(item))
         cache.Add(item, item);
   }

   public bool Contains(T item)
   {
      return cache.ContainsKey(item);
    }
}

Now when I run the test with the TestRunner, I get a PASS (well we would expect this implementation to be massively faster that the linear search list version!).

Integration with our build server

Obviously we run a build/continuous integration server, so we want to integrate these tests into our builds. Now it may be that you can use the NBench runner within your build, but (as mentioned in a previous post) there’s already a way to achieve this integration with the likes on NUnit (see NBench Performance Testing – NUnit and ReSharper Integration).

I’ve recreated the code show in the aforementioned blog post here, for completeness

public abstract class PerformanceTestSuite<T>
{
   [TestCaseSource(nameof(Benchmarks))]
   public void PerformanceTests(Benchmark benchmark)
   {
      Benchmark.PrepareForRun();
      benchmark.Run();
      benchmark.Finish();
    }

    public static IEnumerable Benchmarks()
    {
      var discovery = new ReflectionDiscovery(
         new ActionBenchmarkOutput(report => { }, results =>
         {
            foreach (var assertion in results.AssertionResults)
            {
                Assert.True(assertion.Passed, 
                    results.BenchmarkName + " " + assertion.Message);
                Console.WriteLine(assertion.Message);
            }
      }));

      var benchmarks = discovery.FindBenchmarks(typeof(T)).ToList();

      foreach (var benchmark in benchmarks)
      {
         var name = benchmark.BenchmarkName.Split('+')[1];
         yield return new TestCaseData(benchmark).SetName(name);
      }
   }
}

Now simple derive out test from PerformanceTestSuite, like this

public class CacheTest : PerformanceTestSuite<CacheTest>
{
   // our code
}

Benchmarking GC collections

What if we want to look at measuring the method in terms of garbage collection and it’s possible affect on your code’s performance. NBench inclues the GCTotalAssertAttribute. Just add the following to the previous method

[GcTotalAssertion(GcMetric.TotalCollections, 
   GcGeneration.Gen0, MustBe.ExactlyEqualTo, 0.0d)]
public void Add_Benchmark_Performance()
{
    // our code
}

This, as one might expect, causes a failure on my test as it’s expecting ZERO Gen 0 collections. With this FAIL information we can now update our test to something more realistic or look at whether we can alter our code to pass the test (obviously this is less likely for a caching class).

Pre and Post benchmarking code

We have the equivalent of a setup/teardown attributes. A PerfSetupAttribute marked method is run before the benchmarking tests, this is useful for setting up the counters or the likes used within the tests and a PerCleanupAttribute is used on a method to clean up any code, post test.

Available Assertions

In the current release of NBench we have the following assertions

  • MemoryAssertionAttribute – asserts based upon the memory allocated
  • GcTotalAssertionAttribute – asserts based upon total GC’s
  • ElapsedTimeAssertionAttribute – asserts based upon the amount of time a method takes
  • CounterTotalAssertionAttribute – asserts based upon counter collection
  • GcThroughputAssertionAttribute – asserts based upon GC throughput (i.e. average time)
  • CounterThroughputAssertionAttribute – asserts based upon counter throughput (i.e. average time)
  • PerformanceCounterTotalAssertionAttribute – asserts based upon total average performance counter values
  • PerformanceCounterTotalAssertionAttribute – asserts based upon throughput of performance counters

Akka Remoting

In this post I’ll be covering pretty much the same as the Akka.net Remoting page. So I would definitely suggest you read that instead or in conjunction with this post.

As Akka.net has been designed for distributed systems and because (as you’ll have seen from my previous post on Akka.net) you interact with Actor objects via messages. Distributing your Actors should be pretty simple and painless. Let’s see if that holds true.

Initially we’re going to simply create two console applications. Let’s start off by thinking of one as the AkkaServer and the other the AkkaClient (although conceptually, in many ways, the idea of a server and client are meaningless in such an application as they’re really just “peers”).

Let’s write some code

  • Both projects are going to be compiled in .NET 4.6, so go ahead a create two console applications, name the first AkkaServer and the second AkkaClient.
  • Next up, add the Nuget Packages for Akka and Akka.Remote to both projects.
  • We could now create a third solution for our shared types, but let’s just add a new project to the AkkaServer, mine’s named Shared, you’ll need to add the Akka Nuget package to this project also.
  • In the Shared project, add the GreetingActor (as outlined previously and in the Akka.net documentation, here it is for completeness
    public class Greet
    {
       public Greet(string who)
       {
          Who = who;
       }
    
       public string Who { get; private set; }
    }
    
    public class GreetingActor : ReceiveActor
    {
       public GreetingActor()
       {
          Receive<Greet>(greet =>
             Console.WriteLine("{0} Greeting {1}",
             Thread.CurrentThread.ManagedThreadId, 
             greet.Who));
       }
    }
    
  • Once built, add the Shared.dll as a reference to your AkkaClient, so you’ve got access to the same type of GreetingActor etc.
  • In the AkkaServer Main method simply place the following
    var config = ConfigurationFactory.ParseString(@"
    akka {
        actor {
            provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
        }
    
        remote {
            helios.tcp {
                port = 8080
                hostname = localhost
            }
        }
    }");
    
    using (var system = ActorSystem.Create("MyServer", config))
    {
       system.ActorOf<GreetingActor>("greeter");
       Console.ReadKey();
    }
    

    This code is taken from Remoting as is the next piece of code for the client

  • Now in the AkkaClient Main method place the following
    var config = ConfigurationFactory.ParseString(@"
    akka {
        actor {
            provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
        }
        remote {
            helios.tcp {
                port = 8090
                hostname = localhost
            }
        }
    }");
    
    using (var system = ActorSystem.Create("MyClient", config))
    {
       var greeter = system.ActorSelection(
          "akka.tcp://MyServer@localhost:8080/user/greeter");
    
       greeter.Tell(new Greet("Roger"));
    
       Console.ReadLine();
    }
    

Run the server and then the client and you should see (in the server console window) the Greeting Roger text.

What have we just done?

So as you can see, we’re using the ConfigurationFactory.ParseString to simply create our remoting configuration in both the client and server. For this example, both applications are expected to be available on the localhost and therefore require different ports to communicate through.

We then create our ActorSystem in each application, for the sake of this example, one is perceived as the server and one as the client, but the beauty of Akka.net is they can be deployed in a peer-to-peer manner (which we’ll look at also).

Our AkkaServer creates an instance of the GreetingActor and then waits for messages. The AkkaClient uses the ActorSelection method to locate the server Actor (or a known name greeter. Although ofcourse we could just find all Actors if we wished) and then via the Tell method sends a messages to the Actor running on the server.

Let’s move towards a Peer-to-Peer design

Time to create the classic peer-to-peer chat application. This is going to be very basic and built using the previous code. The only changes to the two solutions are in the Main methods. Keep the config code the same as it was, but in the server replace the existing code with

using (var system = ActorSystem.Create("MyServer", config))
{
   system.ActorOf<GreetingActor>("greeter");

   string msg;
   while (!String.IsNullOrEmpty(msg = Console.ReadLine()))
   {
      var greeter = system.ActorSelection(
          "akka.tcp://MyClient@localhost:8090/user/greeter");

      greeter.Tell(new Greet(msg));
   }
}

and in the client, the code is exactly the same except MyServer becomes MyClient and the akka.tcp line changes to akka.tcp://MyServer@localhost:8080/user/greeter. For completeness here’s the code in full anyway

using (var system = ActorSystem.Create("MyClient", config))
{
   system.ActorOf<GreetingActor>("greeter");

   string msg;
   while (!String.IsNullOrEmpty(msg = Console.ReadLine()))
   {
      var greeter = system.ActorSelection(
         "akka.tcp://MyServer@localhost:8080/user/greeter");

      greeter.Tell(new Greet(msg));
   }
}

If you run up both solutions, both will create their own greeter Actor and only upon receiving some input via Console.ReadLine, will try to connect to all greeter Actors on to other’s ActorSystem (i.e. server will try to send to client and vice versa).

All this is happening via TCP and hence we could just as easily move one of the applications onto another machine – as long as both are accessible to one another, they should seamlessly work.

So there you have it, a very basic introduction to peer to peer Akka.net objects.