Friday, 14 September 2018

SpringBoot restApi With Derby database

Tools & Techniques used:
Java
Maven
SpringBoot
RestApi 
Derby database

Derby is a full JDBC database, It can be used as a standalone database need not to be installed. Just need to point to an empty folder where it will create the data files. unlike in-memory database, the data can be persisted to the files.

The example illustrates the creation of an entity "user" and saves the data in the "users" table in derby.
crud operations: user:  add, edit, serachById, del, hard-delete are demonstrated through rest APIs.  

pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.13.1.1</version>
</dependency>

application.properties
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true

JpaConfig.java    custom class to configure the data source
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JpaConfig {
        // primary Springboot datasource will be overwritten.
@Bean
public DataSource getDataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url("jdbc:derby:/Database/Derby/DB-Data;create=true");
                //the database will be created at path c:/Database/Derby/DB-Data in windows
                //bydefault userid/password are not required by derby though can be provided.
return dataSourceBuilder.build();
}
}
Entity class User.java 

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "id")
int id;
@Column(name = "userid")
String userid;
@Column(name = "password")
String password;
@Column(name = "role")
String role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
UserRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.letUsLearn.entity.User;

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
}

UserService.java
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.letUsLearn.entity.User;
import com.letUsLearn.repositiry.UserRepository;

@Service
public class UserService {

@Autowired
UserRepository repository;

public User getUserById(int id) {
return repository.findById(id).get();
}

public User findById(int id) {
return repository.findById(id).get();
}

public List<User> findAll() {
return repository.findAll();
}

public User addUser(User user) {
return repository.save(user);
}

public User inactiveUser(int id) {
User user = getUserById(id);
if (user != null) {
user.setRole(null);
return repository.save(user);
}
return null;
}

public String delete(int id) {
User user = getUserById(id);
if (user != null) {
repository.delete(user);
return "deleted";
}
return "record not found";
}
}

UserControler,java  
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import com.letUsLearn.entity.User;
import com.letUsLearn.service.UserService;

@RestController
@RequestMapping("/user")
public class UserControler {
@Autowired
UserService service;

@RequestMapping(method = RequestMethod.GET, path = "/hello")
public String hello() {
return "hello:";
}

@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public User getUserById(@PathVariable(value = "id") int id) {
try {
return service.findById(id);
} catch (Exception e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
}

@RequestMapping(method = RequestMethod.GET, path = "/list")
public List<User> getAllUsers() {
try {
return service.findAll();
} catch (Exception e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
}

@RequestMapping(method = RequestMethod.POST, path = "/add")
public User addUser(@RequestBody User user) {
try {
return service.addUser(user);
} catch (Exception e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
}

@RequestMapping(method = RequestMethod.GET, path = "/del/{id}")
public User inactiveUser(@PathVariable(value = "id") int id) {
try {
return service.inactiveUser(id);
} catch (Exception e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
}
@RequestMapping(method = RequestMethod.GET, path = "/del/{id}/hard")
public String delete(@PathVariable(value = "id") int id) {
try {
return service.delete(id);
} catch (Exception e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
}
}


the following JSON can be stored in a file and be imported to the postman.
SpringBootDerby.postman_collection.json

{
"variables": [],
"info": {
"name": "SpringBootDerby",
"_postman_id": "f5141a18-6b92-b381-7f0a-b76b237fb305",
"description": "",
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
},
"item": [
{
"name": "http://localhost:8080/user/add 1st admin",
"request": {
"url": "http://localhost:8080/user/add",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\r\n\t\"id\":\"1\",\r\n\t\"userid\":\"admin1\",\r\n\t\"password\":\"@#$\",\r\n\t\"role\":\"admin\"\r\n}"
},
"description": ""
},
"response": []
},
{
"name": "http://localhost:8080/user/add 2nd admin",
"request": {
"url": "http://localhost:8080/user/add",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\r\n\t\"id\":\"2\",\r\n\t\"userid\":\"admin2\",\r\n\t\"password\":\"@#$\",\r\n\t\"role\":\"admin\"\r\n}"
},
"description": ""
},
"response": []
},
{
"name": "http://localhost:8080/user/add 1st Editor",
"request": {
"url": "http://localhost:8080/user/add",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\r\n\t\"id\":\"3\",\r\n\t\"userid\":\"editor1\",\r\n\t\"password\":\"@#$\",\r\n\t\"role\":\"editor\"\r\n}"
},
"description": ""
},
"response": []
},
{
"name": "http://localhost:8080/user/add 2nd Editor",
"request": {
"url": "http://localhost:8080/user/add",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\r\n\t\"id\":\"4\",\r\n\t\"userid\":\"editor2\",\r\n\t\"password\":\"@#$\",\r\n\t\"role\":\"editor\"\r\n}"
},
"description": ""
},
"response": []
},
{
"name": "http://localhost:8080/user/add 3rd Editor",
"request": {
"url": "http://localhost:8080/user/add",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\r\n\t\"id\":\"5\",\r\n\t\"userid\":\"editor3\",\r\n\t\"password\":\"@#$\",\r\n\t\"role\":\"editor\"\r\n}"
},
"description": ""
},
"response": []
},
{
"name": "http://localhost:8080/user/1",
"request": {
"url": "http://localhost:8080/user/1",
"method": "GET",
"header": [],
"body": {},
"description": ""
},
"response": []
},
{
"name": "http://localhost:8080/user",
"request": {
"url": "http://localhost:8080/user/list",
"method": "GET",
"header": [],
"body": {},
"description": ""
},
"response": []
},
{
"name": "http://localhost:8080/user/del/5",
"request": {
"url": "http://localhost:8080/user/del/5",
"method": "GET",
"header": [],
"body": {},
"description": ""
},
"response": []
},
{
"name": "http://localhost:8080/user/del/5/hard",
"request": {
"url": "http://localhost:8080/user/del/5/hard",
"method": "GET",
"header": [],
"body": {},
"description": ""
},
"response": []
}
]
}

