Merged HEAD (5.2) to 5.2.N (5.2.1)

126478 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)
      122543 gjames: RA-211: Moving around execution logic in preparation for more flexible respoonse handling


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126822 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ancuta Morarasu
2016-05-11 11:37:23 +00:00
parent 8f1051b408
commit 64afcc134e
13 changed files with 155 additions and 273 deletions

View File

@@ -91,7 +91,7 @@ public class NetworkWebScriptGet extends ApiWebScript
{
// TODO this is not ideal, but the only way to populate the embedded network entities (this would normally be
// done automatically by the api framework).
Object wrapped = helper.processAdditionsToTheResponse(Api.ALFRESCO_PUBLIC, NetworksEntityResource.NAME, Params.valueOf(personId, null, req), networkMembership);
Object wrapped = helper.processAdditionsToTheResponse(res, Api.ALFRESCO_PUBLIC, NetworksEntityResource.NAME, Params.valueOf(personId, null, req), networkMembership);
objectMapper.writeValue(generator, wrapped);
}

View File

@@ -102,7 +102,7 @@ public class NetworksWebScriptGet extends ApiWebScript
{
// TODO this is not ideal, but the only way to populate the embedded network entities (this would normally be
// done automatically by the api framework).
Object wrapped = helper.processAdditionsToTheResponse(Api.ALFRESCO_PUBLIC, NetworksEntityResource.NAME, Params.valueOf(personId, null, req), networkMember);
Object wrapped = helper.processAdditionsToTheResponse(res, Api.ALFRESCO_PUBLIC, NetworksEntityResource.NAME, Params.valueOf(personId, null, req), networkMember);
entities.add(wrapped);
}

View File

@@ -30,6 +30,7 @@ import org.alfresco.rest.framework.core.ResourceWithMetadata;
import org.alfresco.rest.framework.resource.content.ContentInfo;
import org.alfresco.rest.framework.resource.parameters.Params;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* Executes an action in the system
@@ -40,22 +41,12 @@ public interface ActionExecutor extends HttpMethodSupport
{
/**
* Invokes the resource with the Params calling the callback onSuccess
* Invokes the resource with the Params
* @param resource ResourceWithMetadata
* @param params Params
* @param executionCallback ExecutionCallback
* @param boolean should we use a readonly transaction.
*/
@SuppressWarnings("rawtypes")
public void execute(ResourceWithMetadata resource, Params params, ExecutionCallback executionCallback);
/**
* The result of an Action execution.
*
* @author Gethin James
*/
public interface ExecutionCallback<R>
{
public void onSuccess(R result, ContentInfo contentInfo, int statusCode);
}
public Object execute(ResourceWithMetadata resource, Params params, WebScriptResponse res, boolean isReadOnly);
}

View File

