From 57e40cabfe3ca78fbcaaf6bfa6385acf631977f5 Mon Sep 17 00:00:00 2001
From: "Barbara B. Frosik" <bfrosik@aps.anl.gov>
Date: Wed, 5 Aug 2015 22:29:51 +0000
Subject: [PATCH] added source

---
 .../lib/jdatepicker-1.3.4.jar                 | Bin 0 -> 42949 bytes
 .../gov/anl/dm/esafsync/ExperimentList.java   | 324 +++++++++++
 .../src/gov/anl/dm/esafsync/Gui.java          |  92 ++++
 .../src/gov/anl/dm/esafsync/LoginWindow.java  | 102 ++++
 .../gov/anl/dm/esafsync/OracleConnection.java |  50 ++
 .../gov/anl/dm/esafsync/PsqlConnection.java   |  91 ++++
 .../serviceconn/DaqServiceConnection.java     |  30 +
 .../serviceconn/ServiceConnection.java        | 513 ++++++++++++++++++
 .../anl/dm/esafsync/serviceconn/Session.java  | 131 +++++
 .../serviceconn/StorageServiceConnection.java |  46 ++
 10 files changed, 1379 insertions(+)
 create mode 100644 tools/ExperimentSynchronizer/lib/jdatepicker-1.3.4.jar
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/ExperimentList.java
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/Gui.java
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/LoginWindow.java
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/OracleConnection.java
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/PsqlConnection.java
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/DaqServiceConnection.java
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/ServiceConnection.java
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/Session.java
 create mode 100644 tools/ExperimentSynchronizer/src/gov/anl/dm/esafsync/serviceconn/StorageServiceConnection.java

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
GIT binary patch
literal 42949
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

literal 0
HcmV?d00001

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 00000000..c65538bd
--- /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 00000000..acfa7e43
--- /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 00000000..0dd93486
--- /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 00000000..f91bfe76
--- /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 00000000..cdfc3889
--- /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 00000000..1975ee37
--- /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 00000000..bb6d0d15
--- /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 00000000..2b72e2c3
--- /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 00000000..915bae4f
--- /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);
+    }
+}
-- 
GitLab