Map in a Tiny Box : Geoserver with Raspberry Pi

Introduction

When Raspberry PI came out in early 2012, I had to get my hand on one. I didn’t know what I would do with it but the tiny size of that little computer made me have it. I bought one after waiting 6 weeks on back order. First thing I installed on that machine was Java and then Tomcat application server just to see if my favorite language and app server would run from a tiny thing. Well then years has passed and didn’t spend any time on it.Few days back I thought why not make a tiny map server out of Raspberry Pi. Here I’m inviting you on a tiny journey with me hoping that it would amazes you too to see how a tiny machine serves maps.

 

Sandbox

Raspberry Pi Model B

20141206_214144

Raspberry Pi Model B

First let me list out software and operating systems involved in this tiny lab.

  1. Operating System:RASPBIAN Debian Wheezy Version:September 2014
  2. Java:
  3. Java Servlet Server:Tomcat 7
  4. GIS Map Server:Geoserver
  5. A Client:A Windows 7 Laptop
  6. SSH Client:Putty on Windows

Steps

Install Operating System

For this lab I went with Raspbian Wheezy. It is a variant of Debian and one of the matured operating system made specially for Raspberry Pi. Download Raspbian from here. A detail instruction on how to install Rasbian image on a sd card also can be found here. Once you have the SD card you are all set to start Raspberry PI. Start Raspberry Pi.

 

Using Raspberry PI as Headless Server

For this lab we will use Raspberry PI in headless mode. Raspberry Pi can be run just like a regular computer using a monitor, keyboard and mouse. I’m choosing to run the little machine more like a remote server aka “headless mode”.

 

SSH to Raspberry Pi

We will use a laptop running Windows 7 to connect to our Raspberry Pi box. SSH protocol can be used to connect. In order to use SSH we will need to know the ip address that Raspberry Pi is running of off. We can find ip address in two different methods. Both of these methods are nicely describe here.

 

Using Router to find Raspberry’s IP

Log in to router’s web admin console. In my case the address to admin console was http://192.168.11.1. From the control panel find the list of connected devices to router. From the list figure out the ip address of Raspberry Pi and note it down. In my case the ip was 192.168.11.131.

2 Router

 

Using namp to find Raspberry’s IP

Download and install nmap. namap is a free networking utility to find ip and mac addresses inside a network. Running the following command will display all connected devices in network. Let us type up the following command to display a list of connected devices. In this lab our subnet is 192.168.11.xxx

 

nmap -sP 192.168.11.0/24

 

Here is sample console out. In this situation raspberrypi can be identified to have ip address of 192.168.11.131

1 nmap console

Using Putty to SSH

Install Putty if not installed already and start it up. Type in the IP address that was found in our previous step. Click open. SSH console would be displayed. Type in user as pi and provide appropriate password to login. You should be connected to Pi now.

3

Install Java Servlet Server

In recent versions of Raspbian image distribution Oracle Java 1.8 is already bundled.

4

In this lab we will install and use Tomcat version 7 as the servlet server. A servlet container is required to run Geoserver GIS map server which we intend to use as our spatial server. We would type the following command to install Tomcat 7.

 

sudo apt-get install tomcat7

 

Most likely the process will run into a JAVA_HOME not found problem as illustrated below whilte trying to start up tomcat instance.

5

This problem can be solved by adding JAVA_HOME to /etc/default/tomcat7 file. Add the following line to the file using a file editor like vi or vim.

 

JAVA_HOME=”/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt”

Let us now start Tomcat instance by typing the following command.

 

sudo service tomcat7 start

7

 

 

 

Let us test Tomcat7 installation by using a browser and connecting to the default landing page. Type up the following address in a browser where the IP address is pointing to the IP address of the Raspberry Pi.

 

http://192.168.11.131:8080

 

A successful Tomcat installation would present a page as displayed as follows.

50

Install Geoserver Map Server

Download Geoserver war zip

wget http://sourceforge.net/projects/geoserver/files/GeoServer/2.6.1/geoserver-2.6.1-war.zip

55

 

Now unzip the archive to extract WAR file by typing the following.

unzip geoserver-2.6.1-war.zip

56

 

 

Let us stop Tomcat server

sudo service tomcat7 stop

Now let us move the war to Tomcat’s webapps folder. The webapps folder is located under

/var/lib/tomcat7/webapps . Let us move the war by typing up the following.

sudo mv geoserver.war /var/lib/tomcat7/webapps

Start Tomcat7

sudo service tomcat7 start

57

Login to Geoserver admin console by typing

http://192.168.11.131:8080/geoserver/

 

You should be presented with the Geoserver login page. Now type in admin as user id and geoserver as password to log into Geoserver admin console. A successful login will present us with a page like as shown here.

60

 

 

Click on “Layer Preview” tab on the left to bring up layer preview page.

61

Now click on “OpenLayers” link for topp:states USA Population. We should be presented by a preview of USA States map as shown below.

raspiGeo_99

 

 

 