@@ -30,6 +30,8 @@ import java.util.List;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
/**
* Permissible actions for an Entity Resource
@@ -70,7 +72,9 @@ public interface EntityResourceAction
*/
public static interface ReadById<E> extends ResourceAction
{
public E readById (String id, Parameters parameters) throws EntityNotFoundException;
public E readById (String id, Parameters parameters) throws EntityNotFoundException;
// public E readById (String id, Parameters parameters, Status status, Cache cache) throws EntityNotFoundException;
}
/**

View File

@@ -30,10 +30,13 @@ import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.web.scripts.content.ContentStreamer;
import org.alfresco.rest.framework.Api;
import org.alfresco.rest.framework.core.HttpMethodSupport;
import org.alfresco.rest.framework.core.ResourceInspector;
import org.alfresco.rest.framework.core.ResourceLocator;
import org.alfresco.rest.framework.core.ResourceOperation;
import org.alfresco.rest.framework.core.ResourceWithMetadata;
import org.alfresco.rest.framework.core.exceptions.ApiException;
import org.alfresco.rest.framework.jacksonextensions.JacksonHelper;
@@ -51,6 +54,7 @@ import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.extensions.surf.util.URLEncoder;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Description;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
@@ -95,42 +99,12 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
final ResourceWithMetadata resource = locator.locateResource(api,templateVars, httpMethod);
final Params params = paramsExtractor.extractParams(resource.getMetaData(),req);
final ActionExecutor executor = findExecutor(httpMethod, params, resource, req.getContentType());
final boolean isReadOnly = HttpMethod.GET==httpMethod;
//This execution usually takes place in a Retrying Transaction (see subclasses)
executor.execute(resource, params, new ExecutionCallback()
{
@Override
public void onSuccess(Object result, ContentInfo contentInfo, int statusCode)
{
respons.put("toSerialize", result);
respons.put("contentInfo", contentInfo);
if (result instanceof NodeBinaryResource)
{
String attachFileName = ((NodeBinaryResource)result).getAttachFileName();
if ((attachFileName != null) && (attachFileName.length() > 0))
{
String headerValue = "attachment; filename=\"" + attachFileName + "\"; filename*=UTF-8''" + URLEncoder.encode(attachFileName);
res.setHeader(HDR_NAME_CONTENT_DISPOSITION, headerValue);
}
}
// The response status must be set before the response is written by Jackson (which will by default close and commit the response).
// In a r/w txn, web script buffered responses ensure that it doesn't really matter but for r/o txns this is important.
res.setStatus(statusCode);
}
});
final Object toSerialize = executor.execute(resource, params, res, isReadOnly);
//Outside the transaction.
final Object toSerialize = respons.get("toSerialize");
ContentInfo contentInfo = (ContentInfo) respons.get("contentInfo");
// set caching (MNT-13938)
res.setCache(ApiWebScript.CACHE_NEVER);
// set content info
setContentInfoOnResponse(res, contentInfo);
if (toSerialize != null)
{
if (toSerialize instanceof BinaryResource)
@@ -176,6 +150,26 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
}
}
@Override
public Object execute(final ResourceWithMetadata resource, final Params params, final WebScriptResponse res, boolean isReadOnly)
{
final String entityCollectionName = ResourceInspector.findEntityCollectionNameName(resource.getMetaData());
return transactionService.getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
{
@Override
public Object execute() throws Throwable
{
final ResourceOperation operation = resource.getMetaData().getOperation(getHttpMethod());
Object result = executeAction(resource, params);
setResponse(res,operation.getSuccessStatus(),ApiWebScript.CACHE_NEVER, DEFAULT_JSON_CONTENT);
return helper.processAdditionsToTheResponse(res, resource.getMetaData().getApi(), entityCollectionName, params, result);
}
}, isReadOnly, true);
}
protected abstract Object executeAction(ResourceWithMetadata resource, Params params) throws Throwable;
protected void streamResponse(final WebScriptRequest req, final WebScriptResponse res, BinaryResource resource) throws IOException
{
if (resource instanceof FileBinaryResource)
@@ -186,9 +180,31 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
else if (resource instanceof NodeBinaryResource)
{
NodeBinaryResource nodeResource = (NodeBinaryResource) resource;
ContentInfo contentInfo = nodeResource.getContentInfo();
setContentInfoOnResponse(res,contentInfo);
String attachFileName = nodeResource.getAttachFileName();
if ((attachFileName != null) && (attachFileName.length() > 0))
{
String headerValue = "attachment; filename=\"" + attachFileName + "\"; filename*=UTF-8''" + URLEncoder.encode(attachFileName);
res.setHeader(HDR_NAME_CONTENT_DISPOSITION, headerValue);
}
streamer.streamContent(req, res, nodeResource.getNodeRef(), nodeResource.getPropertyQName(), false, null, null);
}
}
/**
* The response status must be set before the response is written by Jackson (which will by default close and commit the response).
* In a r/w txn, web script buffered responses ensure that it doesn't really matter but for r/o txns this is important.
* @param res
* @param status
* @param cache
* @param contentInfo
*/
protected void setResponse(final WebScriptResponse res, int status, Cache cache, ContentInfo contentInfo)
{
res.setStatus(status);
res.setCache(cache);
setContentInfoOnResponse(res,contentInfo);
}
/**

View File

@@ -38,7 +38,6 @@ import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResou
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
import org.alfresco.rest.framework.resource.parameters.Params;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.http.HttpMethod;
@@ -113,7 +112,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
* @param params parameters to use
* @return anObject the result of the execute
*/
private void executeInternal(ResourceWithMetadata resource, Params params)
public Object executeAction(ResourceWithMetadata resource, Params params)
{
switch (resource.getMetaData().getType())
{
@@ -125,7 +124,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
EntityResourceAction.Delete entityDeleter = (EntityResourceAction.Delete) resource.getResource();
entityDeleter.delete(params.getEntityId(), params);
//Don't pass anything to the callback - its just successful
return;
return null;
case RELATIONSHIP:
if (resource.getMetaData().isDeleted(RelationshipResourceAction.Delete.class))
{
@@ -134,7 +133,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
RelationshipResourceAction.Delete relationDeleter = (RelationshipResourceAction.Delete) resource.getResource();
relationDeleter.delete(params.getEntityId(), params.getRelationshipId(), params);
//Don't pass anything to the callback - its just successful
return;
return null;
case PROPERTY:
if (BinaryResourceAction.Delete.class.isAssignableFrom(resource.getResource().getClass()))
{
@@ -145,7 +144,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
BinaryResourceAction.Delete binDeleter = (BinaryResourceAction.Delete) resource.getResource();
binDeleter.deleteProperty(params.getEntityId(), params);
//Don't pass anything to the callback - its just successful
return;
return null;
}
if (RelationshipResourceBinaryAction.Delete.class.isAssignableFrom(resource.getResource().getClass()))
{
@@ -156,7 +155,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
RelationshipResourceBinaryAction.Delete binDeleter = (RelationshipResourceBinaryAction.Delete) resource.getResource();
binDeleter.deleteProperty(params.getEntityId(), params.getRelationshipId(), params);
//Don't pass anything to the callback - its just successful
return;
return null;
}
default:
throw new UnsupportedResourceOperationException("DELETE not supported for Actions");
@@ -164,7 +163,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
}
@Override
public void execute(final ResourceWithMetadata resource, final Params params, final ExecutionCallback executionCallback)
public Void execute(final ResourceWithMetadata resource, final Params params, final WebScriptResponse res, boolean isReadOnly)
{
transactionService.getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionCallback<Void>()
@@ -173,11 +172,12 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
public Void execute() throws Throwable
{
final ResourceOperation operation = resource.getMetaData().getOperation(HttpMethod.DELETE);
executeInternal(resource, params); //ignore return result
executionCallback.onSuccess(null, DEFAULT_JSON_CONTENT, operation.getSuccessStatus());
executeAction(resource, params); //ignore return result
setResponse(res,operation.getSuccessStatus(),ApiWebScript.CACHE_NEVER, DEFAULT_JSON_CONTENT);
return null;
}
}, false, true);
return null;
}
}

