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 deleted file mode 100644 index 985c0b7bb89..00000000000 --- 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 +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016, 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.services.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.application.mgt.api.APIUtil; -import org.wso2.carbon.device.application.mgt.api.services.LifecycleManagementAPI; -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; - -/** - * Lifecycle Management related jax-rs APIs. - */ -@Path("/lifecycles") -public class LifecycleManagementAPIImpl implements LifecycleManagementAPI { - - private static Log log = LogFactory.getLog(LifecycleManagementAPIImpl.class); - - @GET - public Response getLifecycleStates() { - LifecycleStateManager lifecycleStateManager = APIUtil.getLifecycleStateManager(); - List lifecycleStates = new ArrayList<>(); - try { - lifecycleStates = lifecycleStateManager.getLifecycleStates(); - } catch (LifecycleManagementException e) { - String msg = "Error occurred while retrieving lifecycle states."; - log.error(msg, e); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - return Response.status(Response.Status.OK).entity(lifecycleStates).build(); - } - - @POST - public Response addLifecycleState(LifecycleState state) { - LifecycleStateManager lifecycleStateManager = APIUtil.getLifecycleStateManager(); - try { - lifecycleStateManager.addLifecycleState(state); - } catch (LifecycleManagementException e) { - String msg = "Error occurred while adding lifecycle state."; - log.error(msg, e); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - return Response.status(Response.Status.OK).entity("Lifecycle state added successfully.").build(); - } - - @DELETE - @Path("/{identifier}") - public Response deleteLifecycleState(@PathParam("identifier") String identifier) { - LifecycleStateManager lifecycleStateManager = APIUtil.getLifecycleStateManager(); - try { - lifecycleStateManager.deleteLifecycleState(identifier); - } catch (LifecycleManagementException e) { - String msg = "Error occurred while deleting lifecycle state."; - log.error(msg, e); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - return Response.status(Response.Status.OK).entity("Lifecycle state deleted successfully.").build(); - } -} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/pom.xml similarity index 100% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/pom.xml diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/APIUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/APIUtil.java new file mode 100644 index 00000000000..2ca87b04bf9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/APIUtil.java @@ -0,0 +1,189 @@ +/* + * 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.publisher.api; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.publisher.api.beans.ErrorResponse; +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.CategoryManager; +import org.wso2.carbon.device.application.mgt.common.services.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; + +import javax.ws.rs.core.Response; + + +/** + * Holds util methods required for Application-Mgt API component. + */ +public class APIUtil { + + private static Log log = LogFactory.getLog(APIUtil.class); + + private static ApplicationManager applicationManager; + private static LifecycleStateManager lifecycleStateManager; + private static ApplicationReleaseManager applicationReleaseManager; + private static ApplicationStorageManager applicationStorageManager; + private static SubscriptionManager subscriptionManager; + private static CategoryManager categoryManager; + + public static ApplicationManager getApplicationManager() { + if (applicationManager == null) { + synchronized (APIUtil.class) { + if (applicationManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + applicationManager = + (ApplicationManager) ctx.getOSGiService(ApplicationManager.class, null); + if (applicationManager == null) { + String msg = "Application Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + + return applicationManager; + } + + public static LifecycleStateManager getLifecycleStateManager() { + if (lifecycleStateManager == null) { + synchronized (APIUtil.class) { + if (lifecycleStateManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + lifecycleStateManager = + (LifecycleStateManager) ctx.getOSGiService(LifecycleStateManager.class, null); + if (lifecycleStateManager == null) { + String msg = "Lifecycle Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + 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; + } + + /** + * To get the Category Manager from the osgi context. + * + * @return CategoryManager instance in the current osgi context. + */ + public static CategoryManager getCategoryManager() { + if (categoryManager == null) { + synchronized (APIUtil.class) { + if (categoryManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + categoryManager = (CategoryManager) ctx.getOSGiService(CategoryManager.class, null); + if (categoryManager == null) { + String msg = "Category Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return categoryManager; + } + + public static Response getResponse(Exception ex, Response.Status status) { + return getResponse(ex.getMessage(), status); + } + + public static Response getResponse(String message, Response.Status status) { + ErrorResponse errorMessage = new ErrorResponse(); + errorMessage.setMessage(message); + if (status == null) { + status = Response.Status.INTERNAL_SERVER_ERROR; + } + errorMessage.setCode(status.getStatusCode()); + return Response.status(status).entity(errorMessage).build(); + } + + /** + * To get the Subscription Manager from the osgi context. + * @return SubscriptionManager instance in the current osgi context. + */ + public static SubscriptionManager getSubscriptionManager() { + if (subscriptionManager == null) { + synchronized (APIUtil.class) { + if (subscriptionManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + subscriptionManager = + (SubscriptionManager) ctx.getOSGiService(SubscriptionManager.class, null); + if (subscriptionManager == null) { + String msg = "Subscription Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + + return subscriptionManager; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/FileStreamingOutput.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/FileStreamingOutput.java new file mode 100644 index 00000000000..3c6fc98bda9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/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.publisher.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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/JSONMessageHandler.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/JSONMessageHandler.java new file mode 100644 index 00000000000..16137573e76 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/JSONMessageHandler.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016, 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.publisher.api; + + +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; +import javax.ws.rs.core.MediaType; +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 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) +public class JSONMessageHandler implements MessageBodyWriter, MessageBodyReader { + + private Gson gson; + private static final String UTF_8 = "UTF-8"; + + public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + private Gson getGson() { + if (gson == null) { + final GsonBuilder gsonBuilder = new GsonBuilder() + .setDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz") + .setExclusionStrategies(new AnnotationExclusionStrategy()); + gson = gsonBuilder.create(); + } + return gson; + } + + public Object readFrom(Class objectClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringStringMultivaluedMap, InputStream entityStream) + throws IOException, WebApplicationException { + try (InputStreamReader reader = new InputStreamReader(entityStream, UTF_8)) { + return getGson().fromJson(reader, type); + } + } + + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + public long getSize(Object o, Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + public void writeTo(Object object, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringObjectMultivaluedMap, OutputStream entityStream) + throws IOException, WebApplicationException { + try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8)) { + getGson().toJson(object, type, writer); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/MultipartCustomProvider.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/MultipartCustomProvider.java new file mode 100644 index 00000000000..cbe1ac3b8fe --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/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.publisher.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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/beans/ErrorListItem.java similarity index 96% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorListItem.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/beans/ErrorListItem.java index 3c049465926..5fb80516834 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/beans/ErrorListItem.java @@ -16,7 +16,7 @@ * under the License. * */ -package org.wso2.carbon.device.application.mgt.api.beans; +package org.wso2.carbon.device.application.mgt.publisher.api.beans; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/beans/ErrorResponse.java similarity index 97% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/beans/ErrorResponse.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/beans/ErrorResponse.java index 6c9321e3342..7727b7a6954 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/beans/ErrorResponse.java @@ -16,7 +16,7 @@ * under the License. * */ -package org.wso2.carbon.device.application.mgt.api.beans; +package org.wso2.carbon.device.application.mgt.publisher.api.beans; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationManagementAPI.java similarity index 99% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ApplicationManagementAPI.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationManagementAPI.java index 8c30ab484b8..64c833301c8 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationManagementAPI.java @@ -16,7 +16,7 @@ * under the License. * */ -package org.wso2.carbon.device.application.mgt.api.services; +package org.wso2.carbon.device.application.mgt.publisher.api.services; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -32,7 +32,7 @@ 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.publisher.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; @@ -118,7 +118,7 @@ import javax.ws.rs.core.Response; } ) -@Path("/applications") +@Path("/publisher/applications") @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) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationReleaseManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationReleaseManagementAPI.java new file mode 100644 index 00000000000..abacafaf9cb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationReleaseManagementAPI.java @@ -0,0 +1,436 @@ +/* + * 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.publisher.api.services; + +import io.swagger.annotations.*; +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.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.publisher.api.beans.ErrorResponse; + +import javax.validation.Valid; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +/** + * APIs to handle application management related tasks. + */ +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "Application Management Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ApplicationManagementService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt/v1.0/applications"), + }) + } + ), + tags = { + @Tag(name = "application_management, device_management", description = "Application Management related " + + "APIs") + } +) +@Scopes( + scopes = { + @Scope( + name = "Get Application Details", + description = "Get application details", + key = "perm:application:get", + permissions = {"/device-mgt/application/get"} + ), + @Scope( + name = "Create an Application", + description = "Create an application", + key = "perm:application:create", + permissions = {"/device-mgt/application/create"} + ), + @Scope( + name = "Update an Application", + description = "Update an application", + key = "perm:application:update", + permissions = {"/device-mgt/application/update"} + ), + @Scope( + name = "Create an Application", + description = "Create an application", + key = "perm:application-mgt:login", + permissions = {"/device-mgt/application-mgt/login"} + ), + @Scope( + name = "Delete an Application", + description = "Delete an application", + key = "perm:application:delete", + permissions = {"/device-mgt/application/delete"} + ), + @Scope( + name = "Create an application category", + description = "Create an application category", + key = "perm:application-category:create", + permissions = {"/device-mgt/application/category/create"} + ), + @Scope( + name = "Delete an Application category", + description = "Delete an application category", + key = "perm:application-category:delete", + permissions = {"/device-mgt/application/category/delete"} + ) + + + } +) +@Path("/publisher/release") +@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) +public interface ApplicationReleaseManagementAPI { + + String SCOPE = "scope"; + + @POST + @Path("/{appType}/{appId}") + @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( + @Multipart(value = "applicationRelease", type = "application/json") ApplicationRelease applicationRelease, + @ApiParam( + name = "binaryFile", + value = "Binary file of uploading application", + required = true) + @Multipart(value = "binaryFile") Attachment binaryFile, + @ApiParam( + name = "icon", + value = "Icon of the uploading application", + required = true) + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading application", + required = true) + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot", + value = "Screen Shots of the uploading application", + required = true) + @Multipart(value = "screenshot") List attachmentList, + @ApiParam( + name = "appType", + value = "Application Type", + required = true) + @PathParam("appType") String applicationType, + @ApiParam( + name = "appId", + value = "Application ID", + required = true) + @PathParam("appId") int applicationId); + + + @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); + + @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); + + @PUT + @Path("/release/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + @ApiOperation( + consumes = MediaType.MULTIPART_FORM_DATA, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update an application release", + notes = "This will update a new application release", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:update") + }) + } + ) + @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 updateApplicationRelease( + @ApiParam(name = "UUID", value = "Unique identifier of the Application", required = true) @PathParam("uuid") String applicationUUID, + @Multipart(value = "applicationRelease", required = false, type = "application/json") ApplicationRelease applicationRelease, + @Multipart(value = "binaryFile", required = false) 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 = "GET", + value = "Get an application release", + notes = "This will return the application release indicated by Application UUID and version", + 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); + + @DELETE + @Path("/release/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Delete the releases of a particular applicaion", + notes = "This will delete the releases or specific release of an application", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:delete") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the Application release."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting the release of a" + + "particular application.", + response = ErrorResponse.class) + }) + Response deleteApplicationRelease( + @ApiParam(name = "UUID", value = "Unique identifier of the Application", required = true) @PathParam("uuid") String applicationUUID, + @ApiParam(name = "version", value = "Version of the application") @QueryParam("version") String version); + + @GET + @Path("/image-artifacts/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Delete the releases of a particular applicaion", + notes = "This will delete 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 deleted the Application release."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting the release of a" + + "particular application.", + response = ErrorResponse.class) + }) + Response getApplicationImageArtifacts( + @ApiParam(name = "UUID", value = "Unique identifier of the Application", required = true) @PathParam("uuid") String applicationUUID, + @ApiParam(name = "name", value = "Name of the artifact to be retrieved", required = true) @QueryParam("name") String name, + @ApiParam(name = "count", value = "Count of the screen-shot artifact to be retrieved", required = false) @QueryParam("count") int count); + +} 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/LifecycleManagementAPI.java similarity index 97% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/LifecycleManagementAPI.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/LifecycleManagementAPI.java index 0386c12e253..a4ffd41010d 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/LifecycleManagementAPI.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.wso2.carbon.device.application.mgt.api.services; +package org.wso2.carbon.device.application.mgt.publisher.api.services; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -28,7 +28,7 @@ import io.swagger.annotations.SwaggerDefinition; import io.swagger.annotations.Tag; 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.publisher.api.beans.ErrorResponse; import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.LifecycleState; 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java similarity index 98% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ApplicationManagementAPIImpl.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java index 7ade8a70756..586e847ba04 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.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java @@ -16,15 +16,15 @@ * under the License. * */ -package org.wso2.carbon.device.application.mgt.api.services.impl; +package org.wso2.carbon.device.application.mgt.publisher.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.publisher.api.APIUtil; +import org.wso2.carbon.device.application.mgt.publisher.api.FileStreamingOutput; +import org.wso2.carbon.device.application.mgt.publisher.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; @@ -63,7 +63,7 @@ import javax.ws.rs.core.Response; * Implementation of Application Management related APIs. */ @Produces({"application/json"}) -@Path("/applications") +@Path("/publisher/applications") public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { private static final int DEFAULT_LIMIT = 20; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationReleaseManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationReleaseManagementAPIImpl.java new file mode 100644 index 00000000000..6375af8b8ce --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationReleaseManagementAPIImpl.java @@ -0,0 +1,408 @@ +/* + * 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.publisher.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.common.*; +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.exception.ResourceManagementException; +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.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.application.mgt.publisher.api.APIUtil; +import org.wso2.carbon.device.application.mgt.publisher.api.FileStreamingOutput; +import org.wso2.carbon.device.application.mgt.publisher.api.services.ApplicationManagementAPI; +import org.wso2.carbon.device.application.mgt.publisher.api.services.ApplicationReleaseManagementAPI; +import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; + +import javax.validation.Valid; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +/** + * Implementation of Application Management related APIs. + */ +@Produces({"application/json"}) +@Path("/publisher/release") +public class ApplicationReleaseManagementAPIImpl implements ApplicationReleaseManagementAPI { + + private static final int DEFAULT_LIMIT = 20; + private static Log log = LogFactory.getLog(ApplicationReleaseManagementAPIImpl.class); + + @Override + @POST + @Path("/{appType}/{appId}") + public Response createApplicationRelease( + @Multipart("applicationRelease") ApplicationRelease applicationRelease, + @Multipart("binaryFile") Attachment binaryFile, + @Multipart("icon") Attachment iconFile, + @Multipart("banner") Attachment bannerFile, + @Multipart("screenshot") List attachmentList, + @PathParam("appType") String applicationType, + @PathParam("appId") int applicationId) { + + ApplicationReleaseManager applicationReleaseManager = APIUtil.getApplicationReleaseManager(); + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + InputStream iconFileStream; + InputStream bannerFileStream; + List attachments = new ArrayList<>(); + + try { + + if (iconFile == null) { + throw new ApplicationManagementException( + "Icon file is not uploaded for the application release of " + applicationId); } + + if (bannerFile != null) { + throw new ApplicationManagementException( + "Banner file is not uploaded for the application release of " + applicationId); } + + if (attachmentList == null || attachmentList.isEmpty()) { + throw new ApplicationManagementException( + "Screenshots are not uploaded for the application release of " + applicationId); } + + if (binaryFile == null){ + throw new ApplicationManagementException( + "Binary file is not uploaded for the application release of " + applicationId); } + + + iconFileStream = iconFile.getDataHandler().getInputStream(); + bannerFileStream = bannerFile.getDataHandler().getInputStream(); + + for (Attachment screenshot : attachmentList) { + attachments.add(screenshot.getDataHandler().getInputStream()); + } + + applicationStorageManager.uploadReleaseArtifacts(applicationUUID, applicationRelease.getVersion(), + binaryFile.getDataHandler().getInputStream()); + + + + + applicationRelease.setUuid(UUID.randomUUID().toString()); + applicationRelease = applicationReleaseManager.createRelease(applicationUUID, applicationRelease); + + + return Response.status(Response.Status.CREATED).entity(applicationRelease).build(); + } catch (ApplicationManagementException e) { + log.error("Error while creating an application release for the application ID " + applicationId, + e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } catch (IOException e) { + String errorMessage = + "Error while uploading binary file and resources for the application release of the application ID " + + applicationId; + log.error(errorMessage, e); + return APIUtil.getResponse(new ApplicationManagementException(errorMessage, e), + Response.Status.INTERNAL_SERVER_ERROR); + } catch (ResourceManagementException e) { + log.error("Error occurred while uploading the releases artifacts of the application id " + + applicationId + " the release version is " + applicationRelease.getVersion(), e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + + @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.getVersion(), + 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); + } catch (ResourceManagementException e) { + log.error("Error occurred while uploading the releases artifacts of the application with the uuid " + + applicationUUID + " for the release " + applicationRelease.getVersion(), e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + + @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 (NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).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); + } catch (ResourceManagementException e) { + log.error("Error occurred while uploading the image artifacts of the application with the uuid " + + applicationUUID, e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + @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 (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); + } catch (ResourceManagementException e) { + log.error("Error occurred while uploading the image artifacts of the application with the uuid " + + applicationUUID, e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + + + + @Override + @PUT + @Path("/release/{uuid}") + public Response updateApplicationRelease(@PathParam("uuid") String applicationUUID, @Multipart + ("applicationRelease") ApplicationRelease applicationRelease, @Multipart("binaryFile") Attachment + binaryFile) { + ApplicationReleaseManager applicationReleaseManager = APIUtil.getApplicationReleaseManager(); + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + if (applicationRelease != null) { + applicationRelease = applicationReleaseManager.updateRelease(applicationUUID, applicationRelease); + } + if (binaryFile != null) { + String version = applicationRelease == null ? null : applicationRelease.getVersion(); + + if (version == null) { + return Response.status(Response.Status.BAD_REQUEST).entity("Version cannot be null. Version is a " + + "mandatory parameter to update the release artifacts").build(); + } + applicationStorageManager + .uploadReleaseArtifacts(applicationUUID, version, binaryFile.getDataHandler().getInputStream()); + } + return Response.status(Response.Status.OK).entity(applicationRelease).build(); + } catch (NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).build(); + } catch (ApplicationManagementException e) { + log.error("Error while updating the application release of the application with UUID " + applicationUUID); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } catch (IOException e) { + log.error("Error while updating the release artifacts of the application with UUID " + applicationUUID); + return APIUtil.getResponse(new ApplicationManagementException( + "Error while updating the release artifacts of the application with UUID " + + applicationUUID), Response.Status.INTERNAL_SERVER_ERROR); + } catch (ResourceManagementException e) { + log.error("Error occurred while updating the releases artifacts of the application with the uuid " + + applicationUUID + " for the release " + applicationRelease.getVersion(), e); + return APIUtil.getResponse(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 application 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 (NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).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); + } + } + + @Override + @DELETE + @Path("/release/{uuid}") + public Response deleteApplicationRelease(@PathParam("uuid") String applicationUUID, + @QueryParam("version") String version) { + ApplicationReleaseManager applicationReleaseManager = APIUtil.getApplicationReleaseManager(); + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + if (version != null && !version.isEmpty()) { + applicationStorageManager.deleteApplicationReleaseArtifacts(applicationUUID, version); + applicationReleaseManager.deleteApplicationRelease(applicationUUID, version); + return Response.status(Response.Status.OK) + .entity("Successfully deleted Application release with " + "version " + version + + " for the application with UUID " + applicationUUID).build(); + } else { + applicationStorageManager.deleteAllApplicationReleaseArtifacts(applicationUUID); + applicationReleaseManager.deleteApplicationReleases(applicationUUID); + return Response.status(Response.Status.OK) + .entity("Successfully deleted Application releases for the " + "application with UUID " + + applicationUUID).build(); + } + } catch (NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).build(); + } catch (ApplicationManagementException e) { + log.error("Error while deleting application release with the application UUID " + applicationUUID, e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } catch (ApplicationStorageManagementException e) { + log.error("Error occurred while deleting the releases artifacts of the application with the uuid " + + applicationUUID + " for the release " + version, e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + @Override + @GET + @Path("/image-artifacts/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + public Response getApplicationImageArtifacts(@PathParam("uuid") String applicationUUID, + @QueryParam("name") String name, @QueryParam("count") int count) { + if (name == null || name.isEmpty()) { + return Response.status(Response.Status.BAD_REQUEST).entity("Name should not be null. Name is mandatory to" + + " retrieve the particular image artifact of the release").build(); + } + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + ImageArtifact imageArtifact = applicationStorageManager.getImageArtifact(applicationUUID, name, count); + Response.ResponseBuilder response = Response.status(Response.Status.OK).entity(imageArtifact); + return response.build(); + } catch (ApplicationStorageManagementException e) { + log.error("Application Storage Management Exception while getting the image artifact " + name + " of " + + "the application with UUID " + applicationUUID, e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/LifecycleManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/LifecycleManagementAPIImpl.java new file mode 100644 index 00000000000..600c49210d2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/LifecycleManagementAPIImpl.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016, 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.publisher.api.services.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +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.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.application.mgt.publisher.api.APIUtil; +import org.wso2.carbon.device.application.mgt.publisher.api.services.LifecycleManagementAPI; +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.Arrays; +import java.util.List; +import javax.ws.rs.*; +import javax.ws.rs.core.Response; + +/** + * Lifecycle Management related jax-rs APIs. + */ +@Path("/lifecycles") +public class LifecycleManagementAPIImpl implements LifecycleManagementAPI { + + private static Log log = LogFactory.getLog(LifecycleManagementAPIImpl.class); + + @GET + public Response getLifecycleStates() { + LifecycleStateManager lifecycleStateManager = APIUtil.getLifecycleStateManager(); + List lifecycleStates = new ArrayList<>(); + try { + lifecycleStates = lifecycleStateManager.getLifecycleStates(); + } catch (LifecycleManagementException e) { + String msg = "Error occurred while retrieving lifecycle states."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + return Response.status(Response.Status.OK).entity(lifecycleStates).build(); + } + + @POST + public Response addLifecycleState(LifecycleState state) { + LifecycleStateManager lifecycleStateManager = APIUtil.getLifecycleStateManager(); + try { + lifecycleStateManager.addLifecycleState(state); + } catch (LifecycleManagementException e) { + String msg = "Error occurred while adding lifecycle state."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + return Response.status(Response.Status.OK).entity("Lifecycle state added successfully.").build(); + } + + @DELETE + @Path("/{identifier}") + public Response deleteLifecycleState(@PathParam("identifier") String identifier) { + LifecycleStateManager lifecycleStateManager = APIUtil.getLifecycleStateManager(); + try { + lifecycleStateManager.deleteLifecycleState(identifier); + } catch (LifecycleManagementException e) { + String msg = "Error occurred while deleting lifecycle state."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + return Response.status(Response.Status.OK).entity("Lifecycle state deleted successfully.").build(); + } + +// @PUT +// @Consumes("application/json") +// @Path("/{uuid}/lifecycle") +// public Response changeLifecycleState(@PathParam("uuid") String applicationUUID, @QueryParam("state") String state) { +// ApplicationManager applicationManager = APIUtil.getApplicationManager(); +// +// if (!Arrays.asList(Constants.LIFE_CYCLES).contains(state)) { +// log.warn("Provided lifecycle state " + state + " is not valid. Please select one from" +// + Arrays.toString(Constants.LIFE_CYCLES)); +// return Response.status(Response.Status.BAD_REQUEST) +// .entity("Provided lifecycle state " + state + " is not valid. Please select one from " +// + Arrays.toString(Constants.LIFE_CYCLES)).build(); +// } +// try { +// applicationManager.changeLifecycle(applicationUUID, state); +// return Response.status(Response.Status.OK) +// .entity("Successfully changed the lifecycle state of the application: " + applicationUUID).build(); +// } catch (org.wso2.carbon.device.application.mgt.core.exception.NotFoundException e) { +// return Response.status(Response.Status.NOT_FOUND).build(); +// } catch (ApplicationManagementException e) { +// String msg = "Error occurred while changing the lifecycle of application: " + applicationUUID; +// log.error(msg, e); +// return APIUtil.getResponse(e, Response.Status.BAD_REQUEST); +// } +// } +// +// @GET +// @Path("/{uuid}/lifecycle") +// @Override +// public Response getNextLifeCycleStates(@PathParam("uuid") String applicationUUID) { +// ApplicationManager applicationManager = APIUtil.getApplicationManager(); +// try { +// if (applicationManager.getApplication(applicationUUID) == null) { +// if (log.isDebugEnabled()) { +// log.debug("Application with the UUID '" + applicationUUID + "' is not found."); +// } +// return Response.status(Response.Status.NOT_FOUND).entity("Application with the UUID '" + +// applicationUUID + "' is not found.").build(); +// } +// +// if (log.isDebugEnabled()) { +// log.debug("Application with UUID '" + applicationUUID + "' is found. Request received for getting " +// + "next life-cycle states for the particular application."); +// } +// return Response.status(Response.Status.OK).entity(applicationManager.getLifeCycleStates(applicationUUID)) +// .build(); +// } catch (NotFoundException e) { +// return Response.status(Response.Status.NOT_FOUND).build(); +// } catch (ApplicationManagementException e) { +// log.error("Application Management Exception while trying to get next states for the applications with " +// + "the application ID", 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/webapp/META-INF/permissions.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/webapp/META-INF/permissions.xml similarity index 100% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/permissions.xml rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/webapp/META-INF/permissions.xml diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/webapp-classloading.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/webapp/META-INF/webapp-classloading.xml similarity index 100% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/webapp-classloading.xml rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/webapp/META-INF/webapp-classloading.xml 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.publisher.api/src/main/webapp/WEB-INF/cxf-servlet.xml similarity index 84% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 00d7489560d..8e0452c6b37 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.publisher.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -35,11 +35,11 @@ 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.publisher.api/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/web.xml rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/webapp/WEB-INF/web.xml diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/pom.xml new file mode 100644 index 00000000000..b72917d6741 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/pom.xml @@ -0,0 +1,229 @@ + + + + + + + application-mgt + org.wso2.carbon.devicemgt + 3.0.192-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.application.mgt.store.api + 3.0.192-SNAPSHOT + war + WSO2 Carbon - Application Management API + WSO2 Carbon - Application Management API + http://wso2.org + + + + + maven-war-plugin + + WEB-INF/lib/*cxf*.jar + api#application-mgt-store#v1.0 + + + + + + + + deploy + + compile + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + compile + + run + + + + + + + + + + + + + + + + + + client + + test + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + test + + java + + + + + + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + provided + + + org.apache.cxf + cxf-rt-frontend-jaxrs + provided + + + org.apache.cxf + cxf-rt-transports-http + provided + + + junit + junit + test + + + org.codehaus.jackson + jackson-jaxrs + + + org.codehaus.jackson + jackson-core-asl + + + javax.ws.rs + jsr311-api + provided + + + org.wso2.carbon + org.wso2.carbon.utils + provided + + + org.wso2.carbon + org.wso2.carbon.logging + provided + + + org.json.wso2 + json + + + commons-codec.wso2 + commons-codec + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.application.mgt.core + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.application.mgt.common + provided + + + io.swagger + swagger-annotations + + + io.swagger + swagger-core + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + org.slf4j + slf4j-api + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-core + + + + + io.swagger + swagger-jaxrs + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + org.slf4j + slf4j-api + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-core + + + + + javax.servlet + servlet-api + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + provided + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-annotations + + + org.hibernate + hibernate-validator + + + javax.ws.rs + javax.ws.rs-api + + + \ No newline at end of file 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.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/APIUtil.java similarity index 98% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/APIUtil.java index f129c0f2026..d4d919879c3 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.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/APIUtil.java @@ -16,12 +16,12 @@ * under the License. */ -package org.wso2.carbon.device.application.mgt.api; +package org.wso2.carbon.device.application.mgt.store.api; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.application.mgt.api.beans.ErrorResponse; +import org.wso2.carbon.device.application.mgt.publisher.api.beans.ErrorResponse; 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; 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.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/FileStreamingOutput.java similarity index 96% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/FileStreamingOutput.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/FileStreamingOutput.java index aad9a9a73ef..40ddf5b329f 100644 --- 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.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/FileStreamingOutput.java @@ -17,7 +17,7 @@ * */ -package org.wso2.carbon.device.application.mgt.api; +package org.wso2.carbon.device.application.mgt.store.api; import java.io.IOException; import java.io.InputStream; 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.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/JSONMessageHandler.java similarity index 98% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/JSONMessageHandler.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/JSONMessageHandler.java index d01bed5199f..d116bf6bffb 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.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/JSONMessageHandler.java @@ -16,7 +16,7 @@ * under the License. */ -package org.wso2.carbon.device.application.mgt.api; +package org.wso2.carbon.device.application.mgt.store.api; import com.google.gson.Gson; 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.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/MultipartCustomProvider.java similarity index 97% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/MultipartCustomProvider.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/MultipartCustomProvider.java index 84ed5e634ab..03771296b25 100644 --- 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.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/MultipartCustomProvider.java @@ -16,7 +16,7 @@ * */ -package org.wso2.carbon.device.application.mgt.api; +package org.wso2.carbon.device.application.mgt.store.api; import com.google.gson.Gson; import com.google.gson.GsonBuilder; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/beans/ErrorListItem.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/beans/ErrorListItem.java new file mode 100644 index 00000000000..5fb80516834 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/beans/ErrorListItem.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016, 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.publisher.api.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +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 { + + @NotNull + private String code = null; + @NotNull + private String message = null; + + @ApiModelProperty(required = true, value = "") + @JsonProperty("code") + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public ErrorListItem() { + } + + public ErrorListItem(String code, String msg) { + this.code = code; + this.message = msg; + } + + /** + * Description about individual errors occurred + */ + @ApiModelProperty(required = true, value = "Description about individual errors occurred") + @JsonProperty("message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("errorItem {\n"); + + sb.append(" code: ").append(code).append("\n"); + sb.append(" message: ").append(message).append("\n"); + sb.append("}\n"); + return sb.toString(); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/beans/ErrorResponse.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/beans/ErrorResponse.java new file mode 100644 index 00000000000..7727b7a6954 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/beans/ErrorResponse.java @@ -0,0 +1,98 @@ +/* + * 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.publisher.api.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +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 { + + private Integer code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List errorItems = new ArrayList<>(); + + @JsonProperty(value = "code") + @ApiModelProperty(required = true, value = "") + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @JsonProperty(value = "message") + @ApiModelProperty(required = true, value = "ErrorResponse message.") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @JsonProperty(value = "description") + @ApiModelProperty(value = "A detail description about the error message.") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @JsonProperty(value = "moreInfo") + @ApiModelProperty(value = "Preferably an url with more details about the error.") + public String getMoreInfo() { + return moreInfo; + } + + public void setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + } + + public void addErrorListItem(ErrorListItem item) { + this.errorItems.add(item); + } + + /** + * If there are more than one error list them out. \nFor example, list out validation errors by each field. + */ + @JsonProperty(value = "errorItems") + @ApiModelProperty(value = "If there are more than one error list them out. \n" + + "For example, list out validation errors by each field.") + public List getErrorItems() { + return errorItems; + } + + public void setErrorItems(List error) { + this.errorItems = error; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ApplicationManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ApplicationManagementAPI.java new file mode 100644 index 00000000000..7bead236b46 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ApplicationManagementAPI.java @@ -0,0 +1,345 @@ +/* + * 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.publisher.api.services; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Extension; +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.publisher.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; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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; + +/** + * APIs to handle application management related tasks. + */ +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "Application Management Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ApplicationManagementService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt/v1.0/applications"), + }) + } + ), + tags = { + @Tag(name = "application_management, device_management", description = "Application Management related " + + "APIs") + } +) +@Scopes( + scopes = { + @Scope( + name = "Get Application Details", + description = "Get application details", + key = "perm:application:get", + permissions = {"/device-mgt/application/get"} + ), + @Scope( + name = "Create an Application", + description = "Create an application", + key = "perm:application:create", + permissions = {"/device-mgt/application/create"} + ), + @Scope( + name = "Update an Application", + description = "Update an application", + key = "perm:application:update", + permissions = {"/device-mgt/application/update"} + ), + @Scope( + name = "Create an Application", + description = "Create an application", + key = "perm:application-mgt:login", + permissions = {"/device-mgt/application-mgt/login"} + ), + @Scope( + name = "Delete an Application", + description = "Delete an application", + key = "perm:application:delete", + permissions = {"/device-mgt/application/delete"} + ), + @Scope( + name = "Create an application category", + description = "Create an application category", + key = "perm:application-category:create", + permissions = {"/device-mgt/application/category/create"} + ), + @Scope( + name = "Delete an Application category", + description = "Delete an application category", + key = "perm:application-category:delete", + permissions = {"/device-mgt/application/category/delete"} + ) + + + } +) +@Path("/store/applications") +@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) +public interface ApplicationManagementAPI { + + String SCOPE = "scope"; + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get all applications", + notes = "This will get all applications", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:get") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully got application list.", + response = ApplicationList.class), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version " + + "of the requested resource."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the application list.", + response = ErrorResponse.class) + }) + Response getApplications( + @ApiParam( + name = "searchQuery", + value = "Relevant search query to search on", defaultValue = "*") + @QueryParam("query") String searchQuery, + @ApiParam( + name = "offset", + value = "Provide from which position apps should return", defaultValue = "20") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many apps it should return", defaultValue = "0") + @QueryParam("limit") int limit + + ); + + @GET + @Path("/{appType}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get the application of requesting application type", + notes = "This will get the application identified by the application type and name, if exists", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:application:get") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved relevant application.", + response = Application.class), + @ApiResponse( + code = 404, + message = "Application not found"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting relevant application.", + response = ErrorResponse.class) + }) + Response getApplication( + @ApiParam( + name = "appType", + value = "Type of the application", + required = true) + @PathParam("appType") String appType, + @ApiParam( + name = "appName", + value = "Application name", + required = true) + @QueryParam("appName") String appName + ); + + + @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 = "GET", + value = "Get an application release", + notes = "This will return the application release indicated by Application UUID and version", + 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 getPublishedRelease( + @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); + + @GET + @Path("/image-artifacts/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Delete the releases of a particular applicaion", + notes = "This will delete 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 deleted the Application release."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting the release of a" + + "particular application.", + response = ErrorResponse.class) + }) + Response getApplicationImageArtifacts( + @ApiParam( + name = "UUID", + value = "Unique identifier of the Application", + required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "name", + value = "Name of the artifact to be retrieved", + required = true) + @QueryParam("name") String name, + @ApiParam( + name = "count", + value = "Count of the screen-shot artifact to be retrieved", + required = false) + @QueryParam("count") int count); + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/SubscriptionManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java similarity index 98% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/SubscriptionManagementAPI.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java index de6304b89da..fb6d0e24465 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/SubscriptionManagementAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java @@ -15,11 +15,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.wso2.carbon.device.application.mgt.api.services; +package org.wso2.carbon.device.application.mgt.publisher.api.services; import io.swagger.annotations.*; 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.publisher.api.beans.ErrorResponse; import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.InstallationDetails; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ApplicationManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ApplicationManagementAPIImpl.java new file mode 100644 index 00000000000..4afcf61d14c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ApplicationManagementAPIImpl.java @@ -0,0 +1,224 @@ +/* + * 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.publisher.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.store.api.APIUtil; +import org.wso2.carbon.device.application.mgt.store.api.FileStreamingOutput; +import org.wso2.carbon.device.application.mgt.publisher.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.ImageArtifact; +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.exception.ResourceManagementException; +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.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; + +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; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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"}) +@Path("/store/applications") +public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { + + private static final int DEFAULT_LIMIT = 20; + private static Log log = LogFactory.getLog(ApplicationManagementAPIImpl.class); + + @GET + @Consumes("application/json") + @Override + public Response getApplications( + @QueryParam("query") String searchQuery, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + + try { + if (limit == 0) { + limit = DEFAULT_LIMIT; + } + Filter filter = new Filter(); + filter.setOffset(offset); + filter.setLimit(limit); + filter.setSearchQuery(searchQuery); + + ApplicationList applications = applicationManager.getApplications(filter); + + for (Application application : applications.getApplications()) { +// ToDo : use better approach to solve this + String uuId = applicationManager.getUuidOfLatestRelease(application.getId()); + if (uuId != null){ + application.setUuidOfLatestRelease(uuId); + ImageArtifact imageArtifact = applicationStorageManager.getImageArtifact(uuId, Constants.IMAGE_ARTIFACTS[0], 0); + application.setIconOfLatestRelease(imageArtifact); + }else{ +// ToDo set default icon + } + } + return Response.status(Response.Status.OK).entity(applications).build(); + } catch (NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting the application list"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).build(); + } catch (ApplicationStorageManagementException e) { + log.error("Error occurred while getting the image artifacts of the application", e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + + + @GET + @Consumes("application/json") + @Path("/{appType}") + public Response getApplication(@PathParam("appType") String appType, @QueryParam("appName") String appName) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + Application application = applicationManager.getApplication(appType, appName); + if (application == null) { + return Response.status(Response.Status.NOT_FOUND) + .entity("Application with UUID " + appType + " not found").build(); + } + + // ToDo : use better approach to solve this + String uuId = applicationManager.getUuidOfLatestRelease(application.getId()); + if (uuId != null){ + application.setUuidOfLatestRelease(uuId); + ImageArtifact imageArtifact = applicationStorageManager.getImageArtifact(uuId, Constants.IMAGE_ARTIFACTS[0], 0); + application.setIconOfLatestRelease(imageArtifact); + }else{ + // ToDo set default icon + } + + return Response.status(Response.Status.OK).entity(application).build(); + } catch (NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).build(); + } catch (ApplicationManagementException e) { + log.error("Error occurred while getting application with the uuid " + appType, e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } catch (ApplicationStorageManagementException e) { + log.error("Error occurred while getting the image artifacts of the application with the uuid " + appType, e); + return APIUtil.getResponse(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 application 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 getPublishedRelease(@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 (NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND).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); + } + } + + @Override + @GET + @Path("/image-artifacts/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + public Response getApplicationImageArtifacts(@PathParam("uuid") String applicationUUID, + @QueryParam("name") String name, @QueryParam("count") int count) { + if (name == null || name.isEmpty()) { + return Response.status(Response.Status.BAD_REQUEST).entity("Name should not be null. Name is mandatory to" + + " retrieve the particular image artifact of the release").build(); + } + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + try { + ImageArtifact imageArtifact = applicationStorageManager.getImageArtifact(applicationUUID, name, count); + Response.ResponseBuilder response = Response.status(Response.Status.OK).entity(imageArtifact); + return response.build(); + } catch (ApplicationStorageManagementException e) { + log.error("Application Storage Management Exception while getting the image artifact " + name + " of " + + "the application with 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/SubscriptionManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java similarity index 94% rename from components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/SubscriptionManagementAPIImpl.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java index 9960725684c..6f2d77fc46e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/SubscriptionManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java @@ -15,13 +15,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.wso2.carbon.device.application.mgt.api.services.impl; +package org.wso2.carbon.device.application.mgt.publisher.api.services.impl; import io.swagger.annotations.ApiParam; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.application.mgt.api.APIUtil; -import org.wso2.carbon.device.application.mgt.api.services.SubscriptionManagementAPI; +import org.wso2.carbon.device.application.mgt.store.api.APIUtil; +import org.wso2.carbon.device.application.mgt.publisher.api.services.SubscriptionManagementAPI; import org.wso2.carbon.device.application.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.application.mgt.common.InstallationDetails; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/META-INF/permissions.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/META-INF/permissions.xml new file mode 100644 index 00000000000..df2d1cf5b58 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,110 @@ + + + + + + + + + + Get Application + /device-mgt/application/get + /application-mgt/applications + GET + + + Create Application + /device-mgt/application/create + /application-mgt/applications + POST + + + Edit Application + /device-mgt/application/update + /application-mgt/applications + PUT + + + Login to Application Management + /device-mgt/application-mgt/login + /application-mgt/applications + PUT + + + Login to Application Management + device-mgt/application/delete + /application-mgt/applications/* + DELETE + + + + + Get Platform + /device-mgt/platform/get + /application-mgt/platforms/* + GET + + + Add Platform + /device-mgt/platform/add + /application-mgt/platforms + POST + + + Update Platform + /device-mgt/platform/update + /application-mgt/platforms/* + PUT + + + Remove Platform + /device-mgt/platform/remove + /application-mgt/platforms/* + DELETE + + + + + Install Application + /device-mgt/subscription/install + /application-mgt/subscription + POST + + + Uninstall Application + /device-mgt/subscription/uninstall + /application-mgt/subscription + POST + + + Get Application + /device-mgt/subscription/getApplication + /application-mgt/subscription + GET + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/META-INF/webapp-classloading.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 00000000000..ed2ed216247 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 00000000000..8e0452c6b37 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/WEB-INF/web.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..7574e19e4c0 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,115 @@ + + + + Application Management Webapp + + JAX-WS/JAX-RS Application Management Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + + + CXFServlet + /* + + + 60 + + + doAuthentication + true + + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + isSharedWithAllTenants + true + + + + CorsFilter + org.apache.catalina.filters.CorsFilter + + cors.allowed.origins + * + + + cors.allowed.methods + GET,POST,DELETE,PUT + + + cors.allowed.headers + Content-Type + + + + + HttpHeaderSecurityFilter + org.apache.catalina.filters.HttpHeaderSecurityFilter + + hstsEnabled + false + + + + + ContentTypeBasedCachePreventionFilter + org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter + + patterns + text/html" ,application/json" ,text/plain + + + filterAction + enforce + + + httpHeaders + Cache-Control: no-store, no-cache, must-revalidate, private + + + + + HttpHeaderSecurityFilter + /* + + + + ContentTypeBasedCachePreventionFilter + /* + + + + CorsFilter + /* + + + \ No newline at end of file diff --git a/components/application-mgt/pom.xml b/components/application-mgt/pom.xml index fdc9f2d6b35..bcdb836e995 100644 --- a/components/application-mgt/pom.xml +++ b/components/application-mgt/pom.xml @@ -36,7 +36,8 @@ org.wso2.carbon.device.application.mgt.core org.wso2.carbon.device.application.mgt.common - org.wso2.carbon.device.application.mgt.api + org.wso2.carbon.device.application.mgt.publisher.api + org.wso2.carbon.device.application.mgt.store.api org.wso2.carbon.device.application.mgt.publisher.ui org.wso2.carbon.device.application.mgt.store.ui org.wso2.carbon.device.application.mgt.authhandler