Tuesday, December 22, 2015

Grant A Group Users Sudo Access

Useful Linux Commands

Grant A Group Users Sudo Access

  • vi /etc/sudoers
  • copy / paste the line with #%wheel
  • Change the wheel with your user group, say, mule is a user group in my case

Wednesday, October 28, 2015

How Send Cookie Using Postman or Curl

Using Curl

Here is an simple example about to send json message with a cookie.
curl -X POST 
-d @input2.json 
--cookie "portalOpenSSOToken=sso-token-1" 
--header "Content-Type: application/json"  
http://localhost:8080/caweb/api/seatRevenueByAgency 

Using Postman

To use postman, we need to install inteceptor. Then you need to turn on the interceptor as shown in the following feature.

Monday, August 31, 2015

Mule Application Development Using MySQL and ActiveMQ Connectors

Introduction

In this blog, I am going to explain how to use Mule ESB to perform integration with database and messaging brokers. I use MySQL as database engine and ActiveMQ as message broker.
The youtube video now available at https://www.youtube.com/watch?v=DAsFv045nlw&feature=youtu.be






Here is the use case:
  1. A user sends HTTP GET request to retrieve customer information based on company name
  2. A Mule flow will retrieve all the records from database table named Customer
  3. Send each record to JMS Queue
  4. Return use the counter of total records
  5. handle exceptions

Infrastructure Setup

In order achieve this, we need to setup MySQL database. Also we need to setup ActiveMQ.

Setup MySQL

Here is the procedures to setup MySQL on MacBook Pro:
  • Down load MySQL dmg
  • Install it
  • Start the mysqld by run: sudo $MYSQL_INSTALLATION/mysql/support-files/mysql.server start
After start MySQL server, you need to do the following:
$mysql -u root

mysql> create user 'mule'@'localhost' identified by 'mule';

mysql> create database dataformule;

$mysql -u mule -p dataformule

mysql> grant all privileges on * . * to 'mule'@'localhost';

mysql> show databases;

mysql> select user from mysql.user;

mysql -u mule -p dataformule
use dataformule;
show tables;

create table Customer (
     id INT NOT NULL AUTO_INCREMENT,
     company_name char(30) NOT NULL,
     contact_name char (30) NOT NULL,
     phone char(30),
     company_address char(30),
     PRIMARY KEY (id)
);

mysql> desc Customer;
+-----------------+----------+------+-----+---------+----------------+
| Field           | Type     | Null | Key | Default | Extra          |
+-----------------+----------+------+-----+---------+----------------+
| id              | int(11)  | NO   | PRI | NULL    | auto_increment |
| company_name    | char(30) | NO   |     | NULL    |                |
| contact_name    | char(30) | NO   |     | NULL    |                |
| phone           | char(30) | YES  |     | NULL    |                |
| company_address | char(30) | YES  |     | NULL    |                |
+-----------------+----------+------+-----+---------+----------------+
5 rows in set (0.01 sec)



select * from dataformule.Customer;

INSERT INTO dataformule.Customer (id, company_name, contact_name, phone, company_address) VALUES (102, 'Company_B', 'Contact_B', '999-888-7778', 'Address_B');
INSERT INTO dataformule.Customer (id, company_name, contact_name, phone, company_address) VALUES (103, 'Company_C', 'Contact_C', '999-888-7779', 'Address_C');
INSERT INTO dataformule.Customer (id, company_name, contact_name, phone, company_address) VALUES (104, 'Company_D', 'Contact_D', '999-888-7781', 'Address_D');
INSERT INTO dataformule.Customer (id, company_name, contact_name, phone, company_address) VALUES (105, 'Company_E', 'Contact_E', '999-888-7782', 'Address_E');


mysql> select * from customer;
+-----+--------------+--------------+--------------+-----------------+
| id  | company_name | contact_name | phone        | company_address |
+-----+--------------+--------------+--------------+-----------------+
| 102 | Company_B    | Contact_B    | 999-888-7778 | Address_B       |
| 103 | Company_C    | Contact_C    | 999-888-7779 | Address_C       |
| 104 | Company_D    | Contact_D    | 999-888-7781 | Address_D       |
| 105 | Company_E    | Contact_E    | 999-888-7782 | Address_E       |
+-----+--------------+--------------+--------------+-----------------+
4 rows in set (0.01 sec)

For setup ActiveMQ with SSL, you may search my previous blog. I have documented in details about the set up

The Code

