diff --git a/tools/ExperimentSynchronizer/lib/jdatepicker-1.3.4.jar b/tools/ExperimentSynchronizer/lib/jdatepicker-1.3.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..a71625968ac3da67a3ec30b5d9f0e6fb344ca59e Binary files /dev/null and b/tools/ExperimentSynchronizer/lib/jdatepicker-1.3.4.jar differ diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/ExperimentList.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/ExperimentList.java new file mode 100644 index 0000000000000000000000000000000000000000..c65538bd008764f9b2883124cb631d0ab0028309 --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/ExperimentList.java @@ -0,0 +1,324 @@ +package gov.anl.dm.esafsync; + +import gov.anl.dm.esafsync.serviceconn.DaqServiceConnection; +import gov.anl.dm.esafsync.serviceconn.ServiceConnection; +import gov.anl.dm.esafsync.serviceconn.ServiceConnection.ServiceConnectionStatus; +import gov.anl.dm.esafsync.serviceconn.StorageServiceConnection; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.sql.SQLException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JFormattedTextField.AbstractFormatter; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.AbstractTableModel; + +import org.jdatepicker.impl.JDatePanelImpl; +import org.jdatepicker.impl.JDatePickerImpl; +import org.jdatepicker.impl.UtilDateModel; + + +class ExperimentList extends JFrame +{ + private static final long serialVersionUID = 1L; + + public class DateLabelFormatter extends AbstractFormatter { + private static final long serialVersionUID = 1L; + private String datePattern = "MM-dd-yyyy"; + private SimpleDateFormat dateFormatter = new SimpleDateFormat(datePattern); + + @Override + public Object stringToValue(String text) throws ParseException { + return dateFormatter.parseObject(text); + } + + @Override + public String valueToString(Object value) throws ParseException { + if (value != null) { + Calendar cal = (Calendar) value; + return dateFormatter.format(cal.getTime()); + } + return ""; + } + + public String valueToString(Date value) throws ParseException { + if (value != null) { + Date cal = (Date) value; + return dateFormatter.format(cal.getTime()); + } + return ""; + } + + } + + enum Column { + NAME("Experiment name"), + DESCRIPTION("Description"), + START_DATE("Start Date"), + END_DATE("End Date"), + MANAGER("Manager(s)"), + PI("Principal Investigator(s)"), + USER("Users"); + + private final String column; + + private Column(String column) { + this.column = column; + } + + @Override + public String toString() { + return column; + } + } + + enum Role { + MANAGER("Manager"), + PI("Principal Investigator"), + USER("User"); + + private final String role; + + private Role(String role) { + this.role = role; + } + + @Override + public String toString() { + return role; + } + } + + class ExperimentTableModel extends AbstractTableModel { + private static final long serialVersionUID = 1L; + + String dataValues [][]; + + @Override + public int getRowCount() { + return dataValues.length; + } + + @Override + public int getColumnCount() { + return Column.values().length; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + return dataValues[rowIndex][columnIndex]; + } + + public String getColumnName(int col) { + return Column.values()[col].toString(); + } + + public Class getColumnClass(int c) { + return getValueAt(0, c).getClass(); + } + + void setTable(String list) { + List<String[]> expTable = new ArrayList<>(); + String [] rows = list.split("EXP"); + for (int i=0; i<rows.length; i++) { + String [] cells = rows[i].split(","); + boolean goodRow = false; + int j = 0; + for (j = 0; j < cells[0].length(); j++) { + if ( Character.isDigit(cells[0].charAt(j)) ) { + goodRow = true; + break; + } + } + if (!goodRow) { + continue; + } else { + // parse experiment data + String[] experiment = new String[getColumnCount()+1]; + experiment[Column.NAME.ordinal()] = cells[0].substring(j); + experiment[Column.DESCRIPTION.ordinal()] = cells[1]; + experiment[Column.START_DATE.ordinal()] = cells[3]; + experiment[Column.END_DATE.ordinal()] = cells[4]; + experiment[Column.MANAGER.ordinal()] = parseUsers(cells[5]); + experiment[Column.PI.ordinal()] = parseUsers(cells[6]); + int lastIndex = cells[7].indexOf("\""); + experiment[Column.USER.ordinal()] = parseUsers(cells[7].substring(0, lastIndex)); + expTable.add(experiment); + } + } + dataValues = new String [expTable.size()][getColumnCount()]; + for (int i=0; i < expTable.size(); i++) { + for (int j=0; j < getColumnCount(); j++) { + dataValues[i][j] = expTable.get(i)[j]; + } + } + } + + private String parseUsers(String userList) { + if (userList.equals("00000")) { + return ""; + } + String parsedUsers = ""; + String [] users = userList.split(":"); + for (int i=0; i < users.length; i++) { + parsedUsers = parsedUsers + "d" + users[i] + " "; + } + return parsedUsers; + } + } + + StorageServiceConnection sconnection; + private JTable table = null; + private ExperimentTableModel tableModel = null; + private JScrollPane scrollPane; + + ExperimentList(String sector, OracleConnection oconnection, StorageServiceConnection sconnection, DaqServiceConnection dconnection) { + this.sconnection = sconnection; + setTitle("Experiment Import"); + setSize(1000, 500); + setBackground(Color.gray); + + JPanel topPanel = new JPanel(); + topPanel.setBorder(BorderFactory.createLoweredSoftBevelBorder()); + topPanel.setLayout( new BorderLayout() ); + getContentPane().add( topPanel ); + + JPanel entryPanel = new JPanel(new FlowLayout()); + topPanel.add(entryPanel, BorderLayout.NORTH); + + JLabel entryLabel = new JLabel("Enter date range of experiment start date"); + entryPanel.add(entryLabel); + + UtilDateModel startModel = new UtilDateModel(); + Properties p = new Properties(); + p.put("text.today", "Today"); + p.put("text.month", "Month"); + p.put("text.year", "Year"); + JDatePanelImpl startDatePanel = new JDatePanelImpl(startModel, p); + JDatePickerImpl startDatePicker = new JDatePickerImpl(startDatePanel, new DateLabelFormatter()); + entryPanel.add(startDatePicker); + + UtilDateModel endModel = new UtilDateModel(); + JDatePanelImpl endDatePanel = new JDatePanelImpl(endModel, p); + JDatePickerImpl endDatePicker = new JDatePickerImpl(endDatePanel, new DateLabelFormatter()); + entryPanel.add(endDatePicker); + + JButton submitDatesBtn = new JButton("click to get experiments list"); + entryPanel.add(submitDatesBtn); + + JPanel selectPanel = new JPanel(new FlowLayout()); + topPanel.add(selectPanel, BorderLayout.SOUTH); + + JButton submitSelectionBtn = new JButton("select experiments and click the button to import"); + selectPanel.add(submitSelectionBtn); + submitSelectionBtn.setVisible(false); + + JButton submitSelectionStartExpBtn = new JButton("select experiments and click the button to import and start"); + selectPanel.add(submitSelectionStartExpBtn); + submitSelectionStartExpBtn.setVisible(false); + + submitDatesBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + try { + entryLabel.setVisible(true); + submitDatesBtn.setVisible(true); + submitSelectionBtn.setVisible(true); + submitSelectionStartExpBtn.setVisible(true); + + DateLabelFormatter df = new DateLabelFormatter(); + Date startSelectedDate = (Date) startDatePicker.getModel().getValue(); + String start = df.valueToString(startSelectedDate); + Date endSelectedDate = (Date) endDatePicker.getModel().getValue(); + String end = df.valueToString(endSelectedDate); + String list = oconnection.getExperiments(sector, start, end); + if (table == null) { + tableModel = new ExperimentTableModel(); + tableModel.setTable(list); + table = new JTable(tableModel); + scrollPane = new JScrollPane( table ); + topPanel.add( scrollPane, BorderLayout.CENTER ); + table.setRowSelectionAllowed( true ); + pack(); + setVisible(true); + table.setVisible(true); + } else { + tableModel.setTable(list); + tableModel.fireTableStructureChanged(); + } + } catch (SQLException | ParseException e1) { + JOptionPane.showMessageDialog(null, e1.getMessage()); + } + } + }); + + submitSelectionBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + int[] selection = table.getSelectedRows(); + for (int i = 0; i < selection.length; i++) { + String experimentName = (String)table.getModel().getValueAt(selection[i], Column.NAME.ordinal()); + String description = (String)table.getModel().getValueAt(selection[i], Column.DESCRIPTION.ordinal()); + if (sconnection.addExperiment(experimentName, description) != ServiceConnection.ServiceConnectionStatus.SUCCESS) { + continue; + } + addRole((String)table.getModel().getValueAt(selection[i], Column.MANAGER.ordinal()), experimentName, Role.MANAGER); +// addRole((String)table.getModel().getValueAt(selection[i], Column.PI.ordinal()), experimentName, Role.PI); + addRole((String)table.getModel().getValueAt(selection[i], Column.USER.ordinal()), experimentName, Role.USER); + } + table.clearSelection(); + } + }); + + submitSelectionStartExpBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + int[] selection = table.getSelectedRows(); + if ((selection.length > 0) && (dconnection.init() == ServiceConnectionStatus.SUCCESS) && (dconnection.login() == ServiceConnectionStatus.SUCCESS)) { + for (int i = 0; i < selection.length; i++) { + String experimentName = (String)table.getModel().getValueAt(selection[i], Column.NAME.ordinal()); + String description = (String)table.getModel().getValueAt(selection[i], Column.DESCRIPTION.ordinal()); + if (sconnection.addExperiment(experimentName, description) != ServiceConnection.ServiceConnectionStatus.SUCCESS) { + continue; + } + addRole((String)table.getModel().getValueAt(selection[i], Column.MANAGER.ordinal()), experimentName, Role.MANAGER); + // addRole((String)table.getModel().getValueAt(selection[i], Column.PI.ordinal()), experimentName, Role.PI); + addRole((String)table.getModel().getValueAt(selection[i], Column.USER.ordinal()), experimentName, Role.USER); + if (sconnection.startExperiment(experimentName) == ServiceConnection.ServiceConnectionStatus.SUCCESS) { + dconnection.startDaq(experimentName, experimentName); + } + } + } + table.clearSelection(); + } + }); + } + + private void addRole(String userList, String experimentName, Role role) { + if ((userList == null) || userList.isEmpty()) { + return; + } + String [] users = userList.split(" "); + for (int i = 0; i < users.length; i++) { + sconnection.addExperimentUser(users[i], experimentName, role.toString()); + } + } + +} diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/Gui.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/Gui.java new file mode 100644 index 0000000000000000000000000000000000000000..acfa7e431ee51bf0c3a261c5e625e14bb37ab5fe --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/Gui.java @@ -0,0 +1,92 @@ +package gov.anl.dm.esafsync; + +import gov.anl.dm.esafsync.serviceconn.DaqServiceConnection; +import gov.anl.dm.esafsync.serviceconn.ServiceConnection; +import gov.anl.dm.esafsync.serviceconn.StorageServiceConnection; + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.sql.SQLException; +import java.util.Properties; + +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +class Gui +{ + public static void main(String arg[]) + { + + String configFile = arg[0]; + Properties configProperties = new Properties(); + setConfig(configFile, configProperties); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + new Gui(configProperties); + } + }); + } + + private Gui(Properties configProperties) { + OracleConnection oconnection = new OracleConnection(); + try { + oconnection.connect(configProperties); + } catch (SQLException e1) { + JOptionPane.showMessageDialog(null, e1.getMessage()); + System.exit(0); + } + StorageServiceConnection sconnection = new StorageServiceConnection(); + if (sconnection.init(configProperties.getProperty("dm.storageServ.connection")) != ServiceConnection.ServiceConnectionStatus.SUCCESS) { + System.exit(0); + } + DaqServiceConnection dconnection = new DaqServiceConnection(configProperties.getProperty("dm.daqServ.connection")); + try + { + LoginWindow frame = new LoginWindow(sconnection, oconnection, dconnection); + frame.setSize(300,200); + frame.setVisible(true); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + if (sconnection != null) { + sconnection.close(); + } + if (oconnection != null) { + oconnection.close(); + } + System.exit(0); + } + }); + } + catch(Exception e) { + JOptionPane.showMessageDialog(null, e.getMessage()); + } + } + + private static void setConfig(String config, Properties configProperties) { + InputStream configInputStream = null; + try { + configInputStream = new FileInputStream(config); + } catch (Exception e) { + JOptionPane.showMessageDialog(null, e.getMessage()); + System.exit(0); + } + + if (configInputStream != null) { + try { + configProperties.load(configInputStream); + } catch (IOException e1) { + JOptionPane.showMessageDialog(null, e1.getMessage()); + System.exit(0); + } + } else { + System.exit(-1); + } + } +} \ No newline at end of file diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/LoginWindow.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/LoginWindow.java new file mode 100644 index 0000000000000000000000000000000000000000..0dd93486d977e05667436fa230971ac094b8f69b --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/LoginWindow.java @@ -0,0 +1,102 @@ +package gov.anl.dm.esafsync; + + + +import gov.anl.dm.esafsync.serviceconn.DaqServiceConnection; +import gov.anl.dm.esafsync.serviceconn.ServiceConnection; +import gov.anl.dm.esafsync.serviceconn.StorageServiceConnection; + +import javax.swing.*; + +import java.awt.event.*; + +public final class LoginWindow extends JFrame { + private static final long serialVersionUID = 1L; + + StorageServiceConnection sconnection; + OracleConnection oconnection; + JPanel panel; + + LoginWindow(StorageServiceConnection sconnection, OracleConnection oconnection, DaqServiceConnection dconnection) { + this.sconnection = sconnection; + this.oconnection = oconnection; + + setTitle("Experiment Import Login"); + JPanel panel = new JPanel(); + add(panel); + panel.setLayout(null); + + JLabel userLabel = new JLabel("User"); + userLabel.setBounds(10, 10, 80, 25); + panel.add(userLabel); + + JTextField userText = new JTextField(20); + userText.setBounds(100, 10, 160, 25); + panel.add(userText); + + JLabel passwordLabel = new JLabel("Password"); + passwordLabel.setBounds(10, 40, 80, 25); + panel.add(passwordLabel); + + JPasswordField passwordText = new JPasswordField(20); + passwordText.setBounds(100, 40, 160, 25); + panel.add(passwordText); + + JLabel sectorLabel = new JLabel("Sector"); + sectorLabel.setBounds(10, 70, 80, 25); + panel.add(sectorLabel); + + JTextField sectorText = new JTextField(20); + sectorText.setBounds(100, 70, 160, 25); + panel.add(sectorText); + + JButton submitButton = new JButton("submit"); + submitButton.setBounds(10, 120, 80, 25); + panel.add(submitButton); + + submitButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String user = userText.getText().trim(); + String pass = new String(passwordText.getPassword()); + if ((user == null) || (user.isEmpty()) || (pass == null) || (pass.isEmpty())) { + JOptionPane.showMessageDialog(null,"enter login and password", + "Error",JOptionPane.ERROR_MESSAGE); + } else { + sconnection.setLogin(user, pass); + dconnection.setLogin(user, pass); + int aaResult = sconnection.login(); + switch (aaResult) { + case ServiceConnection.ServiceConnectionStatus.SUCCESS: + setVisible(false); + ExperimentList page=new ExperimentList(sectorText.getText().trim(), oconnection, sconnection, dconnection); + page.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + page.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + sconnection.close(); + oconnection.close(); + System.exit(0); + } + }); + page.setVisible(true); + break; + case ServiceConnection.ServiceConnectionStatus.AUTHORIZATION_ERROR: + userText.setText(""); + passwordText.setText(""); + JOptionPane.showMessageDialog(null,"not authorized user", + "Error",JOptionPane.ERROR_MESSAGE); + break; + case ServiceConnection.ServiceConnectionStatus.AUTHENTICATION_ERROR: + userText.setText(""); + passwordText.setText(""); + JOptionPane.showMessageDialog(null,"Incorrect login or password", + "Error",JOptionPane.ERROR_MESSAGE); + break; + default: + // error message generated from exception + } + } + } + }); + } +} \ No newline at end of file diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/OracleConnection.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/OracleConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..f91bfe76abcf54d13e8d48d7801921965e919629 --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/OracleConnection.java @@ -0,0 +1,50 @@ +package gov.anl.dm.esafsync; + +import java.sql.CallableStatement; +import java.sql.DriverManager; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import java.util.Properties; + +public class OracleConnection { + Connection connection = null; + Statement statement; + + void connect(Properties config) throws SQLException { + DriverManager.registerDriver(new oracle.jdbc.OracleDriver()); + connection = DriverManager.getConnection( + config.getProperty("oracle.database.connection"), + config.getProperty("oracle.database.username"), + config.getProperty("oracle.database.password")); + } + + String getExperiments(String sector, String lower, String upper) throws SQLException { + CallableStatement callableStatement = + connection.prepareCall("{? = call safety.esaf_exp0001.get_exps(?,?,?,?)}"); + + callableStatement.registerOutParameter(1, Types.VARCHAR); + callableStatement.setObject(2, ""); + callableStatement.setString(3, sector); + callableStatement.setString(4, lower); + callableStatement.setString(5, upper); + + callableStatement.execute(); + + return callableStatement.getString(1); + } + + void close() { + try { + if (statement != null) { + statement.close(); + } + if (connection != null) { + connection.close(); + } + } catch (SQLException ex) { +// nothing to do here + } + } +} diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/PsqlConnection.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/PsqlConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..cdfc388953b0f2fdaa508f662127efc5d5ea6199 --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/PsqlConnection.java @@ -0,0 +1,91 @@ +package gov.anl.dm.esafsync; + +import java.sql.DriverManager; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +public class PsqlConnection { + public final class UserInfo { + private final String signature; + private final int id; + + UserInfo(String signature, int id) { + this.signature = signature; + this.id = id; + } + String getSignature() { + return signature; + } + + int getId() { + return id; + } + } + + final int ADMIN_ROLE_ID = 1; + Connection connection = null; + + public void connect(Properties config) throws SQLException, ClassNotFoundException { + Class.forName("org.postgresql.Driver"); + connection = DriverManager.getConnection( + config.getProperty("dm.database.connection"), + config.getProperty("dm.database.username"), + config.getProperty("dm.database.password")); + } + + UserInfo getUserInfo(String user) throws SQLException { + String signature = null; + int id = -1; + Statement statement = connection.createStatement(); + if (statement != null) { + ResultSet results = statement.executeQuery("SELECT * FROM user_info WHERE username = '" + user + "';"); + if (results != null) { + while (results.next()) { + signature = results.getString("password"); + if (signature.length() > 0) { + id = Integer.parseInt(results.getString("id")); + break; + } + } + results.close(); + } + statement.close(); + } + if (id < 0) { + return null; + } else { + return new UserInfo(signature, id); + } + } + + boolean isAuthorized(int id) throws SQLException { + boolean isAuthorized = false; + Statement statement = connection.createStatement(); + if (statement != null) { + ResultSet results = statement.executeQuery("SELECT * FROM user_system_role WHERE user_id = " + id + ";"); + if (results != null) { + while (results.next()) { + int roleId = Integer.parseInt(results.getString("role_type_id")); + if (roleId == ADMIN_ROLE_ID) { + isAuthorized = true; + break; + } + } + results.close(); + } + statement.close(); + } + return isAuthorized; + } + + void close() { + try { + connection.close(); + } catch (SQLException ex) { + // nothing to do here + } + } +} diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/DaqServiceConnection.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/DaqServiceConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..1975ee376acc43d5a9aba4caf6df8287575892c9 --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/DaqServiceConnection.java @@ -0,0 +1,30 @@ +package gov.anl.dm.esafsync.serviceconn; + +import java.util.HashMap; +import java.util.Map; + +public class DaqServiceConnection extends ServiceConnection{ + + class Keyword { + static final String DAQ_EXPERIMENT_NAME = "experimentName"; + static final String DAQ_DATA_DIRECTORY = "dataDirectory"; + } + + private final String url; + + public DaqServiceConnection(String url) { + this.url = url; + } + + public final int init() { + return super.init(url); + } + + public void startDaq(String experimentName, String directory) { + Map<String, String> data = new HashMap<>(); + data.put(Keyword.DAQ_EXPERIMENT_NAME, experimentName); + data.put(Keyword.DAQ_DATA_DIRECTORY, directory); + invokeSessionPostRequest(StorageServUrl.EXPERIMENT, data); + } + +} diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/ServiceConnection.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/ServiceConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..bb6d0d151b30aaae32152c513eb71dc9076f2ac0 --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/ServiceConnection.java @@ -0,0 +1,513 @@ +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.HttpURLConnection; +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.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"; + static final String EXPERIMENT = "/experiments"; + static final String EXPERIMENT_USER = "/usersByExperiment"; + static final String START_EXPERIMENT = "/experiments/start"; + static final String START_DAQ = "/experiments/startDaq"; + } + + 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; + + 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(); + System.out.println("protocol "+ protocol); + if (protocol == null) { + JOptionPane.showMessageDialog(null,"Unsupported service protocol specified in " + serviceUrl, "Error",JOptionPane.ERROR_MESSAGE); + return ServiceConnectionStatus.ERROR; + } + return ServiceConnectionStatus.SUCCESS; + } + + private URL getServiceUrl() { + return serviceUrl; + } + + private int checkHttpResponse(HttpURLConnection 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(HttpURLConnection 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, HttpURLConnection connection) { + String postData = preparePostData(data); + try (DataOutputStream dos = new DataOutputStream(connection.getOutputStream())) { + dos.writeBytes(postData); + dos.flush(); + return ServiceConnectionStatus.SUCCESS; + } catch (IOException ex) { + JOptionPane.showMessageDialog(null, ex.getMessage()); + JOptionPane.showMessageDialog(null, "misconfigured service or closed ", "Error",JOptionPane.ERROR_MESSAGE); + return ServiceConnectionStatus.CONNECTION_ERROR; + } + } + + private static String readHttpResponse(HttpURLConnection 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(HttpURLConnection connection, String sessionCookie) { + if (sessionCookie != null) { + connection.setRequestProperty("Cookie", sessionCookie); + } + } + + private static int setPostRequestHeaders(HttpURLConnection connection, String sessionCookie) { + int resp = setPostRequestHeaders(connection); + if (resp != ServiceConnectionStatus.SUCCESS) { + return resp; + } + setCookieRequestHeader(connection, sessionCookie); + return resp; + } + + private static int setPostRequestHeaders(HttpURLConnection 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); + HttpURLConnection connection = null; + try { + String sessionCookie = session.verifyCookie(); + URL url = new URL(urlString); + connection = (HttpURLConnection) 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(HttpURLConnection connection, String sessionCookie) { + int resp = setPutRequestHeaders(connection); + if ( resp != ServiceConnectionStatus.SUCCESS) { + return resp; + } + setCookieRequestHeader(connection, sessionCookie); + return resp; + } + + private static int setPutRequestHeaders(HttpURLConnection 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); + HttpURLConnection connection = null; + try { + String sessionCookie = session.verifyCookie(); + URL url = new URL(urlString); + connection = (HttpURLConnection) 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(); + } + } + } + + protected String encode(String s) { + byte[] encoded1 = Base64.getEncoder().encode(s.getBytes()); + String encoded2 = Base64.getEncoder().encodeToString(encoded1); + return encoded2; + } + +// private String verifySessionCookie() { +// return session.verifyCookie(); +// } +// +// private static String getResponseHeaders(HttpURLConnection 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); +// HttpURLConnection connection = null; +// try { +// String sessionCookie = session.verifyCookie(); +// URL url = new URL(urlString); +// connection = (HttpURLConnection) 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); +// HttpURLConnection connection = null; +// try { +// URL url = new URL(urlString); +// connection = (HttpURLConnection) 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); +// HttpURLConnection connection = null; +// try { +// String sessionCookie = session.verifyCookie(); +// URL url = new URL(urlString); +// connection = (HttpURLConnection) 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(HttpURLConnection connection, String sessionCookie) { +// setGetRequestHeaders(connection); +// setCookieRequestHeader(connection, sessionCookie); +// } +// +// private static void setGetRequestHeaders(HttpURLConnection connection) { +// try { +// connection.setRequestMethod("GET"); +// } catch (ProtocolException ex) { +// JOptionPane.showMessageDialog(null, ex.getMessage()); +// } +// } +// +// private static void setDeleteRequestHeaders(HttpURLConnection connection, String sessionCookie) { +// setDeleteRequestHeaders(connection); +// setCookieRequestHeader(connection, sessionCookie); +// } +// +// private static void setDeleteRequestHeaders(HttpURLConnection connection) { +// try { +// connection.setRequestMethod("DELETE"); +// } catch (ProtocolException ex) { +// JOptionPane.showMessageDialog(null, ex.getMessage()); +// } +// } +// +// +// private void getData(HttpURLConnection 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); +// System.out.println(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(); + } + + private final int login(String username, String password) { + HttpURLConnection connection = null; + try { + String urlString = getFullRequestUrl(StorageServUrl.LOGIN_REQUEST); + URL url = new URL(urlString); + connection = (HttpURLConnection) 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) { + JOptionPane.showMessageDialog(null, ex.getMessage()); + return ServiceConnectionStatus.ERROR; + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } + + public void close() { + session = null; + } + +} diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/Session.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/Session.java new file mode 100644 index 0000000000000000000000000000000000000000..2b72e2c3c369b5239b5f4fb7b4cff087d4eb3d6a --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/Session.java @@ -0,0 +1,131 @@ +package gov.anl.dm.esafsync.serviceconn; + +import java.io.Serializable; +import java.net.HttpCookie; + +import javax.swing.JOptionPane; + +/** + * CDB session class, used for keeping all session-related information (session + * id, username, role, etc.). + */ +public class Session implements Serializable { + + public enum Role { + + USER("User"), + ADMIN("Administrator"); + + private final String type; + + private Role(String type) { + this.type = type; + } + + @Override + public String toString() { + return type; + } + + public static Role fromString(String type) { + Role role = null; + switch (type) { + case "User": + role = USER; + break; + case "Administrator": + role = ADMIN; + break; + } + return role; + } + } + + private static final long serialVersionUID = 1L; + + private String id = null; + private String username = null; + private String cookie = null; + + private Role role = null; + + public Session() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCookie() { + return cookie; + } + + public void setCookie(String cookie) { + this.cookie = cookie; + } + + public String verifyCookie() { + if (cookie == null) { + JOptionPane.showMessageDialog(null, "Valid session has not been established.", "Info",JOptionPane.INFORMATION_MESSAGE); + } else { + HttpCookie httpCookie = HttpCookie.parse(cookie).get(0); + if (httpCookie.hasExpired()) { + JOptionPane.showMessageDialog(null, "Session has expired.", "Info",JOptionPane.INFORMATION_MESSAGE); + } + } + return cookie; + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public boolean isAdminRole() { + if (role != null) { + return role.equals(Role.ADMIN); + } + return false; + } + + public boolean isUserRole() { + if (role != null) { + return role.equals(Role.USER); + } + return false; + } + + @Override + public String toString() { + String result = "{ "; + String delimiter = ""; + if (username != null) { + result += "username :" + username; + delimiter = "; "; + } + if (id != null) { + result += delimiter + "id : " + id; + delimiter = "; "; + } + if (cookie != null) { + result += delimiter + "cookie : " + cookie; + } + result += " }"; + return result; + } +} diff --git a/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/StorageServiceConnection.java b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/StorageServiceConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..915bae4f6f55d380ed59693aea6222c26eda6e56 --- /dev/null +++ b/tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/StorageServiceConnection.java @@ -0,0 +1,46 @@ +package gov.anl.dm.esafsync.serviceconn; + +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JOptionPane; + +public class StorageServiceConnection extends ServiceConnection{ + + class Keyword { + static final String EXPERIMENT_NAME = "name"; + static final String EXPERIMENT_DESCRIPTION = "description"; + static final String EXPERIMENT_TYPE_ID = "experimentTypeId"; + } + + public int addExperiment(String name, String description) { + Map<String, String> data = new HashMap<>(); + if (name == null) { + JOptionPane.showMessageDialog(null, "The experiment name is null", "Error",JOptionPane.ERROR_MESSAGE); + return ServiceConnection.ServiceConnectionStatus.ERROR; + } else { + data.put(Keyword.EXPERIMENT_NAME, encode(name)); + } + if (description != null) { + data.put(Keyword.EXPERIMENT_DESCRIPTION, encode(description)); + } + data.put(Keyword.EXPERIMENT_TYPE_ID, ESAF_EXPERIMENT_TYPE); + return invokeSessionPostRequest(StorageServUrl.EXPERIMENT, data); + } + + public int addExperimentUser(String userName, String experimentName, String role) { + Map<String, String> data = new HashMap<>(); + return invokeSessionPostRequest(StorageServUrl.EXPERIMENT_USER + "/" + userName + "/" + experimentName + "/" + role, data); + } + + public int startExperiment(String name) { + Map<String, String> data = new HashMap<>(); + if (name == null) { + JOptionPane.showMessageDialog(null, "The experiment name is null", "Error",JOptionPane.ERROR_MESSAGE); + return ServiceConnection.ServiceConnectionStatus.ERROR; + } else { + data.put(Keyword.EXPERIMENT_NAME, encode(name)); + } + return invokeSessionPutRequest(StorageServUrl.START_EXPERIMENT, data); + } +}