Thursday, January 18, 2018

CI/CD with Baby Steps (Jenkins - Build with Maven Project)

In last tutorial we automate our Eclipse Project build process with default "Freestyle Project" option of Jenkins, in which we scheduled build process with shell commands.

In this tutorial we will explore Jenkins "Maven Project" options.

Maven is a build / project management tool, based on the concept of a project object model (POM) which contains every information about your project. Maven allows a project to build using its project object model to manage builds, dependencies, releases and documentation which are all managed from the pom.xml file

In Jenkins 2.101 Maven Project is not available with default installation so we have to install plugin "Maven Integration plugin", So install plugin accordingy.

Maven Integration plugin
"This plug-in provides, for better and for worse, a deep integration of Jenkins and Maven:
Automatic triggers between projects depending on SNAPSHOTs, automated configuration of
various Jenkins publishers (Junit, ...)."

If Maven is not configured in Jenkins, Please configure

Configuring System
Go to Manage Jenkins-> Global Tool Configuration
1 - Configure JDK
-Give the JDK name
-JAVA_HOME : C:\Java\jdk1.8.0_121

2 - Maven configuration
-Give a maven name
-MAVEN_HOME : C:\Apache\apache-maven-3.5.0

Step 1 : Jenkins - New Item - Enter an Item name (any name) - select Maven project - click OK

it will show multi Tab windows

Step 2 : In General Tab provide description

Step 3 : In Source Code Management Tab, Jenkins supports CVS and Subversion out of the box, with built-in support for Git, and also integrates with many other version control systems via plugins. We will look into these details in next tutorials. Now lets make it simple and select 'None' to execute from local machine.

Step 4 : Build Triggers Tab, We have multiple options like 'Build periodically', 'Poll SCM', 'Build whenever a SNAPSHOT dependency is built, etc. Example, if you select 'Poll SCM' option, Jenkins will poll the repository for changes based on the cron expression specified. we will select
"Build periodically" which support Cron like job schedule like after 15 min or once a day.
As of now we will start with after every 5 minutes and put "H/5 * * * *" in schedule Text Field.

Step 5 : In Build, We need to tell Jenkins where to find pom.xml file. Please specify the path of your pom.xml file in Build Root POM and Specify 'Goals and options', in this example 'clean test'.
Root Pom: C:\Users\imran\workspace\GreenFarm\pom.xml
Goals and options: package

Step 6:- In Build Settings, If you want to send an email notifications, you can check 'Email Notification' and add Recipients address.

Saturday, January 13, 2018

CI/CD with Baby Steps (Jenkins - Build Periodically)

This is a first in a series of blog posts about CI/CD practices.


Build process before Continuous Integration had many flaws. Software delivery was slow and
Developers had to work hard in locating and fixing bugs due to run lot of stuff manually.


Continuous Integration is a development practice in which the developers are required to commit changes to the source code in a shared repository several times a day or more frequently. Every commit made in the repository is then built. the results of which will let you know if the code works or breaks. Apart from this, depending on the Continuous Integration tool, there are several other functions like deploying the build application on the test server, providing the concerned teams with the build and test results etc. If the build result shows that there is a bug in the code, then the developers only need to check that particular commit.
Now a days Companies are shifting from Nightly build to Continuous Integration.

Continuous Delivery involves the steps required to deploy to non-production environments. This
means that on top of having automated your testing(CI), you also have automated your release
process and you can deploy your releases at any point of time.

Continuous deployment is continuous delivery that extends to automatically pushing the
deployment to production once some predetermined criteria is met.

We will use Jenkin to automate these process.


Jenkins is an automation tool built for Continuous Integration purpose. Jenkins is used to build and
test your software projects continuously making it easier for developers to integrate changes to the project.
Jenkins achieves Continuous Integration with the help of plugins that allow it to integrate
with most of the development, testing and deployment tools. Its no more just a Continuous
Integration tool. It is a Continuous Integration and Continuous delivery tools.