The complete code is available at GitHub at:
https://github.com/garyliu1119/Mule-Development/tree/master/ActiveMQ-Messaging
The mule flow code list as the following:

    
    
        
    
    
    
    
        <![CDATA[SELECT * FROM Customer WHERE company_name = :companyName;]]>
        
    
    
        <![CDATA[SELECT * FROM CUSTOMER WHERE phone = :phoneNumber;]]>
        
    
    
        
        
            
                
            
            
                
            
            
                
                    <![CDATA[throw new IllegalArgumentException('Paramenter Not Acceptable')]]>
                
            
        
        
        
        
        
        
            
                
                
            
            
                
                
            
            
                
                
            
        
    
    
        
            
            
            
            
        
    
    
        
            
            
        
        
        
    
    
        
            
            
        
        
        
    
    
        
        
    


Detailed Explanation

You can view the video for detailed explanation about this application at http://youtu.be/DAsFv045nlw 


How To Stop mysqld

Recently, I find I could not stop the mysqld process on my MacBook Pro. After some research, trial and errors, I found the following command works:

sudo launchctl unload -w /Library/LaunchDaemons/com.oracle.oss.mysql.mysqld.plist 

Tuesday, August 11, 2015

Mule ESB Tutorial: Introduction To DataWeave

Introduction

MuleSoft's DataWeave available only from Anypoint Studio 3.7 since May 2015. It is a new powerful tool for data transformation. Earlier, we use DataMapper, or customer transformer to perform data transformation in addition to the out-of-box transformers, like Byte Array to String, object to JSON, XML to JSON, etc., just to name a few.

With DataWeave, the transformation become much less painful. In particular, if you don't want to write customer transform in java or scripts. Still, if you are good at writing java code, like me, customer transformer still be the best from development point of view. But it may not be the best for the long term maintenance. Once you get to the habits to write write customer transformer, you tend to use it a lot. I think it is time to change with this kind of powerful tool.

In this tutorial, I am going to demonstrate the basics about the DataWeave. Later, I will introduce more complicated cases. I will put this tutorial to Youtube.com. If you prefer to watch the usage in action.

Using Using Data Weave

The flow is like this:

With this configuration, we will use the input of JSON like the follwoing:

{
 "abc":
     {
     "cba":"ddd",
     "ccc":"eee",
     "aaa":["fgh","ghf","hgf"]
     }
}

Put the above file into your local somewhere name it as transform1.json. I strongly recommend a tool named: subline test 2 for edition JSON.

Now create HTTP connector. Everything is the same as simple configuration. Only extra procedure is add Metadata as the following:

Now, we can add Transform Message to the flow. Note that the "Transform Message" which is DataWeave component, it is not a transformer!

Simple Transform Doing Nothing

For the doing nothing case, the transformer will be the following:
%dw 1.0
%input payload application/json
%output application/xml
---
payload

Here is the snapshot of the transform panel:

Now we can test using PostMan with url: http://lcoalhost:8082/transform1. You should see the xml output like the following:



    ddd
    eee
    
        fgh
        ghf
        hgf
    

All above is nothing fancy. Note, the payload in the transform panel. It means doing nothing. The power comes from that panel. All the logics will be input there. We will see in the next section.

Transform From JSON To XML

Now let's change the transform scripts to the following:

%dw 1.0
%input payload application/json
%output application/xml
---
items: {
 name: payload.abc.aaa[1],
 address: payload.abc.cba,
 ID: payload.abc.ccc
}

Now if you run the POST operation, you will get the following result:



    ghf
    
ddd
eee

This is the transformation a bit interesting. Of course, you can do this with data mapper transformer. But I hope you see the power behind it. It opens up the huge possibility in manipulate data for the transformation purpose. I will cover more cases in my later blogs.

Conclusion

I think DataWeave is a powerful tool. It takes time to learn the syntaxes, but I think it worths the time spending if you want to be a good integration architect! You can visit my youtube channel to get dynamics of the DataWeave!

Monday, August 10, 2015

Mule Flow: Setup HTTPS Connector and Setup Content-type

Introduction

The most popular connector probably is HTTP connector. However, for the enterprise application, this is not good enough. We need to setup HTTPS connect. Since Anypoint Studio, previously called Mule Studio, the configuration of HTTPS has been change. In this blog, I am going document the procedures on how to setup the HTTPS connector for the on-premise application, together with few other technical aspects. Here is the flow I have setup:

In this flow, I have few interesting parts. One is about content-based-routing, and the other is how to setup response content-type. In my case, I setup it as applicaiton/json.

Generate Self-signed Keystore

For the self-signed certificates, we can use keytool coming with JDK. First created a directory name something like certs. In my case, it is located at:
/Users/Gary2013/AnypointStudio-3.7/certs
Now inside the certs directory, execute the following command:
keytool -genkey -alias mule-server -keyalg RSA -keystore keystore.jks
That is all you need to do!

Setup HTTPS Connector

The following 2 pictures show where to put the certificates. In order to setup HTTPS connector, we need to configure 2 pages from the Anypoint Studio as shown below:

Setup The Mule Flow

The flow setup is not that complicated. Here I just provide the configuration file. For the details, I will provide a video, you can my youtube video.



 
  
   
   
  
 
 
 
  
  
        
        
            
                
            
            
                
                
            
        
        
            
        
 



From the above xml file, you may see that I have configured a HTTP and HTTPS connectors. The HTTPS configuration can be view in the following xml form:
 
  
   
   
  
 
You may note that the variable"${https.port.onpremise}". This together with other parameters are defined in the file name mule-app.properties.

Test The Flow

I use PostMan to test the flow for GET and POST methods with following URL:

https://localhost:8443/inventory
To test POST method, put the following JSON into the body of the PostMan:
{
  "name": "Barack Obama",
  "phone": "888-555-8888",
  "address": "1600 Pennsylvania Avenue Northwest, Washington, DC 20500",
  "Title" : "US President"
}

You should get the same json back as the following:

{
  "name": "Barack Obama",
  "phone": "888-555-8888",
  "address": "1600 Pennsylvania Avenue Northwest, Washington, DC 20500",
  "Title": "US President"
}
To test GET method, you use the following URL:
https://localhost:8443/inventory?name=Gary Liu Jr.
You should see the following JSON output:
{
  "name": "Gary Liu Jr."
}

Conclusion

This blog explains the basic procedure to configure HTTPS connector together with few other interesting aspects of mule flow, such as, content-base-routing, response content-type setup etc.

Sunday, August 9, 2015

Change Mule Application Logging Level

Introduction

MuleSoft has changed many stuff for the last year. One of the questions developer will ask is how to change the logging level. One might think that he can just create log4j.properties file and set the logging there. Unfortunately, this will not work. We have to create a file name log4j2.xml.

Solution

Put the following file (named as: log4j2.xml) into src/main/resources:


  
    
      
    
  
  
  
  
	
	
    
	
	
    
    
    
    
	
	
    
    
    
    
    
    
   
    
      
    
  

Mule's Anypoint Studio comes with slf4j librarary. You can create your logger like this:

   private static Logger logger = LoggerFactory.getLogger(TransformListOfObjects.class);
After you put the file of log4j2.xml in place as stated above, you can run your application from the Anypoint Studio, you will see debug messages. These message can be very valuable, in particular, to check the parameters set for various connectors.

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
          

Monday, April 20, 2015

Solution for JBoss BPM Suite Maven Build Error

Introduction

This post is a solution for the error of: "package org.kie.api.definition.type does not exist".

If you google the error, you will get this page: https://access.redhat.com/solutions/892893. I could not find the direct solution. Thus I post the solution here

What Is The Issue?

