Java tutorial
/* * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.iot.agent.proxy; import android.content.Context; import android.content.SharedPreferences; import android.preference.Preference; import android.util.Log; import com.android.volley.AuthFailureError; import com.android.volley.DefaultRetryPolicy; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonArrayRequest; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.StringRequest; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import org.wso2.iot.agent.proxy.utils.Constants.HTTP_METHODS; import org.wso2.iot.agent.proxy.beans.EndPointInfo; import org.wso2.iot.agent.proxy.beans.Token; import org.wso2.iot.agent.proxy.interfaces.APIResultCallBack; import org.wso2.iot.agent.proxy.interfaces.TokenCallBack; import org.wso2.iot.agent.proxy.utils.Constants; import org.wso2.iot.agent.proxy.utils.ServerUtilities; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * This class includes the functionality related to invoking APIs and * return API results to the client. */ public class APIController implements TokenCallBack { private static final String TAG = "APIController"; private Token token; private String clientKey, clientSecret; private APIResultCallBack apiResultCallback; private EndPointInfo apiEndPointInfo; private int requestMethod; private boolean isStringRequest = false; public APIController(String clientKey, String clientSecret) { this.clientKey = clientKey; this.clientSecret = clientSecret; if (Constants.DEBUG_ENABLED) { Log.d(TAG, "APIController created."); } } public APIController() { } /** * Invoking an API using retrieved token. * * @param apiEndPointInfo - Server and API end point information. * @param apiResultCallBack - API result callback data. * @param requestCode - Request code to avoid response complications. * @param context - Application context. */ public void invokeAPI(EndPointInfo apiEndPointInfo, APIResultCallBack apiResultCallBack, int requestCode, Context context) { if (Constants.DEBUG_ENABLED) { Log.d(TAG, "invokeAPI called"); } this.apiResultCallback = apiResultCallBack; this.apiEndPointInfo = apiEndPointInfo; if (IdentityProxy.getInstance().getContext() == null) { IdentityProxy.getInstance().setContext(context); } IdentityProxy.getInstance().setRequestCode(requestCode); IdentityProxy.getInstance().requestToken(IdentityProxy.getInstance().getContext(), this, this.clientKey, this.clientSecret); } public void invokeAPI(EndPointInfo apiEndPointInfo, APIResultCallBack apiResultCallBack, int requestCode, Context context, boolean isString) { this.isStringRequest = isString; this.apiResultCallback = apiResultCallBack; this.apiEndPointInfo = apiEndPointInfo; if (IdentityProxy.getInstance().getContext() == null) { IdentityProxy.getInstance().setContext(context); } IdentityProxy.getInstance().setRequestCode(requestCode); IdentityProxy.getInstance().requestToken(IdentityProxy.getInstance().getContext(), this, this.clientKey, this.clientSecret); } @Override public void onReceiveTokenResult(Token token, String status, String message) { if (Constants.REQUEST_SUCCESSFUL.equals(status)) { this.token = token; setRequestMethod(apiEndPointInfo.getHttpMethod()); if (isStringRequest) { sendStringRequest(apiResultCallback, apiEndPointInfo, false); } else { if (apiEndPointInfo.getRequestParamsMap() != null) { sendStringRequest(apiResultCallback, apiEndPointInfo, false); } else if (apiEndPointInfo.getRequestParams() != null) { if (isJSONObject(apiEndPointInfo.getRequestParams())) { sendJsonObjectRequest(apiResultCallback, apiEndPointInfo, false); } else { sendJsonArrayRequest(apiResultCallback, apiEndPointInfo, false); } } else if (apiEndPointInfo.isJSONArrayRequest()) { sendJsonArrayRequest(apiResultCallback, apiEndPointInfo, false); } else { sendJsonObjectRequest(apiResultCallback, apiEndPointInfo, false); } } } else if (Constants.ACCESS_FAILURE.equals(status)) { Log.w(TAG, "Bad request: " + message); Map<String, String> responseParams = new HashMap<>(); responseParams.put(Constants.SERVER_RESPONSE_STATUS, status); responseParams.put(Constants.SERVER_RESPONSE_BODY, message); apiResultCallback.onReceiveAPIResult(responseParams, IdentityProxy.getInstance().getRequestCode()); } } private boolean isJSONObject(String data) { Object json; try { json = new JSONTokener(data).nextValue(); return (json instanceof JSONObject); } catch (JSONException e) { Log.e(TAG, "Failed to parse response JSON", e); return false; } } private void setRequestMethod(HTTP_METHODS httpMethod) { switch (httpMethod) { case GET: requestMethod = Request.Method.GET; break; case POST: requestMethod = Request.Method.POST; break; case DELETE: requestMethod = Request.Method.DELETE; break; case PUT: requestMethod = Request.Method.PUT; break; } } /** * Secured network call to contact server and access the API with retrieved token. */ public void securedNetworkCall(final APIResultCallBack callBack, int requestCode, final EndPointInfo apiUtilities, Context context) { if (IdentityProxy.getInstance().getContext() == null) { IdentityProxy.getInstance().setContext(context); } setRequestMethod(apiUtilities.getHttpMethod()); IdentityProxy.getInstance().setRequestCode(requestCode); if (apiUtilities.getRequestParamsMap() != null) { sendStringRequest(callBack, apiUtilities, true); } else if (apiUtilities.getRequestParams() != null) { if (isJSONObject(apiUtilities.getRequestParams())) { sendJsonObjectRequest(callBack, apiUtilities, true); } else { sendJsonArrayRequest(callBack, apiUtilities, true); } } else if (apiUtilities.isJSONArrayRequest()) { sendJsonArrayRequest(callBack, apiUtilities, true); } else { sendJsonObjectRequest(callBack, apiUtilities, true); } } public void sendStringRequest(final APIResultCallBack callBack, final EndPointInfo apiUtilities, final boolean isSecured) { RequestQueue queue = null; try { queue = ServerUtilities.getCertifiedHttpClient(); } catch (IDPTokenManagerException e) { Log.e(TAG, "Failed to retrieve HTTP client", e); } StringRequest request = new StringRequest(requestMethod, apiUtilities.getEndPoint(), new Response.Listener<String>() { @Override public void onResponse(String response) { Log.d(TAG, response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, error.toString()); } }) { @Override protected Response<String> parseNetworkResponse(NetworkResponse response) { String result = new String(response.data); if (Constants.DEBUG_ENABLED) { if (result != null && !result.isEmpty()) { Log.d(TAG, "Result :" + result); } } Map<String, String> responseParams = new HashMap<>(); responseParams.put(Constants.SERVER_RESPONSE_BODY, result); responseParams.put(Constants.SERVER_RESPONSE_STATUS, String.valueOf(response.statusCode)); callBack.onReceiveAPIResult(responseParams, IdentityProxy.getInstance().getRequestCode()); return super.parseNetworkResponse(response); } @Override public byte[] getBody() throws AuthFailureError { return apiUtilities.getRequestParams().getBytes(); } @Override protected Map<String, String> getParams() throws AuthFailureError { return apiUtilities.getRequestParamsMap(); } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "text/plain"); headers.put("Accept", "text/plain"); headers.put("User-Agent", "Mozilla/5.0 ( compatible ), Android"); if (!isSecured) { String accessToken = getToken().getAccessToken(); headers.put("Authorization", "Bearer " + accessToken); } ServerUtilities.addHeaders(headers); return headers; } }; request.setRetryPolicy(new DefaultRetryPolicy(Constants.HttpClient.DEFAULT_TIME_OUT, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); queue.add(request); } private void sendJsonObjectRequest(final APIResultCallBack callBack, final EndPointInfo apiUtilities, final boolean isSecured) { RequestQueue queue = null; try { queue = ServerUtilities.getCertifiedHttpClient(); } catch (IDPTokenManagerException e) { Log.e(TAG, "Failed to retrieve HTTP client", e); } JsonObjectRequest request = null; try { request = new JsonObjectRequest(requestMethod, apiUtilities.getEndPoint(), (apiUtilities.getRequestParams() != null) ? new JSONObject(apiUtilities.getRequestParams()) : null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.d(TAG, response.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, error.toString()); } }) { @Override protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { String result = new String(response.data); if (Constants.DEBUG_ENABLED) { if (result != null && !result.isEmpty()) { Log.d(TAG, "Result :" + result); } } Map<String, String> responseParams = new HashMap<>(); responseParams.put(Constants.SERVER_RESPONSE_BODY, result); responseParams.put(Constants.SERVER_RESPONSE_STATUS, String.valueOf(response.statusCode)); callBack.onReceiveAPIResult(responseParams, IdentityProxy.getInstance().getRequestCode()); return super.parseNetworkResponse(response); } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("Accept", "*/*"); headers.put("User-Agent", "Mozilla/5.0 ( compatible ), Android"); if (!isSecured) { String accessToken = getToken().getAccessToken(); headers.put("Authorization", "Bearer " + accessToken); } ServerUtilities.addHeaders(headers); return headers; } }; } catch (JSONException e) { Log.e(TAG, "Failed to parse request JSON", e); } request.setRetryPolicy(new DefaultRetryPolicy(Constants.HttpClient.DEFAULT_TIME_OUT, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); queue.add(request); } private void sendJsonArrayRequest(final APIResultCallBack callBack, final EndPointInfo apiUtilities, final boolean isSecured) { RequestQueue queue = null; try { queue = ServerUtilities.getCertifiedHttpClient(); } catch (IDPTokenManagerException e) { Log.e(TAG, "Failed to retrieve HTTP client", e); } JsonArrayRequest request = null; try { request = new JsonArrayRequest(requestMethod, apiUtilities.getEndPoint(), (apiUtilities.getRequestParams() != null) ? new JSONArray(apiUtilities.getRequestParams()) : null, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { Log.d(TAG, response.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, error.toString()); } }) { @Override protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) { String result = new String(response.data); if (Constants.DEBUG_ENABLED) { if (result != null && !result.isEmpty()) { Log.d(TAG, "Result :" + result); } } Map<String, String> responseParams = new HashMap<>(); responseParams.put(Constants.SERVER_RESPONSE_BODY, result); responseParams.put(Constants.SERVER_RESPONSE_STATUS, String.valueOf(response.statusCode)); callBack.onReceiveAPIResult(responseParams, IdentityProxy.getInstance().getRequestCode()); return super.parseNetworkResponse(response); } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("Accept", "*/*"); headers.put("User-Agent", "Mozilla/5.0 ( compatible ), Android"); if (!isSecured) { String accessToken = getToken().getAccessToken(); headers.put("Authorization", "Bearer " + accessToken); } ServerUtilities.addHeaders(headers); return headers; } }; } catch (JSONException e) { Log.e(TAG, "Failed to parse request JSON", e); } request.setRetryPolicy(new DefaultRetryPolicy(Constants.HttpClient.DEFAULT_TIME_OUT, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); queue.add(request); } private Token getToken() { if (token == null) { SharedPreferences mainPref = IdentityProxy.getInstance().getContext() .getSharedPreferences(Constants.APPLICATION_PACKAGE, Context.MODE_PRIVATE); String refreshToken = mainPref.getString(Constants.REFRESH_TOKEN, null); String accessToken = mainPref.getString(Constants.ACCESS_TOKEN, null); long expiresOn = mainPref.getLong(Constants.EXPIRE_TIME, 0); token = new Token(); token.setExpiresOn(new Date(expiresOn)); token.setRefreshToken(refreshToken); token.setAccessToken(accessToken); } return token; } }