Implementation of workflow web services

From SIMSTADT
Jump to: navigation, search

SimStadt workflows can be published as web services. But first you have to implement the actual web service. Web services can come in different flavours. We will tackle SOAP services in this article. Once you have implemented your web service you can publish it by implementing the "web service publisher" interface. This interface is located at "eu.simstadt.webservices.WebServicePublisher" of the "HierarchicWorkflow" project. It is a service provider interface.

Besides the WebServicePublisher interface, "eu.simstadt.webservices" also offers a web service launcher class with the purpose to search for web service publisher implementations on its classpath and publishing them automatically. The project can be distributed and deployed on a Windows or Linux server.

[edit] Steps to implement and publish a web service

It is assumed that the workflow to be published exists already. For the sake of simplicity it is also assumed the workflow is called "ABC". Please replace "ABC" with the actual name of your workflow.

  1. Create a new Java project called "ABCWebService".
  2. The new project "ABCWebService" has to reference your workflow project and the project "HierarchicWorkflow" which holds the web service publisher interface.
  3. Create a new package named "de.hftstuttgart.abc".
  4. For the time being, implement the WebServicePublisher interface in the package as a stub like this:
    public class ABCOperationsPublisher implements WebServicePublisher
    {	
      @Override
      public String getWorkflowName() {
        return "My fake workflow";
      }
      @Override
      public void publish() {
        System.out.println(String.format("{0} has been published as a web service.", getWorkflowName()));
      }
    }
    
  5. Create and run a simple JUnit test in the project. We will flesh out this thing later.
    @Test
    public void testWorkflowOperation() {
      (new WorkflowOperationsPublisher()).publish();
    }
    
  6. Create a folder named "META-INF/services" in the "src" folder of your project. Inside this folder create a plain text file containing a line like this:
    de.hftstuttgart.abc.ABCOperationsPublisher
    

    This line signals all referencing applications that your project implements the service provider interface.

  7. In Eclipse create a Java application run configuration for the project "ABCWebService". Entry point of the Java application is the "eu.simstadt.webservices.Launcher" class. The Java application has to detect the new web service publisher implementation at runtime. For this reason, add your project to the classpath of the run configuration.
  8. Run the newly created configuration. You should see the following output on the console:
    Nov 19, 2015 10:29:45 AM eu.simstadt.webservices.Launcher main
    INFO: My fake workflow has been deployed as a web service.
    
  9. Now the actual web service can be implemented. In this tutorial we will create a SOAP web service. A SOAP flavoured web service can be created in two steps: (a) Web service interface definition and (b) implementation of the web service interface.

    Create a web service interface:

    @WebService(name = "ABCOperations", targetNamespace = "http://localhost:9999/abc_ops")
    @SOAPBinding(style = SOAPBinding.Style.RPC)
    public interface ABCOperations
    {
      @WebMethod
      @WebResult(partName = "return")
      public double simulateSomething(String gmlId);
    }
    

    Implement the web service interface:

    @WebService(endpointInterface = "de.hftstuttgart.abc.ABCOperations")
    public class ABCOperationsImpl implements ABCOperations
    {
      @Override
      public double simulateSomething(String gmlId) {
        // Call your workflow here. For a working example of an operational web service using the
        // monthly energy balance workflow please check out the project "MonthlyEnergyBalanceWebService"
        // from the repository.
        return 1.0;
      }
    }
    

    If you want to or have to throw an exception in your implementation, then throw a WebServiceException.

  10. Come back to your JUnit test, flesh it out and test your web service like this:
    @Test
    public void testWorkflowOperation() {
      Endpoint.publish("http://localhost:9999/wfops", new ABCOperationsImpl(provider));
      URL url = new URL("http://localhost:9999/wfops?wsdl");
      QName qname = new QName("http://energy.simstadtworkflows.hftstuttgart.de/", 
          "ABCOperationsImplService");
      Service service = Service.create(url, qname);
      ABCOperations abcOps = service.getPort(ABCOperations.class);
      assertEquals(1.0, abcOps.simulateSomething("_1"), 0.0);
    }
      
  11. Lets come back to the ABCOperationsPublisher. Now that you implemented and tested the actual SOAP web service, use it in your publish method by publishing an end point:
    public class ABCOperationsPublisher implements WebServicePublisher
    {	
      @Override
      public String getWorkflowName() {
        return "My fake workflow";
      }
    	
      @Override
      public void publish() {
        System.out.println(String.format("{0} has been published as a web service.", getWorkflowName()));
        Endpoint.publish("http://localhost:9999/abc_ops", new ABCOperationsImpl());
      }
    }
    
  12. Execute the previously created run configuration for the "SimStadtWebServices" project. Now clients who implement your web service publisher interface can call your web service.

[edit] Already implemented web services

Check out the project "MonthlyEnergyBalanceWebService" from the kepler repository to see a working example for a SOAP web service.

[edit] Deployment

To create releases of your web services execute the ANT deploy script like this:

<project default="deploy" name="Deploy SimStadt web services" basedir="..">
	<property name="deploy.dir.path" location="${user.home}/Desktop/SimStadt" />
	<property name="target.path" value="webservices/simstadt-webservices" />
	<property name="projects" value="MonthlyEnergyBalanceWebService" />
	<import file="../SimStadt/deploy-common.xml" />
	<target name="deploy" depends="deploy-common">
		<!-- Create batch scripts -->
		<echo file="${deploy.dir}/SimStadtWebServices.bat">
java -d64 -classpath *;lib/*;workflows/*;webservices/* -Xms512m -Xmx2g eu.simstadt.webservices.Launcher
pause > nul
		</echo>	
		<echo file="${deploy.dir}/SimStadtWebServices.sh">
java -d64 -classpath './*:.:lib/*:workflows/*:webservices/*' -Xms512m -Xmx2g eu.simstadt.webservices.Launcher
		</echo>
		<chmod file="${deploy.dir}/SimStadtWebServices.sh" perm="u+x"/>	<!-- no effect if script runs under windows -->
	</target>
</project>
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox