Sunday, February 18, 2018

CI/CD with Baby Steps (Jenkins - Build with Git Hooks)

Git is the most widely used modern version control system in the world today, which allows multiple persons to safely work on the same project without hampering other team members. As a part of a team using Git, You and your team members will clone working copy of a local repository from Git server. You/team will add and commit the test scripts that are developed locally and push your changes to the Git.
We can make Jenkins to pull the project’s source code from the remote Git Server, by selecting the option in Source code management and specify the path/url can find the source code of the project.

Git hooks automate things like…
  • verifying that you included the associated JIRA issue key in your commit message
  • enforcing preconditions for merging
  • sending notifications to your team’s chat room
  • setting up your workspace after switching over to a different branch
Server-side pre-receive hooks are an especially powerful compliment to continuous integration because they can prevent developers from pushing code to master, unless the code meets certain conditions – like elite ninja guardians, protecting it from bad code.
Developers are generally conscientious enough not to merge to master when there are broken tests on their branch. But sometimes we forget to check. Or when we’re sharing a branch with other people, sometimes more changes get made since we last checked the branch build… stuff happens.
So you can add a server-side hook that looks for incoming merges to master. When it finds one, the script checks the latest build on your branch, and if there are any failing tests, the merge is rejected.

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. We will select Git and provide Repository URL like C:\Users\Imran\workspace\GreenFarm\.git

Step 4 : Build Triggers Tab, We will select Trigger builds remotely (e.g., from scripts) and also set Authentication Token.

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.

Now configure project with git like below

Command Prompt/Shell
Eclipse GUI
  1. Open up your terminal
  2. Navigate to your project directory
  3. Type git init to create a repository
  4. Assuming you already have files in that folder, type git add --all to add all your files to the repository (Note: if you skip this step, you will have an empty repository. You can also use git add filename to add only specific files/folders)
  5. Type git commit -m "your message here" to perform your first commit
At this point, you have a brand new local repository containing your files! The following steps will hook it up to a remote repository.
  1. Create your remote repository (using GitHub as an example, simply click the New button, and follow the prompts.
  2. Open up your terminal and navigate to your project directory
  3. On the page for your repository, you should see an HTTPS link ending in your-repository-name.git
  4. Paste git remote add origin into your terminal, followed by that HTTPS link
  5. Paste git push -u origin master into your terminal (Note: these last two steps are shown on the GitHub new project page as well, for easy copy-and-pasting into your terminal)
Now you have a local repository connected to a remote repository, ready to use! All Eclipse projects exist somewhere in your file system, and can easily be accessed just like any other folder you might want to turn into a repository.
I do realize you asked to avoid the command line, but this is a relatively simple command line task, and learning to be somewhat familiar with how to use your command line can pay big dividends later on.

Right click on the project, select Team then Share and you will be prompted to select the tool you prefer. Select git and go on.

Next, let's navigate to the .git/hooks directory in our project

Here create file post-commit with following content

#!/bin/sh

curl --user admin:2d910402b37e32a4279fb7523f9066be http://localhost:9192/job/GreenFarmJob-GitHooks/build?token=myhooktoken

now whenever you performed commit it will trigger this script.

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