From ba5a3c882b32ed207024a5e81572c9eed96846fe Mon Sep 17 00:00:00 2001 From: Sanjay Dalal Date: Wed, 7 Apr 2010 18:23:06 +0000 Subject: [PATCH] CSPACE-1304 create permission CSPACE-1305 delete permission CPSACE-1306 get permission CSPACE-1307 update permission CSPACE-1309 search permission with resource name only CSPACE-1311 list permissions added new service authorization/permissions first checkin. permissions are yet to be plugged in with spring acls. minor copyright javadoc changes in role and account classes jpastorageclient now supports delete (with parent deleting children) and deletewhere (a shallow delete with where clause) test: mvn test at the service level, added PermissionServiceTest in authorization-mgt/client M services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java M services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml _M services/authorization-mgt/service A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleStorageConstants.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleValidatorHandler.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java A services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java M services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java A services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java A services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java A services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java M services/authorization/jaxb/src/main/resources/roles.xsd A services/authorization/jaxb/src/main/resources/permissions_list.xsd M services/authorization/jaxb/src/main/resources/permissions.xsd M services/authorization/jaxb/src/main/resources/roles_list.xsd M services/authorization/pstore/src/main/resources/db/mysql/authorization.sql M services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java M services/common/src/main/config/services/tenant-bindings.xml M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java D services/account/client/src/test/java/org/collectionspace/services/client --- .../CollectionSpaceJaxRsApplication.java | 2 + .../main/resources/META-INF/persistence.xml | 3 + .../account/storage/AccountJpaFilter.java | 25 - .../account/storage/AccountStorageClient.java | 13 +- .../services/client/PermissionClient.java | 132 ++++ .../services/client/PermissionProxy.java | 79 +++ .../client/test/PermissionServiceTest.java | 604 ++++++++++++++++++ .../client/test/RoleServiceTest.java | 8 +- .../authorization/PermissionResource.java | 302 +++++++++ .../services/authorization/RoleResource.java | 2 +- .../storage/PermissionDocumentHandler.java | 161 +++++ .../storage/PermissionJpaFilter.java | 76 +++ .../storage/PermissionStorageConstants.java | 38 ++ .../storage/PermissionValidatorHandler.java | 80 +++ .../authorization/storage/RoleJpaFilter.java | 28 +- .../storage/RoleStorageConstants.java | 26 - .../storage/RoleValidatorHandler.java | 21 - .../jaxb/src/main/resources/permissions.xsd | 49 +- .../src/main/resources/permissions_list.xsd | 49 ++ .../jaxb/src/main/resources/roles.xsd | 2 +- .../jaxb/src/main/resources/roles_list.xsd | 2 +- .../main/resources/db/mysql/authorization.sql | 2 +- .../main/config/services/tenant-bindings.xml | 33 + .../storage/jpa/JpaStorageClientImpl.java | 117 +++- 24 files changed, 1689 insertions(+), 165 deletions(-) create mode 100644 services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java create mode 100644 services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java create mode 100644 services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java create mode 100644 services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java create mode 100644 services/authorization/jaxb/src/main/resources/permissions_list.xsd diff --git a/services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java b/services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java index baa7c5f62..10c7b7554 100644 --- a/services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java +++ b/services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java @@ -41,6 +41,7 @@ import org.collectionspace.services.person.PersonAuthorityResource; import javax.ws.rs.core.Application; import java.util.HashSet; import java.util.Set; +import org.collectionspace.services.authorization.PermissionResource; import org.collectionspace.services.authorization.RoleResource; import org.collectionspace.services.common.security.SecurityInterceptor; @@ -61,6 +62,7 @@ public class CollectionSpaceJaxRsApplication extends Application { singletons.add(new SecurityInterceptor()); singletons.add(new AccountResource()); singletons.add(new RoleResource()); + singletons.add(new PermissionResource()); singletons.add(new CollectionObjectResource()); singletons.add(new IDResource()); singletons.add(new IntakeResource()); diff --git a/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml b/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml index dc4ee6643..120511413 100644 --- a/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml +++ b/services/JaxRsServiceProvider/src/main/resources/META-INF/persistence.xml @@ -9,6 +9,9 @@ org.collectionspace.services.account.AccountTenant org.collectionspace.services.account.Status org.collectionspace.services.authentication.User + org.collectionspace.services.authorization.Permission + org.collectionspace.services.authorization.PermissionAction + org.collectionspace.services.authorization.PermissionsList org.collectionspace.services.authorization.Role org.collectionspace.services.authorization.RolesList org.collectionspace.services.authorization.UserRole diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java index ad6c95353..21d04f781 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java @@ -20,32 +20,7 @@ * 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. - *//** - * 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 University of California at Berkeley - - * 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. - */ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. */ package org.collectionspace.services.account.storage; diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java index db960b1a4..be4c7482d 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountStorageClient.java @@ -198,12 +198,6 @@ public class AccountStorageClient extends JpaStorageClientImpl { //query an delete is inefficient AccountsCommon accountFound = getAccount(em, id); - StringBuilder accDelStr = new StringBuilder("DELETE FROM "); - accDelStr.append(getEntityName(ctx)); - accDelStr.append(" WHERE csid = :csid"); - //TODO: add tenant id - Query accDel = em.createQuery(accDelStr.toString()); - accDel.setParameter("csid", id); //TODO: add tenant id //if userid gives any indication about the id provider, it should @@ -219,12 +213,7 @@ public class AccountStorageClient extends JpaStorageClientImpl { usrDel.setParameter("username", accountFound.getUserId()); } em.getTransaction().begin(); -// int accDelCount = accDel.executeUpdate(); -// if (accDelCount != 1) { -// if (em != null && em.getTransaction().isActive()) { -// em.getTransaction().rollback(); -// } -// } + if (userLocal != null) { int usrDelCount = usrDel.executeUpdate(); if (usrDelCount != 1) { diff --git a/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java new file mode 100644 index 000000000..bea5c333b --- /dev/null +++ b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionClient.java @@ -0,0 +1,132 @@ +/** + * PermissionClient.java + * + * {Purpose of This Class} + * + * {Other Notes Relating to This Class (Optional)} + * + * $LastChangedBy: $ + * $LastChangedRevision: $ + * $LastChangedDate: $ + * + * 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 (C) 2009 {Contributing Institution} + * + * 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 + */ +package org.collectionspace.services.client; + +import javax.ws.rs.core.Response; + + +import org.collectionspace.services.authorization.Permission; +import org.collectionspace.services.authorization.PermissionsList; +import org.jboss.resteasy.client.ProxyFactory; +import org.jboss.resteasy.plugins.providers.RegisterBuiltin; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.spi.ResteasyProviderFactory; + +/** + * A PermissionClient. + + * @version $Revision:$ + */ +public class PermissionClient extends AbstractServiceClientImpl { + + /** + * + */ + private PermissionProxy permissionProxy; + + /* (non-Javadoc) + * @see org.collectionspace.services.client.AbstractServiceClientImpl#getServicePathComponent() + */ + public String getServicePathComponent() { + return "authorization/permissions"; + } + + /** + * + * Default constructor for PermissionClient class. + * + */ + public PermissionClient() { + ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance(); + RegisterBuiltin.register(factory); + setProxy(); + } + + /** + * allow to reset proxy as per security needs + */ + public void setProxy() { + if (useAuth()) { + permissionProxy = ProxyFactory.create(PermissionProxy.class, + getBaseURL(), getHttpClient()); + } else { + permissionProxy = ProxyFactory.create(PermissionProxy.class, + getBaseURL()); + } + } + + /** + * @return + * @see org.collectionspace.hello.client.PermissionProxy#readList() + */ + public ClientResponse readList() { + return permissionProxy.readList(); + + } + + public ClientResponse readSearchList(String resourceName) { + return permissionProxy.readSearchList(resourceName); + + } + + /** + * @param csid + * @return + * @see org.collectionspace.hello.client.PermissionProxy#getAccount(java.lang.String) + */ + public ClientResponse read(String csid) { + return permissionProxy.read(csid); + } + + /** + * @param permission + * @return + * @see org.collectionspace.hello.client.PermissionProxy#create(org.collectionspace.services.permission.Permission) + */ + public ClientResponse create(Permission permission) { + return permissionProxy.create(permission); + } + + /** + * @param csid + * @param permission + * @return + * @see org.collectionspace.hello.client.PermissionProxy#updateAccount(java.lang.Long, org.collectionspace.services.permission.Permission) + */ + public ClientResponse update(String csid, Permission permission) { + return permissionProxy.update(csid, permission); + } + + /** + * @param csid + * @return + * @see org.collectionspace.hello.client.PermissionProxy#deleteAccount(java.lang.Long) + */ + public ClientResponse delete(String csid) { + return permissionProxy.delete(csid); + } +} diff --git a/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java new file mode 100644 index 000000000..f096f824b --- /dev/null +++ b/services/authorization-mgt/client/src/main/java/org/collectionspace/services/client/PermissionProxy.java @@ -0,0 +1,79 @@ +/** + * PermissionProxy.java + * + * {Purpose of This Class} + * + * {Other Notes Relating to This Class (Optional)} + * + * $LastChangedBy: $ + * $LastChangedRevision: $ + * $LastChangedDate: $ + * + * 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 (C) 2009 {Contributing Institution} + * + * 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 + */ +package org.collectionspace.services.client; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + + +import org.collectionspace.services.authorization.Permission; +import org.collectionspace.services.authorization.PermissionsList; +import org.jboss.resteasy.client.ClientResponse; + +/** + * @version $Revision:$ + */ +@Path("/authorization/permissions") +@Produces({"application/xml"}) +@Consumes({"application/xml"}) +public interface PermissionProxy { + + @GET + @Produces({"application/xml"}) + ClientResponse readList(); + + @GET + + ClientResponse readSearchList(@QueryParam("res") String resourceName); + + //(C)reate + @POST + ClientResponse create(Permission permission); + + //(R)ead + @GET + @Path("/{csid}") + ClientResponse read(@PathParam("csid") String csid); + + //(U)pdate + @PUT + @Path("/{csid}") + ClientResponse update(@PathParam("csid") String csid, Permission permission); + + //(D)elete + @DELETE + @Path("/{csid}") + ClientResponse delete(@PathParam("csid") String csid); +} diff --git a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java new file mode 100644 index 000000000..3a15e30f4 --- /dev/null +++ b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/PermissionServiceTest.java @@ -0,0 +1,604 @@ +/** + * 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.authorization.client.test; + +import java.util.ArrayList; +import java.util.List; +import javax.ws.rs.core.Response; +import org.collectionspace.services.authorization.ActionType; +import org.collectionspace.services.authorization.EffectType; + +import org.collectionspace.services.client.PermissionClient; +import org.collectionspace.services.authorization.Permission; +import org.collectionspace.services.authorization.PermissionAction; +import org.collectionspace.services.authorization.PermissionsList; +import org.collectionspace.services.client.test.AbstractServiceTestImpl; +import org.collectionspace.services.client.test.ServiceRequestType; +import org.jboss.resteasy.client.ClientResponse; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterClass; + +/** + * PermissionServiceTest, carries out tests against a + * deployed and running Permission Service. + * + * $LastChangedRevision: 917 $ + * $LastChangedDate: 2009-11-06 12:20:28 -0800 (Fri, 06 Nov 2009) $ + */ +public class PermissionServiceTest extends AbstractServiceTestImpl { + + private final Logger logger = + LoggerFactory.getLogger(PermissionServiceTest.class); + // Instance variables specific to this test. + private PermissionClient client = new PermissionClient(); + private String knownResourceId = null; + private List allResourceIdsCreated = new ArrayList(); + boolean addTenant = true; + /* + * This method is called only by the parent class, AbstractServiceTestImpl + */ + + @Override + protected String getServicePathComponent() { + return client.getServicePathComponent(); + } + + // --------------------------------------------------------------- + // CRUD tests : CREATE tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void create(String testName) throws Exception { + + // Perform setup, such as initializing the type of service request + // (e.g. CREATE, DELETE), its valid and expected status codes, and + // its associated HTTP method name (e.g. POST, DELETE). + setupCreate(testName); + + // Submit the request to the service and store the response. + List actions = getDefaultActions(); + Permission permission = createPermissionInstance("accounts", + "default permissions for account", + actions, + EffectType.PERMIT, + true, + true, + true); + ClientResponse res = client.create(permission); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + // + // Specifically: + // Does it fall within the set of valid status codes? + // Does it exactly match the expected status code? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + // Store the ID returned from this create operation + // for additional tests below. + knownResourceId = extractId(res); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": knownResourceId=" + knownResourceId); + } + } + + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void createWithoutResourceName(String testName) throws Exception { + + setupCreate(testName); + + // Submit the request to the service and store the response. + List actions = getDefaultActions(); + Permission permission = createPermissionInstance(null, + "default permissions for account", + actions, + EffectType.PERMIT, + false, + true, + true); + ClientResponse res = client.create(permission); + int statusCode = res.getStatus(); + // Does it exactly match the expected status code? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, Response.Status.BAD_REQUEST.getStatusCode()); + } + + //to not cause uniqueness violation for permission, createList is removed + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void createList(String testName) throws Exception { + + setupCreate(testName); + // Submit the request to the service and store the response. + List actions = getDefaultActions(); + Permission permission1 = createPermissionInstance("collectionobjects", + "default permissions for collectionobjects", + actions, + EffectType.PERMIT, + true, + true, + true); + ClientResponse res = client.create(permission1); + int statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + allResourceIdsCreated.add(extractId(res)); + + Permission permission2 = createPermissionInstance("intakes", + "default permissions for intakes", + actions, + EffectType.PERMIT, + true, + true, + true); + res = client.create(permission2); + statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + allResourceIdsCreated.add(extractId(res)); + + Permission permission3 = createPermissionInstance("ids", + "default permissions for id service", + actions, + EffectType.PERMIT, + true, + true, + true); + res = client.create(permission3); + statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + allResourceIdsCreated.add(extractId(res)); + } + + // Failure outcomes + // Placeholders until the three tests below can be uncommented. + // See Issue CSPACE-401. + @Override + public void createWithEmptyEntityBody(String testName) throws Exception { + } + + @Override + public void createWithMalformedXml(String testName) throws Exception { + } + + @Override + public void createWithWrongXmlSchema(String testName) throws Exception { + } + + // --------------------------------------------------------------- + // CRUD tests : READ tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void read(String testName) throws Exception { + + // Perform setup. + setupRead(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.read(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); + + Permission output = (Permission) res.getEntity(); + Assert.assertNotNull(output); + } + + // Failure outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"read"}) + public void readNonExistent(String testName) throws Exception { + + // Perform setup. + setupReadNonExistent(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.read(NON_EXISTENT_ID); + 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); + } + + // --------------------------------------------------------------- + // CRUD tests : READ_LIST tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"createList", "read"}) + public void readList(String testName) throws Exception { + + // Perform setup. + setupReadList(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.readList(); + PermissionsList list = res.getEntity(); + 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); + + // Optionally output additional data about list members for debugging. + boolean iterateThroughList = true; + if (iterateThroughList && logger.isDebugEnabled()) { + printList(testName, list); + } + } + + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"createList", "read"}) + public void searchResourceName(String testName) throws Exception { + + // Perform setup. + setupReadList(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.readSearchList("intake"); + PermissionsList list = res.getEntity(); + 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); + int EXPECTED_ITEMS = 1; + if (logger.isDebugEnabled()) { + logger.debug(testName + ": received = " + list.getPermissions().size() + + " expected=" + EXPECTED_ITEMS); + } + Assert.assertEquals(EXPECTED_ITEMS, list.getPermissions().size()); + // Optionally output additional data about list members for debugging. + boolean iterateThroughList = true; + if (iterateThroughList && logger.isDebugEnabled()) { + printList(testName, list); + } + } + + // Failure outcomes + // None at present. + // --------------------------------------------------------------- + // CRUD tests : UPDATE tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"read", "readList", "readNonExistent"}) + public void update(String testName) throws Exception { + + // Perform setup. + setupUpdate(testName); + + + ClientResponse res = + client.read(knownResourceId); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": read status = " + res.getStatus()); + } + Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE); + + if (logger.isDebugEnabled()) { + logger.debug("got object to update with ID: " + knownResourceId); + } + Permission toUpdatePermission = + (Permission) res.getEntity(); + Assert.assertNotNull(toUpdatePermission); + + // Update the content of this resource. + toUpdatePermission.setResourceName("updated-" + toUpdatePermission.getResourceName()); + if (logger.isDebugEnabled()) { + logger.debug("updated object"); + logger.debug(objectAsXmlString(toUpdatePermission, + Permission.class)); + } + + // Submit the request to the service and store the response. + res = client.update(knownResourceId, toUpdatePermission); + 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); + + + Permission updatedPermission = (Permission) res.getEntity(); + Assert.assertNotNull(updatedPermission); + + Assert.assertEquals(updatedPermission.getResourceName(), + toUpdatePermission.getResourceName(), + "Data in updated object did not match submitted data."); + } + + // Failure outcomes + // Placeholders until the three tests below can be uncommented. + // See Issue CSPACE-401. + @Override + public void updateWithEmptyEntityBody(String testName) throws Exception { + } + + @Override + public void updateWithMalformedXml(String testName) throws Exception { + } + + @Override + public void updateWithWrongXmlSchema(String testName) throws Exception { + } + + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"readNonExistent", "testSubmitRequest"}) + public void updateNonExistent(String testName) throws Exception { + + // Perform setup. + setupUpdateNonExistent(testName); + + // Submit the request to the service and store the response. + // + // Note: The ID used in this 'create' call may be arbitrary. + // The only relevant ID may be the one used in updatePermission(), below. + List actions = getDefaultActions(); + Permission permission = createPermissionInstance("intakes", + "default permissions for intakes", + actions, + EffectType.PERMIT, + true, + true, + true); + ClientResponse res = + client.update(NON_EXISTENT_ID, permission); + 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); + } + + // --------------------------------------------------------------- + // CRUD tests : DELETE tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"update"}) + public void delete(String testName) throws Exception { + + // Perform setup. + setupDelete(testName); + + // Submit the request to the service and store the response. + 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); + } + + // Failure outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"delete"}) + public void deleteNonExistent(String testName) throws Exception { + + // Perform setup. + setupDeleteNonExistent(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.delete(NON_EXISTENT_ID); + 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 tests : tests of code used in tests above + // --------------------------------------------------------------- + /** + * Tests the code for manually submitting data that is used by several + * of the methods above. + */ + @Test(dependsOnMethods = {"create", "read"}) + public void testSubmitRequest() throws Exception { + + // Expected status code: 200 OK + final int EXPECTED_STATUS = Response.Status.OK.getStatusCode(); + + // Submit the request to the service and store the response. + String method = ServiceRequestType.READ.httpMethodName(); + String url = getResourceURL(knownResourceId); + int statusCode = submitRequest(method, url); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug("testSubmitRequest: url=" + url + + " status=" + statusCode); + } + Assert.assertEquals(statusCode, EXPECTED_STATUS); + + } + + // --------------------------------------------------------------- + // Utility methods used by tests above + // --------------------------------------------------------------- + /** + * create permission instance + * @param resourceName + * @param description + * @param actionList list of actions for this permission + * @param effect effect of the permission + * @param useResourceName + * @param useAction + * @param useEffect + * @return + */ + private Permission createPermissionInstance(String resourceName, + String description, + List actionList, + EffectType effect, + boolean useResourceName, + boolean useAction, + boolean useEffect) { + + Permission permission = new Permission(); + if (useResourceName) { + permission.setResourceName(resourceName); + } + if (useAction) { + permission.setActions(actionList); + } + if (useEffect) { + permission.setEffect(effect); + } + + + if (logger.isDebugEnabled()) { + logger.debug("to be created, permission common"); + logger.debug(objectAsXmlString(permission, Permission.class)); + } + return permission; + } + + private List getDefaultActions() { + List actions = new ArrayList(); + PermissionAction create = new PermissionAction(); + create.setName(ActionType.CREATE); + actions.add(create); + + PermissionAction read = new PermissionAction(); + read.setName(ActionType.READ); + actions.add(read); + + PermissionAction update = new PermissionAction(); + update.setName(ActionType.UPDATE); + actions.add(update); + + PermissionAction delete = new PermissionAction(); + delete.setName(ActionType.DELETE); + actions.add(delete); + + PermissionAction search = new PermissionAction(); + search.setName(ActionType.SEARCH); + actions.add(search); + + return actions; + } + + @AfterClass(alwaysRun = true) + public void cleanUp() { + setupDelete("delete"); + if (logger.isDebugEnabled()) { + logger.debug("Cleaning up temporary resources created for testing ..."); + } + for (String resourceId : allResourceIdsCreated) { + // Note: Any non-success responses are ignored and not reported. + ClientResponse res = client.delete(resourceId); + int statusCode = res.getStatus(); + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + } + + private int printList(String testName, PermissionsList list) { + + int i = 0; + + for (Permission permission : list.getPermissions()) { + logger.debug(testName + " permission csid=" + permission.getCsid() + + " name=" + permission.getResourceName() + + " desc=" + permission.getDescription()); + i++; + } + return i; + } +} diff --git a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java index cda37b7b6..59e085de7 100644 --- a/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java +++ b/services/authorization-mgt/client/src/test/java/org/collectionspace/services/authorization/client/test/RoleServiceTest.java @@ -310,8 +310,8 @@ public class RoleServiceTest extends AbstractServiceTestImpl { Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); int EXPECTED_ITEMS = 1; if (logger.isDebugEnabled()) { - logger.debug(testName + ": received = " + list.getRoles().size() + - " expected=" + EXPECTED_ITEMS); + logger.debug(testName + ": received = " + list.getRoles().size() + + " expected=" + EXPECTED_ITEMS); } Assert.assertEquals(EXPECTED_ITEMS, list.getRoles().size()); // Optionally output additional data about list members for debugging. @@ -428,7 +428,7 @@ public class RoleServiceTest extends AbstractServiceTestImpl { // Success outcomes @Override @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, - dependsOnMethods = {"testSubmitRequest"}) + dependsOnMethods = {"update"}) public void delete(String testName) throws Exception { // Perform setup. @@ -517,7 +517,7 @@ public class RoleServiceTest extends AbstractServiceTestImpl { if (useRoleName) { role.setRoleName(roleName); } - + role.setDescription(description); if (logger.isDebugEnabled()) { logger.debug("to be created, role common"); logger.debug(objectAsXmlString(role, Role.class)); diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java new file mode 100644 index 000000000..37a0f0a33 --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/PermissionResource.java @@ -0,0 +1,302 @@ +/** + * 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 University of California at Berkeley + + * 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.authorization; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.DELETE; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.PathParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; + +import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl; +import org.collectionspace.services.common.context.RemoteServiceContextImpl; +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.BadRequestException; +import org.collectionspace.services.common.document.DocumentFilter; +import org.collectionspace.services.common.document.DocumentNotFoundException; +import org.collectionspace.services.common.document.DocumentHandler; +import org.collectionspace.services.common.security.UnauthorizedException; +import org.collectionspace.services.common.storage.StorageClient; +import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl; +import org.jboss.resteasy.util.HttpResponseCodes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("/authorization/permissions") +@Consumes("application/xml") +@Produces("application/xml") +public class PermissionResource + extends AbstractCollectionSpaceResourceImpl { + + final private String serviceName = "authorization/permissions"; + final Logger logger = LoggerFactory.getLogger(PermissionResource.class); + final StorageClient storageClient = new JpaStorageClientImpl(Permission.class); + + @Override + protected String getVersionString() { + /** The last change revision. */ + final String lastChangeRevision = "$LastChangedRevision: 1165 $"; + return lastChangeRevision; + } + + @Override + public String getServiceName() { + return serviceName; + } + + private ServiceContext createServiceContext(T obj) throws Exception { + ServiceContext ctx = new RemoteServiceContextImpl(getServiceName()); + ctx.setInput(obj); + ctx.setDocumentType(Permission.class.getPackage().getName()); //persistence unit + ctx.setProperty("entity-name", Permission.class.getName()); + return ctx; + } + + @Override + public StorageClient getStorageClient(ServiceContext ctx) { + //FIXME use ctx to identify storage client + return storageClient; + } + + @Override + public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception { + DocumentHandler docHandler = ctx.getDocumentHandler(); + docHandler.setCommonPart(ctx.getInput()); + return docHandler; + } + + @POST + public Response createPermission(Permission input) { + try { + ServiceContext ctx = createServiceContext(input); + DocumentHandler handler = createDocumentHandler(ctx); + String csid = getStorageClient(ctx).create(ctx, handler); + UriBuilder path = UriBuilder.fromResource(PermissionResource.class); + path.path("" + csid); + Response response = Response.created(path.build()).build(); + return response; + } catch (BadRequestException bre) { + Response response = Response.status( + Response.Status.BAD_REQUEST).entity("Create failed reason " + + bre.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Create failed reason " + + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception in createPermission", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity( + "Create failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + } + + @GET + @Path("{csid}") + public Permission getPermission( + @PathParam("csid") String csid) { + if (logger.isDebugEnabled()) { + logger.debug("getPermission with csid=" + csid); + } + if (csid == null || "".equals(csid)) { + logger.error("getPermission: missing csid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "get failed on Permission csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + Permission result = null; + try { + ServiceContext ctx = createServiceContext((Permission) null); + DocumentHandler handler = createDocumentHandler(ctx); + getStorageClient(ctx).get(ctx, csid, handler); + result = (Permission) ctx.getOutput(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Get failed reason " + + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (DocumentNotFoundException dnfe) { + if (logger.isDebugEnabled()) { + logger.debug("getPermission", dnfe); + } + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Get failed on Permission csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("getPermission", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity( + "Get failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + + if (result == null) { + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Get failed, the requested Permission CSID:" + csid + ": was not found.").type( + "text/plain").build(); + throw new WebApplicationException(response); + } + return result; + } + + @GET + @Produces("application/xml") + public PermissionsList getPermissionList( + @Context UriInfo ui) { + PermissionsList permissionList = new PermissionsList(); + try { + ServiceContext ctx = createServiceContext((PermissionsList) null); + DocumentHandler handler = createDocumentHandler(ctx); + MultivaluedMap queryParams = ui.getQueryParameters(); + DocumentFilter myFilter = handler.createDocumentFilter(ctx); + myFilter.setPagination(queryParams); + myFilter.setQueryParams(queryParams); + handler.setDocumentFilter(myFilter); + getStorageClient(ctx).getFiltered(ctx, handler); + permissionList = (PermissionsList) handler.getCommonPartList(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Index failed reason " + + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception in getPermissionsList", e); + } + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity( + "Index failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + return permissionList; + } + + @PUT + @Path("{csid}") + public Permission updatePermission( + @PathParam("csid") String csid, + Permission theUpdate) { + if (logger.isDebugEnabled()) { + logger.debug("updatePermission with csid=" + csid); + } + if (csid == null || "".equals(csid)) { + logger.error("updatePermission: missing csid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "update failed on Permission csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + Permission result = null; + try { + ServiceContext ctx = createServiceContext(theUpdate); + DocumentHandler handler = createDocumentHandler(ctx); + getStorageClient(ctx).update(ctx, csid, handler); + result = (Permission) ctx.getOutput(); + } catch (BadRequestException bre) { + Response response = Response.status( + Response.Status.BAD_REQUEST).entity("Update failed reason " + + bre.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Update failed reason " + + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + } catch (DocumentNotFoundException dnfe) { + if (logger.isDebugEnabled()) { + logger.debug("caugth exception in updatePermission", dnfe); + } + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Update failed on Permission csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity( + "Update failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + return result; + } + + @DELETE + @Path("{csid}") + public Response deletePermission(@PathParam("csid") String csid) { + + if (logger.isDebugEnabled()) { + logger.debug("deletePermission with csid=" + csid); + } + if (csid == null || "".equals(csid)) { + logger.error("deletePermission: missing csid!"); + Response response = Response.status(Response.Status.BAD_REQUEST).entity( + "delete failed on Permission csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } + try { + ServiceContext ctx = createServiceContext((Permission) null); + getStorageClient(ctx).delete(ctx, csid); + return Response.status(HttpResponseCodes.SC_OK).build(); + } catch (UnauthorizedException ue) { + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity("Delete failed reason " + + ue.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); + + } catch (DocumentNotFoundException dnfe) { + if (logger.isDebugEnabled()) { + logger.debug("caught exception in deletePermission", dnfe); + } + Response response = Response.status(Response.Status.NOT_FOUND).entity( + "Delete failed on Permission csid=" + csid).type( + "text/plain").build(); + throw new WebApplicationException(response); + } catch (Exception e) { + Response response = Response.status( + Response.Status.INTERNAL_SERVER_ERROR).entity( + "Delete failed").type("text/plain").build(); + throw new WebApplicationException(response); + } + + } +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java index 67edf0acb..d36d497f5 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/RoleResource.java @@ -266,7 +266,7 @@ public class RoleResource } try { ServiceContext ctx = createServiceContext((Role) null); - getStorageClient(ctx).delete(ctx, csid); + ((JpaStorageClientImpl)getStorageClient(ctx)).deleteWhere(ctx, csid); return Response.status(HttpResponseCodes.SC_OK).build(); } catch (UnauthorizedException ue) { Response response = Response.status( diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java new file mode 100644 index 000000000..cc613fcf8 --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java @@ -0,0 +1,161 @@ +/** + * 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 University of California at Berkeley + + * 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.authorization.storage; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.collectionspace.services.authorization.Permission; +import org.collectionspace.services.authorization.PermissionsList; +import org.collectionspace.services.common.context.ServiceContext; + +import org.collectionspace.services.common.document.AbstractDocumentHandlerImpl; +import org.collectionspace.services.common.document.DocumentFilter; +import org.collectionspace.services.common.document.DocumentWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Document handler for Permission + * @author + */ +public class PermissionDocumentHandler + extends AbstractDocumentHandlerImpl { + + private final Logger logger = LoggerFactory.getLogger(PermissionDocumentHandler.class); + private Permission permission; + private PermissionsList permissionsList; + + @Override + public void handleCreate(DocumentWrapper wrapDoc) throws Exception { + String id = UUID.randomUUID().toString(); + Permission permission = wrapDoc.getWrappedObject(); + permission.setCsid(id); + //FIXME: if admin updating the permission is a CS admin rather than + //the tenant admin, tenant id should be retrieved from the request + permission.setTenantId(getServiceContext().getTenantId()); + } + + @Override + public void handleUpdate(DocumentWrapper wrapDoc) throws Exception { + Permission permission = wrapDoc.getWrappedObject(); + //FIXME: if admin updating the permission is a CS admin rather than + //the tenant admin, tenant id should be retrieved from the request + permission.setTenantId(getServiceContext().getTenantId()); + } + + @Override + public void completeUpdate(DocumentWrapper wrapDoc) throws Exception { + Permission upAcc = wrapDoc.getWrappedObject(); + getServiceContext().setOutput(permission); + sanitize(upAcc); + } + + @Override + public void handleGet(DocumentWrapper wrapDoc) throws Exception { + setCommonPart(extractCommonPart(wrapDoc)); + sanitize(getCommonPart()); + getServiceContext().setOutput(permission); + } + + @Override + public void handleGetAll(DocumentWrapper wrapDoc) throws Exception { + PermissionsList permissionsList = extractCommonPartList(wrapDoc); + setCommonPartList(permissionsList); + getServiceContext().setOutput(getCommonPartList()); + } + + @Override + public Permission extractCommonPart( + DocumentWrapper wrapDoc) + throws Exception { + return wrapDoc.getWrappedObject(); + } + + @Override + public void fillCommonPart(Permission obj, DocumentWrapper wrapDoc) + throws Exception { + throw new UnsupportedOperationException("operation not relevant for AccountDocumentHandler"); + } + + @Override + public PermissionsList extractCommonPartList( + DocumentWrapper wrapDoc) + throws Exception { + + PermissionsList permissionsList = new PermissionsList(); + List list = new ArrayList(); + permissionsList.setPermissions(list); + for (Object obj : wrapDoc.getWrappedObject()) { + Permission permission = (Permission) obj; + sanitize(permission); + list.add(permission); + } + return permissionsList; + } + + @Override + public Permission getCommonPart() { + return permission; + } + + @Override + public void setCommonPart(Permission permission) { + this.permission = permission; + } + + @Override + public PermissionsList getCommonPartList() { + return permissionsList; + } + + @Override + public void setCommonPartList(PermissionsList permissionsList) { + this.permissionsList = permissionsList; + } + + @Override + public String getQProperty( + String prop) { + return null; + } + + @Override + public DocumentFilter createDocumentFilter(ServiceContext ctx) { + DocumentFilter filter = new PermissionJpaFilter(); + filter.setPageSize( + ctx.getServiceBindingPropertyValue( + DocumentFilter.PAGE_SIZE_DEFAULT_PROPERTY)); + return filter; + } + + /** + * sanitize removes data not needed to be sent to the consumer + * @param permission + */ + private void sanitize(Permission permission) { + permission.setTenantId(null); + } +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java new file mode 100644 index 000000000..e5cae5bcd --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java @@ -0,0 +1,76 @@ +/** + * 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 University of California at Berkeley + + * 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.authorization.storage; + +import java.util.ArrayList; +import java.util.List; +import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * PermissionJpaFilter is to build where clause for role queries + * @author + */ +public class PermissionJpaFilter extends JpaDocumentFilter { + + private final Logger logger = LoggerFactory.getLogger(PermissionJpaFilter.class); + + @Override + public List buildWhereForSearch(StringBuilder queryStrBldr) { + + List paramList = new ArrayList(); + boolean hasWhere = false; + //TODO: add tenant id + + String resName = null; + List rn = getQueryParam(PermissionStorageConstants.Q_RESOURCE_NAME); + if (null != rn) { + resName = rn.get(0); + } + if (null != resName && !resName.isEmpty()) { + hasWhere = true; + queryStrBldr.append(" WHERE"); + queryStrBldr.append(" UPPER(a." + PermissionStorageConstants.RESOURCE_NAME + ")"); + queryStrBldr.append(" LIKE"); + queryStrBldr.append(" :" + PermissionStorageConstants.Q_RESOURCE_NAME); + paramList.add(new ParamBinding(PermissionStorageConstants.Q_RESOURCE_NAME, "%" + + resName.toUpperCase() + "%")); + } + + if (logger.isDebugEnabled()) { + String query = queryStrBldr.toString(); + logger.debug("query=" + query); + } + + return paramList; + } + + @Override + public List buildWhere(StringBuilder queryStrBldr) { + return new ArrayList(); + } +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java new file mode 100644 index 000000000..08f7a01e3 --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionStorageConstants.java @@ -0,0 +1,38 @@ +/** + * 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 University of California at Berkeley + + * 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.authorization.storage; + +/** + * PermissionStorageConstants declares query params, etc. + * @author + */ +public class PermissionStorageConstants { + + final public static String Q_RESOURCE_NAME = "res"; + + final public static String RESOURCE_NAME = "resourceName"; + +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java new file mode 100644 index 000000000..05980eb06 --- /dev/null +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionValidatorHandler.java @@ -0,0 +1,80 @@ +/** + * 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 University of California at Berkeley + + * 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.authorization.storage; + +import org.collectionspace.services.authorization.Permission; +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.DocumentHandler.Action; +import org.collectionspace.services.common.document.InvalidDocumentException; +import org.collectionspace.services.common.document.ValidatorHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * PermissionValidatorHandler executes validation rules for permission + * @author + */ +public class PermissionValidatorHandler implements ValidatorHandler { + + final Logger logger = LoggerFactory.getLogger(PermissionValidatorHandler.class); + + @Override + public void validate(Action action, ServiceContext ctx) + throws InvalidDocumentException { + if (logger.isDebugEnabled()) { + logger.debug("validate() action=" + action.name()); + } + try { + Permission permission = (Permission) ctx.getInput(); + StringBuilder msgBldr = new StringBuilder("validate() "); + boolean invalid = false; + + if (action.equals(Action.CREATE)) { + + //create specific validation here + if (permission.getResourceName() == null || permission.getResourceName().isEmpty()) { + invalid = true; + msgBldr.append("\npermissionName : missing"); + } + } else if (action.equals(Action.UPDATE)) { + //update specific validation here + if (permission.getResourceName() != null && permission.getResourceName().isEmpty()) { + invalid = true; + msgBldr.append("\npermissionName : cannot be changed!"); + } + } + if (invalid) { + String msg = msgBldr.toString(); + logger.error(msg); + throw new InvalidDocumentException(msg); + } + } catch (InvalidDocumentException ide) { + throw ide; + } catch (Exception e) { + throw new InvalidDocumentException(e); + } + } + +} diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java index 51c2028f2..7cb44c05d 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java @@ -20,32 +20,6 @@ * 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. - *//** - * 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 University of California at Berkeley - - * 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. - */ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. */ package org.collectionspace.services.authorization.storage; @@ -72,7 +46,7 @@ public class RoleJpaFilter extends JpaDocumentFilter { String roleName = null; List rn = getQueryParam(RoleStorageConstants.Q_ROLE_NAME); - if (rn != null) { + if (null != rn) { roleName = rn.get(0); } if (null != roleName && !roleName.isEmpty()) { diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleStorageConstants.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleStorageConstants.java index 4ee7dfec6..85e40523b 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleStorageConstants.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleStorageConstants.java @@ -20,32 +20,6 @@ * 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. - *//** - * 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 University of California at Berkeley - - * 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. - */ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. */ package org.collectionspace.services.authorization.storage; diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleValidatorHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleValidatorHandler.java index 9686fc617..721650248 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleValidatorHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleValidatorHandler.java @@ -20,28 +20,7 @@ * 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. - *//** - * 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 University of California at Berkeley - - * 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.authorization.storage; diff --git a/services/authorization/jaxb/src/main/resources/permissions.xsd b/services/authorization/jaxb/src/main/resources/permissions.xsd index b63c557d2..94c696b4e 100644 --- a/services/authorization/jaxb/src/main/resources/permissions.xsd +++ b/services/authorization/jaxb/src/main/resources/permissions.xsd @@ -3,7 +3,7 @@ - - - - - - - - - - - permission configuration list - - - - - - + + + @@ -101,6 +101,15 @@ + + + + + + + + + diff --git a/services/authorization/jaxb/src/main/resources/permissions_list.xsd b/services/authorization/jaxb/src/main/resources/permissions_list.xsd new file mode 100644 index 000000000..2a3e51584 --- /dev/null +++ b/services/authorization/jaxb/src/main/resources/permissions_list.xsd @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + permission configuration list + + + + + + + + diff --git a/services/authorization/jaxb/src/main/resources/roles.xsd b/services/authorization/jaxb/src/main/resources/roles.xsd index 32e76eaca..74eaae89d 100644 --- a/services/authorization/jaxb/src/main/resources/roles.xsd +++ b/services/authorization/jaxb/src/main/resources/roles.xsd @@ -3,7 +3,7 @@ + + + + org.collectionspace.services.authorization.storage.PermissionDocumentHandler + + + org.collectionspace.services.authorization.storage.PermissionValidatorHandler + + + + + + + + + + + + + + + + + diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java index d9d11e56d..f865119a7 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java @@ -83,6 +83,7 @@ public class JpaStorageClientImpl implements StorageClient { private final Logger logger = LoggerFactory.getLogger(JpaStorageClientImpl.class); /** The Constant CS_PERSISTENCE_UNIT. */ public final static String CS_PERSISTENCE_UNIT = "org.collectionspace.services"; + private Class entityClazz; /** * Instantiates a new jpa storage client. @@ -90,6 +91,10 @@ public class JpaStorageClientImpl implements StorageClient { public JpaStorageClientImpl() { } + public JpaStorageClientImpl(Class entityClazz) { + this.entityClazz = entityClazz; + } + /* (non-Javadoc) * @see org.collectionspace.services.common.storage.StorageClient#create(org.collectionspace.services.common.context.ServiceContext, org.collectionspace.services.common.document.DocumentHandler) */ @@ -98,11 +103,6 @@ public class JpaStorageClientImpl implements StorageClient { DocumentHandler handler) throws BadRequestException, DocumentException { - String docType = ctx.getDocumentType(); - if (docType == null) { - throw new DocumentNotFoundException( - "Unable to find DocumentType for service " + ctx.getServiceName()); - } if (handler == null) { throw new IllegalArgumentException( "JpaStorageClient.create: handler is missing"); @@ -167,11 +167,6 @@ public class JpaStorageClientImpl implements StorageClient { if (docFilter == null) { docFilter = handler.createDocumentFilter(ctx); } - String docType = ctx.getDocumentType(); - if (docType == null) { - throw new DocumentNotFoundException( - "Unable to find DocumentType for service " + ctx.getServiceName()); - } EntityManagerFactory emf = null; EntityManager em = null; try { @@ -251,12 +246,6 @@ public class JpaStorageClientImpl implements StorageClient { if (docFilter == null) { docFilter = handler.createDocumentFilter(ctx); } - String docType = ctx.getDocumentType(); - if (docType == null) { - throw new DocumentNotFoundException( - "Unable to find DocumentType for service " + ctx.getServiceName()); - } - EntityManagerFactory emf = null; EntityManager em = null; try { @@ -310,11 +299,6 @@ public class JpaStorageClientImpl implements StorageClient { public void update(ServiceContext ctx, String id, DocumentHandler handler) throws BadRequestException, DocumentNotFoundException, DocumentException { - String docType = ctx.getDocumentType(); - if (docType == null) { - throw new DocumentNotFoundException( - "Unable to find DocumentType for service " + ctx.getServiceName()); - } if (handler == null) { throw new IllegalArgumentException( "JpaStorageClient.update: handler is missing"); @@ -365,7 +349,7 @@ public class JpaStorageClientImpl implements StorageClient { } } - /* (non-Javadoc) + /* delete use delete to remove parent entity along with child entities * @see org.collectionspace.services.common.storage.StorageClient#delete(org.collectionspace.services.common.context.ServiceContext, java.lang.String) */ @Override @@ -376,10 +360,60 @@ public class JpaStorageClientImpl implements StorageClient { if (logger.isDebugEnabled()) { logger.debug("deleting entity with id=" + id); } - String docType = ctx.getDocumentType(); - if (docType == null) { - throw new DocumentNotFoundException( - "Unable to find DocumentType for service " + ctx.getServiceName()); + EntityManagerFactory emf = null; + EntityManager em = null; + try { + + //TODO: add tenant id + + emf = getEntityManagerFactory(); + em = emf.createEntityManager(); + + em.getTransaction().begin(); + Object entityFound = getEntity(em, id); + if (entityFound == null) { + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + String msg = "could not find entity with id=" + id; + logger.error(msg); + throw new DocumentNotFoundException(msg); + } + em.remove(entityFound); + em.getTransaction().commit(); + + } catch (DocumentException de) { + throw de; + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception ", e); + } + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + throw new DocumentException(e); + } finally { + if (emf != null) { + releaseEntityManagerFactory(emf); + } + } + } + + /** + * deleteWhere uses the where clause to delete an entity represented by the id + * it does not delete any child entities. + * @param ctx + * @param id + * @throws DocumentNotFoundException + * @throws DocumentException + */ + public void deleteWhere(ServiceContext ctx, String id) + throws DocumentNotFoundException, + DocumentException { + + + if (logger.isDebugEnabled()) { + logger.debug("deleting entity with id=" + id); } EntityManagerFactory emf = null; EntityManager em = null; @@ -563,6 +597,37 @@ public class JpaStorageClientImpl implements StorageClient { return (String) o; } + /** + * getEntity returns persistent entity for given id. it assumes that + * JpaStorageClientImpl is implemented using the JpaStorageClientImpl(entityClazz) + * constructor + * @param em + * @param id + * @return + * @throws DocumentNotFoundException + * @throws UnsupportedOperationException if JpaStorageClientImpl is not implemented + * using the JpaStorageClientImpl(entityClazz) + * constructor + */ + protected Object getEntity(EntityManager em, String id) throws DocumentNotFoundException { + if (entityClazz == null) { + String msg = "Not constructed with JpaStorageClientImpl(entityClazz) ctor"; + logger.error(msg); + throw new UnsupportedOperationException(msg); + } + Object entityFound = em.find(entityClazz, id); + if (entityFound == null) { + if (em != null && em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + String msg = "could not find entity of type=" + entityClazz.getName() + + " with id=" + id; + logger.error(msg); + throw new DocumentNotFoundException(msg); + } + return entityFound; + } + @Override public void get(ServiceContext ctx, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { -- 2.47.3