Skip to content
Snippets Groups Projects
Commit f495281a authored by cramakri's avatar cramakri
Browse files

LMS-1465 Skeleton of an implementation of RPC for DSS.

SVN: 15311
parent d0907a64
No related branches found
No related tags found
No related merge requests found
Showing with 512 additions and 0 deletions
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.rpc.client;
import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
import ch.systemsx.cisd.common.spring.HttpInvokerUtils;
import ch.systemsx.cisd.openbis.dss.rpc.shared.IDataSetDss;
import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
/**
* Implementation of the IDssComponent interface. It is a facade for interacting with openBIS and
* multiple DSS servers.
*
* @author Chandrasekhar Ramakrishnan
*/
public class DssComponent implements IDssComponent
{
final IETLLIMSService service;
AbstractDssComponentState state;
SessionContextDTO sessionOrNull;
/**
* Create a DSS component that connects to the openBIS instance specified by the URL.
* <p>
* The DSS component needs to connect to openBIS to find out which DSS manages a given data set.
* Once it has a connection to openBIS, it can figure out how to connect to DSS servers itself.
*
* @param openBISURL The url to connect to openBIS
*/
public DssComponent(String openBISURL)
{
this(HttpInvokerUtils.createServiceStub(IETLLIMSService.class, openBISURL + "/rmi-etl", 5));
}
/**
* Internal constructor used for testing.
*
* @param service
*/
protected DssComponent(IETLLIMSService service)
{
this.service = service;
this.state = new UnauthenticatedState(service);
}
public void login(String user, String password) throws AuthorizationFailureException
{
// login and transition to the authenticated state
state.login(user, password);
state = new AuthenticatedState(service, state.getSession());
}
public void checkSession() throws InvalidSessionException
{
state.checkSession();
}
public IDataSetDss getDataSet(String code)
{
return state.getDataSet(code);
}
public void logout()
{
// logout and transition to the unauthenticated state
state.logout();
state = new UnauthenticatedState(service);
}
}
/**
* Superclass for component states, which make the state machine of the DSS component explicit.
* <p>
* By default, all methods just throw an exception. Subclasses should override the methods they
* accept.
*
* @author Chandrasekhar Ramakrishnan
*/
abstract class AbstractDssComponentState implements IDssComponent
{
protected final IETLLIMSService service;
AbstractDssComponentState(IETLLIMSService service)
{
this.service = service;
}
public void checkSession() throws InvalidSessionException
{
throw new UserFailureException("Please log in");
}
public IDataSetDss getDataSet(String code)
{
throw new UserFailureException("Please log in");
}
abstract SessionContextDTO getSession();
}
/**
* An object representing an unauthenticated state. Being in this state implies that the user has
* not yet logged in. Only login and logout are allowed in this state.
*
* @author Chandrasekhar Ramakrishnan
*/
class UnauthenticatedState extends AbstractDssComponentState
{
private SessionContextDTO sessionOrNull;
UnauthenticatedState(IETLLIMSService service)
{
super(service);
}
public void login(String user, String password) throws AuthorizationFailureException
{
sessionOrNull = service.tryToAuthenticate(user, password);
if (sessionOrNull == null)
throw new AuthorizationFailureException("Login or Password invalid");
}
public void logout()
{
return;
}
@Override
SessionContextDTO getSession()
{
if (sessionOrNull == null)
throw new UserFailureException("Please log in");
return sessionOrNull;
}
}
class AuthenticatedState extends AbstractDssComponentState
{
final SessionContextDTO session;
/**
* @param service
*/
AuthenticatedState(IETLLIMSService service, SessionContextDTO session)
{
super(service);
this.session = session;
}
@Override
SessionContextDTO getSession()
{
return session;
}
public void login(String user, String password) throws AuthorizationFailureException
{
throw new UserFailureException("Already logged in.");
}
public void logout()
{
service.logout(session.getSessionToken());
}
@Override
public IDataSetDss getDataSet(String code)
{
service.tryGetDataSet(session.getSessionToken(), code);
// Contact openBIS to find out which DSS server manages the data set
// Get an RPC service for the DSS server
// Get a proxy to the data set
// TODO Auto-generated method stub
return null;
}
}
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.rpc.client;
import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
import ch.systemsx.cisd.openbis.dss.rpc.shared.IDataSetDss;
/**
* A component that manages a connection to openBIS and 1 or more data store servers.
* <p>
* The component is a kind of state machine. In the initial state, only login is allowed. After
* login, other operations may be called. Thus clients should follow the following usage pattern:
* <ol>
* <li>login</li>
* <li>...do stuff...</li>
* <li>logout</li>
* </ol>
* <p>
* The IDssComponent itself is designed to be used in a single thread, though it may return objects
* that can be used in multiple threads.
*
* @author Chandrasekhar Ramakrishnan
*/
public interface IDssComponent
{
/**
* Authenticates the <code>user</code> with given <code>password</code>.
*/
public void login(final String user, final String password)
throws AuthorizationFailureException;
/**
* Checks whether the session is alive.
*
* @throws InvalidSessionException If the session is not alive.
*/
public void checkSession() throws InvalidSessionException;
/**
* Get a proxy to the data set designated by the given data set code.
*/
public IDataSetDss getDataSet(String code);
/**
* Logs the current user out.
*/
public void logout();
}
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.rpc.shared;
import java.io.Serializable;
/**
* Represents information about a file stored in DSS.
*
* @author Chandrasekhar Ramakrishnan
*/
public class FileInfoDss implements Serializable
{
private static final long serialVersionUID = 1L;
}
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.rpc.shared;
import java.io.OutputStream;
import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
/**
* The representation of a Data Set managed by a DSS server. It is safe to use instances in multiple
* threads.
*
* @author Chandrasekhar Ramakrishnan
*/
public interface IDataSetDss
{
/**
* List files contained in this data set.
*
* @param startPath The path for the listing. "/" is the root of the hierarchy for this data
* set.
* @param isRecursive If true, the contents of any subdirectories will be listed as well.
*/
public FileInfoDss[] listFiles(String startPath, boolean isRecursive)
throws InvalidSessionException;
/**
* Get a file contained in this data set.
*
* @param path The path of the file to retrieve.
*/
public OutputStream getFile(String path) throws InvalidSessionException;
}
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.rpc.shared;
/**
* The most generic interface for RPC invocations into DSS.
* <p>
* This interface defines a minimal interface presented by DSS and is not useful for clients.
* Clients should use a versioned interface, e.g., IDssServiceRpcV1.
*
* @author Chandrasekhar Ramakrishnan
*/
public interface IDssServiceRpc
{
//
// Protocol versioning
//
/** Returns the version of the server side interface. */
public int getVersion();
/**
* Returns the minimal version that the client needs to have in order to be able to talk to this
* server.
*/
public int getMinClientVersion();
}
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.rpc.shared;
/**
* @author Chandrasekhar Ramakrishnan
*/
public interface IDssServiceRpcV1 extends IDssServiceRpc
{
//
// Protocol versioning
//
/** The version of this service interface. */
public static final int VERSION = 1;
/**
* Get a proxy to the data set object managed by the data store server.
*/
public IDataSetDss getDataSet(String sessionId, String code);
}
/*
* Copyright 2010 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.rpc.client;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.AssertJUnit;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import ch.systemsx.cisd.openbis.dss.rpc.client.DssComponent;
import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
/**
* @author Chandrasekhar Ramakrishnan
*/
public class DssComponentTest extends AssertJUnit
{
private Mockery context;
private IETLLIMSService service;
private DssComponent dssComponent;
private static final String DUMMY_SESSSION_TOKEN = "DummySessionToken";
public DssComponentTest()
{
}
@BeforeMethod
public void setUp()
{
context = new Mockery();
service = context.mock(IETLLIMSService.class);
dssComponent = new DssComponent(service);
}
@Test
public void testLogin()
{
final SessionContextDTO session = getDummySession();
context.checking(new Expectations()
{
{
one(service).tryToAuthenticate("foo", "bar");
will(returnValue(session));
}
});
dssComponent.login("foo", "bar");
}
@Test
public void testGetDataSet()
{
final SessionContextDTO session = getDummySession();
context.checking(new Expectations()
{
{
one(service).tryToAuthenticate("foo", "bar");
will(returnValue(session));
one(service).tryGetDataSet(DUMMY_SESSSION_TOKEN, "DummyDataSetCode");
will(returnValue(new ExternalData()));
}
});
dssComponent.login("foo", "bar");
dssComponent.getDataSet("DummyDataSetCode");
}
private SessionContextDTO getDummySession()
{
final SessionContextDTO session = new SessionContextDTO();
session.setSessionToken(DUMMY_SESSSION_TOKEN);
return session;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment