mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-21 18:09:20 +00:00
Merged API-STRIKES-BACK (5.2.0) to HEAD (5.2)
126242 gjames: RA-878:All api errors should return the standard error object git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@127571 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -45,6 +45,7 @@ import org.alfresco.rest.framework.resource.content.ContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.FileBinaryResource;
|
||||
import org.alfresco.rest.framework.resource.content.NodeBinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -145,11 +146,11 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
}
|
||||
catch (AlfrescoRuntimeException | ApiException | WebScriptException xception )
|
||||
{
|
||||
renderErrorResponse(resolveException(xception), res);
|
||||
assistant.renderException(xception, res);
|
||||
}
|
||||
catch (RuntimeException runtimeException)
|
||||
{
|
||||
renderErrorResponse(resolveException(runtimeException), res);
|
||||
assistant.renderException(runtimeException, res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +158,7 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
{
|
||||
final String entityCollectionName = ResourceInspector.findEntityCollectionNameName(resource.getMetaData());
|
||||
final ResourceOperation operation = resource.getMetaData().getOperation(getHttpMethod());
|
||||
final WithResponse callBack = new WithResponse(operation.getSuccessStatus(),DEFAULT_JSON_CONTENT,ApiWebScript.CACHE_NEVER);
|
||||
final WithResponse callBack = new WithResponse(operation.getSuccessStatus(), ApiAssistant.DEFAULT_JSON_CONTENT,ApiAssistant.CACHE_NEVER);
|
||||
Object toReturn = transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
|
||||
{
|
||||
@@ -191,7 +192,7 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
{
|
||||
NodeBinaryResource nodeResource = (NodeBinaryResource) resource;
|
||||
ContentInfo contentInfo = nodeResource.getContentInfo();
|
||||
setContentInfoOnResponse(res, contentInfo);
|
||||
assistant.setContentInfoOnResponse(res, contentInfo);
|
||||
// if requested, set attachment
|
||||
boolean attach = StringUtils.isNotEmpty(nodeResource.getAttachFileName());
|
||||
Map<String, Object> model = getModelForCacheDirective(nodeResource.getCacheDirective());
|
||||
@@ -226,7 +227,7 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
{
|
||||
res.setStatus(status);
|
||||
if (cache != null) res.setCache(cache);
|
||||
setContentInfoOnResponse(res,contentInfo);
|
||||
assistant.setContentInfoOnResponse(res,contentInfo);
|
||||
if (headers != null && !headers.isEmpty())
|
||||
{
|
||||
for (Map.Entry<String, List<String>> header:headers.entrySet())
|
||||
@@ -262,7 +263,7 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
protected void renderJsonResponse(final WebScriptResponse res, final Object toSerialize)
|
||||
throws IOException
|
||||
{
|
||||
jsonHelper.withWriter(res.getOutputStream(), new JacksonHelper.Writer()
|
||||
assistant.getJsonHelper().withWriter(res.getOutputStream(), new JacksonHelper.Writer()
|
||||
{
|
||||
@Override
|
||||
public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
|
||||
|
@@ -32,6 +32,7 @@ import org.alfresco.rest.framework.jacksonextensions.JacksonHelper;
|
||||
import org.alfresco.rest.framework.jacksonextensions.JacksonHelper.Writer;
|
||||
import org.alfresco.rest.framework.resource.content.ContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.ContentInfoImpl;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
@@ -57,10 +58,7 @@ import org.springframework.extensions.webscripts.servlet.WebScriptServletRespons
|
||||
public abstract class ApiWebScript extends AbstractWebScript
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ApiWebScript.class);
|
||||
protected JacksonHelper jsonHelper;
|
||||
ExceptionResolver<Exception> defaultResolver = new DefaultExceptionResolver();
|
||||
ExceptionResolver<Exception> resolver;
|
||||
|
||||
protected ApiAssistant assistant;
|
||||
protected boolean encryptTempFiles = false;
|
||||
protected String tempDirectoryName = null;
|
||||
protected int memoryThreshold = 4 * 1024 * 1024; // 4mb
|
||||
@@ -73,9 +71,8 @@ public abstract class ApiWebScript extends AbstractWebScript
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
public void setDefaultResolver(ExceptionResolver<Exception> defaultResolver)
|
||||
{
|
||||
this.defaultResolver = defaultResolver;
|
||||
public void setAssistant(ApiAssistant assistant) {
|
||||
this.assistant = assistant;
|
||||
}
|
||||
|
||||
public void setTempDirectoryName(String tempDirectoryName)
|
||||
@@ -102,41 +99,18 @@ public abstract class ApiWebScript extends AbstractWebScript
|
||||
{
|
||||
this.streamFactory = streamFactory;
|
||||
}
|
||||
|
||||
|
||||
public void init()
|
||||
{
|
||||
File tempDirectory = TempFileProvider.getTempDir(tempDirectoryName);
|
||||
this.streamFactory = ThresholdOutputStreamFactory.newInstance(tempDirectory, memoryThreshold, maxContentSize, encryptTempFiles);
|
||||
}
|
||||
|
||||
public final static String UTF8 = "UTF-8";
|
||||
public final static Cache CACHE_NEVER = new Cache(new RequiredCache()
|
||||
{
|
||||
@Override
|
||||
public boolean getNeverCache()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIsPublic()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMustRevalidate()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
});
|
||||
public final static ContentInfo DEFAULT_JSON_CONTENT = new ContentInfoImpl(Format.JSON.mimetype(),UTF8, 0, null);
|
||||
|
||||
@Override
|
||||
public void execute(final WebScriptRequest req, final WebScriptResponse res) throws IOException
|
||||
{
|
||||
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
|
||||
Api api = determineApi(templateVars);
|
||||
Api api = assistant.determineApi(templateVars);
|
||||
|
||||
final BufferedRequest bufferedReq = getRequest(req);
|
||||
final BufferedResponse bufferedRes = getResponse(res);
|
||||
@@ -161,24 +135,6 @@ public abstract class ApiWebScript extends AbstractWebScript
|
||||
}
|
||||
}
|
||||
|
||||
public Api determineApi(Map<String, String> templateVars)
|
||||
{
|
||||
String apiScope = templateVars.get("apiScope");
|
||||
String apiVersion = templateVars.get("apiVersion");
|
||||
String apiName = templateVars.get("apiName");
|
||||
return Api.valueOf(apiName,apiScope,apiVersion);
|
||||
}
|
||||
|
||||
protected ErrorResponse resolveException(Exception ex)
|
||||
{
|
||||
ErrorResponse error = resolver.resolveException(ex);
|
||||
if (error == null)
|
||||
{
|
||||
error = defaultResolver.resolveException(ex);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
protected BufferedRequest getRequest(final WebScriptRequest req)
|
||||
{
|
||||
// create buffered request and response that allow transaction retrying
|
||||
@@ -195,97 +151,4 @@ public abstract class ApiWebScript extends AbstractWebScript
|
||||
|
||||
public abstract void execute(final Api api, WebScriptRequest req, WebScriptResponse res) throws IOException;
|
||||
|
||||
/**
|
||||
* Renders a JSON error response
|
||||
* @param errorResponse The error
|
||||
* @param res web script response
|
||||
* @throws IOException
|
||||
*/
|
||||
public void renderErrorResponse(ErrorResponse errorResponse, final WebScriptResponse res) throws IOException {
|
||||
|
||||
String logId = "";
|
||||
|
||||
if (Status.STATUS_INTERNAL_SERVER_ERROR == errorResponse.getStatusCode() || logger.isDebugEnabled())
|
||||
{
|
||||
logId = GUID.generate();
|
||||
logger.error(logId+" : "+errorResponse.getStackTrace());
|
||||
}
|
||||
|
||||
String stackMessage = I18NUtil.getMessage(DefaultExceptionResolver.STACK_MESSAGE_ID);
|
||||
|
||||
final ErrorResponse errorToWrite = new ErrorResponse(errorResponse.getErrorKey(),
|
||||
errorResponse.getStatusCode(),
|
||||
errorResponse.getBriefSummary(),
|
||||
stackMessage,
|
||||
logId,
|
||||
errorResponse.getAdditionalState(),
|
||||
DefaultExceptionResolver.ERROR_URL);
|
||||
|
||||
setContentInfoOnResponse(res, DEFAULT_JSON_CONTENT);
|
||||
|
||||
// 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(errorToWrite.getStatusCode());
|
||||
|
||||
jsonHelper.withWriter(res.getOutputStream(), new Writer()
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
|
||||
throws JsonGenerationException, JsonMappingException, IOException
|
||||
{
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("error", errorToWrite);
|
||||
objectMapper.writeValue(generator, obj);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the response headers with any information we know about the content
|
||||
* @param res WebScriptResponse
|
||||
* @param contentInfo Content Information
|
||||
*/
|
||||
protected void setContentInfoOnResponse(WebScriptResponse res, ContentInfo contentInfo)
|
||||
{
|
||||
if (contentInfo != null)
|
||||
{
|
||||
//Set content info on the response
|
||||
res.setContentType(contentInfo.getMimeType());
|
||||
res.setContentEncoding(contentInfo.getEncoding());
|
||||
|
||||
if (res instanceof WrappingWebScriptResponse)
|
||||
{
|
||||
WrappingWebScriptResponse wrappedRes = ((WrappingWebScriptResponse) res);
|
||||
res = wrappedRes.getNext();
|
||||
}
|
||||
|
||||
if (res instanceof WebScriptServletResponse)
|
||||
{
|
||||
WebScriptServletResponse servletResponse = (WebScriptServletResponse) res;
|
||||
if (contentInfo.getLength() > 0)
|
||||
{
|
||||
if (contentInfo.getLength() > 0 && contentInfo.getLength() < Integer.MAX_VALUE)
|
||||
{
|
||||
servletResponse.getHttpServletResponse().setContentLength((int) contentInfo.getLength());
|
||||
}
|
||||
}
|
||||
if (contentInfo.getLocale() != null)
|
||||
{
|
||||
servletResponse.getHttpServletResponse().setLocale(contentInfo.getLocale());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setResolver(ExceptionResolver<Exception> resolver)
|
||||
{
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public void setJsonHelper(JacksonHelper jsonHelper)
|
||||
{
|
||||
this.jsonHelper = jsonHelper;
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAct
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||
@@ -189,7 +190,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
|
||||
public Void execute(final ResourceWithMetadata resource, final Params params, final WebScriptResponse res, boolean isReadOnly)
|
||||
{
|
||||
final ResourceOperation operation = resource.getMetaData().getOperation(HttpMethod.DELETE);
|
||||
final WithResponse callBack = new WithResponse(operation.getSuccessStatus(),DEFAULT_JSON_CONTENT,ApiWebScript.CACHE_NEVER);
|
||||
final WithResponse callBack = new WithResponse(operation.getSuccessStatus(), ApiAssistant.DEFAULT_JSON_CONTENT,ApiAssistant.CACHE_NEVER);
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(
|
||||
new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
|
@@ -58,6 +58,7 @@ import org.alfresco.rest.framework.resource.parameters.where.InvalidQueryExcepti
|
||||
import org.alfresco.rest.framework.resource.parameters.where.Query;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.QueryImpl;
|
||||
import org.alfresco.rest.framework.resource.parameters.where.WhereCompiler;
|
||||
import org.alfresco.rest.framework.tools.ApiAssistant;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
@@ -668,7 +669,7 @@ public class ResourceWebScriptHelper
|
||||
paramFilter = filters.get(resourceKey);
|
||||
}
|
||||
final Params executionParams = Params.valueOf(paramFilter, uniqueEntityId, params.getRequest());
|
||||
final WithResponse callBack = new WithResponse(Status.STATUS_OK,ApiWebScript.DEFAULT_JSON_CONTENT,ApiWebScript.CACHE_NEVER);
|
||||
final WithResponse callBack = new WithResponse(Status.STATUS_OK, ApiAssistant.DEFAULT_JSON_CONTENT,ApiAssistant.CACHE_NEVER);
|
||||
//Read only because this only occurs for GET requests
|
||||
Object result = executor.executeAction(resource, executionParams, callBack);
|
||||
return processAdditionsToTheResponse(null, api, null, executionParams, result);
|
||||
|
@@ -102,7 +102,7 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
if (objectType!= null)
|
||||
{
|
||||
//Operations don't support a List as json body
|
||||
postedObj = ResourceWebScriptHelper.extractJsonContent(req, jsonHelper, objectType);
|
||||
postedObj = ResourceWebScriptHelper.extractJsonContent(req, assistant.getJsonHelper(), objectType);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(propertyName))
|
||||
@@ -156,7 +156,7 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
// Only allow 1 value.
|
||||
try
|
||||
{
|
||||
Object content = ResourceWebScriptHelper.extractJsonContent(req,jsonHelper, objType);
|
||||
Object content = ResourceWebScriptHelper.extractJsonContent(req,assistant.getJsonHelper(), objType);
|
||||
return Arrays.asList(content);
|
||||
}
|
||||
catch (InvalidArgumentException iae)
|
||||
@@ -173,7 +173,7 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
|
||||
}
|
||||
}
|
||||
}
|
||||
return ResourceWebScriptHelper.extractJsonContentAsList(req, jsonHelper, objType);
|
||||
return ResourceWebScriptHelper.extractJsonContentAsList(req, assistant.getJsonHelper(), objType);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -81,7 +81,7 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
|
||||
} else
|
||||
{
|
||||
|
||||
Object putEnt = ResourceWebScriptHelper.extractJsonContent(req, jsonHelper, resourceMeta.getObjectType(operation));
|
||||
Object putEnt = ResourceWebScriptHelper.extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
|
||||
return Params.valueOf(entityId,params,putEnt, req);
|
||||
}
|
||||
case RELATIONSHIP:
|
||||
@@ -90,7 +90,7 @@ public class ResourceWebScriptPut extends AbstractResourceWebScript implements P
|
||||
throw new UnsupportedResourceOperationException("PUT is executed against the instance URL");
|
||||
} else
|
||||
{
|
||||
Object putRel = ResourceWebScriptHelper.extractJsonContent(req, jsonHelper, resourceMeta.getObjectType(operation));
|
||||
Object putRel = ResourceWebScriptHelper.extractJsonContent(req, assistant.getJsonHelper(), resourceMeta.getObjectType(operation));
|
||||
ResourceWebScriptHelper.setUniqueId(putRel,relationshipId);
|
||||
return Params.valueOf(entityId, params, putRel, req);
|
||||
}
|
||||
|
@@ -52,8 +52,8 @@ public class InfoWebScriptGet extends ApiWebScript
|
||||
{
|
||||
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_INVALID_API);
|
||||
}
|
||||
|
||||
jsonHelper.withWriter(res.getOutputStream(), new Writer()
|
||||
|
||||
assistant.getJsonHelper().withWriter(res.getOutputStream(), new Writer()
|
||||
{
|
||||
@Override
|
||||
public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
|
||||
|
@@ -130,8 +130,8 @@ public class WebScriptOptionsMetaData extends ApiWebScript implements ResourceMe
|
||||
{
|
||||
|
||||
final Object result = processResult(resource,allApiResources);
|
||||
|
||||
jsonHelper.withWriter(out, new Writer()
|
||||
|
||||
assistant.getJsonHelper().withWriter(out, new Writer()
|
||||
{
|
||||
@Override
|
||||
public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
|
||||
|
Reference in New Issue
Block a user