Tuesday, January 30, 2018

GETTING STARTED WITH JAVA, TRAVIS CI AND HEROKU.


Hi there!

This post will drive you into a basic application in Spring Boot, building through Travis CI and finally deploying to Heroku.
First of all , Lets clone the sample Hello World Spring Boot project through eclipse, which I have already integrated from Travis CI and deployed to Heroku, from here. The project structure will look like below.



















After cloning the project through eclipse, you can simply commit the project to your Github Repository.

TRAVIS-CI

Travis CI is a continuous integration service used to build and test software projects. It will be listening to our commits on Github and make all the deploy process for us. You can sign in with your Github account.



Once logged in , click in the + button (besides "My repositories" text) sync your account and enable the repository of our project.

Now we have to instruct Travis how to build the project. These instructions are already in the .travis.yml file which is in the Project directory.

Since this is a Java project we have to set the language as Java and the relevant jdk.

.travis.yml


language: java
jdk:
 - oraclejdk8
deploy:
 provider: heroku
 api-key: 
  secure: $HEROKU_API_KEY
 app: traviscitestashen

You can also set the build phase as <script: ./mvnw clean install> inside yaml file. This will bypass the default phase.
./mvnw install -DskipTests=true -Dmaven.javadoc.skip=true -B -V

HEROKU

Heroku is a Paas cloud computing service that supports several programming languages.
To get started, first we have to create an account, then create an app.
We have to give instructions how to correctly deploy our app.  For that we have to create a Procfile which is already created in the project root directory.

Procfile 

