package gov.anl.dm.esafsync.serviceconn; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.ConnectException; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.net.URLEncoder; // import java.util.Base64; import java.util.HashMap; import java.util.Map; import javax.xml.bind.DatatypeConverter; import javax.net.ssl.HttpsURLConnection; import javax.swing.JOptionPane; public class ServiceConnection { class DmHttpHeaders { static final String DM_SET_COOKIE_HEADER = "Set-Cookie"; final static String DM_SESSION_ROLE_HTTP_HEADER = "Dm-Session-Role"; final static String DM_STATUS_CODE_HTTP_HEADER = "Dm-Status-Code"; final static String DM_STATUS_MESSAGE_HTTP_HEADER = "Dm-Status-Message"; final static String DM_EXCEPTION_TYPE_HTTP_HEADER = "Dm-Exception-Type"; } class DmHttpStatus { static final int DM_HTTP_OK = 200; static final int DM_HTTP_UNAUTHORIZED = 401; static final int DM_HTTP_INTERNAL_ERROR = 500; } class StorageServUrl { static final String LOGIN_REQUEST = "/login"; } class DmStatus { static final int DM_OK = 0; static final int DM_ERROR = 1; static final int DM_INTERNAL_ERROR = 2; static final int DM_COMMUNICATION_ERROR = 3; static final int DM_CONFIGURATION_ERROR = 4; static final int DM_AUTHORIZATION_ERROR = 5; static final int DM_AUTHENTICATION_ERROR = 6; static final int DM_DB_ERROR = 7; static final int DM_URL_ERROR = 8; static final int DM_TIMEOUT = 9; static final int DM_INVALID_ARGUMENT = 10; static final int DM_INVALID_REQUEST = 11; static final int DM_INVALID_SESSION = 12; static final int DM_COMMAND_FAILED =13; static final int DM_OBJECT_NOT_FOUND = 14; static final int DM_OBJECT_ALREADY_EXISTS = 15; static final int DM_INVALID_OBJECT_STATE = 16; } class Keyword { static final String USERNAME = "username"; static final String PASSWORD = "password"; } public class ServiceConnectionStatus { public static final int SUCCESS = 0; public static final int AUTHENTICATION_ERROR = -2; public static final int AUTHORIZATION_ERROR = -3; public static final int INVALID_OPERATION = -4; public static final int CONNECTION_ERROR = -5; public static final int PROTOCOL_ERROR = -6; public static final int ERROR = -1; } private final class Login { private String username; private String password; private Login(String username, String password) { this.username = username; this.password = password; } private void clear() { this.username = null; this.password = null; } private int login() { int result = ServiceConnection.this.login(username, password); clear(); return result; } } static final String ESAF_EXPERIMENT_TYPE = "1"; protected URL serviceUrl; private Session session = new Session(); private Login login; private boolean initialized = false; public final int init(String serviceUrl) { if (serviceUrl == null) { JOptionPane.showMessageDialog(null,"service url is not specified.", "Error",JOptionPane.ERROR_MESSAGE); return ServiceConnectionStatus.ERROR; } try { this.serviceUrl = new URL(serviceUrl); } catch (MalformedURLException ex) { JOptionPane.showMessageDialog(null,"Malformed service url: " + serviceUrl, "Error",JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(null, ex.getMessage()); return ServiceConnectionStatus.ERROR; } String protocol = this.serviceUrl.getProtocol(); if (protocol == null) { JOptionPane.showMessageDialog(null,"Unsupported service protocol specified in " + serviceUrl, "Error",JOptionPane.ERROR_MESSAGE); return ServiceConnectionStatus.ERROR; } HttpsURLConnection.setDefaultSSLSocketFactory(new NoServerVerificationSSLSocketFactory()); initialized = true; return ServiceConnectionStatus.SUCCESS; } public boolean isInitialized() { return initialized; } public boolean isSessionValid() { return session.isValid(); } private URL getServiceUrl() { return serviceUrl; } private int checkHttpResponse(HttpsURLConnection connection) { int code = 0; String exceptionType = connection.getHeaderField(DmHttpHeaders.DM_EXCEPTION_TYPE_HTTP_HEADER); if (exceptionType != null) { String statusMessage = connection.getHeaderField(DmHttpHeaders.DM_STATUS_MESSAGE_HTTP_HEADER); String statusCode = connection.getHeaderField(DmHttpHeaders.DM_STATUS_CODE_HTTP_HEADER); code = Integer.parseInt(statusCode); JOptionPane.showMessageDialog(null,exceptionType +" "+ code +" "+ statusMessage, "Error",JOptionPane.ERROR_MESSAGE); } switch (code) { case DmStatus.DM_OK : return ServiceConnectionStatus.SUCCESS; case DmStatus.DM_AUTHENTICATION_ERROR: return ServiceConnectionStatus.AUTHENTICATION_ERROR; case DmStatus.DM_AUTHORIZATION_ERROR: return ServiceConnectionStatus.AUTHORIZATION_ERROR; case DmStatus.DM_COMMUNICATION_ERROR: case DmStatus.DM_CONFIGURATION_ERROR: case DmStatus.DM_ERROR: case DmStatus.DM_INVALID_SESSION: case DmStatus.DM_TIMEOUT: case DmStatus.DM_URL_ERROR: return ServiceConnectionStatus.ERROR; default: return ServiceConnectionStatus.INVALID_OPERATION; } } private String getFullRequestUrl(String requestUrl) { String url = serviceUrl + requestUrl; return url; } private static String preparePostData(Map<String, String> data) { try { String postData = ""; String separator = ""; for (String key : data.keySet()) { postData += separator + key + "=" + URLEncoder.encode(data.get(key), "UTF8"); separator = "&"; } return postData; } catch (UnsupportedEncodingException ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); return null; } } private void updateSessionCookie(HttpsURLConnection connection) { String cookie = connection.getHeaderField(DmHttpHeaders.DM_SET_COOKIE_HEADER); if (cookie != null) { session.setCookie(cookie); } String sessionRole = connection.getHeaderField(DmHttpHeaders.DM_SESSION_ROLE_HTTP_HEADER); if (sessionRole != null) { session.setRole(Session.Role.fromString(sessionRole)); } } private static int sendPostData(Map<String, String> data, HttpsURLConnection connection) { String postData = preparePostData(data); try (DataOutputStream dos = new DataOutputStream(connection.getOutputStream())) { dos.writeBytes(postData); dos.flush(); return ServiceConnectionStatus.SUCCESS; } catch (IOException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(null, ex.getMessage()); JOptionPane.showMessageDialog(null, "misconfigured service or closed ", "Error",JOptionPane.ERROR_MESSAGE); return ServiceConnectionStatus.CONNECTION_ERROR; } } private static String readHttpResponse(HttpsURLConnection connection) { try { BufferedReader br = new BufferedReader(new InputStreamReader( (connection.getInputStream()))); StringBuilder sb = new StringBuilder(); String output; while ((output = br.readLine()) != null) { sb.append(output); sb.append('\n'); } return sb.toString(); } catch (IOException ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); return null; } } private static void setCookieRequestHeader(HttpsURLConnection connection, String sessionCookie) { if (sessionCookie != null) { connection.setRequestProperty("Cookie", sessionCookie); } } private static int setPostRequestHeaders(HttpsURLConnection connection, String sessionCookie) { int resp = setPostRequestHeaders(connection); if (resp != ServiceConnectionStatus.SUCCESS) { return resp; } setCookieRequestHeader(connection, sessionCookie); return resp; } private static int setPostRequestHeaders(HttpsURLConnection connection) { try { connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); return ServiceConnectionStatus.SUCCESS; } catch (ProtocolException ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); return ServiceConnectionStatus.PROTOCOL_ERROR; } } protected int invokeSessionPostRequest(String requestUrl, Map<String, String> data) { String urlString = getFullRequestUrl(requestUrl); HttpsURLConnection connection = null; try { String sessionCookie = session.verifyCookie(); URL url = new URL(urlString); connection = (HttpsURLConnection) url.openConnection(); int resp = setPostRequestHeaders(connection, sessionCookie); if ( resp != ServiceConnectionStatus.SUCCESS) { return resp; } resp = sendPostData(data, connection); if ( resp != ServiceConnectionStatus.SUCCESS) { return resp; } updateSessionCookie(connection); resp = checkHttpResponse(connection); readHttpResponse(connection); return resp; } catch (Exception ex) { String errorMsg = "Cannot connect to " + getServiceUrl(); JOptionPane.showMessageDialog(null,errorMsg, "Error",JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(null, ex.getMessage()); return ServiceConnectionStatus.ERROR; } finally { if (connection != null) { connection.disconnect(); } } } private static int setPutRequestHeaders(HttpsURLConnection connection, String sessionCookie) { int resp = setPutRequestHeaders(connection); if ( resp != ServiceConnectionStatus.SUCCESS) { return resp; } setCookieRequestHeader(connection, sessionCookie); return resp; } private static int setPutRequestHeaders(HttpsURLConnection connection) { try { connection.setDoOutput(true); connection.setRequestMethod("PUT"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); return ServiceConnectionStatus.SUCCESS; } catch (ProtocolException ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); return ServiceConnectionStatus.PROTOCOL_ERROR; } } protected int invokeSessionPutRequest(String requestUrl, Map<String, String> data) { String urlString = getFullRequestUrl(requestUrl); HttpsURLConnection connection = null; try { String sessionCookie = session.verifyCookie(); URL url = new URL(urlString); connection = (HttpsURLConnection) url.openConnection(); int resp = setPutRequestHeaders(connection, sessionCookie); if ( resp != ServiceConnectionStatus.SUCCESS) { return resp; } resp = sendPostData(data, connection); if ( resp != ServiceConnectionStatus.SUCCESS) { return resp; } updateSessionCookie(connection); resp = checkHttpResponse(connection); readHttpResponse(connection); return resp; } catch (Exception ex) { String errorMsg = "Cannot connect to " + getServiceUrl(); JOptionPane.showMessageDialog(null,errorMsg, "Error",JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(null, ex.getMessage()); return ServiceConnectionStatus.ERROR; } finally { if (connection != null) { connection.disconnect(); } } } // // this method works with java 8 java.util.Base64 // protected String encode(String s) { // byte[] encoded1 = Base64.getEncoder().encode(s.getBytes()); // String encoded2 = Base64.getEncoder().encodeToString(encoded1); // return encoded2; // } public static String encode(String input) { try { // Input is twice encoded in order to avoid issues like // '+' being interpreted as space if (input == null) { return input; } String s1 = DatatypeConverter.printBase64Binary(input.getBytes()); String s2 = DatatypeConverter.printBase64Binary(s1.getBytes()); return s2; } catch (Exception ex) { ex.printStackTrace(); return null; } } // public static String decode(String input) { // try { // // Input is twice encoded in order to avoid issues like // // '+' being interpreted as space // byte[] ba1 = DatatypeConverter.parseBase64Binary(input); // byte[] ba2 = DatatypeConverter.parseBase64Binary(new String(ba1)); // return new String(ba2); // } catch (Exception ex) { // ex.printStackTrace(); // return null; // } // } // private String verifySessionCookie() { // return session.verifyCookie(); // } // // private static String getResponseHeaders(HttpsURLConnection connection) { // String headerString = ""; // Map<String, List<String>> headerMap = connection.getHeaderFields(); // for (String key : headerMap.keySet()) { // List<String> values = headerMap.get(key); // headerString += key + ": " + values + "\n"; // } // return headerString; // } // // private String invokeSessionGetRequest(String requestUrl) { // String urlString = getFullRequestUrl(requestUrl); // HttpsURLConnection connection = null; // try { // String sessionCookie = session.verifyCookie(); // URL url = new URL(urlString); // connection = (HttpsURLConnection) url.openConnection(); // // setGetRequestHeaders(connection, sessionCookie); // updateSessionCookie(connection); // checkHttpResponse(connection); // return readHttpResponse(connection); // } catch (Exception ex) { // String errorMsg = "Cannot connect to " + getServiceUrl(); // JOptionPane.showMessageDialog(null,errorMsg, "Error",JOptionPane.ERROR_MESSAGE); // JOptionPane.showMessageDialog(null, ex.getMessage()); // return null; // } finally { // if (connection != null) { // connection.disconnect(); // } // } // } // // private String invokeGetRequest(String requestUrl) { // String urlString = getFullRequestUrl(requestUrl); // HttpsURLConnection connection = null; // try { // URL url = new URL(urlString); // connection = (HttpsURLConnection) url.openConnection(); // updateSessionCookie(connection); // checkHttpResponse(connection); // return readHttpResponse(connection); // } catch (Exception ex) { // String errorMsg = "Cannot connect to " + getServiceUrl(); // JOptionPane.showMessageDialog(null,errorMsg, "Error",JOptionPane.ERROR_MESSAGE); // JOptionPane.showMessageDialog(null, ex.getMessage()); // return null; // } finally { // if (connection != null) { // connection.disconnect(); // } // } // } // // private String invokeSessionDeleteRequest(String requestUrl) { // String urlString = getFullRequestUrl(requestUrl); // HttpsURLConnection connection = null; // try { // String sessionCookie = session.verifyCookie(); // URL url = new URL(urlString); // connection = (HttpsURLConnection) url.openConnection(); // // setDeleteRequestHeaders(connection, sessionCookie); // updateSessionCookie(connection); // checkHttpResponse(connection); // return readHttpResponse(connection); // } catch (Exception ex) { // String errorMsg = "Cannot connect to " + getServiceUrl(); // JOptionPane.showMessageDialog(null,errorMsg, "Error",JOptionPane.ERROR_MESSAGE); // JOptionPane.showMessageDialog(null, ex.getMessage()); // return null; // } finally { // if (connection != null) { // connection.disconnect(); // } // } // } // // private static void setGetRequestHeaders(HttpsURLConnection connection, String sessionCookie) { // setGetRequestHeaders(connection); // setCookieRequestHeader(connection, sessionCookie); // } // // private static void setGetRequestHeaders(HttpsURLConnection connection) { // try { // connection.setRequestMethod("GET"); // } catch (ProtocolException ex) { // JOptionPane.showMessageDialog(null, ex.getMessage()); // } // } // // private static void setDeleteRequestHeaders(HttpsURLConnection connection, String sessionCookie) { // setDeleteRequestHeaders(connection); // setCookieRequestHeader(connection, sessionCookie); // } // // private static void setDeleteRequestHeaders(HttpsURLConnection connection) { // try { // connection.setRequestMethod("DELETE"); // } catch (ProtocolException ex) { // JOptionPane.showMessageDialog(null, ex.getMessage()); // } // } // // // private void getData(HttpsURLConnection connection) { // BufferedReader in; // try { // in = new BufferedReader( // new InputStreamReader(connection.getInputStream())); // String inputLine; // StringBuffer response = new StringBuffer(); // // while ((inputLine = in.readLine()) != null) { // response.append(inputLine); // } // } catch (IOException e) { // JOptionPane.showMessageDialog(null, e.getMessage()); // } // } public final void setLogin(String username, String password) { this.login = new Login(username, password); } public final int login() { return login.login(); } public final int login(String username, String password) { HttpsURLConnection connection = null; try { String urlString = getFullRequestUrl(StorageServUrl.LOGIN_REQUEST); URL url = new URL(urlString); connection = (HttpsURLConnection) url.openConnection(); setPostRequestHeaders(connection); HashMap<String, String> loginData = new HashMap<>(); loginData.put(Keyword.USERNAME, username); loginData.put(Keyword.PASSWORD, password); int resp = sendPostData(loginData, connection); if (resp != ServiceConnectionStatus.SUCCESS) { return resp; } resp = checkHttpResponse(connection); if (resp != ServiceConnectionStatus.SUCCESS) { return resp; } session.setUsername(username); // session.setId(sessionId); updateSessionCookie(connection); return ServiceConnectionStatus.SUCCESS; } catch (ConnectException ex) { String errorMsg = "Cannot connect to " + getServiceUrl(); JOptionPane.showMessageDialog(null,errorMsg, "Error",JOptionPane.ERROR_MESSAGE); return ServiceConnectionStatus.ERROR; } catch (Exception ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(null, ex.getMessage()); return ServiceConnectionStatus.ERROR; } finally { if (connection != null) { connection.disconnect(); } } } public void close() { session = null; } }