If you work on the JBoss BPM Suite 6.1, you will see that all the source code is in git server, which in build in the JBoss BPM Suite. You can clone the GIT repository by the following commands: [Suppose you have created a git repository of "demo"

git init
git clone git clone git://localhost:9418/demo

After you check out the code from the git repositroy [In my case, I have cloned the code to : ary2013@Guojiangs-MacBook-Pro:~/jBPMS/mygit/. And I have a project, named "Insurance". Now do the following:

/Users/Gary2013/jBPMS/mygit/demo/Insurance
mvn clean install

You will see errors complaining something like:

[ERROR] /Users/Gary2013/jBPMS/mygit/demo/Insurance/src/main/java/com/ggl/insurance/InsuredObject.java:[7,29] package org.kie.api.definition.type does not exist

Fix The Error

To fix the error, you will need to add the following code to the pom.xml file:



  4.0.0
  com.ggl.insurance
  Insurance
  1.0
  kjar
  Insurance
  
    
      guvnor-m2-repo
      Guvnor M2 Repo
      http://localhost:8080/business-central/maven2/
    
  
  
    
      
        org.kie
        kie-maven-plugin
        6.0.3-redhat-4
        true
      
    
  

  
    
 org.kie
 kie-api
 6.1.0.Final
    
   


The section of dependencies are added. Now if you build the project, it will be successful!

Monday, March 30, 2015

ActiveMQ: Encrypt ActiveMQ Console Password

Introduction

ActiveMQ console, by default, use jetty as web container. The login credentials are not encrypted. In the enterprise application, this will not pass the security scan. Thus we need to encrypt the password. This blog will document the process for such a purpose.

Executive Summary

  • Download Jetty Utility from: http://download.eclipse.org/jetty/
  • run: java -cp lib/jetty-util-$JETTY_VERSION.jar org.eclipse.jetty.util.security.Password admin admin
  • replace the admin password in jetty-realm.properties

Detailed Procedures

Download Jetty Utlity

The jetty utility can be downloaded from http://download.eclipse.org/jetty/. At the writing, the latest version is stable-9. For linux, you will need to download .tgz file. Unpack the archive file using the following command:

tar vxzf /software/JETTY/jetty-distribution-9.2.10.v20150310.tar.gz

In my case, I install the jetty under

/opt/app/amq/jetty/

Once you unzip the file, you can use the following command to create encrypted password:

java -cp lib/jetty-util-$JETTY_VERSION.jar org.eclipse.jetty.util.security.Password admin admin

Here is the output

java -cp lib/jetty-util-$JETTY_VERSION.jar org.eclipse.jetty.util.security.Password admin admin
2015-03-30 15:19:15.977:INFO::main: Logging initialized @48ms
admin
OBF:1u2a1toa1w8v1tok1u30
MD5:21232f297a57a5a743894a0e4a801fc3
CRYPT:adpexzg3FUZAk

Now we can copy the line of: CRYPT:adpexzg3FUZAk to the file of jetty-realm.properties, and here is the how the file looks like:

$ cat jetty-realm.properties
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements.  See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License.  You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------

# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: CRYPT:adpexzg3FUZAk, admin
user: CRYPT:us6EKZMmfBVwI, user

As you can see the original password: "admin" is replaced with "CRYPT:adpexzg3FUZAk". Now you can restart the activemq.

Saturday, March 14, 2015

Broker-To-Broker Network Connector With SSL And JAAS Plugin

Introduction

In my previous blogs, I have explained many topics related to enterprise messaging with ActiveMQ from simple installation to complicated configuration with Network-Of-Brokers. In this blog, I am going to demonstrate in detail how to setup a Network-Of-Brokers using SSL for network connection. Currently, there is little detailed documentation available with regard to how to setup network of brokers using SSL. One of my goals of this blog is to fill this gap.

Topology

As shown in the above picture, I have setup two clusters, name WEST and EAST. Each cluster has a master-slave pair of ActiveMQ instances. The master-slave instance are located on the same Linux server. Thus, I have two Linux servers, name SERVER01 and SERVER02.

Generate Keys and Certificates

Generate Private and Public Keys On SERVERV01

First, I created the following dir:

[amq@SERVERV01 dev1certs]$ pwd
/opt/app/activemq/cluster/master-slave/certificates/dev1certs

Generate Private Key

Then, I will need to create private key namd serverv01.ks as the following:

[amq@SERVERV01 dev1certs]$ keytool -genkey -alias serverv01 -keyalg RSA -keystore serverv01.ks
Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  Gary Liu
What is the name of your organizational unit?
  [Unknown]:  OU
What is the name of your organization?
  [Unknown]:  OG
What is the name of your City or Locality?
  [Unknown]:  MyCity
What is the name of your State or Province?
  [Unknown]:  PA
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Gary Liu, OU=OU, O=OG, L=MyCity, ST=PA, C=US correct?
  [no]:  yes

Enter key password for 
        (RETURN if same as keystore password):
serverv01.ks

Enter password as amqadmin@. We will need this password later. Make sure you use the alias the same as host name, so that we can update the key based on the unique alias, if necessary. As you can see, we have created a private key, name serverv01.ks. We interrogate this key by the following command:

[amq@SERVERV01 democerts]$ keytool -list -keystore serverv01.ks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

serverv01, Mar 14, 2015, PrivateKeyEntry,
Certificate fingerprint (SHA1): 31:43:79:2B:33:3E:73:8A:C1:1C:3C:D1:EA:68:ED:00:6A:8C:F6:D3

Generate Public Key

After generating private key, we need to create public key. Outside world will use this key to communicate with ActiveMQ broker. Here is the command to generate public key [sametimes, it is called certificates. It is the same thing.].


 keytool -export -alias server1 -keystore server1.ks -file server1_cert

Here is the details:

 [amq@SERVERV01 democerts]$ keytool -export -alias serverv01 -keystore serverv01.ks -file serverv01_cert
Enter keystore password:
Certificate stored in file 
[amq@SERVERV01 democerts]$ ls
serverv01_cert  serverv01.ks

We can also verify the public key by the following command:

keytool -printcert -file serverv01_cert

Here are the details

[amq@SERVERV01 democerts]$ keytool -printcert -file serverv01_cert
Owner: CN=Gary Liu, OU=OU, O=OG, L=Jessup, ST=PA, C=US
Issuer: CN=Gary Liu, OU=OU, O=OG, L=Jessup, ST=PA, C=US
Serial number: 5a47ce77
Valid from: Sat Mar 14 13:57:23 CDT 2015 until: Fri Jun 12 13:57:23 CDT 2015
Certificate fingerprints:
         MD5:  C7:90:BC:22:C6:F9:E8:D0:CA:EB:DE:55:AF:D3:90:F8
         SHA1: 31:43:79:2B:33:3E:73:8A:C1:1C:3C:D1:EA:68:ED:00:6A:8C:F6:D3
         SHA256: B2:EE:9F:AE:89:88:00:E9:9D:E8:6C:34:BF:11:82:11:0A:A1:A9:4C:80:35:39:C2:66:08:58:02:BE:9A:89:97
         Signature algorithm name: SHA256withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 9D E7 60 DE 70 93 6E 2B   EA 19 D0 98 44 D9 9B AE  ..`.p.n+....D...
0010: DC C4 B3 AD                                        ....
]
]

Generate Shared Keystore shared.ks

We need to have shared public key store to include all the public keys in one file. Thus client can use this file communicated with server. And ActiveMQ brokers can communicate with each other. Now, we will create a file named shared.ks using the following commands:

 keytool -import -alias serverv01 -keystore shared.ks -file serverv01_cert

And here are the details:

 [amq@SERVERV01 democerts]$ keytool -import -alias serverv01 -keystore shared.ks -file serverv01_cert
Enter keystore password:
Re-enter new password:
Owner: CN=Gary Liu, OU=OU, O=OG, L=Jessup, ST=PA, C=US
Issuer: CN=Gary Liu, OU=OU, O=OG, L=Jessup, ST=PA, C=US
Serial number: 5a47ce77
Valid from: Sat Mar 14 13:57:23 CDT 2015 until: Fri Jun 12 13:57:23 CDT 2015
Certificate fingerprints:
         MD5:  C7:90:BC:22:C6:F9:E8:D0:CA:EB:DE:55:AF:D3:90:F8
         SHA1: 31:43:79:2B:33:3E:73:8A:C1:1C:3C:D1:EA:68:ED:00:6A:8C:F6:D3
         SHA256: B2:EE:9F:AE:89:88:00:E9:9D:E8:6C:34:BF:11:82:11:0A:A1:A9:4C:80:35:39:C2:66:08:58:02:BE:9A:89:97
         Signature algorithm name: SHA256withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 9D E7 60 DE 70 93 6E 2B   EA 19 D0 98 44 D9 9B AE  ..`.p.n+....D...
0010: DC C4 B3 AD                                        ....
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore

So far I have performed 3 tasks:

  • Generate private key
  • Generate public key
  • Create a shared keystore

And I have executed the following commands:

  keytool -genkey -alias serverv01 -keyalg RSA -keystore serverv01.ks
  keytool -export -alias serverv01 -keystore serverv01.ks -file serverv01_cert
  keytool -import -keystore shared.ks -file serverv01_cert
  keytool -list -keystore shared.ks

Generate Private And Public Keys On The Second Server

Now, we need execute the same commands on the other server. In my case, the other server is name as SERVERV02. During the execution of the commands, replace all host name by the server name. [In my case, I replace serverv01 with serverv02].

And I have executed the following commands:

  keytool -genkey -alias serverv02 -keyalg RSA -keystore serverv02.ks
  keytool -export -alias serverv02 -keystore serverv02.ks -file serverv02_cert
  keytool -import -keystore shared.ks -file serverv02_cert
  keytool -list -keystore shared.ks

At this point, on each server we have 3 files:

  1. HOSTNAME.ks
  2. HOSTNAME_cert
  3. shared.ks

This means for each host we have a private key, a public key, and shared key. The next step is to exchange public key and update the shared key.

Exchange Public Keys

In order for the ActiveMQ brokers to authenticate each other, we need to change the public keys. So that copy the file of HOSTNAME_cert to each other's server. In my case, I use scp. Here is the command for copy from server 2 to server 1:

scp gliu@serverv02:/opt/app/activemq/cluster/master-slave/certificates/democerts/serverv02_cert .

From server 1 to server 2:

scp gliu@serverv01:/opt/app/activemq/cluster/master-slave/certificates/democerts/serverv01_cert .

Now we need to import the newly copied public key to the shared keystore, namely shared.ks. Thus on server 1[serverv01] execute the following commands:

keytool -import -alias serverv02 -keystore shared.ks -file serverv02_cert

And on the server 2[serverv02], execute the following command:

keytool -import -alias serverv01 -keystore shared.ks -file serverv01_cert

We can check what is the content of the shared keystore by following command:

[amq@SERVERV02 democerts]$ keytool -list -keystore shared.ks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

serverv02, Mar 15, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): AB:21:A4:20:2B:81:E3:23:79:37:7D:07:45:9E:0A:D0:B6:71:4B:6B
serverv01, Mar 15, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): 31:43:79:2B:33:3E:73:8A:C1:1C:3C:D1:EA:68:ED:00:6A:8C:F6:D3

