Skip to content
Snippets Groups Projects
Forked from DM / dm-docs
261 commits behind, 653 commits ahead of the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ServiceConnection.java 20.07 KiB
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;		
	}
    
}