diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java index 6817698a355..5c6e52837ef 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java @@ -24,6 +24,8 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.application.mgt.api.beans.ErrorResponse; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationReleaseManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; import org.wso2.carbon.device.application.mgt.common.services.LifecycleStateManager; import org.wso2.carbon.device.application.mgt.common.services.PlatformManager; @@ -40,6 +42,8 @@ public class APIUtil { private static ApplicationManager applicationManager; private static PlatformManager platformManager; private static LifecycleStateManager lifecycleStateManager; + private static ApplicationReleaseManager applicationReleaseManager; + private static ApplicationStorageManager applicationStorageManager; public static ApplicationManager getApplicationManager() { if (applicationManager == null) { @@ -96,6 +100,50 @@ public class APIUtil { return lifecycleStateManager; } + /** + * To get the Application Release Manager from the osgi context. + * + * @return ApplicationRelease Manager instance in the current osgi context. + */ + public static ApplicationReleaseManager getApplicationReleaseManager() { + if (applicationReleaseManager == null) { + synchronized (APIUtil.class) { + if (applicationReleaseManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + applicationReleaseManager = (ApplicationReleaseManager) ctx + .getOSGiService(ApplicationReleaseManager.class, null); + if (applicationReleaseManager == null) { + String msg = "Application Release Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return applicationReleaseManager; + } + + /** + * To get the Application Storage Manager from the osgi context. + * @return ApplicationStoreManager instance in the current osgi context. + */ + public static ApplicationStorageManager getApplicationStorageManager() { + if (applicationStorageManager == null) { + synchronized (APIUtil.class) { + if (applicationStorageManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + applicationStorageManager = (ApplicationStorageManager) ctx + .getOSGiService(ApplicationStorageManager.class, null); + if (applicationStorageManager == null) { + String msg = "Application Storage Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return applicationStorageManager; + } public static Response getResponse(ApplicationManagementException ex, Response.Status status) { return getResponse(ex.getMessage(), status); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/FileStreamingOutput.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/FileStreamingOutput.java new file mode 100644 index 00000000000..aad9a9a73ef --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/FileStreamingOutput.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.device.application.mgt.api; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.StreamingOutput; + +/** + * FileStreamingOutput to allow the user to send the files as Stream. + */ +public class FileStreamingOutput implements StreamingOutput { + private InputStream inputStream; + + public FileStreamingOutput(InputStream inputStream) { + this.inputStream = inputStream; + } + + @Override + public void write(OutputStream outputStream) throws IOException, WebApplicationException { + try { + byte[] buffer = new byte[inputStream.available()]; + inputStream.read(buffer); + outputStream.write(buffer); + outputStream.flush(); + } finally { + if (inputStream != null) { + inputStream.close(); + } + if (outputStream != null) { + outputStream.close(); + } + } + + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/JSONMessageHandler.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/JSONMessageHandler.java index 2f88b223068..d01bed5199f 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/JSONMessageHandler.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/JSONMessageHandler.java @@ -23,6 +23,13 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.wso2.carbon.device.application.mgt.common.jaxrs.AnnotationExclusionStrategy; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; @@ -31,12 +38,12 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import java.io.*; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; +/** + * This provider is used to change a JSON object to complex object and inversely in request and response. + */ @Provider @Produces(APPLICATION_JSON) @Consumes(APPLICATION_JSON) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/MultipartCustomProvider.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/MultipartCustomProvider.java new file mode 100644 index 00000000000..84ed5e634ab --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/MultipartCustomProvider.java @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.wso2.carbon.device.application.mgt.api; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.wso2.carbon.device.application.mgt.common.jaxrs.AnnotationExclusionStrategy; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import javax.ws.rs.Consumes; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.Provider; + +/** + * Provider for the text/plain type of input. Particularly use-ful for the complex objects sent along with Multipart + * request. + */ +@Provider +@Consumes(MediaType.TEXT_PLAIN) +public class MultipartCustomProvider implements MessageBodyReader { + private Gson gson; + + public MultipartCustomProvider() { + final GsonBuilder gsonBuilder = new GsonBuilder().setDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz") + .setExclusionStrategies(new AnnotationExclusionStrategy()); + gson = gsonBuilder.create(); + } + @Override + public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return !aClass.equals(Attachment.class); + } + + @Override + public Object readFrom(Class objectClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap headers, InputStream inputStream) throws IOException, + WebApplicationException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + String jsonString = result.toString(); + JsonObject obj = new JsonParser().parse(jsonString).getAsJsonObject(); + return gson.fromJson(obj, type); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorListItem.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorListItem.java index 91599d539a6..3c049465926 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorListItem.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorListItem.java @@ -24,6 +24,9 @@ import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +/** + * Represents a single error item in the error response. + */ @ApiModel(description = "Error List Item") public class ErrorListItem { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorResponse.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorResponse.java index a755b82a4e6..6c9321e3342 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorResponse.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorResponse.java @@ -25,6 +25,10 @@ import io.swagger.annotations.ApiModelProperty; import java.util.ArrayList; import java.util.List; +/** + * This represents a response that need to be send back to the client, when the request cannot be completed + * successfully. + */ @ApiModel(description = "Error Response") public class ErrorResponse { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ApplicationManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ApplicationManagementAPI.java index f463fc95006..69f2c8f3e32 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ApplicationManagementAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ApplicationManagementAPI.java @@ -28,11 +28,14 @@ import io.swagger.annotations.ExtensionProperty; import io.swagger.annotations.Info; import io.swagger.annotations.SwaggerDefinition; import io.swagger.annotations.Tag; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.wso2.carbon.apimgt.annotations.api.Scope; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.device.application.mgt.api.beans.ErrorResponse; import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.ApplicationList; +import org.wso2.carbon.device.application.mgt.common.ApplicationRelease; import java.util.List; import javax.validation.Valid; @@ -106,7 +109,6 @@ import javax.ws.rs.core.Response; @Api(value = "Application Management", description = "This API carries all application management related operations " + "such as get all the applications, add application, etc.") @Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) public interface ApplicationManagementAPI { String SCOPE = "scope"; @@ -270,6 +272,82 @@ public interface ApplicationManagementAPI { required = true) @Valid Application application); + @POST + @Path("upload-artifacts/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + @ApiOperation( + consumes = MediaType.MULTIPART_FORM_DATA, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Upload artifacts", + notes = "This will create a new application", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:create") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully uploaded artifacts."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the application list.", + response = ErrorResponse.class) + }) + Response uploadApplicationArtifacts( + @ApiParam( + name = "uuid", + value = "UUID of the application", + required = true) + @PathParam("uuid") String applicationUUID, + @Multipart(value = "icon") Attachment iconFile, + @Multipart(value = "banner") Attachment bannerFile, + @Multipart(value = "screenshot") List screenshots); + + @PUT + @Path("upload-artifacts/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + @ApiOperation( + consumes = MediaType.MULTIPART_FORM_DATA, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Upload artifacts", + notes = "This will create a new application", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:create") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully uploaded artifacts."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the application list.", + response = ErrorResponse.class) + }) + Response updateApplicationArtifacts( + @ApiParam( + name = "uuid", + value = "UUID of the application", + required = true) + @PathParam("uuid") String applicationUUID, + @Multipart(value = "icon", required = false) Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart(value = "screenshot", required = false) List screenshots); + + + @PUT @Consumes("application/json") @Path("/{uuid}/lifecycle") @@ -376,4 +454,121 @@ public interface ApplicationManagementAPI { value = "Unique identifier of the Application", required = true) @PathParam("appuuid") String applicationUUID); + + @POST + @Path("/release/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + @ApiOperation( + consumes = MediaType.MULTIPART_FORM_DATA, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an application release", + notes = "This will create a new application release", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:create") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application release.", + response = ApplicationRelease.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + + Response createApplicationRelease( + @ApiParam( + name = "UUID", + value = "Unique identifier of the Application", + required = true) + @PathParam("uuid") String applicationUUID, + @Multipart(value = "applicationRelease", type = "application/json") ApplicationRelease applicationRelease, + @Multipart(value = "binaryFile") Attachment binaryFile); + + @GET + @Path("/release-artifacts/{uuid}/{version}") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Consumes(MediaType.MULTIPART_FORM_DATA) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_OCTET_STREAM, + httpMethod = "POST", + value = "Create an application release", + notes = "This will create a new application release", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:get") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the Application release.", + response = Attachment.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + Response getApplicationReleaseArtifacts( + @ApiParam( + name = "UUID", + value = "Unique identifier of the Application", + required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "Version", + value = "Version of the Application release need to be retrieved", + required = true) + @PathParam("version") String version); + + @GET + @Path("/release/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get all the releases or specific release of an application", + notes = "This will retrieve the all the releases or specific release of an application", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:get") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the Application release."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + Response getApplicationReleases( + @ApiParam( + name = "UUID", + value = "Unique identifier of the Application", + required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "version", + value = "Version of the application", + required = false) + @QueryParam("version") String version); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/LifecycleManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/LifecycleManagementAPI.java index fdd33f1a29b..0386c12e253 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/LifecycleManagementAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/LifecycleManagementAPI.java @@ -31,8 +31,8 @@ import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.device.application.mgt.api.beans.ErrorResponse; import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.LifecycleState; -import org.wso2.carbon.device.application.mgt.common.Platform; +import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -40,8 +40,10 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.List; +/** + * Lifecycle management related APIs. + */ @SwaggerDefinition( info = @Info( version = "1.0.0", @@ -139,7 +141,8 @@ public interface LifecycleManagementAPI { @ApiResponse( code = 304, message = "Not Modified. \n " + - "Empty body because the client already has the latest version of the requested resource."), + "Empty body because the client already has the latest version of the requested " + + "resource."), @ApiResponse( code = 500, message = "Internal Server Error. \n Error occurred adding a lifecycle state.", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ApplicationManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ApplicationManagementAPIImpl.java index a833e8a7309..271520149ec 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ApplicationManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ApplicationManagementAPIImpl.java @@ -20,16 +20,27 @@ package org.wso2.carbon.device.application.mgt.api.services.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.wso2.carbon.device.application.mgt.api.APIUtil; +import org.wso2.carbon.device.application.mgt.api.FileStreamingOutput; import org.wso2.carbon.device.application.mgt.api.services.ApplicationManagementAPI; import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.ApplicationList; +import org.wso2.carbon.device.application.mgt.common.ApplicationRelease; import org.wso2.carbon.device.application.mgt.common.Filter; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationReleaseManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; import org.wso2.carbon.device.application.mgt.core.util.Constants; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -40,13 +51,14 @@ 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.MediaType; import javax.ws.rs.core.Response; + /** * Implementation of Application Management related APIs. */ @Produces({"application/json"}) -@Consumes({"application/json"}) @Path("/applications") public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { @@ -160,6 +172,92 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { } } + @Override + @POST + @Path("upload-image-artifacts/{uuid}") + public Response uploadApplicationArtifacts(@PathParam("uuid") String applicationUUID, + @Multipart("icon")Attachment iconFile, @Multipart("banner") Attachment bannerFile, @Multipart + ("screenshot") List attachmentList) { + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + InputStream iconFileStream; + InputStream bannerFileStream; + List attachments = new ArrayList<>(); + + if (iconFile != null) { + iconFileStream = iconFile.getDataHandler().getInputStream(); + } else { + throw new ApplicationManagementException( + "Icon file is not uploaded for the application " + applicationUUID); + } + if (bannerFile != null) { + bannerFileStream = bannerFile.getDataHandler().getInputStream(); + } else { + throw new ApplicationManagementException( + "Banner file is not uploaded for the application " + applicationUUID); + } + if (attachmentList != null && !attachmentList.isEmpty()) { + for (Attachment screenshot : attachmentList) { + attachments.add(screenshot.getDataHandler().getInputStream()); + } + } else { + throw new ApplicationManagementException( + "Screen-shot are not uploaded for the application " + applicationUUID); + } + applicationStorageManager + .uploadImageArtifacts(applicationUUID, iconFileStream, bannerFileStream, attachments); + return Response.status(Response.Status.OK) + .entity("Successfully uploaded artifacts for the application " + applicationUUID).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating the application"; + log.error(msg, e); + return APIUtil.getResponse(e, Response.Status.BAD_REQUEST); + } catch (IOException e) { + log.error("Exception while trying to read icon, banner files for the application " + applicationUUID); + return APIUtil.getResponse(new ApplicationManagementException( + "Exception while trying to read icon, " + "banner files for the application " + + applicationUUID, e), Response.Status.BAD_REQUEST); + } + } + + @Override + @PUT + @Path("upload-image-artifacts/{uuid}") + public Response updateApplicationArtifacts(@PathParam("uuid") String applicationUUID, + @Multipart("icon")Attachment iconFile, @Multipart("banner") Attachment bannerFile, @Multipart + ("screenshot") List attachmentList) { + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + InputStream iconFileStream = null; + InputStream bannerFileStream = null; + List attachments = new ArrayList<>(); + + if (iconFile != null) { + iconFileStream = iconFile.getDataHandler().getInputStream(); + } + if (bannerFile != null) { + bannerFileStream = bannerFile.getDataHandler().getInputStream(); + } + if (attachmentList != null) { + for (Attachment screenshot : attachmentList) { + attachments.add(screenshot.getDataHandler().getInputStream()); + } + } + applicationStorageManager + .uploadImageArtifacts(applicationUUID, iconFileStream, bannerFileStream, attachments); + return Response.status(Response.Status.OK) + .entity("Successfully updated artifacts for the application " + applicationUUID).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while updating the artifact for the application " + applicationUUID; + log.error(msg, e); + return APIUtil.getResponse(e, Response.Status.BAD_REQUEST); + } catch (IOException e) { + log.error("Exception while trying to read icon, banner files for the application " + applicationUUID); + return APIUtil.getResponse(new ApplicationManagementException( + "Exception while trying to read icon, banner files for the application " + + applicationUUID, e), Response.Status.BAD_REQUEST); + } + } @PUT @Consumes("application/json") @@ -191,4 +289,79 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { String responseMsg = "Successfully deleted the application: " + uuid; return Response.status(Response.Status.OK).entity(responseMsg).build(); } + + @Override + @POST + @Path("/release/{uuid}") + public Response createApplicationRelease(@PathParam("uuid") String applicationUUID, + @Multipart("applicationRelease") ApplicationRelease applicationRelease, + @Multipart("binaryFile") Attachment binaryFile) { + ApplicationReleaseManager applicationReleaseManager = APIUtil.getApplicationReleaseManager(); + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + applicationRelease = applicationReleaseManager.createRelease(applicationUUID, applicationRelease); + + if (binaryFile != null) { + applicationStorageManager.uploadReleaseArtifacts(applicationUUID, applicationRelease.getVersionName(), + binaryFile.getDataHandler().getInputStream()); + } + return Response.status(Response.Status.CREATED).entity(applicationRelease).build(); + } catch (ApplicationManagementException e) { + log.error("Error while creating an application release for the application with UUID " + applicationUUID, + e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } catch (IOException e) { + String errorMessage = + "Error while uploading binary file for the application release of the application with UUID " + + applicationUUID; + log.error(errorMessage, e); + return APIUtil.getResponse(new ApplicationManagementException(errorMessage, e), + Response.Status.INTERNAL_SERVER_ERROR); + } + } + + @Override + @GET + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Path("/release-artifacts/{uuid}/{version}") + public Response getApplicationReleaseArtifacts(@PathParam("uuid") String applicationUUID, + @PathParam("version") String version) { + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + InputStream binaryFile = applicationStorageManager.getReleasedArtifacts(applicationUUID, version); + FileStreamingOutput fileStreamingOutput = new FileStreamingOutput(binaryFile); + Response.ResponseBuilder response = Response.status(Response.Status.OK).entity(fileStreamingOutput); + response.header("Content-Disposition", "attachment; filename=\"" + version + "\""); + return response.build(); + } catch (ApplicationStorageManagementException e) { + log.error("Error while retrieving the binary file of the applcation release for the application UUID " + + applicationUUID + " and version " + version, e); + if (e.getMessage().contains("Binary file does not exist")) { + return APIUtil.getResponse(e, Response.Status.NOT_FOUND); + } else { + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + } + + @Override + @Path("/release/{uuid}") + @GET + public Response getApplicationReleases(@PathParam("uuid") String applicationUUID, + @QueryParam("version") String version) { + ApplicationReleaseManager applicationReleaseManager = APIUtil.getApplicationReleaseManager(); + try { + if (version == null || version.isEmpty()) { + List applicationReleases = applicationReleaseManager.getReleases(applicationUUID); + return Response.status(Response.Status.OK).entity(applicationReleases).build(); + } else { + ApplicationRelease applicationRelease = applicationReleaseManager.getRelease(applicationUUID, version); + return Response.status(Response.Status.OK).entity(applicationRelease).build(); + } + } catch (ApplicationManagementException e) { + log.error("Error while getting all the application releases for the application with the UUID " + + applicationUUID, e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/LifecycleManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/LifecycleManagementAPIImpl.java index 751b0dc2255..985c0b7bb89 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/LifecycleManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/LifecycleManagementAPIImpl.java @@ -25,15 +25,18 @@ import org.wso2.carbon.device.application.mgt.common.LifecycleState; import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; import org.wso2.carbon.device.application.mgt.common.services.LifecycleStateManager; +import java.util.ArrayList; +import java.util.List; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Response; -import java.util.ArrayList; -import java.util.List; +/** + * Lifecycle Management related jax-rs APIs. + */ @Path("/lifecycles") public class LifecycleManagementAPIImpl implements LifecycleManagementAPI { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 5b4af27dbe8..1dacaaef3e8 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -31,6 +31,7 @@ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> + @@ -38,6 +39,7 @@ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/web.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/web.xml index 55fe863d2e7..7574e19e4c0 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/web.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/web.xml @@ -27,7 +27,7 @@ org.apache.cxf.transport.servlet.CXFServlet - + CXFServlet /* diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Application.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Application.java index bce0cad7a7b..4fe9a25c384 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Application.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Application.java @@ -26,7 +26,7 @@ import java.util.List; import java.util.Map; /** - * Application represents the an Application in Application Store + * Application represents the an Application in Application Store. */ public class Application { @@ -250,4 +250,10 @@ public class Application { public void setUser(User user) { this.user = user; } + + @Override + public String toString() { + return "UUID : " + uuid + "\tIdentifier : " + identifier + "\tName : " + name + "\tShort Description : " + + shortDescription + "\tLifecycle State : " + currentLifecycle.getLifecycleState(); + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationRelease.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationRelease.java index e78d3e8926a..e43b4fda640 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationRelease.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationRelease.java @@ -18,6 +18,8 @@ */ package org.wso2.carbon.device.application.mgt.common; +import org.wso2.carbon.device.application.mgt.common.jaxrs.Exclude; + import java.util.Date; import java.util.Map; @@ -30,6 +32,7 @@ public class ApplicationRelease { PRODUCTION, ALPHA, BETA } + @Exclude private int id; private int versionId; @@ -46,10 +49,6 @@ public class ApplicationRelease { private Application application; - private Date lifecycleStateModifiedAt; - - private String lifecycleStateModifiedBy; - private Map properties; private boolean isDefault; @@ -62,14 +61,6 @@ public class ApplicationRelease { this.id = id; } - public int getVersionId() { - return versionId; - } - - public void setVersionId(int versionId) { - this.versionId = versionId; - } - public String getVersionName() { return versionName; } @@ -90,8 +81,8 @@ public class ApplicationRelease { return releaseChannel; } - public void setReleaseChannel(Channel releaseChannel) { - this.releaseChannel = releaseChannel; + public void setReleaseChannel(String releaseChannel) { + this.releaseChannel = Channel.valueOf(releaseChannel); } public String getReleaseDetails() { @@ -118,22 +109,6 @@ public class ApplicationRelease { this.application = application; } - public Date getLifecycleStateModifiedAt() { - return lifecycleStateModifiedAt; - } - - public void setLifecycleStateModifiedAt(Date lifecycleStateModifiedAt) { - this.lifecycleStateModifiedAt = lifecycleStateModifiedAt; - } - - public String getLifecycleStateModifiedBy() { - return lifecycleStateModifiedBy; - } - - public void setLifecycleStateModifiedBy(String lifecycleStateModifiedBy) { - this.lifecycleStateModifiedBy = lifecycleStateModifiedBy; - } - public Map getProperties() { return properties; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationManagementException.java index ce5ed1cb39a..a74c6e3e709 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationManagementException.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationManagementException.java @@ -22,8 +22,7 @@ package org.wso2.carbon.device.application.mgt.common.exception; * Represents the exception thrown during application management. */ public class ApplicationManagementException extends Exception { - - String message; + private String message; public ApplicationManagementException(String message, Throwable throwable) { super(message, throwable); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationUploadManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationStorageManagementException.java similarity index 61% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationUploadManager.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationStorageManagementException.java index 997342bd5a6..cba6915bcb9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationUploadManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationStorageManagementException.java @@ -16,11 +16,18 @@ * under the License. * */ -package org.wso2.carbon.device.application.mgt.common.services; + +package org.wso2.carbon.device.application.mgt.common.exception; /** - * This interface manages all the operations related with Application Upload. + * Represents the exception thrown during storing and retrieving the artifacts. */ -public interface ApplicationUploadManager { +public class ApplicationStorageManagementException extends ApplicationManagementException { + public ApplicationStorageManagementException(String message, Throwable ex) { + super(message, ex); + } + public ApplicationStorageManagementException(String message) { + super(message); + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java index 0bbd63c1cad..89a46e8bd8f 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java @@ -18,7 +18,10 @@ */ package org.wso2.carbon.device.application.mgt.common.services; -import org.wso2.carbon.device.application.mgt.common.*; +import org.wso2.carbon.device.application.mgt.common.Application; +import org.wso2.carbon.device.application.mgt.common.ApplicationList; +import org.wso2.carbon.device.application.mgt.common.Filter; +import org.wso2.carbon.device.application.mgt.common.LifecycleStateTransition; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import java.util.List; @@ -62,11 +65,11 @@ public interface ApplicationManager { /** * To change the lifecycle of the Application. * - * @param applicationUUID UUID of the Application + * @param applicationUuid UUID of the Application * @param lifecycleIdentifier New life-cycle that need to be changed. * @throws ApplicationManagementException Application Management Exception. */ - public void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws + public void changeLifecycle(String applicationUuid, String lifecycleIdentifier) throws ApplicationManagementException; /** @@ -88,4 +91,5 @@ public interface ApplicationManager { */ public Application getApplication(String uuid) throws ApplicationManagementException; + } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationReleaseManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationReleaseManager.java index 129404c8218..05d293282fa 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationReleaseManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationReleaseManager.java @@ -18,6 +18,11 @@ */ package org.wso2.carbon.device.application.mgt.common.services; +import org.wso2.carbon.device.application.mgt.common.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; + +import java.util.List; + /** * ApplicationReleaseManager is responsible for handling all the operations related with * {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease} which involving addition, updation , @@ -26,4 +31,45 @@ package org.wso2.carbon.device.application.mgt.common.services; */ public interface ApplicationReleaseManager { + /** + * To create an application release for an Application. + * + * @param appicationUuid UUID of the Application + * @param applicationRelease ApplicatonRelease that need to be be created. + * @return the unique id of the application release, if the application release succeeded else -1 + */ + public ApplicationRelease createRelease(String appicationUuid, ApplicationRelease applicationRelease) throws + ApplicationManagementException; + + /** + * To get the application release of the Application/ + * @param applicationUuid UUID of the Application. + * @param version Version of the ApplicationRelease that need to be retrieved. + * @return ApplicationRelease related with particular Application UUID and version. + * @throws ApplicationManagementException ApplicationManagementException + */ + public ApplicationRelease getRelease(String applicationUuid, String version) throws ApplicationManagementException; + + /** + * To get all the releases of a particular Application. + * @param applicationUuid UUID of the Application to get all the releases. + * @return the List of the Application releases related with the particular Application. + * @throws ApplicationManagementException Application Management Exception. + */ + public List getReleases(String applicationUuid) throws ApplicationManagementException; + + /** + * To make a release as the default one for an application. + * + * @param id ID of the ApplicationRelease, that need to be made default. + */ + public void makeDefaultRelease(int id) throws ApplicationManagementException; + + /** + * To update with a new release for an Application. + * + * @param applicationRelease ApplicationRelease + * @throws ApplicationManagementException Application Management Exception. + */ + public void updateRelease(ApplicationRelease applicationRelease) throws ApplicationManagementException; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java new file mode 100644 index 00000000000..72da318963d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.device.application.mgt.common.services; + +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; + +import java.io.InputStream; +import java.util.List; + +/** + * This manages all the storage related requirements of Application. + */ +public interface ApplicationStorageManager { + /** + * To upload image artifacts related with an Application. + * + * @param applicationUUID UUID of the application + * @param iconFile Icon File input stream + * @param bannerFile Banner File input stream + * @throws ApplicationStorageManagementException Application Storage Management Exception. + */ + public void uploadImageArtifacts(String applicationUUID, InputStream iconFile, InputStream bannerFile, + List screenshots) throws ApplicationStorageManagementException; + + /** + * To upload release artifacts for an Application. + * @param applicationUUID UUID of the application related with the release. + * @param versionName Name of version of the Applcation Release. + * @param binaryFile Binary File for the release. + * @throws ApplicationStorageManagementException Application Storage Management Exception. + */ + public void uploadReleaseArtifacts(String applicationUUID, String versionName, InputStream binaryFile) throws + ApplicationStorageManagementException; + + /** + * To get released artifacts for the particular version of the application. + * @param applicationUUID UUID of the Application + * @param versionName Version of the release to be retrieved + * @return the artifact related with the Application Release. + * @throws ApplicationStorageManagementException Application Storage Management Exception. + */ + public InputStream getReleasedArtifacts(String applicationUUID, String versionName) throws + ApplicationStorageManagementException; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Artifacts.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Artifacts.java new file mode 100644 index 00000000000..0c451ec7c9d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Artifacts.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.device.application.mgt.core.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * This represents Artifacts element in application-mgt configuration file. + */ +@XmlRootElement(name = "Artifacts") +public class Artifacts { + private String imageLocation; + private String binaryLocation; + + @XmlElement(name = "ImageLocation", required = true) + public String getImageLocation() { + return imageLocation; + } + + public void setImageLocation(String imageLocation) { + this.imageLocation = imageLocation; + } + + @XmlElement(name = "BinaryLocation", required = true) + public String getBinaryLocation() { + return binaryLocation; + } + + public void setBinaryLocation(String binaryLocation) { + this.binaryLocation = binaryLocation; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Configuration.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Configuration.java index 36fadc7af0f..2d076c1d37b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Configuration.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Configuration.java @@ -33,6 +33,8 @@ public class Configuration { private List extensions; + private Artifacts artifacts; + @XmlElement(name = "DatasourceName", required = true) public String getDatasourceName() { return datasourceName; @@ -51,6 +53,15 @@ public class Configuration { public void setExtensions(List extensions) { this.extensions = extensions; } + + @XmlElement(name = "Artifacts") + public Artifacts getArtifacts() { + return artifacts; + } + + public void setArtifacts(Artifacts artifacts) { + this.artifacts = artifacts; + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Extension.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Extension.java index 45f0cdcf733..5ad1d05440f 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Extension.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Extension.java @@ -87,7 +87,8 @@ public class Extension { PlatformManager, VisibilityTypeManager, SubscriptionManager, - VisibilityManager + VisibilityManager, + ApplicationStorageManager } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java index 621cbd58212..8205a3250d8 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java @@ -18,9 +18,42 @@ */ package org.wso2.carbon.device.application.mgt.core.dao; +import org.wso2.carbon.device.application.mgt.common.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.util.List; + /** * This is responsible for Application Release related DAO operations. */ public interface ApplicationReleaseDAO { + /** + * To create an Application release. + * + * @param applicationRelease Application Release that need to be created. + * @return Unique ID of the relevant release. + * @throws ApplicationManagementDAOException Application Management DAO Exception. + */ + ApplicationRelease createRelease(ApplicationRelease applicationRelease) throws + ApplicationManagementDAOException; + + /** + * To get a release details with the particular version. + * @param applicationUuid UUID of the application to get the release. + * @param versionName Name of the version + * @return ApplicationRelease for the particular version of the given application + * @throws ApplicationManagementDAOException Application Management DAO Exception. + */ + ApplicationRelease getRelease(String applicationUuid, String versionName) throws ApplicationManagementDAOException; + + /** + * To get all the releases of a particular application. + * + * @param applicationUUID Application UUID + * @return list of the application releases + * @throws ApplicationManagementDAOException Application Management DAO Exception. + */ + List getApplicationReleases(String applicationUUID) throws ApplicationManagementDAOException; + } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/LifecycleStateDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/LifecycleStateDAO.java index dbe164b7cb1..b408621582d 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/LifecycleStateDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/LifecycleStateDAO.java @@ -24,6 +24,9 @@ import org.wso2.carbon.device.application.mgt.core.exception.DAOException; import java.util.List; +/** + * This is responsible for all the DAO operations related to Lifecycle state. + */ public interface LifecycleStateDAO { LifecycleState getLifeCycleStateByIdentifier(String identifier) throws ApplicationManagementDAOException; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/DAOFactory.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/DAOFactory.java index 87b485527f4..5f97b518fa7 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/DAOFactory.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/DAOFactory.java @@ -23,9 +23,11 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.application.mgt.common.exception.UnsupportedDatabaseEngineException; import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; import org.wso2.carbon.device.application.mgt.core.dao.LifecycleStateDAO; import org.wso2.carbon.device.application.mgt.core.dao.PlatformDAO; import org.wso2.carbon.device.application.mgt.core.dao.impl.application.GenericApplicationDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.application.release.GenericApplicationReleaseDAOImpl; import org.wso2.carbon.device.application.mgt.core.dao.impl.lifecyclestate.GenericLifecycleStateImpl; import org.wso2.carbon.device.application.mgt.core.dao.impl.platform.GenericPlatformDAOImpl; import org.wso2.carbon.device.application.mgt.core.dao.impl.platform.OracleMsSQLPlatformDAOImpl; @@ -96,6 +98,23 @@ public class DAOFactory { throw new IllegalStateException("Database engine has not initialized properly."); } + /** + * To get the instance of ApplicationReleaseDAOImplementation of the particular database engine. + * @return specific ApplicationReleaseDAOImplementation + */ + public static ApplicationReleaseDAO getApplicationReleaseDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case Constants.DataBaseTypes.DB_TYPE_H2: + case Constants.DataBaseTypes.DB_TYPE_MYSQL: + return new GenericApplicationReleaseDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } + /** * This method initializes the databases by creating the database. * diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/AbstractDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/AbstractDAOImpl.java index a85ce946a59..bbc1f85c0e9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/AbstractDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/AbstractDAOImpl.java @@ -23,6 +23,9 @@ import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; import java.sql.Connection; +/** + * This class deals with getting the DB connection. + */ public abstract class AbstractDAOImpl { protected Connection getDBConnection() throws DBConnectionException { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java new file mode 100644 index 00000000000..f35c63f0db5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.application.release; + +import org.wso2.carbon.device.application.mgt.common.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; +import org.wso2.carbon.device.application.mgt.core.dao.common.Util; +import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; + +import java.sql.Connection; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * GenericApplicationReleaseDAOImpl holds the implementation of ApplicationRelease related DAO operations. + */ +public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements ApplicationReleaseDAO { + + @Override + public ApplicationRelease createRelease(ApplicationRelease applicationRelease) throws + ApplicationManagementDAOException { + Connection connection; + PreparedStatement statement = null; + ResultSet resultSet = null; + String sql = "insert into APPM_APPLICATION_RELEASE(VERSION_NAME, RESOURCE, RELEASE_CHANNEL ," + + "RELEASE_DETAILS, CREATED_AT, APPM_APPLICATION_ID, IS_DEFAULT) values (?, ?, ?, ?, ?, ?, ?)"; + int index = 0; + boolean isBatchExecutionSupported = ConnectionManagerUtil.isBatchQuerySupported(); + + try { + connection = this.getDBConnection(); + statement = connection.prepareStatement(sql); + statement.setString(++index, applicationRelease.getVersionName()); + statement.setString(++index, applicationRelease.getResource()); + statement.setString(++index, String.valueOf(applicationRelease.getReleaseChannel())); + statement.setString(++index, applicationRelease.getReleaseDetails()); + statement.setDate(++index, new Date(applicationRelease.getCreatedAt().getTime())); + statement.setInt(++index, applicationRelease.getApplication().getId()); + statement.setBoolean(++index, applicationRelease.isDefault()); + statement.executeUpdate(); + resultSet = statement.getGeneratedKeys(); + if (resultSet.next()) { + applicationRelease.setId(resultSet.getInt(1)); + } + + if (applicationRelease.getProperties() != null && applicationRelease.getProperties().size() != 0) { + sql = "INSERT INTO APPM_RELEASE_PROPERTY (PROP_KEY, PROP_VALUE, APPLICATION_RELEASE_ID) VALUES (?,?,?)"; + statement = connection.prepareStatement(sql); + for (Object entry : applicationRelease.getProperties().entrySet()) { + Map.Entry property = (Map.Entry) entry; + statement.setString(1, property.getKey()); + statement.setString(2, property.getValue()); + statement.setInt(3, applicationRelease.getId()); + if (isBatchExecutionSupported) { + statement.addBatch(); + } else { + statement.execute(); + } + } + if (isBatchExecutionSupported) { + statement.executeBatch(); + } + } + return applicationRelease; + } catch (SQLException e) { + throw new ApplicationManagementDAOException( + "SQL Exception while trying to release an application (UUID : " + applicationRelease + .getApplication().getUuid() + "), by executing the query " + sql, e); + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException( + "Database Connection Exception while trying to release the " + "applcation with UUID " + + applicationRelease.getApplication().getUuid(), e); + } finally { + Util.cleanupResources(statement, resultSet); + } + } + + @Override + public ApplicationRelease getRelease(String applicationUuid, String versionName) + throws ApplicationManagementDAOException { + Connection connection; + PreparedStatement statement = null; + ResultSet resultSet = null; + String sql = "SELECT * FROM APPM_APPLICATION_RELEASE WHERE VERSION_NAME = ? AND APPM_APPLICATION_ID = " + + "(SELECT ID FROM APPM_APPLICATION WHERE UUID = ?)"; + ApplicationRelease applicationRelease = null; + ResultSet rsProperties = null; + + try { + connection = this.getDBConnection(); + statement = connection.prepareStatement(sql); + statement.setString(1, versionName); + statement.setString(2, applicationUuid); + resultSet = statement.executeQuery(); + + if (resultSet.next()) { + applicationRelease = new ApplicationRelease(); + applicationRelease.setVersionName(versionName); + applicationRelease.setDefault(resultSet.getBoolean("IS_DEFAULT")); + applicationRelease.setCreatedAt(resultSet.getDate("CREATED_AT")); + applicationRelease.setReleaseChannel(resultSet.getString("RELEASE_CHANNEL")); + applicationRelease.setReleaseDetails(resultSet.getString("RELEASE_DETAILS")); + applicationRelease.setResource(resultSet.getString("RESOURCE")); + + sql = "SELECT * FROM APPM_RELEASE_PROPERTY WHERE APPLICATION_RELEASE_ID=?"; + statement = connection.prepareStatement(sql); + statement.setInt(1, resultSet.getInt("ID")); + rsProperties = statement.executeQuery(); + + Map properties = new HashMap<>(); + while (rsProperties.next()) { + properties.put(rsProperties.getString("PROP_KEY"), + rsProperties.getString("PROP_VAL")); + } + applicationRelease.setProperties(properties); + } + return applicationRelease; + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException("Database connection exception while trying to gett the " + + "release details of the application with UUID " + applicationUuid + " and version " + + versionName, e); + } catch (SQLException e) { + throw new ApplicationManagementDAOException("Error while getting release details of the application " + + applicationUuid + " and version " + versionName + " , while executing the query " + sql, e); + } finally { + Util.cleanupResources(statement, resultSet); + Util.cleanupResources(null, rsProperties); + } + } + + @Override + public List getApplicationReleases(String applicationUUID) + throws ApplicationManagementDAOException { + Connection connection; + PreparedStatement statement = null; + ResultSet resultSet = null; + String sql = "SELECT * FROM APPM_APPLICATION_RELEASE WHERE APPM_APPLICATION_ID = (SELECT ID FROM " + + "APPM_APPLICATION WHERE UUID = ?)"; + List applicationReleases = new ArrayList<>(); + ResultSet rsProperties = null; + + try { + connection = this.getDBConnection(); + statement = connection.prepareStatement(sql); + statement.setString(1, applicationUUID); + resultSet = statement.executeQuery(); + + while (resultSet.next()) { + ApplicationRelease applicationRelease = new ApplicationRelease(); + applicationRelease.setVersionName(resultSet.getString("VERSION_NAME")); + applicationRelease.setDefault(resultSet.getBoolean("IS_DEFAULT")); + applicationRelease.setCreatedAt(resultSet.getDate("CREATED_AT")); + applicationRelease.setReleaseChannel(resultSet.getString("RELEASE_CHANNEL")); + applicationRelease.setReleaseDetails(resultSet.getString("RELEASE_DETAILS")); + applicationRelease.setResource(resultSet.getString("RESOURCE")); + + sql = "SELECT * FROM APPM_RELEASE_PROPERTY WHERE APPLICATION_RELEASE_ID= ?"; + statement = connection.prepareStatement(sql); + statement.setInt(1, resultSet.getInt("ID")); + rsProperties = statement.executeQuery(); + + Map properties = new HashMap<>(); + while (rsProperties.next()) { + properties.put(rsProperties.getString("PROP_KEY"), rsProperties.getString("PROP_VAL")); + } + applicationRelease.setProperties(properties); + applicationReleases.add(applicationRelease); + } + return applicationReleases; + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException("Database connection exception while trying to get the " + + "release details of the application with UUID " + applicationUUID, e); + } catch (SQLException e) { + throw new ApplicationManagementDAOException( + "Error while getting all the release details of the " + "application " + applicationUUID + + ", while executing the query " + sql, e); + } finally { + Util.cleanupResources(statement, resultSet); + Util.cleanupResources(null, rsProperties); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/GenericLifecycleStateImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/GenericLifecycleStateImpl.java index 0c1edf5c222..a772ba8583b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/GenericLifecycleStateImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/GenericLifecycleStateImpl.java @@ -33,6 +33,9 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +/** + * Concrete implementation for Lifecycle related DB operations. + */ public class GenericLifecycleStateImpl extends AbstractDAOImpl implements LifecycleStateDAO { @Override @@ -82,7 +85,7 @@ public class GenericLifecycleStateImpl extends AbstractDAOImpl implements Lifecy String sql = "SELECT IDENTIFIER, NAME, DESCRIPTION FROM APPM_LIFECYCLE_STATE"; stmt = conn.prepareStatement(sql); rs = stmt.executeQuery(); - while(rs.next()) { + while (rs.next()) { LifecycleState lifecycleState = new LifecycleState(); lifecycleState.setIdentifier(rs.getString("IDENTIFIER")); lifecycleState.setName(rs.getString("NAME")); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationManagementDAOException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationManagementDAOException.java index d951b84c9d9..c50602a1868 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationManagementDAOException.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationManagementDAOException.java @@ -20,6 +20,9 @@ package org.wso2.carbon.device.application.mgt.core.exception; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +/** + * Exception thrown during the Application Management DAO operations. + */ public class ApplicationManagementDAOException extends ApplicationManagementException { public ApplicationManagementDAOException(String message, Throwable throwable) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/DAOException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/DAOException.java index 2d5121bdca1..82fb6e1530a 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/DAOException.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/DAOException.java @@ -17,6 +17,9 @@ */ package org.wso2.carbon.device.application.mgt.core.exception; +/** + * This exception will be thrown when there is an issue with Lifecycle related DAO operations. + */ public class DAOException extends Exception { public DAOException(String message) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/NotFoundException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/NotFoundException.java index 5314dd06ac8..43daf8890a0 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/NotFoundException.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/NotFoundException.java @@ -20,6 +20,9 @@ package org.wso2.carbon.device.application.mgt.core.exception; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +/** + * This exception will be thrown when the requested application or platform not found. + */ public class NotFoundException extends ApplicationManagementException { public NotFoundException(String message, Throwable throwable) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ValidationException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ValidationException.java index 7044f2ce5e7..a537cdf7cb9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ValidationException.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ValidationException.java @@ -20,6 +20,9 @@ package org.wso2.carbon.device.application.mgt.core.exception; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +/** + * This exception will be thrown when the initial validation fails to perform an operation. + */ public class ValidationException extends ApplicationManagementException { public ValidationException(String message, Throwable throwable) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index 05afbb555c4..837ba1ea7c8 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -46,10 +46,14 @@ import org.wso2.carbon.user.api.UserRealm; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; +/** + * Default Concrete implementation of Application Management related implementations. + */ public class ApplicationManagerImpl implements ApplicationManager { private static final Log log = LogFactory.getLog(ApplicationManagerImpl.class); @@ -182,15 +186,15 @@ public class ApplicationManagerImpl implements ApplicationManager { } @Override - public void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws + public void changeLifecycle(String applicationUuid, String lifecycleIdentifier) throws ApplicationManagementException { boolean isAvailableNextState = false; String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - List nextLifeCycles = getLifeCycleStates(applicationUUID); + List nextLifeCycles = getLifeCycleStates(applicationUuid); for (LifecycleStateTransition lifecycleStateTransition : nextLifeCycles) { if (log.isDebugEnabled()) { - log.debug("Lifecycle state of the application " + applicationUUID + " can be changed to" + log.debug("Lifecycle state of the application " + applicationUuid + " can be changed to" + lifecycleStateTransition.getNextState()); } if (lifecycleStateTransition.getNextState().equalsIgnoreCase(lifecycleIdentifier)) { @@ -200,13 +204,13 @@ public class ApplicationManagerImpl implements ApplicationManager { } if (!isAvailableNextState) { throw new ApplicationManagementException("User " + userName + " does not have the permission to change " - + "the lifecycle state of the application " + applicationUUID + " to lifecycle state " + + "the lifecycle state of the application " + applicationUuid + " to lifecycle state " + lifecycleIdentifier); } try { ConnectionManagerUtil.beginDBTransaction(); ApplicationDAO applicationDAO = DAOFactory.getApplicationDAO(); - applicationDAO.changeLifecycle(applicationUUID, lifecycleIdentifier, userName); + applicationDAO.changeLifecycle(applicationUuid, lifecycleIdentifier, userName); ConnectionManagerUtil.commitDBTransaction(); } catch (ApplicationManagementDAOException e) { ConnectionManagerUtil.rollbackDBTransaction(); @@ -282,6 +286,12 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + public void uploadArtifacts(String applicationUUID, InputStream iconFileStream, InputStream bannerFileStream, + List screenShotStreams) + throws ApplicationManagementException { + + } + /** * To check whether current user is application owner or admin. * @@ -297,7 +307,8 @@ public class ApplicationManagerImpl implements ApplicationManager { } } catch (UserStoreException e) { throw new ApplicationManagementException("Userstore exception while checking whether user is an admin", e); - } try { + } + try { ConnectionManagerUtil.openDBConnection(); Application application = DAOFactory.getApplicationDAO().getApplication(applicationUUID); return application.getUser().getUserName().equals(userName) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationReleaseManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationReleaseManagerImpl.java index 874164efeeb..bc7cfa33a03 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationReleaseManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationReleaseManagerImpl.java @@ -18,8 +18,139 @@ */ package org.wso2.carbon.device.application.mgt.core.impl; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.Application; +import org.wso2.carbon.device.application.mgt.common.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.services.ApplicationReleaseManager; +import org.wso2.carbon.device.application.mgt.core.dao.common.DAOFactory; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; +import java.util.Date; +import java.util.List; + +/** + * Concrete implementation for Application Release Management related tasks. + */ public class ApplicationReleaseManagerImpl implements ApplicationReleaseManager { + private static Log log = LogFactory.getLog(ApplicationReleaseManagerImpl.class); + + @Override + public ApplicationRelease createRelease(String appicationUuid, ApplicationRelease applicationRelease) throws + ApplicationManagementException { + Application application = validateReleaseCreateRequest(appicationUuid, applicationRelease); + if (log.isDebugEnabled()) { + log.debug("Application release request is received for the application " + application.toString()); + } + applicationRelease.setCreatedAt(new Date()); + try { + ConnectionManagerUtil.beginDBTransaction(); + applicationRelease.setApplication(application); + applicationRelease = DAOFactory.getApplicationReleaseDAO().createRelease(applicationRelease); + ConnectionManagerUtil.commitDBTransaction(); + return applicationRelease; + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + throw e; + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public ApplicationRelease getRelease(String applicationUuid, String version) throws + ApplicationManagementException { + Application application = validationGetReleaseRequest(applicationUuid); + if (log.isDebugEnabled()) { + log.debug("Application release retrieval request is received for the application " + + application.toString() + " and version " + version); + } + try { + ConnectionManagerUtil.openDBConnection(); + return DAOFactory.getApplicationReleaseDAO().getRelease(applicationUuid, version); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getReleases(String applicationUuid) throws ApplicationManagementException { + Application application = validationGetReleaseRequest(applicationUuid); + if (log.isDebugEnabled()) { + log.debug("Request is received to retrieve all the releases related with the application " + + application.toString()); + } + try { + ConnectionManagerUtil.openDBConnection(); + return DAOFactory.getApplicationReleaseDAO().getApplicationReleases(applicationUuid); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void makeDefaultRelease(int id) throws ApplicationManagementException { + + } + + @Override + public void updateRelease(ApplicationRelease applicationRelease) throws ApplicationManagementException { + + } + + /** + * To validate the pre-request of the ApplicationRelease. + * + * @param applicationUuid UUID of the Application. + * @return Application related with the UUID + */ + private Application validationGetReleaseRequest(String applicationUuid) throws ApplicationManagementException { + if (applicationUuid == null) { + throw new ApplicationManagementException("Application UUID is null. Application UUID is a required " + + "parameter to get the releases related to a particular application."); + } + Application application = DataHolder.getInstance().getApplicationManager().getApplication(applicationUuid); + if (application == null) { + throw new ApplicationManagementException( + "Application with UUID " + applicationUuid + " does not exist. Cannot " + + "retrieve the releases for a non-existing application."); + } + return application; + } + /** + * To validate a create release request to make sure all the pre-conditions satisfied. + * + * @param applicationUuid UUID of the Application. + * @param applicationRelease ApplicationRelease that need to be created. + * @return the Application related with the particular Application Release + * @throws ApplicationManagementException Application Management Exception. + */ + private Application validateReleaseCreateRequest(String applicationUuid, ApplicationRelease applicationRelease) + throws ApplicationManagementException { + if (applicationUuid == null) { + throw new ApplicationManagementException("Application UUID is null. Application UUID is a required " + + "parameter to do the application release"); + } + Application application = DataHolder.getInstance().getApplicationManager().getApplication(applicationUuid); + if (application == null) { + throw new ApplicationManagementException( + "Application with UUID " + applicationUuid + " does not exist. Cannot " + + "release an application that is not existing"); + } + if (applicationRelease == null || applicationRelease.getVersionName() == null) { + throw new ApplicationManagementException("ApplicationRelease version name is a mandatory parameter for " + + "creating release. It cannot be found."); + } + if (getRelease(applicationUuid, applicationRelease.getVersionName()) != null) { + throw new ApplicationManagementException( + "Application Release for the Application UUID " + applicationUuid + " " + "with the version " + + applicationRelease.getVersionName() + " already exists. Cannot create an " + + "application release with the same version."); + } + return application; + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java new file mode 100644 index 00000000000..30e9499dfa8 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.device.application.mgt.core.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.Application; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.util.Constants; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + +/** + * This class contains the default concrete implementation of ApplicationStorage Management. + */ +public class ApplicationStorageManagerImpl implements ApplicationStorageManager { + private static final Log log = LogFactory.getLog(ApplicationStorageManagerImpl.class); + + @Override + public void uploadImageArtifacts(String applicationUUID, InputStream iconFileStream, InputStream bannerFileStream, + List screenShotStreams) throws ApplicationStorageManagementException { + Application application; + try { + application = DataHolder.getInstance().getApplicationManager().getApplication(applicationUUID); + } catch (ApplicationManagementException e) { + throw new ApplicationStorageManagementException( + "Exception while retrieving the application details for " + "the application with UUID " + + applicationUUID); + } + if (application == null) { + throw new ApplicationStorageManagementException("Application with UUID " + applicationUUID + " does not " + + "exist. Cannot upload the artifacts to non-existing application."); + } + String artifactDirectoryPath = Constants.artifactPath + application.getId(); + if (log.isDebugEnabled()) { + log.debug("Artifact Directory Path for saving the artifacts related with application " + applicationUUID + + " is " + artifactDirectoryPath); + } + createArtifactDirectory(artifactDirectoryPath); + if (iconFileStream != null) { + String iconName = application.getIconName(); + iconName = (iconName == null) ? "icon" : iconName; + try { + saveFile(iconFileStream, artifactDirectoryPath + File.separator + iconName); + } catch (IOException e) { + throw new ApplicationStorageManagementException( + "IO Exception while saving the icon file in the server for " + "the application " + + applicationUUID, e); + } + } + if (bannerFileStream != null) { + String bannerName = application.getBannerName(); + bannerName = (bannerName == null) ? "banner" : bannerName; + try { + saveFile(bannerFileStream, artifactDirectoryPath + File.separator + bannerName); + } catch (IOException e) { + throw new ApplicationStorageManagementException( + "IO Exception while saving the banner file in the server for" + " the application " + + applicationUUID, e); + } + } + if (screenShotStreams != null) { + int count = 1; + String screenshotName; + List screenShotNames = application.getScreenshots(); + boolean isScreenShotNameExist = (screenShotNames == null || screenShotNames.isEmpty()); + int screenShotNameLength = isScreenShotNameExist ? screenShotNames.size() : 0; + for (InputStream screenshotStream : screenShotStreams) { + try { + if (isScreenShotNameExist && count <= screenShotNameLength) { + screenshotName = screenShotNames.get(count); + } else { + screenshotName = "screenshot_" + count; + } + saveFile(screenshotStream, artifactDirectoryPath + File.separator + screenshotName); + count++; + } catch (IOException e) { + throw new ApplicationStorageManagementException( + "IO Exception while saving the screens hots for the " + "application " + applicationUUID, + e); + } + } + } + } + + @Override + public void uploadReleaseArtifacts(String applicationUUID, String versionName, InputStream binaryFile) + throws ApplicationStorageManagementException { + Application application; + try { + application = DataHolder.getInstance().getApplicationManager().getApplication(applicationUUID); + } catch (ApplicationManagementException e) { + throw new ApplicationStorageManagementException("Exception while retrieving the application details for " + + "the application with UUID " + applicationUUID); + } + if (application == null) { + throw new ApplicationStorageManagementException("Application with UUID " + applicationUUID + " does not " + + "exist. Cannot upload release artifacts for not existing application."); + } + String artifactDirectoryPath = Constants.artifactPath + application.getId(); + if (log.isDebugEnabled()) { + log.debug("Artifact Directory Path for saving the application release related artifacts related with " + + "application " + applicationUUID + " is " + artifactDirectoryPath); + } + + createArtifactDirectory(artifactDirectoryPath); + if (binaryFile != null) { + try { + saveFile(binaryFile, artifactDirectoryPath + File.separator + versionName); + } catch (IOException e) { + throw new ApplicationStorageManagementException( + "IO Exception while saving the release artifacts in the server for the application " + + applicationUUID, e); + } + } + + } + + @Override + public InputStream getReleasedArtifacts(String applicationUUID, String versionName) + throws ApplicationStorageManagementException { + Application application; + try { + application = DataHolder.getInstance().getApplicationManager().getApplication(applicationUUID); + } catch (ApplicationManagementException e) { + throw new ApplicationStorageManagementException("Exception while retrieving the application details for " + + "the application with UUID " + applicationUUID); + } + if (application == null) { + throw new ApplicationStorageManagementException("Application with UUID " + applicationUUID + " does not " + + "exist. Cannot retrieve release artifacts for not existing application."); + } + String artifactPath = Constants.artifactPath + application.getId() + File.separator + versionName; + + if (log.isDebugEnabled()) { + log.debug("ApplicationRelease artifacts are searched in the location " + artifactPath); + } + + File binaryFile = new File(artifactPath); + + if (!binaryFile.exists()) { + throw new ApplicationStorageManagementException("Binary file does not exist for this release"); + } else { + try { + return new FileInputStream(artifactPath); + } catch (FileNotFoundException e) { + throw new ApplicationStorageManagementException("Binary file does not exist for the version " + + versionName + " for the application ", e); + } + } + } + + /** + * To save a file in a given location. + * + * @param inputStream Stream of the file. + * @param path Path the file need to be saved in. + */ + private void saveFile(InputStream inputStream, String path) throws IOException { + OutputStream outStream = null; + try { + byte[] buffer = new byte[inputStream.available()]; + inputStream.read(buffer); + outStream = new FileOutputStream(new File(path)); + outStream.write(buffer); + } finally { + if (inputStream != null) { + inputStream.close(); + } + if (outStream != null) { + outStream.close(); + } + } + } + + /** + * This method is responsible for creating artifact parent directories in the given path. + * + * @param artifactDirectoryPath Path for the artifact directory. + * @throws ApplicationStorageManagementException Application Storage Management Exception. + */ + private void createArtifactDirectory(String artifactDirectoryPath) throws ApplicationStorageManagementException { + File artifactDirectory = new File(artifactDirectoryPath); + + if (!artifactDirectory.exists()) { + if (!artifactDirectory.mkdirs()) { + throw new ApplicationStorageManagementException( + "Cannot create directories in the path to save the application related artifacts"); + } + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationUploadManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationUploadManagerImpl.java deleted file mode 100644 index 38b908c00dd..00000000000 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationUploadManagerImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.wso2.carbon.device.application.mgt.core.impl; - - -import org.wso2.carbon.device.application.mgt.common.services.ApplicationUploadManager; - -public class ApplicationUploadManagerImpl implements ApplicationUploadManager { - - public ApplicationUploadManagerImpl(String uploadPath){ - - } -} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/LifecycleStateManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/LifecycleStateManagerImpl.java index eccf7d4530a..9e9f8d9b74b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/LifecycleStateManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/LifecycleStateManagerImpl.java @@ -30,6 +30,9 @@ import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; import java.util.List; +/** + * Concrete implementation of Lifecycle state management. + */ public class LifecycleStateManagerImpl implements LifecycleStateManager { private static final Log log = LogFactory.getLog(LifecycleStateManagerImpl.class); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/PlatformManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/PlatformManagerImpl.java index 44e516217c5..5daa733cd30 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/PlatformManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/PlatformManagerImpl.java @@ -89,16 +89,11 @@ public class PlatformManagerImpl implements PlatformManager { + "PlatformManager level"); } try { - ConnectionManagerUtil.beginDBTransaction(); + ConnectionManagerUtil.openDBConnection(); platforms = DAOFactory.getPlatformDAO().getPlatforms(tenantId); - ConnectionManagerUtil.commitDBTransaction(); - } catch (DBConnectionException | TransactionManagementException e) { - ConnectionManagerUtil.rollbackDBTransaction(); + } catch (DBConnectionException e) { throw new PlatformManagementDAOException( "Database Connection Exception while getting the platforms for the tenant : " + tenantId, e); - } catch (PlatformManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); - throw e; } finally { ConnectionManagerUtil.closeDBConnection(); } @@ -136,20 +131,15 @@ public class PlatformManagerImpl implements PlatformManager { Platform platform = getPlatformFromInMemory(tenantId, identifier); if (platform == null) { try { - ConnectionManagerUtil.beginDBTransaction(); + ConnectionManagerUtil.openDBConnection(); platform = DAOFactory.getPlatformDAO().getPlatform(tenantId, identifier); - ConnectionManagerUtil.commitDBTransaction(); if (platform != null) { return platform; } - } catch (DBConnectionException | TransactionManagementException e) { - ConnectionManagerUtil.rollbackDBTransaction(); + } catch (DBConnectionException e) { throw new PlatformManagementDAOException( "Database Connection Exception while trying to get the " + "platform with the id :" + identifier + " for the tenant : " + tenantId, e); - } catch (PlatformManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); - throw e; } finally { ConnectionManagerUtil.closeDBConnection(); } @@ -455,18 +445,16 @@ public class PlatformManagerImpl implements PlatformManager { private void validateBeforeRegister(int tenantId, Platform platform) throws PlatformManagementException { validatePlatformSharing(tenantId, platform); try { - ConnectionManagerUtil.beginDBTransaction(); + ConnectionManagerUtil.openDBConnection(); int existingPlatformId = DAOFactory.getPlatformDAO() .getSuperTenantAndOwnPlatforms(platform.getIdentifier(), tenantId); - ConnectionManagerUtil.commitDBTransaction(); if (existingPlatformId != -1) { throw new PlatformManagementException( "Another platform exists with the identifier " + platform.getIdentifier() + " in the tenant " + tenantId + " or super-tenant. Please choose a " + "different identifier for your platform"); } - } catch (TransactionManagementException | DBConnectionException e) { - ConnectionManagerUtil.rollbackDBTransaction(); + } catch (DBConnectionException e) { throw new PlatformManagementException( "Error while checking pre-conditions before registering" + " platform identifier '" + platform .getIdentifier() + "' for the tenant :" + tenantId); @@ -488,10 +476,9 @@ public class PlatformManagerImpl implements PlatformManager { PlatformManagementException { validatePlatformSharing(tenantId, platform); try { - ConnectionManagerUtil.beginDBTransaction(); + ConnectionManagerUtil.openDBConnection(); Platform oldPlatform = DAOFactory.getPlatformDAO().getTenantOwnedPlatform(tenantId, oldPlatformIdentifier); if (oldPlatform == null) { - ConnectionManagerUtil.commitDBTransaction(); throw new PlatformManagementException( "Cannot update platform. Platform with identifier : " + oldPlatformIdentifier + " does not exist for the tenant : " + tenantId); @@ -499,7 +486,6 @@ public class PlatformManagerImpl implements PlatformManager { if (platform.getIdentifier() != null && !platform.getIdentifier().equals(oldPlatformIdentifier)) { int existingPlatformID = DAOFactory.getPlatformDAO() .getSuperTenantAndOwnPlatforms(platform.getIdentifier(), tenantId); - ConnectionManagerUtil.commitDBTransaction(); if (existingPlatformID == -1) { throw new PlatformManagementException( "Cannot update the identifier of the platform from '" + oldPlatformIdentifier + "' to '" @@ -509,8 +495,7 @@ public class PlatformManagerImpl implements PlatformManager { } } return oldPlatform; - } catch (TransactionManagementException | DBConnectionException e) { - ConnectionManagerUtil.rollbackDBTransaction(); + } catch (DBConnectionException e) { throw new PlatformManagementException( "Database error while validating the platform update with the " + "platform identifier: " + oldPlatformIdentifier + " for the tenant :" + tenantId); @@ -532,18 +517,16 @@ public class PlatformManagerImpl implements PlatformManager { + " cannot be shared by the tenant domain - " + tenantId); } try { - ConnectionManagerUtil.beginDBTransaction(); + ConnectionManagerUtil.openDBConnection(); if (platform.isShared()) { int sharedPlatform = DAOFactory.getPlatformDAO().getMultiTenantPlatforms(platform.getIdentifier()); - ConnectionManagerUtil.commitDBTransaction(); if (sharedPlatform != -1) { throw new PlatformManagementException( "Platform '" + platform.getIdentifier() + "' cannot be shared as some other tenants have " + "platforms with the same identifier."); } } - } catch (TransactionManagementException | DBConnectionException e) { - ConnectionManagerUtil.rollbackDBTransaction(); + } catch (DBConnectionException e) { throw new PlatformManagementException( "Error while checking platform sharing conditions for " + " platform identifier '" + platform .getIdentifier() + "' for the tenant :" + tenantId); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java index 5c4bac04954..426b13b02e5 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java @@ -20,7 +20,7 @@ package org.wso2.carbon.device.application.mgt.core.internal; import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; import org.wso2.carbon.device.application.mgt.common.services.ApplicationReleaseManager; -import org.wso2.carbon.device.application.mgt.common.services.ApplicationUploadManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; import org.wso2.carbon.device.application.mgt.common.services.CategoryManager; import org.wso2.carbon.device.application.mgt.common.services.CommentsManager; import org.wso2.carbon.device.application.mgt.common.services.LifecycleStateManager; @@ -58,7 +58,7 @@ public class DataHolder { private VisibilityManager visibilityManager; - private ApplicationUploadManager applicationUploadManager; + private ApplicationStorageManager applicationStorageManager; private static final DataHolder applicationMgtDataHolder = new DataHolder(); @@ -150,14 +150,6 @@ public class DataHolder { this.visibilityManager = visibilityManager; } - public void setApplicationUploadManager(ApplicationUploadManager applicationUploadManager) { - this.applicationUploadManager = applicationUploadManager; - } - - public ApplicationUploadManager getApplicationUploadManager() { - return applicationUploadManager; - } - public RealmService getRealmService() { return realmService; } @@ -166,4 +158,11 @@ public class DataHolder { this.realmService = realmService; } + public void setApplicationStorageManager(ApplicationStorageManager applicationStorageManager) { + this.applicationStorageManager = applicationStorageManager; + } + + public ApplicationStorageManager getApplicationStorageManager() { + return applicationStorageManager; + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ServiceComponent.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ServiceComponent.java index 1a5884852dc..1a808090ef8 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ServiceComponent.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ServiceComponent.java @@ -25,7 +25,7 @@ import org.osgi.service.component.ComponentContext; import org.wso2.carbon.device.application.mgt.common.exception.InvalidConfigurationException; import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; import org.wso2.carbon.device.application.mgt.common.services.ApplicationReleaseManager; -import org.wso2.carbon.device.application.mgt.common.services.ApplicationUploadManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; import org.wso2.carbon.device.application.mgt.common.services.CategoryManager; import org.wso2.carbon.device.application.mgt.common.services.CommentsManager; import org.wso2.carbon.device.application.mgt.common.services.LifecycleStateManager; @@ -37,6 +37,7 @@ import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; import org.wso2.carbon.device.application.mgt.core.dao.common.DAOFactory; import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; import org.wso2.carbon.device.application.mgt.core.util.ApplicationManagementUtil; +import org.wso2.carbon.device.application.mgt.core.util.Constants; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.ndatasource.core.DataSourceService; import org.wso2.carbon.user.core.service.RealmService; @@ -77,6 +78,8 @@ public class ServiceComponent { String datasourceName = ConfigurationManager.getInstance().getConfiguration().getDatasourceName(); DAOFactory.init(datasourceName); + Constants.artifactPath = ConfigurationManager.getInstance().getConfiguration().getArtifacts() + .getBinaryLocation(); ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance(); DataHolder.getInstance().setApplicationManager(applicationManager); bundleContext.registerService(ApplicationManager.class.getName(), applicationManager, null); @@ -114,9 +117,10 @@ public class ServiceComponent { DataHolder.getInstance().setVisibilityTypeManager(visibilityTypeManager); bundleContext.registerService(VisibilityTypeManager.class.getName(), visibilityTypeManager, null); - ApplicationUploadManager uploadManager = ApplicationManagementUtil.getApplicationUploadManagerInstance(); - DataHolder.getInstance().setApplicationUploadManager(uploadManager); - bundleContext.registerService(ApplicationUploadManager.class.getName(), uploadManager, null); + ApplicationStorageManager applicationStorageManager = ApplicationManagementUtil + .getApplicationStorageManagerInstance(); + DataHolder.getInstance().setApplicationStorageManager(applicationStorageManager); + bundleContext.registerService(ApplicationStorageManager.class.getName(), applicationStorageManager, null); bundleContext.registerService(Axis2ConfigurationContextObserver.class.getName(), new PlatformManagementAxis2ConfigurationObserverImpl(), null); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java index 004ae7dda71..de1a03255ba 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java @@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.application.mgt.common.exception.InvalidConfigurationException; import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; import org.wso2.carbon.device.application.mgt.common.services.ApplicationReleaseManager; -import org.wso2.carbon.device.application.mgt.common.services.ApplicationUploadManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; import org.wso2.carbon.device.application.mgt.common.services.CategoryManager; import org.wso2.carbon.device.application.mgt.common.services.CommentsManager; import org.wso2.carbon.device.application.mgt.common.services.LifecycleStateManager; @@ -99,10 +99,11 @@ public class ApplicationManagementUtil { return getInstance(extension, SubscriptionManager.class); } - public static ApplicationUploadManager getApplicationUploadManagerInstance() throws InvalidConfigurationException { + public static ApplicationStorageManager getApplicationStorageManagerInstance() throws + InvalidConfigurationException { ConfigurationManager configurationManager = ConfigurationManager.getInstance(); - Extension extension = configurationManager.getExtension(Extension.Name.ApplicationUploadManager); - return getInstance(extension, ApplicationUploadManager.class); + Extension extension = configurationManager.getExtension(Extension.Name.ApplicationStorageManager); + return getInstance(extension, ApplicationStorageManager.class); } private static T getInstance(Extension extension, Class cls) throws InvalidConfigurationException { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java index a8701495bb9..467be38824b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java @@ -53,4 +53,9 @@ public class Constants { */ public static final String[] LIFE_CYCLES = {"CREATED", "IN REVIEW", "APPROVED", "REJECTED", "PUBLISHED", "UNPUBLISHED", "RETIRED"}; + + /** + * Path to save the Application related artifacts. + */ + public static String artifactPath = ""; } diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml index fd99ffe3de8..1fb22c2b4a5 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml @@ -55,6 +55,13 @@ org.wso2.carbon.device.application.mgt.core.impl.VisibilityTypeManagerImpl + + org.wso2.carbon.device.application.mgt.core.impl.ApplicationStorageManagerImpl + + + ${carbon.home}/repository/resources/mobileapps/images/ + ${carbon.home}/repository/resources/mobileapps/binary/ + \ No newline at end of file diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql index c2b9a615b49..f344747a4a5 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql @@ -181,15 +181,14 @@ CREATE INDEX FK_APPLICATION_PROPERTY_APPLICATION ON APPM_APPLICATION_PROPERTY(AP -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS APPM_APPLICATION_RELEASE ( ID INT NOT NULL AUTO_INCREMENT, - VERSION_ID INT NOT NULL, VERSION_NAME VARCHAR(100) NOT NULL, RESOURCE TEXT NULL, RELEASE_CHANNEL VARCHAR(50) NULL, RELEASE_DETAILS TEXT NULL, CREATED_AT DATETIME NOT NULL, APPM_APPLICATION_ID INT NOT NULL, - PUBLISHED TINYINT NULL, - PRIMARY KEY (ID, APPM_APPLICATION_ID), + IS_DEFAULT TINYINT NULL, + PRIMARY KEY (APPM_APPLICATION_ID, VERSION_NAME), CONSTRAINT FK_APPLICATION_VERSION_APPLICATION FOREIGN KEY (APPM_APPLICATION_ID) REFERENCES APPM_APPLICATION (ID) diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql index 40766adc0c7..d0785ca9b03 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql @@ -189,7 +189,6 @@ CREATE TABLE IF NOT EXISTS `APPM_APPLICATION_PROPERTY` ( -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `APPM_APPLICATION_RELEASE` ( `ID` INT NOT NULL AUTO_INCREMENT, - `VERSION_ID` INT NOT NULL, `VERSION_NAME` VARCHAR(100) NOT NULL, `RESOURCE` TEXT NULL, `RELEASE_CHANNEL` VARCHAR(50) NULL, @@ -197,7 +196,7 @@ CREATE TABLE IF NOT EXISTS `APPM_APPLICATION_RELEASE` ( `CREATED_AT` DATETIME NOT NULL, `APPM_APPLICATION_ID` INT NOT NULL, `IS_DEFAULT` TINYINT(1) NULL, - PRIMARY KEY (`ID`, `APPM_APPLICATION_ID`), + PRIMARY KEY (`APPM_APPLICATION_ID`, `VERSION_NAME`), INDEX `FK_APPLICATION_VERSION_APPLICATION` (`APPM_APPLICATION_ID` ASC), CONSTRAINT `FK_APPLICATION_VERSION_APPLICATION` FOREIGN KEY (`APPM_APPLICATION_ID`)