fullURL = fixupFullURL(fullURL, protoHostPort, uri);
} else if (method.equalsIgnoreCase("DELETE")){
String fromTestID = testNode.valueOf("fromTestID");
- ServiceResult pr = serviceResultsMap.get(fromTestID);
- if (pr!=null){
+ ServiceResult pr = Tools.notBlank(fromTestID) ? serviceResultsMap.get(fromTestID) : null;
+ if (pr != null) {
serviceResult = XmlReplayTransport.doDELETE(pr.deleteURL, authForTest, testIDLabel, fromTestID);
serviceResult.fromTestID = fromTestID;
if (expectedCodes.size()>0){
deleteMethod.setRequestHeader("Accept", "multipart/mixed");
deleteMethod.addRequestHeader("Accept", "application/xml");
deleteMethod.setRequestHeader("Authorization", formatAuth(authForTest));
- deleteMethod.setRequestHeader("X-XmlReplay-fromTestID", fromTestID);
+ if (Tools.notBlank(fromTestID)) {
+ deleteMethod.setRequestHeader("X-XmlReplay-fromTestID", fromTestID);
+ }
int statusCode1 = 0;
String res = "";
try {
<filename>dimension/1.xml</filename>
</test>
<test ID="dimensionBigbirdPUTAfterPermrolesDeleted">
- <expectedCodes>404</expectedCodes>
+ <expectedCodes>403</expectedCodes>
<method>PUT</method>
<uri>/cspace-services/dimensions/${dimension1.CSID}</uri>
<filename>dimension/2-put.xml</filename>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<ns2:role
-xmlns:ns2="http://collectionspace.org/services/authorization">
- <roleName>ROLE_TEST_CM</roleName>
- <description>role for ROLE_TEST_CM</description>
+<ns2:role xmlns:ns2="http://collectionspace.org/services/authorization">
+ <roleName>ROLE_TEST_CM</roleName>
+ <description>role for ROLE_TEST_CM</description>
+ <permission>
+ <permRelationshipId>4381</permRelationshipId>
+ <permissionId>1-vocabularies-RL</permissionId>
+ <resourceName>vocabularies</resourceName>
+ <actionGroup>RL</actionGroup>
+ </permission>
+ <permission>
+ <permRelationshipId>4382</permRelationshipId>
+ <permissionId>1-groups-RL</permissionId>
+ <resourceName>groups</resourceName>
+ <actionGroup>RL</actionGroup>
+ </permission>
+ <permission>
+ <permRelationshipId>4381</permRelationshipId>
+ <permissionId>1-vocabularies-CRUL</permissionId>
+ <resourceName>vocabularies</resourceName>
+ <actionGroup>CRUL</actionGroup>
+ </permission>
+ <permission>
+ <permRelationshipId>4382</permRelationshipId>
+ <permissionId>1-groups-CRUL</permissionId>
+ <resourceName>groups</resourceName>
+ <actionGroup>CRUL</actionGroup>
+ </permission>
</ns2:role>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:role xmlns:ns2="http://collectionspace.org/services/authorization">
- <roleName>ROLE_TEST_INTERN</roleName>
- <description>role for ROLE_TEST_INTERN</description>
+ <roleName>ROLE_TEST_INTERN</roleName>
+ <description>role for ROLE_TEST_INTERN</description>
+ <permission>
+ <permRelationshipId>4381</permRelationshipId>
+ <permissionId>1-vocabularies-RL</permissionId>
+ <resourceName>vocabularies</resourceName>
+ <actionGroup>RL</actionGroup>
+ </permission>
+ <permission>
+ <permRelationshipId>4382</permRelationshipId>
+ <permissionId>1-groups-RL</permissionId>
+ <resourceName>groups</resourceName>
+ <actionGroup>RL</actionGroup>
+ </permission>
</ns2:role>
RoleClient roleClient = new RoleClient();
Role role = RoleFactory.createRoleInstance(roleName,
roleName, //the display name
- "role for " + roleName, true);
+ "role for " + roleName, true, RoleFactory.EMPTY_PERMVALUE_LIST);
setupCreate();
Response res = roleClient.create(role);
try {
<artifactId>org.collectionspace.services.authorization.jaxb</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.collectionspace.services</groupId>
+ <artifactId>org.collectionspace.services.hyperjaxb</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.collectionspace.services</groupId>
<artifactId>org.collectionspace.services.client</artifactId>
import java.util.List;
import javax.ws.rs.core.Response;
-
import org.apache.http.HttpStatus;
+
import org.collectionspace.services.authorization.perms.ActionType;
import org.collectionspace.services.authorization.perms.Permission;
import org.collectionspace.services.authorization.perms.PermissionAction;
public Response readSearchList(String resourceName) {
return getProxy().readSearchList(resourceName);
-
}
/**
public Response read(String csid) {
return getProxy().read(csid);
}
+
+ /*
+ * We expect a single result. An resourceName/actionGroup tuple should uniquely identify the permission resource
+ */
+ public Permission read(String resourceName, String actionGroup) {
+ Permission result = null;
+
+ Response res = getProxy().read(resourceName, actionGroup);
+ try {
+ if (res != null && res.getStatus() == Response.Status.OK.getStatusCode()) {
+ PermissionsList permsListElement = res.readEntity(PermissionsList.class);
+ if (permsListElement != null && permsListElement.getPermission() != null) {
+ List<Permission> permsList = permsListElement.getPermission();
+ if (permsList.size() == 1) {
+ result = permsList.get(0);
+ }
+ }
+ }
+ } finally {
+ res.close();
+ }
+
+ return result;
+ }
/**
* @param permission
@Consumes({"application/xml"})
public interface PermissionProxy extends CollectionSpaceProxy<PermissionsList> {
- @GET
+ @Override
+ @GET
@Produces({"application/xml"})
Response readList();
@GET
@Path("/{csid}")
Response read(@PathParam("csid") String csid);
-
+
+ //(R)read
+ @GET
+ Response read(@QueryParam("res") String resourceName, @QueryParam("actGrp") String actionGroup);
+
//(U)pdate
@PUT
@Path("/{csid}")
import org.collectionspace.services.authorization.PermissionRole;
import org.collectionspace.services.authorization.PermissionValue;
import org.collectionspace.services.authorization.RoleValue;
+import org.collectionspace.services.authorization.SubjectType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
boolean useRoleId) {
PermissionRole permRole = new PermissionRole();
- //service consume is not required to provide subject as it is determined
- //from URI used
-// permRole.setSubject(SubjectType.ROLE);
if (useRoleId) {
ArrayList<RoleValue> rvs = new ArrayList<RoleValue>();
rvs.add(rv);
permRole.setRole(rvs);
}
+
if (usePermId) {
permRole.setPermission(pvs);
}
return permRole;
}
+
+ public static PermissionRole createPermissionRoleInstance(SubjectType subjectType,
+ RoleValue rv,
+ List<PermissionValue> pvs,
+ boolean usePermId,
+ boolean useRoleId) {
+
+ PermissionRole permRole = createPermissionRoleInstance(rv, pvs, usePermId, useRoleId);
+ permRole.setSubject(subjectType);
+ return permRole;
+ }
+
}
package org.collectionspace.services.client;
+import java.util.List;
+
+import org.collectionspace.services.authorization.PermissionValue;
import org.collectionspace.services.authorization.Role;
+import org.collectionspace.services.authorization.RoleValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RoleFactory {
static private final Logger logger = LoggerFactory.getLogger(RoleFactory.class);
+
+ public static final List<PermissionValue> EMPTY_PERMVALUE_LIST = null;
+
/**
* create role instance
* @param roleName
public static Role createRoleInstance(String roleName,
String displayName,
String description,
- boolean useRoleName) {
+ boolean useRoleName,
+ List<PermissionValue> permValueList) {
Role role = new Role();
if (useRoleName == true) {
}
role.setDisplayName(displayName);
role.setDescription(description);
+ role.setPermission(permValueList);
+
return role;
}
+
+ public static RoleValue createRoleValueInstance(Role role) {
+ RoleValue result = new RoleValue();
+
+ result.setDisplayName(role.getDisplayName());
+ result.setRoleId(role.getCsid());
+ result.setRoleName(role.getRoleName());
+ result.setTenantId(role.getTenantId());
+
+ return result;
+ }
}
Role role = RoleFactory.createRoleInstance(roleName,
roleName, //the display name
- "role for " + roleName, true);
+ "role for " + roleName, true, RoleFactory.EMPTY_PERMVALUE_LIST);
Response res = null;
String id = null;
try {
Role role = RoleFactory.createRoleInstance(roleName,
roleName, //the display name
- "role for " + roleName, true);
+ "role for " + roleName, true, RoleFactory.EMPTY_PERMVALUE_LIST);
role.setRoleGroup("something");
Response res = null;
String id = null;
*/
package org.collectionspace.services.authorization.client.test;
-//import java.util.ArrayList;
-//import java.util.List;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
-
import javax.ws.rs.core.Response;
import org.collectionspace.services.client.CollectionSpaceClient;
+import org.collectionspace.services.client.PermissionClient;
import org.collectionspace.services.client.RoleClient;
+import org.collectionspace.services.authorization.PermissionValue;
import org.collectionspace.services.authorization.Role;
import org.collectionspace.services.authorization.RolesList;
+import org.collectionspace.services.authorization.perms.Permission;
import org.collectionspace.services.client.RoleFactory;
import org.collectionspace.services.client.test.AbstractServiceTestImpl;
+
import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// Used to create unique identifiers
static private final Random random = new Random(System.currentTimeMillis());
+
+ private static final String PERM_1_RL_RESOURCE = "ROLE_TEST_PERMVALUE_RESOURCE_1";
+ private static final String PERM_1_RL_ACTIONGROUP = "RL";
+ private static final String PERM_2_RL_RESOURCE = "ROLE_TEST_PERMVALUE_RESOURCE_2";
+ private static final String PERM_2_RL_ACTIONGROUP = "CRUL";
+ private static final String PERM_3_RL_RESOURCE = "ROLE_TEST_PERMVALUE_RESOURCE_3";
+ private static final String PERM_3_RL_ACTIONGROUP = "CRUDL";
+
// Instance variables specific to this test.
/** The known resource id. */
private String knownRoleDisplayName = "ROLE_DISPLAYNAME_USERS_MOCK-1";
private String verifyResourceId = null;
private String verifyRoleName = "collections_manager_mock-1";
-// private List<String> allResourceIdsCreated = new ArrayList<String>();
+ //
+ // Permission values
+ //
+ private List<PermissionValue> permissionValues = RoleFactory.EMPTY_PERMVALUE_LIST;
@Override
public String getServiceName() {
@Override
protected CollectionSpaceClient getClientInstance(String clientPropertiesFilename) throws Exception {
return new RoleClient(clientPropertiesFilename);
- }
+ }
+
+ /**
+ * Seed data.
+ * @throws Exception
+ */
+ @BeforeClass(alwaysRun = true)
+ public void seedData() throws Exception {
+ permissionValues = new ArrayList<PermissionValue>();
+ permissionValues.add(createPermissionValueInstance(PERM_1_RL_RESOURCE, PERM_1_RL_ACTIONGROUP));
+ permissionValues.add(createPermissionValueInstance(PERM_2_RL_RESOURCE, PERM_2_RL_ACTIONGROUP));
+ permissionValues.add(createPermissionValueInstance(PERM_3_RL_RESOURCE, PERM_3_RL_ACTIONGROUP));
+ }
- /* (non-Javadoc)
+ private PermissionValue createPermissionValueInstance(String resource, String actionGroup) {
+ PermissionValue permValue = new PermissionValue();
+ permValue.setResourceName(resource);
+ permValue.setActionGroup(actionGroup);
+ return permValue;
+ }
+
+ /**
+ * Clean up.
+ * @throws Exception
+ */
+ @AfterClass(alwaysRun = true)
+ @Override
+ public void cleanUp() throws Exception {
+ String noTest = System.getProperty("noTestCleanup");
+ if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Skipping Cleanup phase ...");
+ }
+ return;
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("Cleaning up temporary resources created for testing ...");
+ }
+ //
+ // Delete the permissions we indirectly created with when we created via the "createRoleWithPerms()" test
+ //
+ for (PermissionValue pv : permissionValues) {
+ deletePermission(pv);
+ }
+
+ //
+ // Call our parent cleanup method.
+ //
+ super.cleanUp();
+ }
+
+
+ /*
+ * Use a resource name and action group value to find and delete a permission record/resource.
+ */
+ private void deletePermission(PermissionValue permissionValue) throws Exception {
+ int statusCode = Response.Status.OK.getStatusCode();
+ PermissionClient client = new PermissionClient();
+ Permission permission = client.read(permissionValue.getResourceName(), permissionValue.getActionGroup());
+ if (permission != null) {
+ Response res = client.delete(permission.getCsid());
+ try {
+ statusCode = res.getStatus();
+ } finally {
+ res.close();
+ }
+ } else {
+ //
+ // Something bad happened.
+ //
+ statusCode = Response.Status.BAD_REQUEST.getStatusCode();
+ }
+
+ if (statusCode != Response.Status.OK.getStatusCode()) {
+ String msg = String.format("Could not delete test Permission record: resource name='%s', actionGroup='%s'.",
+ permissionValue.getResourceName(), permissionValue.getActionGroup());
+ logger.error(msg);
+ }
+ }
+
+ /* (non-Javadoc)
* @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readPaginatedList(java.lang.String)
*/
@Override
// Submit the request to the service and store the response.
RoleClient client = new RoleClient();
Role role = createRoleInstance(knownRoleName, "All users are required to be in this role",
- true);
+ true, RoleFactory.EMPTY_PERMVALUE_LIST);
Response res = client.create(role);
try {
int statusCode = res.getStatus();
}
}
+ @Test(dataProvider = "testName",
+ dependsOnMethods = {"CRUDTests"})
+ public void createRoleWithPerms(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();
+
+ // Submit the request to the service and store the response.
+ RoleClient client = new RoleClient();
+ Role role = createRoleInstance("CREATE_ROLE_WITH_PERMS" + System.currentTimeMillis(), "A role created with perms.",
+ true, permissionValues);
+ Response res = client.create(role);
+ try {
+ 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(testRequestType.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(testRequestType, statusCode));
+ Assert.assertEquals(statusCode, testExpectedStatusCode);
+
+ // Store the ID returned from this create operation
+ // for additional tests below.
+ String csid = extractId(res);
+ allResourceIdsCreated.add(csid);
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + ": role with perms ID=" + csid);
+ }
+ } finally {
+ res.close();
+ }
+ }
+
+ @Test(dataProvider = "testName",
+ dependsOnMethods = {"CRUDTests"})
+ public void createDupliateRole(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).
+ setupDuplicate();
+
+ // Submit the request to the service and store the response.
+ RoleClient client = new RoleClient();
+ Role role = createRoleInstance(knownRoleName, "This is a duplicate of an existing role.",
+ true, RoleFactory.EMPTY_PERMVALUE_LIST);
+ Response res = client.create(role);
+ try {
+ int statusCode = res.getStatus();
+ if (statusCode == 201) {
+ // We expected NOT to create a new role, so if we did then we need to keep track of it and eventually delete it.
+ String duplicateRole = extractId(res);
+ allResourceIdsCreated.add(duplicateRole);
+ }
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ //
+ // Specifically:
+ // Does it exactly match the expected status code?
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + ": status = " + statusCode);
+ }
+ Assert.assertEquals(statusCode, testExpectedStatusCode);
+
+ } finally {
+ res.close();
+ }
+ }
+
@Test(dataProvider = "testName",
dependsOnMethods = {"CRUDTests"})
public void createWithDisplayname(String testName) throws Exception {
*/
public Role createRoleInstance(String roleName,
String description,
- boolean useRoleName) {
+ boolean useRoleName,
+ List<PermissionValue> permValueList) {
Role role = RoleFactory.createRoleInstance(roleName,
roleName, //the display name
description,
- useRoleName);
+ useRoleName,
+ permValueList);
+
if (logger.isDebugEnabled()) {
logger.debug("to be created, role");
org.collectionspace.services.authorization.ObjectFactory objectFactory = new org.collectionspace.services.authorization.ObjectFactory();
logger.debug(objectAsXmlString(objectFactory.createRole(role),
Role.class));
}
+
return role;
-
}
-
+
+ public Role createRoleInstance(String roleName,
+ String description,
+ boolean useRoleName) {
+ return this.createRoleInstance(roleName, description, useRoleName, RoleFactory.EMPTY_PERMVALUE_LIST);
+ }
+
/**
* Prints the list.
*
import java.util.List;
import java.util.UUID;
+import org.collectionspace.services.authorization.PermissionRole;
+import org.collectionspace.services.authorization.PermissionRoleSubResource;
+import org.collectionspace.services.authorization.PermissionValue;
import org.collectionspace.services.authorization.Role;
+import org.collectionspace.services.authorization.RoleValue;
import org.collectionspace.services.authorization.RolesList;
+import org.collectionspace.services.authorization.SubjectType;
+import org.collectionspace.services.client.PermissionRoleFactory;
import org.collectionspace.services.client.RoleClient;
+import org.collectionspace.services.client.RoleFactory;
+
import org.collectionspace.services.common.document.BadRequestException;
import org.collectionspace.services.common.document.DocumentFilter;
import org.collectionspace.services.common.document.DocumentWrapper;
role.setMetadataProtection(null);
role.setPermsProtection(null);
}
+
+ @Override
+ public void completeCreate(DocumentWrapper<Role> wrapDoc) throws Exception {
+ Role role = wrapDoc.getWrappedObject();
+ List<PermissionValue> permValueList = role.getPermission();
+ if (permValueList != null && permValueList.size() > 0) {
+ // create and persist a permrole instance
+ // The caller of this method needs to ensure a valid and active EM (EntityManager) instance is in the Service context
+ RoleValue roleValue = RoleFactory.createRoleValueInstance(role);
+ PermissionRole permRole = PermissionRoleFactory.createPermissionRoleInstance(SubjectType.PERMISSION, roleValue,
+ permValueList, true, true);
+ PermissionRoleSubResource subResource =
+ new PermissionRoleSubResource(PermissionRoleSubResource.ROLE_PERMROLE_SERVICE);
+ String permrolecsid = subResource.createPermissionRole(permRole, SubjectType.PERMISSION);
+ }
+ }
@Override
public void handleUpdate(DocumentWrapper<Role> wrapDoc) throws Exception {
jaxb:extensionBindingPrefixes="hj orm xjc"
>
+ <xs:include schemaLocation="authorization_common.xsd"/>
+
<!--
see http://weblogs.java.net/blog/2006/03/03/why-does-jaxb-put-xmlrootelement-sometimes-not-always
for more details behind xjc:simple
</xs:appinfo>
</xs:annotation>
</xs:element>
- <xs:element name="metadataProtection" type="xs:string" minOccurs="0" maxOccurs="1">
- <xs:annotation>
- <xs:appinfo>
- <hj:basic>
- <orm:column name="metadata_protection" nullable="true"/>
- </hj:basic>
- </xs:appinfo>
- </xs:annotation>
- </xs:element>
- <xs:element name="permsProtection" type="xs:string" minOccurs="0" maxOccurs="1">
- <xs:annotation>
- <xs:appinfo>
- <hj:basic>
- <orm:column name="perms_protection" nullable="true"/>
- </hj:basic>
- </xs:appinfo>
- </xs:annotation>
- </xs:element>
+ <xs:element name="metadataProtection" type="xs:string" minOccurs="0" maxOccurs="1">
+ <xs:annotation>
+ <xs:appinfo>
+ <hj:basic>
+ <orm:column name="metadata_protection" nullable="true"/>
+ </hj:basic>
+ </xs:appinfo>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="permsProtection" type="xs:string" minOccurs="0" maxOccurs="1">
+ <xs:annotation>
+ <xs:appinfo>
+ <hj:basic>
+ <orm:column name="perms_protection" nullable="true"/>
+ </hj:basic>
+ </xs:appinfo>
+ </xs:annotation>
+ </xs:element>
<xs:element name="createdAt" type="xs:dateTime">
<xs:annotation>
<xs:appinfo>
</xs:appinfo>
</xs:annotation>
</xs:element>
+ <xs:element name="permission" type="ns:permission_value" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="csid" type="xs:string">
<xs:annotation>
</xs:appinfo>
</xs:annotation>
</xs:attribute>
+
</xs:complexType>
</xs:schema>
testSetup(testExpectedStatusCode, testRequestType);
}
+ /**
+ * Sets up create duplicate request.
+ */
+ protected void setupDuplicate() {
+ testExpectedStatusCode = STATUS_BAD_REQUEST;
+ testRequestType = ServiceRequestType.CREATE;
+ testSetup(testExpectedStatusCode, testRequestType);
+ }
+
/**
* Initializes setup values for a given test.
*
import java.util.ArrayList;
import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.NoResultException;
+
import org.collectionspace.services.authorization.PermissionRole;
import org.collectionspace.services.authorization.PermissionRoleRel;
import org.collectionspace.services.authorization.PermissionValue;
import org.collectionspace.services.authorization.PermissionsRolesList;
import org.collectionspace.services.authorization.RoleValue;
import org.collectionspace.services.authorization.SubjectType;
-
+import org.collectionspace.services.authorization.perms.Permission;
import org.collectionspace.services.common.authorization_mgt.AuthorizationRoleRel;
import org.collectionspace.services.common.authorization_mgt.PermissionRoleUtil;
import org.collectionspace.services.common.document.DocumentFilter;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter;
import org.collectionspace.services.common.storage.jpa.JpaDocumentHandler;
+import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
public void handleCreate(DocumentWrapper<List<PermissionRoleRel>> wrapDoc) throws Exception {
fillCommonPart(getCommonPart(), wrapDoc);
+ filterOutExisting(wrapDoc);
+ }
+
+ private boolean permRoleRelExists(EntityManager em, PermissionRoleRel permRoleRel) {
+ boolean result = false;
+
+ PermissionRoleRel queryResult = null;
+ try {
+ queryResult = (PermissionRoleRel) JpaStorageUtils.getEntityByDualKeys(em,
+ PermissionRoleRel.class.getName(),
+ PermissionStorageConstants.PERMREL_ROLE_ID, permRoleRel.getRoleId(),
+ PermissionStorageConstants.PERMREL_PERM_ID, permRoleRel.getPermissionId());
+ } catch (NoResultException e) {
+ // Ignore exception. Just means the permission hasn't been stored/persisted yet.
+ }
+
+ if (queryResult != null) {
+ result = true;
+ }
+
+ return result;
+ }
+
+ /**
+ * Find the existing (already persisted)
+ * @param wrapDoc
+ * @throws Exception
+ */
+ private void filterOutExisting(DocumentWrapper<List<PermissionRoleRel>> wrapDoc) throws Exception {
+ List<PermissionRoleRel> permRoleRelList = wrapDoc.getWrappedObject();
+
+ EntityManagerFactory emf = null;
+ EntityManager em = null;
+ try {
+ emf = JpaStorageUtils.getEntityManagerFactory(JpaStorageUtils.CS_PERSISTENCE_UNIT);
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+
+ for (PermissionRoleRel permRoleRel : permRoleRelList) {
+ if (permRoleRelExists(em, permRoleRel) == true) {
+ //
+ // Remove the item from the list since it already exists
+ //
+ permRoleRelList.remove(permRoleRel);
+ }
+ }
+
+ em.getTransaction().commit();
+ em.close();
+ } catch (Exception e) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("Caught exception ", e);
+ }
+ throw e;
+ } finally {
+ if (em != null) {
+ JpaStorageUtils.releaseEntityManagerFactory(emf);
+ }
+ }
+
}
/* (non-Javadoc)
final public static String RESOURCE_NAME = "resourceName";
final public static String ACTION_GROUP = "actionGroup";
+ public static final String PERMREL_ROLE_ID = "roleId";
+ public static final String PERMREL_PERM_ID = "permissionId";
}
}
}
+ //
+ // Since our permissionValue may not have been supplied by the client with an ID, we need
+ // to add it now.
+ //
+ if (permissionValue.getPermissionId() == null || permissionValue.getPermissionId().trim().isEmpty()) {
+ permissionValue.setPermissionId(permission.getCsid());
+ }
+
//
// Create the permission-role to persist
//
import org.collectionspace.services.common.ServiceMain;
import org.collectionspace.services.common.config.ConfigUtils;
import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
+import org.collectionspace.services.common.document.TransactionException;
import org.collectionspace.services.common.security.UnauthorizedException;
+import org.collectionspace.services.common.storage.StorageClient;
+import org.collectionspace.services.common.storage.TransactionContext;
+import org.collectionspace.services.common.storage.jpa.JPATransactionContext;
import org.collectionspace.services.config.service.ServiceBindingType;
import org.collectionspace.services.config.tenant.TenantBindingType;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// TODO Auto-generated method stub
throw new RuntimeException("Unimplemented method.");
}
+
+ //
+ // Transaction management methods
+ //
+
+ private TransactionContext getCurrentTransactionContext() {
+ return (TransactionContext) this.getProperty(StorageClient.SC_TRANSACTION_CONTEXT_KEY);
+ }
+
+ @Override
+ public void releaseConnection() throws TransactionException {
+ if (isTransactionContextShared() == true) {
+ throw new TransactionException("Attempted to release a shared storage connection. Only the originator can release the connection");
+ }
+
+ TransactionContext transactionCtx = getCurrentTransactionContext();
+ if (transactionCtx != null) {
+ transactionCtx.close();
+ this.setProperty(StorageClient.SC_TRANSACTION_CONTEXT_KEY, null);
+ } else {
+ throw new TransactionException("Attempted to release a non-existent storage connection. Transaction context missing from service context.");
+ }
+ }
+
+ @Override
+ public TransactionContext openConnection() throws TransactionException {
+ TransactionContext result = getCurrentTransactionContext();
+ if (result != null) {
+ throw new TransactionException("Attempted to open a new connection when a current connection is still part of the current service context. The current connection must be closed with the releaseConnection() method.");
+ }
+
+ result = new JPATransactionContext(this);
+ this.setProperty(StorageClient.SC_TRANSACTION_CONTEXT_KEY, result);
+
+ return result;
+ }
+
+ @Override
+ public void setTransactionContext(TransactionContext transactionCtx) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * Returns true if the TransactionContext is shared with another ServiceContext instance
+ * @throws TransactionException
+ */
+ @Override
+ public boolean isTransactionContextShared() throws TransactionException {
+ boolean result = true;
+
+ TransactionContext transactionCtx = getCurrentTransactionContext();
+ if (transactionCtx != null) {
+ if (transactionCtx.getServiceContext() == this) { // check to see if the service context used to create the connection is the same as the current service context
+ result = false;
+ }
+ } else {
+ throw new TransactionException("Transaction context missing from service context.");
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean hasActiveConnection() {
+ return getCurrentTransactionContext() != null;
+ }
}
import org.collectionspace.services.common.CollectionSpaceResource;
import org.collectionspace.services.common.ResourceMap;
import org.collectionspace.services.common.document.DocumentHandler;
+import org.collectionspace.services.common.document.TransactionException;
import org.collectionspace.services.common.document.ValidatorHandler;
import org.collectionspace.services.common.security.SecurityContext;
+import org.collectionspace.services.common.storage.TransactionContext;
+import org.collectionspace.services.common.storage.jpa.JPATransactionContext;
import org.collectionspace.services.config.ClientType;
import org.collectionspace.services.config.service.ObjectPartType;
import org.collectionspace.services.config.service.ServiceBindingType;
* @return The JAX-RS request information
*/
Request getRequestInfo();
+
+ /**
+ *
+ */
+ public TransactionContext openConnection() throws TransactionException; // Only 1 active connection at a time
+
+ /**
+ *
+ */
+ public boolean hasActiveConnection();
+
+ /**
+ *
+ */
+ public void releaseConnection() throws TransactionException; // Assumes there's been a call to getConnection.
+
+ /**
+ *
+ */
+ public void setTransactionContext(TransactionContext transactionCtx); // For sharing a transaction context with another service context.
+
+ /**
+ *
+ */
+ public boolean isTransactionContextShared() throws TransactionException;
}
*/
public interface StorageClient {
+ public static final String SC_TRANSACTION_CONTEXT_KEY = "SC_ACTIVE_TRANSACTION_KEY";
+
/**
* create entity in the persistence store
* @param ctx service context under which this method is invoked
--- /dev/null
+package org.collectionspace.services.common.storage;
+
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.TransactionException;
+
+@SuppressWarnings("rawtypes")
+public abstract class TransactionContext {
+
+ protected ServiceContext ctx;
+
+ public ServiceContext getServiceContext() {
+ // TODO Auto-generated method stub
+ return ctx;
+ }
+
+ abstract public void markForRollback();
+
+ abstract public void close() throws TransactionException;
+
+ abstract public void beginTransaction() throws TransactionException;
+
+ abstract public void commitTransaction() throws TransactionException;
+
+ abstract public boolean isTransactionActive() throws TransactionException;
+}
--- /dev/null
+package org.collectionspace.services.common.storage.jpa;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.TransactionException;
+import org.collectionspace.services.common.storage.TransactionContext;
+
+@SuppressWarnings("rawtypes")
+public class JPATransactionContext extends TransactionContext {
+ EntityManagerFactory emf;
+ EntityManager em;
+
+ @SuppressWarnings("unused")
+ private JPATransactionContext() {
+ // Don't allow anyone to create an empty instance
+ }
+
+ public JPATransactionContext(ServiceContext ctx) {
+ emf = JpaStorageUtils.getEntityManagerFactory();
+ em = emf.createEntityManager();
+ this.ctx = ctx;
+ }
+
+ protected EntityManagerFactory getEntityManagerFactory() {
+ return emf;
+ }
+
+ protected EntityManager getEntityManager() {
+ return em;
+ }
+
+ @Override
+ public ServiceContext getServiceContext() {
+ return ctx;
+ }
+
+ @Override
+ public void markForRollback() {
+ em.getTransaction().setRollbackOnly();
+ }
+
+ @Override
+ public void close() throws TransactionException {
+ if (em.getTransaction().isActive() == true && em.getTransaction().getRollbackOnly() == true) {
+ em.getTransaction().rollback();
+ } else if (em.getTransaction().isActive() == true) {
+ throw new JPATransactionException("There is an active transaction. You must commit the active transaction prior to calling this close method.");
+ }
+
+ em.close();
+ JpaStorageUtils.releaseEntityManagerFactory(emf);
+ }
+
+ @Override
+ public void beginTransaction() {
+ em.getTransaction().begin();
+ }
+
+ @Override
+ public void commitTransaction() {
+ em.getTransaction().commit();
+ }
+
+ @Override
+ public boolean isTransactionActive() {
+ return em.getTransaction().isActive();
+ }
+}
--- /dev/null
+package org.collectionspace.services.common.storage.jpa;
+
+import org.collectionspace.services.common.document.TransactionException;
+
+public class JPATransactionException extends TransactionException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2018758347488796620L;
+
+ public JPATransactionException(String msg) {
+ super(msg);
+ }
+}
} catch (EntityExistsException ee) {
//
// We found an existing matching entity in the store, so we don't need to create one. Just update the transient 'entity' instance with the existing persisted entity we found.
+ // An entity's document handler class will throw this exception only if attempting to create (but not actually creating) duplicate is ok -e.g., Permission records.
//
entity = wrapDoc.getWrappedObject(); // the handler should have reset the wrapped transient object with the existing persisted entity we just found.
}
Role role = RoleFactory.createRoleInstance(roleName, roleName, // the
// display
// name
- "role for " + roleName, true);
+ "role for " + roleName, true, RoleFactory.EMPTY_PERMVALUE_LIST);
Response res = roleClient.create(role);
try {
assertStatusCode(res, "CreateRole");
roleClient.setAuth(true, ui.userName, true, ui.password, true);
Role role = RoleFactory.createRoleInstance(roleName,
roleName, //the display name
- "role for " + roleName, true);
+ "role for " + roleName, true, RoleFactory.EMPTY_PERMVALUE_LIST);
role.setTenantId(tenantId);
Response res = roleClient.create(role);
try {