This will bring to an end of my Tiny Map server demo. In future I may present with more tutorial like this one if  I get enough interest. I wish to create a series on how to create web based Maps based on open source and commercial server and client products. Thanks for reading.

 

References:

Raspberry Pihttp://www.raspberrypi.org/

Tomcathttp://tomcat.apache.org/

Geoserverhttp://geoserver.org/

Tomcat embedded with JAX-RS Jersey

Introduction

This tutorial will show how to setup Tomcat 8.0 with Jersey and running restful application from an embedded mode.

 

Developer Sandbox

  • Windows 7 64 bit
  • Tomcat 8.0 Embedded
  • Jersey 2.6
  • Eclipse Juno

 

Steps

I will explain two ways of deploying a Jersey rest application. The first one will use web.xml. The second example will use ResrouceConfig class.

Download Libraries

Download Tomcat 8 Embedded

  • Unzip to a location like C:\LIBS_and_Jars\tomcatembeddedjars
Tomcat JARs

Tomcat JARs

Download Jersey 2.6

Maven will be used to download Jersey and dependent jars. Manually downloading jars is a pain. Here I’ll explain how to use Maven just as a downloading and dependency management tool.

  • Create a folder like C:\LIBS_and_Jars\jerseyjars
  • Assuming you have maven installed, open up a command prompt.
  • CD to C:\LIBS_and_Jars\jerseyjars
  • Issue the following mvn command

mvn archetype:generate -DarchetypeGroupId=org.glassfish.jersey.archetypes  -DarchetypeArtifactId=jersey-quickstart-webapp -DarchetypeVersion=2.6 -DgroupId=com.example -Dpackage=com.example -Dversion=1.0 -DinteractiveMode=false -DartifactId=jersey-basic-2.6

  • A folder named jersey-basic-2.6 should be created like C:\LIBS_and_Jars\jerseyjars\jersey-basic-2.6
  • Change directory to jersey-basic-2.6
  • Now issue the following maven command to put all jersey and dependent jars into one location at target\dependency.

mvn dependency:copy-dependencies

  • All jars should be copied over to a folder like C:\LIBS_and_Jars\jerseyjars\jersey-basic-2.6\target\dependency
Jersey JARs

Jersey JARs

Setup Eclipse Project

  •  Start new Eclipse project of type “Java”.
  • Add all jars that were downloaded in previous steps as External JARs.
  • Start adding Java sources as stated in next step.
Java Build Path

Java Build Path

 

 

HelloWorldRestResource.java

First a very basic Jersey resource.


import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/helloworld")
public class HelloWorldRestResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHello() {
        return "Hello World from Tomcat Embedded with Jersey!";
    }
}

 

ResourceLoader.java

Now let us write a Jersey resource loader class that will register a restful Java resource. In this example the resource loader will load HellowWorldRestResource.


import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

public class ResourceLoader extends Application{

    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet<Class<?>>();
       
        // register root resource
        classes.add(HelloWorldRestResource.class);
        return classes;
    }
}

 

Main.java with web.xml

Now we are going to write the Main.java which will be responsible for starting embedded Tomcat. In the first version of Main.java I’ll show how to register the resource loader using a traditional web.xml. First the Main.java source file.


import javax.servlet.ServletException;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.Context;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import java.io.File;
import java.net.MalformedURLException;

public class Main {

    public static void main(String[] args) throws Exception, LifecycleException {
        new Main().start();
    }

    public void start() throws ServletException, LifecycleException,
            MalformedURLException {

        // Define a folder to hold web application contents.
        String webappDirLocation = "WebContent/";
        Tomcat tomcat = new Tomcat();

        // Define port number for the web application
        String webPort = System.getenv("PORT");
        if (webPort == null || webPort.isEmpty()) {
            webPort = "8080";
        }
        // Bind the port to Tomcat server
        tomcat.setPort(Integer.valueOf(webPort));

        // Define a web application context.
        Context context = tomcat.addWebapp("/tomcatembedded", new File(
                webappDirLocation).getAbsolutePath());

        // Define and bind web.xml file location.
        File configFile = new File(webappDirLocation + "WEB-INF/web.xml");
        context.setConfigFile(configFile.toURI().toURL());

        tomcat.start();
        tomcat.getServer().await();
    }

}

Now the web.xml.

web.xml


<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
 
  <servlet>
    <servlet-name>REST Servlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>ResourceLoader</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>REST Servlet</servlet-name>
    <url-pattern>/resourceloader/*</url-pattern>
  </servlet-mapping>
    
</web-app>

Here is an overview of folder and file structure to show where to put web.xml file in the Eclipse project

Eclipse Folder Structure

Eclipse Folder Structure 

 

Test the REST Resource

Use a browser to test out the REST resource using this url

http://localhost:8080/tomcatembedded/resourceloader/helloworld

This should display the following page as shown here.

Browser page

Browser page 

 

Main.java using ResourceConfig() no web.xml

Please notice that I’ve taken out reference to web.xml and instead using resourceConfig() to load a servlet container which in turn loading the ResourceLoader.java.


import javax.servlet.ServletException;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.Context;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import java.io.File;
import java.net.MalformedURLException;

public class Main {

    public static void main(String[] args) throws Exception, LifecycleException {
        new Main().start();
    }

    public void start() throws ServletException, LifecycleException,
            MalformedURLException {

        // Define a folder to hold web application contents.
        String webappDirLocation = "WebContent/";
        Tomcat tomcat = new Tomcat();

        // Define port number for the web application
        String webPort = System.getenv("PORT");
        if (webPort == null || webPort.isEmpty()) {
            webPort = "8080";
        }
        // Bind the port to Tomcat server
        tomcat.setPort(Integer.valueOf(webPort));

        // Define a web application context.
        Context context = tomcat.addWebapp("/tomcatembedded", new File(
                webappDirLocation).getAbsolutePath());

       // Add servlet that will register Jersey REST resources
        Tomcat.addServlet(context, "jersey-container-servlet", resourceConfig());
        context.addServletMapping("/rest/*", "jersey-container-servlet");

        tomcat.start();
        tomcat.getServer().await();
    }

    private ServletContainer resourceConfig() {
        return new ServletContainer(new ResourceConfig(
                new ResourceLoader().getClasses()));
    }

 
}

 

Test the REST Resource

Use a browser to test out the REST resource using this url

http://localhost:8080/tomcatembedded/rest/helloworld

 

That is it for now.

How to set SSL on Apache Server on Windows using Fake Local Certificate Authority

Introduction

This is a tutorial to demonstrate how to setup Apache with SSL/TLS and client authentication utilizing Client Certificate with Private Key in Windows 7 environment. A typical ecosystem for SSL/TLS setup involves three parties. These three parties are Certificate Authority (CA), Server, and Client. Inspiration for this tutorial came from my desire to understand how two way ssl works. Before starting researching my knowledge on SSL was close to none. The result of my research note has been polished to publish this blog post.

Real life examples

For this Tutorial

Certificate Authority (CA)

VeriSign, DigiCert

Fake CA

Server

Apache, Tomcat, SMTP

Apache with XAMPP

Client

Firefox, Internet Explorer

Firefox  and Java

Sandbox

Windows 7 64

Apache for Windows

OpenSSL for Windows

FireFox

Apache

  • In this tutorial XAMPP v 1.8.1 for Windows  has been used to get Apache server. Downlaod XAMPP for Windows from here
  • Install XAMPP by unzipping the zip content.
  • Location of Apache on the laptop that was used for this demo is
    • “S:\servers\xampp\apache”

Firefox

Installed Firefox portable version 20.0.1 for this tutorial.

OpenSSL for Windows

  • Download and install OpenSSL for Windows. For this tutorial Win64 OpenSSL v 1.0.1e is used. Download it from here
  • Install by running the setup exe. For this blog demo the location for OpenSSL for Windows is
    • “S:\apps\OpenSSL-Win64”

Fig: Sequence of communication between server and client to negotiate two way ssl

Steps

  • Open a command prompt in Windows.

  • Change directory to <APACHE_HOME>\conf folder

  • Set environment variables for proper operation of OpenSSL for Windows

    • Example location of installed OpenSSL

    • OPENSSL_HOME = C:\apps\OpenSSL-Win32

  • Set environment variable

    • SET OPENSSL_HOME = C:\apps\OpenSSL-Win32

    • SET OPENSSL_CONF=%OPENSSL_HOME%\bin\openssl.cfg

    • SET PATH=%PATH%;%OPENSSL_HOME%\bin

Generate Certificates

Create the Certificate Authority (CA) for Server

In this tutorial no real CA will be used. A fake certificate authority “CA Server Certificate” will be created on local sandbox laptop.

  • Generate CA key file named ca.key by typing in openssl commands on cmd prompt as below.

openssl genrsa -out ca_server.key 1024
  • Generate certificate signing request ca.csr for CA. Provide CA related information on subject section.

openssl req -new -newkey rsa:1024 -nodes -out ca_server.csr -keyout ca_server.key -subj "/C=US/ST=NY/L=New York/O=CA Server Certificate/OU=IT/CN=www.CAServer.org"
  • Generate CA certificate using csr and sign the certificate using ca.key

openssl x509 -req -days 365 -in ca_server.csr -signkey ca_server.key -out ca_server.crt

Setup the Web Server Certificate

Now certificate for server will be generated.

  • Generate server key file named server.key

openssl genrsa -out server.key 1024

  • Generate server csr

openssl req -new -newkey rsa:1024 -nodes -out server.csr -keyout server.key -subj "/C=US/ST=Texas/L=Austin/O=Server /OU=IT/CN=localhost
  • Generate server certificate having it signed by CA that was generated in previous steps.

openssl x509 -req -days 365 -CA ca_server.crt -CAkey ca_server.key -CAcreateserial -in server.csr -out server.crt

Note: If Self Signed was desired instead of a CA signed certificate.

# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Create the Certificate Authority (CA) for Client

openssl genrsa -out ca_client.key 1024
openssl req -new -newkey rsa:1024 -nodes -out ca_client.csr -keyout ca_client.key -subj "/C=US/ST=TX/L=Austin/O=CA for Client Cert/OU=IT/CN=www.CAforClient.org"
openssl x509 -req -days 365 -in ca_client.csr -signkey ca_client.key -out ca_client.crt

Have the Client Request a Certificate

  • Generate server key file named server.key

openssl genrsa -out client.key 1024
  • Generate client csr

openssl req -new -key client.key -out client.csr -subj "/C=US/ST=Texas/L=Austin/O=Client Iqbal/OU=IT/CN=ClientIqbal"
  • Generate client ertificate having it signed by CA.

openssl x509 -req -days 365 -CA ca_client.crt -CAkey ca_client.key -CAcreateserial -in client.csr -out client_signedby_ca_client.crt

Convert Client

Convert client.crt certificate to make it suitable for use with Firefox browser.

openssl pkcs12 -export -clcerts -in client_signedby_ca_client.crt -inkey client.key -out client_signedby_ca_client.p12
  • provide password

Setup Server Apache

Edit apache configuration file httpd-ssl.conf. For https connection document root is set to “S:/projects/blog_and_howto/htdocs”. For client auth a sub folder “protected_by_client_cert” has been created to demo client certificate authentication process.


	DocumentRoot "S:/projects/blog_and_howto/htdocs"

	<Directory "S:/projects/blog_and_howto/htdocs">
		Options Indexes
		Order allow,deny
		Allow from all

	   SSLRequireSSL
	   SSLVerifyClient require
	   SSLVerifyDepth 1

	SSLEngine on

    SSLCertificateFile		"S:\projects\Eclipse_Juno_Blog\SSLClientWithCert\resources\server.crt"
    SSLCertificateKeyFile	"S:\projects\Eclipse_Juno_Blog\SSLClientWithCert\resources\server.key"
    SSLCACertificateFile	"S:\projects\Eclipse_Juno_Blog\SSLClientWithCert\resources\ca_client.crt"

    ErrorLog "logs/dummy-host.localhost-error.log"
    CustomLog "logs/dummy-host.localhost-access.log" combined

Test using Browser Firefox

Setup Client Firefox

Add CA certificate ca_server.crt

  • Go to Firefox menu item > options > options > Advance

d

  • Click “View Certificates”
  • Select “Authorities” tab
  • Select “Import…” button to select “ca_server.crt” certificate that was created before.
  • Select “Trust this CA to identify websites.” as shown on the following image and click “Ok”

  • ca_server.crt entry should show up as “CA Server Certificate” under “Certificate Name” column.

  • Now select “Your Certificates” tab.
  • Click “Import” button to select Client key with certificate file PKCS12 named “client_signedby_ca_server.p12”

  • Click “Ok”.
  • Now Firefox should be ready to connect to Apache server…

Test

Make sure Apache HTTPD server is running. In ths tutorial XAMPP for windows is used. The console window should look like the following image.

  • Open Firefox and enter url “https://localhost/protectedclient” or whatever you have defined your protected client location on httpd-ssl.conf file inside <VirtualHost>

configuration.

  • Pressing enter button should bring up the following image which will prompt to accept

  •  
  • This is the p12 client certificate that Firefox is requesting to accept.
  • Clicking “Ok” should display the protected html resource.

Step by Step JAX-WS Web Services with Eclipse, TomEE, and Apache CXF

This is a step by step tutorial to try out JAX-WS web services using Eclipse, TomEE, and CXF. There will not be a need to use maven and all configuration and preparation will be done manually using Eclipse.

Sandbox Environment

  • Sandbox OS : Windows 7 64 bit
  • JDK : Java SE Development Kit 7. <Link>
  • IDE : Eclipse IDE for Java EE Developers, Version Juno <Link>
  • App Server: Apache TomEE is a Java EE application server built on top of Tomcat <Link>
  • JAX-WS Runtime: Apache CXF that is bundled in TomEE container. <Link>

Download and installation

  • Download “Windows x64” JDK 7 from here. Install JDK by double clicking on the downloaded .exe file.
  • Download Eclipse from here. Expand the zip folder onto a folder location of your choice. We will be referring to this location as “<Eclipse_home>”.
  • Download TomEE from here. Expand the zip folder onto a folder location of your choice. We will be referring to this location as “<TomEE_Home>”

Steps and Discussion

Steps and source code are developed mostly customizing the tutorial “JAX-WS @WebService example” provided at TomEE site at location http://tomee.apache.org/examples-trunk/simple-webservice/ .

Write Web Services Code

  • Start Eclipse IDE by clicking <Eclipse_Home>\eclipse.exe

01

  • Click File > New > Other…

02

  • Type in “dynamic Web Project” in Wizards input box. Dynamic Web Project wizard should show up for selection. Select “Dynamic Web Project”. Click “Next” button.

03

  • Type in “WebServicesExperiment” in Project name input box.

04

  • Click “New Runtime…” button. A “New Server Runtime Environment” dialog box shows up. Expand “Apache” and select “Apache Tomcat v7.0”. Click “Next” button.

05

  • Type in “TomEE Runtime” on “Name” input box. Click “Browse…” button to selection TomEE installed location which is being referred to as “<TomEE_Home>”. For example for the laptop that was used for this tutorial, <TomEE_Home> location is “S:\servers\apache-tomee-plus-1.5.1”. Click “Finish” button.

06

  • Click “Finish” button again on “New Dynamic Web Project” dialog box.
  • Select Window > Show View > Navigator. Your Eclipse window should look similar to below.

07

  • Select File > New > Other… and type in “Class”. This should make “Class” wizard visible on dialog box. Select “Class” and click “Next” button to view “New Java Class”
  • Type “HelloTomEEWs” as Name and click Finish.
  • Type in the following code and save the java class HelloTomEEWs. HelloTomEEWs is the interface for the web service that we are creating.
import javax.jws.WebService;

@WebService(targetNamespace = "http://sortedset.com/wsdl")
public interface HelloTomEEWs {

    public int sum(int add1, int add2);

    public int multiply(int mul1, int mul2);
}
  • Create another class named “HelloTomEEIMplementation . HelloTomEEIMplementation is the implementation web services. Type in code as below.
import javax.ejb.Stateless;
import javax.jws.WebService;

@Stateless
@WebService(
        portName = "HelloTomEEPort",
        serviceName = "HelloTomEEService",
        targetNamespace = "http://sortedset.com/wsdl",
        endpointInterface = "HelloTomEEWs")
public class HelloTomEEIMplementation implements HelloTomEEWs {

    public int sum(int add1, int add2) {
        return add1 + add2;
    }

    public int multiply(int mul1, int mul2) {
        return mul1 * mul2;
    }
}

Deploy WAR

  • Now select menu item File > Export… > Web > War file
  • Click Next button
  • Select “WebServicesExperiment” project from “Web project: drop down menu if it is no already selected.
  • On Destination: input box click “Browse” button.
  • Navigate to <TomEE_Home>\webapps and click “Save” button. This action should have “WebServicesExperiment.war” with full folder path location on Destination input box.
  • Select “TomEE Runtime” from Target runtime drop down box right under the check box named “Optimize for a specific server runtime. The “Expoert” window should look like below.

08

  • Click “Finish” button. This action should produce a WAR  under <TomEE_Home>\webapps folder.
  • Click windows Start > All Programs > Accessories > Command Prompt to bring up a Command Console
  • Change Directory CD to <TomEE_Home>\bin folder location.
  • For example TomEE installation location on the machine that was used for this blog was

S:\servers\apache-tomee-plus-1.5.1\

Run TomEE

  • Set JAVA_HOME environment variable to <Java_Home>.
  • Where jdk has been installed in S:\JDKs\64bit\jdk1.7.0_05 on the machine that was used to create this blog example.
  • The following command has been used to set Java_Home.

SET JAVA_HOME=S:\JDKs\64bit\jdk1.7.0_05

  • Start TomEE by typing startup in the command prompt. This action will bring up another command prompt with a title “Tomcat”. After spitting out a lot of system log the windows should stabilized with a line like “INFO: Server startup in 2560 ms” or something similar

09

View WSDL

  • Fire up a Firefox browser.
  • Type in the following url to view the WSDL of the web services that is running off of TomEE server

http://localhost:8080/WebServicesExperiment/webservices/HelloTomEEIMplementation?wsdl

  • You should see WSDL on Firefox

10

  • Note: It took a little bit time to find the WSDL url. Apache TomEE has a “Admin GUI” window. The url to WSDL was found logging in to TomEE Adming GUI and clicking on Console button. The consol button brought up a dialog box where the details of the web services were displayed.

Testing with soapUI

  • Download and install SoapUI from http://sourceforge.net/projects/soapui/files/
  • Start SoapUI
  • Select menu item File > New soapUI Project to bring up “New soapUI Project” dialog box.
  • Type in TomEE SoapUI Test in “Project Name” input box
  • Paste WSDL url on “Initial WSDL/WADL:” input box. For example for this blog example the wsdl is

http://localhost:8080/WebServicesExperiment/webservices/HelloTomEEIMplementation?wsdl

  • Click OK button

11

  • Double Click “Request 1” under multiply

12

  • Type in 4 between <arg0> and </arg0>
  • Type in 6 between <arg1> and </arg1>
  • Click Green Arrow button on top left to POST soap request to TomEE web service.

13

  • Server returns a soap message back with result 24

14

Testing With Firefox SOA Extension “Poser”

15

  • A soap message should be returned from the server with a result of 24 as shown below.

16

Test with Java Web Services Client

  • Open up Eclipse if it is not running already.
  • Create File > New > Java Project
  • Type TomEEClient on Project name: input box
  • Click “Finish”
  • Eclipse will ask for your permission to change perspective to “Java”. Select Yes.
  • On “Project Explorer” pane on the left right click on project “TomEEClient” and select “Properties” from the bottom of the dialog box.
  • Select “Java Build Path” from left pane.
  • Click on “Libraries” tab from right pane.
  • Then click on “Add Library…” button from right.

17

  • “Add Library” dialog box shows up.
  • Select “Server Runtime” from left pane and click “Next” button

18

  • Select  already configured from previous project “TomEE Runtime” and click “Finish” button

19

  • Click “OK” button to get out of “Properties for TomEEClient” window.
  • Right click on “src” from left pane and select “Class” wizard.

20

import javax.ejb.embeddable.EJBContainer;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;


public class TomEECalculatorClient {

	public static void main (String[] args) throws Exception{
		Properties properties = new Properties();
        properties.setProperty("openejb.embedded.remotable", "true");

        Service calculatorService = Service.create(
                new URL("http://localhost:8080/WebServicesExperiment/webservices/HelloTomEEIMplementation?wsdl"),
                new QName("http://sortedset.com/wsdl", "HelloTomEEService"));
        HelloTomEEWs calculator = calculatorService.getPort(HelloTomEEWs.class);
        
        System.out.println("Sum of 10 and 10 is : " + calculator.sum(10, 10));
        System.out.println("Multiple of 10 and 10 is : " + calculator.multiply(10, 10));
	}
	
}
  • Two Java code that was written as service interface and implementation for the previous web services project will need to be copied over to this client code as well. To make things simple this blog example is not using wsimport to generate Java artifacts from WSDL url as usually done as standard practice.
  • The Package Explorer pane should look like bellow with all three Java classes.

21

  • Now right click on “TomEECalculatorClient.java” and select “Run As” > “Java Application”
  • Java client should get results back from the server and the Console window of Eclipse should display result as below.

22

Some Notes

  • TomEE container is configured and packaged with Apache CXF runtime and required libraries. TomEE relieves you from configuration a web component only container like Tomcat with Apache CXF. That is the main selling point of TomEE that it enables you to write fully loaded JEE application server applications.
  • Selecting TomEE as runtime from within Eclipse also relieves a developer from using build tools like maven. Maven is a wonderful tool and it should be used a lot. However, sometime maven is tough to use specially if a person is developing behind a very strict company firewall where even a proxy is not allowed. In this kind of situation manual configuration is more desired.

How to populate a html form with PHP MySQL and JQuery

We need to populate a form with data from back end database given a specific user’s id.

User Story

  • As a user I will get a HTML form.
  • As a user I will also be able to type in a User ID on the form
  • As a user I will click on a submit button.
  • As a user I will be able to view all form data get populated based on user id I provided.

Sandbox

  • OS : Windows 7
  • Code Editor : Notepad++
  • Development Environment : XAMPP
  • RDBMS : MySQL
  • Server Side : PHP
  • Front : HTML
  • Javascript Library : JQuery
  • Web Server : Apache


Discussion & Steps

We will use HTML, JQuery, PHP, and MySQL to solve this problem. Let us take bottom up approach. We will first build our database, then middleware and then the front end.

Prepare MySQL Database with Test Data Tables

Connect to MySQL command prompt

1
C:\xampp\mysql\bin&gt;mysql --user=root mysql

Create a User named ‘usertutor’

1
2
3
4
mysql&gt; create user 'usertutor'@'localhost' identified by 'mypassword';
mysql&gt; grant all privileges on *.* to 'usertutor'@'localhost' with grant option;
mysql&gt; create user 'usertutor'@'%' identified by 'mypassword';
mysql&gt; grant all privileges on *.* to 'usertutor'@'%' with grant option;

Quit mysql command prompt

Connect back to “test” database schema using user ‘usertutor’

1
C:\servers\xampp\mysql\bin&gt;mysql --user=usertutor --password=mypassword test

Create a ‘users’ table with ‘id’, ‘lname’ and ‘fname’ field

mysql>create table users (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, firstname varchar(60), lastname varchar(60), email varchar(60), telephone varchar(60));

Populate ‘persons’ table with the following data.

1
2
3
4
5
insert into users (id,firstname,lastname,email,telephone ) values (null,"John","Doe","jdoe@yahoo.com","512-334-5567");
insert into users (id,firstname,lastname,email,telephone ) values (null,"Mo","Joseph","moe@gmail.com","645-908-9090");
insert into users (id,firstname,lastname,email,telephone ) values (null,"Michael","Johnson","michael.jon@mjon.com","718-554-5507");
insert into users (id,firstname,lastname,email,telephone ) values (null,"Maria","Mamma","mariam@yahoo.com","809-100-5533");
insert into users (id,firstname,lastname,email,telephone ) values (null,"Idrisi","Midrisi","i.mid@agni.com","214-1908-2309");

We will use the USERS table. The table will contain data as shown below

1
2
3
4
5
6
7
8
9
+----+-----------+----------+----------------------+---------------+
| id | firstname | lastname | email                | telephone     |
+----+-----------+----------+----------------------+---------------+
|  1 | John      | Doe      | jdoe@yahoo.com       | 512-334-5567  |
|  3 | Michael   | Johnson  | michael.jon@mjon.com | 718-554-5507  |
|  4 | Maria     | Mamma    | mariam@yahoo.com     | 809-100-5533  |
|  5 | Idrisi    | Midrisi  | i.mid@agni.com       | 214-1908-2309 |
|  6 | Mo        | Joseph   | moe@gmail.com        | 645-908-9090  |
+----+-----------+----------+----------------------+---------------+

Solution 1: Single PHP File

Create a single PHP file to do it all.

1
put single page php here??????????????????

Solution 2: Use HTML, PHP, JQuery, AJAX and JSON

In this option we will use a decoupled design. HTML page will act as a front end. The html front end will invoke a server side PHP using AJAX. Data transfer between front end HTML and backend PHP will be done using JSON. Prepare the middleware with PHP. This middleware script will get invoked by a HTTP call. PHP will parse the call and extract out User ID. Extracted User Id will be used to query MySQL USERS table. Result coming back from Users table will be return back to callee HTML as JSON encoded data.

PHP to get MySQL Data

Write a PHP to make a query to MySQL ‘users’ table. The query query will fetch data and encode it in JSON and send the data back to a HTML front end.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
    $db_host = "localhost";
    $db_user = "< user id >";
    $db_pass = "< password >";
    $db_name = "test";
    $mysqli = new MySQLi($db_host, $db_user, $db_pass, $db_name);
    $myQuery = "SELECT * FROM users";
    $result = $mysqli->query($myQuery) or die($mysqli->error);
	$data = array();
 
	while ( $row = $result->fetch_assoc() ){
		$data[] = ($row);
	}
 
	echo json_encode( $data );
?>
HTML Front End

We will create a front end using HTML and JQuery. There will be two buttons that use JQuery .ajax to fetch json encoded data from backend.php and populate a few drop down list built using html select tag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<!DOCTYPE html>
<html>
<head>
<script src="jquery-19.1.min.js"></script>
 
<script>
$(document).ready(function(){
 
	$("#buttonFirstNameLastName").click(function(){
		$.ajax({url:"backend.php",success:function(result){
			var obj1 = $.parseJSON(result);
 
			//Populate first name drop down
			var options = '';
			for (var i = 0; i < obj1.length; i++) {
				options += '<option value="' + obj1[i].id + '">' + obj1[i].firstname + '</option>';
			}
			$("#firstNameList").html(options);
 
			//Populate last name drop down
			var options = '';
			for (var i = 0; i < obj1.length; i++) {
				options += '<option value="' + obj1[i].id + '">' + obj1[i].lastname + '</option>';
			}
			$("#lastNameList").html(options);
		}});
	});
 
	$("#buttonEmailTelephone").click(function(){
		$.ajax({url:"backend.php",success:function(result){
			var obj2 = $.parseJSON(result);
 
			//Populate first name drop down
			var options = '';
			for (var i = 0; i < obj2.length; i++) {
				options += '<option value="' + obj2[i].id + '">' + obj2[i].email + '</option>';
			}
			$("#emailList").html(options);
 
			//Populate last name drop down
			var options = '';
			for (var i = 0; i < obj2.length; i++) {
				options += '<option value="' + obj2[i].id + '">' + obj2[i].telephone + '</option>';
			}
			$("#phoneList").html(options);
		}});
	});
 
});
</script>
</head>
 
<body>
<div id="div1" ><h2>Populate First Name and Last Name from BACKEND.php w/ JSON data</h2>
		<button id="buttonFirstNameLastName">Get First Name & Last Name from Backend.PHP</button>
 
 
		<h4>Drop down list with First Name</h4>		<select name="fname" id="firstNameList">
			<option value="place holder">Click the button</option>
		</select>
		<select name="lname" id="lastNameList">
			<option value="place holder">Click the button</option>
		</select>
	</div
 
	<div id="div2"><h2>Populate eMail and Telephone from BACKEND.php w/ JSON data </h2>
		<button id="buttonEmailTelephone">Get eMail & Telephone</button>
 
		<h4>Drop down list with First Name</h4>
		<select name="emila" id="emailList">
			<!-- will be populated by backend data -->
		</select>
		<select name="phone" id="phoneList">
			<!-- will be populated by backend data -->
		</select>
	</div>
 
</body>
</html>

How to Encrypt Decrypt a Password Stored in a Properties File with Java + Jasypt + Apache Commons Configuration

Introduction

Often password information is kept in a properties file for some Java based application. Password often needs to be changed so having them in properties file is a convenient way to update password without changing and recompiling source java code. However this convenience puts the password exposed in a text based properties file. For example Java application may store a database connection password in a properties file. This tutorial will show how to encrypt a password text stored in a properties file and retrieve the password later through a decryption process. JSypt will be used for encryption and decryption task. Apache Commons Configuration project will be used to easily manipulate properties file.

Sandbox Environment

  • OS: Windows 7 32 bit
  • IDE: Eclipse Juno
  • Libraries
    • Jasypt 1.9.0
    • Apache Commons Configuration 1.9

Steps

This is a simple project with only two java class and one properties file. If you run the tester it will encrypt a password and then decrypt it back. Go through the code and code comments to follow and understand how Jasypt is working.

The Encryptor & Decryptor Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.sortedset.wpblog.encryption;
 
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
 
public class EncryptDecrypt {
    private final String propertyFileName;
    private final String propertyKey;
    private final String isPropertyKeyEncrypted;
 
    final String decryptedUserPassword;
 
    /**
     * The constructor does most of the work.
     * It initializes all final variables and invoke two methods
     * for encryption and decryption job. After successful job
     * the constructor puts the decrypted password in variable
     * to be retrieved by calling class.
     * 
	 * 
	 * @param pPropertyFileName /Name of the properties file that contains the password
	 * @param pUserPasswordKey	/Left hand side of the password property as key. 
	 * @param pIsPasswordEncryptedKey 	/Key in the properties file that will tell us if the password is already encrypted or not
	 * 
	 * @throws Exception
	 */
    public EncryptDecrypt(String pPropertyFileName,String pUserPasswordKey, String pIsPasswordEncryptedKey) throws Exception {
        this.propertyFileName = pPropertyFileName;
        this.propertyKey = pUserPasswordKey;
        this.isPropertyKeyEncrypted = pIsPasswordEncryptedKey;
        try {
            encryptPropertyValue();
        } catch (ConfigurationException e) {
            throw new Exception("Problem encountered during encryption process",e);
        }
        decryptedUserPassword = decryptPropertyValue();
 
    }
 
    /**
     * The method that encrypt password in the properties file. 
     * This method will first check if the password is already encrypted or not. 
     * If not then only it will encrypt the password.
     * 
     * @throws ConfigurationException
     */
    private void encryptPropertyValue() throws ConfigurationException {
        System.out.println("Starting encryption operation");
        System.out.println("Start reading properties file");
 
        //Apache Commons Configuration 
        PropertiesConfiguration config = new PropertiesConfiguration(propertyFileName);
 
        //Retrieve boolean properties value to see if password is already encrypted or not
        String isEncrypted = config.getString(isPropertyKeyEncrypted);
 
        //Check if password is encrypted?
        if(isEncrypted.equals("false")){
            String tmpPwd = config.getString(propertyKey);
            //System.out.println(tmpPwd); 
            //Encrypt
            StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
            // This is a required password for Jasypt. You will have to use the same password to
            // retrieve decrypted password later. T
            // This password is not the password we are trying to encrypt taken from properties file.
            encryptor.setPassword("jasypt");
            String encryptedPassword = encryptor.encrypt(tmpPwd);
            System.out.println("Encryption done and encrypted password is : " + encryptedPassword ); 
 
            // Overwrite password with encrypted password in the properties file using Apache Commons Cinfiguration library
            config.setProperty(propertyKey, encryptedPassword);
            // Set the boolean flag to true to indicate future encryption operation that password is already encrypted
            config.setProperty(isPropertyKeyEncrypted,"true");
            // Save the properties file
            config.save();
        }else{
        	 System.out.println("User password is already encrypted.\n ");
        }
    }
 
    private String decryptPropertyValue() throws ConfigurationException {
    	 System.out.println("Starting decryption");
        PropertiesConfiguration config = new PropertiesConfiguration(propertyFileName);
        String encryptedPropertyValue = config.getString(propertyKey);
        //System.out.println(encryptedPropertyValue); 
 
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword("jasypt");
        String decryptedPropertyValue = encryptor.decrypt(encryptedPropertyValue);
        //System.out.println(decryptedPropertyValue); 
 
        return decryptedPropertyValue;
    }
}

