final public static String ROLE_TENANT_ADMINISTRATOR = "TENANT_ADMINISTRATOR";
final public static String ROLE_TENANT_READER = "TENANT_READER";
final public static String ROLE_ADMINISTRATOR_ID = "0";
+ final public static String ADMINISTRATOR_TENANT_ID = "0";
//
// ActionGroup labels/constants
//
final public static String ACTIONGROUP_CRUDL = "CRUDL";
final public static String ACTIONGROUP_RL = "RL";
+ //
+ // Should the base resource act as a proxy for its sub-resources for AuthZ purposes
+ //
+ final public static boolean AUTHZ_IS_ENTITY_PROXY = false;
final Logger logger = LoggerFactory.getLogger(AuthorizationGen.class);
private List<Permission> adminPermList = new ArrayList<Permission>();
*/
public void createDefaultPermissions() {
for (String tenantId : tenantBindings.keySet()) {
- List<Permission> adminPerms = createDefaultAdminPermissions(tenantId);
+ List<Permission> adminPerms = createDefaultAdminPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY);
adminPermList.addAll(adminPerms);
- List<Permission> readerPerms = createDefaultReaderPermissions(tenantId);
+ List<Permission> readerPerms = createDefaultReaderPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY);
readerPermList.addAll(readerPerms);
}
}
* @param tenantId
* @return
*/
- public List<Permission> createDefaultAdminPermissions(String tenantId) {
+ public List<Permission> createDefaultAdminPermissions(String tenantId, boolean isEntityProxy) {
ArrayList<Permission> apcList = new ArrayList<Permission>();
TenantBindingType tbinding = tenantBindings.get(tenantId);
for (ServiceBindingType sbinding : tbinding.getServiceBindings()) {
//add permissions for the main path
String resourceName = sbinding.getName().toLowerCase().trim();
- if (SecurityUtils.isEntityProxy() == true) {
+ if (isEntityProxy == true) {
resourceName = SecurityUtils.getResourceEntity(resourceName);
}
Permission perm = buildAdminPermission(tbinding.getId(),
apcList.add(perm);
//add permissions for alternate paths
- if (SecurityUtils.isEntityProxy() == false) {
+ if (isEntityProxy == false) {
List<String> uriPaths = sbinding.getUriPath();
for (String uriPath : uriPaths) {
perm = buildAdminPermission(tbinding.getId(),
* @param tenantId
* @return
*/
- public List<Permission> createDefaultReaderPermissions(String tenantId) {
+ public List<Permission> createDefaultReaderPermissions(String tenantId, boolean isEntityProxy) {
ArrayList<Permission> apcList = new ArrayList<Permission>();
TenantBindingType tbinding = tenantBindings.get(tenantId);
for (ServiceBindingType sbinding : tbinding.getServiceBindings()) {
//add permissions for the main path
String resourceName = sbinding.getName().toLowerCase().trim();
- if (SecurityUtils.isEntityProxy() == true) {
+ if (isEntityProxy == true) {
resourceName = SecurityUtils.getResourceEntity(resourceName);
}
Permission perm = buildReaderPermission(tbinding.getId(),
apcList.add(perm);
//add permissions for alternate paths
- if (SecurityUtils.isEntityProxy() == false) {
+ if (isEntityProxy == false) {
List<String> uriPaths = sbinding.getUriPath();
for (String uriPath : uriPaths) {
perm = buildReaderPermission(tbinding.getId(),
public void associateDefaultPermissionsRoles() {
for (Permission p : adminPermList) {
- PermissionRole permAdmRole = associatePermissionRoles(p, adminRoles);
+ PermissionRole permAdmRole = associatePermissionRoles(p, adminRoles, true);
adminPermRoleList.add(permAdmRole);
}
for (Permission p : readerPermList) {
- PermissionRole permRdrRole = associatePermissionRoles(p, readerRoles);
+ PermissionRole permRdrRole = associatePermissionRoles(p, readerRoles, true);
readerPermRoleList.add(permRdrRole);
}
List<Role> roles = new ArrayList<Role>();
roles.add(cspaceAdminRole);
for (Permission p : adminPermList) {
- PermissionRole permCAdmRole = associatePermissionRoles(p, roles);
+ PermissionRole permCAdmRole = associatePermissionRoles(p, roles, false);
adminPermRoleList.add(permCAdmRole);
}
}
- public List<PermissionRole> associatePermissionsRoles(List<Permission> perms, List<Role> roles) {
+ public List<PermissionRole> associatePermissionsRoles(List<Permission> perms, List<Role> roles, boolean enforceTenancy) {
+ List<PermissionRole> result = null;
+
List<PermissionRole> permRoles = new ArrayList<PermissionRole>();
for (Permission perm : perms) {
- PermissionRole permRole = associatePermissionRoles(perm, roles);
- permRoles.add(permRole);
+ PermissionRole permRole = associatePermissionRoles(perm, roles, enforceTenancy);
+ if (permRole != null) {
+ permRoles.add(permRole);
+ }
+ }
+
+ if (permRoles.isEmpty() == false) {
+ result = permRoles;
}
- return permRoles;
+
+ return result;
}
private PermissionRole associatePermissionRoles(Permission perm,
- List<Role> roles) {
-
+ List<Role> roles, boolean enforceTenancy) {
+ PermissionRole result = null;
+
PermissionRole pr = new PermissionRole();
pr.setSubject(SubjectType.ROLE);
List<PermissionValue> permValues = new ArrayList<PermissionValue>();
List<RoleValue> roleValues = new ArrayList<RoleValue>();
for (Role role : roles) {
- RoleValue rv = new RoleValue();
- // This needs to use the qualified name, not the display name
- rv.setRoleName(role.getRoleName().toUpperCase());
- rv.setRoleId(role.getCsid());
- roleValues.add(rv);
+ boolean tenantIdsMatched = true;
+ if (enforceTenancy == true) {
+ tenantIdsMatched = role.getTenantId().equals(perm.getTenantId());
+ }
+ if (tenantIdsMatched == true) {
+ RoleValue rv = new RoleValue();
+ // This needs to use the qualified name, not the display name
+ rv.setRoleName(role.getRoleName().toUpperCase());
+ rv.setRoleId(role.getCsid());
+ roleValues.add(rv);
+ } else {
+ if (logger.isDebugEnabled() == true) {
+ logger.debug("Role and Permission tenant ID did not match."); //FIXME: REM - Remove this debug statement.
+ }
+ }
+ }
+ //
+ // If 'roleValues' is not empty, then associate it with the incoming 'perm' values
+ // otherwise, return null;
+ //
+ if (roleValues.isEmpty() == false) {
+ pr.setRoles(roleValues);
+ result = pr;
}
- pr.setRoles(roleValues);
- return pr;
+ return result;
}
public List<PermissionRole> getDefaultPermissionRoles() {
role.setDisplayName(ROLE_ADMINISTRATOR);
role.setRoleName(ROLE_PREFIX + role.getDisplayName());
role.setCsid(ROLE_ADMINISTRATOR_ID);
+ role.setTenantId(ADMINISTRATOR_TENANT_ID);
return role;
}
\r
import org.collectionspace.services.common.authorityref.AuthorityRefList;\r
import org.collectionspace.services.jaxb.AbstractCommonList;\r
-import org.collectionspace.services.workflow.WorkflowsCommon;\r
+import org.collectionspace.services.workflow.WorkflowCommon;\r
import org.jboss.resteasy.client.ClientResponse; //import org.collectionspace.services.common.context.ServiceContext;\r
import org.jboss.resteasy.client.ProxyFactory;\r
import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor;\r
import javax.ws.rs.QueryParam;\r
import javax.ws.rs.core.Response;\r
\r
+import org.collectionspace.services.client.workflow.WorkflowClient;\r
import org.collectionspace.services.common.authorityref.AuthorityRefList;\r
import org.collectionspace.services.jaxb.AbstractCommonList;\r
\r
@GET\r
@Produces({"application/xml"})\r
@Consumes({"application/xml"}) \r
- @Path("{csid}/workflow")\r
+ @Path("{csid}" + WorkflowClient.SERVICE_PATH)\r
ClientResponse<String> getWorkflow(@PathParam("csid") String csid);\r
\r
@PUT\r
@Produces({"application/xml"})\r
@Consumes({"application/xml"}) \r
- @Path("{csid}/workflow")\r
+ @Path("{csid}" + WorkflowClient.SERVICE_PATH)\r
ClientResponse<String> updateWorkflow(@PathParam("csid") String csid, byte[] xmlPayload);\r
\r
/*\r
//\r
// Constructors\r
//\r
- PayloadOutputPart(String label, Object body) {\r
+ public PayloadOutputPart(String label, Object body) {\r
super(label, body);\r
}\r
\r
import java.util.List;
import org.collectionspace.services.jaxb.AbstractCommonList;
+import org.collectionspace.services.workflow.WorkflowCommon;
+import org.collectionspace.services.client.AbstractPoxServiceClientImpl;
import org.collectionspace.services.client.CollectionSpaceClient;
+import org.collectionspace.services.client.PayloadOutputPart;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.client.workflow.WorkflowClient;
import org.jboss.resteasy.client.ClientResponse;
import org.slf4j.Logger;
import org.testng.annotations.Test;
import javax.activation.MimetypesFileTypeMap;
+import javax.ws.rs.core.Response;
/**
totalItems);//expected total num of items
}
}
-
-// @Override
-// protected CollectionSpaceClient getClientInstance() {
-// throw new UnsupportedOperationException(); //FIXME: REM - See http://issues.collectionspace.org/browse/CSPACE-3498
-// }
-//
-// @Override
-// protected String getServiceName() {
-// throw new UnsupportedOperationException(); //FIXME: REM - See http://issues.collectionspace.org/browse/CSPACE-3498
-// }
-
+
+ @SuppressWarnings("rawtypes")
+ protected void updateLifeCycleState(String testName, String resourceId, String lifeCycleState) throws Exception {
+ //
+ // Read the existing object
+ //
+ CollectionSpaceClient client = this.getClientInstance();
+ ClientResponse<String> res = client.getWorkflow(resourceId);
+ assertStatusCode(res, testName);
+ logger.debug("Got object to update life cycle state with ID: " + resourceId);
+ PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
+ WorkflowCommon workflowCommons = (WorkflowCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowCommon.class);
+ Assert.assertNotNull(workflowCommons);
+ //
+ // Mark it for a soft delete.
+ //
+ logger.debug("Current workflow state:" + objectAsXmlString(workflowCommons, WorkflowCommon.class));
+ workflowCommons.setCurrentLifeCycleState(lifeCycleState);
+ PoxPayloadOut output = new PoxPayloadOut(WorkflowClient.SERVICE_PAYLOAD_NAME);
+ PayloadOutputPart commonPart = output.addPart(WorkflowClient.SERVICE_COMMONPART_NAME, workflowCommons);
+ //
+ // Perform the update
+ //
+ res = client.updateWorkflow(resourceId, output);
+ assertStatusCode(res, testName);
+ input = new PoxPayloadIn(res.getEntity());
+ WorkflowCommon updatedWorkflowCommons = (WorkflowCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowCommon.class);
+ Assert.assertNotNull(updatedWorkflowCommons);
+ //
+ // Read the updated object and make sure it was updated correctly.
+ //
+ res = client.getWorkflow(resourceId);
+ assertStatusCode(res, testName);
+ logger.debug("Got workflow state of updated object with ID: " + resourceId);
+ input = new PoxPayloadIn(res.getEntity());
+ updatedWorkflowCommons = (WorkflowCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowCommon.class);
+ Assert.assertNotNull(workflowCommons);
+ Assert.assertEquals(updatedWorkflowCommons.getCurrentLifeCycleState(), lifeCycleState);
+ }
+
+ /*
+ * Sub-classes must override for the workflow tests.
+ */
+
+ protected String createWorkflowTarget(String testName) throws Exception {
+ logger.warn("Sub-class test clients should override this method");
+ throw new UnsupportedOperationException();
+ }
+
+ protected String createTestObject(String testName) throws Exception {
+ logger.warn("Sub-class test clients should override this method");
+ throw new UnsupportedOperationException();
+ }
}
*
*/
public class WorkflowClient extends AbstractPoxServiceClientImpl<AbstractCommonList, WorkflowProxy> {
- public static final String SERVICE_NAME = "workflows";
+ public static final String SERVICE_NAME = "workflow";
public static final String SERVICE_PATH_COMPONENT = SERVICE_NAME;
public static final String SERVICE_PATH = "/" + SERVICE_PATH_COMPONENT;
public static final String SERVICE_PAYLOAD_NAME = SERVICE_NAME;
public static final String SERVICE_COMMONPART_NAME = SERVICE_NAME + PART_LABEL_SEPARATOR + PART_COMMON_LABEL;
+ public static final String SERVICE_AUTHZ_SUFFIX = "/*/" + SERVICE_PATH_COMPONENT + "/";
//
// Workflow states
//
<!-- end movement service meta-data -->
<!-- begin Workflow service meta-data -->
- <tenant:serviceBindings name="Workflows" type="procedure" version="0.1">
+ <tenant:serviceBindings name="Workflow" type="procedure" version="0.1">
<service:repositoryDomain xmlns:service='http://collectionspace.org/services/common/service'>
default-domain
</service:repositoryDomain>
xmlns:service='http://collectionspace.org/services/common/service'>
<service:part id="0" control_group="Managed"
versionable="true" auditable="false"
- label="workflows-system" updated="" order="0">
+ label="workflow-system" updated="" order="0">
<service:content contentType="application/xml">
<service:xmlContent
namespaceURI="http://collectionspace.org/services/common/system"
</service:part>
<service:part id="1" control_group="Managed"
versionable="true" auditable="false"
- label="workflows_common" updated="" order="1">
+ label="workflow_common" updated="" order="1">
<service:content contentType="application/xml">
<service:xmlContent
namespaceURI="http://collectionspace.org/services/workflow"
- schemaLocation="http://collectionspace.org/services/workflow http://services.collectionspace.org/movement/workflows_common.xsd">
+ schemaLocation="http://collectionspace.org/services/workflow http://services.collectionspace.org/movement/workflow_common.xsd">
</service:xmlContent>
</service:content>
</service:part>
<!-- begin dimension service meta-data -->
<tenant:serviceBindings name="Dimensions" version="0.1">
<!-- other URI paths using which this service could be accessed -->
+ <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
+ /dimensions/*/workflow/
+ </service:uriPath>
<service:repositoryDomain xmlns:service='http://collectionspace.org/services/common/service'>
default-domain
</service:repositoryDomain>
import org.collectionspace.services.common.document.DocumentNotFoundException;\r
import org.collectionspace.services.common.security.UnauthorizedException;\r
import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;\r
-import org.collectionspace.services.workflow.WorkflowsCommon;\r
+import org.collectionspace.services.workflow.WorkflowCommon;\r
import org.jboss.resteasy.client.ClientResponse;\r
\r
import org.slf4j.Logger;\r
\r
WorkflowDocumentModelHandler docHandler = (WorkflowDocumentModelHandler)createDocumentHandler(ctx,\r
WorkflowClient.SERVICE_COMMONPART_NAME,\r
- WorkflowsCommon.class); \r
+ WorkflowCommon.class); \r
\r
return docHandler;\r
}\r
*/\r
\r
@GET\r
- @Path("{csid}/workflow")\r
+ @Path("{csid}" + WorkflowClient.SERVICE_PATH)\r
public byte[] getWorkflow(\r
@PathParam("csid") String csid) {\r
PoxPayloadOut result = null;\r
}\r
\r
@PUT\r
- @Path("{csid}/workflow")\r
+ @Path("{csid}" + WorkflowClient.SERVICE_PATH)\r
public byte[] updateWorkflow(@PathParam("csid") String csid, String xmlPayload) {\r
PoxPayloadOut result = null;\r
try {\r
import java.io.IOException;
import java.io.InputStream;
+import org.collectionspace.services.client.PayloadOutputPart;
import org.collectionspace.services.client.PoxPayloadIn;
import org.collectionspace.services.client.PoxPayloadOut;
import org.dom4j.Element;
*/
public void addOutputPart(String label, Element doc, String contentType) throws Exception;
+ public void addOutputPart(PayloadOutputPart outputPart) throws Exception;
+
public void setRespositoryWorkspaceName(String workspaceName);
}
if (logger.isTraceEnabled() == true) {
logger.trace("Adding part:" + label +
" to " + getOutput().getName() + " document.");
- }
- }
+ }
+ }
+
+ @Override
+ public void addOutputPart(PayloadOutputPart outputPart) throws Exception {
+ PayloadOutputPart part = getOutput().addPart(outputPart);
+ if (logger.isTraceEnabled() == true) {
+ logger.trace("Adding part:" + part.getLabel() +
+ " to " + getOutput().getName() + " document.");
+ }
+ }
/* (non-Javadoc)
* @see org.collectionspace.services.common.context.RemoteServiceContextImpl#getLocalContext(java.lang.String)
import org.collectionspace.services.authorization.AuthZ;
import org.collectionspace.services.authorization.CSpaceResource;
import org.collectionspace.services.authorization.URIResourceImpl;
+import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.common.document.JaxbUtils;
import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
import org.collectionspace.services.common.security.SecurityUtils;
Response response = Response.status(
Response.Status.FORBIDDEN).entity(uriPath + " " + httpMethod).type("text/plain").build();
throw new WebApplicationException(response);
+ } else {
+ //
+ // They passed the first round of security checks, so now let's check to see if they're trying
+ // to perform a workflow state change and make sure they are allowed to to this.
+ //
+ if (uriPath.endsWith(WorkflowClient.SERVICE_PATH_COMPONENT) == true) {
+ String workflowSubResName = getResourceName(request.getUri());
+ res = new URIResourceImpl(workflowSubResName, httpMethod);
+ if (!authZ.isAccessAllowed(res)) {
+ logger.error("Access to " + resName + ":" + res.getId() + " is NOT allowed to "
+ + " user=" + AuthN.get().getUserId());
+ Response response = Response.status(
+ Response.Status.FORBIDDEN).entity(uriPath + " " + httpMethod).type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ }
}
+ //
+ // We've passed all the checks. Now just log the results
+ //
if (logger.isDebugEnabled()) {
logger.debug("Access to " + res.getId() + " is allowed to "
+ " user=" + AuthN.get().getUserId() +
/** The Constant CS_PERSISTENCE_UNIT. */
public final static String CS_PERSISTENCE_UNIT = "org.collectionspace.services";
private final static String CS_AUTHZ_PERSISTENCE_UNIT = "org.collectionspace.services.authorization";
- private final static String CS_CURRENT_USER = "0";
+ public final static String CS_CURRENT_USER = "0";
/**
* getEntity for given id and class
return result;
}
- //FIXME: This method should be moved to the AccountPermissionDocumemntHandler
+ //FIXME: REM - This method should probably be moved to the AccountPermissionDocumemntHandler
/*
* This is a prototype for the /accounts/{csid}/permissions GET service call.
*/
public static AccountPermission getAccountPermissions(String csid)
+ throws UnauthorizedException, DocumentNotFoundException {
+ return getAccountPermissions(csid, null, null);
+ }
+
+ //FIXME: REM - This method should probably be moved to the AccountPermissionDocumemntHandler
+ /*
+ * This is a prototype for the /accounts/{csid}/permissions GET service call.
+ */
+ public static AccountPermission getAccountPermissions(String csid, String currentResource, String permissionResource)
throws UnauthorizedException, DocumentNotFoundException {
//
// Make sure the user asking for this list has the correct
try {
StringBuilder queryStrBldr = new StringBuilder("SELECT ar, pr FROM " + AccountRoleRel.class.getName() +
" ar, " + PermissionRoleRel.class.getName() + " pr" +
- " WHERE ar.roleId = pr.roleId and ar.userId=" + "'" + userId + "'" +
- "group by pr.permissionId");
+ " WHERE ar.roleId = pr.roleId and ar.userId=" + "'" + userId + "'");
+ //
+ // Filter by the permissionResource param if it is set to something
+ //
+ if (permissionResource != null && currentResource != null) {
+ queryStrBldr.append(" and (pr.permissionResource = " + "'" + currentResource + "'" +
+ " or pr.permissionResource = " + "'" + permissionResource + "'" + ")");
+ }
+ //
+ // Add group by clause
+ //
+ queryStrBldr.append(" group by pr.permissionId");
emf = getEntityManagerFactory();
em = emf.createEntityManager();
import org.collectionspace.services.common.workflow.jaxb.WorkflowJAXBSchema;
import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
-import org.collectionspace.services.workflow.WorkflowsCommon;
+import org.collectionspace.services.workflow.WorkflowCommon;
import org.dom4j.Element;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WorkflowDocumentModelHandler
- extends DocHandlerBase<WorkflowsCommon> {
+ extends DocHandlerBase<WorkflowCommon> {
/** The logger. */
private final Logger logger = LoggerFactory.getLogger(WorkflowDocumentModelHandler.class);
ObjectPartType partMeta, Action action,
ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx)
throws Exception {
- WorkflowsCommon workflowsCommon = (WorkflowsCommon)part.getBody();
+ WorkflowCommon workflowsCommon = (WorkflowCommon)part.getBody();
docModel.followTransition(getTransitionFromState(workflowsCommon.getCurrentLifeCycleState()));
}
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import org.collectionspace.services.authorization.AccountPermission;
import org.collectionspace.services.jaxb.AbstractCommonList;
import org.collectionspace.services.client.PayloadInputPart;
+import org.collectionspace.services.client.PayloadOutputPart;
import org.collectionspace.services.client.PoxPayloadIn;
import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.common.authorityref.AuthorityRefList;
+import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon;
import org.collectionspace.services.common.context.MultipartServiceContext;
import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.document.BadRequestException;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
import org.collectionspace.services.common.document.DocumentUtils;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.document.DocumentFilter;
import org.collectionspace.services.common.document.DocumentHandler.Action;
+import org.collectionspace.services.common.security.UnauthorizedException;
import org.collectionspace.services.common.service.ObjectPartType;
+import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
import org.collectionspace.services.common.vocabulary.RefNameUtils;
import org.dom4j.Element;
Map<String, Object> unQObjectProperties = extractPart(docModel, schema, partMeta);
addOutputPart(unQObjectProperties, schema, partMeta);
}
+ addAccountPermissionsPart();
+ }
+
+ private void addAccountPermissionsPart() throws Exception {
+ MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
+ String currentServiceName = ctx.getServiceName();
+ AccountPermission accountPermission = JpaStorageUtils.getAccountPermissions(JpaStorageUtils.CS_CURRENT_USER,
+ currentServiceName, "/" + currentServiceName + WorkflowClient.SERVICE_AUTHZ_SUFFIX);
+ PayloadOutputPart accountPermissionPart = new PayloadOutputPart("account_permission", accountPermission);
+ ctx.addOutputPart(accountPermissionPart);
}
/* (non-Javadoc)
import org.collectionspace.services.client.PayloadOutputPart;
import org.collectionspace.services.client.PoxPayloadIn;
import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.dimension.DimensionsCommon;
import org.collectionspace.services.dimension.DimensionsCommonList;
import org.collectionspace.services.jaxb.AbstractCommonList;
+import org.collectionspace.services.workflow.WorkflowCommon;
import org.jboss.resteasy.client.ClientResponse;
return multipart;
}
+
+ @Override
+ protected String createWorkflowTarget(String testName) throws Exception {
+ String result = null;
+
+ result = createTestObject(testName);
+
+ return result;
+ }
+
+ @Override
+ protected String createTestObject(String testName) throws Exception {
+ String result = null;
+
+ DimensionClient client = new DimensionClient();
+ String identifier = createIdentifier();
+ PoxPayloadOut multipart = createDimensionInstance(client.getCommonPartName(),
+ identifier);
+ ClientResponse<Response> res = client.create(multipart);
+
+ int statusCode = res.getStatus();
+ Assert.assertEquals(statusCode, STATUS_CREATED);
+
+ result = extractId(res);
+ allResourceIdsCreated.add(result);
+
+ return result;
+ }
+
+ /*
+ * This test assumes that no objects exist yet.
+ *
+ * http://localhost:8180/cspace-services/intakes?wf_deleted=false
+ */
+ @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, dependsOnMethods = {"update"})
+ public void readWorkflowList(String testName) throws Exception {
+ //
+ // Create 3 new objects
+ //
+ final int OBJECTS_TOTAL = 3;
+ for (int i = 0; i < OBJECTS_TOTAL; i++) {
+ this.createWorkflowTarget(testName);
+ }
+ //
+ // Mark one as soft deleted
+ //
+ int currentTotal = allResourceIdsCreated.size();
+ String csid = allResourceIdsCreated.get(currentTotal - 1); //0-based index to get the last one added
+ this.setupUpdate();
+ this.updateLifeCycleState(testName, csid, WorkflowClient.WORKFLOWSTATE_DELETED);
+ //
+ // Read the list back. The deleted item should not be in the list
+ //
+// int updatedTotal = readIncludeDeleted(testName, Boolean.FALSE);
+// Assert.assertEquals(updatedTotal, currentTotal - 1, "Deleted items seem to be returned in list results.");
+ }
+
+ protected void updateLifeCycleState(String testName, String resourceId, String lifeCycleState) throws Exception {
+ //
+ // Read the existing object
+ //
+ DimensionClient client = new DimensionClient();
+ ClientResponse<String> res = client.getWorkflow(resourceId);
+ assertStatusCode(res, testName);
+ logger.debug("Got object to update life cycle state with ID: " + resourceId);
+ PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
+ WorkflowCommon workflowCommons = (WorkflowCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowCommon.class);
+ Assert.assertNotNull(workflowCommons);
+ //
+ // Mark it for a soft delete.
+ //
+ logger.debug("Current workflow state:" + objectAsXmlString(workflowCommons, WorkflowCommon.class));
+ workflowCommons.setCurrentLifeCycleState(lifeCycleState);
+ PoxPayloadOut output = new PoxPayloadOut(WorkflowClient.SERVICE_PAYLOAD_NAME);
+ PayloadOutputPart commonPart = output.addPart(workflowCommons, MediaType.APPLICATION_XML_TYPE);
+ commonPart.setLabel(WorkflowClient.SERVICE_COMMONPART_NAME);
+ //
+ // Perform the update
+ //
+ res = client.updateWorkflow(resourceId, output);
+ assertStatusCode(res, testName);
+ input = new PoxPayloadIn(res.getEntity());
+ WorkflowCommon updatedWorkflowCommons = (WorkflowCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowCommon.class);
+ Assert.assertNotNull(updatedWorkflowCommons);
+ //
+ // Read the updated object and make sure it was updated correctly.
+ //
+ res = client.getWorkflow(resourceId);
+ assertStatusCode(res, testName);
+ logger.debug("Got workflow state of updated object with ID: " + resourceId);
+ input = new PoxPayloadIn(res.getEntity());
+ updatedWorkflowCommons = (WorkflowCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowCommon.class);
+ Assert.assertNotNull(workflowCommons);
+ Assert.assertEquals(updatedWorkflowCommons.getCurrentLifeCycleState(), lifeCycleState);
+ }
+
}
See http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html
-->
<!-- workflow -->
- <xs:element name="workflows_common">
+ <xs:element name="workflow_common">
<xs:complexType>
<xs:sequence>
<!-- Workflow Information Group -->
<?xml version="1.0"?>
<component name="org.collectionspace.workflow.coreTypes">
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
- <schema name="workflows_common" prefix="workflows_common" src="schemas/workflows_common.xsd"/>
+ <schema name="workflow_common" prefix="workflow_common" src="schemas/workflow_common.xsd"/>
</extension>
</component>
import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.jaxb.AbstractCommonList;
-import org.collectionspace.services.workflow.WorkflowsCommon;
+import org.collectionspace.services.workflow.WorkflowCommon;
import org.collectionspace.services.client.DimensionClient;
import org.collectionspace.services.client.workflow.WorkflowClient;
import org.collectionspace.services.dimension.DimensionsCommon;
/*
* Create a Dimension instance to use as our test target.
*/
- public void createTestObject(String testName) throws Exception {
+ @Override
+ protected String createWorkflowTarget(String testName) throws Exception {
+ String result = null;
+
+ result = createTestObject(testName);
+
+ return result;
+ }
+
+ /*
+ * Create a Dimension instance to use as our test target.
+ */
+ protected String createTestObject(String testName) throws Exception {
+ String result = null;
+
logger.debug(testBanner(testName, CLASS_NAME));
setupCreate();
DimensionClient client = new DimensionClient();
knownResourceId = extractId(res); // Store the ID returned from the first resource created for additional tests below.
logger.debug(testName + ": knownResourceId=" + knownResourceId);
}
- allResourceIdsCreated.add(extractId(res)); // Store the IDs from every resource created by tests so they can be deleted after tests have been run.
+ result = extractId(res);
+ allResourceIdsCreated.add(result); // Store the IDs from every resource created by tests so they can be deleted after tests have been run.
+
+ return result;
}
@Override
ClientResponse<String> res = client.getWorkflow(knownResourceId);
assertStatusCode(res, testName);
PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
- WorkflowsCommon workflowsCommon = (WorkflowsCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowsCommon.class);
+ WorkflowCommon workflowsCommon = (WorkflowCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowCommon.class);
if (logger.isDebugEnabled() == true) {
logger.debug("Workflow payload is: " + input.getXmlPayload());
}
updateLifeCycleState(testName, knownResourceId, WorkflowClient.WORKFLOWSTATE_APPROVED);
}
- private void updateLifeCycleState(String testName, String resourceId, String lifeCycleState) throws Exception {
- //
- // Read the existing object
- //
- DimensionClient client = new DimensionClient();
- ClientResponse<String> res = client.getWorkflow(resourceId);
- assertStatusCode(res, testName);
- logger.debug("Got object to update life cycle state with ID: " + resourceId);
- PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
- WorkflowsCommon workflowCommons = (WorkflowsCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowsCommon.class);
- Assert.assertNotNull(workflowCommons);
- //
- // Mark it for a soft delete.
- //
- logger.debug("Current workflow state:" + objectAsXmlString(workflowCommons, WorkflowsCommon.class));
- workflowCommons.setCurrentLifeCycleState(lifeCycleState);
- PoxPayloadOut output = new PoxPayloadOut(WorkflowClient.SERVICE_PAYLOAD_NAME);
- PayloadOutputPart commonPart = output.addPart(workflowCommons, MediaType.APPLICATION_XML_TYPE);
- commonPart.setLabel(WorkflowClient.SERVICE_COMMONPART_NAME);
- //
- // Perform the update
- //
- res = client.updateWorkflow(resourceId, output);
- assertStatusCode(res, testName);
- input = new PoxPayloadIn(res.getEntity());
- WorkflowsCommon updatedWorkflowCommons = (WorkflowsCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowsCommon.class);
- Assert.assertNotNull(updatedWorkflowCommons);
- //
- // Read the updated object and make sure it was updated correctly.
- //
- res = client.getWorkflow(resourceId);
- assertStatusCode(res, testName);
- logger.debug("Got workflow state of updated object with ID: " + resourceId);
- input = new PoxPayloadIn(res.getEntity());
- updatedWorkflowCommons = (WorkflowsCommon) extractPart(input, WorkflowClient.SERVICE_COMMONPART_NAME, WorkflowsCommon.class);
- Assert.assertNotNull(workflowCommons);
- Assert.assertEquals(updatedWorkflowCommons.getCurrentLifeCycleState(), lifeCycleState);
- }
@Override
// @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, dependsOnMethods = {"update", "testSubmitRequest"})
return result;
}
+ @Override
+ public void readList(String testName) throws Exception {
+ }
+
/*
* This test assumes that no objects exist yet.
*
* http://localhost:8180/cspace-services/intakes?wf_deleted=false
*/
- @Override
@Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, dependsOnMethods = {"update"})
- public void readList(String testName) throws Exception {
+ public void readWorkflow(String testName) throws Exception {
+ //
+ // Get the total count of non-deleted existing records
+ //
+ int existingRecords = readIncludeDeleted(testName, Boolean.FALSE);
+
//
// Create 3 new objects
//
- final int OBJECTS_TOTAL = 3;
- for (int i = 0; i < OBJECTS_TOTAL; i++) {
- this.createTestObject(testName);
+ final int OBJECTS_TO_CREATE = 3;
+ for (int i = 0; i < OBJECTS_TO_CREATE; i++) {
+ this.createWorkflowTarget(testName);
}
+
//
// Mark one as soft deleted
//
- int currentTotal = allResourceIdsCreated.size();
- String csid = allResourceIdsCreated.get(currentTotal - 1); //0-based index to get the last one added
+ int existingTestCreated = allResourceIdsCreated.size(); // assumption is that no other test created records were soft deleted
+ String csid = allResourceIdsCreated.get(existingTestCreated - 1); //0-based index to get the last one added
this.setupUpdate();
this.updateLifeCycleState(testName, csid, WorkflowClient.WORKFLOWSTATE_DELETED);
//
- // Read the list back. The deleted item should not be in the list
+ // Read the list of existing non-deleted records
//
int updatedTotal = readIncludeDeleted(testName, Boolean.FALSE);
- Assert.assertEquals(updatedTotal, currentTotal - 1, "Deleted items seem to be returned in list results.");
+ Assert.assertEquals(updatedTotal, existingRecords + OBJECTS_TO_CREATE - 1, "Deleted items seem to be returned in list results.");
}
@Override
import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.common.document.InvalidDocumentException;
import org.collectionspace.services.common.document.ValidatorHandlerImpl;
-import org.collectionspace.services.workflow.WorkflowsCommon;
+import org.collectionspace.services.workflow.WorkflowCommon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
protected Class<?> getCommonPartClass() {
- return WorkflowsCommon.class;
+ return WorkflowCommon.class;
}
@Override
protected void handleCreate() throws InvalidDocumentException {
try {
- WorkflowsCommon intakesCommon = (WorkflowsCommon)getCommonPart();
+ WorkflowCommon intakesCommon = (WorkflowCommon)getCommonPart();
assert(intakesCommon != null);
} catch (AssertionError e) {
if (logger.isErrorEnabled() == true) {