web: java $JAVA_OPTS -Dserver.port=$PORT -jar target/*.jar -Dspring.profiles.active=prod

Make sure packaging in pom.xml is set to jar file.

Next we have to teach Travis CI to deploy the project on Heroku after integration services are passed.
First we have to copy HEROKU API KEY from account settings.

After that, go to your repository settings in Travis CI and add a new variable called "HEROKU_API_KEY" and for the value, paste the copied Heroku Api Key.



Next you have to enable automatic deploy and tick 'wait for CI to pass" checkbox in your Heroku app deploy section.



Thats it! The configurations that is required to deploy the app are already in the .travis.yml file as

deploy:
 provider: heroku
 api-key: 
  secure: $HEROKU_API_KEY
 app: traviscitestashen

Note that the app name in yaml file should be the same as the app name in Heroku.

Now it's time to test the continuous integration and continuous deployment. Add a change to the project and commit it to your Github repo. Travis Ci will start the integration and if all goes well (excited with 0 in console) you should get a output as below and if not, app will not be deployed to Heroku.













After all the integration services are passed , Travis Ci will deploy the app to Heroku.



Alright That's it folks, now you can open the app from Heroku dashboard and you should be able to  see a output as shown below.



Links
https://docs.travis-ci.com/user/languages/java
https://blog.frankel.ch/travis-ci-tutorial-for-java-projects/
https://blog.javabien.net/2015/08/21/travis-ci-on-a-java-project-with-docker-support/

Happy Coding! :)

~ Ashen Jayasinghe ~

Monday, January 29, 2018

REST WS using Apache Camel CXFRS Component



Hi there!
In this post, I will try to explain how to write a web service using Apache Camel CXFRS component.
It will be a simple web service that will accept a GET and a POST request and returns a plain text output for the GET request and a JSON object for the POST request.

1. Start by creating a simple Maven Project , Choose the archetype of webapp. The final project structure will appear as follows.


2. Include the below dependencies in the pom.xml file.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>ExampleRestAPI</groupId>
  <artifactId>com.restapi</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>Rest Api Camel </name>
  <description>Rest API Camel project</description>
 
<properties>
<camel-web>2.5.0</camel-web>
<camel-version>2.12.0</camel-version>
<xbean-spring-version>3.5</xbean-spring-version>
</properties>
 
<dependencies>
 
<!-- Spring + Camel jars -->
 
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>${xbean-spring-version}</version>
</dependency>
 
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel-version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>${camel-version}</version>
</dependency>
 
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stream</artifactId>
<version>${camel-version}</version>
</dependency>
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
 
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>${camel-version}</version>
</dependency>
 
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf-transport</artifactId>
<version>${camel-version}</version>
</dependency>
 
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>2.7.6</version>
</dependency>
 
<!-- Other jars (logging, io etc) -->
 
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
 
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
 
</dependencies>
</project>

We have used Apache Camel cxf jars , SLF4J jars , Apache common IO , Spring jars. Spring jars are used to load the Application Contexts automatically.

2. After adding the dependencies, start creating the required resources. First we will start creating the servlet which listens to the input html requests. The contents of the  WEB-INF/web.xml file will look as below.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <context-param>
 <param-name>test</param-name>
 <param-value>true</param-value>
 </context-param>
 <context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>/WEB-INF/applicationContext.xml</param-value>
 </context-param>
 <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
</web-app>

Here we have added the applicationContext.xml as the contextConfigLocation and the listener class.
In the applicationContext.xml file, we have to set the route for all implementation classes.

3. Add the below configurations to the WEB-INF/applicationContext.xml file.


<?xml version="1.0" encoding="UTF-8"?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
 license agreements. See the NOTICE file distributed with this work for additional
 information regarding copyright ownership. The ASF licenses this file to
 You under the Apache License, Version 2.0 (the "License"); you may not use
 this file except in compliance with the License. You may obtain a copy of
 the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License. -->
 
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:camel="http://camel.apache.org/schema/spring" xmlns:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
 http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
 ">
 
<bean id="contextApplicationContextProvider" class="conf.ApplicationCtxProvider"></bean>
 
 <camelContext xmlns="http://camel.apache.org/schema/spring"
 id="Demo-Camel">
 
 <!-- All the Routes should be created within below Package -->
 <camel:package>camel.route</camel:package>
 
 </camelContext>
 
</beans>

In here we have added the route for all implementation classes under camelContext/camel:package as  camel.route which has the DemoRouteBuilder class that contains the REST endpoint URI.

4. Add the applicationContexts classes. These classes are loaded during spring initializing.

ApplicationCtx.java


package conf;
 
import org.springframework.context.ApplicationContext;
 
public class ApplicationCtx {
 
private static ApplicationContext ctx;
 
// Injected from the class "ApplicationCtxProvider" which is automatically loaded during Spring-Initialization.
 
public static void setApplicationContext(
ApplicationContext applicationContext) {
ctx = applicationContext;
}
 
// Get access to the Spring ApplicationContext from everywhere in your Application.
 
public static ApplicationContext getApplicationContext() {
return ctx;
}
}

ApplicationCtxProvider.java


package conf;
 
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
 
public class ApplicationCtxProvider implements ApplicationContextAware {
 

public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
ApplicationCtx.setApplicationContext(ctx);
}
}

5. Add the camel router implementation to DemoRouteBuilder.java file. This class handles all the REST calls to the REST service. It will run automatically when the server starts since the location is mentioned in the applicationContect.xml file as camel.route. It consist of cxfrs endpoint URI and resourceClasses which points to the request service classes in camel.rs.

DemoRouteBuilder.java 


package camel.route;
 
import org.apache.camel.builder.RouteBuilder;
 
import camel.process.MappingProcessor;
import rs.RequestServiceImpl;
 
public class DemoRouteBuilder extends RouteBuilder {
 
private static final String REST_ENDPOINT_URI = "cxfrs://http://localhost:9003/rest?resourceClasses=rs.RequestServiceImpl";
 
@Override
public void configure() {
errorHandler(noErrorHandler());
 
from(REST_ENDPOINT_URI)
.routeId("RestFulService")
.process(new MappingProcessor(new RequestServiceImpl()));
}
 
}

6. Content of camel process is implemented by MappingProcessor.java file.


package camel.process;
 
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.component.cxf.common.message.CxfConstants;
public class MappingProcessor implements Processor {
 
private Class<?> beanClass;
private Object instance;
 
public MappingProcessor(Object obj) {
beanClass = obj.getClass();
instance = obj;
}
 
public void process(Exchange exchange) throws Exception {
String operationName = exchange.getIn().getHeader(CxfConstants.OPERATION_NAME, String.class);
Method method = findMethod(operationName,exchange.getIn().getBody(Object[].class));
try {
Object response = method.invoke(instance, exchange.getIn().getBody(Object[].class));
exchange.getOut().setBody(response);
} catch (InvocationTargetException e) {
throw (Exception) e.getCause();
}
}
 
private Method findMethod(String operationName, Object[] parameters)throws SecurityException, NoSuchMethodException {
return beanClass.getMethod(operationName,getParameterTypes(parameters));
}
 
private Class<?>[] getParameterTypes(Object[] parameters) {
if (parameters == null) {
return new Class[0];
}
Class<?>[] answer = new Class[parameters.length];
int i = 0;
for (Object object : parameters) {
answer[i] = object.getClass();
i++;
}
return answer;
}
 
}

7. Now we will start by coding the java resource which will handle the rest request. It will consist of a interface and a implementation class. The interface class will contain the web service annotations where as the implementation class will respond to the client requests. Here the paths are defined by using the path annotation. The main path is /book.  Each method defined in this class must be called staring from http://localhost:9003/rest/book. The interface class will look as below.

RequestService.java


package rs;
 
import javax.jws.WebParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
 
@Path("/book")
@Consumes("application/json")
@Produces(MediaType.APPLICATION_JSON)
public interface RequestService {
 
 @GET
 @Path("/author/{id}")
 @Produces(MediaType.APPLICATION_JSON)
 Response getAvailabilityResults(@PathParam("id") Long id); 
 
 @POST
 @Path("/search")
 @Produces(MediaType.APPLICATION_JSON)
 String getSearhResults(@WebParam(name="request") String request); 
 
}

RequestServiceImpl.java


package rs;
 
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class RequestServiceImpl implements RequestService {
 
 final Logger logger = LoggerFactory.getLogger(RequestServiceImpl.class);
 
 public String getSearhResults(String request) {
 
 logger.info("getSearhResults().request : " + request);
 
 return "Hello request " + request;
 }
 
 public Response getAvailabilityResults(Long id){
 
 logger.info("getAvailabilityResults().Long : " + id);
 return Response.ok("Hello request ID :"+id).status(Status.OK).build();
 }
 
}

And that is all you require to write a REST web service with cxfrs component.

Build the project from Maven. I have used clean install package as the Maven goal in Eclipse.
Deploy the war file in a web container like Tomcat. I have used Tomcat 8 for this project.

Finally test the GET and POST methods using a rest client. I have used Postman.

GET 

















POST


Also note that getSearhResults() method in RequestService class which accept POST requests only consumes json objects. If we remove the Consume annotation and send a XML input in the body, the
getSearhResults(0 will get invoked and you will be able to see the xml input. You can send any content type with the resource url and the method will get invoked as long as it doesn't contain consume annotation which consumes a specific content type. The example is below for your reference.



Happy Coding !!!

~ Ashen Jayasinghe ~


Monday, September 4, 2017

AngularJs , Java Rest (JAX-RS) , RestEasy , Wildfly AS and Elastic Search CRUD Tutorial.

Hi there!
In this tutorial I have used AngularJs as the frontend , Java Restful web services and RestEasy as the backend, Elastic Search as the database and finally deployed to Wildfly Application Server.

The reason I have used RestEasy Framework is because it comes bundled with JBoss / Wildfly Application Server making it more easier to implement restful web services.

This project has two classes. UserController class which is the rest web service and the RestEasy ApplicationConfig class which is a empty class only used to bootstrap JAX-RS and not a directly used class.

Prerequisites

Elastic Search and Wildfly AS running.
Eclipse IDE.
Maven, Java installed.

Download source codes

UserController.java


package org.ashen.domain.controller;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;


import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

@Path("/userlist")
public class userController {
 
 //userService userService=new userService();
 
 TransportClient client;

    public userController() throws UnknownHostException {
        client = new PreBuiltTransportClient(Settings.EMPTY)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));

    }
    
    @GET
    @Produces(MediaType.APPLICATION_JSON)

    public Map<String , Object> getAllUsers() {
        GetResponse getResponse = client.prepareGet("employee", "id", "1")
        .get();
        System.out.println(getResponse.getSource());
        return getResponse.getSource();
    } 
 

    @GET
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String, Object> getAUser(@PathParam("id") final String id) {

        GetResponse getResponse = client.prepareGet("employee", "id", id).get();
        System.out.println(getResponse.getSource());

        return getResponse.getSource();
    }
   
    
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String insert(String sname , String sage) throws IOException {

     IndexResponse response = client.prepareIndex("employee", "id", "1")
                 .setSource(jsonBuilder()
                         .startObject()
                         .field("name", sname)
                         .field("age", sage)

                         .endObject()
                 )
                 .get();
         return response.getResult().toString();

      }

    @DELETE
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public String delete(@PathParam("id") final String id) {
 
    DeleteResponse deleteResponse = client.prepareDelete("employee", "id", id).get();

        System.out.println(deleteResponse.getResult().toString());
        return deleteResponse.getResult().toString();
    }
 
 
}

The TransportClient code inside the constructor connects remotely to an Elasticsearch cluster using the transport module. It does not join the cluster, but simply gets one or more initial transport addresses and communicates with them.

RestApplicationConfig.java


package org.ashen.domain.restconfig;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

/**
 * Used to bootstrap JAX-RS.  Otherwise this class is
 * not directly used.
 *
 */