From the above output, we can see that the public keys from two servers [serverv01 and serverv02] are included in the shared.ks file. Upon this point, we have completed the key generation procedure. It seems a long procedure, but it is pretty straight forward in reality.

Remember, in the large network of brokers, many servers many involved. In order for the client to connect any server in the clusters, we will need to add all the keys to the shared.ks file. With this file, client will be able to connect to the all the brokers.

ActiveMQ Configuration

For each broker, we need to copy the private key [HOSTNAME.ks] and shared.ks to the $ACTIVEMQ_BASE/conf. Once that is done, we need to update the activemq.xml file.

Update activemq.xml On The WEST Cluster

The in my case, the west cluster has two nodes [WEST-NORTH and WEST-SOUTH] playing as master-slave pair. In my design, I use WEST cluster as the active part which contains the networkConnector configuration, while the EAST cluster does not define any network connector. This is desired configuration. Firstly, it is simple to define duplex connection than define two separate one-way connection. Secondly, in the enterprise application, there may be firewall restriction which prevent us from having two one-way connections. Here is the relevant configuraiton:


        ...

        
            
        

        
            
                     
                        
                     
            
            
                     
                        
                     
            
        

        ...

         
          

          
            
              
                
                  
                  

                  
                  

                  
                

                
                  
               
              
            
          
        

        
            
            
        


        
            
        

        ...


Update activemq.xml On The EAST Cluster

The configurations of the EAST cluster are almost the same as the WEST cluster, except we do not need to define the networkConnector as explained in the previous section.

Trouble Shooting

Make Sure Ports Open On Firewall

When you run the network of brokers, make sure the ports are open. If you use 61617, for example, as ssl connection, make sure that port is open from firewallusing command of:

 sudo iptables -L -v -n]

Make Sure HOSTNAME.ks and shared.ks Aviable

In my example, I explicitly tell ActiveMQ the location of the private and public keys. In that way, I know which key I am using.

Check Log

$ACTIVEMQ_BASE/data/activemq.log contains very important server information. Alway check the log after you start the broker. If connection are established, you should see something like this:
2015-03-13 16:18:28,710 | INFO  | Establishing network connection from vm://WEST-NORTH?async=false&network=true to failover:(nio+ssl://serverv02:61617,nio+ssl://serverv02:61627)?randomize=false&maxReconnectAttempts=0 | org.apache.activemq.network.DiscoveryNetworkConnector | ActiveMQ Task-1
2015-03-13 16:18:28,711 | INFO  | Connector vm://WEST-NORTH started | org.apache.activemq.broker.TransportConnector | ActiveMQ Task-1
2015-03-13 16:18:28,724 | INFO  | Establishing network connection from vm://WEST-NORTH?async=false&network=true to failover:(nio+ssl://serverv02:61617,nio+ssl://serverv02:61627)?randomize=false&maxReconnectAttempts=0 | org.apache.activemq.network.DiscoveryNetworkConnector | ActiveMQ Task-1
2015-03-13 16:18:29,017 | INFO  | Successfully connected to nio+ssl://serverv02:61617 | org.apache.activemq.transport.failover.FailoverTransport | ActiveMQ Task-1
2015-03-13 16:18:29,021 | INFO  | Successfully connected to nio+ssl://serverv02:61617 | org.apache.activemq.transport.failover.FailoverTransport | ActiveMQ Task-1