Tester

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.sortedset.wpblog.encryption;
 
import junit.framework.Assert;
 
import org.junit.Test;
 
public class EncryptDecryptTest {
    public EncryptDecryptTest() {
    }
 
    @Test
    public void encryptDecryptTest() throws Exception {
    	//Name of the properties file that needs encryption
        String propertyFileName = "application.properties";
        //Key portion of the properties the left hand side
        String userPwdKey = "database.user.password" ;
        //Key in the properties file that will tell us if the password is already encrypted or not
        String isPwdEcnryptedKey = "is.database.user.password.encrypted";
 
        //Invoke the constrsuctor
        EncryptDecrypt app = new EncryptDecrypt(propertyFileName,userPwdKey,isPwdEcnryptedKey);
 
        //Retrieve the decrypted password
        String result = app.decryptedUserPassword;
        Assert.assertTrue("Decrypted password should be \"myPassWord\"", result.equalsIgnoreCase("myPassWord"));
    }
 
}

The properties file

1
2
3
database.user.name=clouduser
database.user.password=mydbpassword
is.database.user.password.encrypted=false

The properties file after encryption

1
2
3
database.user.name=clouduser
database.user.password=Gsi3ZNTtven+WjExGA1Q3UD1brweHOqf
is.database.user.password.encrypted=true

Resources