@ApplicationPath("/rest")
public class RestApplicationConfig extends Application {
 // intentionally empty
}

index.html


<html>
  <head>  
  
  <script src="lib/angular.js"></script>
    <script src="lib/angular.min.js"></script>
    <title>Sample Application</title>  
 <script type="text/javascript">
            var app = angular.module("userManagement", []);
         
            //Controller Part
            app.controller("userController", function($scope, $http) {
         
               
                $scope.userlist = [];
                $scope.userForm = {
                    id : -1,
                    userName : "",
                    age : ""
                };
         
                //load the data from server
              
                _refreshuserData();
         
                //HTTP POST/PUT methods for add/edit user 
             
                $scope.submituser = function() {
         
                    var method = "";
                    var url = "";
                    if ($scope.userForm.id == -1) {
                        //Id is absent in form data,create new user operation
                        method = "POST";
                        url = 'rest/userlist';
                    } else {
                        //Id is present in form data, edit user operation
                        method = "PUT";
                        url = 'rest/userlist';
                    }
         
                    $http({
                        method : method,
                        url : url,
                        data : angular.toJson($scope.userForm),
                        headers : {
                            'Content-Type' : 'application/json'
                        }
                    }).then( _success, _error );
                };
         
                //HTTP DELETE- delete user by Id
                $scope.deleteuser = function(user) {
                    $http({
                        method : 'DELETE',
                        url : 'rest/userlist/' + user.id
                    }).then(_success, _error);
                };
 
             // In case of edit, populate form fields and assign form.id with user id
                $scope.edituser = function(user) {
                  
                    $scope.userForm.userName = user.userName;
                    $scope.userForm.age = user.age;
                    $scope.userForm.id = user.id;
                };
         
                /* Private Methods */
                //HTTP GET- get all userlist collection
                function _refreshuserData() {
                    $http({
                        method : 'GET',
                        url : 'http://localhost:8080/angularCrudJava/rest/userlist'
                    }).then(function successCallback(response) {
                        $scope.userlist = response.data;
                    }, function errorCallback(response) {
                        console.log(response.statusText);
                    });
                }
         
                function _success(response) {
                    _refreshuserData();
                    _clearFormData()
                }
         
                function _error(response) {
                    console.log(response.statusText);
                }
         
                //Clear the form
                function _clearFormData() {
                    $scope.userForm.id = -1;
                    $scope.userForm.userName = "";
                    $scope.userForm.age = "";
                
                };
            });
        </script>
        
    <head>
    <body ng-app="userManagement" ng-controller="userController">
         <h1>
          Sample Application using AngularJs , Java 
        </h1> 
        <form ng-submit="submituser()">
            <table>
               
                <tr>
                    <th colspan="2">User Details</th>
                 </tr>
                <tr>
                    <td>Name</td>
                    <td><input type="text" ng-model="userForm.userName" /></td>
                </tr>
                <tr>
                    <td>age</td>
                    <td><input type="text" ng-model="userForm.age"  /></td>
                </tr>
                <tr>
                    <td colspan="2"><input type="submit" value="Submit" class="blue-button" /></td>
                </tr>
            </table>
        </form>
        <table>
            <tr>
              
                <th>user</th>
                <th>age</th>
                <th>operations</th>
               
            </tr>
 
            <tr ng-repeat="userd in userlist">
            <td> {{ userd .name }}</td>
            <td >{{ userd .name }}</td>  
            <td>{{userd}}</td>
            <td><a ng-click="edituser(user)" >Edit</a> | <a ng-click="deleteuser(user)">Delete</a></td>
            </tr>
 
        </table>
 
   </body>