Tuesday, 17 November 2015

Summary of differences between Java versions



JSR Language Changes Library Changes Platform Changes
Java 8(a.k.a 1.8) JSR 337, what's new
  • lambda expressions (JSR 335, includes method handles)
  • continuation of Project Coin (small language improvements)
  • annotations on Java types
  • Improved Date and Time API

Java 7
(a.k.a 1.7)
JSR 336, features and enhancements
  • Project Coin (small changes)
  • switch on Strings
  • try-with-resources
  • diamond operator
  • new abstracted file-system API (NIO.2) (with support for virtual filesystems)
  • improved concurrency libraries
  • elliptic curve encryption
  • more incremental upgrades
  • Support for dynamic languages
Java 6
 (a.k.a 1.6)
JSR 270. features and enhancements Mostly incremental improvements to existing libraries, no new language features (except for the @Override snafu).

Java 5 (a.k.a 1.5) JSR 176, features and enhancements
  • generics (that's the big one)
  • annotations
  • enum types
  • varargs
  • enhanced for loops (for-each)
  • concurrency utilities in java.util.concurrent

Java 1.4 JSR 59
  • the assert keyword
  • regular expressions support
  • NIO
  • integrated XML handling

Java 1.3
Mostly minor improvements, really.
  • HotSpot JVM: improvement over the original JIT
Java 1.2
  • the strictfp keyword
  • a unified collections system
  • Swing as a new UI-System on top of AWT
  • a real JIT, greatly improving speed
Java 1.1
  • inner classes
  • AWT event changes
  • JDBC
  • RMI
  • reflection

Java 1.0
Initial release, everything is new



Friday, 25 September 2015

Java Config Cacheing



Tags: Java, Config-Cacheing


This Post talks about Reading All Properties Files in a folder/sub-folders into one object then use that object as a glue throughout the project.

Lets say for example the config properties of a project have the following folder Structure.














File Contents
POC/errorMessages.properties
message1=Hey POC, its working
message2=Hey POC, its worked again

POC/screenMessage.properties
message1=Hey POC, its working on the screen
message2=Hey POC, its worked again on the screen

Test/errorMessages.properties
message1=Hey test, its working
message2=Hey test, its worked again


Test/screenMessage.properties
message1=Hey its working on the screen
message2=Hey its worked again on the screen




Output of the sysouts
System.out.println(gcv("POC.errorMessage", "message1"));
-->Hey POC, its working
System.out.println(gcv("POC.screenMessage", "message1"));
-->Hey POC, its working on the screen

System.out.println(gcv("TEST.errorMessage", "message1"));
-->Hey test, its working
System.out.println(gcv("TEST.screenMessage", "message1"));
-->Hey its working on the screen



CODE



ConfigTester.java


import com.company_name.common.configuration.ConfigurationHelper;
public class ConfigTester {
      public static void main(String[] args) {
            try {
                  ConfigurationHelper.init("c:/config");
                  System.out.println(gcv("POC.errorMessage", "message1"));
                  System.out.println(gcv("POC.screenMessage", "message1"));
                  System.out.println(gcv("TEST.errorMessage", "message1"));
                  System.out.println(gcv("TEST.screenMessage", "message1"));
            } catch (Exception e) {
                  e.printStackTrace();
            }
      }
    private static String gvc(String string, String string2) {      
        return ConfigurationHelper.getConfigValue(string, string2);
    }
}


ConfigurationHelper.java


package com.company_name.common.configuration;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public final class ConfigurationHelper {
      private static final String PACKAGE = "package";
      private static final String KEY = "key";
      private static final String VALUE = "value";
      private static HashMap configHashMap = null;
      private static String configRootFolder = null;
      public synchronized static void init(String configFolderPath) throws Exception {
            configRootFolder = (new File(configFolderPath).getCanonicalPath()).toString();
            configHashMap = new HashMap();
            initConfigHashMap(configFolderPath);
      }

      private static void initConfigHashMap(String configFolderPath) throws Exception {
            File rootDirectory = new File(configFolderPath);
            File[] files = rootDirectory.listFiles();
            if (files != null) {
                  for (int k = 0; k < files.length; ++k) {
                        String filePath = files[k].getAbsolutePath();
                        String fileName = files[k].getName();
                        if (files[k].isFile()) {
                              if (fileName.endsWith(".xml")) {
                                    populateConfigHashTable(configHashMap, filePath);
                              } else if (fileName.endsWith(".properties")) {
                                    String packageName = fetchPackageName(filePath);
                                    populateConfigHashTableWithProperties(configHashMap, filePath, packageName);
                              }
                        } else if (files[k].isDirectory()) {
                              initConfigHashMap(filePath);
                        }
                  }
            }
      }

      private static void populateConfigHashTableWithProperties(HashMap configHashMap, String filePath, String packageName) throws Exception {
            ArrayList configItems = new ArrayList();
            Properties properties = new Properties();
            properties.load(new FileInputStream(filePath));
            Enumeration enumeration = properties.keys();
            while (enumeration.hasMoreElements()) {
                  String keyName = (String) enumeration.nextElement();
                  String value = properties.getProperty(keyName);
                  ConfigurationItem theConfigItem = new ConfigurationItem();
                  theConfigItem.setKey(keyName.trim());
                  theConfigItem.setValue(value.trim());
                  configItems.add(theConfigItem);
            }
            ArrayList arrayList = (ArrayList) configHashMap.get(packageName.toLowerCase());
            if (arrayList == null) {
                  configHashMap.put(packageName.toLowerCase(), configItems);
            } else {
                  arrayList.addAll(configItems);
            }
      }

      private static String fetchPackageName(String filePath) {
            String packageName = filePath.replaceFirst("\\.properties", "");
            packageName = packageName.replace(configRootFolder, "");
            packageName = packageName.replace("\\", ".");
            packageName = packageName.substring(1);
            return packageName;
      }

      public static String getConfigValue(String packageName, String key) {
            String configItemValue = null;
            ConfigurationItem[] configItemsArray = getConfigItems(packageName.toLowerCase());
            if (configItemsArray != null) {
                  for (int i = 0; i < configItemsArray.length; ++i) {
                        ConfigurationItem configItem = configItemsArray[i];
                        if (configItem.getKey().compareTo(key) == 0) {
                              configItemValue = configItem.getValue();
                              break;
                        }
                  }
            }
            return configItemValue;
      }

      public static String getConfigValue(String packageName, String key, String locale) {
            String packageNameINT = packageName + "_" + locale;
            String configItemValue = getConfigValue(packageNameINT, key);
            if (configItemValue == null) {
                  configItemValue = getConfigValue(packageName, key);
            }
            return configItemValue;
      }

      private static void populateConfigHashTable(HashMap configHashtable, String fileName) throws Exception {
            Document dom = createDocumentFromFile(fileName);
            NodeList nl = dom.getElementsByTagName(PACKAGE);
            String packageName = null;
            for (int i = 0; i < nl.getLength(); ++i) {
                  Node node = nl.item(i);
                  Node child = node.getFirstChild();

                  if (child != null) {
                        packageName = child.getNodeValue().trim();
                        if (packageName == null)
                              continue;

                  }
                  ArrayList configItems = new ArrayList();
                  getAllValues(configItems, node);
                  ArrayList arrayList = (ArrayList) configHashtable.get(packageName.toLowerCase());
                  if (arrayList == null) {
                        configHashtable.put(packageName.toLowerCase(), configItems);
                  } else {
                        arrayList.addAll(configItems);
                  }
            }
      }

      private static void getAllValues(ArrayList configItems, Node node) {
            NodeList allNodesInThisPackage = node.getChildNodes();
            int j = 0;
            while ((allNodesInThisPackage != null) && (j < allNodesInThisPackage.getLength())) {
                  Node keyValueNode = allNodesInThisPackage.item(j);
                  if (keyValueNode != null) {
                        String nodeName = keyValueNode.getNodeName();
                        if ((nodeName != null) && (nodeName.equals(KEY))) {
                              String keyName = keyValueNode.getFirstChild().getNodeValue();
                              Node ValueNode = findNode(VALUE, keyValueNode.getChildNodes());
                              String tagValue = "";
                              if ((ValueNode != null) && (ValueNode.getFirstChild() != null)) {
                                    tagValue = ValueNode.getFirstChild().getNodeValue();
                              }
                              ConfigurationItem theConfigItem = new ConfigurationItem();
                              if (keyName != null) {
                                    theConfigItem.setKey(keyName.trim());
                              }
                              if (tagValue != null) {
                                    theConfigItem.setValue(tagValue.trim());
                              }
                              configItems.add(theConfigItem);
                        }
                  }
                  ++j;
            }
      }

      private static Node findNode(String tagName, NodeList nodeList) {
            Node foundNode = null;
            if (nodeList != null) {
                  for (int i = 0; i < nodeList.getLength(); i++) {
                        Node node = nodeList.item(i);
                        String nodeName = node.getNodeName();
                        if (nodeName.equals(tagName)) {
                              foundNode = node;
                              break;
                        }
                  }
            }
            return foundNode;
      }

      private static Document createDocumentFromFile(String URL) throws Exception {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document dom = documentBuilder.parse(new File(URL));
            return dom;
      }

      public static ConfigurationItem[] getConfigItems(String packageName) {
            ArrayList arrayList = (ArrayList) configHashMap.get(packageName.toLowerCase());
            if (arrayList == null)
                  return null;
            ConfigurationItem[] configurationItemArray = new ConfigurationItem[arrayList.size()];
            for (int i = arrayList.size() - 1; i >= 0; i--) {
                  configurationItemArray[i] = (ConfigurationItem) arrayList.get(i);
            }
            return configurationItemArray;
      }

      public static void printHashMap() {
            Set setOfKeys = configHashMap.keySet();
            Iterator iterator = setOfKeys.iterator();
            while (iterator.hasNext()) {
                  String packageName = (String) iterator.next();
                  ConfigurationItem[] configurationItems = getConfigItems(packageName);
                  System.out.println("Package:" + packageName);
                  System.out.println("\tKey\tValue");
                  for (ConfigurationItem configurationItem : configurationItems) {
                        System.out.println("\t" + configurationItem.getKey() + "\t" + configurationItem.getValue());
                  }
            }
      }
}
ConfigurationItem.java
package com.company_name.common.configuration;
public class ConfigurationItem {
      private String key;
      private String value;

      public String getKey() {
            return key;
      }
      public void setKey(String key) {
            this.key = key;
      }
      public String getValue() {
            return value;
      }
      public void setValue(String value) {
            this.value = value;
      }
}