Pre-Requisites
  • You have an IDE with Git support, such as Eclipse or a standalone Git client
  • Create a java program and run it through command line.
  • Download Jenkins Generic Java Package(.war)Jenkins
  • Create a Jenkins job to run the java program.

After developing any Java Project in Eclipse or Standalone, download Jenkin and start like below.
You can run Jenkins by executing the following from the Command Prompt:

java -jar jenkins.war --httpPort=9192
During first execution you would find following lines in command prompt
*************************************************************
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
c78510c3d7f04e878b42cb9f80a
This may also be found at: C:\Users\imran\.jenkins\secrets\initialAdminPassword
*************************************************************
Access Jenkins with  http://localhost:9192 and use admin/ to login and change password
accordingly.
Setting up Jenkins build server with Build periodically option
I already developed sample Springboot+ApacheCamel based application, I used Maven for
dependency management and build automation.
On local system i run following commands to compile, test and run
  • To Compile   `mvn install`
  • To Run `mvn spring-boot:run`
  • Run `mvn package` to create a JAR file in the `target` folder which can be deploy on other servers.
Now we will automate this for continuous integration by using Jenkins. We will create different Jenkins Jobs to automate this build process.


Step 1 : Jenkins - New Item - add details. it will show multi Tab windows


Step 2 : In General Tab provide description of Build Job.


Step 3 : Source Code Management Tab have different option if we want to integrate with SCM like GIT,
For current option we will select none.(In coming blogs we will integrate with GIT).


Step 4 : "Build Triggers" Tab provide different options to start/trigger build process, we will select
"Build periodically" which support Cron like job schedule like after 15 min or once a day.
As of now we will start with after every 5 minutes and put "H/5 * * * *" in schedule Text Field.


Step 5 : In Build section we can provide CommandPrompt/Shell commands, as we want to generate
JAR file we will enter below commands in command textfield


cd C:\Users\workspace\GreenFarm\
mvn clean package


Step 5 : "Post Build Actions" we will execute some scripts so we need "PostBuildScript" plugin.
"PostBuildScript" plugin makes it possible to execute a set of scripts at the end of the build.
Provide path for scripts file and it will get execute.


You can put contents like
java -jar greenfarm-1.0-SNAPSHOT.jar
curl -i http://localhost:8181/orders/1

Main purpose of this blog was to get introduced jenkin to old fashioned java developer,

coming blogs will cover more advanced topics.

Sunday, December 11, 2016

Bright your LED with Raspberry PI


In Last blog i setup Raspberry PI, Initially i planned to not write blog for this example as internet already provided lot of examples and tutorial for flashing LED with Raspberry PI. but during my experience to test with PI4J i tried to explain things in my way.

This will be step by step tutorial starting with connecting the cables then some explanations and writing code in PI4J.

The Raspberry Pi is single board computer which is very good for prototyping and it has 40 pins that can be configured for General Purpose I/O (GPIO) and more.

First fit T-shaped Cobbler breakout board via a ribbon cable on breadboard. This is easier and safer than working directly on Raspberry Pi.(Like showed in Pic on left side)

Pin Numbering
Due to Pin numbering issue i was not able to run my sample at first so i have to learn more.
Pi4J is based on a project called WiringPi, which is a set of native libraries that provide access to the RPi’s GPIO ports. The labeled name on cobbler is different then the name used by PI4J, The pin numbers and their mapping to the actual pins on the RPi header are given in the picture below. So refer below for running for your samples.
For basic concept i will recommend following link

Breadboard
The breadboard is a way of connecting electronic components to each other without having to solder them together. They are often used to test a circuit design before creating a Printed Circuit Board (PCB).
The holes on the breadboard are connected in a pattern.
LED
When you pick up the LED, you will notice that one leg is longer than the other. The longer leg (known as the ‘anode’), is always connected to the positive supply of the circuit. The shorter leg (known as the ‘cathode’) is connected to the negative side of the power supply, known as ‘ground’.
Resistor
You must ALWAYS use resistors to connect LEDs up to the GPIO pins of the Raspberry Pi. The Raspberry Pi can only supply a small current (about 60mA). The LEDs will want to draw more, and if allowed to they will burn out the Raspberry Pi. Therefore putting the resistors in the circuit will ensure that only this small current will flow and the Pi will not be damaged.

Building Circuit
The circuit consists of a power supply (the Pi), an LED that lights when the power is applied, and a resistor to limit the current that can flow through the circuit.
You will be using one of the ‘ground’ (GND) pins to act like the ‘negative’ or 0 volt ends of a battery. The ‘positive’ end of the battery will be provided by a GPIO pin. 
GPIO pin 0 --> Jumper one leg
Jumper Second leg --> long leg of LED(same column)
Short leg of LED --> 330Ω resistor --> Ground.

Find below picture



Now you can run pi4j example, follow below link


Raspberry PI setup in Headless Mode


Today i received my Raspberry PI 3 ultimate kit, The Raspberry Pi (RPi) is a single board computer based on the Broadcom BCM2835 System on Chip (SoC) it comes equipped with a General Purpose Input/Output (GPIO) connector, that can be used for connecting peripherals such as sensor, LEDs, motors etc.
 
I dont have monitor and keyboard to make it workable for me as i only have MAC laptop, After searching and reading different blogs and lot of different tries and failures following are steps which make my Raspberry PI accessible from my MAC without using any cable. Only requirement is you should have WiFi LAN, mostly we have for Internet connectivity

Unbox kit and assemble Raspberry PI as per Quick start guide provided by Vilros.

The microSD card that comes with kit already contains NOOBS(New Out of Box Software), When Pi will start and load the NOOBS tool, you can install Raspbian(its Linux distribution based on Debian, another popular version of linux) using NOOBS GUI.

To perform above steps we need Monitor and Keybooard but as we don't have so its recommended to prepare your MicroSD card using steps mentioned on this link http://elinux.org/RPi_Easy_SD_Card_Setup

So just put Card in your laptop Card reader and follow steps mentioned on above link. Keep card in card reader and do following configurations

edit following configuration on your card like

vi /etc/wpa_supplicant/wpa_supplicant.conf

add below line make sure values are in quotes don't remove it
network={
    ssid="wifi user name"
    psk="wifi network password"
}
To insert SD card, Make sure raspberry power is off and locate SD Card socket under side of Pi's board. Push SD card gently in socket.

Now when you Power On your PI you would be able to SSH but how to get IP of raspberry PI?

In my CISCO routers its like
status --> local network --> DHCP Client Table

I can see raspberrypi IP.

Now simply from the Laptop which is connected on same router just do

ssh pi@

and now Raspberry PI is in your control. :)

You can configure VNC Server if you still want to access raspberry PI in desktop environment.

To configure VNC Server from command line of same ssh do following

pi@raspberry:/ sudo raspi-config

Your command prompt would be like


Navigate to Advanced Options
scroll down and select VNC and select Yes

Then run vncserver, Make note of the IP Address/display number like 192.168.1.6:1

Now from your laptop use VNC Viewer and provide above mentioned info. You Can access Raspberry PI in GUI mode.

Friday, October 2, 2015

MMS with Apache Camel

Following is the sample code to send MultiMedia message to MMSc over MM7 protocol

public class MmsRouter extends RouteBuilder {

     public void configure() {
        from("timer:foo?period=5m")
        .process(    new MmsPreProcessor()      )
        .to("http://x.x.x.x/vasp/servlet/messagerouter");
    }

}

public class MmsPreProcessor implements Processor {

