From ee237f46b3130b7a17fc139c9be67cc4af3d6b14 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Fri, 5 Aug 2022 19:35:09 +0530 Subject: [PATCH 1/5] api setup --- pom.xml | 119 +++--- src/main/java/com/razorpay/ApiClient.java | 376 +++++++++--------- src/main/java/com/razorpay/ApiUtils.java | 332 +++++++++------- src/main/java/com/razorpay/Constants.java | 2 - src/main/java/com/razorpay/Entity.java | 3 +- .../com/razorpay/EntityNameURLMapping.java | 29 +- src/main/java/com/razorpay/IApiUtils.java | 19 + .../razorpay/TLSSocketConnectionFactory.java | 372 +++++++++++++++++ 8 files changed, 838 insertions(+), 414 deletions(-) create mode 100644 src/main/java/com/razorpay/IApiUtils.java create mode 100644 src/main/java/com/razorpay/TLSSocketConnectionFactory.java diff --git a/pom.xml b/pom.xml index 1b0abe6f..2baf0f60 100644 --- a/pom.xml +++ b/pom.xml @@ -36,73 +36,48 @@ UTF-8 - 1.8 - 1.8 + 6 + 6 - - junit - junit - 4.13.2 - test - - - org.mockito - mockito-inline - 2.13.0 - test - + org.json json - test - - - - com.fasterxml.jackson.core - jackson-databind - 2.13.1 - test + 20070829 - - - - com.squareup.okhttp3 - okhttp - 3.10.0 - - - com.squareup.okhttp3 - logging-interceptor - 3.10.0 + org.apache.commons + commons-lang3 + 3.1 - org.json - json - 20180130 + junit + junit + 4.10 + test - - commons-codec - commons-codec - 1.11 + org.mockito + mockito-all + 1.10.19 + test - org.apache.commons - commons-text - 1.3 + org.bouncycastle + bcprov-jdk15on + 1.54 @@ -131,7 +106,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.9 + 1.6.4 true ossrh @@ -139,6 +114,15 @@ true + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + org.apache.maven.plugins maven-source-plugin @@ -154,31 +138,44 @@ org.apache.maven.plugins - maven-javadoc-plugin + maven-source-plugin 3.0.1 - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify + attach-sources - sign + jar-no-fork + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/razorpay/ApiClient.java b/src/main/java/com/razorpay/ApiClient.java index 319ec3c0..f380e601 100755 --- a/src/main/java/com/razorpay/ApiClient.java +++ b/src/main/java/com/razorpay/ApiClient.java @@ -1,226 +1,234 @@ package com.razorpay; -import java.io.IOException; +import java.io.*; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.List; +import java.util.Iterator; -import org.apache.commons.text.WordUtils; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; +import org.apache.commons.lang3.text.WordUtils; -import okhttp3.HttpUrl; -import okhttp3.Response; class ApiClient { - String auth; + String auth; - private final String ENTITY = "entity"; + IApiUtils iApp; - private final String COLLECTION = "collection"; + private final String ENTITY = "entity"; - private final String ERROR = "error"; + private final String COLLECTION = "collection"; - private final String DESCRIPTION = "description"; + private final String ERROR = "error"; - private final String STATUS_CODE = "code"; + private final String DESCRIPTION = "description"; - private final int STATUS_OK = 200; + private final String STATUS_CODE = "code"; - private final int STATUS_MULTIPLE_CHOICE = 300; + private final int STATUS_OK = 200; - ApiClient(String auth) { - this.auth = auth; - } + private final int STATUS_MULTIPLE_CHOICE = 300; - public T get(String path, JSONObject requestObject) throws RazorpayException { - Response response = ApiUtils.getRequest(path, requestObject, auth); - return processResponse(response); - } + ApiClient(String auth) { + this.auth = auth; + } + + public T get(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { - public T post(String path, JSONObject requestObject) throws RazorpayException { - Response response = ApiUtils.postRequest(path, requestObject, auth); - return processResponse(response); - } + String query = null; + if(requestObject != null){ + query = queryBuilder(requestObject); + } - public T put(String path, JSONObject requestObject) throws RazorpayException { - Response response = ApiUtils.putRequest(path, requestObject, auth); - return processResponse(response); - } + ApiUtils utils = new ApiUtils(); + URL builder = getBuilder(path,query); + String response = utils.processGetRequest(builder.toString(),requestObject, auth); + return processResponse(response,builder.toString()); + } - public T patch(String path, JSONObject requestObject) throws RazorpayException { - Response response = ApiUtils.patchRequest(path, requestObject, auth); - return processResponse(response); - } + public T post(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { + ApiUtils x = new ApiUtils(); + URL builder = getBuilder(path,null); + String response = x.processPostRequest(builder.toString(),requestObject, auth); + return processResponse(response,builder.toString()); + } + public T put(String path, JSONObject requestObject) throws RazorpayException, JSONException, IOException, URISyntaxException { + ApiUtils utils = new ApiUtils(); + URL builder = getBuilder(path,null); + String response = utils.processPutRequest(builder.toString(),requestObject, auth); + return processResponse(response,builder.toString()); + } - ArrayList getCollection(String path, JSONObject requestObject) - throws RazorpayException { - Response response = ApiUtils.getRequest(path, requestObject, auth); - return processCollectionResponse(response); - } + public T patch(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { + ApiUtils utils = new ApiUtils(); + URL builder = getBuilder(path,null); + String response = utils.processPatchRequest(builder.toString(),requestObject, auth); + return processResponse(response,builder.toString()); + } - public T delete(String path, JSONObject requestObject) throws RazorpayException { - Response response = ApiUtils.deleteRequest(path, requestObject, auth); - return processDeleteResponse(response); - } + public T delete(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { + ApiUtils utils = new ApiUtils(); + URL builder = getBuilder(path,null); + String response = utils.processDeleteRequest(builder.toString(),requestObject, auth); + return processDeleteResponse(response,builder.toString()); + } - private T processDeleteResponse(Response response) throws RazorpayException { - if (response == null) { - throw new RazorpayException("Invalid Response from server"); + ArrayList getCollection(String path, JSONObject requestObject) + throws RazorpayException, IOException, URISyntaxException, JSONException { + String query = null; + if(requestObject != null){ + query = queryBuilder(requestObject); + } + + ApiUtils utils = new ApiUtils(); + URL builder = getBuilder(path,query); + String response = utils.processGetRequest(builder.toString(),requestObject, auth); + return processCollectionResponse(response,builder.toString()); } - int statusCode = response.code(); - String responseBody = null; - JSONObject responseJson = null; - try { - responseBody = response.body().string(); - if(responseBody.equals("[]")){ - return (T) Collections.emptyList(); - } - else if(response.code()==204){ - return null; - } - else{ - responseJson = new JSONObject(responseBody); - } - } catch (IOException e) { - throw new RazorpayException(e.getMessage()); + private ArrayList parseCollectionResponse(JSONArray jsonArray, URL requestUrl) + throws RazorpayException, JSONException { + + ArrayList modelList = new ArrayList(); + try { + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jsonObj = jsonArray.getJSONObject(i); + T t = parseResponse(jsonObj, getEntity(jsonObj,requestUrl)); + modelList.add(t); + } + return modelList; + } catch (RazorpayException e) { + throw e; + } } - if (statusCode < STATUS_OK || statusCode >= STATUS_MULTIPLE_CHOICE) { - throwException(statusCode, responseJson); + T processResponse(String response,String url) throws RazorpayException, JSONException, IOException { + if (response == null) { + throw new RazorpayException("Invalid Response from server"); + } + + JSONObject responseJson = new JSONObject(response); + return parseResponse(responseJson, getEntity(responseJson, new URL(url))); + } - return (T) parseResponse(responseJson, getEntity(responseJson, response.request().url())); - } - private T parseResponse(JSONObject jsonObject, String entity) throws RazorpayException { - if (entity != null) { - Class cls = getClass(entity); - try { - return cls.getConstructor(JSONObject.class).newInstance(jsonObject); - } catch (Exception e) { - throw new RazorpayException("Unable to parse response because of " + e.getMessage()); - } + private T parseResponse(JSONObject jsonObject, String entity) throws RazorpayException { + if (entity != null) { + Class cls = getClass(entity); + try { + return cls.getConstructor(JSONObject.class).newInstance(jsonObject); + } catch (Exception e) { + throw new RazorpayException("Unable to parse response because of " + e.getMessage()); + } + } + + throw new RazorpayException("Unable to parse response"); } - throw new RazorpayException("Unable to parse response"); - } + ArrayList processCollectionResponse(String response,String url) + throws RazorpayException, JSONException, IOException { + if (response == null) { + throw new RazorpayException("Invalid Response from server"); + } + + String collectionName = null; + + JSONObject responseJson = new JSONObject(response); + + collectionName = responseJson.has("payment_links")? "payment_links": "items"; - private ArrayList parseCollectionResponse(JSONArray jsonArray, HttpUrl requestUrl) - throws RazorpayException { + return parseCollectionResponse(responseJson.getJSONArray(collectionName), new URL(url)); - ArrayList modelList = new ArrayList(); - try { - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject jsonObj = jsonArray.getJSONObject(i); - T t = parseResponse(jsonObj, getEntity(jsonObj,requestUrl)); - modelList.add(t); - } - return modelList; - } catch (RazorpayException e) { - throw e; - } - } - - /* - * this method will take http url as : https://api.razorpay.com/v1/invocies - * and will return entity name with the help of @EntityNameURLMapping class - */ - private String getEntityNameFromURL(HttpUrl url) { - String param = url.pathSegments().get(1); - return EntityNameURLMapping.getEntityName(param); - } - - - T processResponse(Response response) throws RazorpayException { - if (response == null) { - throw new RazorpayException("Invalid Response from server"); - } - - int statusCode = response.code(); - String responseBody = null; - JSONObject responseJson = null; - try { - responseBody = response.body().string(); - responseJson = new JSONObject(responseBody); - } catch (IOException e) { - throw new RazorpayException(e.getMessage()); - } - - if (statusCode >= STATUS_OK && statusCode < STATUS_MULTIPLE_CHOICE) { - return parseResponse(responseJson, getEntity(responseJson, response.request().url())); - } - - throwException(statusCode, responseJson); - return null; - } - - ArrayList processCollectionResponse(Response response) - throws RazorpayException { - if (response == null) { - throw new RazorpayException("Invalid Response from server"); - } - - int statusCode = response.code(); - String responseBody = null; - JSONObject responseJson = null; - - try { - responseBody = response.body().string(); - responseJson = new JSONObject(responseBody); - } catch (IOException e) { - throw new RazorpayException(e.getMessage()); - } - - String collectionName = null; - collectionName = responseJson.has("payment_links")? - "payment_links": "items"; - - if (statusCode >= STATUS_OK && statusCode < STATUS_MULTIPLE_CHOICE) { - return parseCollectionResponse(responseJson.getJSONArray(collectionName), response.request().url()); - } - - throwException(statusCode, responseJson); - return null; - } - private String getEntity(JSONObject jsonObj, HttpUrl url) { - if(!jsonObj.has(ENTITY)) { - return getEntityNameFromURL(url); - }else if(jsonObj.get("entity").toString().equals("settlement.ondemand")){ - return "settlement"; - }else{ - return jsonObj.getString(ENTITY); - } - } - - private void throwException(int statusCode, JSONObject responseJson) throws RazorpayException { - if (responseJson.has(ERROR)) { - JSONObject errorResponse = responseJson.getJSONObject(ERROR); - String code = errorResponse.getString(STATUS_CODE); - String description = errorResponse.getString(DESCRIPTION); - throw new RazorpayException(code + ":" + description); } - throwServerException(statusCode, responseJson.toString()); - } - - private void throwServerException(int statusCode, String responseBody) throws RazorpayException { - StringBuilder sb = new StringBuilder(); - sb.append("Status Code: ").append(statusCode).append("\n"); - sb.append("Server response: ").append(responseBody); - throw new RazorpayException(sb.toString()); - } - - private Class getClass(String entity) { - try { - String entityClass = "com.razorpay." + WordUtils.capitalize(entity, '_').replaceAll("_", ""); - return Class.forName(entityClass); - } catch (ClassNotFoundException e) { - return null; + + private T processDeleteResponse(String response,String url) throws RazorpayException, JSONException, IOException { + if (response == null) { + throw new RazorpayException("Invalid Response from server"); + } + JSONObject responseJson = null; + + if(response.startsWith("[")){ + return (T) Collections.emptyList(); + } + else{ + responseJson = new JSONObject(response); + } + + return (T) parseResponse(responseJson, getEntity(responseJson, new URL(url))); + } + + /* + * this method will take http url as : https://api.razorpay.com/v1/invocies + * and will return entity name with the help of @EntityNameURLMapping class + */ + private String getEntityNameFromURL(URL url) { + String[] path = url.getPath().split("/"); + String param = path[2]; + return EntityNameURLMapping.getEntityName(param); + } + + private String getEntity(JSONObject jsonObj, URL url) throws JSONException { + if(!jsonObj.has(ENTITY)) { + return getEntityNameFromURL(url); + }else if(jsonObj.get("entity").toString().equals("settlement.ondemand")){ + return "settlement"; + }else{ + return jsonObj.getString(ENTITY); + } + } + + private String queryBuilder(JSONObject requestObject) throws JSONException { + String query = null; + Iterator keys = requestObject.keys(); + while(keys.hasNext()) { + String key = keys.next(); + if(query==null){ + query = ""; + } + query += "&" + key + "=" + requestObject.get(key); + } + + return query; + } + + public static URL getBuilder(String path,String query) throws URISyntaxException, MalformedURLException { + URI uri = new URI(Constants.SCHEME, Constants.HOSTNAME, "/"+Constants.VERSION + "/"+path+"", query,null); + return uri.toURL(); + } + + private void throwException(int statusCode, JSONObject responseJson) throws RazorpayException, JSONException { + if (responseJson.has(ERROR)) { + JSONObject errorResponse = responseJson.getJSONObject(ERROR); + String code = errorResponse.getString(STATUS_CODE); + String description = errorResponse.getString(DESCRIPTION); + throw new RazorpayException(code + ":" + description); + } + throwServerException(statusCode, responseJson.toString()); + } + + private void throwServerException(int statusCode, String responseBody) throws RazorpayException { + StringBuilder sb = new StringBuilder(); + sb.append("Status Code: ").append(statusCode).append("\n"); + sb.append("Server response: ").append(responseBody); + throw new RazorpayException(sb.toString()); + } + + private Class getClass(String entity) { + try { + String CapEntity = entity.substring(0, 1).toUpperCase() + entity.substring(1); + String entityClass = "com.razorpay." + WordUtils.capitalize(entity, '_').replaceAll("_", ""); + return Class.forName(entityClass); + } catch (ClassNotFoundException e) { + return null; + } } - } } \ No newline at end of file diff --git a/src/main/java/com/razorpay/ApiUtils.java b/src/main/java/com/razorpay/ApiUtils.java index 0dcc73da..73af4ecc 100755 --- a/src/main/java/com/razorpay/ApiUtils.java +++ b/src/main/java/com/razorpay/ApiUtils.java @@ -1,179 +1,203 @@ package com.razorpay; -import java.io.IOException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; + +import java.io.*; +import java.net.*; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; +import org.json.JSONException; import org.json.JSONObject; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okhttp3.logging.HttpLoggingInterceptor; +import javax.net.ssl.HttpsURLConnection; -class ApiUtils { - private static OkHttpClient client; - private static Map headers = new HashMap(); +class ApiUtils implements IApiUtils { - private static String version = null; + private static HttpsURLConnection client; + private static Map headers = new HashMap(); - static void createHttpClientInstance(boolean enableLogging) throws RazorpayException { - if (client == null) { - HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); - if (enableLogging) { - loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); - } else { - loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE); - } - - try { - client = new OkHttpClient.Builder() - .readTimeout(60, TimeUnit.SECONDS) - .writeTimeout(60, TimeUnit.SECONDS) - .addInterceptor(loggingInterceptor) - .sslSocketFactory(new CustomTLSSocketFactory(), createDefaultTrustManager()) - .build(); - } catch (Exception e) { - throw new RazorpayException(e); - } - } + private static String version = null; - Properties properties = new Properties(); - try { - properties.load(ApiUtils.class.getResourceAsStream("/project.properties")); - version = (String) properties.get("version"); - } catch (IOException e) { - throw new RazorpayException(e.getMessage()); + private enum Method { + GET, POST, PUT, PATCH, DELETE } - } - - private enum Method { - GET, POST, PUT, PATCH, DELETE - } - - static Response postRequest(String path, JSONObject requestObject, String auth) - throws RazorpayException { - - HttpUrl.Builder builder = getBuilder(path); - - String requestContent = requestObject == null ? "" : requestObject.toString(); - RequestBody requestBody = RequestBody.create(Constants.MEDIA_TYPE_JSON, requestContent); - - Request request = - createRequest(Method.POST.name(), builder.build().toString(), requestBody, auth); - return processRequest(request); - } - - static Response putRequest(String path, JSONObject requestObject, String auth) - throws RazorpayException { - - HttpUrl.Builder builder = getBuilder(path); - - String requestContent = requestObject == null ? "" : requestObject.toString(); - RequestBody requestBody = RequestBody.create(Constants.MEDIA_TYPE_JSON, requestContent); - - Request request = - createRequest(Method.PUT.name(), builder.build().toString(), requestBody, auth); - return processRequest(request); - } - - static Response patchRequest(String path, JSONObject requestObject, String auth) - throws RazorpayException { - HttpUrl.Builder builder = getBuilder(path); - String requestContent = requestObject == null ? "" : requestObject.toString(); - RequestBody requestBody = RequestBody.create(Constants.MEDIA_TYPE_JSON, requestContent); - - Request request = - createRequest(Method.PATCH.name(), builder.build().toString(), requestBody, auth); - return processRequest(request); - } - - static Response getRequest(String path, JSONObject requestObject, String auth) - throws RazorpayException { - - HttpUrl.Builder builder = getBuilder(path); - addQueryParams(builder, requestObject); - - Request request = createRequest(Method.GET.name(), builder.build().toString(), null, auth); - return processRequest(request); - } - - static Response deleteRequest(String path, JSONObject requestObject, String auth) - throws RazorpayException { - - HttpUrl.Builder builder = getBuilder(path); - addQueryParams(builder, requestObject); - - Request request = createRequest(Method.DELETE.name(), builder.build().toString(), null, auth); - return processRequest(request); - } + @Override + public String processGetRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + HttpsURLConnection httpconn = createRequest(Method.GET.name(), new URL(path), null, auth); + try { + BufferedReader br = new BufferedReader(new InputStreamReader( + httpconn.getInputStream())); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + + sb.append(line + "\n"); + } + br.close(); + + return sb.toString(); + } catch (IOException e) { + InputStream errorStream = httpconn.getErrorStream(); + String getMessage = HttpException(errorStream); + throw new RazorpayException(getMessage); + } + } - private static HttpUrl.Builder getBuilder(String path) { - return new HttpUrl.Builder().scheme(Constants.SCHEME).host(Constants.HOSTNAME) - .port(Constants.PORT).addPathSegment(Constants.VERSION).addPathSegments(path); - } + @Override + public String processPostRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + + HttpsURLConnection httpconn = createRequest(Method.POST.name(), new URL(path), requestObject, auth); + try { + BufferedReader br = new BufferedReader(new InputStreamReader( + httpconn.getInputStream())); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + + sb.append(line + "\n"); + } + br.close(); + + return sb.toString(); + } catch (IOException e) { + InputStream errorStream = httpconn.getErrorStream(); + String getMessage = HttpException(errorStream); + throw new RazorpayException(getMessage); + } + } - private static Request createRequest(String method, String url, RequestBody requestBody, - String auth) { - Request.Builder builder = - new Request.Builder().url(url).addHeader(Constants.AUTH_HEADER_KEY, auth); - builder.addHeader(Constants.USER_AGENT, - "Razorpay/v1 JAVASDK/" + version + " Java/" + System.getProperty("java.version")); + @Override + public String processDeleteRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + + HttpsURLConnection httpconn = createRequest(Method.DELETE.name(), new URL(path), requestObject, auth); + try { + BufferedReader br = new BufferedReader(new InputStreamReader( + httpconn.getInputStream())); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + + sb.append(line + "\n"); + } + br.close(); + + return sb.toString(); + } catch (IOException e) { + InputStream errorStream = httpconn.getErrorStream(); + String getMessage = HttpException(errorStream); + throw new RazorpayException(getMessage); + } + } - for (Map.Entry header : headers.entrySet()) { - builder.addHeader(header.getKey(), header.getValue()); + @Override + public String processPutRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + + HttpsURLConnection httpconn = createRequest(Method.PUT.name(), new URL(path), requestObject, auth); + try { + BufferedReader br = new BufferedReader(new InputStreamReader( + httpconn.getInputStream())); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + + sb.append(line + "\n"); + } + br.close(); + + return sb.toString(); + } catch (IOException e) { + InputStream errorStream = httpconn.getErrorStream(); + String getMessage = HttpException(errorStream); + throw new RazorpayException(getMessage); + } } - return builder.method(method, requestBody).build(); - } + @Override + public String processPatchRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + + HttpsURLConnection httpconn = createRequest(Method.PATCH.name(), new URL(path), requestObject, auth); + try { + BufferedReader br = new BufferedReader(new InputStreamReader( + httpconn.getInputStream())); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + + sb.append(line + "\n"); + } + br.close(); + + return sb.toString(); + } catch (IOException e) { + InputStream errorStream = httpconn.getErrorStream(); + String getMessage = HttpException(errorStream); + throw new RazorpayException(getMessage); + } + } - private static void addQueryParams(HttpUrl.Builder builder, JSONObject request) { - if (request == null) - return; + private static HttpsURLConnection createRequest(String method, URL url, JSONObject requestBody, + String auth) throws RazorpayException, IOException { + HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); + conn.setConnectTimeout(60*1000); + conn.setReadTimeout(60*1000); + conn.setSSLSocketFactory(new TLSSocketConnectionFactory()); + /* Checking headers value */ + if(headers.size() > 0){ + for(Map.Entry header: headers.entrySet()){ + conn.setRequestProperty(header.getKey(), header.getValue()); + } + } + + conn.setRequestProperty("Authorization", "Basic " + auth); + conn.setRequestProperty(Constants.USER_AGENT, "Razorpay/v1 JAVASDK/" + version + " Java/" + System.getProperty("java.version")); + + if (method == Method.PATCH.name()) { + conn.setRequestMethod("POST"); + conn.setRequestProperty("X-HTTP-Method-Override", "PATCH"); + }else{ + conn.setRequestMethod(method); + } + + conn.setUseCaches(false); + if (conn.getRequestMethod() == Method.POST.name() || conn.getRequestMethod() == Method.PUT.name()) { + conn.setRequestProperty("Content-Type", "application/json"); + if(requestBody != null ) { + byte[] out = requestBody.toString().getBytes("UTF-8"); + conn.setDoOutput(true); + OutputStream stream = conn.getOutputStream(); + stream.write(out); + } + } + + return conn; + } - Iterator keys = request.keys(); - while (keys.hasNext()) { - String key = (String) keys.next(); - builder.addQueryParameter(key, request.get(key).toString()); - } - } + static void addHeaders(Map header) { + headers.putAll(header); + } - private static Response processRequest(Request request) throws RazorpayException { - try { - return client.newCall(request).execute(); - } catch (IOException e) { - throw new RazorpayException(e.getMessage()); + private static String HttpException(InputStream errorStream) throws IOException { + String responseString = null; + BufferedInputStream bis = null; + try { + StringBuilder sb = new StringBuilder(); + bis = new BufferedInputStream(errorStream); + byte[] byteContents = new byte[4096]; + int bytesRead; + String strContents; + while ((bytesRead = bis.read(byteContents)) != -1) { + strContents = new String(byteContents, 0, bytesRead, "UTF-8"); // You might need to replace the charSet as per the responseEncoding returned by httpurlconnection above + sb.append(strContents); + } + return sb.toString(); + } finally { + if (bis != null) { + bis.close(); + } + } } - } - - static void addHeaders(Map header) { - headers.putAll(header); - } - - private static X509TrustManager createDefaultTrustManager() throws NoSuchAlgorithmException, KeyStoreException { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init((KeyStore) null); - TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { - throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); } - X509TrustManager trustManager = (X509TrustManager) trustManagers[0]; - return trustManager; - } -} + diff --git a/src/main/java/com/razorpay/Constants.java b/src/main/java/com/razorpay/Constants.java index 748d58db..75d7b49b 100755 --- a/src/main/java/com/razorpay/Constants.java +++ b/src/main/java/com/razorpay/Constants.java @@ -1,6 +1,5 @@ package com.razorpay; -import okhttp3.MediaType; public class Constants { @@ -12,7 +11,6 @@ public class Constants { static final String AUTH_HEADER_KEY = "Authorization"; static final String USER_AGENT = "User-Agent"; - static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8"); // API URI static final String PAYMENT_GET = "payments/%s"; diff --git a/src/main/java/com/razorpay/Entity.java b/src/main/java/com/razorpay/Entity.java index ec46e474..1260c8aa 100644 --- a/src/main/java/com/razorpay/Entity.java +++ b/src/main/java/com/razorpay/Entity.java @@ -2,6 +2,7 @@ import java.util.Date; +import org.json.JSONException; import org.json.JSONObject; public abstract class Entity { @@ -15,7 +16,7 @@ public abstract class Entity { this.modelJson = jsonObject; } - public T get(String key) { + public T get(String key) throws JSONException { // Return null if key not in JSONObject if (!has(key)) { return null; diff --git a/src/main/java/com/razorpay/EntityNameURLMapping.java b/src/main/java/com/razorpay/EntityNameURLMapping.java index 106f4885..f742e7f6 100644 --- a/src/main/java/com/razorpay/EntityNameURLMapping.java +++ b/src/main/java/com/razorpay/EntityNameURLMapping.java @@ -1,19 +1,19 @@ package com.razorpay; -import java.util.Arrays; +import java.util.*; - /** +/** * Enum name is acting as url and entity is denoting Entity class - * ex: https://api.razorpay.com/v1/invocies - * getEntityName method will take "invoices" from above mentioned url - * and will return "invoice" as entity name as mentioned below in mapping INVOICES("invoice") + * ex: https://api.razorpay.com/v1/invoices + * getEntityName method will take "invoices" from above mentioned url + * and will return "invoice" as entity name as mentioned below in mapping INVOICES("invoice") */ public enum EntityNameURLMapping { - + INVOICES("invoice"), SETTLEMENTS("settlement"), - PAYMENTS("payment"), + PAYMENTS("payment"), PAYMENT_LINKS("payment_link"), ITEMS("item"), CUSTOMERS("customer"); @@ -23,15 +23,20 @@ public enum EntityNameURLMapping { EntityNameURLMapping(String entity) { this.entity= entity; } - + private String getEntity() { return entity; } - public static String getEntityName(String urlStirng) + public static String getEntityName(String urlString) { - EntityNameURLMapping item = Arrays.asList(values()).stream().filter( val -> val.name().equalsIgnoreCase(urlStirng)).findFirst().orElseThrow(() -> new IllegalArgumentException("Unable to resolve")); - return item.getEntity(); + EntityNameURLMapping entityNames[] = EntityNameURLMapping.values(); + for(EntityNameURLMapping entityName : entityNames){ + if(urlString.equals(entityName.toString().toLowerCase())){ + return entityName.entity; + } + } + throw new IllegalArgumentException("Unable to resolve"); } -} \ No newline at end of file +} diff --git a/src/main/java/com/razorpay/IApiUtils.java b/src/main/java/com/razorpay/IApiUtils.java new file mode 100644 index 00000000..c930b79e --- /dev/null +++ b/src/main/java/com/razorpay/IApiUtils.java @@ -0,0 +1,19 @@ +package com.razorpay; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.URISyntaxException; + +interface IApiUtils { + + public String processGetRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; + + public String processPostRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; + public String processDeleteRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; + + public String processPatchRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; + + public String processPutRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; +} diff --git a/src/main/java/com/razorpay/TLSSocketConnectionFactory.java b/src/main/java/com/razorpay/TLSSocketConnectionFactory.java new file mode 100644 index 00000000..9574fd2b --- /dev/null +++ b/src/main/java/com/razorpay/TLSSocketConnectionFactory.java @@ -0,0 +1,372 @@ +package com.razorpay; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.security.Principal; +import java.security.SecureRandom; +import java.security.Security; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; + +import javax.net.ssl.HandshakeCompletedEvent; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSessionContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.security.cert.X509Certificate; + +import org.bouncycastle.crypto.tls.Certificate; +import org.bouncycastle.crypto.tls.CertificateRequest; +import org.bouncycastle.crypto.tls.DefaultTlsClient; +import org.bouncycastle.crypto.tls.ExtensionType; +import org.bouncycastle.crypto.tls.TlsAuthentication; +import org.bouncycastle.crypto.tls.TlsClientProtocol; +import org.bouncycastle.crypto.tls.TlsCredentials; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +/** + * This Class enables TLS V1.2 connection based on BouncyCastle Providers. Just + * to use: URL myurl = new URL( "http:// ...URL tha only Works in TLS 1.2); + * HttpsURLConnection con = (HttpsURLConnection )myurl.openConnection(); + * con.setSSLSocketFactory(new TSLSocketConnectionFactory()); + * + * @author AZIMUTS + * + */ +public class TLSSocketConnectionFactory extends SSLSocketFactory { + + // ******************Adding Custom BouncyCastleProvider*********************// + static { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + } + + // ******************HANDSHAKE LISTENER*********************// + public class TLSHandshakeListener implements HandshakeCompletedListener { + + @Override + public void handshakeCompleted(HandshakeCompletedEvent event) { + + } + } + + private SecureRandom _secureRandom = new SecureRandom(); + + // ******************Adding Custom BouncyCastleProvider*********************// + @Override + public Socket createSocket(Socket socket, final String host, int port, boolean arg3) throws IOException { + if (socket == null) { + socket = new Socket(); + } + if (!socket.isConnected()) { + socket.connect(new InetSocketAddress(host, port)); + } + + final TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), _secureRandom); + return _createSSLSocket(host, tlsClientProtocol); + } + + // ******************SOCKET FACTORY METHODS*********************// + @Override + public String[] getDefaultCipherSuites() { + return null; + } + + @Override + public String[] getSupportedCipherSuites() { + return null; + } + + @Override + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + return null; + } + + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + return null; + } + + @Override + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { + return null; + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { + return null; + } + + // ******************SOCKET CREATION*********************// + private SSLSocket _createSSLSocket(final String host, final TlsClientProtocol tlsClientProtocol) { + return new SSLSocket() { + private java.security.cert.Certificate[] peertCerts; + + @Override + public InputStream getInputStream() throws IOException { + return tlsClientProtocol.getInputStream(); + } + + @Override + public OutputStream getOutputStream() throws IOException { + return tlsClientProtocol.getOutputStream(); + } + + @Override + public synchronized void close() throws IOException { + tlsClientProtocol.close(); + } + + @Override + public void addHandshakeCompletedListener(HandshakeCompletedListener arg0) { + + } + + @Override + public boolean getEnableSessionCreation() { + return false; + } + + @Override + public String[] getEnabledCipherSuites() { + return null; + } + + @Override + public String[] getEnabledProtocols() { + return null; + } + + @Override + public boolean getNeedClientAuth() { + return false; + } + + @Override + public SSLSession getSession() { + return new SSLSession() { + + @Override + public int getApplicationBufferSize() { + return 0; + } + + @Override + public String getCipherSuite() { + throw new UnsupportedOperationException(); + } + + @Override + public long getCreationTime() { + throw new UnsupportedOperationException(); + } + + @Override + public byte[] getId() { + throw new UnsupportedOperationException(); + } + + @Override + public long getLastAccessedTime() { + throw new UnsupportedOperationException(); + } + + @Override + public java.security.cert.Certificate[] getLocalCertificates() { + throw new UnsupportedOperationException(); + } + + @Override + public Principal getLocalPrincipal() { + throw new UnsupportedOperationException(); + } + + @Override + public int getPacketBufferSize() { + throw new UnsupportedOperationException(); + } + + @Override + public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException { + return null; + } + + @Override + public java.security.cert.Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { + return peertCerts; + } + + @Override + public String getPeerHost() { + throw new UnsupportedOperationException(); + } + + @Override + public int getPeerPort() { + return 0; + } + + @Override + public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { + return null; + //throw new UnsupportedOperationException(); + } + + @Override + public String getProtocol() { + throw new UnsupportedOperationException(); + } + + @Override + public SSLSessionContext getSessionContext() { + throw new UnsupportedOperationException(); + } + + @Override + public Object getValue(String arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public String[] getValueNames() { + throw new UnsupportedOperationException(); + } + + @Override + public void invalidate() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isValid() { + throw new UnsupportedOperationException(); + } + + @Override + public void putValue(String arg0, Object arg1) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeValue(String arg0) { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public String[] getSupportedProtocols() { + return null; + } + + @Override + public boolean getUseClientMode() { + return false; + } + + @Override + public boolean getWantClientAuth() { + return false; + } + + @Override + public void removeHandshakeCompletedListener(HandshakeCompletedListener arg0) { + } + + @Override + public void setEnableSessionCreation(boolean arg0) { + } + + @Override + public void setEnabledCipherSuites(String[] arg0) { + } + + @Override + public void setEnabledProtocols(String[] arg0) { + } + + @Override + public void setNeedClientAuth(boolean arg0) { + } + + @Override + public void setUseClientMode(boolean arg0) { + } + + @Override + public void setWantClientAuth(boolean arg0) { + } + + @Override + public String[] getSupportedCipherSuites() { + return null; + } + + @Override + public void startHandshake() throws IOException { + tlsClientProtocol.connect(new DefaultTlsClient() { + @Override + public Hashtable getClientExtensions() throws IOException { + Hashtable clientExtensions = super.getClientExtensions(); + if (clientExtensions == null) { + clientExtensions = new Hashtable(); + } + + //Add host_name + byte[] host_name = host.getBytes(); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final DataOutputStream dos = new DataOutputStream(baos); + dos.writeShort(host_name.length + 3); // entry size + dos.writeByte(0); // name type = hostname + dos.writeShort(host_name.length); + dos.write(host_name); + dos.close(); + clientExtensions.put(ExtensionType.server_name, baos.toByteArray()); + return clientExtensions; + } + + @Override + public TlsAuthentication getAuthentication() throws IOException { + return new TlsAuthentication() { + @Override + public void notifyServerCertificate(Certificate serverCertificate) throws IOException { + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + List certs = new LinkedList(); + for (org.bouncycastle.asn1.x509.Certificate c : serverCertificate.getCertificateList()) { + certs.add(cf.generateCertificate(new ByteArrayInputStream(c.getEncoded()))); + } + peertCerts = certs.toArray(new java.security.cert.Certificate[0]); + } catch (CertificateException e) { + System.out.println("Failed to cache server certs" + e); + throw new IOException(e); + } + } + + @Override + public TlsCredentials getClientCredentials(CertificateRequest arg0) throws IOException { + return null; + } + }; + } + }); + } + };//Socket + + } +} \ No newline at end of file From 0648098ca66266cd31878142dbc0d61aa4998cfc Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Sat, 13 Aug 2022 18:39:15 +0530 Subject: [PATCH 2/5] api setup --- pom.xml | 50 ++++----- src/main/java/com/razorpay/ApiClient.java | 62 ++++------- src/main/java/com/razorpay/ApiUtils.java | 25 ++--- src/main/java/com/razorpay/IApiUtils.java | 19 ---- src/main/java/com/razorpay/IAppUtils.java | 19 ++++ .../java/com/razorpay/RazorpayClient.java | 100 +++++++++--------- .../java/com/razorpay/RazorpayException.java | 20 +--- 7 files changed, 124 insertions(+), 171 deletions(-) delete mode 100644 src/main/java/com/razorpay/IApiUtils.java create mode 100644 src/main/java/com/razorpay/IAppUtils.java diff --git a/pom.xml b/pom.xml index 2baf0f60..f4663fff 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.razorpay razorpay-java - 1.4.3 + 1.1.1 jar razorpay-java @@ -73,7 +73,6 @@ 1.10.19 test - org.bouncycastle bcprov-jdk15on @@ -138,44 +137,31 @@ org.apache.maven.plugins - maven-source-plugin + maven-javadoc-plugin 3.0.1 - attach-sources + attach-javadocs - jar-no-fork + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/com/razorpay/ApiClient.java b/src/main/java/com/razorpay/ApiClient.java index f380e601..688ee884 100755 --- a/src/main/java/com/razorpay/ApiClient.java +++ b/src/main/java/com/razorpay/ApiClient.java @@ -19,7 +19,7 @@ class ApiClient { String auth; - IApiUtils iApp; + ApiUtils apiUtils; private final String ENTITY = "entity"; @@ -35,8 +35,9 @@ class ApiClient { private final int STATUS_MULTIPLE_CHOICE = 300; - ApiClient(String auth) { + ApiClient(String auth,ApiUtils apiUtils) { this.auth = auth; + this.apiUtils = apiUtils; } public T get(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { @@ -45,38 +46,35 @@ public T get(String path, JSONObject requestObject) throws Ra if(requestObject != null){ query = queryBuilder(requestObject); } - - ApiUtils utils = new ApiUtils(); URL builder = getBuilder(path,query); - String response = utils.processGetRequest(builder.toString(),requestObject, auth); + String request = requestObject==null ? null : requestObject.toString(); + String response = apiUtils.processGetRequest(builder.toString(),request, auth); return processResponse(response,builder.toString()); } public T post(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { - ApiUtils x = new ApiUtils(); URL builder = getBuilder(path,null); - String response = x.processPostRequest(builder.toString(),requestObject, auth); + String request = requestObject==null ? null : requestObject.toString(); + String response = apiUtils.processPostRequest(builder.toString(),request, auth); return processResponse(response,builder.toString()); } public T put(String path, JSONObject requestObject) throws RazorpayException, JSONException, IOException, URISyntaxException { - ApiUtils utils = new ApiUtils(); URL builder = getBuilder(path,null); - String response = utils.processPutRequest(builder.toString(),requestObject, auth); + String response = apiUtils.processPutRequest(builder.toString(),requestObject.toString(), auth); return processResponse(response,builder.toString()); } public T patch(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { - ApiUtils utils = new ApiUtils(); URL builder = getBuilder(path,null); - String response = utils.processPatchRequest(builder.toString(),requestObject, auth); + String response = apiUtils.processPatchRequest(builder.toString(),requestObject.toString(), auth); return processResponse(response,builder.toString()); } public T delete(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { - ApiUtils utils = new ApiUtils(); URL builder = getBuilder(path,null); - String response = utils.processDeleteRequest(builder.toString(),requestObject, auth); + String request = requestObject==null ? null : requestObject.toString(); + String response = apiUtils.processDeleteRequest(builder.toString(),request, auth); return processDeleteResponse(response,builder.toString()); } @@ -86,10 +84,14 @@ ArrayList getCollection(String path, JSONObject requestObj if(requestObject != null){ query = queryBuilder(requestObject); } - - ApiUtils utils = new ApiUtils(); URL builder = getBuilder(path,query); - String response = utils.processGetRequest(builder.toString(),requestObject, auth); + String response = apiUtils.processGetRequest(builder.toString(),null, auth); + return processCollectionResponse(response,builder.toString()); + } + + ArrayList postCollection(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { + URL builder = getBuilder(path,null); + String response = apiUtils.processPostRequest(builder.toString(),requestObject.toString(), auth); return processCollectionResponse(response,builder.toString()); } @@ -129,7 +131,6 @@ private T parseResponse(JSONObject jsonObject, String entity) throw new RazorpayException("Unable to parse response because of " + e.getMessage()); } } - throw new RazorpayException("Unable to parse response"); } @@ -138,16 +139,10 @@ ArrayList processCollectionResponse(String response,String if (response == null) { throw new RazorpayException("Invalid Response from server"); } - String collectionName = null; - JSONObject responseJson = new JSONObject(response); - collectionName = responseJson.has("payment_links")? "payment_links": "items"; - return parseCollectionResponse(responseJson.getJSONArray(collectionName), new URL(url)); - - } private T processDeleteResponse(String response,String url) throws RazorpayException, JSONException, IOException { @@ -155,10 +150,12 @@ private T processDeleteResponse(String response,String url) throw new RazorpayException("Invalid Response from server"); } JSONObject responseJson = null; - if(response.startsWith("[")){ return (T) Collections.emptyList(); } + else if(response.length()==0){ + return null; + } else{ responseJson = new JSONObject(response); } @@ -205,23 +202,6 @@ public static URL getBuilder(String path,String query) throws URISyntaxException return uri.toURL(); } - private void throwException(int statusCode, JSONObject responseJson) throws RazorpayException, JSONException { - if (responseJson.has(ERROR)) { - JSONObject errorResponse = responseJson.getJSONObject(ERROR); - String code = errorResponse.getString(STATUS_CODE); - String description = errorResponse.getString(DESCRIPTION); - throw new RazorpayException(code + ":" + description); - } - throwServerException(statusCode, responseJson.toString()); - } - - private void throwServerException(int statusCode, String responseBody) throws RazorpayException { - StringBuilder sb = new StringBuilder(); - sb.append("Status Code: ").append(statusCode).append("\n"); - sb.append("Server response: ").append(responseBody); - throw new RazorpayException(sb.toString()); - } - private Class getClass(String entity) { try { String CapEntity = entity.substring(0, 1).toUpperCase() + entity.substring(1); diff --git a/src/main/java/com/razorpay/ApiUtils.java b/src/main/java/com/razorpay/ApiUtils.java index 73af4ecc..8ba7166c 100755 --- a/src/main/java/com/razorpay/ApiUtils.java +++ b/src/main/java/com/razorpay/ApiUtils.java @@ -6,15 +6,10 @@ import java.util.HashMap; import java.util.Map; -import org.json.JSONException; -import org.json.JSONObject; - import javax.net.ssl.HttpsURLConnection; -class ApiUtils implements IApiUtils { - - private static HttpsURLConnection client; +class ApiUtils implements IAppUtils { private static Map headers = new HashMap(); private static String version = null; @@ -25,7 +20,7 @@ private enum Method { @Override - public String processGetRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + public String processGetRequest(String path, String requestObject, String auth) throws RazorpayException, IOException, URISyntaxException { HttpsURLConnection httpconn = createRequest(Method.GET.name(), new URL(path), null, auth); try { BufferedReader br = new BufferedReader(new InputStreamReader( @@ -47,7 +42,7 @@ public String processGetRequest(String path, JSONObject requestObject, String au } @Override - public String processPostRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + public String processPostRequest(String path, String requestObject, String auth) throws RazorpayException, IOException, URISyntaxException { HttpsURLConnection httpconn = createRequest(Method.POST.name(), new URL(path), requestObject, auth); try { @@ -70,7 +65,7 @@ public String processPostRequest(String path, JSONObject requestObject, String a } @Override - public String processDeleteRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + public String processDeleteRequest(String path, String requestObject, String auth) throws RazorpayException, IOException, URISyntaxException { HttpsURLConnection httpconn = createRequest(Method.DELETE.name(), new URL(path), requestObject, auth); try { @@ -93,7 +88,7 @@ public String processDeleteRequest(String path, JSONObject requestObject, String } @Override - public String processPutRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + public String processPutRequest(String path, String requestObject, String auth) throws RazorpayException, IOException, URISyntaxException { HttpsURLConnection httpconn = createRequest(Method.PUT.name(), new URL(path), requestObject, auth); try { @@ -116,7 +111,7 @@ public String processPutRequest(String path, JSONObject requestObject, String au } @Override - public String processPatchRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException { + public String processPatchRequest(String path, String requestObject, String auth) throws RazorpayException, IOException, URISyntaxException { HttpsURLConnection httpconn = createRequest(Method.PATCH.name(), new URL(path), requestObject, auth); try { @@ -138,8 +133,8 @@ public String processPatchRequest(String path, JSONObject requestObject, String } } - private static HttpsURLConnection createRequest(String method, URL url, JSONObject requestBody, - String auth) throws RazorpayException, IOException { + private static HttpsURLConnection createRequest(String method, URL url, String requestBody, + String auth) throws IOException { HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setConnectTimeout(60*1000); conn.setReadTimeout(60*1000); @@ -165,7 +160,7 @@ private static HttpsURLConnection createRequest(String method, URL url, JSONObje if (conn.getRequestMethod() == Method.POST.name() || conn.getRequestMethod() == Method.PUT.name()) { conn.setRequestProperty("Content-Type", "application/json"); if(requestBody != null ) { - byte[] out = requestBody.toString().getBytes("UTF-8"); + byte[] out = requestBody.getBytes("UTF-8"); conn.setDoOutput(true); OutputStream stream = conn.getOutputStream(); stream.write(out); @@ -198,6 +193,6 @@ private static String HttpException(InputStream errorStream) throws IOException bis.close(); } } - } + } } diff --git a/src/main/java/com/razorpay/IApiUtils.java b/src/main/java/com/razorpay/IApiUtils.java deleted file mode 100644 index c930b79e..00000000 --- a/src/main/java/com/razorpay/IApiUtils.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.razorpay; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.net.URISyntaxException; - -interface IApiUtils { - - public String processGetRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; - - public String processPostRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; - public String processDeleteRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; - - public String processPatchRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; - - public String processPutRequest(String path, JSONObject requestObject, String auth) throws RazorpayException, IOException, URISyntaxException, JSONException; -} diff --git a/src/main/java/com/razorpay/IAppUtils.java b/src/main/java/com/razorpay/IAppUtils.java new file mode 100644 index 00000000..ad4524d2 --- /dev/null +++ b/src/main/java/com/razorpay/IAppUtils.java @@ -0,0 +1,19 @@ +package com.razorpay; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.URISyntaxException; + +interface IAppUtils { + + String processGetRequest(String path, String request, String auth) throws RazorpayException, IOException, URISyntaxException; + + String processPostRequest(String path, String request, String auth) throws RazorpayException, IOException, URISyntaxException; + String processDeleteRequest(String path, String request, String auth) throws RazorpayException, IOException, URISyntaxException; + + String processPatchRequest(String path, String request, String auth) throws RazorpayException, IOException, URISyntaxException; + + String processPutRequest(String path, String request, String auth) throws RazorpayException, IOException, URISyntaxException; +} diff --git a/src/main/java/com/razorpay/RazorpayClient.java b/src/main/java/com/razorpay/RazorpayClient.java index a42bbcdd..581776ba 100755 --- a/src/main/java/com/razorpay/RazorpayClient.java +++ b/src/main/java/com/razorpay/RazorpayClient.java @@ -1,55 +1,59 @@ package com.razorpay; + +import java.io.UnsupportedEncodingException; import java.util.Map; -import okhttp3.Credentials; public class RazorpayClient { - public PaymentClient payments; - public RefundClient refunds; - public OrderClient orders; - public InvoiceClient invoices; - public CardClient cards; - public CustomerClient customers; - public TransferClient transfers; - public SubscriptionClient subscriptions; - public AddonClient addons; - public PlanClient plans; - public SettlementClient settlement; - public QrCodeClient qrCode; - public PaymentLinkClient paymentLink; - public ItemClient items; - public FundAccountClient fundAccount; - public VirtualAccountClient virtualAccounts; - - public RazorpayClient(String key, String secret) throws RazorpayException { - this(key, secret, false); - } - - public RazorpayClient(String key, String secret, Boolean enableLogging) throws RazorpayException { - ApiUtils.createHttpClientInstance(enableLogging); - String auth = Credentials.basic(key, secret); - payments = new PaymentClient(auth); - refunds = new RefundClient(auth); - orders = new OrderClient(auth); - invoices = new InvoiceClient(auth); - cards = new CardClient(auth); - customers = new CustomerClient(auth); - transfers = new TransferClient(auth); - subscriptions = new SubscriptionClient(auth); - addons = new AddonClient(auth); - plans = new PlanClient(auth); - settlement = new SettlementClient(auth); - qrCode = new QrCodeClient(auth); - paymentLink = new PaymentLinkClient(auth); - items = new ItemClient(auth); - fundAccount = new FundAccountClient(auth); - virtualAccounts = new VirtualAccountClient(auth); - } - - public RazorpayClient addHeaders(Map headers) { - ApiUtils.addHeaders(headers); - return this; - } -} + public PaymentClient payments; + public InvoiceClient invoices; + public CustomerClient customers; + public CardClient cards; + public FundAccountClient fundAccount; + public ItemClient items; + public OrderClient orders; + public AddonClient addons; + public RefundClient refunds; + public TransferClient transfers; + public SubscriptionRegistrationClient subscriptionRegistrations; + public SubscriptionClient subscriptions; + public PlanClient plans; + public SettlementClient settlement; + public QrCodeClient qrCode; + public PaymentLinkClient paymentLink; + public VirtualAccountClient virtualAccounts; + + public RazorpayClient(String key, String secret) throws RazorpayException, UnsupportedEncodingException { + this(key, secret, false); + } + + public RazorpayClient(String key, String secret, Boolean enableLogging) throws RazorpayException, UnsupportedEncodingException { + byte[] message = (key + ":" + secret).getBytes("UTF-8"); + String auth = javax.xml.bind.DatatypeConverter.printBase64Binary(message); + ApiUtils apiUtils = new ApiUtils(); + payments = new PaymentClient(auth,apiUtils); + invoices = new InvoiceClient(auth,apiUtils); + customers = new CustomerClient(auth,apiUtils); + cards = new CardClient(auth,apiUtils); + subscriptionRegistrations = new SubscriptionRegistrationClient(auth,apiUtils); + fundAccount = new FundAccountClient(auth,apiUtils); + items = new ItemClient(auth,apiUtils); + orders = new OrderClient(auth,apiUtils); + addons = new AddonClient(auth,apiUtils); + refunds = new RefundClient(auth,apiUtils); + transfers = new TransferClient(auth,apiUtils); + subscriptions = new SubscriptionClient(auth,apiUtils); + plans = new PlanClient(auth,apiUtils); + settlement = new SettlementClient(auth,apiUtils); + qrCode = new QrCodeClient(auth,apiUtils); + paymentLink = new PaymentLinkClient(auth,apiUtils); + virtualAccounts = new VirtualAccountClient(auth,apiUtils); + } + + public RazorpayClient addHeaders(Map headers) { + ApiUtils.addHeaders(headers); + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/razorpay/RazorpayException.java b/src/main/java/com/razorpay/RazorpayException.java index f89c7f45..c9fb8248 100644 --- a/src/main/java/com/razorpay/RazorpayException.java +++ b/src/main/java/com/razorpay/RazorpayException.java @@ -1,21 +1,9 @@ package com.razorpay; -public class RazorpayException extends Exception { - - public RazorpayException(String message) { - super(message); - } - public RazorpayException(String message, Throwable cause) { - super(message, cause); - } - public RazorpayException(Throwable cause) { - super(cause); - } - - public RazorpayException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } +public class RazorpayException extends Exception { + public RazorpayException(String message) { + super(message); + } } From a8fb17ad3cce39112e35412a5ffe793e136f497f Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Sun, 14 Aug 2022 11:57:56 +0530 Subject: [PATCH 3/5] mock basetest class --- src/test/java/com/razorpay/BaseTest.java | 105 ++++------------------- 1 file changed, 17 insertions(+), 88 deletions(-) diff --git a/src/test/java/com/razorpay/BaseTest.java b/src/test/java/com/razorpay/BaseTest.java index 926364c8..419652bd 100644 --- a/src/test/java/com/razorpay/BaseTest.java +++ b/src/test/java/com/razorpay/BaseTest.java @@ -1,104 +1,33 @@ package com.razorpay; -import okhttp3.*; -import okio.Buffer; -import org.apache.commons.lang3.reflect.FieldUtils; -import org.json.JSONObject; -import org.junit.Before; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.Collections; -import java.util.List; +import org.json.JSONException; +import org.json.JSONObject; +import java.io.*; +import java.net.URISyntaxException; +import java.net.URL; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyObject; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class BaseTest { - - private OkHttpClient okHttpClient; - Response mockedResponse; - - static final String TEST_SECRET_KEY = "test"; +public class BaseTest{ - @Before - public void setUp() throws Exception { - - MockitoAnnotations.initMocks(this); - mockGetCall(); - mockURL(Collections.emptyList()); + protected void mockGetRequest(ApiUtils apiUtils, URL url, String request, String response) throws JSONException, IOException, URISyntaxException, RazorpayException { + when(apiUtils.processGetRequest(url.toString(),request,"test")).thenReturn(response); } - - private void mockGetCall() throws IOException, IllegalAccessException { - - okHttpClient = mock(OkHttpClient.class); - mockedResponse = mock(Response.class); - Field clientField =FieldUtils.getDeclaredField(ApiUtils.class,"client",true); - FieldUtils.writeField(clientField,new ApiUtils(),okHttpClient); - - Call call = mock(Call.class); - when(call.execute()).thenReturn(mockedResponse); - when(okHttpClient.newCall(anyObject())).thenReturn(call); + protected void mockPostRequest(ApiUtils apiUtils, URL url, String request, String response) throws JSONException, IOException, URISyntaxException, RazorpayException { + when(apiUtils.processPostRequest(url.toString(),request,"test")).thenReturn(response); } - - protected void mockResponseHTTPCodeFromExternalClient(int code) - { - when(mockedResponse.code()).thenReturn(code); + protected void mockPutRequest(ApiUtils apiUtils, URL url, String request, String response) throws JSONException, IOException, URISyntaxException, RazorpayException { + when(apiUtils.processPutRequest(url.toString(),request,"test")).thenReturn(response); } - protected void mockURL(List urlString) - { - HttpUrl url = mock(HttpUrl.class); - when(url.pathSegments()).thenReturn(urlString); - Request request = mock(Request.class); - when(request.url()).thenReturn(url); - when(mockedResponse.request()).thenReturn(request); + protected void mockDeleteRequest(ApiUtils apiUtils, URL url, String request, String response) throws JSONException, IOException, URISyntaxException, RazorpayException { + when(apiUtils.processDeleteRequest(url.toString(),request,"test")).thenReturn(response); } - protected void mockResponseFromExternalClient(String response) throws IOException { - if(response.equals("[]")){ - ResponseBody rb = mock(ResponseBody.class); - when(rb.string()).thenReturn(response); - when(mockedResponse.body()).thenReturn(rb); - }else{ - JSONObject parse = new JSONObject(response); - ResponseBody rb = mock(ResponseBody.class); - when(rb.string()).thenReturn(parse.toString()); - when(mockedResponse.body()).thenReturn(rb); - } + protected void mockPatchRequest(ApiUtils apiUtils, URL url, String request, String response) throws JSONException, IOException, URISyntaxException, RazorpayException { + when(apiUtils.processPatchRequest(url.toString(),request,"test")).thenReturn(response); } - protected OkHttpClient getOkHttpClient() - { - return okHttpClient; - } - protected String getHost(String url) { - return Constants.SCHEME + "://" + Constants.HOSTNAME + "/" + Constants.VERSION + "/" + url; - } - protected void verifySentRequest(boolean hasBody, String request, String requestPath) { - ArgumentCaptor req = ArgumentCaptor.forClass(Request.class); - Mockito.verify(getOkHttpClient()).newCall(req.capture()); - if(hasBody) { - assertEquals(new JSONObject(request).toString(), new JSONObject(bodyToString(req.getAllValues().get(0))).toString()); - } - assertEquals(requestPath, req.getValue().url().toString()); - } - - private static String bodyToString(final Request request) { - - try { - final Request copy = request.newBuilder().build(); - final Buffer buffer = new Buffer(); - copy.body().writeTo(buffer); - return buffer.readUtf8(); - } catch (final IOException e) { - return "did not work"; - } - } -} +} \ No newline at end of file From 937cb25a8b5bd5290ead4f003d04c5ee0c064c00 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Wed, 24 Aug 2022 13:04:51 +0530 Subject: [PATCH 4/5] added comments & indentation --- src/main/java/com/razorpay/ApiClient.java | 76 +++++++++++++++++++ .../java/com/razorpay/RazorpayClient.java | 33 +++++--- 2 files changed, 100 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/razorpay/ApiClient.java b/src/main/java/com/razorpay/ApiClient.java index 688ee884..f5bfc711 100755 --- a/src/main/java/com/razorpay/ApiClient.java +++ b/src/main/java/com/razorpay/ApiClient.java @@ -40,6 +40,16 @@ class ApiClient { this.apiUtils = apiUtils; } + /** + * Create get request + * @param path + * @param requestObject + * @return + * @throws RazorpayException + * @throws IOException + * @throws URISyntaxException + * @throws JSONException + */ public T get(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { String query = null; @@ -52,6 +62,16 @@ public T get(String path, JSONObject requestObject) throws Ra return processResponse(response,builder.toString()); } + /** + * Create post request + * @param path + * @param requestObject + * @return + * @throws RazorpayException + * @throws IOException + * @throws URISyntaxException + * @throws JSONException + */ public T post(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { URL builder = getBuilder(path,null); String request = requestObject==null ? null : requestObject.toString(); @@ -59,18 +79,49 @@ public T post(String path, JSONObject requestObject) throws R return processResponse(response,builder.toString()); } + /** + * Create put request + * @param path + * @param requestObject + * @return + * @throws RazorpayException + * @throws IOException + * @throws URISyntaxException + * @throws JSONException + */ public T put(String path, JSONObject requestObject) throws RazorpayException, JSONException, IOException, URISyntaxException { URL builder = getBuilder(path,null); String response = apiUtils.processPutRequest(builder.toString(),requestObject.toString(), auth); return processResponse(response,builder.toString()); } + /** + * Create patch request + * @param path + * @param requestObject + * @return + * @throws RazorpayException + * @throws IOException + * @throws URISyntaxException + * @throws JSONException + */ public T patch(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { URL builder = getBuilder(path,null); String response = apiUtils.processPatchRequest(builder.toString(),requestObject.toString(), auth); return processResponse(response,builder.toString()); } + /** + * Create delete request + * @param path + * @param requestObject + * @param + * @return + * @throws RazorpayException + * @throws IOException + * @throws URISyntaxException + * @throws JSONException + */ public T delete(String path, JSONObject requestObject) throws RazorpayException, IOException, URISyntaxException, JSONException { URL builder = getBuilder(path,null); String request = requestObject==null ? null : requestObject.toString(); @@ -197,11 +248,36 @@ private String queryBuilder(JSONObject requestObject) throws JSONException { return query; } + /** + * The API url is built using this method + * @param path + * @param query + * @return + * @throws URISyntaxException + * @throws MalformedURLException + */ public static URL getBuilder(String path,String query) throws URISyntaxException, MalformedURLException { URI uri = new URI(Constants.SCHEME, Constants.HOSTNAME, "/"+Constants.VERSION + "/"+path+"", query,null); return uri.toURL(); } + private void throwException(int statusCode, JSONObject responseJson) throws RazorpayException, JSONException { + if (responseJson.has(ERROR)) { + JSONObject errorResponse = responseJson.getJSONObject(ERROR); + String code = errorResponse.getString(STATUS_CODE); + String description = errorResponse.getString(DESCRIPTION); + throw new RazorpayException(code + ":" + description); + } + throwServerException(statusCode, responseJson.toString()); + } + + private void throwServerException(int statusCode, String responseBody) throws RazorpayException { + StringBuilder sb = new StringBuilder(); + sb.append("Status Code: ").append(statusCode).append("\n"); + sb.append("Server response: ").append(responseBody); + throw new RazorpayException(sb.toString()); + } + private Class getClass(String entity) { try { String CapEntity = entity.substring(0, 1).toUpperCase() + entity.substring(1); diff --git a/src/main/java/com/razorpay/RazorpayClient.java b/src/main/java/com/razorpay/RazorpayClient.java index 581776ba..08911576 100755 --- a/src/main/java/com/razorpay/RazorpayClient.java +++ b/src/main/java/com/razorpay/RazorpayClient.java @@ -29,29 +29,44 @@ public RazorpayClient(String key, String secret) throws RazorpayException, Unsup this(key, secret, false); } + /** + * Initializes Razorpay client instance + * @param key + * @param secret + * @param enableLogging + * @throws RazorpayException + * @throws UnsupportedEncodingException + */ public RazorpayClient(String key, String secret, Boolean enableLogging) throws RazorpayException, UnsupportedEncodingException { byte[] message = (key + ":" + secret).getBytes("UTF-8"); String auth = javax.xml.bind.DatatypeConverter.printBase64Binary(message); ApiUtils apiUtils = new ApiUtils(); - payments = new PaymentClient(auth,apiUtils); - invoices = new InvoiceClient(auth,apiUtils); - customers = new CustomerClient(auth,apiUtils); + cards = new CardClient(auth,apiUtils); - subscriptionRegistrations = new SubscriptionRegistrationClient(auth,apiUtils); - fundAccount = new FundAccountClient(auth,apiUtils); items = new ItemClient(auth,apiUtils); + plans = new PlanClient(auth,apiUtils); orders = new OrderClient(auth,apiUtils); addons = new AddonClient(auth,apiUtils); + qrCode = new QrCodeClient(auth,apiUtils); refunds = new RefundClient(auth,apiUtils); + payments = new PaymentClient(auth,apiUtils); + invoices = new InvoiceClient(auth,apiUtils); + customers = new CustomerClient(auth,apiUtils); transfers = new TransferClient(auth,apiUtils); - subscriptions = new SubscriptionClient(auth,apiUtils); - plans = new PlanClient(auth,apiUtils); settlement = new SettlementClient(auth,apiUtils); - qrCode = new QrCodeClient(auth,apiUtils); + fundAccount = new FundAccountClient(auth,apiUtils); paymentLink = new PaymentLinkClient(auth,apiUtils); + subscriptions = new SubscriptionClient(auth,apiUtils); virtualAccounts = new VirtualAccountClient(auth,apiUtils); - } + subscriptionRegistrations = new SubscriptionRegistrationClient(auth,apiUtils); + } + /** + * Add headers + * ex: X-Razorpay-Account + * @param headers + * @return + */ public RazorpayClient addHeaders(Map headers) { ApiUtils.addHeaders(headers); return this; From f69566173b02e10fdf12b056cb929b5de68b0a19 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Wed, 24 Aug 2022 18:17:19 +0530 Subject: [PATCH 5/5] updated pom and fix security checks --- pom.xml | 28 ++----------------- .../razorpay/TLSSocketConnectionFactory.java | 3 -- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/pom.xml b/pom.xml index f4663fff..78bd2e50 100644 --- a/pom.xml +++ b/pom.xml @@ -1,16 +1,13 @@ 4.0.0 - com.razorpay razorpay-java 1.1.1 jar - razorpay-java Official java bindings for the Razorpay API https://github.com/razorpay/razorpay-java - Razorpay @@ -19,13 +16,11 @@ https://www.razorpay.com - scm:git:git@github.com:razorpay/razorpay-java.git scm:git:git@github.com:razorpay/razorpay-java.git git@github.com:razorpay/razorpay-java.git - MIT License @@ -33,34 +28,22 @@ repo - UTF-8 6 6 - - - - - - - org.json json 20070829 - - - org.apache.commons commons-lang3 3.1 - junit junit @@ -78,9 +61,7 @@ bcprov-jdk15on 1.54 - - ossrh @@ -91,16 +72,13 @@ https://oss.sonatype.org/service/local/repositories/releases/content/ - - src/main/resources true - org.sonatype.plugins @@ -125,7 +103,7 @@ org.apache.maven.plugins maven-source-plugin - 3.0.1 + 2.3 attach-sources @@ -138,7 +116,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.1 + 2.9.1 attach-javadocs @@ -163,7 +141,5 @@ - - \ No newline at end of file diff --git a/src/main/java/com/razorpay/TLSSocketConnectionFactory.java b/src/main/java/com/razorpay/TLSSocketConnectionFactory.java index 9574fd2b..87712d5d 100644 --- a/src/main/java/com/razorpay/TLSSocketConnectionFactory.java +++ b/src/main/java/com/razorpay/TLSSocketConnectionFactory.java @@ -69,9 +69,6 @@ public void handshakeCompleted(HandshakeCompletedEvent event) { // ******************Adding Custom BouncyCastleProvider*********************// @Override public Socket createSocket(Socket socket, final String host, int port, boolean arg3) throws IOException { - if (socket == null) { - socket = new Socket(); - } if (!socket.isConnected()) { socket.connect(new InetSocketAddress(host, port)); }