Repository: falcon Updated Branches: refs/heads/master c2a802b40 -> 7c0481eac
FALCON-1105 REST API support for Server side extensions artifact repository management REST API support for Server side extensions artifact repository management. Fixed the warnings in the file. Author: Sowmya Ramesh <[email protected]> Reviewers: "Balu<[email protected]>, Ying Zheng<[email protected]>" Closes #102 from sowmyaramesh/FALCON-1105 Project: http://git-wip-us.apache.org/repos/asf/falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/7c0481ea Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/7c0481ea Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/7c0481ea Branch: refs/heads/master Commit: 7c0481eac4793102bb5124d60db14fb6fd30100c Parents: c2a802b Author: Sowmya Ramesh <[email protected]> Authored: Thu Apr 21 15:18:43 2016 -0700 Committer: Sowmya Ramesh <[email protected]> Committed: Thu Apr 21 15:18:43 2016 -0700 ---------------------------------------------------------------------- .../falcon/extensions/store/ExtensionStore.java | 13 +- .../resource/extensions/ExtensionManager.java | 158 ++++++++++++++++--- 2 files changed, 147 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/falcon/blob/7c0481ea/extensions/src/main/java/org/apache/falcon/extensions/store/ExtensionStore.java ---------------------------------------------------------------------- diff --git a/extensions/src/main/java/org/apache/falcon/extensions/store/ExtensionStore.java b/extensions/src/main/java/org/apache/falcon/extensions/store/ExtensionStore.java index 9e07112..2c2e3c6 100644 --- a/extensions/src/main/java/org/apache/falcon/extensions/store/ExtensionStore.java +++ b/extensions/src/main/java/org/apache/falcon/extensions/store/ExtensionStore.java @@ -53,8 +53,8 @@ public final class ExtensionStore { private Path storePath; // Convention over configuration design paradigm - private static final String RESOURCES_DIR= "resources"; - private static final String LIBS_DIR= "libs"; + private static final String RESOURCES_DIR = "resources"; + private static final String LIBS_DIR = "libs"; private static final String EXTENSION_STORE_URI = "extension.store.uri"; @@ -204,6 +204,15 @@ public final class ExtensionStore { return extesnionList; } + public String getResource(final String extensionName, final String resourceName) throws StoreAccessException { + Map<String, String> resources = getExtensionArtifacts(extensionName); + if (resources.isEmpty()) { + throw new StoreAccessException(new Exception("No extension resources found for " + extensionName)); + } + + return getExtensionResource(resources.get(resourceName)); + } + public Path getExtensionStorePath() { return storePath; } http://git-wip-us.apache.org/repos/asf/falcon/blob/7c0481ea/prism/src/main/java/org/apache/falcon/resource/extensions/ExtensionManager.java ---------------------------------------------------------------------- diff --git a/prism/src/main/java/org/apache/falcon/resource/extensions/ExtensionManager.java b/prism/src/main/java/org/apache/falcon/resource/extensions/ExtensionManager.java index 07d4217..c9be472 100644 --- a/prism/src/main/java/org/apache/falcon/resource/extensions/ExtensionManager.java +++ b/prism/src/main/java/org/apache/falcon/resource/extensions/ExtensionManager.java @@ -18,38 +18,43 @@ package org.apache.falcon.resource.extensions; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.POST; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - import org.apache.commons.lang3.StringUtils; import org.apache.falcon.FalconException; import org.apache.falcon.FalconWebException; +import org.apache.falcon.entity.store.StoreAccessException; import org.apache.falcon.entity.v0.Entity; -import org.apache.falcon.entity.v0.process.Process; -import org.apache.falcon.entity.v0.feed.Feed; import org.apache.falcon.entity.v0.cluster.Cluster; +import org.apache.falcon.entity.v0.feed.Feed; +import org.apache.falcon.entity.v0.process.Process; +import org.apache.falcon.extensions.AbstractExtension; import org.apache.falcon.extensions.Extension; import org.apache.falcon.extensions.ExtensionProperties; +import org.apache.falcon.extensions.store.ExtensionStore; import org.apache.falcon.resource.APIResult; import org.apache.falcon.resource.AbstractSchedulableEntityManager; import org.apache.falcon.resource.EntityList; -import org.apache.falcon.resource.ExtensionJobList; import org.apache.falcon.resource.ExtensionInstanceList; +import org.apache.falcon.resource.ExtensionJobList; import org.apache.falcon.resource.InstancesResult; import org.apache.falcon.util.DeploymentUtil; +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -74,6 +79,18 @@ public class ExtensionManager extends AbstractSchedulableEntityManager { public static final String DESCENDING_SORT_ORDER = "desc"; private Extension extension = new Extension(); + private static final ExtensionStore STORE = ExtensionStore.get(); + private static final String EXTENSION_RESULTS = "extensions"; + private static final String TOTAL_RESULTS = "totalResults"; + private static final String README = "README"; + private static final String EXTENSION_PROPERTY_JSON_SUFFIX = "-properties.json"; + private static final String SHORT_DESCRIPTION = "shortDescription"; + private static final String EXTENSION_NAME = "name"; + private static final String EXTENSION_TYPE = "type"; + private static final String EXTENSION_DESC = "description"; + + private static final String TRUSTED_EXTENSION = "Trusted extension"; + private static final String CUSTOM_EXTENSION = "Custom extension"; //SUSPEND CHECKSTYLE CHECK ParameterNumberCheck @GET @@ -322,6 +339,103 @@ public class ExtensionManager extends AbstractSchedulableEntityManager { return new APIResult(APIResult.Status.SUCCEEDED, "Validated successfully"); } + + // Extension store related REST API's + @GET + @Path("enumerate") + @Produces({MediaType.APPLICATION_JSON}) + public Response getExtensions() { + JSONArray results; + + try { + List<String> extensions = STORE.getExtensions(); + results = buildEnumerateResult(extensions); + } catch (StoreAccessException e) { + LOG.error("Failed when accessing extension store.", e); + throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR); + } catch (FalconException e) { + throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + + try { + JSONObject response = new JSONObject(); + response.put(EXTENSION_RESULTS, results); + response.put(TOTAL_RESULTS, results.length()); + + return Response.ok(response).build(); + } catch (Throwable e) { + throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + @GET + @Path("describe/{extension-name}") + @Produces(MediaType.TEXT_PLAIN) + public String getExtensionDescription( + @PathParam("extension-name") String extensionName) { + validateExtensionName(extensionName); + try { + return STORE.getResource(extensionName, README); + } catch (Throwable e) { + throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + @GET + @Path("definition/{extension-name}") + @Produces({MediaType.APPLICATION_JSON}) + public String getExtensionDefinition( + @PathParam("extension-name") String extensionName) { + validateExtensionName(extensionName); + try { + return STORE.getResource(extensionName, + extensionName.toLowerCase() + EXTENSION_PROPERTY_JSON_SUFFIX); + } catch (Throwable e) { + throw FalconWebException.newAPIException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + private static void validateExtensionName(final String extensionName) { + if (StringUtils.isBlank(extensionName)) { + throw FalconWebException.newAPIException("Extension name is mandatory and shouldn't be blank", + Response.Status.BAD_REQUEST); + } + } + + private static JSONArray buildEnumerateResult(final List<String> extensions) throws FalconException { + JSONArray results = new JSONArray(); + + for (String extension : extensions) { + String extensionType = AbstractExtension.isExtensionTrusted(extension) ? TRUSTED_EXTENSION + : CUSTOM_EXTENSION; + + JSONObject resultObject = new JSONObject(); + + try { + resultObject.put(EXTENSION_NAME, extension.toLowerCase()); + resultObject.put(EXTENSION_TYPE, extensionType); + resultObject.put(EXTENSION_DESC, getShortDescription(extension)); + } catch (JSONException e) { + throw new FalconException(e); + } + results.put(resultObject); + + } + return results; + } + + private static String getShortDescription(final String extensionName) throws FalconException { + String content = STORE.getResource(extensionName, extensionName.toLowerCase() + EXTENSION_PROPERTY_JSON_SUFFIX); + String description; + try { + JSONObject jsonObject = new JSONObject(content); + description = (String) jsonObject.get(SHORT_DESCRIPTION); + } catch (JSONException e) { + throw new FalconException(e); + } + return description; + } + private List<Entity> generateEntities(String extensionName, HttpServletRequest request) throws FalconException, IOException { // get entities for extension job @@ -332,20 +446,20 @@ public class ExtensionManager extends AbstractSchedulableEntityManager { // add tags on extension name and job for (Entity entity : entities) { String tags = entity.getTags(); - if (StringUtils.isEmpty(tags)) { - setEntityTags(entity, TAG_PREFIX_EXTENSION_NAME + extensionName + TAG_SEPARATOR - + TAG_PREFIX_EXTENSION_JOB + properties.getProperty(ExtensionProperties.JOB_NAME.getName())); - } else { - if (tags.indexOf(TAG_PREFIX_EXTENSION_NAME) != -1) { + if (StringUtils.isNotEmpty(tags)) { + if (tags.contains(TAG_PREFIX_EXTENSION_NAME)) { throw new FalconException("Generated extention entity " + entity.getName() + " should not contain tag prefix " + TAG_PREFIX_EXTENSION_NAME); } - if (tags.indexOf(TAG_PREFIX_EXTENSION_JOB) != -1) { + if (tags.contains(TAG_PREFIX_EXTENSION_JOB)) { throw new FalconException("Generated extention entity " + entity.getName() + " should not contain tag prefix " + TAG_PREFIX_EXTENSION_JOB); } setEntityTags(entity, tags + TAG_SEPARATOR + TAG_PREFIX_EXTENSION_NAME + extensionName + TAG_SEPARATOR + TAG_PREFIX_EXTENSION_JOB + properties.getProperty(ExtensionProperties.JOB_NAME.getName())); + } else { + setEntityTags(entity, TAG_PREFIX_EXTENSION_NAME + extensionName + TAG_SEPARATOR + + TAG_PREFIX_EXTENSION_JOB + properties.getProperty(ExtensionProperties.JOB_NAME.getName())); } }