       @Override
       public void process(Exchange exchange) throws Exception {

              MessageFactory factory = MessageFactory.newInstance();
              SOAPMessage soapMeassage = factory.createMessage();

              SOAPEnvelope envelope = soapMeassage.getSOAPPart().getEnvelope();
           
              SOAPHeader header = envelope.getHeader();
              SOAPBody body = envelope.getBody();

              SOAPFactory soapFactory = SOAPFactory.newInstance();

              //Header
              Name headerName = soapFactory.createName("TransactionID", "mm7", "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-4");

              SOAPHeaderElement headerElement = header.addHeaderElement(headerName);
              headerElement.setTextContent("TID.1234567");
              headerElement.setMustUnderstand(true);
           
              //Soap message body
              Name submitReqName = soapFactory.createName("SubmitReq");
              SOAPBodyElement submitReq = body.addBodyElement( submitReqName );
         
              SOAPElement MM7Version =  submitReq.addChildElement(  soapFactory.createName("MM7Version") );
              MM7Version.setTextContent("6.8.0");

              //SO senderIdentification
              SOAPElement senderIdentification =  submitReq.addChildElement( soapFactory.createName("SenderIdentification") );
           
              SOAPElement vaspID =  senderIdentification.addChildElement( soapFactory.createName("VASPID") );
              vaspID.setTextContent("vaspid");
              SOAPElement vasID =  senderIdentification.addChildElement( soapFactory.createName("VASID") );
              vasID.setTextContent("1234");

              SOAPElement senderAddress =  senderIdentification.addChildElement( soapFactory.createName("SenderAddress") );
              SOAPElement shortCode =  senderAddress.addChildElement( soapFactory.createName("Number") );
              shortCode.setTextContent("9394");

              SOAPElement recipients =  submitReq.addChildElement( soapFactory.createName("Recipients") );
              SOAPElement to =  recipients.addChildElement( soapFactory.createName("To") );
              SOAPElement number =  to.addChildElement( soapFactory.createName("Number") );
              number.setTextContent("+9xxxxxxxxx");

              SOAPElement messageClass =  submitReq.addChildElement( soapFactory.createName("MessageClass") );
              messageClass.setTextContent("Auto");

              SOAPElement subject =  submitReq.addChildElement( soapFactory.createName("Subject") );
              subject.setTextContent("Hello World");
           
              Name contentName = soapFactory.createName("Content");
              SOAPElement contentElement =  submitReq.addChildElement( contentName );
              contentElement.addAttribute(envelope.createName("href"), "cid:mm7-content");
              contentElement.addAttribute(envelope.createName("allowAdaptations"), "false");
           
              DataHandler dataHandler = new DataHandler(  new URL("file:///abc.jpg")   );
              AttachmentPart imgAttachment = soapMeassage.createAttachmentPart( dataHandler );
              imgAttachment.setContentId("mms-content-img");

              soapMeassage.addAttachmentPart( imgAttachment );

              exchange.getOut().setHeader(Exchange.HTTP_METHOD,"POST");

 Iterator it = soapMeassage.getMimeHeaders().getAllHeaders();
                 
              while (it.hasNext()) {
                   MimeHeader mimeHeader = (MimeHeader) it.next();
                   exchange.getOut().setHeader(mimeHeader.getName(),mimeHeader.getValue());
              }
                       
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
              soapMeassage.writeTo(baos);

              exchange.getOut().setBody( baos );
           
       }

}

Any suggetions to improve above code are welcome.

Tuesday, July 8, 2014

Running Java Application with Solaris SMF as Non-Root User

Sample SMF manifes file

<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type="manifest" name="myapp">
         <service name="application/management/myapp" type="service" version="1">
                 
<!-- Initial state of the service is disabled -->
<create_default_instance enabled="false" />
 
<single_instance />
                 
<dependency name="multi-user-server" type="service" grouping="require_all" restart_on="none">
    <service_fmri value="svc:/milestone/multi-user-server" />
</dependency>
                 
<exec_method type="method" name="start"     exec="/opt/bin/myapp.sh start" timeout_seconds="-1">
    <method_context>
       <method_credential user='myuser' group='other' />
           <method_environment>
  <envvar name='PATH' value='/usr/bin:/usr/sbin:/usr/ccs/bin:/usr/local/bin:/usr/local/sbin:/usr/sfw/bin' />
  <envvar name='JAVA_HOME' value='/usr/java/' />
       </method_environment>
   </method_context>
