From 07abd78261b3e51aa2626e7e854cf4209b4d3061 Mon Sep 17 00:00:00 2001 From: Yohan Avishke Date: Thu, 5 Dec 2019 08:21:07 +0530 Subject: [PATCH] Create endpoints to undeploy artifacts 4 new endpoints were created to delete each artifact and some minor changes were done to deploy of some of these artifacts. --- .../ArtifactAlreadyExistsException.java | 35 ++ .../AnalyticsArtifactsManagementService.java | 382 ++++++++++++++++-- ...alyticsArtifactsManagementServiceImpl.java | 347 ++++++++++++++-- 3 files changed, 699 insertions(+), 65 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ArtifactAlreadyExistsException.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ArtifactAlreadyExistsException.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ArtifactAlreadyExistsException.java new file mode 100644 index 0000000000..78a75331cb --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ArtifactAlreadyExistsException.java @@ -0,0 +1,35 @@ +package org.wso2.carbon.device.mgt.jaxrs.exception; + +public class ArtifactAlreadyExistsException extends Exception { + private static final long serialVersionUID = 6459451028947683202L; + private String message; + private Throwable cause; + + public ArtifactAlreadyExistsException(String message) { + this.message = message; + } + + public ArtifactAlreadyExistsException(String message, Throwable cause) { + super(message, cause); + this.message = message; + this.cause = cause; + } + + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public Throwable getCause() { + return cause; + } + + public void setCause(Throwable cause) { + this.cause = cause; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/AnalyticsArtifactsManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/AnalyticsArtifactsManagementService.java index 7e5456dadd..e2d5064a4d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/AnalyticsArtifactsManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/AnalyticsArtifactsManagementService.java @@ -39,6 +39,7 @@ import io.swagger.annotations.Tag; import javax.validation.Valid; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -67,31 +68,49 @@ import javax.ws.rs.core.Response; name = "Create Event Stream Artifact", description = "Create Event Stream Artifact", key = "perm:analytics:artifacts:stream", - permissions = {"/device-mgt/analytics/artifacts/stream/add"} - ), + permissions = {"/device-mgt/analytics/artifacts/stream/add"}), + @Scope( + name = "Delete Stream Artifact", + description = "Delete Stream Artifact", + key = "perm:analytics:artifacts:stream:delete", + permissions = {"/device-mgt/analytics/artifacts/stream/delete"}), @Scope( name = "Create Event Receiver Artifact", description = "Create Event Receiver Artifact", key = "perm:analytics:artifacts:receiver", - permissions = {"/device-mgt/analytics/artifacts/receiver/add"} - ), + permissions = {"/device-mgt/analytics/artifacts/receiver/add"}), + @Scope( + name = "Delete Receiver Artifact", + description = "Delete Receiver Artifact", + key = "perm:analytics:artifacts:receiver:delete", + permissions = {"/device-mgt/analytics/artifacts/receiver/delete"}), @Scope( name = "Create Event Publisher Artifact", description = "Create Event Publisher Artifact", key = "perm:analytics:artifacts:publisher", - permissions = {"/device-mgt/analytics/artifacts/publisher/add"} - ), + permissions = {"/device-mgt/analytics/artifacts/publisher/add"}), + @Scope( + name = "Delete Publisher Artifact", + description = "Delete Publisher Artifact", + key = "perm:analytics:artifacts:publisher:delete", + permissions = {"/device-mgt/analytics/artifacts/publisher/delete"}), @Scope( name = "Create Siddhi Script Artifact", description = "Create Siddhi Script Artifact", key = "perm:analytics:artifacts:siddhi", - permissions = {"/device-mgt/analytics/artifacts/siddhi-script/add"} - ) + permissions = {"/device-mgt/analytics/artifacts/siddhi-script/add"}), + @Scope( + name = "Delete Siddhi Script Artifact", + description = "Delete Siddhi Script Artifact", + key = "perm:analytics:artifacts:siddhi:delete", + permissions = {"/device-mgt/analytics/artifacts/siddhi-script/delete"}) } ) -@Api(value = "Analytics Artifacts Management", description = "This API corresponds to services" + - " related to Analytics Artifacts management") +@Api( + value = "Analytics Artifacts Management", + description = "This API corresponds to services related to Analytics Artifacts management" +) @Path("/analytics/artifacts") @Consumes(MediaType.APPLICATION_JSON) public interface AnalyticsArtifactsManagementService { @@ -105,8 +124,10 @@ public interface AnalyticsArtifactsManagementService { tags = "Analytics Artifacts Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:analytics:artifacts:stream") - }) + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:stream" + )}) } ) @ApiResponses( @@ -137,17 +158,23 @@ public interface AnalyticsArtifactsManagementService { message = "Not Acceptable.\n The requested media type is not supported."), @ApiResponse( code = 500, - message = "Internal Server Error. \n Server error occurred while deploying the " + - "Stream Artifact.", + message = "Internal Server Error. \n Server error occurred while " + + "deploying the Stream Artifact.", response = ErrorResponse.class) } ) Response deployEventDefinitionAsString( - @ApiParam(name = "id", value = "Stream id(name:version).") + @ApiParam( + name = "id", + value = "Stream id(name:version).") @PathParam("id") String id, - @ApiParam(name = "isEdited", value = "This stream is being edited or created.") + @ApiParam( + name = "isEdited", + value = "This stream is being edited or created.") @QueryParam("isEdited") boolean isEdited, - @ApiParam(name = "stream", value = "Add the data to complete the EventStream object.", + @ApiParam( + name = "stream", + value = "Add the data to complete the EventStream object.", required = true) @Valid EventStream stream); @@ -160,8 +187,10 @@ public interface AnalyticsArtifactsManagementService { tags = "Analytics Artifacts Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:analytics:artifacts:stream") - }) + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:stream" + )}) } ) @ApiResponses( @@ -198,10 +227,74 @@ public interface AnalyticsArtifactsManagementService { } ) Response deployEventDefinitionAsDto( - @ApiParam(name = "stream", value = "Add the data to complete the EventStream object.", + @ApiParam( + name = "stream", + value = "Add the data to complete the EventStream object.", required = true) @Valid EventStream stream); + @DELETE + @Path("/stream/{name}/{version}/delete") + @ApiOperation( + httpMethod = "DELETE", + value = "Delete the Stream with id as {name}:{version}", + notes = "Use this api to delete an already deployed Stream", + tags = "Analytics Artifacts Management", + extensions = { + @Extension(properties = { + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:stream:delete" + )}) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the Stream Artifact.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + } + ), + @ApiResponse( + code = 400, + message = "Bad Request."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n" + + "The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error.\nServer error occurred while " + + "deleting the Stream Artifact.", + response = ErrorResponse.class) + } + ) + Response deleteStream( + @ApiParam( + name = "name", + value = "Stream name.", + required = true) + @PathParam("name") String name, + @ApiParam( + name = "version", + value = "Stream version.", + required = true) + @PathParam("version") String version + ); + @POST @Path("/receiver/{name}") @ApiOperation( @@ -211,8 +304,10 @@ public interface AnalyticsArtifactsManagementService { tags = "Analytics Artifacts Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:analytics:artifacts:receiver") - }) + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:receiver" + )}) } ) @ApiResponses( @@ -250,11 +345,17 @@ public interface AnalyticsArtifactsManagementService { } ) Response deployEventReceiverAsString( - @ApiParam(name = "name", value = "Receiver name.") + @ApiParam( + name = "name", + value = "Receiver name.") @PathParam("name") String name, - @ApiParam(name = "isEdited", value = "This stream is being edited or created.") + @ApiParam( + name = "isEdited", + value = "This stream is being edited or created.") @QueryParam("isEdited") boolean isEdited, - @ApiParam(name = "receiver", value = "Add the data to complete the EventReceiver object.", + @ApiParam( + name = "receiver", + value = "Add the data to complete the EventReceiver object.", required = true) @Valid Adapter receiver); @@ -267,8 +368,10 @@ public interface AnalyticsArtifactsManagementService { tags = "Analytics Artifacts Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:analytics:artifacts:receiver") - }) + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:receiver" + )}) } ) @ApiResponses( @@ -306,10 +409,74 @@ public interface AnalyticsArtifactsManagementService { } ) Response deployEventReceiverAsDto( - @ApiParam(name = "receiver", value = "Add the data to complete the Adapter object.", + @ApiParam( + name = "receiver", + value = "Add the data to complete the Adapter object.", required = true) @Valid Adapter receiver); + @DELETE + @Path("/receiver/{name}/delete") + @ApiOperation( + httpMethod = "DELETE", + value = "Delete a Receiver with the given name", + notes = "Use this api to delete an already deployed active or inactive Receiver", + tags = "Analytics Artifacts Management", + extensions = { + @Extension(properties = { + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:receiver:delete" + )}) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the Receiver Artifact.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body" + ), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests." + ), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests." + ) + } + ), + @ApiResponse( + code = 400, + message = "Bad Request." + ), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n" + + "The requested media type is not supported." + ), + @ApiResponse( + code = 500, + message = "Internal Server Error.\nServer error occurred while " + + "deleting the Receiver Artifact.", + response = ErrorResponse.class + ) + } + ) + Response deleteReceiver( + @ApiParam( + name = "name", + value = "Receiver name.", + required = true) + @PathParam("name") String name); + @POST @Path("/publisher/{name}") @ApiOperation( @@ -319,8 +486,10 @@ public interface AnalyticsArtifactsManagementService { tags = "Analytics Artifacts Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:analytics:artifacts:publisher") - }) + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:publisher" + )}) } ) @ApiResponses( @@ -358,11 +527,17 @@ public interface AnalyticsArtifactsManagementService { } ) Response deployEventPublisherAsString( - @ApiParam(name = "name", value = "Publisher name.") + @ApiParam( + name = "name", + value = "Publisher name.") @PathParam("name") String name, - @ApiParam(name = "isEdited", value = "This stream is being edited or created.") + @ApiParam( + name = "isEdited", + value = "This stream is being edited or created.") @QueryParam("isEdited") boolean isEdited, - @ApiParam(name = "publisher", value = "Add the data to complete the EventPublisher object.", + @ApiParam( + name = "publisher", + value = "Add the data to complete the EventPublisher object.", required = true) @Valid Adapter publisher); @@ -375,8 +550,10 @@ public interface AnalyticsArtifactsManagementService { tags = "Analytics Artifacts Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:analytics:artifacts:publisher") - }) + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:publisher" + )}) } ) @ApiResponses( @@ -414,10 +591,68 @@ public interface AnalyticsArtifactsManagementService { } ) Response deployEventPublisherAsDto( - @ApiParam(name = "publisher", value = "Add the data to complete the Adapter object.", + @ApiParam( + name = "publisher", + value = "Add the data to complete the Adapter object.", required = true) @Valid Adapter publisher); + @DELETE + @Path("/publisher/{name}/delete") + @ApiOperation( + httpMethod = "DELETE", + value = "Delete a Publisher with the given name", + notes = "Use this api to delete an already deployed active or inactive Publisher", + tags = "Analytics Artifacts Management", + extensions = { + @Extension(properties = { + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:publisher:delete" + )}) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the Publisher Artifact.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + } + ), + @ApiResponse( + code = 400, + message = "Bad Request."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n" + + "The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error.\nServer error occurred while " + + "deleting the Publisher Artifact.", + response = ErrorResponse.class) + } + ) + Response deletePublisher( + @ApiParam( + name = "name", + value = "Publisher name.", + required = true) + @PathParam("name") String name); + @POST @Path("/siddhi-script/{name}") @ApiOperation( @@ -427,8 +662,10 @@ public interface AnalyticsArtifactsManagementService { tags = "Analytics Artifacts Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:analytics:artifacts:siddhi") - }) + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:siddhi" + )}) } ) @ApiResponses( @@ -466,11 +703,74 @@ public interface AnalyticsArtifactsManagementService { } ) Response deploySiddhiExecutableScript( - @ApiParam(name = "name", value = "Siddhi Executable Script name.") + @ApiParam( + name = "name", + value = "Siddhi Executable Script name.") @PathParam("name") String name, - @ApiParam(name = "isEdited", value = "This stream is being edited or created.") + @ApiParam( + name = "isEdited", + value = "This stream is being edited or created.") @QueryParam("isEdited") boolean isEdited, - @ApiParam(name = "plan", value = "Add the data to complete the SiddhiExecutionPlan object.", + @ApiParam( + name = "plan", + value = "Add the data to complete the SiddhiExecutionPlan object.", required = true) @Valid SiddhiExecutionPlan plan); + + @DELETE + @Path("/siddhi-script/{name}/delete") + @ApiOperation( + httpMethod = "DELETE", + value = "Delete an already deployed Siddhi script", + notes = "Use this api to delete an already deployed active or inactive Siddhi script", + tags = "Analytics Artifacts Management", + extensions = { + @Extension(properties = { + @ExtensionProperty( + name = Constants.SCOPE, + value = "perm:analytics:artifacts:siddhi:delete" + ) + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully delete the Siddhi script Artifact.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + } + ), + @ApiResponse( + code = 400, + message = "Bad Request."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n" + + "The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error.\nServer error occurred while " + + "deleting the Siddhi script Artifact.", + response = ErrorResponse.class) + } + ) + Response deleteSiddhiScript( + @ApiParam( + name = "name", + value = "Siddhi script name.", + required = true) + @PathParam("name") String name); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/AnalyticsArtifactsManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/AnalyticsArtifactsManagementServiceImpl.java index bdd7fdb420..b6cdd9a650 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/AnalyticsArtifactsManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/AnalyticsArtifactsManagementServiceImpl.java @@ -25,9 +25,11 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.AdapterConfiguration; import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.AdapterProperty; import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.MessageFormat; import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.SiddhiExecutionPlan; +import org.wso2.carbon.device.mgt.jaxrs.exception.ArtifactAlreadyExistsException; import org.wso2.carbon.device.mgt.jaxrs.exception.BadRequestException; import org.wso2.carbon.device.mgt.jaxrs.exception.ErrorDTO; import org.wso2.carbon.device.mgt.jaxrs.exception.InvalidExecutionPlanException; +import org.wso2.carbon.device.mgt.jaxrs.exception.NotFoundException; import org.wso2.carbon.device.mgt.jaxrs.service.api.AnalyticsArtifactsManagementService; import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.Adapter; import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventStream; @@ -52,6 +54,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.validation.Valid; +import javax.ws.rs.DELETE; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -76,36 +79,39 @@ public class AnalyticsArtifactsManagementServiceImpl @QueryParam("isEdited") boolean isEdited, @Valid EventStream stream) { String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - EventStreamAdminServiceStub eventStreamAdminServiceStub = null; try { String streamDefinition = stream.getDefinition(); - eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); - if (!isEdited) { - eventStreamAdminServiceStub.addEventStreamDefinitionAsString(streamDefinition); + if (deployStream(id, streamDefinition, isEdited)) { + return Response.ok().build(); } else { - if (eventStreamAdminServiceStub.getStreamDetailsForStreamId(id) != null) { - eventStreamAdminServiceStub.editEventStreamDefinitionAsString(streamDefinition, id); - } + String errMsg = "Failed to create the Stream artifact of id: " + id + + " for tenant domain: " + tenantDomain; + return Response.serverError().entity(errMsg).build(); } - return Response.ok().build(); + } catch (ArtifactAlreadyExistsException e) { + String errMsg = "Failed to create Stream artifact for tenant domain: " + tenantDomain; + log.error(errMsg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(errMsg).build(); + } catch (NotFoundException e) { + String errMsg = "Failed to edit Stream artifact for tenant domain: " + tenantDomain; + log.error(errMsg, e); + return Response.status(Response.Status.NOT_FOUND).entity(errMsg).build(); } catch (AxisFault e) { String errMsg = "Failed to create event definitions for tenantDomain: " + tenantDomain; log.error(errMsg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + return Response.serverError().entity(errMsg).build(); } catch (RemoteException e) { String errMsg = "Failed to connect with the remote services for tenantDomain: " + tenantDomain; log.error(errMsg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + return Response.serverError().entity(errMsg).build(); } catch (JWTClientException e) { String errMsg = "Failed to generate jwt token for tenantDomain: " + tenantDomain; log.error(errMsg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + return Response.serverError().entity(errMsg).build(); } catch (UserStoreException e) { String errMsg = "Failed to connect with the user store for tenantDomain: " + tenantDomain; log.error(errMsg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); - } finally { - cleanup(eventStreamAdminServiceStub); + return Response.serverError().entity(errMsg).build(); } } @@ -116,8 +122,16 @@ public class AnalyticsArtifactsManagementServiceImpl String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); try { validateStreamProperties(stream); - deployStream(stream); - return Response.ok().build(); + String name = stream.getName(); + String version = stream.getVersion(); + if (deployStream(stream)) { + return Response.ok().build(); + } else { + String errMsg = String.format("Failed to create the Stream artifact of id: %s:%s " + + "for tenant domain: %s", name, version, tenantDomain); + log.error(errMsg); + return Response.serverError().entity(errMsg).build(); + } } catch (BadRequestException e) { String errMsg = "Failed to deploy stream due to invalid payload"; log.error(errMsg, e); @@ -125,19 +139,58 @@ public class AnalyticsArtifactsManagementServiceImpl } catch (AxisFault e) { String errMsg = "Failed to create event definitions for tenant " + tenantDomain; log.error(errMsg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + return Response.serverError().entity(errMsg).build(); } catch (RemoteException e) { String errMsg = "Failed to connect with the remote services for tenant " + tenantDomain; log.error(errMsg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + return Response.serverError().entity(errMsg).build(); } catch (JWTClientException e) { String errMsg = "Failed to generate jwt token for tenant " + tenantDomain; log.error(errMsg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + return Response.serverError().entity(errMsg).build(); } catch (UserStoreException e) { String errMsg = "Failed to connect with the user store for tenant " + tenantDomain; log.error(errMsg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + return Response.serverError().entity(errMsg).build(); + } + } + + @Override + @DELETE + @Path("/stream/{name}/{version}/delete") + public Response deleteStream(@PathParam("name") String name, + @PathParam("version") String version) { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + try { + if (undeployStream(name, version)) { + return Response.ok().build(); + } else { + String errMsg = String.format("Failed to undeploy the Stream artifact of id: %s:%s " + + "for tenant domain: %s", name, version, tenantDomain); + log.error(errMsg); + return Response.serverError().entity(errMsg).build(); + } + } catch (NotFoundException e) { + String errMsg = String.format("Failed to undeploy Stream with id %s:%s for tenant %s" + , name, version, tenantDomain); + log.error(errMsg, e); + return Response.status(Response.Status.NOT_FOUND).entity(errMsg).build(); + } catch (AxisFault e) { + String errMsg = "Failed to create event definitions for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (RemoteException e) { + String errMsg = "Failed to connect with the remote services for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (JWTClientException e) { + String errMsg = "Failed to generate jwt token for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (UserStoreException e) { + String errMsg = "Failed to connect with the user store for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); } } @@ -214,6 +267,39 @@ public class AnalyticsArtifactsManagementServiceImpl } } + @Override + @DELETE + @Path("/receiver/{name}/delete") + public Response deleteReceiver(@PathParam("name") String name) { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + try { + if (undeployAdapter(name, "Receiver")) { + return Response.ok().build(); + } else { + String errMsg = String.format("Failed to undeploy the Receiver artifact of name: %s" + + "for tenant domain: %s", name, tenantDomain); + log.error(errMsg); + return Response.serverError().entity(errMsg).build(); + } + } catch (AxisFault e) { + String errMsg = "Failed to delete event definitions for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (RemoteException e) { + String errMsg = "Failed to connect with the remote services for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (JWTClientException e) { + String errMsg = "Failed to generate jwt token for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (UserStoreException e) { + String errMsg = "Failed to connect with the user store for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } + } + @Override @POST @Path("/publisher/{name}") @@ -287,6 +373,39 @@ public class AnalyticsArtifactsManagementServiceImpl } } + @Override + @DELETE + @Path("/publisher/{name}/delete") + public Response deletePublisher(@PathParam("name") String name) { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + try { + if (undeployAdapter(name, "Publisher")) { + return Response.ok().build(); + } else { + String errMsg = String.format("Failed to undeploy the Publisher artifact of name: %s" + + "for tenant domain: %s", name, tenantDomain); + log.error(errMsg); + return Response.serverError().entity(errMsg).build(); + } + } catch (AxisFault e) { + String errMsg = "Failed to delete event definitions for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (RemoteException e) { + String errMsg = "Failed to connect with the remote services for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (JWTClientException e) { + String errMsg = "Failed to generate jwt token for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (UserStoreException e) { + String errMsg = "Failed to connect with the user store for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } + } + @Override @POST @Path("/siddhi-script/{name}") @@ -320,12 +439,77 @@ public class AnalyticsArtifactsManagementServiceImpl } } + @Override + @DELETE + @Path("/siddhi-script/{name}/delete") + public Response deleteSiddhiScript(@PathParam("name") String name) { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + try { + undeploySiddhiScript(name); + return Response.ok().build(); + } catch (AxisFault e) { + String errMsg = "Failed to delete event definitions for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (RemoteException e) { + String errMsg = "Failed to connect with the remote services for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (JWTClientException e) { + String errMsg = "Failed to generate jwt token for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } catch (UserStoreException e) { + String errMsg = "Failed to connect with the user store for tenant " + tenantDomain; + log.error(errMsg, e); + return Response.serverError().entity(errMsg).build(); + } + } + + /** + * Deploy Stream by passing a string to a stub + * + * @param streamId Stream name:version + * @param streamDefinition Stream that should be deployed + * @param isEdited Create a new stream or edit an existing one + * @return True if stream successfully created and false if not + * @throws RemoteException Exception that may occur during a remote method call + * @throws UserStoreException Exception that may occur during JWT token generation + * @throws JWTClientException Exception that may occur during connecting to client store + * @throws NotFoundException Exception that may occure if stream doesn't exist while editing + * @throws ArtifactAlreadyExistsException Exception that may occure if stream exist while creating + */ + private boolean deployStream(String streamId, String streamDefinition, boolean isEdited) + throws UserStoreException, JWTClientException, RemoteException, NotFoundException, + ArtifactAlreadyExistsException { + + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + try { + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + if (isEdited) { + validateStreamId(streamId, eventStreamAdminServiceStub, true); + return eventStreamAdminServiceStub + .editEventStreamDefinitionAsString(streamDefinition, streamId); + } else { + validateStreamId(streamId, eventStreamAdminServiceStub, false); + return eventStreamAdminServiceStub.addEventStreamDefinitionAsString(streamDefinition); + } + } finally { + cleanup(eventStreamAdminServiceStub); + } + } + /** - * Set data to a Stream dto and deploy dto through a stub + * Deploy Stream by passing a DTO object to a stub * * @param stream Stream definition + * @return True if stream successfully created and false if not + * @throws RemoteException Exception that may occur during a remote method call + * @throws UserStoreException Exception that may occur during JWT token generation + * @throws JWTClientException Exception that may occur during connecting to client store + * @throws NotFoundException Exception that may occure if stream doesn't exist while editing */ - private void deployStream(EventStream stream) + private boolean deployStream(EventStream stream) throws RemoteException, UserStoreException, JWTClientException { EventStreamAdminServiceStub eventStreamAdminServiceStub = null; List metaData = stream.getMetaData(); @@ -350,9 +534,41 @@ public class AnalyticsArtifactsManagementServiceImpl } String streamId = stream.getName() + ":" + stream.getVersion(); if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamId) != null) { - eventStreamAdminServiceStub.editEventStreamDefinitionAsDto(eventStreamDefinitionDto, streamId); + return eventStreamAdminServiceStub + .editEventStreamDefinitionAsDto(eventStreamDefinitionDto, streamId); } else { - eventStreamAdminServiceStub.addEventStreamDefinitionAsDto(eventStreamDefinitionDto); + return eventStreamAdminServiceStub + .addEventStreamDefinitionAsDto(eventStreamDefinitionDto); + } + } finally { + cleanup(eventStreamAdminServiceStub); + } + } + + /** + * Undeploy a stream artifact + * + * @param name Stream name + * @param version Stream version + * @return True if stream successfully created and false if not + * @throws RemoteException Exception that may occur during a remote method call + * @throws UserStoreException Exception that may occur during JWT token generation + * @throws JWTClientException Exception that may occur during connecting to client store + * @throws NotFoundException Exception that may occure if stream doesn't exist + */ + private boolean undeployStream(String name, String version) + throws RemoteException, UserStoreException, JWTClientException, NotFoundException { + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + try { + String streamId = String.format("%s:%s", name, version); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamId) != null) { + return eventStreamAdminServiceStub.removeEventStreamDefinition(name, version); + } else { + ErrorDTO error = new ErrorDTO(); + String msg = String.format("Stream wit id: %s not found", streamId); + error.setMessage(msg); + throw new NotFoundException(error); } } finally { cleanup(eventStreamAdminServiceStub); @@ -613,6 +829,37 @@ public class AnalyticsArtifactsManagementServiceImpl } } + /** + * @param name Adapter name + * @param type Adapter type(Receiver or Publisher) + * @return True if Adapter successfully created and false if not + * @throws RemoteException Exception that may occur during a remote method call + * @throws UserStoreException Exception that may occur during JWT token generation + * @throws JWTClientException Exception that may occur during connecting to client store + */ + private boolean undeployAdapter(String name, String type) + throws RemoteException, UserStoreException, JWTClientException { + if (type.equals("Receiver")) { + EventReceiverAdminServiceStub eventReceiverAdminServiceStub = null; + try { + eventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); + return eventReceiverAdminServiceStub + .undeployActiveEventReceiverConfiguration(name); + } finally { + cleanup(eventReceiverAdminServiceStub); + } + } else { + EventPublisherAdminServiceStub eventPublisherAdminServiceStub = null; + try { + eventPublisherAdminServiceStub = DeviceMgtAPIUtils.getEventPublisherAdminServiceStub(); + return eventPublisherAdminServiceStub + .undeployActiveEventPublisherConfiguration(name); + } finally { + cleanup(eventPublisherAdminServiceStub); + } + } + } + /** * Publish a siddhi execution plan using a stub * @@ -645,10 +892,60 @@ public class AnalyticsArtifactsManagementServiceImpl } } + /** + * Undeploy a Siddhi artifact + * + * @param name Siddhi script name + * @throws RemoteException Exception that may occur during a remote method call + * @throws UserStoreException Exception that may occur during JWT token generation + * @throws JWTClientException Exception that may occur during connecting to client store + */ + private void undeploySiddhiScript(String name) + throws RemoteException, UserStoreException, JWTClientException { + EventProcessorAdminServiceStub eventProcessorAdminServiceStub = null; + try { + eventProcessorAdminServiceStub = DeviceMgtAPIUtils.getEventProcessorAdminServiceStub(); + eventProcessorAdminServiceStub.undeployActiveExecutionPlan(name); + } finally { + cleanup(eventProcessorAdminServiceStub); + } + } + + /** + * @param streamId Stream name:version + * @param eventStreamAdminServiceStub stub used to mange Stream artifacts + * @param isEdited Create a new stream or edit an existing one + * @throws ArtifactAlreadyExistsException Exception that may occur if stream exist while creating + * @throws RemoteException Exception that may occur during a remote method call + */ + private void validateStreamId(String streamId, + EventStreamAdminServiceStub eventStreamAdminServiceStub, + boolean isEdited) + throws ArtifactAlreadyExistsException, RemoteException { + EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub + .getStreamDefinitionDto(streamId); + if (isEdited) { + if (eventStreamDefinitionDto == null) { + String errMsg = String.format("Failed to edit Stream with id: %s. " + + "Stream not found", streamId); + ErrorDTO error = new ErrorDTO(); + error.setMessage(errMsg); + throw new NotFoundException(error); + } + } else { + if (eventStreamDefinitionDto != null) { + String errMsg = String.format("Failed to create Stream with id: %s. " + + "Stream already exists.", streamId); + throw new ArtifactAlreadyExistsException(errMsg); + } + } + } + /** * Validate stream properties * * @param stream EventStream object + * @throws BadRequestException Exception that may occur if property attributes invalid */ private void validateStreamProperties(EventStream stream) throws BadRequestException { if ((stream.getMetaData() == null || stream.getMetaData().isEmpty()) && @@ -665,6 +962,7 @@ public class AnalyticsArtifactsManagementServiceImpl * Validate adapter payload attributes * * @param adapterProperties Adapter payload attributes + * @throws BadRequestException Exception that may occur if adapter properties invalid */ private void validateAdapterProperties(List adapterProperties) throws BadRequestException { @@ -684,6 +982,7 @@ public class AnalyticsArtifactsManagementServiceImpl * - else continue * * @param adapterMappingConfiguration Adapter mapping attributes + * @throws BadRequestException Exception that may occur if adapter mapping properties invalid */ private void validateAdapterMapping(AdapterMappingConfiguration adapterMappingConfiguration) throws BadRequestException {