Test Configuration

In order to test the configuration of the Network-Of-Broker with nio+ssl, I use the sample code that comes with ActiveMQ. We need to test:

  1. Failover From Both Clusters
  2. Producing And Consuming Messages

Test Failover

To test failover, we need stop one ActiveMQ broker at a time. Make sure the connection between two cluster are established correctly

The above picture shows that the EAST cluster has established 2 connections with the EAST cluster on the EAST-NORHT broker. One is for queue and the other for the topic connection. If we stop the north broker from the WEST cluster, we should see the new connection establish from the WEST to the EAST cluster.

Test Message Exchanging

Here are the basic messaging changing patterns need to be tested. Basically, we need to make sure if producers and consumers are located at the same cluster, they can exchange messages. In this case, we need to make sure messages are not automatically bridged to the other cluster. Another test is to make sure if producers and consumers are located at different cluster, the brokers can bridge messages to the other brokers. Here are the 4 test cases:
  1. Produce and Consumer Messages From WEST cluster
  2. Produce and Consumer Messages From EAST cluster
  3. Produce Messages From WEST Cluster and Consumer FROM EAST Cluster
  4. Produce Messages From EAST Cluster and Consumer FROM WEST Cluster

In order to execute the above test cases, I created 4 scripts as shown in the following.

publishToDev1.sh

#!/bin/bash
# publishToDev1.sh
#
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer \
 -Durl="failover:(nio+ssl://serverv01.mycompany.com:61617,nio+ssl://serverv01.mycompany.com:61627)" \
 -Duser="hmuser" \
 -Dpassword="admin123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/dev1cert/shared.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/dev1cert/shared.ks

consumeFromDev1.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant consumer  \
 -Durl="failover:(nio+ssl://serverv01.mycompany.com:61617,nio+ssl://serverv01.mycompany.com:61627)" \
 -Duser="hmuser" \
 -Dpassword="admin123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/dev1cert/shared.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/dev1cert/shared.ks

publishToDev2.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer \
 -Durl="failover:(nio+ssl://serverv02.mycompany.com:61617,nio+ssl://serverv02.mycompany.com:61627)" \
 -Duser="admin" \
 -Dpassword="admin" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/dev2cert/shared.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/dev2cert/shared.ks

consumeFromDev2.sh

consumeFromDev2.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
# -Durl="failover:(nio+ssl://serverv02.mycompany.com:61617,nio+ssl://serverv02.mycompany.com:61627)" \
ant consumer  \
 -Durl="failover:(nio+ssl://serverv02.mycompany.com:61617,nio+ssl://serverv02.mycompany.com:61627)" \
 -Duser="hmuser" \
 -Dpassword="admin123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/dev2cert/serverv02.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/dev2cert/shared.ks

Conclusion And Summary

The main purpose of this blog is explain the ActiveMQ configuration for a Network-Of-Brokers using nio+ssl. I have included the test scripts so that admin can test the configuration without writing any new java code.

Tuesday, March 10, 2015

ActiveMQ Security Using JAAS Authentication

Introduction

By default, ActiveMQ does not provide access to the message broker anonymously. That means we don't need to pass user name and password. This is not desired. There are two simple authentication schemes. The firsts use simple authentication and the second one uses JAAS plugin. JASS plugin can be used with LDAP.

In this blog, I am going explain how to use jaasAuthenticationPlugin.

Configuration Changes

