Wednesday, May 27, 2015

JBoss FSW Connect ActiveMQ Using ActiveMQ Resource Adapter

Introduction

In order to use external ActiveMQ as message broker, we have install and configure ActiveMQ resource adapter. The resource adapters are the plug-ins for JEE containers. They facilitate the communicates between JEE container and external brokers, databases, etc.

In this post, I am going to demonstrate in details about how to setup and test the ActiveMQ resource adapter. I use my local environment to setup SSL connection to my local ActiveMQ instance.

Install ActiveMQ Resource Adaptoer activemq-rar.rar

Download activemq-rar

activemq-rar (version 5.11.1) file is available at http://mvnrepository.com/artifact/org.apache.activemq/activemq-rar/5.11.1. If you need older version, you can brower the maven repo, and download it accordingly.

Install activemq-rar

  • copy activemq-rar-5.11.1.rar to $JBOSS_FSW_HOME/standalone/deployments
  • mv activemq-rar-5.11.1.rar activemq-rar.rar

Modify JBoss FSW Configuration Files

Here is configuration change on standalone.xml. If you use standalone-full.xml or standalone-fule-ha.xml, do the same.

        
            
                
                    
                        activemq-rar.rar 
                    
                    NoTransaction
                    
                        admin 
                    
                    
                        admin
                    
                    
                        ssl://localhost:61617?jms.rmIdFromConnectionId=true
                    
                    
                        
                            
                                false
                            
                            
                                
                            
                        
                    
                    
                        
                            
                                ServiceGaryQueue
                            
                        
                        
                            
                                ServiceGaryTopic
                            
                        
                    
                
            
        

Another section needs to change is the following:

            
                
                
            

Import ActiveMQ Public Keystore

If you use tcp, there is no need to import certs. However in the enterprise application, nio+ssl is preferred. Thus, we need to perform the following step:

   sudo keytool -import -alias Guojiangs-MacBook-Pro.local \
      -file Guojiangs-MacBook-Pro.local_cert \
      -keystore /Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/security/cacerts 

Where Guojiangs-MacBook-Pro.local_cert is public key for the activemq. For how to setup SSL for ActiveMQ, you can refer my blogs: http://ggl-consulting.blogspot.com/2015/03/broker-to-broker-network-connector-with.html

Test The Configuration

First start JBoss FSW without start ActiveMQ. In such a way, we can see the features of automatic reconnection from JBoss FSW.

cd $JBOSS_FSW_HOME/bin
./standalone.sh
12:22:23,724 ERROR [org.apache.activemq.ra.ActiveMQEndpointWorker] (default-threads - 2) Failed to connect to broker [ssl://localhost:61617?jms.rmIdFromConnectionId=true]: Could not connect to broker URL: ssl://localhost:61617. Reason: java.net.ConnectException: Connection refused: javax.jms.JMSException: Could not connect to broker URL: ssl://localhost:61617. Reason: java.net.ConnectException: Connection refused
	at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:360) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:253) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.ra.ActiveMQResourceAdapter.makeConnection(ActiveMQResourceAdapter.java:136) [activemq-ra-5.11.1.jar:5.11.1]
	at org.apache.activemq.ra.ActiveMQEndpointWorker$1.run(ActiveMQEndpointWorker.java:109) [activemq-ra-5.11.1.jar:5.11.1]
	at org.jboss.jca.core.workmanager.WorkWrapper.run(WorkWrapper.java:218) [ironjacamar-core-impl-1.0.19.Final-redhat-2.jar:1.0.19.Final-redhat-2]
	at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33)
	at org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:806)
	at org.jboss.threads.QueueExecutor.access$100(QueueExecutor.java:45)
	at org.jboss.threads.QueueExecutor$Worker.run(QueueExecutor.java:826)
	at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_75]
	at org.jboss.threads.JBossThread.run(JBossThread.java:122)
Caused by: java.net.ConnectException: Connection refused
	at java.net.PlainSocketImpl.socketConnect(Native Method) [rt.jar:1.7.0_75]
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) [rt.jar:1.7.0_75]
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) [rt.jar:1.7.0_75]
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) [rt.jar:1.7.0_75]
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) [rt.jar:1.7.0_75]
	at java.net.Socket.connect(Socket.java:579) [rt.jar:1.7.0_75]
	at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:625) [jsse.jar:1.7.0_75]
	at org.apache.activemq.transport.tcp.TcpTransport.connect(TcpTransport.java:501) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.transport.tcp.TcpTransport.doStart(TcpTransport.java:464) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.util.ServiceSupport.start(ServiceSupport.java:55) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.transport.AbstractInactivityMonitor.start(AbstractInactivityMonitor.java:138) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.transport.WireFormatNegotiator.start(WireFormatNegotiator.java:72) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58) [activemq-client-5.11.1.jar:5.11.1]
	at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:340) [activemq-client-5.11.1.jar:5.11.1]
	... 10 more

12:22:23,726 ERROR [org.apache.activemq.ra.ActiveMQEndpointWorker] (default-threads - 1) Endpoint will try to reconnect to the JMS broker in 30 seconds
12:22:23,727 ERROR [org.apache.activemq.ra.ActiveMQEndpointWorker] (default-threads - 2) Endpoint will try to reconnect to the JMS broker in 30 seconds

Now start the activemq broker. After about 30 seconds, you should see something like this:

12:23:23,806 INFO  [org.apache.activemq.ra.ActiveMQEndpointWorker] (default-threads - 1) Successfully established connection to broker [ssl://localhost:61617?jms.rmIdFromConnectionId=true]
12:23:23,813 INFO  [org.apache.activemq.ra.ActiveMQEndpointWorker] (default-threads - 2) Successfully established connection to broker [ssl://localhost:61617?jms.rmIdFromConnectionId=true]

This means the connection between JBoss FSW and ActiveMQ is established. To prove this, we can issue the following commands:

Gary2013@Guojiangs-MacBook-Pro:~/jFSW/6.1/jboss-eap-6.1/standalone$ lsof -iTCP -P | egrep 61617 | egrep ESTAB
java      10669 Gary2013 1063u  IPv4 0x9b93e9761ab85c83      0t0  TCP localhost:55666->localhost:61617 (ESTABLISHED)
java      10669 Gary2013 1064u  IPv4 0x9b93e976184e1fc3      0t0  TCP localhost:55667->localhost:61617 (ESTABLISHED)
java      10777 Gary2013  149u  IPv6 0x9b93e976130931b3      0t0  TCP localhost:61617->localhost:55666 (ESTABLISHED)
java      10777 Gary2013  159u  IPv6 0x9b93e97613092cb3      0t0  TCP localhost:61617->localhost:55667 (ESTABLISHED)
Gary2013@Guojiangs-MacBook-Pro:~/jFSW/6.1/jboss-eap-6.1/standalone$ 

Now, we can check the JNDI name from the JBoss FSW console. Here is what I see:

References

Redhat References

Tuesday, May 19, 2015

JBoss FSW Switchyard Tutorial 3: SOAP Binding

Introduction

This is my third tutorial on Switchyard Binding. So far, I have covered, SCA, REST, and SOAP bindings. The use cases for this is to retrieve Person information using SOAP web service

The source code is available at github: https://github.com/garyliu1119/Switchyard-Tutorial/tree/master/switchyard-soap-binding-demo

The live demo is available at youtube: https://www.youtube.com/watch?v=v4EZtzUZMJA

Wednesday, May 13, 2015

JBoss FSW Switchyard Tutorial 2: REST Binding

Introduction

The source code for this tutorial is available at: https://github.com/garyliu1119/Switchyard-Tutorial/tree/master/switchyard-rest-demo-one

The video demo for this blog is available at youtube here now.

In my previous tutorial, I have covered the basics about Switchyard design, using the example of creating a Hello World Service. The link is available here:

The main purpose of this article is to document the basic procedures of the creation of a REST binding for Switchyard application. The 1.1 implementation still has some bugs. There are still quite some room for improvement in terms of simplicity and intuitiveness.

Create Order Service

Step One: Create Project

New --> Switchyard Project.
Project name: switchyard-rest, Next
Fill the form like the following:
click Finish

A new Switchyard project will be created. However, there is problem with pom.xml. This is a know bug for the version 1.1.1-p5-redhard-1. The workaround is to add a parent segment. Here is the complete pom.xml content:



  4.0.0
  
    org.switchyard
    switchyard-parent
    1.1.1-p5-redhat-1
  
  
  com.ggl.switchyard
  switchyard-rest
  com.ggl.switchyard:switchyard-rest
  
    1.1.1-p5-redhat-1
    1.7
    1.7
  
  
    
      org.switchyard.components
      switchyard-component-resteasy
    
    
      org.switchyard.components
      switchyard-component-soap
    
    
      org.switchyard
      switchyard-api
    
    
      org.switchyard
      switchyard-transform
    
    
      org.switchyard
      switchyard-validate
      ${switchyard.version}
    
    
      org.switchyard
      switchyard-test
      test
    
    
      org.switchyard.components
      switchyard-component-test-mixin-cdi
      test
    
  
  
    
      
        org.switchyard
        switchyard-plugin
        
          
            
              configure
            
          
        
        
          
            org.switchyard.transform.config.model.TransformSwitchYardScanner
          
        
      
    
  


This is pretty nasty work around. Your project version has to be the same as the switchyard version. As I know this is fixed in the newer version of switchyard. I will verify that soon.

We need to update the maven project as the pom.xml file is modified [using Option-F5 in MacOS].

Create OrderService

This is the same as my previous HelloWorld service, exception the interface name is OrderService and the bean name is OrderServiceImpl.

Create REST Binding

Switchyard for REST service require a resource file, which is an interface definition. In my case, I have defined as the following:

package com.ggl.switchyard.switchyard_rest_demo;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

@Path("/order")
public interface OrderResource {

    @POST
    @Path("/")
    @Produces({"text/xml"})
    public Order newOrder();

    @GET
    @Path("{orderId}")
    @Produces({"text/xml"})
    public Order getOrder(@PathParam("orderId") Long orderId);

}

This interface must be the same as the implementation service interface. In this tutorial, I have defined the OrderService as the following:

public interface OrderService {
 public Order newOrder (Order order);
 public Order getOrder (Long orderId);
}

As you can see that the signature is the same if you remove the annotations from the resource interface. This seems a bit awkward. To me there should be an implementation for the REST service explicitly, like in Spring MVC, of Apache CXF

Summary

Thursday, May 7, 2015

JBoss FSW Switchyard Tutorial 1: HelloWorld

Introduction

The video version is available at: https://youtu.be/FShVH3GM2Hs
The video for the blog is availabe at youtube now.

In my earlier blog, I have documented how to setup JBoss FSW development environment using JBoss Developer studio 7.1. The blog can be refered at http://ggl-consulting.blogspot.com/2014/10/build-deploy-test-and-debug-jboss-fuse.html

The purpose of this blog is to demonstrate the development process of switchyard application using JBoss Developer Studio 8.1. I will create a Hello World application from scratch, deploy it, and test it. Thus, people can learn the stuff in a ground-up style.

Now, JBDS 8.1 is available. The setup procedure is the same. Make update the Integration Stack from the Software/Update panel in the JBoss Central page as shown below

Procedures To Build The Project

Create Project

Create New Switchyard Project:
Give the project name and Click Next:
Configure the SwitchYard component:
Click Finish. You will see the following:
Drag the Bean Implementation from the Pallet to the Canvas. Fill the HelloWorldBean and HellowWorldService, click finish on both:
Modify the HelloWorldService.java like the following:
package switchyard_helloworld_demo;

public interface HelloWorldService {
 public String sayHello( String name);
}

Modify the HelloWorldServiceBean.java as the following:
package switchyard_helloworld_demo;

import org.switchyard.component.bean.Service;

@Service(HelloWorldService.class)
public class HelloWorldServiceBean implements HelloWorldService {

 @Override
 public String sayHello(String name) {
  
  return "Hello " + name + "!";
 }

}
Now the JBDS looks like this:
Promote The Service:
Click Finish in the new Promote service panel and you will see this:
Bind to SCA:
At this time, we are done with the HelloWorldService.

Test The HelloWorld Service

Now we need to create a test class as the following:
package com.ggl.switchyard_helloworld_demo;

import static java.lang.System.out;
import javax.xml.namespace.QName;

import org.switchyard.remote.RemoteInvoker;
import org.switchyard.remote.RemoteMessage;
import org.switchyard.remote.http.HttpInvoker;

/**
 * Test client which uses RemoteInvoker to invoke a service with an SCA binding.
 */
public final class RemoteClient {

    private static final QName SERVICE = new QName(
            "urn:com.ggl.switchyard_helloworld_demo.HelloWorldService:switchyard-helloworld-demo:1.0",
            "HelloWorldService");
    private static final String URL = "http://localhost:8080/switchyard-remote";

    /**
     * Private no-args constructor.
     */
    private RemoteClient() {
    }

    /**
     * Only execution point for this application.
     * @param ignored not used.
     * @throws Exception if something goes wrong.
     */
    public static void main(final String[] ignored) throws Exception {
        // Create a new remote client invoker
        RemoteInvoker invoker = new HttpInvoker(URL);


        RemoteMessage message = new RemoteMessage();
        message.setService(SERVICE).setOperation("sayHello").setContent("My Dear Earth");

        // Invoke the service
        RemoteMessage reply = invoker.invoke(message);
        if (reply.isFault()) {
            System.err.println("Oops ... something bad happened.  "
                    + reply.getContent());
        } else {
            String greeting = (String) reply.getContent();
            out.println("==================================");
            out.println("Got reply from HelloWorld Service: " + greeting);
            out.println("==================================");
        }
    }


}

Deploy the service and start the runtime. You can right click the the RemoteClient.java and run as java application. You should see the following:
log4j:WARN Continuable parsing error 2 and column 69
log4j:WARN Document root element "log4j:configuration", must match DOCTYPE root "null".
log4j:WARN Continuable parsing error 2 and column 69
log4j:WARN Document is invalid: no grammar found.
==================================
Got reply from HelloWorld Service: Hello My Dear Earth!
==================================

Monday, May 4, 2015

JBoss Switchyard Application pom.xml Fix

The Issue

When you import switchyard application from JBoss quickstart project, you may see the Jboss Devveloper Studio [JBDS] complain about the execution task. This is a well know problem.

The Solution

To fix this problem, simple put the following code to the pom.xml before the end of build tag like the following:
               
                        
                            
                                org.eclipse.m2e
                                lifecycle-mapping
                                1.0.0
                                
                                    
                                        
                                            
                                                
                                                                org.switchyard
                                                                switchyard-plugin
                                                    [1.0.0,)
                                                    
                                                        configure
                                                    
                                                
                                                
                                                    
                                                
                                            
                                        
                                    
                                
                            
                           
                
        
        
    

Make sure update the maven project

Friday, May 1, 2015

Solution For The Failure Of Mule Project Build With Maven

The Issue

If you build a Mule project in the Anypoint Studio, you can run the project with the Studio, and everything works fine. However, if you try to build using mvn clean install from shell console, the compilation will fail. Here is the message:

[ERROR] Failed to execute goal on project http-jms: Could not resolve dependencies for project com.ggl.mule.jms:http-jms:mule:1.0.0-SNAPSHOT: The following artifacts could not be resolved: com.ibm.icu:icu4j-normalizer_transliterator:jar:4.8.1.1, com.googlecode.sardine:sardine:jar:248: Failure to find com.ibm.icu:icu4j-normalizer_transliterator:jar:4.8.1.1 in http://maven.repository.redhat.com/techpreview/all/ was cached in the local repository, resolution will not be reattempted until the update interval of redhat-techpreview-all-repository has elapsed or updates are forced -> [Help 1]

The Solution

You may attempt to modify the pom.xml and add the following dependence:


 com.ibm.icu
 icu4j
 4.8.1.1

This is not the sulution, because if later on, Mule change the version of the dependency, you will have to update for this again. The solution I found is to add the following repository to the pom.xml file:

        
            confluex
            confluex-public
            http://dev.confluex.com/nexus/content/groups/public
            default