/* ############################################################################ ## ## Copyright (C) 2006-2009 University of Utah. All rights reserved. ## ## This file is part of DeepPeep. ## ## This file may be used under the terms of the GNU General Public ## License version 2.0 as published by the Free Software Foundation ## and appearing in the file LICENSE.GPL included in the packaging of ## this file. Please review the following to ensure GNU General Public ## Licensing requirements will be met: ## http://www.opensource.org/licenses/gpl-license.php ## ## If you are unsure which license is appropriate for your use (for ## instance, you are interested in developing a commercial derivative ## of DeepPeep), please contact us at deeppeep@sci.utah.edu. ## ## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ## ############################################################################ */ package focusedCrawler.util.storage.socket; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.Enumeration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import focusedCrawler.util.CommunicationException; import focusedCrawler.util.DataNotFoundException; import focusedCrawler.util.storage.Storage; import focusedCrawler.util.storage.StorageException; public class StorageRemoteAdapter implements Storage { public static final Logger logger = LoggerFactory.getLogger(StorageRemoteAdapter.class); private String remoteHost; private int remotePort; public StorageRemoteAdapter(String remoteHost, int remotePort) { this.remoteHost = remoteHost; this.remotePort = remotePort; } class RemoteChannel { Socket socket; DataInputStream in; DataOutputStream out; ByteArrayOutputStream bout; byte[] buffer; } private RemoteChannel getSocket() throws IOException { // connect to server RemoteChannel rc = new RemoteChannel(); rc.socket = new Socket(remoteHost, remotePort); rc.in = new DataInputStream(new BufferedInputStream(rc.socket.getInputStream())); rc.out = new DataOutputStream(new BufferedOutputStream(rc.socket.getOutputStream())); rc.bout = new ByteArrayOutputStream(); return rc; } private void serializeParamObject(RemoteChannel rc, Object obj) throws IOException { // convert to byte array rc.bout.reset(); ObjectOutputStream oout = new ObjectOutputStream(rc.bout); oout.writeObject(obj); oout.flush(); } private void sendRequestObject(RemoteChannel rc, int method) throws IOException { // send data throw the socket rc.out.writeByte(method); rc.out.writeInt(rc.bout.size()); rc.bout.writeTo(rc.out); rc.out.flush(); } private void readResultData(RemoteChannel rc) throws IOException { // read the result object int resultSize = rc.in.readInt(); rc.buffer = new byte[resultSize]; rc.in.readFully(rc.buffer); } private Object buildResultObject(RemoteChannel rc) throws IOException, ClassNotFoundException { // mount the serialized object ByteArrayInputStream bin = new ByteArrayInputStream(rc.buffer); ObjectInputStream oin = new ObjectInputStream(bin); Object result = oin.readObject(); oin.close(); return result; } private void releaseSocket(RemoteChannel rc) throws IOException { // close connection rc.socket.close(); } private Object defaultMethod(int method_id, Object obj) throws StorageException, DataNotFoundException, CommunicationException { long t1=System.currentTimeMillis(); long t2=0, t3=0, t4=0, t5=0, t6=0, t7=0; try { logger.debug("adapter"+remoteHost+"_"+remotePort, "method["+method_id+"] call_method", Thread.currentThread().getName()); Object response=null; RemoteChannel socket = getSocket(); t2 = System.currentTimeMillis(); try { serializeParamObject(socket, obj); t3 = System.currentTimeMillis(); sendRequestObject(socket, method_id); t4 = System.currentTimeMillis(); int responseCode = socket.in.read(); t5 = System.currentTimeMillis(); readResultData(socket); t5 = System.currentTimeMillis(); response = buildResultObject(socket); t6 = System.currentTimeMillis(); switch(responseCode) { case CommunicationConstants.RETURN_OK: return response; case CommunicationConstants.RETURN_STORAGE_EXCEPTION: throw new StorageException("remote error: " + response); case CommunicationConstants.RETURN_DATA_NOT_FOUND: throw new DataNotFoundException(false, "remote error " + response); default: throw new CommunicationException("protocol error " + response); } } finally { releaseSocket(socket); t7 = System.currentTimeMillis(); } } catch(ClassNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } catch(IOException e) { throw new CommunicationException(e.getMessage(), e); } finally { long tt=System.currentTimeMillis()-t1; t7-=t6; t6-=t5; t5-=t4; t4-=t3; t3-=t2; t2-=t1; logger.debug("StorageRemoteAdapter_"+remoteHost+"_"+remotePort, "method["+method_id+"] tempo="+tt, "t2="+t2+", t3="+t3+", t4="+t4+", t5="+t5+", t6="+t6+", t7="+t7+" "+Thread.currentThread().getName()); } } public Object insert(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_INSERT, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object[] insertArray(Object[] objs) throws StorageException,CommunicationException { try { return (Object[]) defaultMethod(CommunicationConstants.METHOD_INSERT_ARRAY, objs); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object select(Object obj) throws StorageException,DataNotFoundException,CommunicationException { return defaultMethod(CommunicationConstants.METHOD_SELECT, obj); } public Object[] selectArray(Object[] objs) throws StorageException,DataNotFoundException,CommunicationException { return (Object[]) defaultMethod(CommunicationConstants.METHOD_SELECT_ARRAY, objs); } public Enumeration<?> selectEnumeration(Object obj) throws StorageException,DataNotFoundException,CommunicationException { return (Enumeration<?>) defaultMethod(CommunicationConstants.METHOD_SELECT_ENUMERATION, obj); } public Object update(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_UPDATE, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object[] updateArray(Object[] objs) throws StorageException,CommunicationException { try { return (Object[]) defaultMethod(CommunicationConstants.METHOD_UPDATE_ARRAY, objs); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object remove(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_REMOVE, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object[] removeArray(Object[] objs) throws StorageException,CommunicationException { try { return (Object[]) defaultMethod(CommunicationConstants.METHOD_REMOVE_ARRAY, objs); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object addResource(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_ADD_RESOURCE, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object[] addResourceArray(Object[] objs) throws StorageException,CommunicationException { try { return (Object[]) defaultMethod(CommunicationConstants.METHOD_ADD_RESOURCE_ARRAY, objs); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object removeResource(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_REMOVE_RESOURCE, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object[] removeResourceArray(Object[] objs) throws StorageException,CommunicationException { try { return (Object[]) defaultMethod(CommunicationConstants.METHOD_REMOVE_RESOURCE_ARRAY, objs); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object commit(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_COMMIT, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object rollback(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_ROLLBACK, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object finalize(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_FINALIZE, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } public Object ping(Object obj) throws StorageException,CommunicationException { try { return defaultMethod(CommunicationConstants.METHOD_PING, obj); } catch(DataNotFoundException e) { throw new CommunicationException(e.getMessage(), e); } } }