From 42298b4769e70d9c71c2f858967eebc6dc6cc0ea Mon Sep 17 00:00:00 2001 From: mordicus Date: Fri, 7 Aug 2015 11:43:45 +0200 Subject: [PATCH] Added unit test to GDE-war --- .../GDE_App/GDE-war/nbproject/build-impl.xml | 2 + .../GDE_App/GDE-war/nbproject/project.xml | 4 + .../GDE-war/test/com/edf/gde/dao/BaseDao.java | 75 +++ .../test/com/edf/gde/dao/UserDaoClient.java | 179 ++++++ .../com/edf/gde/test/dao/UserDaoTest.java | 197 ++++++ .../test/com/edf/gde/test/restapi/Base64.java | 228 +++++++ .../test/restapi/DefaultResponseHandler.java | 17 + .../edf/gde/test/restapi/ResponseHandler.java | 11 + .../com/edf/gde/test/restapi/RestContext.java | 111 ++++ .../edf/gde/test/restapi/SimpleRestApi.java | 591 ++++++++++++++++++ .../exceptions/RestResponseException.java | 24 + .../providers/CertificateProvider.java | 11 + .../providers/FileCertificateProvider.java | 47 ++ 13 files changed, 1497 insertions(+) create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/dao/BaseDao.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/dao/UserDaoClient.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/dao/UserDaoTest.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/Base64.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/DefaultResponseHandler.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/ResponseHandler.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/RestContext.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/SimpleRestApi.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/exceptions/RestResponseException.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/providers/CertificateProvider.java create mode 100644 projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/providers/FileCertificateProvider.java diff --git a/projects/GDE_App/GDE-war/nbproject/build-impl.xml b/projects/GDE_App/GDE-war/nbproject/build-impl.xml index ae19277..1cf395f 100644 --- a/projects/GDE_App/GDE-war/nbproject/build-impl.xml +++ b/projects/GDE_App/GDE-war/nbproject/build-impl.xml @@ -1005,12 +1005,14 @@ exists or setup the property manually. For example like this: + + diff --git a/projects/GDE_App/GDE-war/nbproject/project.xml b/projects/GDE_App/GDE-war/nbproject/project.xml index d8b7f70..fcd9ad9 100644 --- a/projects/GDE_App/GDE-war/nbproject/project.xml +++ b/projects/GDE_App/GDE-war/nbproject/project.xml @@ -14,6 +14,10 @@ ${reference.GDE-ejb.dist} WEB-INF/lib + + ${libs.junit_4.classpath} + WEB-INF/lib + diff --git a/projects/GDE_App/GDE-war/test/com/edf/gde/dao/BaseDao.java b/projects/GDE_App/GDE-war/test/com/edf/gde/dao/BaseDao.java new file mode 100644 index 0000000..eb25873 --- /dev/null +++ b/projects/GDE_App/GDE-war/test/com/edf/gde/dao/BaseDao.java @@ -0,0 +1,75 @@ +/* + * (C) 2015 EDF + */ +package com.edf.gde.dao; + +import com.edf.gde.transferables.CommandTO; +import com.edf.gde.transferables.responses.CommandResultTO; +import gdetester.restapi.ResponseHandler; +import gdetester.restapi.RestContext; +import gdetester.restapi.SimpleRestApi; + +/** + * + * @author Kavoos + */ +public class BaseDao extends SimpleRestApi { + + public BaseDao() { + super(); + + } + + public BaseDao(RestContext context) { + super(context); + } + + protected T fromJson(String json, Class classOf) { + + return gson.fromJson(json, classOf); + } + + protected String toJson(Object object) { + return gson.toJson(object); + } + + protected CommandTO createCommand(int methodIndex) { + CommandTO commandTO = new CommandTO(); + commandTO.setMethod(methodIndex); + return commandTO; + } + + protected class DaoResponseHandler implements ResponseHandler { + + protected boolean callResult; + protected int resultCode; + protected String callResponse; + + @Override + public boolean checkResponse(int code, String response) { + this.resultCode = code; + callResult = false; + if (resultCode == 200) { + callResult = true; + callResponse = response; + } + return callResult; + } + + public boolean isCallResult() { + return callResult; + } + + public int getResultCode() { + return resultCode; + } + + public CommandResultTO getResultTO() { + CommandResultTO resultTO; + resultTO = fromJson(callResponse, CommandResultTO.class); + return resultTO; + } + + } + +} diff --git a/projects/GDE_App/GDE-war/test/com/edf/gde/dao/UserDaoClient.java b/projects/GDE_App/GDE-war/test/com/edf/gde/dao/UserDaoClient.java new file mode 100644 index 0000000..10d5d10 --- /dev/null +++ b/projects/GDE_App/GDE-war/test/com/edf/gde/dao/UserDaoClient.java @@ -0,0 +1,179 @@ +/* + * (C) 2015 EDF + */ +package com.edf.gde.dao; + +import com.edf.gde.transferables.CommandTO; +import com.edf.gde.transferables.GroupTO; +import com.edf.gde.transferables.UserTO; +import com.edf.gde.transferables.responses.CommandResultTO; +import gdetester.restapi.RestContext; +import java.io.IOException; + +/** + * + * @author Kavoos + */ +public class UserDaoClient extends BaseDao { + + public static final int CREATEUSER = 1; + public static final int DELETEUSER = 2; + public static final int ADDTOGROUP = 3; + public static final int REMOVEFROMGROUP = 4; + public static final int CREATEGROUP = 5; + public static final int DELETEGROUP = 6; + public static final int FINDUSER = 7; + public static final int FINDGROUP = 8; + + protected DaoResponseHandler daoResponseHandler; + + public UserDaoClient() { + getContext().setBaseResource("http://localhost:8080/GDE-war/UserService"); + daoResponseHandler = new DaoResponseHandler(); + } + + public UserDaoClient(RestContext context) { + super(context); + daoResponseHandler = new DaoResponseHandler(); + } + + /** + * + * @param userName + * @param password + * @return + * @throws IOException + */ + public UserTO createUser(String userName, String password) throws IOException { + CommandTO commandTO = createCommand(CREATEUSER); + UserTO userTO = new UserTO(); + userTO.setName(userName); + userTO.setPassword(password); + commandTO.setData(toJson(userTO)); + if (postAsJSonData(commandTO, daoResponseHandler)) { + CommandResultTO resultTO = daoResponseHandler.getResultTO(); + if (resultTO.getCode() == CommandResultTO.OK) { + userTO = fromJson(resultTO.getData(), UserTO.class); + return userTO; + } + } + throw new RuntimeException("Unable to create user"); + } + + /** + * + * @param userId + * @return + * @throws IOException + */ + public boolean deleteUser(long userId) throws IOException { + CommandTO commandTO = createCommand(DELETEUSER); + commandTO.setLong("id", userId); + if (postAsJSonData(commandTO, daoResponseHandler)) { + if (daoResponseHandler.getResultTO().getCode() == CommandResultTO.OK) { + return true; + } + } + return false; + } + + /** + * + * @param userName + * @return null if user not found + * @throws IOException + */ + public UserTO findUser(String userName) throws IOException { + CommandTO commandTO = createCommand(FINDUSER); + commandTO.setString("username", userName); + if (postAsJSonData(commandTO, daoResponseHandler)) { + CommandResultTO resultTO = daoResponseHandler.getResultTO(); + if (resultTO.getCode() == CommandResultTO.OK) { + UserTO userTO = fromJson(resultTO.getData(), UserTO.class); + return userTO; + } + } + return null; + } + + /** + * + * @param groupName + * @return + * @throws IOException + */ + public GroupTO createGroup(String groupName) throws IOException { + CommandTO commandTO = createCommand(CREATEGROUP); + commandTO.setString("name", groupName); + if (postAsJSonData(commandTO, daoResponseHandler)) { + CommandResultTO resultTO = daoResponseHandler.getResultTO(); + if (resultTO.getCode() == CommandResultTO.OK) { + GroupTO groupTO = fromJson(resultTO.getData(), GroupTO.class); + return groupTO; + } + } + return null; + } + + /** + * + * @param groupName + * @return + * @throws IOException + */ + public GroupTO findGroup(String groupName) throws IOException { + CommandTO commandTO = createCommand(FINDGROUP); + commandTO.setString("groupname", groupName); + if (postAsJSonData(commandTO, daoResponseHandler)) { + CommandResultTO resultTO = daoResponseHandler.getResultTO(); + if (resultTO.getCode() == CommandResultTO.OK) { + GroupTO groupTO = fromJson(resultTO.getData(), GroupTO.class); + return groupTO; + } + } + return null; + } +/** + * + * @param id + * @return + * @throws IOException + */ + public boolean deleteGroup(long id) throws IOException { + CommandTO commandTO = createCommand(DELETEGROUP); + commandTO.setLong("id", id); + if (postAsJSonData(commandTO, daoResponseHandler)) { + CommandResultTO resultTO = daoResponseHandler.getResultTO(); + if (resultTO.getCode() == CommandResultTO.OK) { + return true; + } + } + return false; + } + + public boolean addToGroup(long groupId, long userId) throws IOException { + CommandTO commandTO = createCommand(ADDTOGROUP); + commandTO.setLong("groupId", groupId); + commandTO.setLong("userId", userId); + if (postAsJSonData(commandTO,daoResponseHandler)) { + CommandResultTO resultTO = daoResponseHandler.getResultTO(); + if (resultTO.getCode() == CommandResultTO.OK) { + return true; + } + } + return false; + } + + public boolean removeFromGroup(long groupId, long userId) throws IOException { + CommandTO commandTO = createCommand(REMOVEFROMGROUP); + commandTO.setLong("groupId", groupId); + commandTO.setLong("userId", userId); + if (postAsJSonData(commandTO,daoResponseHandler)) { + CommandResultTO resultTO = daoResponseHandler.getResultTO(); + if (resultTO.getCode() == CommandResultTO.OK) { + return true; + } + } + return false; + } +} diff --git a/projects/GDE_App/GDE-war/test/com/edf/gde/test/dao/UserDaoTest.java b/projects/GDE_App/GDE-war/test/com/edf/gde/test/dao/UserDaoTest.java new file mode 100644 index 0000000..f2080f7 --- /dev/null +++ b/projects/GDE_App/GDE-war/test/com/edf/gde/test/dao/UserDaoTest.java @@ -0,0 +1,197 @@ +/* + * (C) 2015 EDF + */ +package com.edf.gde.test.dao; + +import com.edf.gde.dao.UserDaoClient; +import com.edf.gde.transferables.GroupTO; +import com.edf.gde.transferables.UserTO; +import java.io.IOException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author mordicus + */ +public class UserDaoTest { + + public UserDaoTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + private long createUser(String userName, String password) throws IOException { + UserDaoClient instance = new UserDaoClient(); + long result = instance.createUser(userName, password).getId(); + return result; + } + + private boolean deleteUser(long id) throws IOException { + UserDaoClient instance = new UserDaoClient(); + boolean result = instance.deleteUser(id); + return result; + } + + private UserTO findUser(String userName) throws IOException { + UserDaoClient instance = new UserDaoClient(); + UserTO userTO = instance.findUser(userName); + return userTO; + } + + private GroupTO createGroup(String groupName) throws IOException { + UserDaoClient daoClient = new UserDaoClient(); + GroupTO result = daoClient.createGroup(groupName); + return result; + } + + private GroupTO findGroup(String groupName) throws IOException { + UserDaoClient daoClient = new UserDaoClient(); + GroupTO groupTO = daoClient.findGroup(groupName); + return groupTO; + } + + private boolean deleteGroup(long groupID) throws IOException { + UserDaoClient daoClient = new UserDaoClient(); + boolean result = daoClient.deleteGroup(groupID); + return result; + } + + private boolean addToGroup(long groupId, long userId) throws IOException { + UserDaoClient daoClient = new UserDaoClient(); + boolean result = daoClient.addToGroup(groupId, userId); + return result; + } + + private boolean removeFromGroup(long groupId, long userId) throws IOException { + UserDaoClient daoClient = new UserDaoClient(); + boolean result = daoClient.removeFromGroup(groupId, userId); + return result; + } + + /** + * Test of createUser method, of class UserDao. + */ + @Test + public void testCreateUser() throws Exception { + System.out.println("createUser"); + String userName = "Kavoos"; + String password = "edf123"; + long userId = createUser(userName, password); + assertTrue((userId != -1) && (userId > 0)); + assertTrue(deleteUser(userId)); + } + + /** + * Test of deleteUser method, of class UserDao. + */ + @Test + public void testDeleteUser() throws Exception { + System.out.println("deleteUser"); + long userId = createUser("Kavoos", "edf123"); + assertTrue(userId > 0); + boolean expResult = true; + boolean result = deleteUser(userId); + assertEquals(expResult, result); + } + + @Test + public void testFindUser() throws Exception { + System.out.println("findUser"); + long userId = createUser("Kavoos", "edf123"); + assertTrue(userId > 0); + UserTO userTO = findUser("Kavoos"); + assertNotNull(userTO); + assertTrue(userTO.getId() == userId); + assertEquals("Kavoos", userTO.getName()); + assertTrue(deleteUser(userId)); + } + + @Test + public void testCreateGroup() throws Exception { + System.out.println("createGroup"); + GroupTO groupTO = createGroup("Admin"); + assertNotNull(groupTO); + assertEquals("Admin", groupTO.getName()); + assertTrue(deleteGroup(groupTO.getId())); + } + + @Test + public void testFindGroup() throws Exception { + System.out.println("findGroup"); + GroupTO groupTO = createGroup("Admin"); + assertNotNull(groupTO); + assertEquals("Admin", groupTO.getName()); + groupTO = findGroup("Admin"); + assertNotNull(groupTO); + assertEquals("Admin", groupTO.getName()); + assertTrue(deleteGroup(groupTO.getId())); + } + + @Test + public void testDeleteGroup() throws Exception { + System.out.println("deleteGroup"); + GroupTO groupTO = createGroup("Admin"); + assertNotNull(groupTO); + assertEquals("Admin", groupTO.getName()); + assertTrue(deleteGroup(groupTO.getId())); + } + + @Test + public void testAddToGroup() throws Exception { + System.out.println("addToGroup"); + /* create a group */ + GroupTO groupTO = createGroup("Admin"); + assertNotNull(groupTO); + assertTrue(groupTO.getId()>0); + assertEquals("Admin", groupTO.getName()); + /* Create a user */ + long userId = createUser("Kavoos", "edf123"); + assertTrue(userId>0); + /* add the user to the group */ + boolean result = addToGroup(groupTO.getId(),userId); + assertTrue(result); + assertTrue(deleteGroup(groupTO.getId())); + assertTrue(deleteUser(userId)); + } + + @Test + public void testRemoveFromGroup() throws Exception { + System.out.println("removeFromGroup"); + /* create a group */ + GroupTO groupTO = createGroup("Admin"); + assertNotNull(groupTO); + assertTrue(groupTO.getId()>0); + assertEquals("Admin", groupTO.getName()); + /* Create a user */ + long userId = createUser("Kavoos", "edf123"); + assertTrue(userId>0); + /* add the user to the group */ + boolean result = addToGroup(groupTO.getId(),userId); + assertTrue(result); + /* Remove the user from the group */ + result = removeFromGroup(groupTO.getId(),userId); + assertTrue(result); + assertTrue(deleteGroup(groupTO.getId())); + assertTrue(deleteUser(userId)); + } + +} diff --git a/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/Base64.java b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/Base64.java new file mode 100644 index 0000000..2581d5d --- /dev/null +++ b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/Base64.java @@ -0,0 +1,228 @@ +// Copyright 2003-2010 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland +// www.source-code.biz, www.inventec.ch/chdh +// +// This module is multi-licensed and may be used under the terms +// of any of the following licenses: +// +// EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal +// LGPL, GNU Lesser General Public License, V2.1 or later, http://www.gnu.org/licenses/lgpl.html +// GPL, GNU General Public License, V2 or later, http://www.gnu.org/licenses/gpl.html +// AGPL, GNU Affero General Public License V3 or later, http://www.gnu.org/licenses/agpl.html +// AL, Apache License, V2.0 or later, http://www.apache.org/licenses +// BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php +// MIT, MIT License, http://www.opensource.org/licenses/MIT +// +// Please contact the author if you need another license. +// This module is provided "as is", without warranties of any kind. +// +// Project home page: www.source-code.biz/base64coder/java + +package gdetester.restapi; + +/** +* A Base64 encoder/decoder. +* +*