View File

@@ -50,6 +50,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.http.HttpMethod;
/**
@@ -122,7 +123,8 @@ public class ResourceWebScriptGet extends AbstractResourceWebScript implements P
* @param params parameters to use
* @return anObject the result of the execute
*/
private Object executeInternal(ResourceWithMetadata resource, Params params)
@Override
public Object executeAction(ResourceWithMetadata resource, Params params) throws Throwable
{
switch (resource.getMetaData().getType())
@@ -226,34 +228,5 @@ public class ResourceWebScriptGet extends AbstractResourceWebScript implements P
}
}
@Override
public void execute(final ResourceWithMetadata resource, final Params params, final ExecutionCallback executionCallback)
{
final String entityCollectionName = ResourceInspector.findEntityCollectionNameName(resource.getMetaData());
transactionService.getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionCallback<Void>()
{
@Override
public Void execute() throws Throwable
{
final ResourceOperation operation = resource.getMetaData().getOperation(HttpMethod.GET);
Object result = executeInternal(resource, params);
if (result instanceof BinaryResource)
{
ContentInfo ci = null;
if (result instanceof NodeBinaryResource)
{
ci = ((NodeBinaryResource)result).getContentInfo();
}
executionCallback.onSuccess(result, ci, operation.getSuccessStatus());
}
else
{
executionCallback.onSuccess(helper.processAdditionsToTheResponse(resource.getMetaData().getApi(), entityCollectionName, params, result), DEFAULT_JSON_CONTENT, operation.getSuccessStatus());
}
return null;
}
}, true, true); //Read only
}
}

View File

