Finish ALF-4129 - list replication definitions webscript

Fix up the freemarker output, add sorting support, and webscript unit tests


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21539 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2010-08-02 13:22:42 +00:00
parent 04de456146
commit a1c412e4e6
6 changed files with 359 additions and 29 deletions

View File

@@ -4,18 +4,20 @@
{
"name": "${replicationDefinition.name}",
"status" : "${replicationDefinition.status}",
"enabled" : "${replicationDefinition.enabled}",
"details": "${replicationDefinition.details_url}",
"startedAt" : <#if replicationDefinition.startedAt??>"${replicationDefinition.startedAt}"<#else>null</#if>,
"enabled" : ${replicationDefinition.enabled?string},
"details": "${"/api/replication-definition/" + replicationDefinition.name}",
}
</#escape>
</#macro>
<#-- Renders the details of a replication definition. -->
<#macro replicationDefinitionJSON replicationDefinition>
<#escape x as jsonUtils.encodeJSONString(x)>
{
"name": "${replicationDefinition.name}",
"status" : "${replicationDefinition.status}",
"enabled" : "${replicationDefinition.enabled}",
"enabled" : ${replicationDefinition.enabled?string},
<#-- TODO The rest of the fields -->
}
</#escape>

View File

@@ -3,7 +3,7 @@
<description>
Returns a simple representation of all persisted replication definitions.
</description>
<url>/api/replication-definitions</url>
<url>/api/replication-definitions?sort={sort?}</url>
<format default="json"/>
<authentication>admin</authentication>
<transaction allow="readonly">required</transaction>

View File

@@ -18,14 +18,9 @@
*/
package org.alfresco.repo.web.scripts.replication;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.action.ActionTrackingServiceImpl;
import org.alfresco.service.cmr.action.ActionTrackingService;
import org.alfresco.service.cmr.action.ExecutionDetails;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.replication.ReplicationDefinition;
import org.alfresco.service.cmr.replication.ReplicationService;
import org.alfresco.service.cmr.repository.NodeService;
import org.springframework.extensions.webscripts.Cache;

View File

@@ -18,6 +18,7 @@
*/
package org.alfresco.repo.web.scripts.replication;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@@ -40,7 +41,19 @@ public class ReplicationDefinitionsGet extends AbstractReplicationWebscript
// Get all the defined replication definitions
List<ReplicationDefinition> definitions = replicationService.loadReplicationDefinitions();
// How do we need to sort them?
Comparator<Map<String,Object>> sorter = new ReplicationModelBuilder.SimpleSorterByName();
String sort = req.getParameter("sort");
if(sort == null) {
// Default was set above
} else if(sort.equalsIgnoreCase("status")) {
sorter = new ReplicationModelBuilder.SimpleSorterByStatus();
} else if(sort.equalsIgnoreCase("lastRun") ||
sort.equalsIgnoreCase("lastRunTime")) {
sorter = new ReplicationModelBuilder.SimpleSorterByLastRun();
}
// Have them turned into simple models
return modelBuilder.buildSimpleList(definitions);
return modelBuilder.buildSimpleList(definitions, sorter);
}
}

View File