</exec_method>
                          
<exec_method type="method" name="stop"      exec="/opt/bin/myapp.sh stop" timeout_seconds="-1">
  <method_context>
  <method_credential user='myuser' group='other' />
      <method_environment>
<envvar name='PATH' value='/usr/bin:/usr/sbin:/usr/ccs/bin:/usr/local/bin:/usr/local/sbin:/usr/sfw/bin' />
<envvar name='JAVA_HOME' value='/usr/java/' />
      </method_environment>
 </method_context>
 </exec_method>
                 
<property_group name='start' type='method'>
<propval name='action_authorization' type='astring' value='solaris.smf.manage.myapp' />
<propval name='modify_authorization' type='astring' value='solaris.smf.manage.myapp' />
<propval name='value_authorization'  type='astring'  value='solaris.smf.manage.myapp' />
</property_group>
<property_group name='stop' type='method'>
<propval name='action_authorization' type='astring' value='solaris.smf.manage.myapp' />
<propval name='modify_authorization' type='astring' value='solaris.smf.manage.myapp' />
<propval name='value_authorization'  type='astring' value='solaris.smf.manage.myapp' />
</property_group>
<property_group name='general' type='framework'>
<propval name='action_authorization' type='astring' value='solaris.smf.manage.myapp' />
<propval name='value_authorization'  type='astring' value='solaris.smf.manage.myapp' />
<propval name='modify_authorization' type='astring' value='solaris.smf.manage.myapp' />
                  </property_group>
 
                 <stability value="Unstable" />
 
                 <template>
                          <common_name>
                                   <loctext xml:lang='C'>My Application</loctext>
                          </common_name>
                 </template>
         </service>
</service_bundle>

Now perform following steps from root users
  • svccfg validate myapp-smf.xml
  • Add line in /etc/security/auth_attr solaris.smf.manage.myapp:::MyApp Management::
  • usermod -A solaris.smf.manage.myapp myuser(make sure myuser is not logged in)
  • svccfg import /opt/smf/myapp-smf.xml
Now logged as myuser and verify/start/stop application with following commands
svcs -l myapp
svcadm enable myapp
svcadm disable myapp

Saturday, April 5, 2014

Parlay Rest SMS with Apache Camel

Following sample will use http4 Apache component to send Sms using Parlay Rest Specification

package com.test.rest.sms;

import org.apache.camel.main.Main;

public class TestRestSms {

public static void main(String[] args) throws Exception {
            Main main = new Main();
            main.enableHangupSupport();
            main.addRouteBuilder(new TestRestSmsRoute());
            System.out.println("Starting Camel. Use ctrl + c to terminate the JVM.\n");
            main.run();
}
}

Following is RouterClass

import org.apache.camel.builder.RouteBuilder;

public class TestRestSmsRoute extends RouteBuilder {

@Override
public void configure() throws Exception {

from("timer://foo?delay=0&period=20000")
.process(new SendSmsRequest())
.to("http4://172.21.7.1:5001/rest/sms/messages")
.process(new SendSmsResponse())
}

}

Following are processor classes

import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Message;
import org.apache.camel.Processor;

public class SendSmsRequest implements Processor  {

@Override
public void process(Exchange exchange) throws Exception {

exchange.getIn().setHeader(Exchange.HTTP_METHOD, "POST");
exchange.getIn().setHeader(Exchange.CONTENT_TYPE,"application/json");
   
String toAddress = "\"addresses\": [\"tel:6666666666\"]";
String fromAddress = "\"senderName\": \"tel:321\"";
String msgText = "\"message\": \"hello world\"";
        String sms                 = "{"+toAddress+","+fromAddress+","+msgText+"}";

        exchange.getIn().setBody(sms);

} //

}

public class SendSmsResponse implements Processor  {

@Override
public void process(Exchange exchange) throws Exception {

Object result = exchange.getIn().getBody();

System.out.println("sms response="+result);

}

}