Thursday, November 2, 2017

JMS with ActiveMQ

JMS(or Java Message Service) API which is a part of java EE platform, provides a way to do communications between computers in a network by sending and receiving objects called messages. JMS API can be used to assure loose coupling, reliability, and asynchronousness of messaging.

JMS Architecture
Members of a JMS communication mainly consists of below components. Producers and Consumers are commonly called as clients.
  1. JMS Provider
    JMS Provider is the messaging system that implements the JMS API.
    Apache ActiveMQ, RabbitMQ, HornetQ and OpenJMS are some example JMS providers.
  2. Producer
  3. Sender of the message
  4. Consumer
  5. Receiver of the message

Involvement of these three members is shown in below diagram.



ActiveMQ as a JMS Provider

As I have mentioned before ActiveMQ is a JMS provider which implements the JMS API.

Below three classes show how to implement the above architecture using an ActiveMQ as an embedded broker.

Broker
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;

import javax.jms.Connection;
import javax.jms.JMSException;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.TransportConnector;

public class AMQService {
  public static final String BROKER_URI = "tcp://localhost:61616";
  private static ActiveMQConnectionFactory connectionFactory;
  private static Connection connection;
  static BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));

  public static void main(String[] args) {
    try {
      startBroker();
      startListener();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  private static void startBroker() {
    BrokerService broker = new BrokerService();
    TransportConnector connector = new TransportConnector();
    try {
      connector.setUri(new URI(BROKER_URI));
      broker.addConnector(connector);
      broker.start();
      System.out.println("Message broker started at " + BROKER_URI);
    } catch (URISyntaxException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static void startListener() {
    connectionFactory = new ActiveMQConnectionFactory(BROKER_URI);
    try {
      connection = connectionFactory.createConnection();
      connection.start();
      System.out.println("Listener started....");
    } catch (JMSException e) {
      e.printStackTrace();
    }
  }
}


Producer
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Producer {

    private Connection connection;
    private Session session;
    private MessageProducer messageProducer;

    public void create(String destinationName) throws JMSException {
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                AMQService.BROKER_URI);
        connection = connectionFactory.createConnection();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination destination = session.createQueue(destinationName);
        messageProducer = session.createProducer(destination);
    }

    public void close() throws JMSException {
        connection.close();
    }

    public void sendMessage(String message) throws JMSException {
        TextMessage textMessage = session.createTextMessage(message);
        messageProducer.send(textMessage);
        System.out.println("Producer sent: " + message);
    }
}

Consumer
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Consumer {

    private Connection connection;
    private Session session;
    private MessageConsumer messageConsumer;

    public void create(String destinationName) throws JMSException {

        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                AMQService.BROKER_URI);
        connection = connectionFactory.createConnection();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination destination = session.createQueue(destinationName);
        messageConsumer = session.createConsumer(destination);
        connection.start();
    }

    public void close() throws JMSException {
        connection.close();
    }

    public String getMessage(int timeout) throws JMSException {
    String text = "";
        Message message = messageConsumer.receive(timeout);

        if (message != null) {
            TextMessage textMessage = (TextMessage) message;
            text = textMessage.getText();
            System.out.println("Consumer received: " + text);
        } else {
        text = "";
            System.out.println(text);
        }
        return text;
    }
}

You can use below class to test above consumer producer communication.
import javax.jms.JMSException;

public class Test {
private static Producer producer;
private static Consumer consumer;
private static String queueName = "queue1";
public static void main(String[] args) throws JMSException {
producer = new Producer();
producer.create(queueName);

consumer = new Consumer();
consumer.create(queueName);

try {
String message = "Hello my consumers....";
producer.sendMessage(message);

String receivedMessage = consumer.getMessage(1000);
String status = message.equals(receivedMessage) ? "Success..." : "Fail...";
System.out.println(status);
} catch (JMSException e) {
System.out.println("JMS Exception occurred");
}
producer.close();
consumer.close();
}
}

Friday, April 28, 2017

Creating a SOAP web service with Apache CXF and Spring

In this example, I will show you how to use Apache CXF together with Spring to create a simple SOAP web service which returns hard-coded user information.

In Eclipse create a new Maven project as below.
Go to File -> New -> Maven Project
Check the check box "Create a simple project(skip archetype selection)".
Click "Next".
Set below parameters.
Group Id : com.example
Artifact Id : CxfSoapExample
Packaging : war

Click "Finish".

You will see in project explorer that a project named "CxfSoapExample" has been created.
Open the pom.xml file.
You may see an error message in pom.XML file as below because you have no web.XML file created yet.
"web.xml is missing and is set to true"

This message will vanish as soon as you created the web.xml file. However, if this message is annoying you can right click on "Deployment Descriptor" node and click "Generate deployment descriptor stub" to create the web.xml file.

Ok, Now let's go back to the pom.xml file. In this tutorial. I am using CXF 3.1.4 and java 1.7. So add those properties and CXF dependencies into the pom.xml file.
My final pom.xml file looks like below.

<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>CxfSoapExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<properties>
<cxf.version>3.1.4</cxf.version>
<spring.version>4.3.0.RELEASE</spring.version>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
</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>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
</dependency>
</dependencies>
</project>

Now right click on the project and select "Maven -> Update Project". In the popup window select the "CxfSoapExample" project and click "OK".

Now we are going to create below three java components.
1. UserService.java  - This is an interface in which we define the web service methods
    package example.cxf.service;

    import javax.jws.WebMethod;
    import example.cxf.data.User;

    public interface UserService {
@WebMethod
public User getUser(String requestedBy);
    }

2. UserServiceImpl.java - This is the implementation of UserService interface and will act as the actual service class.
    package example.cxf.service;

    import example.cxf.data.User;

    public class UserServiceImpl implements UserService {

@Override
public User getUser(String requestedBy) {
User user = new User();
user.setFirstName("John");
user.setLastName("Williams");
user.setAge(50);
user.setRequestedBy(requestedBy);
return user;
}
    }

3. User.java - This is just a java class which has variables and methods to store and access user information.

    package example.cxf.data;

    public class User {
private String firstName;
private String lastName;
private String requestedBy;
private int age;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getRequestedBy() {
return requestedBy;
}
public void setRequestedBy(String requestedBy) {
this.requestedBy = requestedBy;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
    }

Now in order to expose our service lets register it in beans.XML file.
Create a file in webapp/WEB-INF folder and name it as beans.xml.
Open the newly created file and add below content.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">

<jaxws:endpoint
       id="userService"
       implementor="example.cxf.service.UserServiceImpl"
       address="/userService" />

</beans>

Create the web.xml file in webapp/WEB-INF folder(If you haven't created yet) and add below content.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>CxfSoap2</display-name>
  <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  <context-param>
<param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/beans.xml</param-value>
</context-param>

<servlet>
       <servlet-name>CXF-SERVLET</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>CXF-SERVLET</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

Now run the project in tomcat server.
You should be able to see the WSDL file generated for this service by visiting below link.

http://localhost:8080/CxfSoapExample/userService?wsdl

Below is a sample request and response retrieved from SOAP-UI for above service.


Friday, March 31, 2017

SNMP Introduction

SNMP or Simple Network Management Protocol is a standard way of transferring information of network devices like servers, computers, routers, printers, hubs etc. Today it has become very popular and most of the hardware vendors support this protocol. SNMPv3 is the latest version of SNMP protocol.

How SNMP Works

Below are the main components of SNMP management system
1. SNMP Manager
This is the software which collects information from dofferent components in the network. Usually this is installed on a computer where network administrators have easy access. SNMP Manager polls each devices in the network regularly for information. According to your interest you can purchase or use a free SNMP Manager.

Some of the things that SNMP Manager does are

  • Collects information on bandwidth usage.
  • Alerts on low disk space
  • Monitors disk space usage of servers
  • Monitors CPU usage of servers
  • Monitors Memory usage of servers
  • Alerts on thresholds of disk space, memory usage and CPU usage
  • Sets parameters in agents such as passwords and configurations.


2. SNMP Agent
This is a piece of software which is installed in network devices by the hardware manufacturer. If monitoring of the device is required you need to enable and configure the agent. SNMP Agents run on the devices on the network separately and responsible for collecting information and deliver to the SNMP Manager when polled. In some special situations such as in an error, the agent can initiate and send messages to the SNMP Manager even when it is not polled.

3. MIB(Management Information Base)
This is a database which is used by the manager and agents to exchange information.


SNMP uses UDP(User Datagram Protocol - used to send short messages between a client and a server) as the transport protocol.

Below are the default ports used.
UDP 161 - Manager does polling of agents via this port.
UDP 162 - Messages initiated by agents are sent to the manager via this port.