Sunday, December 13, 2015

Apache Jersey + Tomcat + Eclipse + Maven with “echo” in XML/JSON (REST GET) in less than 30 min. with troubleshooting tips

Disclaimer:
Started with simple settings (with not even JUnit J.)

Pre-requisite:
1.       Jdk (tested with 1.8)
2.       Tomcat (tested with 8)
3.       Eclipse (tested with Mars)

Steps:
1.       Create a Maven project in Eclipse
Create a blank web-project with maven-archtype-web
2.       Add dependencies in Maven
a.       Add jersey-bundle
b.       Ensure java 1.8 is used (not 1.5 as the default is set)
Pom.xml:
      <dependencies>
            <dependency>
                  <groupId>com.sun.jersey</groupId>
                  <artifactId>jersey-bundle</artifactId>
                  <version>1.19</version>
            </dependency>
      </dependencies>
      <build>
            <finalName>pidev</finalName>
            <plugins>
                  <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <version>3.1</version>
                        <configuration>
                              <source>1.8</source>
                              <target>1.8</target>
                        </configuration>
                  </plugin>
            </plugins>
      </build>
3.       Add Tomcat server library in Eclipse AND include in Order and Export
·         Build Path -> Configure Build Path -> Libraries -> Add Library -> Server Runtime -> Apache Tomcat 8.0
4.       Configure Jersey to listen for URI
       <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
                  <param-name>com.sun.jersey.config.property.packages</param-name>
                  <param-value><your package></param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
            <servlet-name>Jersey Web Application</servlet-name>
            <url-pattern>/rest/*</url-pattern>
      </servlet-mapping>


(Note that if the url-pattern is /* then url to address doesn’t need “rest” in the URI J)
5.       Write code
 package <your package>;

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

@Path("/xmlapi")
public class XMLAPI {
      @GET
      @Produces("application/xml")
      public String echo() {
            return ("<xmlapi>default echo</xmlapi>");
      }

      @Path("{c}")
      @GET
      @Produces("application/xml")
      public String echo(@PathParam("c") String c) {
            return ("<xmlapi>"+c+"</xmlapi>");
      }
}



For json
 package <your package>;

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

@Path("/jsonapi")
public class JsonAPI {
      @GET
      @Produces("application/json")
      public String echo() {
            return "{\"message\": \"default echo\"}";
      }

      @Path("{c}")
      @GET
      @Produces("application/xml")
      public String echo(@PathParam("c") String c) {
            return "{\"message\": \"" + c + "\"}";
      }
     

}
6.       Build and deploy
·         Maven -> Update project
·         Run project in Apache Tomcat
7.       Access the service
Output:
<?xml version="1.0"?>
<xmlapi>default echo</xmlapi>
Output:
<?xml version="1.0"?>

<xmlapi>hi</xmlapi>

Potential problems:
1.       Project don’t compile:
Java compiler level does not match the version of the installed Java project facet.
JAX-RS (REST Web Services) 2.0 requires Java 1.6 or newer.
One or more constraints have not been satisfied.
Maven default uses 1.5 J
Solution:
Add/update build element of pom.xml
      <build>
            <finalName><Project name></finalName>
            <plugins>
                  <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <version>3.1</version>
                        <configuration>
                              <source>1.8</source>
                              <target>1.8</target>
                        </configuration>
                  </plugin>
            </plugins>
      </build>

2.       Jersey didn’t load your mapping
com.sun.jersey.api.core.ScanningResourceConfig.init No provider classes found.
Solution:
In web.xml ensure that correct package is specified in init-param
      <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
                  <param-name>com.sun.jersey.config.property.packages</param-name>
                  <param-value><your package></param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
      </servlet>

3.       Status 500 UriBuilder
Duplicate UriBuilder J Usually it happens if you try different dependencies and one of those dependencies downloads it for you (e.g. jersey-bundle with jersey-server or jersey-apache-connector)
Solution:
Remove javax.ws.rs-api.jar. 

Saturday, November 21, 2015

Getting Up with Operation Management Suite in less than 30 min on Linux (CentOS/Ubuntu) and Windows

Operations Management Suite overview:

Quick guide to get up and running with OMS with basic features (Works in both V1(ASM) and V2(ARM)):
·         Create an OMS workspace (onetime setup)
·         Browse the OMS workspaces, setup the workspace, and install agents (Windows and Linux)
(Please note that OMS also has discoverabilities. You can also install the agent while provisioning the VMs.)
·         Check the LogAnalytics backed by superfast search which leverages Azure Machine Learning.
Step 1:
Go to https://manage.windowsazure.com à + New (from bottom left of the page) à App Services à Operational Insights à Quick Create à fill in the form…(start with “Free”)

Step 2:
Go to https://manage.windowsazure.com à Operational Insights à Select your workspace à Select manage à You can skip the email confirmation page à Go through the setting wizard à Select all the default solutions à On the connected sources, install the agents on the Linux/Windows (see below links for supported versions,) please note that this pane will also lists the servers those are being currently monitored à Select the performance counters under data tab à (optional) check from upgrade and account management under account tab.

Step 3:
Play with OMS. (Please note that OMS also provides REST APIs which returns JSON for advanced needs.)

References
·         OMS search reference: https://technet.microsoft.com/en-us/library/mt450427.aspx
·         https://technet.microsoft.com/en-us/library/mt484118.aspx --- Get Started with OMS
Advance:
1.       Automate log searches with the Log Search API: https://technet.microsoft.com/library/mt484116.aspx
2.       Leveraging the OMS Search API in an Azure Automation Runbook: https://azure.microsoft.com/en-us/blog/leveraging-the-oms-search-api-in-an-azure-automation-runbook/
4.       Azure / Azure Stack – IaaS VM ARM MMA & Operational Insights Template Integration: http://www.danielstechblog.de/azure-azure-stack-iaas-vm-arm-mma-operational-insights-template-integration/
5.       Connect computers directly to OMS: https://technet.microsoft.com/library/mt484108.aspx

---
I have tried today OMS with V1 VMs (windows 2012 R2 DC  + centos 7.1; picked from gallery) and V2 VMs (Windows + Ubuntu; picked from gallery) and worked like a charm.
From history of my centos:
uname -a
cd /tmp/
chmod +x omsagent-1.0.0-47.universal.x64.sh
./omsagent-1.0.0-47.universal.x64.sh --install -w <workspaceid> -s  <key>

ps -ef | grep oms

Saturday, July 11, 2015

Install, configure, and test mod_python/mod_wsgi/AWS tools/boto on Apache 2.x on CentOS 6.x

·        Download, compile, make, and install mod_python and mod_wsgi.

PS: mod_python shouldn’t be used. https://docs.python.org/2/howto/webservers.html covers the history and the reasoning for doing so.

Cmds: (as a privileged user)

cd /tmp/;mkdir mod_python_3.5.0;cd mod_python_3.5.0/

wget http://dist.modpython.org/dist/mod_python-3.5.0.tgz

gunzip mod_python-3.5.0.tgz

tar -xvf mod_python-3.5.0.tar

cd mod_python-3.5.0/

[If you don’t have apxs (APache eXtenSion) then install httpd development package]

yum install httpd-devel

./configure --with-python=/usr/local/bin/python2.7

[you can omit --with-python option if you want to use the default

make

sudo make install

ll /etc/httpd/modules/mod_python.so

 

cmds: (as privileged user)

cd /tmp/

mkdir mod_wsgi; cd mod_wsgi/

wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.4.12.tar.gz

tar -zxvf 4.4.12.tar.gz

cd mod_wsgi-4.4.12/

make

sudo make install

ll /usr/lib64/httpd/modules/mod_wsgi.so

ldd /usr/lib64/httpd/modules/mod_wsgi.so

httpd -M

service httpd restart

 

cmds: (as privileged user)

vi /etc/httpd/conf/httpd.conf

LoadModule wsgi_module modules/mod_wsgi.so

#inside VirtualHost or <Directory> where document root is defined:

    WSGIScriptAlias /myapp /var/www/wsgi-scripts/myapp.wsgi

 

    <Directory /var/www/wsgi-scripts/>

    Order allow,deny

    Allow from all

    </Directory>

apachectl configtest

service httpd restart

 

create a file with python content

vi /var/www/wsgi-scripts/myapp.wsgi

import sys

 

def application(environ, start_response):

    status = '200 OK'

 

    output = ''

    output += 'sys.version = %s\n' % repr(sys.version)

    output += 'sys.prefix = %s\n' % repr(sys.prefix)

 

    response_headers = [('Content-type', 'text/plain'),

                        ('Content-Length', str(len(output)))]

    start_response(status, response_headers)

 

    return [output]

 

Test:

curl localhost/myapp

sys.version = '2.7.9 (default, <MON> <DAY> <YYYY>, <<HH:MM:SS>) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-11)]'

sys.prefix = '/usr/local'

 


 

.bashrc file: (you decide you want for all user for a particular user. Pls note that for a particular user for boto they could have .boto file under their home dir)

export LD_LIBRARY_PATH=/usr/local/lib/python2.7

export LD_RUN_PATH=/usr/lib64/httpd/modules

export JRE_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.45-28.b13.el6_6.x86_64/jre/

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.45-28.b13.el6_6.x86_64

export EC2_HOME=/usr/local/ec2/ec2-api-tools-1.7.4.0/

export EC2_URL=https://ec2.us-west-1.amazonaws.com

export PATH=$PATH:$EC2_HOME/bin

export AWS_ACCESS_KEY=<your key>

export AWS_SECRET_KEY=<your secret>

export aws_access_key_id=<your key>

export aws_secret_access_key=<your secret>

 

source . bashrc

 

printenv | grep -i aws

 

 

Accessing boto within Apache

 

1.      Create a python virtual environment, install boto

2.      Create /etc/boto file and copy the contents of your boto file

3.      Configure Apache to use the virtual environment

 

    WSGIScriptAlias /myapp /var/www/wsgi-scripts/myapp.wsgi #mapping

    WSGIPythonHome /usr/local/lib/python2.7/site-packages/BASELINE #home of python virtual environment

    WSGIPythonPath /var/www/wsgi-scripts #path to your python scripts

4.      (optional) redirect output from existing python code so that phython module elsewhere needs minimal code change.

    output = cStringIO.StringIO()

    sys.stdout = stdout = cStringIO.StringIO()

    #call to your python code that uses boto for AWS

    print >> output, stdout.getvalue()