To configure ActiveMQ using JAAS authentication plugin requires to modify the following files [all these files are located at $ACTIVEMQ_HOME/conf:

  1. login.config
  2. users.properties
  3. groups.properties
  4. activemq.xml

activema.xml


       ...
       
         

         
           
             
               
                 
                 

                 
                 

                 
               

               
                 
              
             
           
         
       
       ...



login.config

activemq-domain {
    org.apache.activemq.jaas.PropertiesLoginModule required
        debug=true
        org.apache.activemq.jaas.properties.user="users.properties"
        org.apache.activemq.jaas.properties.group="groups.properties";
};

Note: configuration="activemq-domain" in the activemq.xml implies that ActiveMQ will look for the entry of activemq-domain in the login.config file.

users.properties

admin=admin
hmuser=user123@

groups.properties

admins=admin
users=hmuser

Test Configuration

To test the configuration, you can run the following scripts:

producer: runProducerOneWay.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer \
 -Durl="nio+ssl://localhost:61617" \
 -Duser="hmuser" \
 -Dpassword="user123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.debug=ssl:handshake \
 -Djavax.net.ssl.keyStore=/home/amq/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=/home/amq/client.ts

consumer: runConsumerOneWay.sh

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant consumer  \
 -Durl="nio+ssl://localhost:61617" \
 -Duser="hmuser" \
 -Dpassword="user123@" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts

Saturday, March 7, 2015

Enable HTTPS For ActiveMQ Brower

Introduction

ActiveMQ embedded web console is jetty. In enterprise applications, plain http is not recommended. Thus we should enable HTTPS. In my previous blogs, I have demonstrated how to enable nio+ssl for mutual authentication or one-way authentication. In this blog, I am going to show you how to enable HTTPS for the embedded ActiveMQ console.

Configuration Changes

The configuration file we need to change is ${AMQ_HOME}/conf/jetty.xml. Uncomment out the bean with id of "SecureConnecor" and remove the id with "Connector" as shown below:


    ...
    

        
            
                
                    
                    
                    
                

            
        

        
            
                
                    
                        
                        
                    
                
            
        

    



Run The ActiveMQ

Start ActiveMQ the same way as before. Go to brower with URL of https://hostname:8162, use the same user id and password [admin/admin].

Friday, March 6, 2015

Configure ActiveMQ Using nio+ssl With One-Way Authentication

Introduction

In my previous blog http://ggl-consulting.blogspot.com/2015/02/configure-activemq-transport-connector.html, I have explained the activemq configuration with mutual authentication. In most case, we don't need to have the server to check client's certificates, but rather client just need to send the server's certificate, or broker trust store together with client key.

I should point out that in large enterprise, normally the certificates are not generated by admin. There will be certified organization to issue the certificates. My blogs are just demonstrate how to setup ActiveMQ and run the producers and consumers.

All the certificate generation procedures are still the same except that we don't need to generate broker.ts file. For the completeness, I will provide the complete procedure in this blog, including how to run the producers and consumers.

Generate Keystore and Truststore

For one-way authentication, we will need 3 files as the following:

  1. broker.ks : server keystore
  2. client.ks : client keystore
  3. client.ts : client truststore

Here is the procedure to generate these files:

cd $ACTIVEMQ_HOME/conf
keytool -genkey -alias broker -keyalg RSA -keystore broker.ks
keytool -genkey -alias client -keyalg RSA -keystore client.ks
keytool -export -alias broker -keystore broker.ks -file broker_cert
keytool -import -alias broker -keystore client.ts -file broker_cert

Modify activemq.xml


       ...
       
            
            
        
 
        
            
            
        
        ...

For large network of ActiveMQ Clustering, please refer my other blog: http://ggl-consulting.blogspot.com/2015/03/broker-to-broker-network-connector-with.html

As you can see, comparing the two-authentication case, we only need the keyStore of the broker, which include the broker's key and certificates

Run Producer and Consumer

For running producer, I have created a scrirpt named runProducerOneWay.sh with the following contents:

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant producer -Durl="nio+ssl://localhost:61617" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Dmax=100 \
 -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts 

Run the above script at $ACTIVEMQ_HOME/examples/openwire/swissarmy

The script for running consumer, namely, runConsumerOneWay.sh has the following contents:

#!/bin/bash
ACTIVEMQ_HOME=/opt/app/amq/Transport/NioSsl
ant consumer -Durl="nio+ssl://localhost:61617" \
 -Dtopic=false \
 -Ddurable=true \
 -Dsubject=QUEUE.NIOSSL \
 -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
 -Djavax.net.ssl.keyStorePassword=amqadmin@ \
 -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts 

As you can see, we don't need to know the server's keyStore password. We still need the client's keyStore information in order for the server to know the decryption algorithms.

Anypoint Studio Error: The project is missing Munit lIbrary to run tests

Anypoint Studio 7.9 has a bug. Even if we following the article: https://help.mulesoft.com/s/article/The-project-is-missing-MUnit-libraries-...