+* This class is used to encode and decode data in Base64 format as described in RFC 1521. +* +* @author +* Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland, www.source-code.biz +*/ +public class Base64 { + +// The line separator string of the operating system. +private static final String systemLineSeparator = System.getProperty("line.separator"); + +// Mapping table from 6-bit nibbles to Base64 characters. +private static final char[] map1 = new char[64]; + static { + int i=0; + for (char c='A'; c<='Z'; c++) map1[i++] = c; + for (char c='a'; c<='z'; c++) map1[i++] = c; + for (char c='0'; c<='9'; c++) map1[i++] = c; + map1[i++] = '+'; map1[i++] = '/'; } + +// Mapping table from Base64 characters to 6-bit nibbles. +private static final byte[] map2 = new byte[128]; + static { + for (int i=0; isun.misc.BASE64Encoder.encodeBuffer(byte[]). +* @param in An array containing the data bytes to be encoded. +* @return A String containing the Base64 encoded data, broken into lines. +*/ +public static String encodeLines (byte[] in) { + return encodeLines(in, 0, in.length, 76, systemLineSeparator); } + +/** +* Encodes a byte array into Base 64 format and breaks the output into lines. +* @param in An array containing the data bytes to be encoded. +* @param iOff Offset of the first byte in in to be processed. +* @param iLen Number of bytes to be processed in in, starting at iOff. +* @param lineLen Line length for the output data. Should be a multiple of 4. +* @param lineSeparator The line separator to be used to separate the output lines. +* @return A String containing the Base64 encoded data, broken into lines. +*/ +public static String encodeLines (byte[] in, int iOff, int iLen, int lineLen, String lineSeparator) { + int blockLen = (lineLen*3) / 4; + if (blockLen <= 0) throw new IllegalArgumentException(); + int lines = (iLen+blockLen-1) / blockLen; + int bufLen = ((iLen+2)/3)*4 + lines*lineSeparator.length(); + StringBuilder buf = new StringBuilder(bufLen); + int ip = 0; + while (ip < iLen) { + int l = Math.min(iLen-ip, blockLen); + buf.append(encode(in, iOff+ip, l)); + buf.append(lineSeparator); + ip += l; } + return buf.toString(); } + +/** +* Encodes a byte array into Base64 format. +* No blanks or line breaks are inserted in the output. +* @param in An array containing the data bytes to be encoded. +* @return A character array containing the Base64 encoded data. +*/ +public static char[] encode (byte[] in) { + return encode(in, 0, in.length); } + +/** +* Encodes a byte array into Base64 format. +* No blanks or line breaks are inserted in the output. +* @param in An array containing the data bytes to be encoded. +* @param iLen Number of bytes to process in in. +* @return A character array containing the Base64 encoded data. +*/ +public static char[] encode (byte[] in, int iLen) { + return encode(in, 0, iLen); } + +/** +* Encodes a byte array into Base64 format. +* No blanks or line breaks are inserted in the output. +* @param in An array containing the data bytes to be encoded. +* @param iOff Offset of the first byte in in to be processed. +* @param iLen Number of bytes to process in in, starting at iOff. +* @return A character array containing the Base64 encoded data. +*/ +public static char[] encode (byte[] in, int iOff, int iLen) { + int oDataLen = (iLen*4+2)/3; // output length without padding + int oLen = ((iLen+2)/3)*4; // output length including padding + char[] out = new char[oLen]; + int ip = iOff; + int iEnd = iOff + iLen; + int op = 0; + while (ip < iEnd) { + int i0 = in[ip++] & 0xff; + int i1 = ip < iEnd ? in[ip++] & 0xff : 0; + int i2 = ip < iEnd ? in[ip++] & 0xff : 0; + int o0 = i0 >>> 2; + int o1 = ((i0 & 3) << 4) | (i1 >>> 4); + int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); + int o3 = i2 & 0x3F; + out[op++] = map1[o0]; + out[op++] = map1[o1]; + out[op] = op < oDataLen ? map1[o2] : '='; op++; + out[op] = op < oDataLen ? map1[o3] : '='; op++; } + return out; } + +/** +* Decodes a string from Base64 format. +* No blanks or line breaks are allowed within the Base64 encoded input data. +* @param s A Base64 String to be decoded. +* @return A String containing the decoded data. +* @throws IllegalArgumentException If the input is not valid Base64 encoded data. +*/ +public static String decodeString (String s) { + return new String(decode(s)); } + +/** +* Decodes a byte array from Base64 format and ignores line separators, tabs and blanks. +* CR, LF, Tab and Space characters are ignored in the input data. +* This method is compatible with sun.misc.BASE64Decoder.decodeBuffer(String). +* @param s A Base64 String to be decoded. +* @return An array containing the decoded data bytes. +* @throws IllegalArgumentException If the input is not valid Base64 encoded data. +*/ +public static byte[] decodeLines (String s) { + char[] buf = new char[s.length()]; + int p = 0; + for (int ip = 0; ip < s.length(); ip++) { + char c = s.charAt(ip); + if (c != ' ' && c != '\r' && c != '\n' && c != '\t') + buf[p++] = c; } + return decode(buf, 0, p); } + +/** +* Decodes a byte array from Base64 format. +* No blanks or line breaks are allowed within the Base64 encoded input data. +* @param s A Base64 String to be decoded. +* @return An array containing the decoded data bytes. +* @throws IllegalArgumentException If the input is not valid Base64 encoded data. +*/ +public static byte[] decode (String s) { + return decode(s.toCharArray()); } + +/** +* Decodes a byte array from Base64 format. +* No blanks or line breaks are allowed within the Base64 encoded input data. +* @param in A character array containing the Base64 encoded data. +* @return An array containing the decoded data bytes. +* @throws IllegalArgumentException If the input is not valid Base64 encoded data. +*/ +public static byte[] decode (char[] in) { + return decode(in, 0, in.length); } + +/** +* Decodes a byte array from Base64 format. +* No blanks or line breaks are allowed within the Base64 encoded input data. +* @param in A character array containing the Base64 encoded data. +* @param iOff Offset of the first character in in to be processed. +* @param iLen Number of characters to process in in, starting at iOff. +* @return An array containing the decoded data bytes. +* @throws IllegalArgumentException If the input is not valid Base64 encoded data. +*/ +public static byte[] decode (char[] in, int iOff, int iLen) { + if (iLen%4 != 0) throw new IllegalArgumentException("Length of Base64 encoded input string is not a multiple of 4."); + while (iLen > 0 && in[iOff+iLen-1] == '=') iLen--; + int oLen = (iLen*3) / 4; + byte[] out = new byte[oLen]; + int ip = iOff; + int iEnd = iOff + iLen; + int op = 0; + while (ip < iEnd) { + int i0 = in[ip++]; + int i1 = in[ip++]; + int i2 = ip < iEnd ? in[ip++] : 'A'; + int i3 = ip < iEnd ? in[ip++] : 'A'; + if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) + throw new IllegalArgumentException("Illegal character in Base64 encoded data."); + int b0 = map2[i0]; + int b1 = map2[i1]; + int b2 = map2[i2]; + int b3 = map2[i3]; + if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) + throw new IllegalArgumentException("Illegal character in Base64 encoded data."); + int o0 = ( b0 <<2) | (b1>>>4); + int o1 = ((b1 & 0xf)<<4) | (b2>>>2); + int o2 = ((b2 & 3)<<6) | b3; + out[op++] = (byte)o0; + if (op parametters; + private CertificateProvider certificateProvider; + + public RestContext() { + parametters = new HashMap(); + } + + public RestContext(String resource) { + this.baseResource = resource; + parametters = new HashMap(); + } + + public RestContext(String resource, String trustStorePath) { + this.baseResource = resource; + parametters = new HashMap(); + } + + public RestContext(String resource, String userName, String password) { + this.baseResource = resource; + this.userName = userName; + this.password = password; + parametters = new HashMap(); + } + + public CertificateProvider getCertificateProvider() { + return certificateProvider; + } + + public void setCertificateProvider(CertificateProvider certificateProvider) { + this.certificateProvider = certificateProvider; + } + + public void clear() { + this.parametters.clear(); + } + + public String getPassword() { + return password; + } + + public void setParametter(String name, String value) { + this.parametters.put(name, value); + } + + public String getResource() { + StringBuilder sb = new StringBuilder(); + sb.append(baseResource); + if (parametters.size() > 0) { + Set keys = parametters.keySet(); + String[] k = keys.toArray(new String[0]); + + sb.append("?"); + try { + sb.append(k[0]).append("=").append(URLEncoder.encode(parametters.get(k[0]), "utf-8")); + } catch (UnsupportedEncodingException ex) { + Logger.getLogger(RestContext.class.getName()).log(Level.SEVERE, null, ex); + } + for (int i = 1; i < k.length; i++) { + try { + sb.append("&").append(k[i]).append("=").append(URLEncoder.encode(parametters.get(k[i]), "utf-8")); + } catch (UnsupportedEncodingException ex) { + Logger.getLogger(RestContext.class.getName()).log(Level.SEVERE, null, ex); + } + + } + + } + String ret = sb.toString(); + return ret; + } + + public String getBaseResource() { + return baseResource; + } + + public String getUserName() { + return userName; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setBaseResource(String resource) { + this.baseResource = resource; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/SimpleRestApi.java b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/SimpleRestApi.java new file mode 100644 index 0000000..0ee4476 --- /dev/null +++ b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/SimpleRestApi.java @@ -0,0 +1,591 @@ +package gdetester.restapi; + +import com.google.gson.Gson; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.lang.reflect.Type; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManagerFactory; +import gdetester.restapi.providers.CertificateProvider; + +/** + * + * @author Kavoos Bojnourdi + */ +public class SimpleRestApi { + + /** + * RestContext + */ + protected RestContext restContext; + + private KeyStore keyStore; + private TrustManagerFactory tmf; + private SSLContext context; + private boolean verifyHostName; + private HttpURLConnection connection; + protected Gson gson; + + public SimpleRestApi() { + restContext = new RestContext(); + gson = new Gson(); + } + + public SimpleRestApi(RestContext context) { + this.restContext = context; + gson = new Gson(); + } + + public boolean isVerifyHostName() { + return verifyHostName; + } + + public void setVerifyHostName(boolean verifyHostName) { + this.verifyHostName = verifyHostName; + } + + protected void setContext(RestContext context) { + this.restContext = context; + if (context.getBaseResource() != null) { + initResource(); + } + } + + private void initResource() { + + } + + public RestContext getContext() { + return restContext; + } + + protected void setResource(String resource) { + restContext.setBaseResource(resource); + initResource(); + } + + protected void setResource(String base, String resource) { + restContext.setBaseResource(base + resource); + initResource(); + } + + public void closeConnection() { + if (connection != null) { + connection.disconnect(); + } + } + + public void setCertificateProvider(CertificateProvider certificateProvider) { + restContext.setCertificateProvider(certificateProvider); + } + + /** + * + * @param connection + */ + protected void initAuthentication(HttpURLConnection connection) { + if (restContext.getUserName() == null) { + return; + } + String userCredentials = restContext.getUserName() + ":" + restContext.getPassword(); + String basicAuth = "Basic " + new String(Base64.encode(userCredentials.getBytes())); + connection.setRequestProperty("Authorization", basicAuth); + connection.setRequestProperty("User-Agent", "Deuterium/1.0"); + } + + /** + * + * @param rh + * @return + * @throws IOException + */ + protected boolean remove(ResponseHandler rh) throws IOException { + setUpHttpConnection(); + + try { + connection.setDoInput(true); + connection.setDoOutput(false); + initAuthentication(connection); + + connection.setRequestMethod("DELETE"); + + // Open and do query + int responseCode = connection.getResponseCode(); + String resultString = readStringResponse(connection); + + if (rh == null) { + rh = new DefaultResponseHandler(); + } + return rh.checkResponse(responseCode, resultString); + } finally { + closeConnection(); + } + } + + /** + * + * @param data + * @param rh + * @return + * @throws IOException + */ + protected boolean putAsJSonData(Object data, ResponseHandler rh) throws IOException { + setUpHttpConnection(); + try { + connection.setRequestMethod("PUT"); + return writeJsonData(data, connection, rh); + } finally { + closeConnection(); + } + } + + /** + * + * @param data + * @return + * @throws IOException + */ + protected boolean putAsJSonData(Object data) throws IOException { + return putAsJSonData(data, null); + } + + /** + * + * @param data + * @param rh + * @return + * @throws IOException + */ + protected boolean postAsJSonData(Object data, ResponseHandler rh) throws IOException { + setUpHttpConnection(); + try { + connection.setRequestMethod("POST"); + return writeJsonData(data, connection, rh); + } finally { + closeConnection(); + } + } + + /** + * + * @param data + * @return + * @throws IOException + */ + protected boolean postAsJSonData(Object data) throws IOException { + return postAsJSonData(data, null); + } + + /** + * + * @param data + * @param rh + * @return + * @throws IOException + */ + protected boolean postAsBinaryData(byte[] data, ResponseHandler rh) throws IOException { + setUpHttpConnection(); + try { + connection.setRequestMethod("POST"); + return sendBinaryData(connection, data, rh); + } finally { + closeConnection(); + } + } + + /** + * + * @param data + * @param rh + * @return + * @throws IOException + */ + protected boolean putAsBinaryData(byte[] data, ResponseHandler rh) throws IOException { + setUpHttpConnection(); + try { + connection.setRequestMethod("PUT"); + return sendBinaryData(connection, data, rh); + } finally { + closeConnection(); + } + } + + /** + * + * @param data + * @return + * @throws IOException + */ + protected boolean putAsBinaryData(byte[] data) throws IOException { + return putAsBinaryData(data, null); + } + + /** + * + * @param in + * @param rh + * @return + * @throws IOException + */ + protected boolean postAsBinaryStream(InputStream in, ResponseHandler rh) throws IOException { + setUpHttpConnection(); + try { + connection.setRequestMethod("POST"); + return sendBinaryStream(connection, in, rh); + } finally { + closeConnection(); + } + } + + /** + * + * @param in + * @return + * @throws IOException + */ + protected boolean postAsBinaryStream(InputStream in) throws IOException { + return postAsBinaryStream(in, null); + } + + /** + * + * @param in + * @param rh + * @return + * @throws IOException + */ + protected boolean putAsBinaryStream(InputStream in, ResponseHandler rh) throws IOException { + setUpHttpConnection(); + try { + connection.setRequestMethod("PUT"); + return sendBinaryStream(connection, in, rh); + + } finally { + closeConnection(); + } + } + + /** + * + * @param in + * @return + * @throws IOException + */ + protected boolean putAsBinaryStream(InputStream in) throws IOException { + return putAsBinaryStream(in, null); + } + + /** + * + * @param rh + * @return + * @throws IOException + */ + protected byte[] getBinaryData(ResponseHandler rh) throws IOException { + setUpHttpConnection(); + try { + connection.setRequestMethod("GET"); + connection.setDoInput(true); + connection.setDoOutput(false); + initAuthentication(connection); + + int responseCode = connection.getResponseCode(); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + copy(connection.getInputStream(), outputStream); + + if (rh == null) { + rh = new DefaultResponseHandler(); + } + rh.checkResponse(responseCode, connection.getResponseMessage()); + + return outputStream.toByteArray(); + } finally { + closeConnection(); + } + } + + /** + * + * @return @throws IOException + */ + protected byte[] getBinaryData() throws IOException { + return getBinaryData(null); + } + + /** + * + * @param rh + * @return + * @throws IOException + */ + protected InputStream getBinaryStream(ResponseHandler rh) throws IOException { + setUpHttpConnection(); + connection.setRequestMethod("GET"); + connection.setDoInput(true); + connection.setDoOutput(false); + initAuthentication(connection); + + int responseCode = connection.getResponseCode(); + if (rh == null) { + rh = new DefaultResponseHandler(); + } + rh.checkResponse(responseCode, connection.getResponseMessage()); + return connection.getInputStream(); + } + + /** + * + * @return @throws IOException + */ + protected InputStream getBinaryStream() throws IOException { + return getBinaryStream(null); + } + + /** + * + * @param + * @param classOfT + * @param rh + * @return + * @throws IOException + */ + protected T getData(Class classOfT, ResponseHandler rh) throws IOException { + setUpHttpConnection(); + try { + connection.setRequestMethod("GET"); + connection.setDoInput(true); + connection.setDoOutput(false); + initAuthentication(connection); + + String data = readStringResponse(connection); + int responseCode = connection.getResponseCode(); + if (rh == null) { + rh = new DefaultResponseHandler(); + } + rh.checkResponse(responseCode, connection.getResponseMessage()); + T o = gson.fromJson(data, classOfT); + return o; + } finally { + closeConnection(); + } + } + + /** + * + * @param + * @param classOfT + * @return + * @throws IOException + */ + protected T getData(Class classOfT) throws IOException { + return getData(classOfT, null); + } + + protected List getDataList(Type typeOfT, ResponseHandler rh) throws IOException { + + setUpHttpConnection(); + try { + + connection.setRequestMethod("GET"); + connection.setDoInput(true); + connection.setDoOutput(false); + initAuthentication(connection); + + int responseCode = connection.getResponseCode(); + if (rh == null) { + rh = new DefaultResponseHandler(); + } + rh.checkResponse(responseCode, connection.getResponseMessage()); + + String data = readStringResponse(connection); + T[] o = gson.fromJson(data, typeOfT); + List ret = new ArrayList(); + ret.addAll(Arrays.asList(o)); + return ret; + } finally { + closeConnection(); + } + } + + /* Private methods */ + /* ********************************************************************** */ + private boolean sendBinaryStream(HttpURLConnection connection, InputStream in, ResponseHandler rh) throws IOException { + initAuthentication(connection); + connection.setDoInput(true); + connection.setDoOutput(true); + connection.setChunkedStreamingMode(4096); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + copy(in, connection.getOutputStream()); + int responseCode = connection.getResponseCode(); + String response = readStringResponse(connection); + if (rh == null) { + rh = new DefaultResponseHandler(); + } + + return rh.checkResponse(responseCode, response); + + } + + private void copy(InputStream in, OutputStream out) throws IOException { + ReadableByteChannel source = Channels.newChannel(in); + WritableByteChannel target = Channels.newChannel(out); + + ByteBuffer buffer = ByteBuffer.allocate(16 * 1024); + while (source.read(buffer) != -1) { + buffer.flip(); // Prepare the buffer to be drained + while (buffer.hasRemaining()) { + target.write(buffer); + } + buffer.clear(); // Empty buffer to get ready for filling + } + + source.close(); + target.close(); + + } + + private boolean sendBinaryData(HttpURLConnection connection, byte[] data, ResponseHandler rh) throws IOException { + initAuthentication(connection); + writeData(connection, data); + int responseCode = connection.getResponseCode(); + String response = readStringResponse(connection); + if (rh == null) { + rh = new DefaultResponseHandler(); + } + + return rh.checkResponse(responseCode, response); + } + + private void writeData(HttpURLConnection connection, byte[] data) throws IOException { + connection.setDoInput(true); + connection.setDoOutput(true); + connection.setChunkedStreamingMode(4096); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + BufferedOutputStream outputStream = new BufferedOutputStream(connection.getOutputStream()); + outputStream.write(data); + outputStream.flush(); + outputStream.close(); + + } + + private boolean writeJsonData(Object data, HttpURLConnection connection, ResponseHandler rh) throws IOException { + + String dataStr = gson.toJson(data); + initAuthentication(connection); + writeData(connection, dataStr.getBytes("UTF-8")); + int responseCode = connection.getResponseCode(); + String response = readStringResponse(connection); + if (rh == null) { + rh = new DefaultResponseHandler(); + } + + return rh.checkResponse(responseCode, response); + } + + private String readStringResponse(HttpURLConnection connection) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String inputLine; + StringBuilder builder = new StringBuilder(); + while ((inputLine = reader.readLine()) != null) { + builder.append(inputLine); + } + String resultString = builder.toString(); + reader.close(); + return resultString; + } + + private void setUpHttpConnection() { + try { + + String urlString = restContext.getResource(); + URL url = new URL(urlString); + if (url.getProtocol().equals("http")) { + connection = (HttpURLConnection) url.openConnection(); + + } + if (url.getProtocol().equals("https")) { + connection = makeHttpsConnection(url); + } + + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + /** + * + * @param url + * @return + * @throws CertificateException + * @throws IOException + * @throws KeyManagementException + * @throws NoSuchAlgorithmException + * @throws KeyStoreException + * @throws FileNotFoundException + */ + private HttpURLConnection makeHttpsConnection(URL url) throws CertificateException, IOException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException { + if (keyStore == null) { + CertificateProvider certificateProvider = restContext.getCertificateProvider(); + if (certificateProvider == null) { + throw new CertificateException("Need a certification provider"); + } + Certificate ca = certificateProvider.getCertificate(); + + String keyStoreType = KeyStore.getDefaultType(); + keyStore = KeyStore.getInstance(keyStoreType); + keyStore.load(null, null); + keyStore.setCertificateEntry("ca", ca); + + // Create a TrustManager that trusts the CAs in our KeyStore + String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); + tmf = TrustManagerFactory.getInstance(tmfAlgorithm); + tmf.init(keyStore); + + // Create an SSLContext that uses our TrustManager + context = SSLContext.getInstance("TLS"); + context.init(null, tmf.getTrustManagers(), null); + } + + // Tell the URLConnection to use a SocketFactory from our SSLContext + HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); + urlConnection.setSSLSocketFactory(context.getSocketFactory()); + + if (!verifyHostName) { + HostnameVerifier hv = new HostnameVerifier() { + + @Override + public boolean verify(String string, SSLSession ssls) { + return true; + } + }; + urlConnection.setHostnameVerifier(hv); + } + + return urlConnection; + } +} diff --git a/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/exceptions/RestResponseException.java b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/exceptions/RestResponseException.java new file mode 100644 index 0000000..48cdbde --- /dev/null +++ b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/exceptions/RestResponseException.java @@ -0,0 +1,24 @@ +package gdetester.restapi.exceptions; + +/** + * + * @author mordicus + */ +public class RestResponseException extends RuntimeException { + + public RestResponseException(Throwable cause) { + super(cause); + } + + public RestResponseException(String message, Throwable cause) { + super(message, cause); + } + + public RestResponseException(String message) { + super(message); + } + + public RestResponseException() { + } + +} diff --git a/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/providers/CertificateProvider.java b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/providers/CertificateProvider.java new file mode 100644 index 0000000..5f98153 --- /dev/null +++ b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/providers/CertificateProvider.java @@ -0,0 +1,11 @@ +package gdetester.restapi.providers; + +import java.io.IOException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; + +public interface CertificateProvider { + + public Certificate getCertificate() throws CertificateException, IOException; + +} diff --git a/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/providers/FileCertificateProvider.java b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/providers/FileCertificateProvider.java new file mode 100644 index 0000000..74e0387 --- /dev/null +++ b/projects/GDE_App/GDE-war/test/com/edf/gde/test/restapi/providers/FileCertificateProvider.java @@ -0,0 +1,47 @@ +package gdetester.restapi.providers; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; + +public class FileCertificateProvider implements CertificateProvider { + + private final File file; + private Certificate ca; + + public FileCertificateProvider(File file) { + this.file = file; + } + + public FileCertificateProvider(String fileName) { + file = new File(fileName); + } + + @Override + public Certificate getCertificate() throws CertificateException, IOException { + if (ca != null) { + return ca; + } + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + InputStream caInput = null; + try { + caInput = new BufferedInputStream(new FileInputStream(file)); + ca = cf.generateCertificate(caInput); + return ca; + } catch (FileNotFoundException ex) { + throw new IOException(ex); + } finally { + if (caInput != null) { + caInput.close(); + } + } + } + +} -- 2.39.2