Merge pull request #903 from Megala21/appm_new

Adding Application Release Management related changes.
feature/appm-store/pbac
Megala Uthayakumar 7 years ago committed by GitHub
commit 98ff1179da

@ -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);
}

@ -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();
}
}
}
}

@ -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)

@ -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<Object> {
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<Object> objectClass, Type type, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> 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);
}
}

@ -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 {

@ -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 {

@ -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<Attachment> 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<Attachment> 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);
}

@ -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.",

@ -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<Attachment> attachmentList) {
ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager();
try {
InputStream iconFileStream;
InputStream bannerFileStream;
List<InputStream> 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<Attachment> attachmentList) {
ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager();
try {
InputStream iconFileStream = null;
InputStream bannerFileStream = null;
List<InputStream> 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<ApplicationRelease> 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);
}
}
}

@ -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 {

@ -31,6 +31,7 @@ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jsonProvider"/>
<ref bean="multipartProvider"/>
</jaxrs:providers>
</jaxrs:server>
@ -38,6 +39,7 @@ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<bean id="platformMgtServiceBean" class="org.wso2.carbon.device.application.mgt.api.services.impl.PlatformManagementAPIImpl" />
<bean id="lifecycleMgtServiceBean" class="org.wso2.carbon.device.application.mgt.api.services.impl.LifecycleManagementAPIImpl" />
<bean id="jsonProvider" class="org.wso2.carbon.device.application.mgt.api.JSONMessageHandler"/>
<bean id="multipartProvider" class="org.wso2.carbon.device.application.mgt.api.MultipartCustomProvider"/>
</beans>

@ -27,7 +27,7 @@
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
</servlet>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>

@ -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();
}
}

@ -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<String, String> 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<String, String> getProperties() {
return properties;
}

@ -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);

@ -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);
}
}

@ -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;
}

@ -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<ApplicationRelease> 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;
}

@ -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<InputStream> 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;
}

@ -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;
}
}

@ -33,6 +33,8 @@ public class Configuration {
private List<Extension> 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<Extension> extensions) {
this.extensions = extensions;
}
@XmlElement(name = "Artifacts")
public Artifacts getArtifacts() {
return artifacts;
}
public void setArtifacts(Artifacts artifacts) {
this.artifacts = artifacts;
}
}

@ -87,7 +87,8 @@ public class Extension {
PlatformManager,
VisibilityTypeManager,
SubscriptionManager,
VisibilityManager
VisibilityManager,
ApplicationStorageManager
}
}

@ -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<ApplicationRelease> getApplicationReleases(String applicationUUID) throws ApplicationManagementDAOException;
}

@ -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;

@ -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.
*

@ -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 {

@ -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<String, String> 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<String, String> 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<ApplicationRelease> 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<ApplicationRelease> 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<String, String> 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);
}
}
}

@ -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"));

@ -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) {

@ -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) {

@ -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) {

@ -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) {

@ -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<LifecycleStateTransition> nextLifeCycles = getLifeCycleStates(applicationUUID);
List<LifecycleStateTransition> 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<InputStream> 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)

@ -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<ApplicationRelease> 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;
}
}

@ -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<InputStream> 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<String> 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");
}
}
}
}

@ -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){
}
}

@ -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);

@ -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);

@ -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;
}
}

@ -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);

@ -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> T getInstance(Extension extension, Class<T> cls) throws InvalidConfigurationException {

@ -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 = "";
}

@ -55,6 +55,13 @@
<Extension name="VisibilityTypeManager">
<ClassName>org.wso2.carbon.device.application.mgt.core.impl.VisibilityTypeManagerImpl</ClassName>
</Extension>
<Extension name="ApplicationStorageManager">
<ClassName>org.wso2.carbon.device.application.mgt.core.impl.ApplicationStorageManagerImpl</ClassName>
</Extension>
</Extensions>
<Artifacts>
<ImageLocation>${carbon.home}/repository/resources/mobileapps/images/</ImageLocation>
<BinaryLocation>${carbon.home}/repository/resources/mobileapps/binary/</BinaryLocation>
</Artifacts>
</ApplicationManagementConfiguration>

@ -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)

@ -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`)

Loading…
Cancel
Save