From: Aron Roberts Date: Wed, 1 Jun 2011 23:12:52 +0000 (+0000) Subject: CSPACE-4052: Minimally updated the ID service to remove hard-coded dependencies on... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=8e43c16312848de2497df9abedf59d48d58c263c;p=tmp%2Fjakarta-migration.git CSPACE-4052: Minimally updated the ID service to remove hard-coded dependencies on MySQL and specific database connection properties, to help facilitate services layer migration to PostgreSQL. Updated client and proxy classes, and client tests, to cover basic CRD+L of ID generators, plus generation of new IDs. --- diff --git a/services/id/client/pom.xml b/services/id/client/pom.xml index 496bfb2f5..43f1b46fb 100644 --- a/services/id/client/pom.xml +++ b/services/id/client/pom.xml @@ -14,47 +14,17 @@ services.id.client - - - org.slf4j - slf4j-api - test - - - org.slf4j - slf4j-log4j12 - test - - org.collectionspace.services org.collectionspace.services.client ${project.version} - - - org.testng - testng - 5.6 - - - org.jboss.resteasy - resteasy-jaxrs - - - - tjws - webserver - - - - org.jboss.resteasy - resteasy-jaxb-provider - - - org.jboss.resteasy - resteasy-multipart-provider + org.collectionspace.services + org.collectionspace.services.id.service + 1.8-SNAPSHOT + test + jar diff --git a/services/id/client/src/main/java/org/collectionspace/services/client/IdClient.java b/services/id/client/src/main/java/org/collectionspace/services/client/IdClient.java index e04809c85..fc1f5ebd4 100644 --- a/services/id/client/src/main/java/org/collectionspace/services/client/IdClient.java +++ b/services/id/client/src/main/java/org/collectionspace/services/client/IdClient.java @@ -1,11 +1,13 @@ package org.collectionspace.services.client; +import javax.ws.rs.core.Response; import org.jboss.resteasy.client.ClientResponse; /** - * An AcquisitionClient. - - * @version $Revision:$ + * IDClient. + * + * $LastChangedRevision: $ + * $LastChangedDate: $ */ public class IdClient extends AbstractServiceClientImpl { @@ -13,31 +15,44 @@ public class IdClient extends AbstractServiceClientImpl { * @see org.collectionspace.services.client.BaseServiceClient#getServicePathComponent() */ @Override - public String getServicePathComponent() { + public String getServicePathComponent() { return "idgenerators"; } - @Override - public String getServiceName() { - return null; //FIXME: REM - See http://issues.collectionspace.org/browse/CSPACE-3497 - } + @Override + public String getServiceName() { + return null; //FIXME: REM - See http://issues.collectionspace.org/browse/CSPACE-3497 + } - @Override - public Class getProxyClass() { - return IdProxy.class; - } + @Override + public Class getProxyClass() { + return IdProxy.class; + } - /* + /* * Proxied service calls */ - public ClientResponse readList() { - return getProxy().readList(); + // Operations on ID Generators + + public ClientResponse create(String xmlPayload) { + return getProxy().create(xmlPayload); } public ClientResponse read(String csid) { return getProxy().read(csid); } + + public ClientResponse readList() { + return getProxy().readList(); + } + + @Override + public ClientResponse delete(String csid) { + return getProxy().delete(csid); + } + + // Operations on IDs public ClientResponse createId(String csid) { return getProxy().createId(csid); diff --git a/services/id/client/src/main/java/org/collectionspace/services/client/IdProxy.java b/services/id/client/src/main/java/org/collectionspace/services/client/IdProxy.java index b74014732..062c41348 100644 --- a/services/id/client/src/main/java/org/collectionspace/services/client/IdProxy.java +++ b/services/id/client/src/main/java/org/collectionspace/services/client/IdProxy.java @@ -3,29 +3,54 @@ package org.collectionspace.services.client; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; +import javax.ws.rs.DELETE; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; import org.jboss.resteasy.client.ClientResponse; +/** + * IDProxy. + * + * $LastChangedRevision: $ + * $LastChangedDate: $ + */ + @Path("/idgenerators/") -@Produces({"application/xml"}) -@Consumes({"text/plain"}) +@Produces({"text/plain"}) public interface IdProxy extends CollectionSpaceProxy { - + + // Operations on ID Generators + + //(C)reate ID generator + @POST + @Consumes({"application/xml"}) + @Produces({"*/*"}) + ClientResponse create(String xmlPayload); + + //(R)ead ID Generator + @GET + @Path("/{csid}") + @Produces({"application/xml"}) + ClientResponse read(@PathParam("csid") String csid); + + // Read (L)ist of ID Generators @GET @Produces({"application/xml"}) ClientResponse readList(); - - //(C)reate + + //(D)elete ID Generator + @DELETE + @Path("/{csid}") + @Override + ClientResponse delete(@PathParam("csid") String csid); + + // Operations on IDs + + //(C)reate ID @POST @Path("/{csid}/ids") - @Produces({"text/plain"}) ClientResponse createId(@PathParam("csid") String csid); - - //(R)ead - @GET - @Path("/{csid}") - @Produces({"application/xml"}) - ClientResponse read(@PathParam("csid") String csid); + } diff --git a/services/id/client/src/test/java/org/collectionspace/services/client/test/IdServiceTest.java b/services/id/client/src/test/java/org/collectionspace/services/client/test/IdServiceTest.java index c3767df17..d91dce6a7 100644 --- a/services/id/client/src/test/java/org/collectionspace/services/client/test/IdServiceTest.java +++ b/services/id/client/src/test/java/org/collectionspace/services/client/test/IdServiceTest.java @@ -22,12 +22,19 @@ */ package org.collectionspace.services.client.test; +import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.collectionspace.services.client.CollectionSpaceClient; import org.collectionspace.services.client.IdClient; +import org.collectionspace.services.common.document.BadRequestException; +import org.collectionspace.services.common.document.DocumentNotFoundException; +import org.collectionspace.services.id.IDGeneratorSerializer; +import org.collectionspace.services.id.NumericIDGeneratorPart; +import org.collectionspace.services.id.SettableIDGenerator; +import org.collectionspace.services.id.StringIDGeneratorPart; import org.collectionspace.services.jaxb.AbstractCommonList; import org.jboss.resteasy.client.ClientResponse; @@ -52,7 +59,7 @@ public class IdServiceTest extends BaseServiceTest { private final Logger logger = LoggerFactory.getLogger(CLASS_NAME); String knownResourceId = ""; - + private List allResourceIdsCreated = new ArrayList(); /* (non-Javadoc) * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance() @@ -77,12 +84,54 @@ public class IdServiceTest extends BaseServiceTest { // --------------------------------------------------------------- // Success outcomes + + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class) + public void create(String testName) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + }; + + // Perform setup. + testSetup(STATUS_CREATED, ServiceRequestType.CREATE); + + // Submit the request to the service and store the response. + IdClient client = new IdClient(); + + String xmlPayload = getSampleSerializedIdGenerator(); + logger.debug("payload=\n" + xmlPayload); + ClientResponse res = client.create(xmlPayload); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + String newID = extractId(res); + + // Store the ID returned from the first resource created + // for additional tests below. + if (knownResourceId.isEmpty()){ + knownResourceId = newID; + if (logger.isDebugEnabled()) { + logger.debug(testName + ": knownResourceId=" + knownResourceId); + } + } + + // Store the IDs from every resource created by tests, + // so they can be deleted after tests have been run. + allResourceIdsCreated.add(newID); + + } - // Uncomment when getIDGeneratorCSID() no longer returns a hard-coded value. -/* @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, - dependsOnMethods = {"readList", "read"}) + dependsOnMethods = {"create"}) public void createId(String testName) throws Exception { if (logger.isDebugEnabled()) { @@ -112,14 +161,28 @@ public class IdServiceTest extends BaseServiceTest { invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); - String entity = res.getEntity(); - Assert.assertNotNull(entity); + String generatedId = res.getEntity(); + Assert.assertNotNull(generatedId); + Assert.assertFalse(generatedId.isEmpty()); if (logger.isDebugEnabled()) { - logger.debug("entity body=\r" + entity); + logger.debug("generated ID=" + generatedId); + } + + // Create a second ID. Verify that it is different from the first. + // Assumes that the last part in the ID pattern generates values + // that will always differ at each generation. + res = client.createId(knownResourceId); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + String secondGeneratedId = res.getEntity(); + Assert.assertNotNull(secondGeneratedId); + Assert.assertFalse(secondGeneratedId.isEmpty()); + Assert.assertFalse(secondGeneratedId.equals(generatedId)); + if (logger.isDebugEnabled()) { + logger.debug("second generated ID=" + secondGeneratedId); } + } - * - */ // Failure outcomes // None at present. @@ -131,7 +194,7 @@ public class IdServiceTest extends BaseServiceTest { // Success outcomes @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, - dependsOnMethods = {"readList"}) + dependsOnMethods = {"create"}) public void read(String testName) throws Exception { if (logger.isDebugEnabled()) { @@ -140,6 +203,10 @@ public class IdServiceTest extends BaseServiceTest { // Perform setup. testSetup(STATUS_OK, ServiceRequestType.READ); + + if(logger.isDebugEnabled()){ + logger.debug("Reading ID Generator at CSID " + knownResourceId + " ..."); + } // Submit the request to the service and store the response. IdClient client = new IdClient(); @@ -171,7 +238,8 @@ public class IdServiceTest extends BaseServiceTest { // Success outcomes - @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class) + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) public void readList(String testName) throws Exception { if (logger.isDebugEnabled()) { @@ -210,11 +278,36 @@ public class IdServiceTest extends BaseServiceTest { logger.debug("entity body=\r" + entity); } - knownResourceId = getOneIDGeneratorCSID(entity); } // Failure outcomes // None at present. + + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"create", "createId", "read", "readList"}) + public void delete(String testName) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + + // Perform setup. + testSetup(STATUS_OK, ServiceRequestType.DELETE); + + // Submit the request to the service and store the response. + IdClient client = new IdClient(); + ClientResponse res = client.delete(knownResourceId); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } // --------------------------------------------------------------- // Utility methods used by tests above @@ -227,18 +320,28 @@ public class IdServiceTest extends BaseServiceTest { return new IdClient().getServicePathComponent(); } - private String getOneIDGeneratorCSID(String entity) { - // FIXME: Temporarliy uses a hard-coded, known ID. - // - // Instead get this from the entity body, for now via XPath, - // and later, when we've declared an XSD for ID Generator payloads, - // via the appropriate JAXB-generated method. - return "4b984865-f93d-4481-b874-3dba863ec589"; - } - @Override protected String getServiceName() { throw new UnsupportedOperationException(); //FIXME: REM - See http://issues.collectionspace.org/browse/CSPACE-3498 } } + + /** + * Returns a serialized ID generator, based on the SPECTRUM entry number pattern, + * as a sample ID generator to be used in tests. + * + * This is a minimal ID Generator, containing only ID Generator Parts, + * and lacking a display name, description etc. + * + * @return a serialized ID Generator + * @throws BadRequestException + */ + public String getSampleSerializedIdGenerator() throws BadRequestException { + + SettableIDGenerator generator = new SettableIDGenerator(); + generator.add(new StringIDGeneratorPart("E")); + generator.add(new NumericIDGeneratorPart("1")); + return IDGeneratorSerializer.serialize(generator); + + } } diff --git a/services/id/pom.xml b/services/id/pom.xml index c055b15e3..56d9c7f75 100644 --- a/services/id/pom.xml +++ b/services/id/pom.xml @@ -33,10 +33,9 @@ pom + service - - client diff --git a/services/id/service/pom.xml b/services/id/service/pom.xml index 2541ef85b..dbb291a9f 100644 --- a/services/id/service/pom.xml +++ b/services/id/service/pom.xml @@ -33,15 +33,7 @@ services.id.service - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-log4j12 - + org.collectionspace.services @@ -58,54 +50,6 @@ test - - - - org.testng - testng - 5.6 - - - - - - javax.security - jaas - 1.0.01 - provided - - - - - dom4j - dom4j - 1.6.1 - provided - - - - - - org.jboss.resteasy - resteasy-jaxrs - - - tjws - webserver - - - - - - org.jboss.resteasy - resteasy-jaxb-provider - - - - org.jboss.resteasy - resteasy-multipart-provider - - - - - mysql - mysql-connector-java - - test - - com.thoughtworks.xstream diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java index 25515ae50..e85fcc52c 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDResource.java @@ -22,9 +22,10 @@ */ package org.collectionspace.services.id; -import java.io.StringWriter; import java.util.Map; +import java.util.UUID; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -43,12 +44,9 @@ import org.collectionspace.services.common.document.BadRequestException; import org.collectionspace.services.common.document.DocumentNotFoundException; import org.dom4j.Document; -import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Namespace; -import org.dom4j.io.OutputFormat; -import org.dom4j.io.XMLWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,29 +61,25 @@ import org.slf4j.LoggerFactory; */ // Set the base path component for URLs that access this service. @Path("/idgenerators") +@Produces(MediaType.TEXT_PLAIN) public class IDResource { final Logger logger = LoggerFactory.getLogger(IDResource.class); final static IDService service = new IDServiceJdbcImpl(); - // Query parameter names and values. final static String QUERY_PARAM_LIST_FORMAT = "format"; final static String LIST_FORMAT_SUMMARY = "summary"; final static String LIST_FORMAT_FULL = "full"; final static String QUERY_PARAM_ID_GENERATOR_ROLE = "role"; - // XML namespace for the ID Service. final static String ID_SERVICE_NAMESPACE = - "http://collectionspace.org/services/id"; + "http://collectionspace.org/services/id"; final static String ID_SERVICE_NAMESPACE_PREFIX = "ns2"; - // Names of elements for ID generator instances, lists and list items. final static String ID_GENERATOR_NAME = "idgenerator"; final static String ID_GENERATOR_COMPONENTS_NAME = "idgenerator-components"; final static String ID_GENERATOR_LIST_NAME = "idgenerator-list"; final static String ID_GENERATOR_LIST_ITEM_NAME = "idgenerator-list-item"; - - // Base URL path for REST-based requests to the ID Service. // // @TODO Investigate whether this can be obtained from the @@ -110,7 +104,6 @@ public class IDResource { */ @POST @Path("/{csid}/ids") - @Produces(MediaType.TEXT_PLAIN) public Response newID(@PathParam("csid") String csid) { // @TODO The JavaDoc description reflects an as-yet-to-be-carried out @@ -141,10 +134,7 @@ public class IDResource { // If the new ID is empty, return an error response. if (newId == null || newId.trim().isEmpty()) { response = - Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity("ID Service returned null or empty ID") - .type(MediaType.TEXT_PLAIN) - .build(); + Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ID Service returned null or empty ID").type(MediaType.TEXT_PLAIN).build(); return response; } @@ -152,35 +142,28 @@ public class IDResource { // - HTTP Status code (to '201 Created') // - Content-type header (to the relevant media type) // - Entity body (to the new ID) - response = Response.status(Response.Status.CREATED) - .entity(newId) - .type(MediaType.TEXT_PLAIN) - .build(); + response = Response.status(Response.Status.CREATED).entity(newId).type(MediaType.TEXT_PLAIN).build(); - // @TODO Return an XML-based error results format with the - // responses below. + // @TODO Return an XML-based error results format with the + // responses below. - // @TODO An IllegalStateException often indicates an overflow - // of an IDPart. Consider whether returning a 400 Bad Request - // status code is still warranted, or whether returning some other - // status would be more appropriate. + // @TODO An IllegalStateException often indicates an overflow + // of an IDPart. Consider whether returning a 400 Bad Request + // status code is still warranted, or whether returning some other + // status would be more appropriate. } catch (DocumentNotFoundException dnfe) { - response = Response.status(Response.Status.NOT_FOUND) - .entity(dnfe.getMessage()).type(MediaType.TEXT_PLAIN).build(); + response = Response.status(Response.Status.NOT_FOUND).entity(dnfe.getMessage()).type(MediaType.TEXT_PLAIN).build(); } catch (BadRequestException bre) { - response = Response.status(Response.Status.BAD_REQUEST) - .entity(bre.getMessage()).type(MediaType.TEXT_PLAIN).build(); + response = Response.status(Response.Status.BAD_REQUEST).entity(bre.getMessage()).type(MediaType.TEXT_PLAIN).build(); } catch (IllegalStateException ise) { - response = Response.status(Response.Status.BAD_REQUEST) - .entity(ise.getMessage()).type(MediaType.TEXT_PLAIN).build(); + response = Response.status(Response.Status.BAD_REQUEST).entity(ise.getMessage()).type(MediaType.TEXT_PLAIN).build(); // This is guard code that should never be reached. } catch (Exception e) { - response = Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build(); + response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build(); } return response; @@ -195,39 +178,36 @@ public class IDResource { @POST @Path("") @Consumes(MediaType.APPLICATION_XML) - @Produces(MediaType.TEXT_PLAIN) - public Response createIDGenerator() { - - // @TODO Implement this stubbed method - // by replacing this placeholder code. + public Response createIDGenerator(String xmlPayload) { ResponseBuilder builder = Response.ok(); Response response = builder.build(); - // If we successfully obtained a new ID from the specified - // ID generator instance, return it in the response. + try { - String id = "idGeneratorResourceIdGoesHere"; - // String id = service.createIDGenerator(); + String csid = UUID.randomUUID().toString(); + service.createIDGenerator(csid, xmlPayload); - // Build the URI to be returned in the Location header. - // - // Gets the base URL path to this resource. - UriBuilder path = UriBuilder.fromResource(IDResource.class); - // @TODO Look into whether we can create the path using the - // URI template in the @Path annotation to this method, rather - // than the hard-coded analog to that template currently used. - path.path("" + id); - - // Build the response, setting the: - // - HTTP Status code (to '201 Created') - // - Content-type header (to the relevant media type) - // - Entity body (to the new ID) - response = - Response.created(path.build()) - .entity("") - .type(MediaType.TEXT_PLAIN) - .build(); + // Build the URI to be returned in the Location header. + // + // Gets the base URL path to this resource. + UriBuilder path = UriBuilder.fromResource(IDResource.class); + // @TODO Look into whether we can create the path using the + // URI template in the @Path annotation to this method, rather + // than the hard-coded analog to that template currently used. + path.path("" + csid); + + // Build the response, setting the: + // - HTTP Status code (to '201 Created') + // - Content-type header (to the relevant media type) + // - Entity body (to the new ID) + response = + Response.created(path.build()).entity("").type(MediaType.TEXT_PLAIN).build(); + + } catch (Exception e) { + response = + Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build(); + } return response; } @@ -256,7 +236,7 @@ public class IDResource { Document doc = DocumentHelper.createDocument(); Element root = doc.addElement(ID_GENERATOR_NAME); Namespace namespace = - new Namespace(ID_SERVICE_NAMESPACE_PREFIX, ID_SERVICE_NAMESPACE); + new Namespace(ID_SERVICE_NAMESPACE_PREFIX, ID_SERVICE_NAMESPACE); doc.getRootElement().add(namespace); // Make new elements for each of the components of this ID generator @@ -270,35 +250,23 @@ public class IDResource { resourceRepresentation = XmlTools.prettyPrintXML(doc); response = - Response.status(Response.Status.OK) - .entity(resourceRepresentation) - .type(MediaType.APPLICATION_XML) - .build(); + Response.status(Response.Status.OK).entity(resourceRepresentation).type(MediaType.APPLICATION_XML).build(); - // @TODO Return an XML-based error results format with the - // responses below. + // @TODO Return an XML-based error results format with the + // responses below. } catch (DocumentNotFoundException dnfe) { response = - Response.status(Response.Status.NOT_FOUND) - .entity(dnfe.getMessage()) - .type(MediaType.TEXT_PLAIN) - .build(); + Response.status(Response.Status.NOT_FOUND).entity(dnfe.getMessage()).type(MediaType.TEXT_PLAIN).build(); } catch (IllegalStateException ise) { response = - Response.status(Response.Status.BAD_REQUEST) - .entity(ise.getMessage()) - .type(MediaType.TEXT_PLAIN) - .build(); + Response.status(Response.Status.BAD_REQUEST).entity(ise.getMessage()).type(MediaType.TEXT_PLAIN).build(); - // This is guard code that should never be reached. + // This is guard code that should never be reached. } catch (Exception e) { response = - Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(e.getMessage()) - .type(MediaType.TEXT_PLAIN) - .build(); + Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build(); } return response; @@ -320,8 +288,8 @@ public class IDResource { @Path("") @Produces(MediaType.APPLICATION_XML) public Response readIDGeneratorsList( - @QueryParam(QUERY_PARAM_LIST_FORMAT) String listFormat, - @QueryParam(QUERY_PARAM_ID_GENERATOR_ROLE) String role) { + @QueryParam(QUERY_PARAM_LIST_FORMAT) String listFormat, + @QueryParam(QUERY_PARAM_ID_GENERATOR_ROLE) String role) { // @TODO The names and values of the query parameters above // ("format"and "role") are arbitrary, as are the format of the @@ -334,19 +302,16 @@ public class IDResource { String resourceRepresentation = ""; try { - Map generators = + Map generators = service.readIDGeneratorsList(); // If no ID generator instances were found, return an empty list. - if (generators == null || generators.size() == 0) { + if (generators == null || generators.isEmpty()) { Document doc = baseListDocument(); resourceRepresentation = doc.asXML(); response = - Response.status(Response.Status.OK) - .entity(resourceRepresentation) - .type(MediaType.APPLICATION_XML) - .build(); + Response.status(Response.Status.OK).entity(resourceRepresentation).type(MediaType.APPLICATION_XML).build(); return response; } @@ -365,8 +330,8 @@ public class IDResource { // ID generator instances. if (role == null || role.trim().isEmpty()) { // Do nothing - // Otherwise, return only ID generator instances - // matching the requested role. + // Otherwise, return only ID generator instances + // matching the requested role. } else { // @TODO Implement this stubbed code, by // iterating over generator instances and @@ -380,51 +345,63 @@ public class IDResource { resourceRepresentation = formattedSummaryList(generators); } else if (listFormat.equalsIgnoreCase(LIST_FORMAT_FULL)) { resourceRepresentation = formattedFullList(generators); - // Return an error if the value of the query parameter - // is unrecognized. - // - // @TODO Return an appropriate XML-based entity body upon error. + // Return an error if the value of the query parameter + // is unrecognized. + // + // @TODO Return an appropriate XML-based entity body upon error. } else { String msg = - "Query parameter '" + listFormat + "' was not recognized."; + "Query parameter '" + listFormat + "' was not recognized."; if (logger.isDebugEnabled()) { logger.debug(msg); } response = - Response.status(Response.Status.BAD_REQUEST) - .entity("") - .type(MediaType.TEXT_PLAIN) - .build(); + Response.status(Response.Status.BAD_REQUEST).entity("").type(MediaType.TEXT_PLAIN).build(); } response = - Response.status(Response.Status.OK) - .entity(resourceRepresentation) - .type(MediaType.APPLICATION_XML) - .build(); + Response.status(Response.Status.OK).entity(resourceRepresentation).type(MediaType.APPLICATION_XML).build(); - // @TODO Return an XML-based error results format with the - // responses below. + // @TODO Return an XML-based error results format with the + // responses below. } catch (IllegalStateException ise) { response = - Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(ise.getMessage()) - .type(MediaType.TEXT_PLAIN) - .build(); + Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ise.getMessage()).type(MediaType.TEXT_PLAIN).build(); - // This is guard code that should never be reached. + // This is guard code that should never be reached. } catch (Exception e) { response = - Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(e.getMessage()) - .type(MediaType.TEXT_PLAIN) - .build(); + Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build(); } return response; } ////////////////////////////////////////////////////////////////////// + /** + * Creates a new ID generator instance. + * + */ + @DELETE + @Path("/{csid}") + public Response deleteIDGenerator(@PathParam("csid") String csid) { + + ResponseBuilder builder = Response.ok(); + Response response = builder.build(); + + try { + service.deleteIDGenerator(csid); + response = Response.ok().entity("").type(MediaType.TEXT_PLAIN).build(); + } catch (Exception e) { + response = + Response.status(Response.Status.INTERNAL_SERVER_ERROR). + entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build(); + } + + return response; + } + +////////////////////////////////////////////////////////////////////// /** * Identifies whether the specified ID generator instance can * generate and validate IDs in a specified role (aka type or context). @@ -466,7 +443,7 @@ public class IDResource { Document doc = DocumentHelper.createDocument(); Element root = doc.addElement(ID_GENERATOR_LIST_NAME); Namespace namespace = - new Namespace(ID_SERVICE_NAMESPACE_PREFIX, ID_SERVICE_NAMESPACE); + new Namespace(ID_SERVICE_NAMESPACE_PREFIX, ID_SERVICE_NAMESPACE); doc.getRootElement().add(namespace); return doc; @@ -485,7 +462,7 @@ public class IDResource { * @return A summary list of ID generator instances. */ private String formattedSummaryList( - Map generators) { + Map generators) { Document doc = baseListDocument(); @@ -494,19 +471,18 @@ public class IDResource { // Retrieve the CSIDs from each ID generator instance, // and use these in summary information returned about // each instance. - for (String csid : generators.keySet()) - { + for (String csid : generators.keySet()) { // Add a new element for each item in the list. listitem = - doc.getRootElement().addElement(ID_GENERATOR_LIST_ITEM_NAME); + doc.getRootElement().addElement(ID_GENERATOR_LIST_ITEM_NAME); // Append display name information for this ID generator instance. displayname = generators.get(csid).getDisplayName(); listitem = appendDisplayNameIDGeneratorInformation(listitem, displayname); // Append summary information about this ID generator instance. listitem = appendSummaryIDGeneratorInformation(listitem, csid); - } + } - return XmlTools.prettyPrintXML(doc); + return XmlTools.prettyPrintXML(doc); } ////////////////////////////////////////////////////////////////////// @@ -519,17 +495,16 @@ public class IDResource { * @return A full list of ID generator instances. */ private String formattedFullList( - Map generators) { + Map generators) { Document doc = baseListDocument(); Element listitem = null; String displayname = ""; - for (String csid : generators.keySet()) - { + for (String csid : generators.keySet()) { // Add a new element for each item in the list. listitem = - doc.getRootElement().addElement(ID_GENERATOR_LIST_ITEM_NAME); + doc.getRootElement().addElement(ID_GENERATOR_LIST_ITEM_NAME); // Append display name information for this ID generator instance. displayname = generators.get(csid).getDisplayName(); listitem = appendDisplayNameIDGeneratorInformation(listitem, displayname); @@ -538,12 +513,12 @@ public class IDResource { // Append details of this ID generator instance. Element instance = listitem.addElement(ID_GENERATOR_NAME); listitem = appendDetailedIDGeneratorInformation(instance, - generators.get(csid)); + generators.get(csid)); } return XmlTools.prettyPrintXML(doc); } - + ////////////////////////////////////////////////////////////////////// /** * Appends a display name to an element representing @@ -557,8 +532,8 @@ public class IDResource { * @return The XML element representing an ID generator instance, * with the display name appended. */ - private Element appendDisplayNameIDGeneratorInformation(Element instanceElement, - String displaynameValue) { + private Element appendDisplayNameIDGeneratorInformation(Element instanceElement, + String displaynameValue) { Element displayname = instanceElement.addElement("displayname"); displayname.addText(displaynameValue); @@ -566,7 +541,6 @@ public class IDResource { return instanceElement; } - ////////////////////////////////////////////////////////////////////// /** * Appends summary information to an element representing @@ -581,8 +555,8 @@ public class IDResource { * @return The XML element representing an ID generator instance, * with summary information appended. */ - private Element appendSummaryIDGeneratorInformation(Element instanceElement, - String csidValue) { + private Element appendSummaryIDGeneratorInformation(Element instanceElement, + String csidValue) { Element uri = instanceElement.addElement("uri"); uri.addText(getRelativePath(csidValue)); @@ -606,7 +580,7 @@ public class IDResource { * with detailed information appended. */ private Element appendDetailedIDGeneratorInformation( - Element instanceElement, IDGeneratorInstance generatorInstance) { + Element instanceElement, IDGeneratorInstance generatorInstance) { // Append description information. Element description = instanceElement.addElement("description"); @@ -624,20 +598,18 @@ public class IDResource { // or launch time; or generate or load this value once, at the // time that an ID generator instance is created. String lastgenerated = generatorInstance.getLastGeneratedID(); - if (lastgenerated != null & ! lastgenerated.trim().isEmpty()) { + if (lastgenerated != null & !lastgenerated.trim().isEmpty()) { displayid.addText(lastgenerated); } else { SettableIDGenerator gen; try { - gen = IDGeneratorSerializer.deserialize(generatorInstance - .getGeneratorState()); + gen = IDGeneratorSerializer.deserialize(generatorInstance.getGeneratorState()); String current = gen.getCurrentID(); - if (current != null & ! current.trim().isEmpty()) { + if (current != null & !current.trim().isEmpty()) { displayid.addText(current); } } catch (Exception e) { // Do nothing here. - // @TODO // Could potentially return an error message, akin to: // displayid.addText("No ID available for display"); @@ -646,7 +618,7 @@ public class IDResource { // Append components information. Element generator = - instanceElement.addElement(ID_GENERATOR_COMPONENTS_NAME); + instanceElement.addElement(ID_GENERATOR_COMPONENTS_NAME); // Get an XML string representation of the ID generator's components. String generatorStr = generatorInstance.getGeneratorState(); // Convert the XML string representation of the ID generator's @@ -656,18 +628,17 @@ public class IDResource { Document generatorDoc = XmlTools.textToXMLDocument(generatorStr); Element generatorRoot = generatorDoc.getRootElement(); generator.add(generatorRoot.createCopy()); - // If an error occurs parsing the XML string representation, - // the text of the components element will remain empty. + // If an error occurs parsing the XML string representation, + // the text of the components element will remain empty. } catch (Exception e) { if (logger.isDebugEnabled()) { - logger.debug("Error parsing XML text: " + generatorStr); + logger.debug("Error parsing XML text: " + generatorStr); } } return instanceElement; } - ////////////////////////////////////////////////////////////////////// /** * Returns a relative URI path to a resource @@ -680,14 +651,13 @@ public class IDResource { */ private String getRelativePath(String csid) { - // @TODO Verify that this is the correct relative path. - // Do we need to check the path provided in the original request? - - if (csid !=null && ! csid.trim().isEmpty()) { - return BASE_URL_PATH + "/" + csid; - } else { - return BASE_URL_PATH; - } - } + // @TODO Verify that this is the correct relative path. + // Do we need to check the path provided in the original request? + if (csid != null && !csid.trim().isEmpty()) { + return BASE_URL_PATH + "/" + csid; + } else { + return BASE_URL_PATH; + } + } } diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDService.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDService.java index 34a3dd994..a4693c43f 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDService.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDService.java @@ -14,22 +14,15 @@ * You may obtain a copy of the ECL 2.0 License at * https://source.collectionspace.org/collection-space/LICENSE.txt */ - package org.collectionspace.services.id; -// May at some point instead use -// org.jboss.resteasy.spi.NotFoundException import java.util.Map; -import org.collectionspace.services.common.document.DocumentNotFoundException; -import org.collectionspace.services.common.document.BadRequestException; - /** * IDService * * Interface for the ID Service. * - * $LastChangedBy$ * $LastChangedRevision$ * $LastChangedDate$ */ @@ -38,45 +31,38 @@ public interface IDService { // ---------------------------------------- // IDs // ---------------------------------------- - // Create - // Read single object - // Generates and returns a new ID from the specified ID generator. - public String createID(String csid) throws DocumentNotFoundException, - BadRequestException, IllegalStateException; - + public String createID(String csid) throws Exception; + // Returns the last-generated ID associated with the specified ID generator. public String readLastID(String csid) - throws DocumentNotFoundException, IllegalStateException; + throws Exception; // Read a list of objects (aka read multiple) - // ---------------------------------------- // ID Generators // ---------------------------------------- - // Create - // Adds a new ID generator. public void createIDGenerator(String csid, String serializedIDGenerator) - throws BadRequestException, IllegalStateException; - + throws Exception; + // Read single object public IDGeneratorInstance readIDGenerator(String csid) - throws DocumentNotFoundException, IllegalStateException; - + throws Exception; + // Read a list of objects (aka read multiple) // and return a list (map) of those objects and their identifiers. - public Map readIDGeneratorsList() - throws IllegalStateException; + public Map readIDGeneratorsList() + throws Exception; // Update - public void updateIDGenerator(String csid, String serializedIDGenerator) - throws DocumentNotFoundException, BadRequestException, - IllegalArgumentException, IllegalStateException; - - // Delete (possibly not permitted - deactivate instead?) + public void updateIDGenerator(String csid, String serializedIDGenerator) + throws Exception; + // Delete (possibly not permitted - deactivate instead?) + public void deleteIDGenerator(String csid) + throws Exception; } diff --git a/services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java b/services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java index 8c4cf5222..c6ec9a25a 100644 --- a/services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java +++ b/services/id/service/src/main/java/org/collectionspace/services/id/IDServiceJdbcImpl.java @@ -26,9 +26,6 @@ // // We're currently overloading existing core and extension Java Exceptions // in ways that are not consistent with their original semantic meaning. -// @TODO Get the JDBC driver classname and database URL from configuration; -// better yet, substitute JPA or Hibernate for JDBC for accessing -// database-managed persistence. // @TODO Remove any hard-coded dependencies on MySQL. // @TODO Determine how to restrict access to ID-related tables by role. // @TODO Retrieve IDGenerators from the database (via JDBC or @@ -72,13 +69,12 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.Statement; - -// May at some point instead use -// org.jboss.resteasy.spi.NotFoundException import java.util.LinkedHashMap; import java.util.Map; +import javax.security.auth.login.LoginException; import org.collectionspace.services.common.document.BadRequestException; import org.collectionspace.services.common.document.DocumentNotFoundException; +import org.collectionspace.services.common.storage.JDBCTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -95,11 +91,6 @@ import org.slf4j.LoggerFactory; public class IDServiceJdbcImpl implements IDService { final Logger logger = LoggerFactory.getLogger(IDServiceJdbcImpl.class); - final String JDBC_DRIVER_CLASSNAME = "com.mysql.jdbc.Driver"; - final String DATABASE_NAME = "cspace"; - final String DATABASE_URL = "jdbc:mysql://localhost:3306/" + DATABASE_NAME; - final String DATABASE_USERNAME = "test"; - final String DATABASE_PASSWORD = "test"; final String TABLE_NAME = "id_generator"; boolean jdbcDriverInstantiated = false; boolean hasPreconditions = true; @@ -108,54 +99,7 @@ public class IDServiceJdbcImpl implements IDService { /** * Constructor (no-argument). */ - public void IDServiceJdbcImpl() throws IllegalStateException { - - // @TODO Decide when and how to fail at startup, or else to correct - // failure conditions automatically, when preconditions are not met. - // - // Currently, errors at initialization are merely informative and - // result in exceptions that can be persistently logged. - - try { - init(); - } catch (IllegalStateException e) { - throw e; - } - - } - - // @TODO init() is currently UNTESTED as of 2009-08-11T13:00-0700. - ////////////////////////////////////////////////////////////////////// - /** - * Initializes the service. - * - * @throws IllegalStateException if one or more of the required preconditions - * for the service is not present, or is not in its required state. - */ - public void init() throws IllegalStateException { - - logger.debug("> in init"); - - try { - instantiateJdbcDriver(JDBC_DRIVER_CLASSNAME); - } catch (IllegalStateException e) { - throw e; - } - - try { - boolean hasTable = hasTable(TABLE_NAME); - if (!hasTable) { - String msg = - "Required table " - + "\'" + TABLE_NAME + "\'" - + " could not be found in the database."; - logger.warn(msg); - throw new IllegalStateException(msg); - } - } catch (IllegalStateException e) { - throw e; - } - + public void IDServiceJdbcImpl() { } // ----------------- @@ -178,8 +122,7 @@ public class IDServiceJdbcImpl implements IDService { * @throws IllegalStateException if a storage-related error occurred. */ @Override - public String createID(String csid) throws DocumentNotFoundException, - BadRequestException, IllegalArgumentException, IllegalStateException { + public String createID(String csid) throws Exception { logger.debug("> in createID"); @@ -276,7 +219,7 @@ public class IDServiceJdbcImpl implements IDService { * @throws DocumentNotFoundException if the requested ID generator could not be found. */ public void updateLastID(String csid, String lastId) - throws IllegalStateException, DocumentNotFoundException { + throws IllegalStateException, DocumentNotFoundException, LoginException, SQLException { logger.debug("> in updateLastID"); @@ -376,8 +319,7 @@ public class IDServiceJdbcImpl implements IDService { * @throws IllegalStateException if a storage-related error occurred. */ @Override - public String readLastID(String csid) throws DocumentNotFoundException, - IllegalStateException { + public String readLastID(String csid) throws Exception { logger.debug("> in readLastID"); @@ -402,8 +344,7 @@ public class IDServiceJdbcImpl implements IDService { throw new DocumentNotFoundException( "ID generator " + "\'" + csid + "\'" + " could not be found."); } - - lastId = rs.getString(1); + lastId = (rs.getString(1) != null ? rs.getString(1) : ""); logger.debug("> retrieved ID: " + lastId); rs.close(); @@ -448,7 +389,7 @@ public class IDServiceJdbcImpl implements IDService { * @throws IllegalStateException if a storage-related error occurred. */ public void createIDGenerator(String csid, SettableIDGenerator generator) - throws BadRequestException, IllegalStateException { + throws Exception { logger.debug("> in createIDGenerator(String, SettableIDGenerator)"); @@ -498,7 +439,7 @@ public class IDServiceJdbcImpl implements IDService { */ @Override public void createIDGenerator(String csid, String serializedGenerator) - throws BadRequestException, IllegalStateException { + throws Exception { logger.debug("> in createIDGenerator(String, String)"); @@ -605,8 +546,7 @@ public class IDServiceJdbcImpl implements IDService { * @throws IllegalStateException if a storage-related error occurred. */ @Override - public IDGeneratorInstance readIDGenerator(String csid) throws - DocumentNotFoundException, IllegalStateException { + public IDGeneratorInstance readIDGenerator(String csid) throws Exception { logger.debug("> in readIDGenerator"); @@ -632,10 +572,10 @@ public class IDServiceJdbcImpl implements IDService { } instance = new IDGeneratorInstance(); - instance.setDisplayName(rs.getString(2)); - instance.setDescription(rs.getString(3)); - instance.setGeneratorState(rs.getString(4)); - instance.setLastGeneratedID(rs.getString(5)); + instance.setDisplayName(rs.getString(2) != null ? rs.getString(2) : ""); + instance.setDescription(rs.getString(3) != null ? rs.getString(3) : ""); + instance.setGeneratorState(rs.getString(4) != null ? rs.getString(4) : ""); + instance.setLastGeneratedID(rs.getString(5) != null ? rs.getString(5) : ""); rs.close(); @@ -675,7 +615,7 @@ public class IDServiceJdbcImpl implements IDService { */ @Override public Map readIDGeneratorsList() - throws IllegalStateException { + throws Exception { logger.debug("> in readIDGeneratorsList"); @@ -701,10 +641,10 @@ public class IDServiceJdbcImpl implements IDService { IDGeneratorInstance instance = null; while (moreRows = rs.next()) { instance = new IDGeneratorInstance(); - instance.setDisplayName(rs.getString(2)); - instance.setDescription(rs.getString(3)); - instance.setGeneratorState(rs.getString(4)); - instance.setLastGeneratedID(rs.getString(5)); + instance.setDisplayName(rs.getString(2) != null ? rs.getString(2) : "[No display name]"); + instance.setDescription(rs.getString(3) != null ? rs.getString(3) : "[No description]"); + instance.setGeneratorState(rs.getString(4) != null ? rs.getString(4) : "[No generator state]"); + instance.setLastGeneratedID(rs.getString(5) != null ? rs.getString(5) : "[No last generated ID]"); generators.put(rs.getString(1), instance); } @@ -748,8 +688,7 @@ public class IDServiceJdbcImpl implements IDService { * @throws IllegalStateException if a storage-related error occurred. */ public void updateIDGenerator(String csid, SettableIDGenerator generator) - throws BadRequestException, DocumentNotFoundException, - IllegalStateException { + throws Exception { logger.debug("> in updateIDGenerator(String, SettableIDGenerator)"); @@ -805,8 +744,7 @@ public class IDServiceJdbcImpl implements IDService { */ @Override public void updateIDGenerator(String csid, String serializedGenerator) - throws DocumentNotFoundException, BadRequestException, - IllegalStateException { + throws Exception { logger.debug("> in updateIDGenerator(String, String)"); @@ -914,8 +852,9 @@ public class IDServiceJdbcImpl implements IDService { * * @throws IllegalStateException if a storage-related error occurred. */ + @Override public void deleteIDGenerator(String csid) - throws DocumentNotFoundException, IllegalStateException { + throws Exception { logger.debug("> in deleteIDGenerator"); @@ -986,42 +925,6 @@ public class IDServiceJdbcImpl implements IDService { // ------------------- // Database operations // ------------------- - ////////////////////////////////////////////////////////////////////// - /** - * Creates a new instance of the specified JDBC driver class. - * - * @param jdbcDriverClassname The name of a JDBC driver class. - * - * @throws IllegalStateException if a new instance of the specified - * JDBC driver class cannot be created. - */ - public void instantiateJdbcDriver(String jdbcDriverClassname) - throws IllegalStateException { - - logger.debug("> in instantiateJdbcDriver(String)"); - - try { - Class.forName(jdbcDriverClassname).newInstance(); - } catch (ClassNotFoundException e) { - throw new IllegalStateException( - "Error finding JDBC driver class '" - + JDBC_DRIVER_CLASSNAME - + "' to set up database connection."); - } catch (InstantiationException e) { - throw new IllegalStateException( - "Error instantiating JDBC driver class '" - + JDBC_DRIVER_CLASSNAME - + "' to set up database connection."); - } catch (IllegalAccessException e) { - throw new IllegalStateException( - "Error accessing JDBC driver class '" - + JDBC_DRIVER_CLASSNAME - + "' to set up database connection."); - } - - jdbcDriverInstantiated = true; - - } ////////////////////////////////////////////////////////////////////// /** @@ -1029,27 +932,22 @@ public class IDServiceJdbcImpl implements IDService { * * @return A JDBC database Connection object. * + * @throws LoginException * @throws SQLException if a storage-related error occurred. - * - * @throws IllegalStateException if the attempt to instantiate the - * JDBC driver fails. */ - public Connection getJdbcConnection() throws SQLException { + public Connection getJdbcConnection() throws LoginException, SQLException { logger.debug("> in getJdbcConnection"); - - if (! jdbcDriverInstantiated) { - try { - instantiateJdbcDriver(JDBC_DRIVER_CLASSNAME); - } catch (IllegalStateException e) { - throw e; - } - } + + // Providing an empty repository name to getConnection() will cause the + // default repository name to be used. + final String EMPTY_REPOSITORY_NAME = ""; Connection conn = null; try { - conn = DriverManager.getConnection(DATABASE_URL, - DATABASE_USERNAME, DATABASE_PASSWORD); + conn = JDBCTools.getConnection(EMPTY_REPOSITORY_NAME); + } catch (LoginException e) { + throw e; } catch (SQLException e) { throw e; } @@ -1069,7 +967,7 @@ public class IDServiceJdbcImpl implements IDService { * @throws IllegalStateException if an error occurs while checking for the * existence of the specified table. */ - public boolean hasTable(String tablename) throws IllegalStateException { + public boolean hasTable(String tablename) throws Exception { logger.debug("> in hasTable"); @@ -1084,7 +982,7 @@ public class IDServiceJdbcImpl implements IDService { // Retrieve a list of tables in the current database. final String CATALOG_NAME = null; - final String SCHEMA_NAME_PATTERN = null; + final String SCHEMA_NAME_PATTERN = "cspace"; final String[] TABLE_TYPES = null; ResultSet tablesMatchingTableName = conn.getMetaData().getTables( diff --git a/services/id/service/src/test/java/org/collectionspace/services/id/test/IDServiceJdbcImplTest.java b/services/id/service/src/test/java/org/collectionspace/services/id/test/IDServiceJdbcImplTest.java deleted file mode 100644 index 38c9e7526..000000000 --- a/services/id/service/src/test/java/org/collectionspace/services/id/test/IDServiceJdbcImplTest.java +++ /dev/null @@ -1,244 +0,0 @@ -/** - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - * - * http://www.collectionspace.org - * http://wiki.collectionspace.org - * - * Copyright © 2009 Regents of the University of California - * - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - * - * You may obtain a copy of the ECL 2.0 License at - * https://source.collectionspace.org/collection-space/LICENSE.txt - * - * 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 org.collectionspace.services.id.test; - -import java.util.Map; -import org.collectionspace.services.common.document.BadRequestException; -import org.collectionspace.services.common.document.DocumentNotFoundException; - -import org.collectionspace.services.id.*; - -import org.testng.Assert; -import org.testng.annotations.BeforeSuite; -import org.testng.annotations.Test; - -/** - * IDServiceJdbcImplTest - * - * Unit tests for the ID Service's JDBC implementation class, IDServiceJdbcImpl. - * - * $LastChangedRevision: 302 $ - * $LastChangedDate$ - */ -public class IDServiceJdbcImplTest { - - String csid; - String nextId; - String serializedGenerator; - SettableIDGenerator generator; - IDGeneratorInstance instance; - - IDServiceJdbcImpl jdbc = new IDServiceJdbcImpl(); - IDService service = jdbc; - - final static String TABLE_NAME = "id_generators"; - final static String DEFAULT_CSID = "TEST-1"; - - final static String CURRENT_YEAR = YearIDGeneratorPart.getCurrentYear(); - - // FIXME: Hard-coded driver name here should instead come from - // external configuration. - final String JDBC_DRIVER_CLASSNAME = "com.mysql.jdbc.Driver"; - - @BeforeSuite - public void init() { - try { - Class.forName(JDBC_DRIVER_CLASSNAME).newInstance(); - } catch (Exception e) { - Assert.fail("Error locating required JDBC driver " + JDBC_DRIVER_CLASSNAME); - } - } - - - @Test - public void hasRequiredDatabaseTable() { - Assert.assertTrue( - jdbc.hasTable(TABLE_NAME), - "Table '" + TABLE_NAME + "' must exist in database. " + - "Please first run SQL setup script, " + - "'create_id_generators_table.sql', in 'id' project."); - } - - @Test(dependsOnMethods = {"hasRequiredDatabaseTable"}) - public void createIDGenerator() throws DocumentNotFoundException, - BadRequestException, IllegalStateException { - try { - jdbc.deleteIDGenerator(DEFAULT_CSID); - } catch (Exception e) { - // Fail silently; this is guard code. - } - jdbc.createIDGenerator(DEFAULT_CSID, getSpectrumEntryNumberGenerator()); - } - - - @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "createIDGenerator"}) - public void readIDGenerator() throws DocumentNotFoundException, - BadRequestException, IllegalStateException { - - instance = jdbc.readIDGenerator(DEFAULT_CSID); - Assert.assertTrue(instance != null); - serializedGenerator = instance.getGeneratorState(); - Assert.assertTrue(! serializedGenerator.equals("")); - generator = IDGeneratorSerializer.deserialize(serializedGenerator); - } - - - @Test(dependsOnMethods = - {"hasRequiredDatabaseTable", "createIDGenerator", "readIDGenerator"}) - public void readIDGeneratorsList() throws IllegalStateException { - - Map generators = jdbc.readIDGeneratorsList(); - - // @TODO Replace this placeholder test, which just - // verifies that no error occurred while retrieving the list, - // with a more meaningful test. - Assert.assertTrue(generators != null); - Assert.assertTrue(generators.size() > 0); - } - @Test(dependsOnMethods = - {"hasRequiredDatabaseTable", "createIDGenerator", "readIDGenerator", - "readIDGeneratorsList"}) - public void readIDGeneratorsSummaryList() throws IllegalStateException { - - Map generators = jdbc.readIDGeneratorsList(); - - // @TODO Replace this placeholder test, which just - // verifies that no error occurred while retrieving the list, - // with a more meaningful test. - Assert.assertTrue(generators.size() > 0); - } - -/* - @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "createIDGenerator", - "readIDGenerator"}) - public void updateIDGenerator() throws DocumentNotFoundException, - BadRequestException, IllegalStateException { - - final String NEW_DESCRIPTION = "new description"; - - // Retrieve an existing generator, deserialize it, - // update its contents, serialize it, and write it back. - serializedGenerator = jdbc.readIDGenerator(DEFAULT_CSID); - generator = IDGeneratorSerializer.deserialize(serializedGenerator); - generator.setDescription(NEW_DESCRIPTION); - serializedGenerator = IDGeneratorSerializer.serialize(generator); - - jdbc.updateIDGenerator(DEFAULT_CSID, serializedGenerator); - - serializedGenerator = jdbc.readIDGenerator(DEFAULT_CSID); - generator = IDGeneratorSerializer.deserialize(serializedGenerator); - - Assert.assertEquals(generator.getDescription(), NEW_DESCRIPTION); - - } -*/ - - @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "createIDGenerator", - "readIDGenerator", "readIDGeneratorsList", - "readIDGeneratorsSummaryList"}) - public void deleteIDGenerator() throws DocumentNotFoundException { - jdbc.deleteIDGenerator(DEFAULT_CSID); - } - - @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "createIDGenerator", - "readIDGenerator", "deleteIDGenerator"}) - public void createID() throws DocumentNotFoundException, - BadRequestException, IllegalStateException { - - try { - jdbc.deleteIDGenerator(DEFAULT_CSID); - } catch (Exception e) { - // This deletion attempt may properly fail silently - // if no ID generator with the specified CSID currently - // exists in the database. - } - - jdbc.createIDGenerator(DEFAULT_CSID, getSpectrumEntryNumberGenerator()); - - Assert.assertEquals(service.createID(DEFAULT_CSID), "E1"); - Assert.assertEquals(service.createID(DEFAULT_CSID), "E2"); - Assert.assertEquals(service.createID(DEFAULT_CSID), "E3"); - - try { - jdbc.deleteIDGenerator(DEFAULT_CSID); - } catch (Exception e) { - Assert.fail("Could not delete ID generator '" + DEFAULT_CSID + "'."); - } - - jdbc.createIDGenerator(DEFAULT_CSID, getChinAccessionNumberGenerator()); - - Assert.assertEquals(service.createID(DEFAULT_CSID), CURRENT_YEAR + ".1.1"); - Assert.assertEquals(service.createID(DEFAULT_CSID), CURRENT_YEAR + ".1.2"); - Assert.assertEquals(service.createID(DEFAULT_CSID), CURRENT_YEAR + ".1.3"); - - try { - jdbc.deleteIDGenerator(DEFAULT_CSID); - } catch (Exception e) { - Assert.fail("Could not delete ID generator '" + DEFAULT_CSID + "'."); - } - - } - - - // This test requires that: - // 1. The ID Service is running and accessible to this test; and - // 2. There is no ID generator retrievable through that service - // with the identifier 'non-existent identifier'. - @Test(dependsOnMethods = {"hasRequiredDatabaseTable", "createID"}, - expectedExceptions = DocumentNotFoundException.class) - public void createIDNonExistentGenerator() throws DocumentNotFoundException, - BadRequestException, IllegalArgumentException, IllegalStateException { - nextId = service.createID("non-existent identifier"); - } - - // --------------------------------------------------------------- - // Utility methods used by tests above - // --------------------------------------------------------------- - - // @TODO Read test patterns from external configuration. - - public String getSpectrumEntryNumberGenerator() throws BadRequestException { - - generator = new SettableIDGenerator(); - generator.add(new StringIDGeneratorPart("E")); - generator.add(new NumericIDGeneratorPart("1")); - - return IDGeneratorSerializer.serialize(generator); - - } - - public String getChinAccessionNumberGenerator() throws BadRequestException { - - generator = new SettableIDGenerator(); - generator.add(new YearIDGeneratorPart()); - generator.add(new StringIDGeneratorPart(".")); - generator.add(new NumericIDGeneratorPart("1")); - generator.add(new StringIDGeneratorPart(".")); - generator.add(new NumericIDGeneratorPart("1")); - - return IDGeneratorSerializer.serialize(generator); - - } - -}