@@ -57,7 +57,6 @@ import org.alfresco.rest.framework.jacksonextensions.ExecutionResult;
import org.alfresco.rest.framework.jacksonextensions.JacksonHelper;
import org.alfresco.rest.framework.resource.SerializablePagedCollection;
import org.alfresco.rest.framework.resource.actions.ActionExecutor;
import org.alfresco.rest.framework.resource.actions.ActionExecutor.ExecutionCallback;
import org.alfresco.rest.framework.resource.content.ContentInfo;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.InvalidSelectException;
@@ -81,6 +80,7 @@ import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.map.JsonMappingException;
import org.springframework.beans.BeanUtils;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.http.HttpMethod;
/**
@@ -479,20 +479,20 @@ public class ResourceWebScriptHelper
* @param objectToWrap Object
* @return Object - Either ExecutionResult or CollectionWithPagingInfo<ExecutionResult>
*/
public Object processAdditionsToTheResponse(Api api, String entityCollectionName, Params params, Object objectToWrap)
public Object processAdditionsToTheResponse(WebScriptResponse res, Api api, String entityCollectionName, Params params, Object objectToWrap)
{
PropertyCheck.mandatory(this, null, params);
if (objectToWrap == null ) return null;
if (objectToWrap instanceof SerializablePagedCollection<?>)
{
SerializablePagedCollection<?> collectionToWrap = (SerializablePagedCollection<?>) objectToWrap;
Object sourceEntity = executeIncludedSource(api, params, entityCollectionName);
Object sourceEntity = executeIncludedSource(res, api, params, entityCollectionName);
Collection<Object> resultCollection = new ArrayList(collectionToWrap.getCollection().size());
if (!collectionToWrap.getCollection().isEmpty())
{
for (Object obj : collectionToWrap.getCollection())
{
resultCollection.add(processAdditionsToTheResponse(api,entityCollectionName,params,obj));
resultCollection.add(processAdditionsToTheResponse(res, api,entityCollectionName,params,obj));
}
}
return CollectionWithPagingInfo.asPaged(collectionToWrap.getPaging(), resultCollection, collectionToWrap.hasMoreItems(), collectionToWrap.getTotalItems(), sourceEntity);
@@ -510,7 +510,7 @@ public class ResourceWebScriptHelper
Map<String,Pair<String,Method>> embeddded = ResourceInspector.findEmbeddedResources(objectToWrap.getClass());
if (embeddded != null && !embeddded.isEmpty())
{
Map<String, Object> results = executeEmbeddedResources(api, params,objectToWrap, embeddded);
Map<String, Object> results = executeEmbeddedResources(res, api, params,objectToWrap, embeddded);
execRes.addEmbedded(results);
}
@@ -518,7 +518,7 @@ public class ResourceWebScriptHelper
{
Map<String, ResourceWithMetadata> relationshipResources = locator.locateRelationResource(api,entityCollectionName, params.getRelationsFilter().keySet(), HttpMethod.GET);
String uniqueEntityId = ResourceInspector.findUniqueId(objectToWrap);
Map<String,Object> relatedResources = executeRelatedResources(api, params, relationshipResources, uniqueEntityId);
Map<String,Object> relatedResources = executeRelatedResources(res, api, params, relationshipResources, uniqueEntityId);
execRes.addRelated(relatedResources);
}
@@ -527,14 +527,14 @@ public class ResourceWebScriptHelper
}
}
private Object executeIncludedSource(Api api, Params params, String entityCollectionName)
private Object executeIncludedSource(WebScriptResponse response, Api api, Params params, String entityCollectionName)
{
if (params.includeSource())
{
ResourceWithMetadata res = locator.locateEntityResource(api, entityCollectionName, HttpMethod.GET);
if (res != null)
{
Object result = executeRelatedResource(api, params, params.getEntityId(), null, res);
Object result = executeRelatedResource(response, api, params, params.getEntityId(), null, res);
if (result!=null && result instanceof ExecutionResult) return ((ExecutionResult) result).getRoot();
}
}
@@ -551,7 +551,7 @@ public class ResourceWebScriptHelper
* @param embeddded Map<String, Pair<String, Method>>
* @return Map
*/
private Map<String, Object> executeEmbeddedResources(Api api, Params params, Object objectToWrap, Map<String, Pair<String, Method>> embeddded)
private Map<String, Object> executeEmbeddedResources(WebScriptResponse response, Api api, Params params, Object objectToWrap, Map<String, Pair<String, Method>> embeddded)
{
final Map<String,Object> results = new HashMap<String,Object>(embeddded.size());
for (Entry<String, Pair<String,Method>> embeddedEntry : embeddded.entrySet())
@@ -562,7 +562,7 @@ public class ResourceWebScriptHelper
Object id = ResourceInspectorUtil.invokeMethod(embeddedEntry.getValue().getSecond(), objectToWrap);
if (id != null)
{
Object execEmbeddedResult = executeRelatedResource(api, params, String.valueOf(id), embeddedEntry.getKey(), res);
Object execEmbeddedResult = executeRelatedResource(response, api, params, String.valueOf(id), embeddedEntry.getKey(), res);
if (execEmbeddedResult != null)
{
if (execEmbeddedResult instanceof ExecutionResult)
@@ -592,14 +592,14 @@ public class ResourceWebScriptHelper
* @param uniqueEntityId String
* @return Map
*/
private Map<String,Object> executeRelatedResources(final Api api, Params params,
private Map<String,Object> executeRelatedResources(final WebScriptResponse res, final Api api, Params params,
Map<String, ResourceWithMetadata> relatedResources,
String uniqueEntityId)
{
final Map<String,Object> results = new HashMap<String,Object>(relatedResources.size());
for (final Entry<String, ResourceWithMetadata> relation : relatedResources.entrySet())
{
Object execResult = executeRelatedResource(api, params, uniqueEntityId, relation.getKey(), relation.getValue());
Object execResult = executeRelatedResource(res, api, params, uniqueEntityId, relation.getKey(), relation.getValue());
if (execResult != null)
{
results.put(relation.getKey(), execResult);
@@ -619,7 +619,7 @@ public class ResourceWebScriptHelper
* @param resource ResourceWithMetadata
* @return Object
*/
private Object executeRelatedResource(final Api api, Params params,
private Object executeRelatedResource(final WebScriptResponse res, final Api api, Params params,
final String uniqueEntityId, final String resourceKey, final ResourceWithMetadata resource)
{
try
@@ -632,17 +632,8 @@ public class ResourceWebScriptHelper
paramFilter = filters.get(resourceKey);
}
final Params executionParams = Params.valueOf(paramFilter, uniqueEntityId, params.getRequest());
executor.execute(resource, executionParams, new ExecutionCallback()
{
@Override
public void onSuccess(Object result, ContentInfo contentInfo, int statusCode)
{
resultOfExecution[0] = result;
}
});
return resultOfExecution[0];
//Read only because this only occurs for GET requests
return executor.execute(resource, executionParams,res, true);
}
catch(NotFoundException e)
{

View File

@@ -216,8 +216,8 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
* @param params parameters to use
* @return anObject the result of the execute
*/
@SuppressWarnings("unchecked")
private Object executeInternal(ResourceWithMetadata resource, Params params) throws Throwable
@Override
public Object executeAction(ResourceWithMetadata resource, Params params) throws Throwable
{
final Object resObj = resource.getResource();
@@ -294,24 +294,4 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
}
}
@Override
public void execute(final ResourceWithMetadata resource, final Params params, final ExecutionCallback executionCallback)
{
final String entityCollectionName = ResourceInspector.findEntityCollectionNameName(resource.getMetaData());
transactionService.getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionCallback<Void>()
{
@SuppressWarnings("unchecked")
@Override
public Void execute() throws Throwable
{
final ResourceOperation operation = resource.getMetaData().getOperation(HttpMethod.POST);
Object result = executeInternal(resource, params);
executionCallback.onSuccess(helper.processAdditionsToTheResponse(resource.getMetaData().getApi(), entityCollectionName, params, result),
DEFAULT_JSON_CONTENT, operation.getSuccessStatus());
return null;
}
}, false, true);
}
}

View File

@@ -52,6 +52,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.extensions.webscripts.WrappingWebScriptRequest;
import org.springframework.extensions.webscripts.servlet.WebScriptServletRequest;
import org.springframework.http.HttpMethod;
@@ -184,8 +185,8 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
* @param params parameters to use
* @return anObject the result of the execute
*/
@SuppressWarnings("unchecked")
private Object executeInternal(ResourceWithMetadata resource, Params params)
@Override
public Object executeAction(ResourceWithMetadata resource, Params params) throws Throwable
{
switch (resource.getMetaData().getType())
{
@@ -229,23 +230,4 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
}
}
@Override
public void execute(final ResourceWithMetadata resource, final Params params, final ExecutionCallback executionCallback)
{
final String entityCollectionName = ResourceInspector.findEntityCollectionNameName(resource.getMetaData());
transactionService.getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionCallback<Void>()
{
@Override
public Void execute() throws Throwable
{
final ResourceOperation operation = resource.getMetaData().getOperation(HttpMethod.PUT);
Object result = executeInternal(resource, params);
executionCallback.onSuccess(helper.processAdditionsToTheResponse(resource.getMetaData().getApi(), entityCollectionName, params, result),
DEFAULT_JSON_CONTENT, operation.getSuccessStatus());
return null;
}
}, false, true);
}
}