</html>

After downloading the project, Update the project using Maven, and set the goal as
" clean package wildfly:deploy " to deploy the application.

Test the client server interaction from Advance rest client using the below url.

http://localhost:8080/angularCrudJava/rest/userlist

and finally test the CRUD UI with this url

http://localhost:8080/angularCrudJava/

Sunday, September 3, 2017

Validation Of Duplicate and Empty Rows in JavaScript

Hi there!

In this blog post you will learn how to avoid (validate) duplication and empty rows in a table when you search and select data from a drop down list.

 So every time when I want to implement this validation at my work place I use a common function to identify the id of the selected data (object) from the drop down list and the id of already stored objects and if they are matching or equal, the function will return true hence not allowing duplicate rows. Below is the common function to avoid duplicate rows.

function containsObject(obj, list) {
    var i;
    for (i = 0; i < list.length; i++) {
        if (list[i].id === obj.id) {
            return true;
        }
    }
    return false;
}


Paste the above function somewhere in your controller and call it in the function used to add data to the table. For an example, suppose you want to add user details to a table and you have a function called "AddUserDetails".

$scope.AddUserDetails = function () {

         var tempList = { } ; 
     
         tempList.id = $scope.selectedUserDetails.id;

         templist.name= $scope.selectedUserDetails.name;

         if ( !containsObject (tempList , storedUserList )

         {
             $scope.storedUserList.push ( tempList ) ;
         }
}


The newly selected object is passed to an array called "tempList" and that object in tempList is checked with every object that is stored in the "storedUserList" array by the common function. If there are matching id's of objects in those two arrays, the function will not push the selected object to the storedUserList array.

----- Happy Coding! -----





Sunday, July 9, 2017

Simple CRUD application with User Authentication and Registration using PHP Codeigniter Framework

Hi there!
This is a News application which can perform User Authentication and Registration for users and also performs CRUD operations of News item using MVC architecture. News item contains title and text content. I have used WAMP software bundle.

First of all, create a database named "testdb" and a table named "news".

CREATE DATABASE `testdb`;
use `testdb`;

--
-- Table structure for table `news`
--

CREATE TABLE IF NOT EXISTS `news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(128) NOT NULL,
`slug` varchar(128) NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`id`),
KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

--
-- Dumping data for table `news`
--

INSERT INTO `news` (`id`, `title`, `slug`, `text`) VALUES
(1, 'Test', 'test', 'Hello World !!'),
(2, 'What is Lorem Ipsum?', 'what-is-lorem-ipsum', 'Lorem Ipsum is simply dummy text.');


Click here to download the full code from GitHub.







Thursday, July 6, 2017

Weather Monitoring System - Java Socket Programming and Java RMI.

This is a client and server application developed using NetBeans IDE 8.2 to measure the average rainfall, Humidity, Temperature and Air pressure of the base stations around the country. This system has used Java Socket programming and Java Remote Method Invocation to communicate between sensor, server and client.

A Sensor emulator program is used to send randomly generated data to the server periodically during 1 hour intervals through sockets and the data between server to client is sent using Remote Method Invocation.


Client thereby execute the login GUI and authenticate the Monitoring Stations(clients). After the authentication the weather details are sent to the Weather GUI to be shown for the user.

Click here to download the source code from GitHub.

Sequence Diagram

High Level Architectural Diagram with Software components.




Friday, June 30, 2017

Pharmacy Management System - SLIIT Project NodeJs , AngularJs , MongoDB

This is a pharmacy management system for a hospital developed for the 3rd year first semester final project by 4 members. The system will manage all the pharmaceutical operations to provide comprehensive pharmacy services. Basic features of this system would be managing the drug inventory, patient medical profiles, drug dispensing and prescription management. The main users of this system would be the chief pharmacist, assistant pharmacists, and doctors. They have to login to the system in order to use the services available.

The main benefits of this system are reducing manual data entry, reducing human errors, saves time, and increased efficiency. The system is able to generate customized reports on each of the services when required.

Technologies Used 

  • AngularJS for the front end
  • Github 
  • MongoDB ,Mongoose Library,  ExpressJS and NodeJS for the backend.
  • JetBrains WebStorm IDE


Backend is an API running JSON based web services. The front-end application communicates with the back end only using these web services. 

My part was to monitor the drug stock level and decide whether to re-order from drug suppliers via email after the approval of chief pharmacist if drug levels are low and record supplier details.

Click here to download the source code from GitHub.









Thursday, June 29, 2017

ng-model in AngularJS

Models in Angular.JS are represented by the "ng-model" directive. The primary purpose of this directive is to bind the "view" to the "model".

The ng-model attribute is used for,

  • Binding controls such as input, text area and select in the view into the model. 
  • Provide a validation behavior - for example a validation can be added to a textbox that only numeric characters can be entered into the textbox. 
  • The ng-model attribute maintains the state of the control (By state, we mean that the control and the data is bound to be always kept in sync. If the value of our data changes , it will automatically change the value in the control and vice versa)