@@ -19,6 +19,9 @@
package org.alfresco.repo.web.scripts.replication;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -29,6 +32,7 @@ import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.replication.ReplicationDefinition;
import org.alfresco.service.cmr.replication.ReplicationService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.util.ISO8601DateFormat;
/**
* Builds up models from ReplicationDefinitions, either
@@ -46,7 +50,6 @@ public class ReplicationModelBuilder
protected static final String DEFINITION_STARTED_AT = "startedAt";
protected static final String DEFINITION_ENDED_AT = "endedAt";
protected static final String DEFINITION_ENABLED = "enabled";
protected static final String DEFINITION_DETAILS_URL = "details";
protected NodeService nodeService;
protected ReplicationService replicationService;
@@ -61,11 +64,67 @@ public class ReplicationModelBuilder
}
/**
* Sorts simple definitions by their status
*/
public static class SimpleSorterByStatus implements Comparator<Map<String,Object>> {
private SimpleSorterByName nameSorter = new SimpleSorterByName();
public int compare(Map<String, Object> simpleA, Map<String, Object> simpleB) {
String statusA = (String)simpleA.get(DEFINITION_STATUS);
String statusB = (String)simpleB.get(DEFINITION_STATUS);
if(statusA == null || statusB == null) {
throw new IllegalArgumentException("Status missing during sort");
}
int compare = statusA.compareTo(statusB);
if(compare == 0) {
return nameSorter.compare(simpleA, simpleB);
}
return compare;
}
}
/**
* Sorts simple definitions by their name
*/
public static class SimpleSorterByName implements Comparator<Map<String,Object>> {
public int compare(Map<String, Object> simpleA, Map<String, Object> simpleB) {
String nameA = (String)simpleA.get(DEFINITION_NAME);
String nameB = (String)simpleB.get(DEFINITION_NAME);
if(nameA == null || nameB == null) {
throw new IllegalArgumentException("Name missing during sort");
}
return nameA.compareTo(nameB);
}
}
/**
* Sorts simple definitions by their last run time.
*/
public static class SimpleSorterByLastRun implements Comparator<Map<String,Object>> {
/** Works on ISO8601 formatted date strings */
public int compare(Map<String, Object> simpleA, Map<String, Object> simpleB) {
String dateA = (String)simpleA.get(DEFINITION_STARTED_AT);
String dateB = (String)simpleB.get(DEFINITION_STARTED_AT);
if(dateA == null && dateB == null) {
return 0;
}
if(dateA != null && dateB == null) {
return 1;
}
if(dateA == null && dateB != null) {
return -1;
}
// We want more recent dates first
return 0-dateA.compareTo(dateB);
}
}
/**
* Build a model containing a list of simple definitions for the given
* list of Replication Definitions.
*/
protected Map<String,Object> buildSimpleList(List<ReplicationDefinition> replicationDefinitions)
protected Map<String,Object> buildSimpleList(List<ReplicationDefinition> replicationDefinitions,
Comparator<Map<String,Object>> sorter)
{
List<Map<String,Object>> models = new ArrayList<Map<String,Object>>();
@@ -83,16 +142,21 @@ public class ReplicationModelBuilder
Map<String, Object> rdm = new HashMap<String,Object>();
rdm.put(DEFINITION_NAME, rd.getReplicationName());
rdm.put(DEFINITION_ENABLED, rd.isEnabled());
rdm.put(DEFINITION_DETAILS_URL, buildDefinitionDetailsUrl(rd));
// Do the status
// Do the status - end date isn't needed
setStatus(rd, details, rdm);
rdm.remove(DEFINITION_ENDED_AT);
// Add to the list of finished models
models.add(rdm);
}
}
// Sort the entries
if(sorter != null) {
Collections.sort(models, sorter);
}
// Finish up
Map<String, Object> model = new HashMap<String,Object>();
model.put(MODEL_DATA_LIST, models);
@@ -100,11 +164,6 @@ public class ReplicationModelBuilder
}
protected String buildDefinitionDetailsUrl(ReplicationDefinition replicationDefinition)
{
return "/api/replication-definition/" + replicationDefinition.getReplicationName();
}
/**
* Figures out the status that's one of:
* New|Running|CancelRequested|Completed|Failed|Cancelled
@@ -138,8 +197,21 @@ public class ReplicationModelBuilder
if(details == null) {
// It isn't running, we can use the persisted details
model.put(DEFINITION_STATUS, replicationDefinition.getExecutionStatus().toString());
model.put(DEFINITION_STARTED_AT, replicationDefinition.getExecutionStartDate());
model.put(DEFINITION_ENDED_AT, replicationDefinition.getExecutionEndDate());
Date startDate = replicationDefinition.getExecutionStartDate();
if(startDate != null) {
model.put(DEFINITION_STARTED_AT, ISO8601DateFormat.format(startDate));
} else {
model.put(DEFINITION_STARTED_AT, null);
}
Date endDate = replicationDefinition.getExecutionEndDate();
if(endDate != null) {
model.put(DEFINITION_ENDED_AT, ISO8601DateFormat.format(endDate));
} else {
model.put(DEFINITION_ENDED_AT, null);
}
return;
}
@@ -149,7 +221,7 @@ public class ReplicationModelBuilder
} else {
model.put(DEFINITION_STATUS, "Running");
}
model.put(DEFINITION_STARTED_AT, details.getStartedAt());
model.put(DEFINITION_STARTED_AT, ISO8601DateFormat.format(details.getStartedAt()));
model.put(DEFINITION_ENDED_AT, null);
}

View File

@@ -22,11 +22,13 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.person.TestPersonManager;
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
import org.alfresco.service.cmr.action.ActionTrackingService;
import org.alfresco.service.cmr.replication.ReplicationDefinition;
import org.alfresco.service.cmr.replication.ReplicationService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.util.GUID;
import org.alfresco.util.ISO8601DateFormat;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.context.ApplicationContext;
@@ -74,24 +76,254 @@ public class ReplicationRestApiTest extends BaseWebScriptTest
JSONObject json = new JSONObject(jsonStr);
JSONArray results = json.getJSONArray("data");
assertNotNull(results);
assertTrue(results.length() == 0);
assertEquals(0, results.length());
// Add a definition, it should show up
// TODO
ReplicationDefinition rd = replicationService.createReplicationDefinition("Test1", "Testing");
replicationService.saveReplicationDefinition(rd);
response = sendRequest(new GetRequest(URL_DEFINITIONS), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
jsonStr = response.getContentAsString();
json = new JSONObject(jsonStr);
results = json.getJSONArray("data");
assertNotNull(results);
assertEquals(1, results.length());
JSONObject jsonRD = (JSONObject)results.get(0);
assertNotNull(jsonRD);
assertEquals("Test1", jsonRD.get("name"));
assertEquals("New", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(JSONObject.NULL, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test1", jsonRD.get("details"));
// Change the status to running, and re-check
// TODO
actionTrackingService.recordActionExecuting(rd);
String startedAt = ISO8601DateFormat.format(rd.getExecutionStartDate());
response = sendRequest(new GetRequest(URL_DEFINITIONS), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
jsonStr = response.getContentAsString();
json = new JSONObject(jsonStr);
results = json.getJSONArray("data");
assertNotNull(results);
assertEquals(1, results.length());
jsonRD = (JSONObject)results.get(0);
assertNotNull(jsonRD);
assertEquals("Test1", jsonRD.get("name"));
assertEquals("Running", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test1", jsonRD.get("details"));
// Add a 2nd and 3rd
// TODO
rd = replicationService.createReplicationDefinition("Test2", "2nd Testing");
replicationService.saveReplicationDefinition(rd);
rd = replicationService.createReplicationDefinition("AnotherTest", "3rd Testing");
replicationService.saveReplicationDefinition(rd);
// They should come back sorted by name
response = sendRequest(new GetRequest(URL_DEFINITIONS), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
jsonStr = response.getContentAsString();
json = new JSONObject(jsonStr);
results = json.getJSONArray("data");
assertNotNull(results);
assertEquals(3, results.length());
jsonRD = (JSONObject)results.get(0);
assertNotNull(jsonRD);
assertEquals("AnotherTest", jsonRD.get("name"));
assertEquals("New", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(JSONObject.NULL, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/AnotherTest", jsonRD.get("details"));
jsonRD = (JSONObject)results.get(1);
assertNotNull(jsonRD);
assertEquals("Test1", jsonRD.get("name"));
assertEquals("Running", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test1", jsonRD.get("details"));
jsonRD = (JSONObject)results.get(2);
assertNotNull(jsonRD);
assertEquals("Test2", jsonRD.get("name"));
assertEquals("New", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(JSONObject.NULL, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test2", jsonRD.get("details"));
// Sort by status
response = sendRequest(new GetRequest(URL_DEFINITIONS + "?sort=status"), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
jsonStr = response.getContentAsString();
json = new JSONObject(jsonStr);
results = json.getJSONArray("data");
assertNotNull(results);
assertEquals(3, results.length());
// New, name sorts higher
jsonRD = (JSONObject)results.get(0);
assertNotNull(jsonRD);
assertEquals("AnotherTest", jsonRD.get("name"));
assertEquals("New", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(JSONObject.NULL, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/AnotherTest", jsonRD.get("details"));
// New, name sorts lower
jsonRD = (JSONObject)results.get(1);
assertNotNull(jsonRD);
assertEquals("Test2", jsonRD.get("name"));
assertEquals("New", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(JSONObject.NULL, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test2", jsonRD.get("details"));
// Running
jsonRD = (JSONObject)results.get(2);
assertNotNull(jsonRD);
assertEquals("Test1", jsonRD.get("name"));
assertEquals("Running", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test1", jsonRD.get("details"));
// Set start times and statuses on these other two
rd = replicationService.loadReplicationDefinition("Test2");
actionTrackingService.recordActionExecuting(rd);
actionTrackingService.recordActionComplete(rd);
String startedAt2 = ISO8601DateFormat.format(rd.getExecutionStartDate());
// Try the different sorts
response = sendRequest(new GetRequest(URL_DEFINITIONS + "?sort=status"), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
jsonStr = response.getContentAsString();
json = new JSONObject(jsonStr);
results = json.getJSONArray("data");
assertNotNull(results);
assertEquals(3, results.length());
// Complete
jsonRD = (JSONObject)results.get(0);
assertNotNull(jsonRD);
assertEquals("Test2", jsonRD.get("name"));
assertEquals("Completed", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt2, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test2", jsonRD.get("details"));
// New
jsonRD = (JSONObject)results.get(1);
assertNotNull(jsonRD);
assertEquals("AnotherTest", jsonRD.get("name"));
assertEquals("New", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(JSONObject.NULL, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/AnotherTest", jsonRD.get("details"));
// Running
jsonRD = (JSONObject)results.get(2);
assertNotNull(jsonRD);
assertEquals("Test1", jsonRD.get("name"));
assertEquals("Running", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test1", jsonRD.get("details"));
// By last run
response = sendRequest(new GetRequest(URL_DEFINITIONS + "?sort=lastRun"), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
jsonStr = response.getContentAsString();
json = new JSONObject(jsonStr);
results = json.getJSONArray("data");
assertNotNull(results);
assertEquals(3, results.length());
// Never run first
jsonRD = (JSONObject)results.get(0);
assertNotNull(jsonRD);
assertEquals("AnotherTest", jsonRD.get("name"));
assertEquals("New", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(JSONObject.NULL, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/AnotherTest", jsonRD.get("details"));
// Ran most recently
jsonRD = (JSONObject)results.get(1);
assertNotNull(jsonRD);
assertEquals("Test2", jsonRD.get("name"));
assertEquals("Completed", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt2, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test2", jsonRD.get("details"));
// Ran least recently
jsonRD = (JSONObject)results.get(2);
assertNotNull(jsonRD);
assertEquals("Test1", jsonRD.get("name"));
assertEquals("Running", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test1", jsonRD.get("details"));
// Cancel one of these
// TODO
rd = replicationService.loadReplicationDefinition("AnotherTest");
rd.setEnabled(false);
replicationService.saveReplicationDefinition(rd);
actionTrackingService.recordActionExecuting(rd);
actionTrackingService.requestActionCancellation(rd);
String startedAt3 = ISO8601DateFormat.format(rd.getExecutionStartDate());
response = sendRequest(new GetRequest(URL_DEFINITIONS), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
jsonStr = response.getContentAsString();
json = new JSONObject(jsonStr);
results = json.getJSONArray("data");
assertNotNull(results);
assertEquals(3, results.length());
jsonRD = (JSONObject)results.get(0);
assertNotNull(jsonRD);
assertEquals("AnotherTest", jsonRD.get("name"));
assertEquals("CancelRequested", jsonRD.get("status"));
assertEquals(false, jsonRD.get("enabled"));
assertEquals(startedAt3, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/AnotherTest", jsonRD.get("details"));
jsonRD = (JSONObject)results.get(1);
assertNotNull(jsonRD);
assertEquals("Test1", jsonRD.get("name"));
assertEquals("Running", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test1", jsonRD.get("details"));
jsonRD = (JSONObject)results.get(2);
assertNotNull(jsonRD);
assertEquals("Test2", jsonRD.get("name"));
assertEquals("Completed", jsonRD.get("status"));
assertEquals(true, jsonRD.get("enabled"));
assertEquals(startedAt2, jsonRD.get("startedAt"));
assertEquals("/api/replication-definition/Test2", jsonRD.get("details"));
}
@Override
@@ -109,6 +341,14 @@ public class ReplicationRestApiTest extends BaseWebScriptTest
personManager = new TestPersonManager(authenticationService, personService, nodeService);
personManager.createPerson(USER_NORMAL);
// Ensure we start with no replication definitions
// (eg another test left them behind)
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
for(ReplicationDefinition rd : replicationService.loadReplicationDefinitions()) {
replicationService.deleteReplicationDefinition(rd);
}
AuthenticationUtil.clearCurrentSecurityContext();
}
/* (non-Javadoc)
@@ -118,6 +358,14 @@ public class ReplicationRestApiTest extends BaseWebScriptTest
protected void tearDown() throws Exception
{
super.tearDown();
personManager.clearPeople();
// Zap any replication definitions we created
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
for(ReplicationDefinition rd : replicationService.loadReplicationDefinitions()) {
replicationService.deleteReplicationDefinition(rd);
}
AuthenticationUtil.clearCurrentSecurityContext();
}
}