diff --git a/.gitignore b/.gitignore index fe21460b43..e00a660c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,17 @@ target # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/node_modules/ +components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package-lock.json +components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/npm-debug.log +components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/dist/ +components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/tmp/ +components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/node_modules/ +components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/dist/ +components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package-lock.json +components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/tmp/ +components/device-mgt/io.entgra.device.mgt.ui/react-app/node_modules/ +components/device-mgt/io.entgra.device.mgt.ui/react-app/dist/ +components/device-mgt/io.entgra.device.mgt.ui/react-app/package-lock.json +components/device-mgt/io.entgra.device.mgt.ui/react-app/tmp/ + diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8c19854ef2..f22bfc39ca 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,4 +24,4 @@ deploy: script: - mvn $MAVEN_CLI_OPTS deploy -Dmaven.test.skip=true only: - - master@entgra/carbon-device-mgt \ No newline at end of file + - master@entgra/carbon-device-mgt diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java index 2beaff52ab..aec0df4a16 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java @@ -21,7 +21,6 @@ package org.wso2.carbon.apimgt.application.extension.api; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.json.simple.JSONObject; import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; import org.wso2.carbon.apimgt.application.extension.api.util.APIUtil; import org.wso2.carbon.apimgt.application.extension.api.util.RegistrationProfile; @@ -32,10 +31,9 @@ import org.wso2.carbon.apimgt.integration.client.OAuthRequestInterceptor; import org.wso2.carbon.apimgt.integration.client.store.StoreClient; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.user.api.UserStoreException; -import javax.ws.rs.DELETE; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java index cb7183266e..fdd2e5bb2d 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java @@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.registry.api.Resource; import org.wso2.carbon.registry.core.Registry; @@ -31,7 +31,6 @@ import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; -import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; @@ -44,9 +43,11 @@ public class APIUtil { private static final String DEFAULT_CDMF_API_TAG = "device_management"; private static final String DEFAULT_AGENT_API_TAG = "device_agent"; private static final String DEFAULT_CERT_API_TAG = "scep_management"; + private static final String DEFAULT_APP_MGT_TAG = "application_management"; + private static final String DEFAULT_APP_MGT_REVIEW_MGT_TAG = "review_management"; + private static final String DEFAULT_APP_MGT_SUB_MGT_TAG = "subscription_management"; private static final String DEFAULT_ANALYTICS_ARTIFACT_TAG = "analytics_artifacts_management"; - public static final String PERMISSION_PROPERTY_NAME = "name"; public static String getAuthenticatedUser() { @@ -111,6 +112,9 @@ public class APIUtil { allowedApisTags.add(DEFAULT_CDMF_API_TAG); allowedApisTags.add(DEFAULT_CERT_API_TAG); allowedApisTags.add(DEFAULT_AGENT_API_TAG); + allowedApisTags.add(DEFAULT_APP_MGT_TAG); + allowedApisTags.add(DEFAULT_APP_MGT_REVIEW_MGT_TAG); + allowedApisTags.add(DEFAULT_APP_MGT_SUB_MGT_TAG); allowedApisTags.add(DEFAULT_ANALYTICS_ARTIFACT_TAG); return allowedApisTags; } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/publisher-api.yaml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/publisher-api.yaml index e23d7d28a0..b2068857a7 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/publisher-api.yaml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/publisher-api.yaml @@ -2741,7 +2741,7 @@ parameters: name: limit in: query description: | - Maximum size of resource array to return. + Maximum length of resource array to return. default: 25 type: integer diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/store-api.yaml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/store-api.yaml index 8f85e25759..a57b96d4ab 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/store-api.yaml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/store-api.yaml @@ -1823,7 +1823,7 @@ parameters: name: limit in: query description: | - Maximum size of resource array to return. + Maximum length of resource array to return. default: 25 type: integer diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/pom.xml new file mode 100644 index 0000000000..c7ff5220b7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/pom.xml @@ -0,0 +1,112 @@ + + + + application-mgt + org.wso2.carbon.devicemgt + 4.0.0-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.application.mgt.addons + 4.0.0-SNAPSHOT + WSO2 Carbon - Application Management Add-Ons + WSO2 Carbon - Application Management Add-Ons + https://entgra.io + + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + 1.4.0 + true + + + ${project.artifactId} + ${project.artifactId} + ${carbon.device.mgt.version} + Application Management Add-Ons Bundle + + com.google.gson, + io.swagger.annotations.*;resolution:=optional + + + org.wso2.carbon.device.application.mgt.addons.* + + + + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + provided + + + org.apache.cxf + cxf-rt-frontend-jaxrs + provided + + + org.apache.cxf + cxf-rt-transports-http + provided + + + org.eclipse.osgi + org.eclipse.osgi + + + org.eclipse.equinox + org.eclipse.equinox.common + + + org.wso2.carbon + org.wso2.carbon.logging + + + commons-codec.wso2 + commons-codec + + + commons-io.wso2 + commons-io + + + io.swagger + swagger-annotations + provided + + + org.json.wso2 + json + + + com.google.code.gson + gson + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.application.mgt.common + + + javax.servlet + javax.servlet-api + provided + + + org.hibernate + hibernate-validator + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/ApiOriginFilter.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/ApiOriginFilter.java new file mode 100644 index 0000000000..25446e9513 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/ApiOriginFilter.java @@ -0,0 +1,46 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.addons; + + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ApiOriginFilter implements Filter { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletResponse res = (HttpServletResponse) response; + res.addHeader("Access-Control-Allow-Origin", "*"); + res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); + res.addHeader("Access-Control-Allow-Headers", "Content-Type"); + chain.doFilter(request, response); + } + + public void destroy() { + //do nothing + } + + public void init(FilterConfig filterConfig) throws ServletException { + //do nothing + } +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/FileStreamingOutput.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/FileStreamingOutput.java new file mode 100644 index 0000000000..a1ad912d19 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/FileStreamingOutput.java @@ -0,0 +1,53 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.addons; + + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.StreamingOutput; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * org.wso2.carbon.device.application.mgt.addons.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/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/GsonMessageBodyHandler.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/JSONMessageHandler.java similarity index 67% rename from components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/GsonMessageBodyHandler.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/JSONMessageHandler.java index ff866606ad..6951e02b2e 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/GsonMessageBodyHandler.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/JSONMessageHandler.java @@ -1,12 +1,11 @@ -/* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. * - * WSO2 Inc. licenses this file to you under the Apache License, + * Entgra (Pvt) Ltd. 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 + * 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 @@ -15,12 +14,11 @@ * specific language governing permissions and limitations * under the License. */ - -package org.wso2.carbon.certificate.mgt.jaxrs.api.common; - +package org.wso2.carbon.device.application.mgt.addons; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import org.wso2.carbon.device.application.mgt.addons.jaxrs.AnnotationExclusionStrategy; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; @@ -30,16 +28,23 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import java.io.*; +import java.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 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 GsonMessageBodyHandler implements MessageBodyWriter, MessageBodyReader { +public class JSONMessageHandler implements MessageBodyWriter, MessageBodyReader { private Gson gson; private static final String UTF_8 = "UTF-8"; @@ -50,7 +55,9 @@ public class GsonMessageBodyHandler implements MessageBodyWriter, Messag private Gson getGson() { if (gson == null) { - final GsonBuilder gsonBuilder = new GsonBuilder(); + final GsonBuilder gsonBuilder = new GsonBuilder() + .setDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz") + .setExclusionStrategies(new AnnotationExclusionStrategy()); gson = gsonBuilder.create(); } return gson; @@ -59,13 +66,8 @@ public class GsonMessageBodyHandler implements MessageBodyWriter, Messag public Object readFrom(Class objectClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap stringStringMultivaluedMap, InputStream entityStream) throws IOException, WebApplicationException { - - InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8"); - - try { + try (InputStreamReader reader = new InputStreamReader(entityStream, UTF_8)) { return getGson().fromJson(reader, type); - } finally { - reader.close(); } } @@ -80,12 +82,8 @@ public class GsonMessageBodyHandler implements MessageBodyWriter, Messag public void writeTo(Object object, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap stringObjectMultivaluedMap, OutputStream entityStream) throws IOException, WebApplicationException { - - OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8); - try { + try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8)) { getGson().toJson(object, type, writer); - } finally { - writer.close(); } } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/MultipartCustomProvider.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/MultipartCustomProvider.java new file mode 100644 index 0000000000..647cbcc27d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/MultipartCustomProvider.java @@ -0,0 +1,71 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.addons; + +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.addons.jaxrs.AnnotationExclusionStrategy; + +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; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +/** + * 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/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ValidationInterceptor.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/ValidationInterceptor.java similarity index 93% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ValidationInterceptor.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/ValidationInterceptor.java index 8094aa853e..d36e9986b1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ValidationInterceptor.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/ValidationInterceptor.java @@ -1,12 +1,11 @@ -/* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. * - * WSO2 Inc. licenses this file to you under the Apache License, + * Entgra (Pvt) Ltd. 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 + * 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 @@ -15,8 +14,7 @@ * specific language governing permissions and limitations * under the License. */ - -package org.wso2.carbon.device.mgt.jaxrs.exception; +package org.wso2.carbon.device.application.mgt.addons; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -30,6 +28,7 @@ import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/jaxrs/AnnotationExclusionStrategy.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/jaxrs/AnnotationExclusionStrategy.java new file mode 100644 index 0000000000..d2a92c4c27 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/jaxrs/AnnotationExclusionStrategy.java @@ -0,0 +1,36 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.addons.jaxrs; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; + +/** + * This class is used to exclude certain fields when serializing and de-serializing based on the annotation. + */ +public class AnnotationExclusionStrategy implements ExclusionStrategy { + + @Override + public boolean shouldSkipField(FieldAttributes f) { + return f.getAnnotation(Exclude.class) != null; + } + + @Override + public boolean shouldSkipClass(Class clazz) { + return false; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/jaxrs/Exclude.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/jaxrs/Exclude.java new file mode 100644 index 0000000000..e185ececcb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.addons/src/main/java/org/wso2/carbon/device/application/mgt/addons/jaxrs/Exclude.java @@ -0,0 +1,30 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.addons.jaxrs; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This class is the representation of custom developed Exclude annotation. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Exclude { +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml similarity index 62% rename from components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml rename to components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml index 9f2e5a3169..6c1d182b85 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml @@ -1,82 +1,48 @@ + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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. + --> - certificate-mgt + application-mgt org.wso2.carbon.devicemgt 4.0.0-SNAPSHOT ../pom.xml 4.0.0 - org.wso2.carbon.certificate.mgt.cert.admin.v09.api + org.wso2.carbon.device.application.mgt.api + 4.0.0-SNAPSHOT war - WSO2 Carbon - Admin Certificate Management v09 API - WSO2 Carbon - Admin Certificate Management v09 API - http://wso2.org + WSO2 Carbon - Application Management API + WSO2 Carbon - Application Management API + https://entgra.io - - maven-compiler-plugin - - 1.8 - 1.8 - - maven-war-plugin WEB-INF/lib/*cxf*.jar - api#certificate-mgt#v0.9 + api#application-mgt#v1.0 - - org.jacoco - jacoco-maven-plugin - - ${basedir}/target/coverage-reports/jacoco-unit.exec - - - - jacoco-initialize - - prepare-agent - - - - jacoco-site - test - - report - - - ${basedir}/target/coverage-reports/jacoco-unit.exec - ${basedir}/target/coverage-reports/site - - - - @@ -89,7 +55,7 @@ org.apache.maven.plugins maven-antrun-plugin - 1.7 + 1.8 compile @@ -100,7 +66,7 @@ - + @@ -119,7 +85,7 @@ org.codehaus.mojo exec-maven-plugin - 1.2.1 + 1.5.0 test @@ -138,48 +104,63 @@ org.apache.cxf cxf-rt-frontend-jaxws - - - commons-codec.wso2 - commons-codec - - - commons-codec - commons-codec - - + 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.wso2.carbon.devicemgt - org.wso2.carbon.certificate.mgt.core + org.json.wso2 + json + + + commons-codec.wso2 + commons-codec provided org.wso2.carbon.devicemgt - org.wso2.carbon.identity.jwt.client.extension + org.wso2.carbon.device.application.mgt.core + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.application.mgt.common provided @@ -190,25 +171,41 @@ 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 + javax.servlet-api provided @@ -216,6 +213,13 @@ org.wso2.carbon.apimgt.annotations provided + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-annotations + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.application.mgt.addons + - - + \ 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/services/ArtifactDownloadAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ArtifactDownloadAPI.java new file mode 100644 index 0000000000..f6f149ea62 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ArtifactDownloadAPI.java @@ -0,0 +1,134 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; + +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 org.wso2.carbon.device.application.mgt.common.ApplicationList; +import org.wso2.carbon.device.application.mgt.common.ErrorResponse; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +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 Artifact Download Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ApplicationManagementArtifactDownloadService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt/v1.0/artifact"), + }) + } + ) +) +@Path("/artifact") +@Api(value = "ApplicationDTO Management Artifact Downloading Service") +@Produces(MediaType.APPLICATION_JSON) +public interface ArtifactDownloadAPI { + + @GET + @Path("/{tenantId}/{uuid}/{folderName}/{fileName}") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation( + produces = MediaType.APPLICATION_OCTET_STREAM, + httpMethod = "GET", + value = "get application management UI configuration", + notes = "This will get all UI configuration of application management" + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully got UI config.", + response = ApplicationList.class), + @ApiResponse( + code = 404, + message = "Not Found. There doesn't have an defined UI config." + + "query."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the UI config.", + response = ErrorResponse.class) + }) + Response getArtifact( + @ApiParam( + name = "tenantId", + value = "Tenant Id of the application artifact belongs.", + required = true) + @PathParam("tenantId") int tenantId, + @ApiParam( + name = "uuid", + value = "UUID of the application release.", + required = true) + @PathParam("uuid") String uuid, + @ApiParam( + name = "folderName", + value = "Name of the folder where the artifact store.", + required = true) + @PathParam("folderName") String folderName, + @ApiParam( + name = "fileName", + value = "Name of the artifact", + required = true) + @PathParam("fileName") String fileName); + + @GET + @Path("/plist/{uuid}") + @Produces(MediaType.TEXT_XML) + @ApiOperation( + produces = MediaType.TEXT_XML, + httpMethod = "GET", + value = "Get plist artifact content of an application", + notes = "Get plist artifact content of an application" + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved plist artifact content.", + response = ApplicationList.class), + @ApiResponse( + code = 404, + message = "Not Found. Plist artifact content not found for the application."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while retrieving plist artifact content.", + response = ErrorResponse.class) + }) + Response getPlistArtifact( + @ApiParam( + name = "uuid", + value = "UUID of the application release.", + required = true) + @PathParam("uuid") String uuid); +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ConfigRetrieveAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ConfigRetrieveAPI.java new file mode 100644 index 0000000000..51ea56ef63 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/ConfigRetrieveAPI.java @@ -0,0 +1,83 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +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 org.wso2.carbon.device.application.mgt.common.*; +import org.wso2.carbon.device.application.mgt.common.ErrorResponse; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +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 Config Retrieve Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ApplicationManagementConfigRetrieveService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt/v1.0/config"), + }) + } + ) +) +@Path("/config") +@Api(value = "ApplicationDTO Management Common Service") +@Produces(MediaType.APPLICATION_JSON) +public interface ConfigRetrieveAPI { + + @GET + @Path("/ui-config") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get application management UI configuration", + notes = "This will get all UI configuration of application management" + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully got UI config.", + response = ApplicationList.class), + @ApiResponse( + code = 404, + message = "Not Found. There doesn't have an defined UI config." + + "query."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the UI config.", + response = ErrorResponse.class) + }) + Response getUiConfig(); +} 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/ArtifactDownloadAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ArtifactDownloadAPIImpl.java new file mode 100644 index 0000000000..d442de1b96 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ArtifactDownloadAPIImpl.java @@ -0,0 +1,99 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.services.ArtifactDownloadAPI; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.InputStream; + +/** + * Implementation of ApplicationDTO Management related APIs. + */ +@Produces({"application/json"}) +@Path("/artifact") +public class ArtifactDownloadAPIImpl implements ArtifactDownloadAPI { + + private static Log log = LogFactory.getLog(ArtifactDownloadAPIImpl.class); + + @GET + @Override + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Path("/{tenantId}/{uuid}/{folderName}/{fileName}") + public Response getArtifact( + @PathParam("tenantId") int tenantId, + @PathParam("uuid") String uuid, + @PathParam("folderName") String folderName, + @PathParam("fileName") String fileName) { + AppmDataHandler dataHandler = APIUtil.getDataHandler(); + try { + InputStream fileInputStream = dataHandler.getArtifactStream(tenantId, uuid, folderName, fileName); + Response.ResponseBuilder response = Response + .ok(fileInputStream, MediaType.APPLICATION_OCTET_STREAM); + response.status(Response.Status.OK); + response.header("Content-Disposition", "attachment; filename=\"" + fileName + "\""); + return response.build(); + } catch (NotFoundException e) { + String msg = "Couldn't find an application release for UUID: " + uuid + " and file name: " + fileName; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (BadRequestException e) { + String msg = "Invalid data is used with the request to get input stream of the application release. UUID: " + + uuid + " and file name: " + fileName; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting the application release artifact file. "; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Override + @Produces(MediaType.TEXT_XML) + @Path("/plist/{uuid}") + public Response getPlistArtifact(@PathParam("uuid") String uuid) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + String plistContent = applicationManager.getPlistArtifact(uuid); + return Response.status(Response.Status.OK).entity(plistContent).build(); + } catch (NotFoundException e) { + String msg = "Couldn't find an application release for UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting the application plist artifact file."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } +} 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/ConfigRetrieveAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ConfigRetrieveAPIImpl.java new file mode 100644 index 0000000000..a01dba4e7c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/ConfigRetrieveAPIImpl.java @@ -0,0 +1,57 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.services.ConfigRetrieveAPI; +import org.wso2.carbon.device.application.mgt.common.config.UIConfiguration; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + +/** + * Implementation of ApplicationDTO Management related APIs. + */ +@Produces({"application/json"}) +@Path("/config") +public class ConfigRetrieveAPIImpl implements ConfigRetrieveAPI { + + private static Log log = LogFactory.getLog(ConfigRetrieveAPIImpl.class); + + @GET + @Override + @Consumes("application/json") + @Path("/ui-config") + public Response getUiConfig() { + AppmDataHandler dataHandler = APIUtil.getDataHandler(); + UIConfiguration uiConfiguration = dataHandler.getUIConfiguration(); + if (uiConfiguration == null){ + String msg = "UI configuration is not initiated."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(uiConfiguration).build(); + } +} 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.api/src/main/webapp/META-INF/permissions.xml new file mode 100644 index 0000000000..c15153a078 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/webapp-classloading.xml similarity index 52% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml rename to components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/webapp-classloading.xml index 8ec4d9fa45..e195e08097 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/webapp-classloading.xml @@ -1,21 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/web.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..15677f5277 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,129 @@ + + + + Application Management Webapp + + JAX-WS/JAX-RS Application Management Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + + + swagger.security.filter + ApiAuthorizationFilterImpl + + 1 + + + CXFServlet + /* + + + 60 + + + doAuthentication + true + + + + + + + + + + + + + + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + isSharedWithAllTenants + true + + + + ApiOriginFilter + org.wso2.carbon.device.application.mgt.addons.ApiOriginFilter + + + + 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 + /* + + + + ApiOriginFilter + /* + + + + nonSecuredEndPoints + + /api/application-mgt/v1.0/artifact/.*, + /api/application-mgt/v1.0/config/.* + + + + \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/pom.xml new file mode 100644 index 0000000000..328efa66f8 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/pom.xml @@ -0,0 +1,127 @@ + + + + + + org.wso2.carbon.devicemgt + application-mgt + 4.0.0-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.application.mgt.common + 4.0.0-SNAPSHOT + bundle + WSO2 Carbon - Application Management Common + WSO2 Carbon - Application Management Common + https://entgra.io + + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + ${carbon.device.mgt.version} + Application Management Common Bundle + + org.wso2.carbon.device.mgt.common.*;version="${carbon.device.mgt.version}", + org.wso2.carbon.device.mgt.core.dto;version="${carbon.device.mgt.version}", + com.google.gson, + io.swagger.annotations.*;resolution:=optional, + com.fasterxml.jackson.annotation, + javax.validation.constraints, + javax.xml.bind.annotation.*, + + + org.wso2.carbon.device.application.mgt.common.* + + + + + + + + + + org.eclipse.osgi + org.eclipse.osgi + + + org.eclipse.equinox + org.eclipse.equinox.common + + + org.wso2.carbon + org.wso2.carbon.logging + + + commons-codec.wso2 + commons-codec + + + commons-io.wso2 + commons-io + + + io.swagger + swagger-annotations + provided + + + org.json.wso2 + json + + + com.google.code.gson + gson + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.hibernate + hibernate-validator + + + org.apache.cxf + cxf-rt-frontend-jaxrs + provided + + + org.codehaus.jackson + jackson-core-asl + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/AppLifecycleState.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/AppLifecycleState.java new file mode 100644 index 0000000000..d41de093e2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/AppLifecycleState.java @@ -0,0 +1,26 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + + +/** + * States of the Application. + */ +public enum AppLifecycleState { + CREATED, IN_REVIEW, PUBLISHED, APPROVED, BLOCKED, REJECTED, DEPRECATED, RETIRED +} + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/AppOperation.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/AppOperation.java new file mode 100644 index 0000000000..a7fe3c9ced --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/AppOperation.java @@ -0,0 +1,106 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; + +public class AppOperation { + + private static final long serialVersionUID = 7603215716452548282L; + + private ApplicationDTO application; + private int tenantId; + private String activityId; + private String scheduledDateTime; + private OperationType type; + private String subscribedBy; + private int appReleaseId; + private InstallState installState; + + public InstallState getInstallState() { + return installState; + } + + public void setInstallState(InstallState installState) { + this.installState = installState; + } + + public enum InstallState { + PENDING, INPROGRESS, INSTALLED, UNINSTALLED, ERROR + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public String getSubscribedBy() { + return subscribedBy; + } + + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } + + public enum OperationType { + INSTALL, UNINSTALL, UPDATE + } + + public OperationType getType() { + return type; + } + + public void setType(OperationType type) { + this.type = type; + } + + public ApplicationDTO getApplication() { + return application; + } + + public void setApplication(ApplicationDTO application) { + this.application = application; + } + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getActivityId() { + return activityId; + } + + public void setActivityId(String activityId) { + this.activityId = activityId; + } + + public String getScheduledDateTime() { + return scheduledDateTime; + } + + public void setScheduledDateTime(String scheduledDateTime) { + this.scheduledDateTime = scheduledDateTime; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationArtifact.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationArtifact.java new file mode 100644 index 0000000000..c71a468957 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationArtifact.java @@ -0,0 +1,93 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import java.io.InputStream; +import java.util.Map; + +public class ApplicationArtifact { + + private String installerName; + + private InputStream installerStream; + + private String bannerName; + + private InputStream bannerStream; + + private String iconName; + + private InputStream iconStream; + + private Map screenshots; + + public String getInstallerName() { + return installerName; + } + + public void setInstallerName(String installerName) { + this.installerName = installerName; + } + + public InputStream getInstallerStream() { + return installerStream; + } + + public void setInstallerStream(InputStream installerStream) { + this.installerStream = installerStream; + } + + public String getBannerName() { + return bannerName; + } + + public void setBannerName(String bannerName) { + this.bannerName = bannerName; + } + + public InputStream getBannerStream() { + return bannerStream; + } + + public void setBannerStream(InputStream bannerStream) { + this.bannerStream = bannerStream; + } + + public String getIconName() { + return iconName; + } + + public void setIconName(String iconName) { + this.iconName = iconName; + } + + public InputStream getIconStream() { + return iconStream; + } + + public void setIconStream(InputStream iconStream) { + this.iconStream = iconStream; + } + + public Map getScreenshots() { + return screenshots; + } + + public void setScreenshots(Map screenshots) { + this.screenshots = screenshots; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponse.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponse.java new file mode 100644 index 0000000000..06b0817ac1 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponse.java @@ -0,0 +1,67 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; + +import java.util.List; + +public class ApplicationInstallResponse { + @ApiModelProperty( + name = "ignoredDeviceIdentifiers", + value = "List of devices that application release is already installed.", + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" + ) + private List ignoredDeviceIdentifiers; + + @ApiModelProperty( + name = "errorDevices", + value = "List of devices that either device identity is not exist or device type doesn't compatible with the supported device type of the .", + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" + ) + private List errorDeviceIdentifiers; + + + @ApiModelProperty( + name = "activity", + value = "Activity corresponding to the operation" + ) + private List activities; + + public List getActivities() { + return activities; + } + + public void setActivities(List activity) { + this.activities = activity; + } + + public List getIgnoredDeviceIdentifiers() { + return ignoredDeviceIdentifiers; + } + + public void setIgnoredDeviceIdentifiers(List ignoredDeviceIdentifiers) { + this.ignoredDeviceIdentifiers = ignoredDeviceIdentifiers; + } + + public List getErrorDeviceIdentifiers() { return errorDeviceIdentifiers; } + + public void setErrorDeviceIdentifiers(List errorDeviceIdentifiers) { this.errorDeviceIdentifiers = errorDeviceIdentifiers; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponseTmp.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponseTmp.java new file mode 100644 index 0000000000..1e95b7e0ee --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstallResponseTmp.java @@ -0,0 +1,70 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; + +import java.util.List; + +public class ApplicationInstallResponseTmp { + @ApiModelProperty( + name = "successfulDevices", + value = "List of successful devices", + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" + ) + private List successfulDevices; + + @ApiModelProperty( + name = "failedDevices", + value = "List of failed devices", + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" + ) + private List failedDevices; + + @ApiModelProperty( + name = "activity", + value = "Activity corresponding to the operation" + ) + private Activity activity; + + public List getSuccessfulDevices() { + return successfulDevices; + } + + public void setSuccessfulDevices(List successfulDevices) { + this.successfulDevices = successfulDevices; + } + + public List getFailedDevices() { + return failedDevices; + } + + public void setFailedDevices(List failedDevices) { + this.failedDevices = failedDevices; + } + + public Activity getActivity() { + return activity; + } + + public void setActivity(Activity activity) { + this.activity = activity; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstaller.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstaller.java new file mode 100644 index 0000000000..dde6722d85 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstaller.java @@ -0,0 +1,46 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +public class ApplicationInstaller { + + /*** + * Package name of the Installer + */ + private String packageName; + + /*** + * Version of the Installer. + */ + private String version; + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationList.java new file mode 100644 index 0000000000..e34c55c464 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationList.java @@ -0,0 +1,48 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.response.Application; + +import java.util.List; + +/** + * Represents a list of {@link ApplicationDTO}. + */ +public class ApplicationList { + + private List applications; + + private Pagination pagination; + + public List getApplications() { + return applications; + } + + public void setApplications(List applications) { + this.applications = applications; + } + + public Pagination getPagination() { + return pagination; + } + + public void setPagination(Pagination pagination) { + this.pagination = pagination; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationSubscriptionType.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationSubscriptionType.java new file mode 100644 index 0000000000..5628c9d96d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationSubscriptionType.java @@ -0,0 +1,25 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +/** + * Possible Subscription Type of the application. + */ +public enum ApplicationSubscriptionType { + FREE, PAID +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationType.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationType.java new file mode 100644 index 0000000000..8964ec60e7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationType.java @@ -0,0 +1,26 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + + +/** + * Application Types. + */ +public enum ApplicationType { + ENTERPRISE, PUBLIC, WEB_APP, WEB_CLIP, CUSTOM +} + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasePaginatedResult.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasePaginatedResult.java new file mode 100644 index 0000000000..b2445fcf7f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasePaginatedResult.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +public class BasePaginatedResult { + + @ApiModelProperty( + value = "Number of total resources.", + example = "1") + @JsonProperty("count") + private long count; + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfo.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfo.java similarity index 52% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfo.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfo.java index c0e256144b..26e73d2dc1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfo.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfo.java @@ -1,23 +1,21 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) 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 + * Entgra (pvt) Ltd. 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. + * 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.mgt.jaxrs.beans; +package org.wso2.carbon.device.application.mgt.common; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -33,6 +31,10 @@ public class BasicUserInfo { private String lastname; @ApiModelProperty(name = "emailAddress", value = "The email address of the user.", required = true ) private String emailAddress; + @ApiModelProperty(name = "createdDate", value = "User creation date." ) + private String createdDate; + @ApiModelProperty(name = "modifiedDate", value = "User modifiedDate date." ) + private String modifiedDate; public String getUsername() { return username; @@ -66,4 +68,20 @@ public class BasicUserInfo { this.emailAddress = emailAddress; } + public String getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(String createdDate) { + this.createdDate = createdDate; + } + + public String getModifiedDate() { + return modifiedDate; + } + + public void setModifiedDate(String modifiedDate) { + this.modifiedDate = modifiedDate; + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfoList.java similarity index 55% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoList.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfoList.java index 8cecc1c355..3f4762e3cb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoList.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/BasicUserInfoList.java @@ -1,23 +1,21 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) 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 + * Entgra (pvt) Ltd. 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. + * 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.mgt.jaxrs.beans; +package org.wso2.carbon.device.application.mgt.common; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; @@ -27,7 +25,7 @@ import java.util.ArrayList; import java.util.List; @ApiModel(value = "BasicUserInfoList", description = "This contains basic details of a set of users that matches " + - "a given criteria as a collection") + "a given criteria as a collection") public class BasicUserInfoList extends BasePaginatedResult { private List users = new ArrayList<>(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceGroupList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceGroupList.java similarity index 54% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceGroupList.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceGroupList.java index 201d578afb..698d29ee44 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceGroupList.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceGroupList.java @@ -1,23 +1,21 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) 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 + * Entgra (pvt) Ltd. 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. + * 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.mgt.jaxrs.beans; +package org.wso2.carbon.device.application.mgt.common; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModelProperty; @@ -50,4 +48,3 @@ public class DeviceGroupList extends BasePaginatedResult { } } - diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceList.java similarity index 54% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceList.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceList.java index a25670a2bd..94f81e153c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceList.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceList.java @@ -1,23 +1,21 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) 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 + * Entgra (pvt) Ltd. 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. + * 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.mgt.jaxrs.beans; +package org.wso2.carbon.device.application.mgt.common; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModelProperty; @@ -44,7 +42,6 @@ public class DeviceList extends BasePaginatedResult { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{\n"); - sb.append(" count: ").append(getCount()).append(",\n"); sb.append(" devices: [").append(devices).append("\n"); sb.append("]}\n"); @@ -52,4 +49,3 @@ public class DeviceList extends BasePaginatedResult { } } - diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceSubscriptionData.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceSubscriptionData.java new file mode 100644 index 0000000000..3afac36acd --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceSubscriptionData.java @@ -0,0 +1,80 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +import org.wso2.carbon.device.mgt.common.Device; + +import java.sql.Timestamp; + +public class DeviceSubscriptionData { + + private String action; + private Timestamp actionTriggeredTimestamp; + private String actionTriggeredBy; + private String actionType; + private String status; + private Device device; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public Timestamp getActionTriggeredTimestamp() { + return actionTriggeredTimestamp; + } + + public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { + this.actionTriggeredTimestamp = actionTriggeredTimestamp; + } + + public String getActionTriggeredBy() { + return actionTriggeredBy; + } + + public void setActionTriggeredBy(String actionTriggeredBy) { + this.actionTriggeredBy = actionTriggeredBy; + } + + public String getActionType() { + return actionType; + } + + public void setActionType(String actionType) { + this.actionType = actionType; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceTypes.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceTypes.java new file mode 100644 index 0000000000..465b67cafd --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceTypes.java @@ -0,0 +1,21 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +public enum DeviceTypes { + ANDROID, IOS +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/EnterpriseInstallationDetails.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/EnterpriseInstallationDetails.java new file mode 100644 index 0000000000..e045fecd78 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/EnterpriseInstallationDetails.java @@ -0,0 +1,84 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +public class EnterpriseInstallationDetails { + + /** + * This enum represents the type of entities which an application can be installed on. + * + * e.g: An application can be installed on all the devices belong to a user or a specific device group. + */ + @ApiModel + public enum EnterpriseEntity { + USER, ROLE, DEVICE_GROUP + } + + @ApiModelProperty( + name = "applicationUUID", + value = "ApplicationDTO ID", + required = true, + example = "4354c752-109f-11e8-b642-0ed5f89f718b" + ) + private String applicationUUID; + + @ApiModelProperty( + name = "entityType", + value = "Enterprise entity type", + required = true, + example = "USER" + ) + private EnterpriseEntity entityType; + + @ApiModelProperty( + name = "entityValueList", + value = "List of users/roles or device groups.", + required = true, + example = "user1,user2, user3" + ) + private List entityValueList; + + public String getApplicationUUID() { + return applicationUUID; + } + + public void setApplicationUUID(String applicationUUID) { + this.applicationUUID = applicationUUID; + } + + public EnterpriseEntity getEntityType() { + return entityType; + } + + public void setEntityType(EnterpriseEntity entityType) { + this.entityType = entityType; + } + + public List getEntityValueList() { + return entityValueList; + } + + public void setEntityValueList(List entityValueList) { + this.entityValueList = entityValueList; + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorListItem.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ErrorListItem.java similarity index 63% rename from components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorListItem.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ErrorListItem.java index 4b713af92b..8a5e2e2f60 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorListItem.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ErrorListItem.java @@ -1,23 +1,21 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) 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 + * Entgra (pvt) Ltd. 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. + * 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.certificate.mgt.jaxrs.beans; +package org.wso2.carbon.device.application.mgt.common; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; @@ -25,6 +23,9 @@ import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +/** + * Represents a single error item in the error response. + */ @ApiModel(description = "Error List Item") public class ErrorListItem { @@ -51,7 +52,6 @@ public class ErrorListItem { this.message = msg; } - /** * Description about individual errors occurred */ @@ -70,9 +70,11 @@ public class ErrorListItem { 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.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ErrorResponse.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ErrorResponse.java new file mode 100644 index 0000000000..58c67bfc3a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ErrorResponse.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +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<>(); + + public ErrorResponse() { + + } + + public ErrorResponse(String message) { + this.message = message; + } + + @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.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ExecutionStatus.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ExecutionStatus.java new file mode 100644 index 0000000000..c24a65593f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ExecutionStatus.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +public enum ExecutionStatus { + PENDING, EXECUTED, FAILED +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Filter.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Filter.java new file mode 100644 index 0000000000..942f2cf309 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Filter.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import java.util.List; + +/** + * Filter represents a criteria that can be used for searching applications. + */ +public class Filter { + + /*** + * Supported device type for the application. + * e.g :- Android, iOS, Windows + */ + private String deviceType; + + /*** + * Name of the application. + */ + private String appName; + + /*** + * Type of the application. + * e.g :- ENTERPRISE, PUBLIC + */ + private String appType; + + /*** + * Subscription type of the application. + * e.g :- FREE, PAID etc + */ + private String subscriptionType; + + /*** + * Minimum rating of the application. + * e.g :- 4,5 + */ + private int minimumRating; + + /*** + * Application release version. + */ + private String version; + + /*** + * Release type of the application release. + * e.g :- Alpha, Beta + */ + private String appReleaseType; + + /** + * Category list of the application + */ + private List categories; + + /** + * Tag list of the application + */ + private List tags; + + /*** + * Unrestricted role list. Visibility of the application can restricted through user roles and users can view the + * application who has at least one role in unrestricted role list + */ + private List unrestrictedRoles; + + /** + * Checking the application name matches fully with given name + */ + private boolean isFullMatch; + + /** + * Limit of the applications + */ + private int limit; + + /** + * Started from + */ + private int offset; + + /** + * Ascending or descending order + */ + private String sortBy; + + /** + * Current application release state. + * e.g :- CREATED. IN_REVIEW, PUBLISHED etc + */ + private String appReleaseState; + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getSortBy() { + return sortBy; + } + + public void setSortBy(String sortBy) { + this.sortBy = sortBy; + } + + public boolean isFullMatch() { + return isFullMatch; + } + + public void setFullMatch(boolean fullMatch) { + isFullMatch = fullMatch; + } + + public String getAppType() { + return appType; + } + + public void setAppType(String appType) { + this.appType = appType; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public List getTags() { return tags; } + + public void setTags(List tags) { this.tags = tags; } + + public List getUnrestrictedRoles() { return unrestrictedRoles; } + + public void setUnrestrictedRoles(List unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; } + + public String getAppReleaseState() { return appReleaseState; } + + public void setAppReleaseState(String appReleaseState) { this.appReleaseState = appReleaseState; } + + public String getDeviceType() { return deviceType; } + + public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public String getSubscriptionType() { return subscriptionType; } + + public void setSubscriptionType(String subscriptionType) { this.subscriptionType = subscriptionType; } + + public int getMinimumRating() { return minimumRating; } + + public void setMinimumRating(int minimumRating) { this.minimumRating = minimumRating; } + + public String getVersion() { return version; } + + public void setVersion(String version) { this.version = version; } + + public String getAppReleaseType() { return appReleaseType; } + + public void setAppReleaseType(String appReleaseType) { this.appReleaseType = appReleaseType; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ImageArtifact.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ImageArtifact.java new file mode 100644 index 0000000000..30eed0d513 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ImageArtifact.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +/** + * This represents a image artifact of a application. Icon, Screen-shot or Banner. + * It consists of a name, type and base64 encoded string format of the image. + */ +public class ImageArtifact { + private String name; + private String type; + private String encodedImage; + + public String getType() { + return type; + } + + public String getEncodedImage() { + return encodedImage; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setType(String type) { + this.type = type; + } + + public void setEncodedImage(String encodedImage) { + this.encodedImage = encodedImage; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/InstallationDetails.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/InstallationDetails.java new file mode 100644 index 0000000000..d15dd4a7c5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/InstallationDetails.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.List; + +public class InstallationDetails { + @ApiModelProperty( + name = "applicationUUID", + value = "Application ID", + required = true + ) + private String applicationUUID; + + @ApiModelProperty( + name = "deviceIdentifiers", + value = "List of device identifiers.", + required = true, + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]" + ) + private List deviceIdentifiers; + + public String getApplicationUUID() { + return applicationUUID; + } + + public void setApplicationUUID(String applicationUUID) { + this.applicationUUID = applicationUUID; + } + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/LifecycleChanger.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/LifecycleChanger.java new file mode 100644 index 0000000000..abb39642f9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/LifecycleChanger.java @@ -0,0 +1,32 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +public class LifecycleChanger { + + private String action; + private String reason; + + public String getAction() { return action; } + + public void setAction(String action) { this.action = action; } + + public String getReason() { return reason; } + + public void setReason(String reason) { this.reason = reason; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/LifecycleState.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/LifecycleState.java new file mode 100644 index 0000000000..3021b6fd9b --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/LifecycleState.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import java.sql.Timestamp; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "LifecycleState", description = "LifecycleState represents the Lifecycle state for an application release") +public class LifecycleState { + + @ApiModelProperty(name = "currentState", + value = "Current state of the application release", + required = true) + private String currentState; + + @ApiModelProperty(name = "previousState", + value = "Previous state of the application release", + required = true) + private String previousState; + + @ApiModelProperty(name = "nextStates", + value = "Next possible transferring states from the current state") + private List nextStates; + + @ApiModelProperty(name = "updatedBy", + value = "Username who is update the application release state") + private String updatedBy; + + @ApiModelProperty(name = "updatedAt", + value = "Timestamp of the lifecycle has been updated") + private Timestamp updatedAt; + + @ApiModelProperty(name = "reasonForChange", + value = "Reason for the application release lifecycle change from previous state to current state.") + private String reasonForChange; + + public String getCurrentState() { + return currentState; + } + + public void setCurrentState(String currentState) { + this.currentState = currentState; + } + + public String getPreviousState() { + return previousState; + } + + public void setPreviousState(String previousState) { + this.previousState = previousState; + } + + public String getUpdatedBy() { + return updatedBy; + } + + public void setUpdatedBy(String updatedBy) { + this.updatedBy = updatedBy; + } + + public Timestamp getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Timestamp updatedAt) { + this.updatedAt = updatedAt; + } + + public List getNextStates() { + return nextStates; + } + + public void setNextStates(List nextStates) { + this.nextStates = nextStates; + } + + public String getReasonForChange() { return reasonForChange; } + + public void setReasonForChange(String reasonForChange) { this.reasonForChange = reasonForChange; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Pagination.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Pagination.java new file mode 100644 index 0000000000..01a2205bf7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Pagination.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +/** + * This class represents the pagination details that will be used when fetching application details from database. + */ +public class Pagination { + + private int offset; + + private int limit; + + private int size; + + private int count; + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/PaginationRequest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/PaginationRequest.java new file mode 100644 index 0000000000..80e0f1c603 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/PaginationRequest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +/** + * This class holds required parameters for a querying a paginated device response. + */ +public class PaginationRequest { + + private int offSet; + private int limit; + + public PaginationRequest(int start, int limit) { + this.offSet = start; + this.limit = limit; + } + + public int getOffSet() { + return offSet; + } + + public void setOffSet(int offSet) { + this.offSet = offSet; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public boolean validatePaginationRequest(int offSet, int limit) { + if (offSet < 0) { + throw new IllegalArgumentException("off set value can't be negative"); + } else if (limit < 0) { + throw new IllegalArgumentException("limit value can't be negative"); + } else { + return true; + } + } + + @Override public String toString() { + return "Off Set'" + this.offSet + "' row count '" + this.limit; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/PaginationResult.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/PaginationResult.java new file mode 100644 index 0000000000..3f90066264 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/PaginationResult.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.List; + +/** + * This class holds necessary data to represent a paginated result. + */ +@ApiModel(value = "PaginationResult", description = "This class carries all information related Pagination Result") +public class PaginationResult implements Serializable { + + private static final long serialVersionUID = 1998101711L; + + @ApiModelProperty(name = "recordsTotal", value = "The total number of records that are given before filtering", required = true) + private int recordsTotal; + + @ApiModelProperty(name = "recordsFiltered", value = "The total number of records that are given after filtering", required = true) + private int recordsFiltered; + + @ApiModelProperty(name = "draw", value = "The draw counter that this object is a response to, from the draw parameter sent as part of the data request", required = true) + private int draw; + + @ApiModelProperty(name = "data", value = "This holds the database records that matches given criteria", required = true) + private List data; + + public int getRecordsTotal() { + return recordsTotal; + } + + public int getRecordsFiltered() { + return recordsFiltered; + } + + public void setRecordsFiltered(int recordsFiltered) { + this.recordsFiltered = recordsFiltered; + } + + public void setRecordsTotal(int recordsTotal) { + this.recordsTotal = recordsTotal; + + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public int getDraw() { + return draw; + } + + public void setDraw(int draw) { + this.draw = draw; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ProxyResponse.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ProxyResponse.java new file mode 100644 index 0000000000..dec74d0f63 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ProxyResponse.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +public class ProxyResponse { + + private int code; + private String url; + private String data; + private String executorResponse; + + public int getCode() { return code; } + + public void setCode(int code) { this.code = code; } + + public String getUrl() { return url; } + + public void setUrl(String url) { this.url = url; } + + public String getData() { return data; } + + public void setData(String data) { this.data = data; } + + public String getExecutorResponse() { return executorResponse; } + + public void setExecutorResponse(String executorResponse) { this.executorResponse = executorResponse; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Rating.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Rating.java new file mode 100644 index 0000000000..8ac2414668 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Rating.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import java.util.TreeMap; + +/** + * Rating represents the an overall rating value and number of users who has rated for an application release. + */ +public class Rating { + + /** + * Rating value of the application release. + */ + private double ratingValue; + + /** + * Number of users who has rated for the application release. + */ + private int noOfUsers; + + /** + * Represent the rating variety for the application release + */ + private TreeMap ratingVariety; + + public double getRatingValue() { + return ratingValue; + } + + public void setRatingValue(double ratingValue) { + this.ratingValue = ratingValue; + } + + public int getNoOfUsers() { + return noOfUsers; + } + + public void setNoOfUsers(int noOfUsers) { + this.noOfUsers = noOfUsers; + } + + public TreeMap getRatingVariety() { + return ratingVariety; + } + + public void setRatingVariety(TreeMap ratingVariety) { + this.ratingVariety = ratingVariety; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewNode.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewNode.java new file mode 100644 index 0000000000..c3c5c75026 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewNode.java @@ -0,0 +1,66 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +import java.util.ArrayList; +import java.util.List; + +public class ReviewNode { + + private T data = null; + + private List> children = new ArrayList<>(); + + private ReviewNode parent = null; + + public ReviewNode(T data) { + this.data = data; + } + + public ReviewNode addChild(ReviewNode child) { + child.setParent(this); + this.children.add(child); + return child; + } + + public void addChildren(List> children) { + children.forEach(each -> each.setParent(this)); + this.children.addAll(children); + } + + public List> getChildren() { + return children; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + private void setParent(ReviewNode parent) { + this.parent = parent; + } + + public ReviewNode getParent() { + return parent; + } + +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/RoleList.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/RoleList.java new file mode 100644 index 0000000000..183f196c8c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/RoleList.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "Role List") +public class RoleList extends BasePaginatedResult { + + private List roles; + + @ApiModelProperty(value = "Returns the list of roles that match the offset and limit parameter values " + + "that were specified.") + @JsonProperty("roles") + + public List getList() { + return roles; + } + + public void setList(List roles) { + this.roles = roles; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" roles: [").append(roles).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SortingOrder.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SortingOrder.java new file mode 100644 index 0000000000..f0c19bdffc --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SortingOrder.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common; + + +/** + * Order which the search results should be shown. Ascending or Descending. + */ +public enum SortingOrder { + ASC, DESC +} + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubAction.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubAction.java new file mode 100644 index 0000000000..fde06081ef --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubAction.java @@ -0,0 +1,22 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +public enum SubAction { + INSTALL, UNINSTALL +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscribingDeviceIdHolder.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscribingDeviceIdHolder.java new file mode 100644 index 0000000000..0dd283b3fe --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscribingDeviceIdHolder.java @@ -0,0 +1,69 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.HashMap; +import java.util.Map; + +public class SubscribingDeviceIdHolder { + private Map appInstalledDevices = new HashMap<>(); + private Map appInstallableDevices = new HashMap<>(); + private Map appReInstallableDevices = new HashMap<>(); + private Map appReUnInstallableDevices = new HashMap<>(); + private Map skippedDevices = new HashMap<>(); + + public Map getAppInstalledDevices() { + return appInstalledDevices; + } + + public void setAppInstalledDevices(Map appInstalledDevices) { + this.appInstalledDevices = appInstalledDevices; + } + + public Map getAppInstallableDevices() { + return appInstallableDevices; + } + + public void setAppInstallableDevices(Map appInstallableDevices) { + this.appInstallableDevices = appInstallableDevices; + } + + public Map getAppReInstallableDevices() { + return appReInstallableDevices; + } + + public void setAppReInstallableDevices(Map appReInstallableDevices) { + this.appReInstallableDevices = appReInstallableDevices; + } + + public Map getSkippedDevices() { return skippedDevices; } + + public void setSkippedDevices(Map skippedDevices) { + this.skippedDevices = skippedDevices; + } + + public Map getAppReUnInstallableDevices() { + return appReUnInstallableDevices; + } + + public void setAppReUnInstallableDevices(Map appReUnInstallableDevices) { + this.appReUnInstallableDevices = appReUnInstallableDevices; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscriptionType.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscriptionType.java new file mode 100644 index 0000000000..08af098d8f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/SubscriptionType.java @@ -0,0 +1,22 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common; + +public enum SubscriptionType { + USER, ROLE, GROUP, DEVICE +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/EnrollmentCertificate.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/User.java similarity index 50% rename from components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/EnrollmentCertificate.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/User.java index cb624f0445..780a066b17 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/EnrollmentCertificate.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/User.java @@ -1,7 +1,7 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. * - * WSO2 Inc. licenses this file to you under the Apache License, + * Entgra (pvt) Ltd. 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 @@ -15,13 +15,29 @@ * specific language governing permissions and limitations * under the License. */ +package org.wso2.carbon.device.application.mgt.common; -package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans; +/** + * Represents an user. + */ +public class User { -public class EnrollmentCertificate { - String serial; - String pem; - int tenantId; + private String userName; + + private int tenantId; + + public User(String userName, int tenantId) { + this.userName = userName; + this.tenantId = tenantId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } public int getTenantId() { return tenantId; @@ -31,19 +47,8 @@ public class EnrollmentCertificate { this.tenantId = tenantId; } - public String getSerial() { - return serial; - } - - public void setSerial(String serial) { - this.serial = serial; - } - - public String getPem() { - return pem; - } - - public void setPem(String pem) { - this.pem = pem; + @Override + public String toString() { + return "User-name : " + userName + "\t Tenant-ID : " + tenantId; } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/AppRegistration.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/AppRegistration.java new file mode 100644 index 0000000000..4d764745c1 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/AppRegistration.java @@ -0,0 +1,47 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import java.util.List; + +public class AppRegistration { + + private List tags; + private boolean isAllowToAllDomains; + + @XmlElementWrapper(name = "Tags") + @XmlElement(name = "Tag") + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + @XmlElement(name = "AllowToAllDomains") + public boolean isAllowToAllDomains() { + return isAllowToAllDomains; + } + + public void setAllowToAllDomains(boolean allowToAllDomains) { + isAllowToAllDomains = allowToAllDomains; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/ErrorCallback.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/ErrorCallback.java new file mode 100644 index 0000000000..660c6c4b09 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/ErrorCallback.java @@ -0,0 +1,112 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.config; + +import javax.xml.bind.annotation.XmlElement; + +public class ErrorCallback { + + private String badRequest; + private String unauthorized; + private String forbidden; + private String notFound; + private String methodNotAllowed; + private String notAcceptable; + private String unsupportedMediaType; + private String internalServerError; + private String defaultPage; + + @XmlElement(name = "BadRequest", required=true) + public String getBadRequest() { + return badRequest; + } + + public void setBadRequest(String badRequest) { + this.badRequest = badRequest; + } + + @XmlElement(name = "Unauthorized", required=true) + public String getUnauthorized() { + return unauthorized; + } + + public void setUnauthorized(String unauthorized) { + this.unauthorized = unauthorized; + } + + @XmlElement(name = "Forbidden", required=true) + public String getForbidden() { + return forbidden; + } + + public void setForbidden(String forbidden) { + this.forbidden = forbidden; + } + @XmlElement(name = "NotFound", required=true) + public String getNotFound() { + return notFound; + } + + public void setNotFound(String notFound) { + this.notFound = notFound; + } + + @XmlElement(name = "MethodNotAllowed", required=true) + public String getMethodNotAllowed() { + return methodNotAllowed; + } + + public void setMethodNotAllowed(String methodNotAllowed) { + this.methodNotAllowed = methodNotAllowed; + } + + @XmlElement(name = "NotAcceptable", required=true) + public String getNotAcceptable() { + return notAcceptable; + } + + public void setNotAcceptable(String notAcceptable) { + this.notAcceptable = notAcceptable; + } + + @XmlElement(name = "UnsupportedMediaType", required=true) + public String getUnsupportedMediaType() { + return unsupportedMediaType; + } + + public void setUnsupportedMediaType(String unsupportedMediaType) { + this.unsupportedMediaType = unsupportedMediaType; + } + + @XmlElement(name = "InternalServerError", required=true) + public String getInternalServerError() { + return internalServerError; + } + + public void setInternalServerError(String internalServerError) { + this.internalServerError = internalServerError; + } + + @XmlElement(name = "DefaultPage", required=true) + public String getDefaultPage() { + return defaultPage; + } + + public void setDefaultPage(String defaultPage) { + this.defaultPage = defaultPage; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/LifecycleState.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/LifecycleState.java new file mode 100644 index 0000000000..f94f3b3690 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/LifecycleState.java @@ -0,0 +1,108 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.config; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +/** + * This class represents the lifecycle state config + */ +@XmlRootElement(name = "LifecycleState") +public class LifecycleState { + + private String name; + private String permission; + private List proceedingStates; + private boolean isAppInstallable; + private boolean isAppUpdatable; + private boolean isInitialState; + private boolean isEndState; + private boolean isDeletableState; + + @XmlAttribute(name = "name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @XmlElementWrapper(name = "ProceedingStates") + @XmlElement(name = "State") + public List getProceedingStates() { + return proceedingStates; + } + + public void setProceedingStates(List proceedingStates) { + this.proceedingStates = proceedingStates; + } + + @XmlElement(name = "Permission") + public String getPermission() { + return permission; + } + + public void setPermission(String permission) { + this.permission = permission; + } + + @XmlElement(name = "IsAppInstallable") + public boolean isAppInstallable() { + return isAppInstallable; + } + + public void setAppInstallable(boolean isAppInstallable) { + this.isAppInstallable = isAppInstallable; + } + + @XmlElement(name = "IsAppUpdatable") + public boolean isAppUpdatable() { + return isAppUpdatable; + } + + public void setAppUpdatable(boolean isAppUpdatable) { + this.isAppUpdatable = isAppUpdatable; + } + + @XmlElement(name = "IsInitialState") + public boolean isInitialState() { + return isInitialState; + } + + public void setInitialState(boolean isInitialState) { + this.isInitialState = isInitialState; + } + + @XmlElement(name = "IsEndState") + public boolean isEndState() { + return isEndState; + } + + public void setEndState(boolean isEndState) { + this.isEndState = isEndState; + } + + @XmlElement(name = "IsDeletableState") + public boolean isDeletableState() { return isDeletableState; } + + public void setDeletableState(boolean deletableState) { isDeletableState = deletableState; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/MDMConfig.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/MDMConfig.java new file mode 100644 index 0000000000..1f478f8481 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/MDMConfig.java @@ -0,0 +1,40 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.config; + +import javax.xml.bind.annotation.XmlElement; + +public class MDMConfig { + + private String artifactDownloadProtocol; + private String artifactDownloadEndpoint; + + @XmlElement(name = "ArtifactDownloadProtocol", required=true) + public String getArtifactDownloadProtocol() { return artifactDownloadProtocol; } + + public void setArtifactDownloadProtocol(String artifactDownloadProtocol) { + this.artifactDownloadProtocol = artifactDownloadProtocol; + } + + @XmlElement(name = "ArtifactDownloadEndpoint", required=true) + public String getArtifactDownloadEndpoint() { return artifactDownloadEndpoint; } + + public void setArtifactDownloadEndpoint(String artifactDownloadEndpoint) { + this.artifactDownloadEndpoint = artifactDownloadEndpoint; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/RatingConfiguration.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/RatingConfiguration.java new file mode 100644 index 0000000000..44892c462f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/RatingConfiguration.java @@ -0,0 +1,44 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.config; + +import javax.xml.bind.annotation.XmlElement; + +public class RatingConfiguration { + + private int minRatingValue; + private int maxRatingValue; + + @XmlElement(name = "MinRatingValue") + public int getMinRatingValue() { + return minRatingValue; + } + + public void setMinRatingValue(int minRatingValue) { + this.minRatingValue = minRatingValue; + } + + @XmlElement(name = "MaxRatingValue") + public int getMaxRatingValue() { + return maxRatingValue; + } + + public void setMaxRatingValue(int maxRatingValue) { + this.maxRatingValue = maxRatingValue; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/UIConfiguration.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/UIConfiguration.java new file mode 100644 index 0000000000..fc2726dabf --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/config/UIConfiguration.java @@ -0,0 +1,62 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import java.util.List; + +public class UIConfiguration { + + private AppRegistration appRegistration; + private List scopes; + private boolean isSsoEnable; + private ErrorCallback errorCallback; + + @XmlElement(name = "AppRegistration", required=true) + public AppRegistration getAppRegistration() { + return appRegistration; + } + + public void setAppRegistration(AppRegistration appRegistration) { + this.appRegistration = appRegistration; + } + + @XmlElementWrapper(name = "Scopes") + @XmlElement(name = "Scope") + public List getScopes() { + return scopes; + } + + public void setScopes(List scopes) { + this.scopes = scopes; + } + + @XmlElement(name = "EnableSSO") + public boolean isSsoEnable() { + return isSsoEnable; + } + + public void setSsoEnable(boolean ssoEnable) { + isSsoEnable = ssoEnable; + } + + @XmlElement(name = "ErrorCallback", required=true) + public ErrorCallback getErrorCallback() { return errorCallback; } + + public void setErrorCallback(ErrorCallback errorCallback) { this.errorCallback = errorCallback; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApiRegistrationProfile.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApiRegistrationProfile.java new file mode 100644 index 0000000000..a117584bd8 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApiRegistrationProfile.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.dto; + +public class ApiRegistrationProfile { + + private String applicationName; + private String tags[]; + private boolean isAllowedToAllDomains; + private boolean isMappingAnExistingOAuthApp; + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public String[] getTags() { + return tags; + } + + public void setTags(String[] tags) { + this.tags = tags; + } + + public boolean isAllowedToAllDomains() { + return isAllowedToAllDomains; + } + + public void setAllowedToAllDomains(boolean allowedToAllDomains) { + isAllowedToAllDomains = allowedToAllDomains; + } + + public boolean isMappingAnExistingOAuthApp() { + return isMappingAnExistingOAuthApp; + } + + public void setMappingAnExistingOAuthApp(boolean mappingAnExistingOAuthApp) { + isMappingAnExistingOAuthApp = mappingAnExistingOAuthApp; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationDTO.java new file mode 100644 index 0000000000..57ec6991f9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationDTO.java @@ -0,0 +1,192 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.dto; + + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "ApplicationDTO", description = "ApplicationDTO represents an Application details.") +public class ApplicationDTO { + + @ApiModelProperty(name = "id", + value = "The ID given to the application when it is stored in the APPM database") + private int id; + + @ApiModelProperty(name = "name", + value = "Name of the application", + required = true) + private String name; + + @ApiModelProperty(name = "description", + value = "Description of the application", + required = true) + private String description; + + @ApiModelProperty(name = "appCategories", + value = "Category of the application", + required = true, + example = "Educational, Gaming, Travel, Entertainment etc") + private List appCategories; + + @ApiModelProperty(name = "type", + value = "Type of the application", + required = true, + example = "ENTERPRISE, PUBLIC, WEB, WEB_CLIP etc") + private String type; + + @ApiModelProperty(name = "subType", + value = "Subscription type of the application", + required = true, + example = "PAID, FREE") + private String subType; + + @ApiModelProperty(name = "paymentCurrency", + value = "Payment currency of the application", + required = true, + example = "$") + private String paymentCurrency; + + @ApiModelProperty(name = "tags", + value = "List of application tags") + private List tags; + + @ApiModelProperty(name = "unrestrictedRoles", + value = "List of roles that users should have to access the application") + private List unrestrictedRoles; + + + @ApiModelProperty(name = "deviceTypeId", + value = "Id of the Related device type of the application", + example = "1, 2, 3") + private int deviceTypeId; + + @ApiModelProperty(name = "appRating", + value = "Rating of the aplication") + private double appRating; + + @ApiModelProperty(name = "status", + value = "Application status", + required = true, + example = "RETIRED, ACTIVE") + private String status; + + @ApiModelProperty(name = "applicationReleaseDTOs", + value = "List of application releases", + required = true) + private List applicationReleaseDTOs; + + @ApiModelProperty(name = "packageName", + value = "package name of the application") + private String packageName; + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { this.name = name; } + + public List getAppCategories() { + return appCategories; + } + + public void setAppCategories(List appCategories) { this.appCategories = appCategories; } + + public List getTags() { return tags; } + + public void setTags(List tags) { + this.tags = tags; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getSubType() { + return subType; + } + + public void setSubType(String subType) { + this.subType = subType; + } + + public String getPaymentCurrency() { + return paymentCurrency; + } + + public void setPaymentCurrency(String paymentCurrency) { + this.paymentCurrency = paymentCurrency; + } + + public List getApplicationReleaseDTOs() { + return applicationReleaseDTOs; + } + + public void setApplicationReleaseDTOs(List applicationReleaseDTOs) { + this.applicationReleaseDTOs = applicationReleaseDTOs; + } + + public List getUnrestrictedRoles() { + return unrestrictedRoles; + } + + public void setUnrestrictedRoles(List unrestrictedRoles) { + this.unrestrictedRoles = unrestrictedRoles; + } + + public int getDeviceTypeId() { + return deviceTypeId; + } + + public void setDeviceTypeId(int deviceTypeId) { + this.deviceTypeId = deviceTypeId; + } + + public String getStatus() { return status; } + + public void setStatus(String status) { this.status = status; } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public double getAppRating() { return appRating; } + + public void setAppRating(double appRating) { this.appRating = appRating; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationPolicyDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationPolicyDTO.java new file mode 100644 index 0000000000..5611eb51b7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationPolicyDTO.java @@ -0,0 +1,60 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.dto; + +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.List; + +public class ApplicationPolicyDTO { + ApplicationDTO applicationDTO; + String policy; + List deviceIdentifierList; + String action; + + public List getDeviceIdentifierList() { + return deviceIdentifierList; + } + + public void setDeviceIdentifierList(List deviceIdentifierList) { + this.deviceIdentifierList = deviceIdentifierList; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ApplicationDTO getApplicationDTO() { + return applicationDTO; + } + + public void setApplicationDTO(ApplicationDTO applicationDTO) { + this.applicationDTO = applicationDTO; + } + + public String getPolicy() { + return policy; + } + + public void setPolicy(String policy) { + this.policy = policy; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationReleaseDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationReleaseDTO.java new file mode 100644 index 0000000000..d5df40f969 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationReleaseDTO.java @@ -0,0 +1,272 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +@ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store") +@JsonIgnoreProperties({"appHashValue"}) +public class ApplicationReleaseDTO { + + @ApiModelProperty(name = "id", + value = "ID of the application release") + private int id; + + @ApiModelProperty(name = "description", + value = "Description of the application release") + private String description; + + @ApiModelProperty(name = "version", + value = "Version of the application release") + private String version; + + @ApiModelProperty(name = "uuid", + value = "UUID of the application release") + private String uuid; + + @ApiModelProperty(name = "installerName", + value = "ApplicationDTO storing location") + private String installerName; + + @ApiModelProperty(name = "bannerName", + value = "Banner file storing location") + private String bannerName; + + @ApiModelProperty(name = "iconName", + value = "icon file storing location") + private String iconName; + + @ApiModelProperty(name = "screenshotName1", + value = "Screenshot storing location") + private String screenshotName1; + + @ApiModelProperty(name = "screenshotName2", + value = "Screenshot storing location") + private String screenshotName2; + + @ApiModelProperty(name = "screenshotName3", + value = "Screenshot storing location") + private String screenshotName3; + + @ApiModelProperty(name = "releaseType", + value = "Release type of the application release", + required = true, + example = "alpha, beta etc") + private String releaseType; + + @ApiModelProperty(name = "price", + value = "Price of the application release", + required = true) + private double price; + + @ApiModelProperty(name = "appHashValue", + value = "Hash value of the application release") + private String appHashValue; + + @ApiModelProperty(name = "isSharedWithAllTenants", + value = "If application release is shared with all tenants it is eqal to 1 otherwise 0", + required = true) + private boolean isSharedWithAllTenants; + + @ApiModelProperty(name = "metaData", + value = "Meta data of the application release", + required = true) + private String metaData; + + @ApiModelProperty(name = "ratedUsers", + value = "Number of users who has rated the application release") + private int ratedUsers; + + @ApiModelProperty(name = "rating", + value = "Rating value of the application release") + private double rating; + + @ApiModelProperty(name = "url", + value = "URL which is used for WEB-CLIP") + private String url; + + @ApiModelProperty(name = "supportedOsVersions", + value = "ApplicationDTO release supported OS versions") + private String supportedOsVersions; + + @ApiModelProperty(name = "currentState", + value = "Current state of the application release") + private String currentState; + + @ApiModelProperty(name = "packageName", + value = "ApplicationDTO bundle identifier") + private String packageName; + + public ApplicationReleaseDTO() { + } + + public int getRatedUsers() { + return ratedUsers; + } + + public void setRatedUsers(int ratedUsers) { + this.ratedUsers = ratedUsers; + } + + public double getRating() { + return rating; + } + + public void setRating(double rating) { + this.rating = rating; + } + + public void setId(int id) { + this.id = id; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getReleaseType() { + return releaseType; + } + + public void setReleaseType(String releaseType) { + this.releaseType = releaseType; + } + + public void setAppHashValue(String appHashValue) { + this.appHashValue = appHashValue; + } + + public void setIsSharedWithAllTenants(boolean isSharedWithAllTenants) { + this.isSharedWithAllTenants = isSharedWithAllTenants; + } + + public void setMetaData(String metaData) { + this.metaData = metaData; + } + + public int getId() { + return id; + } + + public String getVersion() { + return version; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public String getAppHashValue() { + return appHashValue; + } + + public boolean getIsSharedWithAllTenants() { return isSharedWithAllTenants; } + + public String getMetaData() { + return metaData; + } + + public String getInstallerName() { + return installerName; + } + + public void setInstallerName(String installerName) { + this.installerName = installerName; + } + + public String getBannerName() { + return bannerName; + } + + public void setBannerName(String bannerName) { + this.bannerName = bannerName; + } + + public String getScreenshotName1() { + return screenshotName1; + } + + public void setScreenshotName1(String screenshotName1) { + this.screenshotName1 = screenshotName1; + } + + public String getScreenshotName2() { + return screenshotName2; + } + + public void setScreenshotName2(String screenshotName2) { + this.screenshotName2 = screenshotName2; + } + + public String getScreenshotName3() { + return screenshotName3; + } + + public void setScreenshotName3(String screenshotName3) { + this.screenshotName3 = screenshotName3; + } + + public String getIconName() { + return iconName; + } + + public void setIconName(String iconName) { + this.iconName = iconName; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public String getPackageName() { + return packageName; + } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public String getSupportedOsVersions() { return supportedOsVersions; } + + public void setSupportedOsVersions(String supportedOsVersions) { this.supportedOsVersions = supportedOsVersions; } + + public String getCurrentState() { return currentState; } + + public void setCurrentState(String currentState) { this.currentState = currentState; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/CategoryDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/CategoryDTO.java new file mode 100644 index 0000000000..5ab45a3079 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/CategoryDTO.java @@ -0,0 +1,39 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.dto; + +public class CategoryDTO { + int id; + + String categoryName; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getCategoryName() { + return categoryName; + } + + public void setCategoryName(String categoryName) { + this.categoryName = categoryName; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/DeviceSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/DeviceSubscriptionDTO.java new file mode 100644 index 0000000000..58809c1b2e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/DeviceSubscriptionDTO.java @@ -0,0 +1,73 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.dto; + +import java.sql.Timestamp; + +public class DeviceSubscriptionDTO { + + private int id; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String actionTriggeredFrom; + private String status; + private int deviceId; + + public int getId() { return id; } + + public void setId(int id) { this.id = id; } + + public String getSubscribedBy() { return subscribedBy; } + + public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + + public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { + this.subscribedTimestamp = subscribedTimestamp; + } + + public boolean isUnsubscribed() { return isUnsubscribed; } + + public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + + public String getUnsubscribedBy() { return unsubscribedBy; } + + public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + + public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } + + public String getActionTriggeredFrom() { return actionTriggeredFrom; } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { this.actionTriggeredFrom = actionTriggeredFrom; } + + public String getStatus() { return status; } + + public void setStatus(String status) { this.status = status; } + + public int getDeviceId() { return deviceId; } + + public void setDeviceId(int deviceId) { this.deviceId = deviceId; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/GroupSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/GroupSubscriptionDTO.java new file mode 100644 index 0000000000..1d1640a247 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/GroupSubscriptionDTO.java @@ -0,0 +1,63 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.dto; + +import java.sql.Timestamp; + +public class GroupSubscriptionDTO { + private int id; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String subscribedFrom; + private int groupdId; + + public int getId() { return id; } + + public void setId(int id) { this.id = id; } + + public String getSubscribedBy() { return subscribedBy; } + + public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + + public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { this.subscribedTimestamp = subscribedTimestamp; } + + public boolean isUnsubscribed() { return isUnsubscribed; } + + public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + + public String getUnsubscribedBy() { return unsubscribedBy; } + + public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + + public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { this.unsubscribedTimestamp = unsubscribedTimestamp; } + + public String getSubscribedFrom() { return subscribedFrom; } + + public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; } + + public int getGroupdId() { return groupdId; } + + public void setGroupdId(int groupdId) { this.groupdId = groupdId; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ReviewDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ReviewDTO.java new file mode 100644 index 0000000000..42f410a26f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ReviewDTO.java @@ -0,0 +1,97 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.dto; + +import java.sql.Timestamp; + +public class ReviewDTO { + private int id; + private String content; + private String username; + private Timestamp createdAt; + private Timestamp modifiedAt; + private int rating; + private int rootParentId; + private int immediateParentId; + private String releaseUuid; + private String releaseVersion; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Timestamp getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Timestamp createdAt) { + this.createdAt = createdAt; + } + + public Timestamp getModifiedAt() { + return modifiedAt; + } + + public void setModifiedAt(Timestamp modifiedAt) { + this.modifiedAt = modifiedAt; + } + + public int getRating() { + return rating; + } + + public void setRating(int rating) { + this.rating = rating; + } + + public int getRootParentId() { return rootParentId; } + + public void setRootParentId(int rootParentId) { this.rootParentId = rootParentId; } + + public int getImmediateParentId() { return immediateParentId; } + + public void setImmediateParentId(int immediateParentId) { this.immediateParentId = immediateParentId; } + + public String getReleaseUuid() { return releaseUuid; } + + public void setReleaseUuid(String releaseUuid) { this.releaseUuid = releaseUuid; } + + public String getReleaseVersion() { return releaseVersion; } + + public void setReleaseVersion(String releaseVersion) { this.releaseVersion = releaseVersion; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/RoleSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/RoleSubscriptionDTO.java new file mode 100644 index 0000000000..9d06179024 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/RoleSubscriptionDTO.java @@ -0,0 +1,67 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.dto; + +import java.sql.Timestamp; + +public class RoleSubscriptionDTO { + private int id; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String subscribedFrom; + private String roleName; + + public int getId() { return id; } + + public void setId(int id) { this.id = id; } + + public String getSubscribedBy() { return subscribedBy; } + + public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + + public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { + this.subscribedTimestamp = subscribedTimestamp; + } + + public boolean isUnsubscribed() { return isUnsubscribed; } + + public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + + public String getUnsubscribedBy() { return unsubscribedBy; } + + public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + + public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } + + public String getSubscribedFrom() { return subscribedFrom; } + + public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; } + + public String getRoleName() { return roleName; } + + public void setRoleName(String roleName) { this.roleName = roleName; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ScheduledSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ScheduledSubscriptionDTO.java new file mode 100644 index 0000000000..65801e9415 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ScheduledSubscriptionDTO.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.dto; + +import com.google.gson.Gson; +import org.wso2.carbon.device.application.mgt.common.ExecutionStatus; +import org.wso2.carbon.device.application.mgt.common.SubscriptionType; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +/** + * This class represents a DTO for AP_SCHEDULED_SUBSCRIPTION table + */ +public class ScheduledSubscriptionDTO { + /** + * Generated ID of the subscription. + */ + private int id; + + /** + * Name of the task which is related to the subscription. + * + * Task name is a generated field and in the following pattern: + * {@code __} + * {@code SUBSCRIPTION-TYPE} - {@see {@linkplain SubscriptionType}} + * {@code ACTION} - {@see {@linkplain org.wso2.carbon.device.application.mgt.common.SubAction} + * {@code HASH-VALUE} - this is a hash value of the combination of application uuid and the subscriber list. + * + * Example: {@code DEVICE_INSTALL_e593e00e8ef55efc764295b6aa9ad56b} + */ + private String taskName; + + /** + * UUID of the application release which is subscribed to. + * {@see {@link org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease}} + */ + private String applicationUUID; + + /** + * List of subscribers for the application release. The type of the list depends on the subscription type. + * {@see {@link SubscriptionType}}. If the subscription type is {@code SubscriptionType.DEVICE} the type will be + * {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} and if not the type will be {@link String}. + */ + private List subscriberList; + + /** + * Status of the subscription. {@see {@link ExecutionStatus}} + */ + private ExecutionStatus status; + + /** + * Scheduled time of subscription. + */ + private LocalDateTime scheduledAt; + + /** + * Username of the scheduler. + */ + private String scheduledBy; + + /** + * If the subscription is marked as deleted or not. + * {@code true} means that the related task is removed from the {@link org.wso2.carbon.ntask.core.TaskManager}. + */ + private boolean deleted; + + public ScheduledSubscriptionDTO() { + + } + + public ScheduledSubscriptionDTO(String taskName, String applicationUUID, LocalDateTime scheduledAt, + List subscriberList, String scheduledBy) { + this.taskName = taskName; + this.applicationUUID = applicationUUID; + this.scheduledAt = scheduledAt; + this.subscriberList = subscriberList; + this.scheduledBy = scheduledBy; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTaskName() { + return taskName; + } + + public void setTaskName(String taskName) { + this.taskName = taskName; + } + + public String getApplicationUUID() { + return applicationUUID; + } + + public void setApplicationUUID(String applicationUUID) { + this.applicationUUID = applicationUUID; + } + + public List getSubscriberList() { + return subscriberList; + } + + public void setSubscriberList(List subscriberList) { + this.subscriberList = subscriberList; + } + + public ExecutionStatus getStatus() { + return status; + } + + public void setStatus(ExecutionStatus status) { + this.status = status; + } + + public LocalDateTime getScheduledAt() { + return scheduledAt; + } + + public void setScheduledAt(LocalDateTime scheduledAt) { + this.scheduledAt = scheduledAt; + } + + public String getScheduledBy() { + return scheduledBy; + } + + public void setScheduledBy(String scheduledBy) { + this.scheduledBy = scheduledBy; + } + + /** + * @return the string representation of the subscriber list. + */ + public String getSubscribersString() { + if (this.taskName.startsWith(SubscriptionType.DEVICE.toString())) { + return new Gson().toJson(this.subscriberList); + } else { + return this.subscriberList.stream().map(String.class::cast).collect(Collectors.joining(",")); + } + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/TagDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/TagDTO.java new file mode 100644 index 0000000000..6a7f5f5af0 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/TagDTO.java @@ -0,0 +1,41 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.dto; + +public class TagDTO { + + int id; + + String tagName; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTagName() { + return tagName; + } + + public void setTagName(String tagName) { + this.tagName = tagName; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/UserSubscriptionDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/UserSubscriptionDTO.java new file mode 100644 index 0000000000..277b04e97d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/UserSubscriptionDTO.java @@ -0,0 +1,31 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.dto; + +import java.sql.Timestamp; + +public class UserSubscriptionDTO { + private int id; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String subscribedFrom; + private String userName; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationCategoryManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationCategoryManagementException.java new file mode 100644 index 0000000000..027aa52d43 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationCategoryManagementException.java @@ -0,0 +1,28 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Exception that will be thrown during Application Category Management. + */ +public class ApplicationCategoryManagementException extends ApplicationManagementException { + public ApplicationCategoryManagementException(String message) { + super(message); + setMessage(message); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationManagementException.java new file mode 100644 index 0000000000..48596fe969 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationManagementException.java @@ -0,0 +1,46 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Represents the exception thrown during application management. + */ +public class ApplicationManagementException extends Exception { + private String message; + + public ApplicationManagementException(String message, Throwable throwable) { + super(message, throwable); + setMessage(message); + } + + public ApplicationManagementException(String message) { + super(message); + setMessage(message); + } + + public ApplicationManagementException() { + + } + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationStorageManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationStorageManagementException.java new file mode 100644 index 0000000000..56cfb19710 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ApplicationStorageManagementException.java @@ -0,0 +1,31 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Represents the exception thrown during storing and retrieving the artifacts. + */ +public class ApplicationStorageManagementException extends ResourceManagementException { + public ApplicationStorageManagementException(String message, Throwable ex) { + super(message, ex); + } + + public ApplicationStorageManagementException(String message) { + super(message); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/DBConnectionException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/DBConnectionException.java new file mode 100644 index 0000000000..cedf06bf7c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/DBConnectionException.java @@ -0,0 +1,33 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Exception thrown due to Database Connection issues. + */ +public class DBConnectionException extends ApplicationManagementException { + + private static final long serialVersionUID = -3151279331929070297L; + + public DBConnectionException(String message, Throwable cause) { + super(message, cause); + } + + public DBConnectionException(String msg) { + super(msg); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/DeviceConnectorException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/DeviceConnectorException.java new file mode 100644 index 0000000000..3e9fb9ddee --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/DeviceConnectorException.java @@ -0,0 +1,46 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Represents the exception thrown during device connections. + */ +public class DeviceConnectorException extends Exception { + private String message; + + public DeviceConnectorException(String message, Throwable throwable) { + super(message, throwable); + setMessage(message); + } + + public DeviceConnectorException(String message) { + super(message); + setMessage(message); + } + + public DeviceConnectorException() { + + } + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/IllegalTransactionStateException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/IllegalTransactionStateException.java new file mode 100644 index 0000000000..40d0c4916a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/IllegalTransactionStateException.java @@ -0,0 +1,38 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Exception thrown due to an issue in database transactions. + */ +public class IllegalTransactionStateException extends RuntimeException { + + private static final long serialVersionUID = -3151279331929070297L; + + public IllegalTransactionStateException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public IllegalTransactionStateException(String message, Throwable cause) { + super(message, cause); + } + + public IllegalTransactionStateException(String msg) { + super(msg); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/InvalidConfigurationException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/InvalidConfigurationException.java new file mode 100644 index 0000000000..9ad11d10b5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/InvalidConfigurationException.java @@ -0,0 +1,32 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Exception thrown due to invalid configurations provided for Application Management. + */ +public class InvalidConfigurationException extends ApplicationManagementException { + + public InvalidConfigurationException(String message, Throwable throwable) { + super(message, throwable); + } + + public InvalidConfigurationException(String message) { + super(message); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/LifecycleManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/LifecycleManagementException.java new file mode 100644 index 0000000000..6df1b09246 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/LifecycleManagementException.java @@ -0,0 +1,31 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Exception caused during the lifecycle management. + */ +public class LifecycleManagementException extends ApplicationManagementException { + + public LifecycleManagementException(String message, Throwable ex) { + super(message, ex); + } + + public LifecycleManagementException(String message) { + super(message); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/RequestValidatingException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/RequestValidatingException.java new file mode 100644 index 0000000000..3fbb27fc35 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/RequestValidatingException.java @@ -0,0 +1,32 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Represents the exception thrown during validating the request. + */ +public class RequestValidatingException extends Exception{ + + public RequestValidatingException(String message, Throwable ex) { + super(message, ex); + } + + public RequestValidatingException(String message) { + super(message); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ResourceManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ResourceManagementException.java new file mode 100644 index 0000000000..3b5125d365 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ResourceManagementException.java @@ -0,0 +1,31 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Represents the exception that will be thrown when there is an issue while managing the resources. + */ +public class ResourceManagementException extends Exception { + public ResourceManagementException(String message, Throwable ex) { + super(message, ex); + } + + public ResourceManagementException(String message) { + super(message); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ReviewDoesNotExistException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ReviewDoesNotExistException.java new file mode 100644 index 0000000000..c31c8b6263 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ReviewDoesNotExistException.java @@ -0,0 +1,43 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +public class ReviewDoesNotExistException extends Exception { + private String message; + + public ReviewDoesNotExistException(String message, Throwable throwable) { + super(message, throwable); + setMessage(message); + } + + public ReviewDoesNotExistException(String message) { + super(message); + setMessage(message); + } + + public ReviewDoesNotExistException() { + + } + + @Override public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ReviewManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ReviewManagementException.java new file mode 100644 index 0000000000..1e6d0c0a63 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/ReviewManagementException.java @@ -0,0 +1,43 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +public class ReviewManagementException extends Exception { + private String message; + + public ReviewManagementException(String message, Throwable throwable) { + super(message, throwable); + setMessage(message); + } + + public ReviewManagementException(String message) { + super(message); + setMessage(message); + } + + public ReviewManagementException() { + + } + + @Override public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/SubscriptionManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/SubscriptionManagementException.java new file mode 100644 index 0000000000..e3c48164d0 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/SubscriptionManagementException.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.exception; + +public class SubscriptionManagementException extends Exception { + private String message; + + public SubscriptionManagementException(String message, Throwable throwable) { + super(message, throwable); + setMessage(message); + } + + public SubscriptionManagementException(String message) { + super(message); + setMessage(message); + } + + public SubscriptionManagementException() { + + } + + @Override public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/TransactionManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/TransactionManagementException.java new file mode 100644 index 0000000000..4fcb6261fd --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/TransactionManagementException.java @@ -0,0 +1,38 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Exception thrown due to an issue in TransactionManagement of Database. + */ +public class TransactionManagementException extends ApplicationManagementException { + + private static final long serialVersionUID = -3151279321929070297L; + + public TransactionManagementException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public TransactionManagementException(String message, Throwable cause) { + super(message, cause); + } + + public TransactionManagementException(String msg) { + super(msg); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/UnsupportedDatabaseEngineException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/UnsupportedDatabaseEngineException.java new file mode 100644 index 0000000000..0be1bc7466 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/UnsupportedDatabaseEngineException.java @@ -0,0 +1,39 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * This runtime exception will be thrown if the server has configured with unsupported DB engine. + */ +public class UnsupportedDatabaseEngineException extends RuntimeException { + + private static final long serialVersionUID = -3151279311929070297L; + + public UnsupportedDatabaseEngineException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public UnsupportedDatabaseEngineException(String message, Throwable cause) { + super(message, cause); + } + + public UnsupportedDatabaseEngineException(String msg) { + super(msg); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/VisibilityManagementException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/VisibilityManagementException.java new file mode 100644 index 0000000000..aecf2c76c5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/VisibilityManagementException.java @@ -0,0 +1,36 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.exception; + +/** + * This specialized exception is thrown by the Visibility Manager during unexpected behaviour + * or unsupported parameters. + */ +public class VisibilityManagementException extends ApplicationManagementException { + + public VisibilityManagementException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public VisibilityManagementException(String message, Throwable cause) { + super(message, cause); + } + + public VisibilityManagementException(String msg) { + super(msg); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java new file mode 100644 index 0000000000..7f1c0200e4 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java @@ -0,0 +1,162 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.response; + +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +public class Application { + @ApiModelProperty(name = "id", + value = "ID of the application", + required = true) + private int id; + + @ApiModelProperty(name = "name", + value = "Name of the application", + required = true) + private String name; + + @ApiModelProperty(name = "description", + value = "Description of the application", + required = true) + private String description; + + @ApiModelProperty(name = "categories", + value = "CategoryDTO of the application", + required = true, + example = "Educational, Gaming, Travel, Entertainment etc") + private List categories; + + @ApiModelProperty(name = "type", + value = "Type of the application", + required = true, + example = "ENTERPRISE, PUBLIC, WEB, WEB_CLIP etc") + private String type; + + @ApiModelProperty(name = "isAndroidEnterpriseApp", + value = "Android enterprise app or not", + required = true, + example = "true or false") + private boolean isAndroidEnterpriseApp; + + @ApiModelProperty(name = "subMethod", + value = "Subscription type of the application", + required = true, + example = "PAID, FREE") + private String subMethod; + + @ApiModelProperty(name = "paymentCurrency", + value = "Payment currency of the application", + required = true, + example = "$") + private String paymentCurrency; + + @ApiModelProperty(name = "tags", + value = "List of application tags") + private List tags; + + @ApiModelProperty(name = "unrestrictedRoles", + value = "List of roles that users should have to access the application") + private List unrestrictedRoles; + + @ApiModelProperty(name = "deviceType", + value = "Related device type of the application", + required = true, + example = "IoS, Android, Arduino, RaspberryPi etc") + private String deviceType; + + @ApiModelProperty(name = "rating", + value = "Application Rating") + private double rating; + + @ApiModelProperty(name = "applicationReleases", + value = "List of application releases", + required = true) + private List applicationReleases; + + @ApiModelProperty(name = "packageName", + value = "package name of the application") + private String packageName; + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public int getId() { return id; } + + public void setId(int id) { this.id = id; } + + public String getName() { + return name; + } + + public void setName(String name) { this.name = name; } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public List getTags() { return tags; } + + public void setTags(List tags) { this.tags = tags; } + + public String getType() { return type; } + + public void setType(String type) { this.type = type; } + + public String getSubMethod() { return subMethod; } + + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } + + public String getPaymentCurrency() { return paymentCurrency; } + + public void setPaymentCurrency(String paymentCurrency) { this.paymentCurrency = paymentCurrency; } + + public List getApplicationReleases() { return applicationReleases; } + + public void setApplicationReleases(List applicationReleases) { + this.applicationReleases = applicationReleases; } + + public List getUnrestrictedRoles() { return unrestrictedRoles; } + + public void setUnrestrictedRoles(List unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; } + + public String getDeviceType() { return deviceType; } + + public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public double getRating() { return rating; } + + public void setRating(double rating) { this.rating = rating; } + + public boolean isAndroidEnterpriseApp() { return isAndroidEnterpriseApp; } + + public void setAndroidEnterpriseApp(boolean androidEnterpriseApp) { isAndroidEnterpriseApp = androidEnterpriseApp; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java new file mode 100644 index 0000000000..36ed3e8648 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java @@ -0,0 +1,165 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.response; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store") +public class ApplicationRelease { + + @ApiModelProperty(name = "description", + value = "Description of the application release") + private String description; + + @ApiModelProperty(name = "version", + value = "Version of the application release") + private String version; + + @ApiModelProperty(name = "uuid", + value = "UUID of the application release") + private String uuid; + + @ApiModelProperty(name = "installerPath", + value = "ApplicationDTO storing location") + private String installerPath; + + @ApiModelProperty(name = "bannerPath", + value = "Banner file storing location") + private String bannerPath; + + @ApiModelProperty(name = "iconPath", + value = "icon file storing location") + private String iconPath; + + @ApiModelProperty(name = "screenshots", + value = "Screenshot storing location") + private List screenshots; + + @ApiModelProperty(name = "releaseType", + value = "Release type of the application release", + required = true, + example = "alpha, beta etc") + private String releaseType; + + @ApiModelProperty(name = "currentStatus", + value = "CurrentStatus of the Application Release.", + required = true, + example = "CREATED, IN-REVIEW, PUBLISHED etc") + private String currentStatus; + + @ApiModelProperty(name = "price", + value = "Price of the application release", + required = true) + private double price; + + @ApiModelProperty(name = "isSharedWithAllTenants", + value = "If application release is shared with all tenants it is eqal to 1 otherwise 0", + required = true) + private boolean isSharedWithAllTenants; + + @ApiModelProperty(name = "metaData", + value = "Meta data of the application release", + required = true) + private String metaData; + + @ApiModelProperty(name = "supportedOsVersions", + value = "ApplicationDTO release supported OS versions") + private String supportedOsVersions; + + @ApiModelProperty(name = "rating", + value = "Application Rating") + private double rating; + + public String getReleaseType() { + return releaseType; + } + + public void setReleaseType(String releaseType) { + this.releaseType = releaseType; + } + + public void setIsSharedWithAllTenants(boolean isSharedWithAllTenants) { + this.isSharedWithAllTenants = isSharedWithAllTenants; + } + + public void setMetaData(String metaData) { + this.metaData = metaData; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public boolean getIsSharedWithAllTenants() { + return isSharedWithAllTenants; + } + + public String getMetaData() { + return metaData; + } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public String getVersion() { return version; } + + public void setVersion(String version) { this.version = version; } + + public String getUuid() { return uuid; } + + public void setUuid(String uuid) { this.uuid = uuid; } + + public String getInstallerPath() { return installerPath; } + + public void setInstallerPath(String installerPath) { this.installerPath = installerPath; } + + public String getBannerPath() { return bannerPath; } + + public void setBannerPath(String bannerPath) { this.bannerPath = bannerPath; } + + public String getIconPath() { return iconPath; } + + public void setIconPath(String iconPath) { this.iconPath = iconPath; } + + public boolean isSharedWithAllTenants() { return isSharedWithAllTenants; } + + public void setSharedWithAllTenants(boolean sharedWithAllTenants) { isSharedWithAllTenants = sharedWithAllTenants; } + + public String getSupportedOsVersions() { return supportedOsVersions; } + + public void setSupportedOsVersions(String supportedOsVersions) { this.supportedOsVersions = supportedOsVersions; } + + public String getCurrentStatus() { return currentStatus; } + + public void setCurrentStatus(String currentStatus) { this.currentStatus = currentStatus; } + + public double getRating() { return rating; } + + public void setRating(double rating) { this.rating = rating; } + + public List getScreenshots() { return screenshots; } + + public void setScreenshots(List screenshots) { this.screenshots = screenshots; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Category.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Category.java new file mode 100644 index 0000000000..f90a688a5f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Category.java @@ -0,0 +1,41 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.response; + +public class Category { + + private String categoryName; + + private boolean isCategoryDeletable; + + public String getCategoryName() { + return categoryName; + } + + public void setCategoryName(String categoryName) { + this.categoryName = categoryName; + } + + public boolean isCategoryDeletable() { + return isCategoryDeletable; + } + + public void setCategoryDeletable(boolean categoryDeletable) { + isCategoryDeletable = categoryDeletable; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Review.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Review.java new file mode 100644 index 0000000000..1c0285fbb4 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Review.java @@ -0,0 +1,115 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.response; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.sql.Timestamp; +import java.util.List; + +@ApiModel(value = "Review", description = "Review represents the user's review for an application release") +public class Review { + + @ApiModelProperty(name = "id", value = "Review ID.") + private int id; + + @ApiModelProperty(name = "content", value = "Review message.") + private String content; + + @ApiModelProperty(name = "username", value = "Username odf the Review creator") + private String username; + + @ApiModelProperty(name = "createdAt", value = "Review created timestamp.") + private Timestamp createdAt; + + @ApiModelProperty(name = "createdAt", value = "Review modified timestamp.") + private Timestamp modifiedAt; + + @ApiModelProperty(name = "rating", value = "Rating value of the application release") + private int rating; + + @ApiModelProperty(name = "releaseUuid", value = "UUID of the review associated application") + private String releaseUuid; + + @ApiModelProperty(name = "releaseVersion", value = "Version of the review associated application") + private String releaseVersion; + + @ApiModelProperty(name = "replies", value = "Replying reviews") + private List replies; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Timestamp getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Timestamp createdAt) { + this.createdAt = createdAt; + } + + public Timestamp getModifiedAt() { + return modifiedAt; + } + + public void setModifiedAt(Timestamp modifiedAt) { + this.modifiedAt = modifiedAt; + } + + public int getRating() { + return rating; + } + + public void setRating(int rating) { + this.rating = rating; + } + + public List getReplies() { return replies; } + + public void setReplies(List replies) { this.replies = replies; } + + public String getReleaseUuid() { return releaseUuid; } + + public void setReleaseUuid(String releaseUuid) { this.releaseUuid = releaseUuid; } + + public String getReleaseVersion() { return releaseVersion; } + + public void setReleaseVersion(String releaseVersion) { this.releaseVersion = releaseVersion; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Tag.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Tag.java new file mode 100644 index 0000000000..a10e3eccc9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Tag.java @@ -0,0 +1,41 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.response; + +public class Tag { + + private String tagName; + + private boolean isTagDeletable; + + public String getTagName() { + return tagName; + } + + public void setTagName(String tagName) { + this.tagName = tagName; + } + + public boolean isTagDeletable() { + return isTagDeletable; + } + + public void setTagDeletable(boolean tagDeletable) { + isTagDeletable = tagDeletable; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java new file mode 100644 index 0000000000..3344356422 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java @@ -0,0 +1,276 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.services; + +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.wso2.carbon.device.application.mgt.common.ApplicationArtifact; +import org.wso2.carbon.device.application.mgt.common.LifecycleChanger; +import org.wso2.carbon.device.application.mgt.common.ApplicationList; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.Filter; +import org.wso2.carbon.device.application.mgt.common.LifecycleState; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException; +import org.wso2.carbon.device.application.mgt.common.response.Application; +import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.response.Category; +import org.wso2.carbon.device.application.mgt.common.response.Tag; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppWrapper; + +import java.util.List; + +/** + * This interface manages the application creation, deletion and editing of the application. + */ +public interface ApplicationManager { + + /*** + * The method is responsible to add new application into entgra App Manager. + * + * @param applicationWrapper Application that need to be created. + * @param applicationArtifact contains artifact data. i.e image name and stream, icon name and stream etc. + * @return {@link Application} + * @throws ApplicationManagementException Catch all other throwing exceptions and throw {@link ApplicationManagementException} + */ + Application createEntApp(ApplicationWrapper applicationWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException; + + Application createWebClip(WebAppWrapper webAppWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException; + + Application createPublicApp(PublicAppWrapper publicAppWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException; + + Application createCustomApp(CustomAppWrapper customAppWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException; + + /** + * Updates an already existing application. + * + * @param applicationId ID of the application + * @param applicationUpdateWrapper Application data that need to be updated. + * @return Updated Application + * @throws ApplicationManagementException ApplicationDTO Management Exception + */ + Application updateApplication(int applicationId, ApplicationUpdateWrapper applicationUpdateWrapper) + throws ApplicationManagementException; + + /** + * Delete an application identified by the unique ID. + * + * @param applicationId ID for tha application + * @throws ApplicationManagementException ApplicationDTO Management Exception + */ + void deleteApplication(int applicationId) throws ApplicationManagementException; + + /** + * Retire an application identified by the unique ID. + * + * @param applicationId ID for tha application + * @throws ApplicationManagementException ApplicationDTO Management Exception + */ + void retireApplication(int applicationId) throws ApplicationManagementException; + + /** + * Delete an application identified by the unique ID. + * + * @param releaseUuid UUID of tha application release + * @throws ApplicationManagementException ApplicationDTO Management Exception + */ + void deleteApplicationRelease(String releaseUuid) throws ApplicationManagementException; + + /** + * To get the applications based on the search filter. + * + * @param filter Search filter + * @return Applications that matches the given filter criteria. + * @throws ApplicationManagementException ApplicationDTO Management Exception + */ + ApplicationList getApplications(Filter filter) throws ApplicationManagementException; + + /** + * To get the Application for given Id. + * + * @param id id of the ApplicationDTO + * @param state state of the ApplicationDTO + * @return the ApplicationDTO identified by the ID + * @throws ApplicationManagementException ApplicationDTO Management Exception. + */ + Application getApplicationById(int id, String state) throws ApplicationManagementException; + + /** + * To get the Application Release for given uuid. + * + * @param uuid uuid of the ApplicationDTO + * @return the Application Release identified by the UUID + * @throws ApplicationManagementException Application Management Exception. + */ + Application getApplicationByUuid(String uuid) throws ApplicationManagementException; + + /** + * To get the ApplicationDTO for given application relase UUID. + * + * @param uuid UUID of the ApplicationDTO + * @param state state of the ApplicationDTO + * @return the ApplicationDTO identified by the ID + * @throws ApplicationManagementException ApplicationDTO Management Exception. + */ + Application getApplicationByUuid(String uuid, String state) throws ApplicationManagementException; + + /** + * To get lifecycle state change flow of a particular Application Release. + * + * @param releaseUuid UUID of the Application Release. + * @return the List of LifecycleStates which represent the lifecycle change flow of the application releases. + * @throws ApplicationManagementException Application Management Exception. + */ + List getLifecycleStateChangeFlow(String releaseUuid) throws ApplicationManagementException; + + /** + * To get all the releases of a particular ApplicationDTO. + * + * @param releaseUuid UUID of the ApplicationDTO Release. + * @param lifecycleChanger Lifecycle changer that contains the action and the reson for the change. + * @throws ApplicationManagementException ApplicationDTO Management Exception. + * @return + */ + ApplicationRelease changeLifecycleState(String releaseUuid, LifecycleChanger lifecycleChanger) + throws ApplicationManagementException; + + /** + * To update release images such as icons, banner and screenshots. + * + * @param uuid uuid of the ApplicationDTO + * @param applicationArtifact Application artifact that contains names and input streams of the application artifacts. + * @throws ApplicationManagementException ApplicationDTO Management Exception. + */ + void updateApplicationImageArtifact(String uuid, ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + + + /** + * To update release images. + * + * @param deviceType Application artifact compatible device type name. + * @param uuid uuid of the ApplicationDTO + * @param applicationArtifact Application artifact that contains names and input streams of the application artifacts. + * @throws ApplicationManagementException ApplicationDTO Management Exception. + */ + void updateApplicationArtifact(String deviceType, String uuid, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + + /** + * To create an application release for an ApplicationDTO. + * + * @param applicationId ID of the ApplicationDTO + * @param entAppReleaseWrapper ApplicatonRelease that need to be be created. + * @return the unique id of the application release, if the application release succeeded else -1 + */ + ApplicationRelease createEntAppRelease(int applicationId, EntAppReleaseWrapper entAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + + /*** + * + * @param releaseUuid UUID of the application release. + * @param entAppReleaseWrapper {@link ApplicationReleaseDTO} + * @param applicationArtifact {@link ApplicationArtifact} + * @return If the application release is updated correctly True returns, otherwise retuen False + */ + ApplicationRelease updateEntAppRelease(String releaseUuid, EntAppReleaseWrapper entAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + + ApplicationRelease updatePubAppRelease(String releaseUuid, PublicAppReleaseWrapper publicAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + + ApplicationRelease updateWebAppRelease(String releaseUuid, WebAppReleaseWrapper webAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + + ApplicationRelease updateCustomAppRelease(String releaseUuid, CustomAppReleaseWrapper customAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + + /*** + * To validate the application creating request + * + */ + void validateAppCreatingRequest(T param) throws ApplicationManagementException; + + /*** + * + * @throws ApplicationManagementException throws if payload does not satisfy requirements. + */ + void validateReleaseCreatingRequest(T param, String deviceType) throws ApplicationManagementException; + + /*** + * + * @param iconFile Icon file for the application. + * @param bannerFile Banner file for the application. + * @param attachmentList Screenshot list. + * @throws RequestValidatingException If request doesn't contains required attachments. + */ + void validateImageArtifacts(Attachment iconFile, Attachment bannerFile, List attachmentList) + throws RequestValidatingException; + + void validateBinaryArtifact(Attachment binaryFile) throws RequestValidatingException; + + void addApplicationCategories(List categories) throws ApplicationManagementException; + + List getRegisteredTags() throws ApplicationManagementException; + + List getRegisteredCategories() throws ApplicationManagementException; + + void deleteApplicationTag(int appId, String tagName) throws ApplicationManagementException; + + void deleteTag(String tagName) throws ApplicationManagementException; + + void deleteUnusedTag(String tagName) throws ApplicationManagementException; + + void updateTag(String oldTagName, String newTagName) throws ApplicationManagementException; + + List addTags(List tags) throws ApplicationManagementException; + + List addApplicationTags(int appId, List tags) throws ApplicationManagementException; + + List addCategories(List categories) throws ApplicationManagementException; + + void deleteCategory(String categoryName) throws ApplicationManagementException; + + void updateCategory(String oldCategoryName, String newCategoryName) throws ApplicationManagementException; + + String getInstallableLifecycleState() throws ApplicationManagementException; + + void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException; + + + /** + * Get plist content to download and install the application. + * + * @param uuid Release UUID of the application. + * @return plist string + * @throws ApplicationManagementException Application management exception + */ + String getPlistArtifact(String uuid) throws ApplicationManagementException; + + List getReleaseByPackageNames(List packageIds) throws ApplicationManagementException; + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java new file mode 100644 index 0000000000..604e1cbab6 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java @@ -0,0 +1,113 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.services; + +import org.wso2.carbon.device.application.mgt.common.ApplicationInstaller; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagementException; + +import java.io.InputStream; +import java.util.List; + +/** + * This manages all the storage related requirements of Application. + */ +public interface ApplicationStorageManager { + + /** + * To upload image artifacts related with an Application. + * + * @param applicationRelease Application Release Object + * @param iconFile InputStream of the icon file. + * @param bannerFile InputStream of the banner file. + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if it finds an empty screenshot array or IOException throws while handling + * input streams. + */ + ApplicationReleaseDTO uploadImageArtifacts(ApplicationReleaseDTO applicationRelease, InputStream iconFile, + InputStream bannerFile, List screenshots, int tenantId) throws ResourceManagementException; + + /** + * To get App Installer data such as version, package name etc. + * + * @param binaryFile Binary file of the application. + * @param deviceType Compatible device type of the application. + * @return {@link ApplicationInstaller} + * @throws ApplicationStorageManagementException if device type is incorrect or error occurred while parsing binary + * data. + */ + ApplicationInstaller getAppInstallerData(InputStream binaryFile, String deviceType) + throws ApplicationStorageManagementException; + + /** + * To upload release artifacts for an Application. + * + * @param applicationRelease Application Release Object. + * @param deviceType Compatible device type of the application. + * @param binaryFile Binary File for the release. + * @param tenantId Tenant Id + * @throws ResourceManagementException if IO Exception occured while saving the release artifacts in the server. + */ + void uploadReleaseArtifact(ApplicationReleaseDTO applicationRelease, String deviceType, InputStream binaryFile, + int tenantId) throws ResourceManagementException; + + /** + * To upload release artifacts for an Application. + * + * @param applicationReleaseDTO application Release of a particular application. + * @param deletingAppHashValue Hash value of the deleting application release. + * @param tenantId Tenant Id + * @throws ApplicationStorageManagementException if IO Exception occurs while copying image artifacts and deleting + * application release installer file. + */ + void copyImageArtifactsAndDeleteInstaller(String deletingAppHashValue, + ApplicationReleaseDTO applicationReleaseDTO, int tenantId) throws ApplicationStorageManagementException; + + /** + * To delete the artifacts related with particular Application Release. + * + * @param appReleaseHashVal Hash value of the application release. + * @param folderName Folder name of the application stored. + * @param fileName Name of the application release artifact. + * @throws ApplicationStorageManagementException if artifact doesn't exist. + */ + void deleteAppReleaseArtifact(String appReleaseHashVal, String folderName, String fileName, int tenantId) + throws ApplicationStorageManagementException; + + /** + * To delete all release artifacts related with particular Application Release. + * + * @param directoryPaths Hash values of the Application. + * @param tenantId Tenant Id + * @throws ApplicationStorageManagementException if artifact doesn't exist or IO exception occurred while deleting + * application artifact. + */ + void deleteAllApplicationReleaseArtifacts(List directoryPaths, int tenantId) + throws ApplicationStorageManagementException; + + /** + * Get the InputStream of the file which is located in filePath + * + * @param hashVal Hash Value of the application release. + * @return {@link InputStream} + * @throws ApplicationStorageManagementException throws if an error occurs when accessing the file. + */ + InputStream getFileStream(String hashVal, String folderName, String fileName, int tenantId) + throws ApplicationStorageManagementException; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/AppmDataHandler.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/AppmDataHandler.java new file mode 100644 index 0000000000..7385688db5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/AppmDataHandler.java @@ -0,0 +1,40 @@ +/* Copyright (c) 2018, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.services; + +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; +import org.wso2.carbon.device.application.mgt.common.config.UIConfiguration; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; + +import java.io.InputStream; +import java.util.Map; + +public interface AppmDataHandler { + /** + * Get UI configuration which is defined in the app-manager.xml + * + * @return {@link UIConfiguration} UI configuration + */ + UIConfiguration getUIConfiguration(); + + Map getLifecycleConfiguration() throws LifecycleManagementException; + + InputStream getArtifactStream(int tenantId, String uuid, String folderName, String artifactName) + throws ApplicationManagementException; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/DeviceConnector.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/DeviceConnector.java new file mode 100644 index 0000000000..b227dd43b5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/DeviceConnector.java @@ -0,0 +1,40 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.services; + +import org.wso2.carbon.device.application.mgt.common.AppOperation; +import org.wso2.carbon.device.application.mgt.common.exception.DeviceConnectorException; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.List; + +/** + * This interface contains operations necessary to perform actions on a device such as install and application on a + * device, uninstall or upgrade. This must be implemented to connect to an external device management server. + */ +public interface DeviceConnector { + + Boolean sendOperationToDevice(AppOperation appOperation, DeviceIdentifier deviceIdentifier) throws + DeviceConnectorException; + + Boolean sendOperationToGroup(AppOperation appOperation, String groupID) throws DeviceConnectorException; + + Boolean sendOperationToUser(AppOperation appOperation, List userList) throws DeviceConnectorException; + + Boolean sendOperationToRole(AppOperation appOperation, String role) throws DeviceConnectorException; + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ReviewManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ReviewManager.java new file mode 100644 index 0000000000..c87b50a3eb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ReviewManager.java @@ -0,0 +1,93 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.services; + +import org.wso2.carbon.device.application.mgt.common.Rating; +import org.wso2.carbon.device.application.mgt.common.response.Review; +import org.wso2.carbon.device.application.mgt.common.PaginationRequest; +import org.wso2.carbon.device.application.mgt.common.PaginationResult; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; +import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper; + +/** + * ReviewManager is responsible for handling all the add/update/delete/get operations related with + */ +public interface ReviewManager { + + /** + * To add a reviewTmp to an application release + * + * @param reviewWrapper reviewTmp of the application. + * @param uuid uuid of the application release. + * @return {@link Review} Added review + * @throws ReviewManagementException Exceptions of the reviewTmp management. + */ + Review addReview(ReviewWrapper reviewWrapper, String uuid, boolean allowMultipleReviews) + throws ReviewManagementException, ApplicationManagementException; + + boolean addReplyComment(ReviewWrapper reviewWrapper, String uuid, int parentReviewId) + throws ReviewManagementException, ApplicationManagementException; + + /** + * Get all review with pagination + * + * @param request Pagination request {@link PaginationRequest} + * @param uuid uuid of the application release + * @return {@link PaginationResult} pagination result with starting offSet and limit + * @throws ReviewManagementException Exceptions of the comment management. + */ + PaginationResult getAllReleaseReviews(PaginationRequest request, String uuid) + throws ReviewManagementException, ApplicationManagementException; + + PaginationResult getAllAppReviews(PaginationRequest request, String uuid) throws ReviewManagementException, + ApplicationManagementException; + + PaginationResult getAllAppReviewsOfUser(PaginationRequest request, String uuid) throws ReviewManagementException, + ApplicationManagementException; + + /** + * To delete review using review id. + * + * @param uuid UUID of the application release + * @throws ReviewManagementException Exceptions of the comment management + */ + void deleteReview(String uuid, int reviewId, boolean isPriviledgedUser) + throws ReviewManagementException, ApplicationManagementException; + + /** + * To update a reviewTmp. + * + * @param reviewId id of the reviewTmp + * @return {@link Review}updated review + * @throws ReviewManagementException Exceptions of the reviewTmp management + */ + Review updateReview(ReviewWrapper updatingReview, int reviewId, String uuid, boolean isPrivilegedUser) + throws ReviewManagementException, ApplicationManagementException; + + /** + * To get the overall rating for a application release + * + * @param appReleaseUuid UUID of the application release. + * @return {@link Review}updated review + * @throws ReviewManagementException Exceptions of the review management + */ + Rating getAppReleaseRating(String appReleaseUuid) throws ReviewManagementException, ApplicationManagementException; + + Rating getAppRating(String appReleaseUuid) throws ReviewManagementException, ApplicationManagementException; + +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java new file mode 100644 index 0000000000..3c8a1d844e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java @@ -0,0 +1,142 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.services; + +import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse; +import org.wso2.carbon.device.application.mgt.common.ExecutionStatus; +import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; +import org.wso2.carbon.device.mgt.common.PaginationResult; + +import java.util.List; + +/** + * This interface manages all the operations related with ApplicationDTO Subscription. + */ +public interface SubscriptionManager { + /** + * Performs bulk subscription operation for a given application and a subscriber list. + * + * @param applicationUUID UUID of the application to subscribe/unsubscribe + * @param params list of subscribers. This list can be of either + * {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is equal + * to DEVICE or + * {@link String} if {@param subType} is USER, ROLE or GROUP + * @param subType subscription type. E.g. DEVICE, USER, ROLE, GROUP {@see { + * @param action subscription action. E.g. INSTALL/UNINSTALL {@see { + * @param generic type of the method. + * @return {@link ApplicationInstallResponse} + * @throws ApplicationManagementException if error occurs when subscribing to the given application + * @link org.wso2.carbon.device.application.mgt.common.SubscriptionType}} + * @link org.wso2.carbon.device.application.mgt.common.SubAction}} + */ + ApplicationInstallResponse performBulkAppOperation(String applicationUUID, List params, String subType, + String action) throws ApplicationManagementException; + + /** + * Create an entry related to the scheduled task in the database. + * + * @param subscriptionDTO {@link ScheduledSubscriptionDTO} with details of the subscription + * @throws SubscriptionManagementException if unable to create/update entry for the scheduled task + */ + void createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO) throws SubscriptionManagementException; + + /** + * Mark already executed, misfired and failed tasks as deleted. + * + * @return deleted list of subscriptions + * @throws SubscriptionManagementException if error occurred while cleaning up subscriptions. + */ + List cleanScheduledSubscriptions() throws SubscriptionManagementException; + + /** + * Retrieves the subscription entry which is pending by task name. At a given time, there should be only a single + * entry in the status {@code PENDING} and not marked as deleted. + * + * @param taskName name of the task to retrieve + * @return {@link ScheduledSubscriptionDTO} + * @throws SubscriptionManagementException if error occurred while retrieving the subscription details + */ + ScheduledSubscriptionDTO getPendingScheduledSubscription(String taskName) throws SubscriptionManagementException; + + /** + * Updates the status of a subscription. + * + * @param id id of the subscription + * @param status new status of the subscription. {@see {@link ExecutionStatus}} + * @throws SubscriptionManagementException if error occurred while updating the status of the subscription + */ + void updateScheduledSubscriptionStatus(int id, ExecutionStatus status) throws SubscriptionManagementException; + + /** + * Perform google enterprise app install + * @param applicationUUID UUID of the application to subscribe/unsubscribe + * @param params list of subscribers. This list can be of either + * {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is equal + * to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP + * @param subType subscription type. E.g. DEVICE, USER, ROLE, GROUP {@see { + * @param action subscription action. E.g. INSTALL/UNINSTALL {@see { + * @param generic type of the method. + * @return {@link ApplicationInstallResponse} + * @throws ApplicationManagementException ApplicationManagementException if error occurs when subscribing to the + * given application + * @link org.wso2.carbon.device.application.mgt.common.SubscriptionType}} + */ + void performEntAppSubscription(String applicationUUID, List params, String subType, String action) + throws ApplicationManagementException; + + /*** + * This method used to get the app id ,device ids and pass them to DM service method. + * + * @param appUUID UUID of the application release. + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @param status status of the devices. + * @return deviceDetails - device details for given application release. + * @throws {@link ApplicationManagementException} Exception of the application management + */ + PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, + String status) throws ApplicationManagementException; + + /*** + * This method used to get category details. + * + * @param appUUID UUID of the application release. + * @param subType subscription type of the application. + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @return {@link PaginationResult} pagination result of the category details. + * @throws {@link ApplicationManagementException} Exception of the application management + */ + PaginationResult getAppInstalledSubscribers(int offsetValue, int limitValue, String appUUID, + String subType) throws ApplicationManagementException; + + /** + * This method is responsible to provide application subscription data for given application release UUID. + * + * @param offsetValue offset + * @param limitValue limit + * @param appUUID application release UUID + * @return {@link PaginationResult} + * @throws ApplicationManagementException if offset or limit contains incorrect values, if it couldn't find an + * application release for given UUID, if an error occurred while getting device details of subscribed device ids, + * if an error occurred while getting subscription details of given application release UUID. + */ + PaginationResult getAppSubscriptionDetails(int offsetValue, int limitValue, String appUUID) + throws ApplicationManagementException; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationUpdateWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationUpdateWrapper.java new file mode 100644 index 0000000000..4c7614e612 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationUpdateWrapper.java @@ -0,0 +1,95 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "ApplicationWrapper", description = "ApplicationWrapper represents the an ApplicationDTO in ApplicationDTO Store") +public class ApplicationUpdateWrapper { + + + @ApiModelProperty(name = "name", + value = "Name of the application", + required = true) + private String name; + + @ApiModelProperty(name = "description", + value = "Description of the application", + required = true) + private String description; + + @ApiModelProperty(name = "categories", + value = "List of app categories.", + required = true, + example = "Educational, Gaming, Travel, Entertainment etc") + private List categories; + + @ApiModelProperty(name = "subMethod", + value = "Subscription type of the application", + required = true, + example = "PAID, FREE") + private String subMethod; + + @ApiModelProperty(name = "paymentCurrency", + value = "Payment currency of the application", + required = true, + example = "$") + private String paymentCurrency; + + @ApiModelProperty(name = "tags", + value = "List of application tags") + private List tags; + + @ApiModelProperty(name = "unrestrictedRoles", + value = "List of roles that users should have to access the application") + private List unrestrictedRoles; + + public String getName() { + return name; + } + + public void setName(String name) { this.name = name; } + + public List getCategories() { return categories; } + + public void setCategories(List categories) { + this.categories = categories; + } + + public List getTags() { return tags; } + + public void setTags(List tags) { this.tags = tags; } + + public String getSubMethod() { return subMethod; } + + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } + + public String getPaymentCurrency() { return paymentCurrency; } + + public void setPaymentCurrency(String paymentCurrency) { this.paymentCurrency = paymentCurrency; } + + public List getUnrestrictedRoles() { return unrestrictedRoles; } + + public void setUnrestrictedRoles(List unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationWrapper.java new file mode 100644 index 0000000000..11ae27b7f2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationWrapper.java @@ -0,0 +1,126 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@ApiModel(value = "ApplicationWrapper", description = "ApplicationWrapper represents the an ApplicationDTO in ApplicationDTO Store") +public class ApplicationWrapper { + + + @ApiModelProperty(name = "name", + value = "Name of the application", + required = true) + @NotNull + private String name; + + @ApiModelProperty(name = "description", + value = "Description of the application", + required = true) + @NotNull + private String description; + + @ApiModelProperty(name = "categories", + value = "CategoryDTO of the application", + required = true, + example = "Educational, Gaming, Travel, Entertainment etc") + @NotNull + private List categories; + + + @ApiModelProperty(name = "subMethod", + value = "Subscription type of the application", + required = true, + example = "PAID, FREE") + @NotNull + private String subMethod; + + @ApiModelProperty(name = "paymentCurrency", + value = "Payment currency of the application", + required = true, + example = "$") + private String paymentCurrency; + + @ApiModelProperty(name = "tags", + value = "List of application tags") + @NotNull + private List tags; + + @ApiModelProperty(name = "unrestrictedRoles", + value = "List of roles that users should have to access the application") + @NotNull + private List unrestrictedRoles; + + @ApiModelProperty(name = "deviceType", + value = "Related device type of the application", + required = true, + example = "IoS, Android, Arduino, RaspberryPi etc") + @NotNull + private String deviceType; + + @ApiModelProperty(name = "entAppReleaseWrappers", + value = "List of application releases", + required = true) + @NotNull + private List entAppReleaseWrappers; + + + public String getName() { + return name; + } + + public void setName(String name) { this.name = name; } + + public List getCategories() { return categories; } + + public void setCategories(List categories) { + this.categories = categories; + } + + public List getTags() { return tags; } + + public void setTags(List tags) { this.tags = tags; } + + public String getSubMethod() { return subMethod; } + + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } + + public String getPaymentCurrency() { return paymentCurrency; } + + public void setPaymentCurrency(String paymentCurrency) { this.paymentCurrency = paymentCurrency; } + + public List getEntAppReleaseWrappers() { return entAppReleaseWrappers; } + + public void setEntAppReleaseWrappers(List entAppReleaseWrappers) { + this.entAppReleaseWrappers = entAppReleaseWrappers; } + + public List getUnrestrictedRoles() { return unrestrictedRoles; } + + public void setUnrestrictedRoles(List unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; } + + public String getDeviceType() { return deviceType; } + + public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/CustomAppReleaseWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/CustomAppReleaseWrapper.java new file mode 100644 index 0000000000..ca9a77e2cd --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/CustomAppReleaseWrapper.java @@ -0,0 +1,125 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +@ApiModel(value = "CustomAppReleaseWrapper", description = "This class holds the details when releasing an Custom app release to application store") +public class CustomAppReleaseWrapper { + + @ApiModelProperty(name = "description", + value = "Description of the application release") + @NotNull + private String description; + + @ApiModelProperty(name = "releaseType", + value = "Release type of the application release", + required = true, + example = "alpha, beta etc") + @NotNull + private String releaseType; + + @ApiModelProperty(name = "price", + value = "Price of the application release", + required = true) + @NotNull + private Double price; + + @ApiModelProperty(name = "isSharedWithAllTenants", + value = "If application release is shared with all tenants it is eqal to 1 otherwise 0", + required = true) + @NotNull + private boolean isSharedWithAllTenants; + + @ApiModelProperty(name = "metaData", + value = "Meta data of the application release", + required = true) + private String metaData; + + @ApiModelProperty(name = "version", + value = "Version of the public app release.", + required = true) + @NotNull + private String version; + + @ApiModelProperty(name = "packageName", + value = "Package name of the public app release.", + required = true) + @NotNull + private String packageName; + + public String getReleaseType() { + return releaseType; + } + + public void setReleaseType(String releaseType) { + this.releaseType = releaseType; + } + + public void setIsSharedWithAllTenants(boolean isSharedWithAllTenants) { + this.isSharedWithAllTenants = isSharedWithAllTenants; + } + + public void setMetaData(String metaData) { + this.metaData = metaData; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public boolean getIsSharedWithAllTenants() { + return isSharedWithAllTenants; + } + + public String getMetaData() { + return metaData; + } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public boolean isSharedWithAllTenants() { return isSharedWithAllTenants; } + + public void setSharedWithAllTenants(boolean sharedWithAllTenants) { + isSharedWithAllTenants = sharedWithAllTenants; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/CustomAppWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/CustomAppWrapper.java new file mode 100644 index 0000000000..ce0108bbd7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/CustomAppWrapper.java @@ -0,0 +1,123 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@ApiModel(value = "CustomAppWrapper", description = "CustomAppWrapper represents an Application used to install in IoT devices") +public class CustomAppWrapper { + + @ApiModelProperty(name = "name", + value = "Name of the application", + required = true) + @NotNull + private String name; + + @ApiModelProperty(name = "description", + value = "Description of the application", + required = true) + @NotNull + private String description; + + @ApiModelProperty(name = "categories", + value = "CategoryDTO of the application", + required = true, + example = "Educational, Gaming, Travel, Entertainment etc") + @NotNull + private List categories; + + @ApiModelProperty(name = "subMethod", + value = "Subscription type of the application", + required = true, + example = "PAID, FREE") + @NotNull + private String subMethod; + + @ApiModelProperty(name = "paymentCurrency", + value = "Payment currency of the application", + required = true, + example = "$") + private String paymentCurrency; + + @ApiModelProperty(name = "tags", + value = "List of application tags") + @NotNull + private List tags; + + @ApiModelProperty(name = "unrestrictedRoles", + value = "List of roles that users should have to access the application") + @NotNull + private List unrestrictedRoles; + + @ApiModelProperty(name = "deviceType", + value = "Related device type of the application", + required = true, + example = "IoS, Android, Arduino, RaspberryPi etc") + @NotNull + private String deviceType; + + @ApiModelProperty(name = "customAppReleaseWrappers", + value = "List of custom app releases", + required = true) + @NotNull + private List customAppReleaseWrappers; + + public String getName() { + return name; + } + + public void setName(String name) { this.name = name; } + + public List getCategories() { return categories; } + + public void setCategories(List categories) { + this.categories = categories; + } + + public List getTags() { return tags; } + + public void setTags(List tags) { this.tags = tags; } + + public String getSubMethod() { return subMethod; } + + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } + + public String getPaymentCurrency() { return paymentCurrency; } + + public void setPaymentCurrency(String paymentCurrency) { this.paymentCurrency = paymentCurrency; } + + public List getCustomAppReleaseWrappers() { return customAppReleaseWrappers; } + + public void setCustomAppReleaseWrappers(List customAppReleaseWrappers) { + this.customAppReleaseWrappers = customAppReleaseWrappers; } + + public List getUnrestrictedRoles() { return unrestrictedRoles; } + + public void setUnrestrictedRoles(List unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; } + + public String getDeviceType() { return deviceType; } + + public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/EntAppReleaseWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/EntAppReleaseWrapper.java new file mode 100644 index 0000000000..5a8bcce737 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/EntAppReleaseWrapper.java @@ -0,0 +1,102 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +@ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store") +public class EntAppReleaseWrapper { + + @ApiModelProperty(name = "description", + value = "Description of the application release") + @NotNull + private String description; + + @ApiModelProperty(name = "releaseType", + value = "Release type of the application release", + required = true, + example = "alpha, beta etc") + @NotNull + private String releaseType; + + @ApiModelProperty(name = "price", + value = "Price of the application release", + required = true) + @NotNull + private Double price; + + @ApiModelProperty(name = "isSharedWithAllTenants", + value = "If application release is shared with all tenants it is eqal to 1 otherwise 0", + required = true) + @NotNull + private boolean isSharedWithAllTenants; + + @ApiModelProperty(name = "metaData", + value = "Meta data of the application release", + required = true) + private String metaData; + + @ApiModelProperty(name = "supportedOsVersions", + value = "Application release supported OS versions", + required = true, + example = "4.0-10.0") + @NotNull + private String supportedOsVersions; + + public String getReleaseType() { + return releaseType; + } + + public void setReleaseType(String releaseType) { + this.releaseType = releaseType; + } + + public void setIsSharedWithAllTenants(boolean isSharedWithAllTenants) { + this.isSharedWithAllTenants = isSharedWithAllTenants; + } + + public void setMetaData(String metaData) { + this.metaData = metaData; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public boolean getIsSharedWithAllTenants() { + return isSharedWithAllTenants; + } + + public String getMetaData() { + return metaData; + } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public String getSupportedOsVersions() { return supportedOsVersions; } + + public void setSupportedOsVersions(String supportedOsVersions) { this.supportedOsVersions = supportedOsVersions; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/PublicAppReleaseWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/PublicAppReleaseWrapper.java new file mode 100644 index 0000000000..badbdf30d5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/PublicAppReleaseWrapper.java @@ -0,0 +1,126 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +@ApiModel(value = "Public App Release Wrapper", description = "This class holds the details when releasing an Public App" + + " Release to application store") +public class PublicAppReleaseWrapper { + + @ApiModelProperty(name = "description", + value = "Description of the public app release") + @NotNull + private String description; + + @ApiModelProperty(name = "releaseType", + value = "Release type of the public app release", + required = true, + example = "alpha, beta etc") + @NotNull + private String releaseType; + + @ApiModelProperty(name = "price", + value = "Price of the public app release", + required = true) + private Double price; + + @ApiModelProperty(name = "isSharedWithAllTenants", + value = "If public app release is shared with all tenants it is equal to 1 otherwise 0", + required = true) + @NotNull + private boolean isSharedWithAllTenants; + + @ApiModelProperty(name = "metaData", + value = "Meta data of the public app release", + required = true) + private String metaData; + + @ApiModelProperty(name = "version", + value = "Version of the public app release.", + required = true) + @NotNull + private String version; + + @ApiModelProperty(name = "packageName", + value = "Package name of the public app release.", + required = true) + @NotNull + private String packageName; + + @ApiModelProperty(name = "supportedOsVersions", + value = "Application release supported OS versions", + required = true, + example = "4.0-10.0") + @NotNull + private String supportedOsVersions; + + public String getReleaseType() { + return releaseType; + } + + public void setReleaseType(String releaseType) { + this.releaseType = releaseType; + } + + public void setIsSharedWithAllTenants(boolean isSharedWithAllTenants) { + this.isSharedWithAllTenants = isSharedWithAllTenants; + } + + public void setMetaData(String metaData) { + this.metaData = metaData; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public boolean getIsSharedWithAllTenants() { + return isSharedWithAllTenants; + } + + public String getMetaData() { + return metaData; + } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public boolean isSharedWithAllTenants() { return isSharedWithAllTenants; } + + public void setSharedWithAllTenants(boolean sharedWithAllTenants) { isSharedWithAllTenants = sharedWithAllTenants; } + + public String getVersion() { return version; } + + public void setVersion(String version) { this.version = version; } + + public String getPackageName() { return packageName; } + + public void setPackageName(String packageName) { this.packageName = packageName; } + + public String getSupportedOsVersions() { return supportedOsVersions; } + + public void setSupportedOsVersions(String supportedOsVersions) { this.supportedOsVersions = supportedOsVersions; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/PublicAppWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/PublicAppWrapper.java new file mode 100644 index 0000000000..beb66706fd --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/PublicAppWrapper.java @@ -0,0 +1,121 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@ApiModel(value = "PublicAppWrapper", description = "PublicAppWrapper represents an Application in App Store") +public class PublicAppWrapper { + + @ApiModelProperty(name = "name", + value = "Name of the public app", + required = true) + @NotNull + private String name; + + @ApiModelProperty(name = "description", + value = "Description of the public app", + required = true) + @NotNull + private String description; + + @ApiModelProperty(name = "categories", + value = "List of Categories", + required = true, + example = "Educational, Gaming, Travel, Entertainment etc") + @NotNull + private List categories; + + @ApiModelProperty(name = "subType", + value = "Subscription method of the public app", + required = true, + example = "PAID, FREE") + @NotNull + private String subMethod; + + @ApiModelProperty(name = "deviceType", + value = "Related device type of the public app", + required = true, + example = "IoS, Android, Arduino, RaspberryPi etc") + @NotNull + private String deviceType; + + @ApiModelProperty(name = "paymentCurrency", + value = "Payment currency of the web clip", + required = true, + example = "$") + private String paymentCurrency; + + @ApiModelProperty(name = "tags", + value = "List of tags") + @NotNull + private List tags; + + @ApiModelProperty(name = "unrestrictedRoles", + value = "List of roles that users should have to view the public app") + @NotNull + private List unrestrictedRoles; + + @ApiModelProperty(name = "applicationReleaseWrappers", + value = "List of public app releases", + required = true) + @NotNull + private List publicAppReleaseWrappers; + + public String getName() { + return name; + } + + public void setName(String name) { this.name = name; } + + public List getTags() { return tags; } + + public void setTags(List tags) { this.tags = tags; } + + public String getDeviceType() { return deviceType; } + + public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public String getPaymentCurrency() { return paymentCurrency; } + + public void setPaymentCurrency(String paymentCurrency) { this.paymentCurrency = paymentCurrency; } + + public List getUnrestrictedRoles() { return unrestrictedRoles; } + + public void setUnrestrictedRoles(List unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public List getPublicAppReleaseWrappers() { return publicAppReleaseWrappers; } + + public void setPublicAppReleaseWrappers(List publicAppReleaseWrappers) { + this.publicAppReleaseWrappers = publicAppReleaseWrappers; } + + public List getCategories() { return categories; } + + public void setCategories(List categories) { this.categories = categories; } + + public String getSubMethod() { return subMethod; } + + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ReviewWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ReviewWrapper.java new file mode 100644 index 0000000000..120df8cc1b --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ReviewWrapper.java @@ -0,0 +1,39 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.common.wrapper; + +public class ReviewWrapper { + private String content; + private int rating; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public int getRating() { + return rating; + } + + public void setRating(int rating) { + this.rating = rating; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebAppReleaseWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebAppReleaseWrapper.java new file mode 100644 index 0000000000..02435bcc8e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebAppReleaseWrapper.java @@ -0,0 +1,117 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +@ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store") +public class WebAppReleaseWrapper { + + @ApiModelProperty(name = "description", + value = "Description of the web clip release") + @NotNull + private String description; + + @ApiModelProperty(name = "releaseType", + value = "Release type of the web clip release", + required = true, + example = "alpha, beta etc") + @NotNull + private String releaseType; + + @ApiModelProperty(name = "price", + value = "Price of the web clip release", + required = true) + private Double price; + + @ApiModelProperty(name = "isSharedWithAllTenants", + value = "If web clip release is shared with all tenants it is equal to 1 otherwise 0", + required = true) + @NotNull + private boolean isSharedWithAllTenants; + + @ApiModelProperty(name = "metaData", + value = "Meta data of the web clip release", + required = true) + private String metaData; + + @ApiModelProperty(name = "version", + value = "Version of the web app release.", + required = true) + @NotNull + private String version; + + @ApiModelProperty(name = "url", + value = "URL which is used for WEB-CLIP") + @NotNull + private String url; + + public String getReleaseType() { + return releaseType; + } + + public void setReleaseType(String releaseType) { + this.releaseType = releaseType; + } + + public void setIsSharedWithAllTenants(boolean isSharedWithAllTenants) { + this.isSharedWithAllTenants = isSharedWithAllTenants; + } + + public void setMetaData(String metaData) { + this.metaData = metaData; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public boolean getIsSharedWithAllTenants() { + return isSharedWithAllTenants; + } + + public String getMetaData() { + return metaData; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public boolean isSharedWithAllTenants() { return isSharedWithAllTenants; } + + public void setSharedWithAllTenants(boolean sharedWithAllTenants) { isSharedWithAllTenants = sharedWithAllTenants; } + + public String getVersion() { return version; } + + public void setVersion(String version) { this.version = version; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebAppWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebAppWrapper.java new file mode 100644 index 0000000000..1c5bba1d20 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebAppWrapper.java @@ -0,0 +1,121 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@ApiModel(value = "WebAppWrapper", description = "WebAppWrapper represents an ApplicationDTO in ApplicationDTO Store") +public class WebAppWrapper { + + @ApiModelProperty(name = "name", + value = "Name of the web clip", + required = true) + @NotNull + private String name; + + @ApiModelProperty(name = "description", + value = "Description of the web clip", + required = true) + @NotNull + private String description; + + @ApiModelProperty(name = "categories", + value = "List of Categories", + required = true, + example = "Educational, Gaming, Travel, Entertainment etc") + @NotNull + private List categories; + + @ApiModelProperty(name = "subType", + value = "Subscription method of the web clip", + required = true, + example = "PAID, FREE") + @NotNull + private String subMethod; + + @ApiModelProperty(name = "Web App Type", + value = "Type of the web app", + required = true, + example = "WEB_APP, WEB_CLIP") + @NotNull + private String type; + + @ApiModelProperty(name = "paymentCurrency", + value = "Payment currency of the web clip", + required = true, + example = "$") + private String paymentCurrency; + + @ApiModelProperty(name = "tags", + value = "List of tags") + @NotNull + private List tags; + + @ApiModelProperty(name = "unrestrictedRoles", + value = "List of roles that users should have to view the web clip") + @NotNull + private List unrestrictedRoles; + + @ApiModelProperty(name = "applicationReleaseWrappers", + value = "List of web clip releases", + required = true) + @NotNull + private List webAppReleaseWrappers; + + public String getName() { + return name; + } + + public void setName(String name) { this.name = name; } + + public List getTags() { return tags; } + + public void setTags(List tags) { this.tags = tags; } + + public String getPaymentCurrency() { return paymentCurrency; } + + public void setPaymentCurrency(String paymentCurrency) { this.paymentCurrency = paymentCurrency; } + + public List getUnrestrictedRoles() { return unrestrictedRoles; } + + public void setUnrestrictedRoles(List unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public List getWebAppReleaseWrappers() { return webAppReleaseWrappers; } + + public void setWebAppReleaseWrappers(List webAppReleaseWrappers) { + this.webAppReleaseWrappers = webAppReleaseWrappers; } + + public List getCategories() { return categories; } + + public void setCategories(List categories) { this.categories = categories; } + + public String getSubMethod() { return subMethod; } + + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } + + public String getType() { return type; } + + public void setType(String type) { this.type = type; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/pom.xml new file mode 100644 index 0000000000..b2940d4d00 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/pom.xml @@ -0,0 +1,254 @@ + + + + + + org.wso2.carbon.devicemgt + application-mgt + 4.0.0-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.application.mgt.core + 4.0.0-SNAPSHOT + bundle + WSO2 Carbon - Application Management Core + WSO2 Carbon - Application Management Core + https://entgra.io + + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + ${carbon.device.mgt.version} + Application Management Core Bundle + org.wso2.carbon.device.application.mgt.core.internal + + org.osgi.framework, + org.osgi.service.component, + org.apache.commons.logging, + javax.xml.parsers;version="${javax.xml.parsers.import.pkg.version}";resolution:=optional, + org.wso2.carbon.context.*, + org.wso2.carbon.utils.*, + org.w3c.dom, + org.json, + javax.sql, + com.google.gson.*, + javax.naming, + javax.xml.bind.annotation, + javax.xml.bind, + org.wso2.carbon.device.application.mgt.common.*, + org.wso2.carbon.device.mgt.core.*, + org.wso2.carbon.device.mgt.common.*, + org.wso2.carbon.user.core.*, + org.wso2.carbon.user.api.*, + org.wso2.carbon.ntask.*, + org.quartz.*, + org.wso2.carbon.ndatasource.core, + org.wso2.carbon, + org.xml.sax, + org.xml.sax.helpers, + org.apache.commons.io, + org.apache.commons.codec.binary;version="${commons-codec.wso2.osgi.version.range}", + org.apache.commons.codec.digest;version="${commons-codec.wso2.osgi.version.range}", + org.wso2.carbon.base, + com.dd.*, + org.wso2.carbon.identity.jwt.client.extension.*, + org.wso2.carbon.apimgt.application.extension.*, + org.apache.commons.httpclient, + org.apache.commons.httpclient.methods, + org.apache.commons.validator.routines + + apk-parser;scope=compile|runtime;inline=false + + + + !org.wso2.carbon.device.application.mgt.core.internal.*, + org.wso2.carbon.device.application.mgt.core.* + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.18 + + + src/test/resources/testng.xml + + + ${basedir}/target/coverage-reports/jacoco-unit.exec + file:src/test/resources/log4j.properties + + + + + + + + + org.eclipse.osgi + org.eclipse.osgi + + + org.eclipse.osgi + org.eclipse.osgi.services + + + org.eclipse.equinox + org.eclipse.equinox.common + + + org.testng + testng + + + junit + junit + test + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.wso2.carbon + org.wso2.carbon.utils + + + commons-codec.wso2 + commons-codec + + + commons-io.wso2 + commons-io + + + org.slf4j + slf4j-simple + test + + + org.json.wso2 + json + + + com.google.code.gson + gson + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.application.mgt.common + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.wso2.carbon + org.wso2.carbon.user.core + + + org.wso2.carbon + org.wso2.carbon.ndatasource.core + + + org.wso2.carbon + org.wso2.carbon.core + + + + com.googlecode.plist + dd-plist + + + net.dongliu + apk-parser + + + commons-validator + commons-validator + 1.6 + + + org.apache.cxf + cxf-rt-frontend-jaxrs + provided + + + cglib + cglib-nodep + 3.2.7 + compile + + + + org.apache.tomcat.wso2 + jdbc-pool + + + + mysql + mysql-connector-java + 5.1.34 + test + + + com.h2database.wso2 + h2-database-engine + test + + + commons-dbcp.wso2 + commons-dbcp + 1.4.0.wso2v1 + test + + + + commons-pool.wso2 + commons-pool + 1.5.6.wso2v1 + test + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.application.extension + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Artifacts.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Artifacts.java new file mode 100644 index 0000000000..2c2e6cf25e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Artifacts.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * This represents Artifacts element in application-mgt configuration file. + */ +@XmlRootElement(name = "Artifacts") +public class Artifacts { + private String imageLocation; + private String binaryLocation; + + @XmlElement(name = "ImageLocation", required = true) + public String getImageLocation() { + return imageLocation; + } + + public void setImageLocation(String imageLocation) { + this.imageLocation = imageLocation; + } + + @XmlElement(name = "BinaryLocation", required = true) + public String getBinaryLocation() { + return binaryLocation; + } + + public void setBinaryLocation(String binaryLocation) { + this.binaryLocation = binaryLocation; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Configuration.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Configuration.java new file mode 100644 index 0000000000..2aedcc3e66 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Configuration.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.config; + +import org.wso2.carbon.device.application.mgt.common.config.MDMConfig; +import org.wso2.carbon.device.application.mgt.common.config.RatingConfiguration; +import org.wso2.carbon.device.application.mgt.common.config.UIConfiguration; +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; + +import java.util.List; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * Represents the Application Management Configuration. + */ +@XmlRootElement(name = "ApplicationManagementConfiguration") +public class Configuration { + + private String datasourceName; + + private List extensions; + + private List lifecycleStates; + + private UIConfiguration uiConfiguration; + + private List appCategories; + + private RatingConfiguration ratingConfiguration; + + private MDMConfig mdmConfig; + + @XmlElement(name = "DatasourceName", required = true) + public String getDatasourceName() { + return datasourceName; + } + + public void setDatasourceName(String datasourceName) { + this.datasourceName = datasourceName; + } + + @XmlElementWrapper(name = "Extensions") + @XmlElement(name = "Extension") + public List getExtensions() { + return extensions; + } + + public void setExtensions(List extensions) { + this.extensions = extensions; + } + + @XmlElementWrapper(name = "LifecycleStates") + @XmlElement(name = "LifecycleState") + public List getLifecycleStates() { + return lifecycleStates; + } + + public void setLifecycleStates(List lifecycleStates) { + this.lifecycleStates = lifecycleStates; + } + + @XmlElement(name = "UIConfigs") + public UIConfiguration getUiConfiguration() { + return uiConfiguration; + } + + public void setUiConfiguration(UIConfiguration uiConfiguration) { + this.uiConfiguration = uiConfiguration; + } + + @XmlElement(name = "RatingConfig") + public RatingConfiguration getRatingConfiguration() { return ratingConfiguration; } + + public void setRatingConfiguration( + RatingConfiguration ratingConfiguration) { this.ratingConfiguration = ratingConfiguration; } + + @XmlElementWrapper(name = "AppCategories") + @XmlElement(name = "Category") + public List getAppCategories() { + return appCategories; + } + + public void setAppCategories(List appCategories) { + this.appCategories = appCategories; + } + + @XmlElement(name = "MDMConfig", required = true) + public MDMConfig getMdmConfig() { return mdmConfig; } + + public void setMdmConfig(MDMConfig mdmConfig) { + this.mdmConfig = mdmConfig; + } +} + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/ConfigurationManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/ConfigurationManager.java new file mode 100644 index 0000000000..17ff4410f2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/ConfigurationManager.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.config; + +import 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.exception.InvalidConfigurationException; +import org.wso2.carbon.device.application.mgt.core.util.Constants; + +import java.io.File; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; + +/** + * ConfigurationManager is responsible for the managing Application Management related configurations. + */ +public class ConfigurationManager { + + private static final Log log = LogFactory.getLog(ConfigurationManager.class); + + private Configuration configuration; + + private static String configPath; + + private static ConfigurationManager configurationManager; + + private ConfigurationManager() { + + } + + public static ConfigurationManager getInstance() { + if (configurationManager == null) { + synchronized (ConfigurationManager.class) { + if (configurationManager == null) { + configurationManager = new ConfigurationManager(); + try { + configurationManager.initConfig(); + } catch (ApplicationManagementException e) { + log.error(e); + } + } + } + } + return configurationManager; + } + + public static synchronized void setConfigLocation(String configPath) throws InvalidConfigurationException { + if (ConfigurationManager.configPath == null) { + ConfigurationManager.configPath = configPath; + } else { + throw new InvalidConfigurationException("Configuration path " + configPath + " is already defined"); + } + } + + private void initConfig() throws ApplicationManagementException { + try { + JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + if (configPath == null) { + configPath = Constants.DEFAULT_CONFIG_FILE_LOCATION; + } + //TODO: Add validation for the configurations + this.configuration = (Configuration) unmarshaller.unmarshal(new File(configPath)); + } catch (Exception e) { + log.error(e); + throw new InvalidConfigurationException("Error occurred while initializing application config: " + + configPath, e); + } + } + + public Configuration getConfiguration() { + return configuration; + } + + public Extension getExtension(Extension.Name extName) throws InvalidConfigurationException { + for (Extension extension : configuration.getExtensions()) { + if (extension.getName().contentEquals(extName.toString())) { + return extension; + } + } + throw new InvalidConfigurationException("Expecting an extension with name - " + extName + " , but not found!"); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Extension.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Extension.java new file mode 100644 index 0000000000..17c9f3f63d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Extension.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.config; + +import java.util.List; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * Represents a extension in the application management configuration. + */ +@XmlRootElement(name = "Extension") +public class Extension { + + private String name; + + private String className; + + private List parameters; + + @XmlAttribute(name = "name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @XmlElement(name = "ClassName") + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + @XmlElementWrapper(name = "Parameters") + @XmlElement(name = "Parameter") + public List getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + + public boolean equals(Object anotherObj) { + if (anotherObj instanceof Extension) { + Extension anExt = (Extension) anotherObj; + if (anExt.getName().contentEquals(this.getName())) { + return true; + } + } + return false; + } + + /** + * ApplicationManagement Extensions. + */ + public enum Name { + ApplicationManager, + ApplicationReleaseManager, + CategoryManager, + ReviewManager, + LifecycleStateManager, + PlatformManager, + VisibilityTypeManager, + SubscriptionManager, + VisibilityManager, + ApplicationStorageManager, + PlatformStorageManager + } +} + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/PaginationConfiguration.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/PaginationConfiguration.java new file mode 100644 index 0000000000..0ca3d0e343 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/PaginationConfiguration.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * This class represents the information related to Pagination configuration. + */ +@XmlRootElement(name = "PaginationConfiguration") public class PaginationConfiguration { + + private int commentListPageSize; + + public int getCommentListPageSize() { + return commentListPageSize; + } + + @XmlElement(name = "commentListPageSize", required = true) public void setCommentListPageSize( + int commentListPageSize) { + this.commentListPageSize = commentListPageSize; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Parameter.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Parameter.java new file mode 100644 index 0000000000..a8e3d1dbc5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/config/Parameter.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.config; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlValue; + +/** + * Parameter of the extensions. + */ +@XmlRootElement(name = "Parameter") +public class Parameter { + + private String name; + + private String value; + + @XmlAttribute(name = "name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @XmlValue + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java new file mode 100644 index 0000000000..2fc936d4a2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao; + +import org.wso2.carbon.device.application.mgt.common.*; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.dto.CategoryDTO; +import org.wso2.carbon.device.application.mgt.common.dto.TagDTO; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.util.List; + +/** + * ApplicationDAO is responsible for handling all the Database related operations related with Application Management. + */ +public interface ApplicationDAO { + + /** + * Use to create an application for given application data and tenant. + * + * @param applicationDTO ApplicationDTO that need to be created. + * @return Primary key of the created application. + * @throws ApplicationManagementDAOException if error occurred wile executing query to inser app data into database. + */ + int createApplication(ApplicationDTO applicationDTO, int tenantId) throws ApplicationManagementDAOException; + + /** + * To add tags for a particular application. + * + * @param tags tags that need to be added for a application. + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + void addTags(List tags, int tenantId) throws ApplicationManagementDAOException; + + List getAllTags(int tenantId) throws ApplicationManagementDAOException; + + List getTagIdsForTagNames (List tagNames, int tenantId) throws ApplicationManagementDAOException; + + TagDTO getTagForTagName(String tagName, int tenantId) throws ApplicationManagementDAOException; + + List getDistinctTagIdsInTagMapping() throws ApplicationManagementDAOException; + + void addTagMapping (List tagIds, int applicationId, int tenantId) throws ApplicationManagementDAOException; + + List getAppTags(int appId, int tenantId) throws ApplicationManagementDAOException; + + boolean hasTagMapping(int tagId, int appId, int tenantId) throws ApplicationManagementDAOException; + + boolean hasTagMapping(int tagId, int tenantId) throws ApplicationManagementDAOException; + + void deleteApplicationTags(List tagIds, int applicationId, int tenantId) throws ApplicationManagementDAOException; + + void deleteApplicationTag(Integer tagId, int applicationId, int tenantId) throws ApplicationManagementDAOException; + + void deleteApplicationTags(int applicationId, int tenantId) throws ApplicationManagementDAOException; + + void deleteTagMapping(int tagId, int tenantId) throws ApplicationManagementDAOException; + + void deleteTag(int tagId, int tenantId) throws ApplicationManagementDAOException; + + void updateTag(TagDTO tagDTO, int tenantId) throws ApplicationManagementDAOException; + + List getAppCategories (int appId, int tenantId) throws ApplicationManagementDAOException; + + boolean hasCategoryMapping(int categoryId, int tenantId) throws ApplicationManagementDAOException; + + List getAllCategories(int tenantId) throws ApplicationManagementDAOException; + + List getCategoryIdsForCategoryNames(List categoryNames, int tenantId) + throws ApplicationManagementDAOException; + + List getDistinctCategoryIdsInCategoryMapping() throws ApplicationManagementDAOException; + + CategoryDTO getCategoryForCategoryName(String categoryName, int tenantId) throws ApplicationManagementDAOException; + + void addCategories(List categories, int tenantId) throws ApplicationManagementDAOException; + + void addCategoryMapping(List categoryIds, int applicationId, int tenantId) + throws ApplicationManagementDAOException; + + void deleteAppCategories(int applicationId, int tenantId) throws ApplicationManagementDAOException; + + void deleteAppCategories(List categoryIds, int applicationId, int tenantId) + throws ApplicationManagementDAOException; + + void deleteCategory(int categoryId, int tenantId) throws ApplicationManagementDAOException; + + void updateCategory(CategoryDTO categoryDTO, int tenantId) throws ApplicationManagementDAOException; + + /** + * To get the applications that satisfy the given criteria. + * + * @param filter Filter criteria. + * @param deviceTypeId ID of the device type + * @param tenantId Id of the tenant. + * @return ApplicationDTO list + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + List getApplications(Filter filter, int deviceTypeId, int tenantId) throws ApplicationManagementDAOException; + + /** + * To get the application with the given id + * + * @param applicationId Id of the application to be retrieved. + * @param tenantId ID of the tenant. + * @return the application + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + ApplicationDTO getApplication(int applicationId, int tenantId) throws ApplicationManagementDAOException; + + /** + * To get the application with the given uuid + * + * @param releaseUuid UUID of the application release. + * @param tenantId ID of the tenant. + * @return the application + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + ApplicationDTO getApplication(String releaseUuid, int tenantId) throws ApplicationManagementDAOException; + + ApplicationDTO getAppWithRelatedRelease(String releaseUuid, int tenantId) throws ApplicationManagementDAOException; + + /** + * Verify whether application exist for given application name and device type. Because a name and device type is + * unique for an application. + * + * @param appName name of the application. + * @param deviceTypeId ID of the device type. + * @param tenantId ID of the tenant. + * @return ID of the ApplicationDTO. + * @throws ApplicationManagementDAOException Application Management DAO Exception. + */ + boolean isExistingAppName(String appName, int deviceTypeId, int tenantId) throws ApplicationManagementDAOException; + + /** + * To edit the given application. + * + * @param application ApplicationDTO that need to be edited. + * @param tenantId Tenant ID of the ApplicationDTO. + * @return Updated ApplicationDTO. + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + boolean updateApplication(ApplicationDTO application, int tenantId) throws ApplicationManagementDAOException; + + void updateApplicationRating(String uuid, double rating, int tenantId) throws ApplicationManagementDAOException; + + + /** + * To delete the application + * + * @param appId ID of the application. + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + void retireApplication(int appId) throws ApplicationManagementDAOException; + + /** + * To get the application count that satisfies gives search query. + * + * @param filter ApplicationDTO Filter. + * @param tenantId Id of the tenant + * @return count of the applications + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + int getApplicationCount(Filter filter, int deviceTypeId, int tenantId) throws ApplicationManagementDAOException; + + void deleteApplication(int appId, int tenantId) throws ApplicationManagementDAOException; + +} + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java new file mode 100644 index 0000000000..ad5d0c4006 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao; + +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.Rating; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.util.List; + +/** + * This is responsible for ApplicationDTO Release related DAO operations. + */ +public interface ApplicationReleaseDAO { + + /** + * To create an ApplicationDTO release. + * + * @param applicationRelease ApplicationDTO Release that need to be created. + * @return Unique ID of the relevant release. + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + ApplicationReleaseDTO createRelease(ApplicationReleaseDTO applicationRelease, int appId, int tenantId) throws + ApplicationManagementDAOException; + + /** + * To update an ApplicationDTO release. + * + * @param applicationRelease ApplicationReleaseDTO that need to be updated. + * @param tenantId Id of the tenant + * @return the updated ApplicationDTO Release + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception + */ + ApplicationReleaseDTO updateRelease(ApplicationReleaseDTO applicationRelease, int tenantId) + throws ApplicationManagementDAOException; + + /** + * To update an ApplicationDTO release. + * @param uuid UUID of the ApplicationReleaseDTO that need to be updated. + * @param rating given stars for the application. + * @param ratedUsers number of users who has rated for the application release. + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception + */ + void updateRatingValue(String uuid, double rating, int ratedUsers) throws ApplicationManagementDAOException; + + /** + * To retrieve rating of an application release. + * + * @param uuid UUID of the application Release. + * @param tenantId Tenant Id + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + Rating getReleaseRating(String uuid, int tenantId) throws ApplicationManagementDAOException; + + List getReleaseRatings(String uuid, int tenantId) throws ApplicationManagementDAOException; + + /** + * To delete a particular release. + * + * @param id ID of the ApplicationDTO which the release need to be deleted. + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + void deleteRelease(int id) throws ApplicationManagementDAOException; + + void deleteReleases(List applicationReleaseIds) throws ApplicationManagementDAOException; + + ApplicationReleaseDTO getReleaseByUUID(String uuid, int tenantId) throws ApplicationManagementDAOException; + + /** + * To verify whether application release exist or not for the given app release version. + * + * @param hashVal Hash value of the application release. + * @param tenantId Tenant Id + * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. + */ + boolean verifyReleaseExistenceByHash(String hashVal, int tenantId) + throws ApplicationManagementDAOException; + + /** + * To verify whether application release exist or not for the given app release version. + * + * @param releaseUuid ID of the application. + * @param tenantId Tenant Id + * @throws ApplicationManagementDAOException Application Management DAO Exception. + */ + String getPackageName(String releaseUuid, int tenantId) throws ApplicationManagementDAOException; + + + String getReleaseHashValue(String uuid, int tenantId) throws ApplicationManagementDAOException; + + /*** + * + * @param packageName Application release package name + * @param tenantId Tenant ID + * @return True if application release package name already exist in the IoT server, Otherwise returns False. + * @throws ApplicationManagementDAOException Application Management DAO Exception. + */ + boolean isActiveReleaseExisitForPackageName(String packageName, int tenantId, String inactiveState) + throws ApplicationManagementDAOException; + + boolean hasExistInstallableAppRelease(String releaseUuid, String installableStateName, int tenantId) + throws ApplicationManagementDAOException; + + List getReleaseByPackages(List packages, int tenantId) + throws ApplicationManagementDAOException; + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/LifecycleStateDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/LifecycleStateDAO.java new file mode 100644 index 0000000000..dd4e2575c9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/LifecycleStateDAO.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao; + +import org.wso2.carbon.device.application.mgt.common.LifecycleState; +import org.wso2.carbon.device.application.mgt.core.exception.LifeCycleManagementDAOException; + +import java.util.List; + +/** + * This is responsible for all the DAO operations related to Lifecycle state. + */ +public interface LifecycleStateDAO { + + /** + * To get the latest lifecycle state for the given application id and the application release UUID. + * @param uuid UUID of the application release + * + * @return Latest Lifecycle State for the given application release + * @throws LifeCycleManagementDAOException Lifecycle Management DAO Exception. + */ + LifecycleState getLatestLifecycleState(String uuid) throws LifeCycleManagementDAOException; + + /** + * To get all changed lifecycle states for the given application release id. + * @param appReleaseId id of the application release. + * @param tenantId Tenant Id. + * + * @return Lifecycle States for the given application release + * @throws LifeCycleManagementDAOException Lifecycle Management DAO Exception. + */ + List getLifecycleStates(int appReleaseId, int tenantId) throws LifeCycleManagementDAOException; + + /** + * To add new lifecycle states for the given application release. + * @param state LifecycleState. + * @param tenantId Tenant id + * + * @throws LifeCycleManagementDAOException Lifecycle Management DAO Exception. + */ + void addLifecycleState(LifecycleState state, int appReleaseId, int tenantId) throws LifeCycleManagementDAOException; + + /** + * To delete lifecycle state data of specific application release. + * @param releaseId Id of the LifecycleState. + * + * @throws LifeCycleManagementDAOException Lifecycle Management DAO Exception. + */ + void deleteLifecycleStateByReleaseId(int releaseId) throws LifeCycleManagementDAOException; + + void deleteLifecycleStates(List appReleaseIds) throws LifeCycleManagementDAOException; + + + /*** + * + * @param appId ID of the application + * @param uuid UUID of the application release + * @return Username of the application release creator + * @throws LifeCycleManagementDAOException {@link LifeCycleManagementDAOException} + */ + String getAppReleaseCreatedUsername(int appId, String uuid, int tenantId) throws LifeCycleManagementDAOException; + + } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ReviewDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ReviewDAO.java new file mode 100644 index 0000000000..ff2cf5d164 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ReviewDAO.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao; + +import org.wso2.carbon.device.application.mgt.common.response.Review; +import org.wso2.carbon.device.application.mgt.common.PaginationRequest; +import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO; +import org.wso2.carbon.device.application.mgt.core.exception.ReviewManagementDAOException; + +import java.util.List; + +/** + * This interface specifies the database access operations performed for reviews. + */ + + public interface ReviewDAO { + + /** + * To add a reviewTmp to an application release. + * + * @param tenantId tenantId. + * @param reviewDTO reviewTmp of the application. + * @param appReleaseId UUID of the application release + * @return If reviewTmp is added successfully, it return true otherwise false + * @throws ReviewManagementDAOException Exceptions of the reviewTmp management DAO. + */ + int addReview(ReviewDTO reviewDTO, int appReleaseId, int tenantId) throws ReviewManagementDAOException; + + /** + * To verify whether user has already commented for the application release or not. + * + * @param appReleaseIds List of the application release IDs. + * @param username username of the logged in user. + * @param tenantId tenantId of the commented application. + * @return If review exists, review returns + * @throws ReviewManagementDAOException Exceptions of the review management DAO. + */ + boolean hasUerReviewedApp(List appReleaseIds, String username, int tenantId) throws ReviewManagementDAOException; + + /** + * To update already added comment. + * + * @param reviewDTO Updating reviewTmp + * @param reviewId id of the updating reviewTmp + * @param tenantId tenant id + * @return row count if updating is succeed otherwise 0 + * @throws ReviewManagementDAOException Exceptions of the reviewTmp management. + */ + ReviewDTO updateReview(ReviewDTO reviewDTO, int reviewId, boolean isActiveReview, int tenantId) + throws ReviewManagementDAOException; + + + /** + * To get the comment with id. + * + * @param reviewId id of the review + * @return {@link Review} + * @throws ReviewManagementDAOException Exceptions of the review management DAO. + */ + ReviewDTO getReview(int reviewId, int tenantId) throws ReviewManagementDAOException; + + + /** + * To get all reviews + * + * @param releaseId ID of the application release. + * @param request {@link PaginationRequest}pagination request with offSet and limit + * @param tenantId Tenant id + * @return {@link List}List of all reviews for the application release + * @throws ReviewManagementDAOException Review management DAO exception + **/ + List getAllReleaseReviews(int releaseId, PaginationRequest request, int tenantId) + throws ReviewManagementDAOException; + + List getAllActiveAppReviews(List releaseIds, PaginationRequest request, int tenantId) + throws ReviewManagementDAOException; + + List getAllActiveAppReviewsOfUser(List releaseIds, PaginationRequest request, String username, + int tenantId) throws ReviewManagementDAOException; + + List getReplyComments(int parentId, int tenantId) + throws ReviewManagementDAOException; + + /** + * To get list of comments using release id and application id. + * @param uuid UUID of the application release + * @param tenantId tenant id + * @return {@link List}List of comments + * @throws ReviewManagementDAOException Exceptions of the review management DAO. + */ + List getAllAppReleaseRatingValues(String uuid, int tenantId) throws ReviewManagementDAOException; + + List getAllAppRatingValues(List uuids, int tenantId) throws ReviewManagementDAOException; + + /** + * To delete review using review id and uuid of the application release. + * + * @param reviewId id of the review + * @throws ReviewManagementDAOException Review management DAO exception. + */ + void deleteReview(int reviewId, int tenantId) throws ReviewManagementDAOException; + + void deleteReviews(List reviewIds, int tenantId) throws ReviewManagementDAOException; + + void deleteAllChildCommentsOfReview(int rootParentId, int tenantId) throws ReviewManagementDAOException; + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java new file mode 100644 index 0000000000..5b7f9a00cb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/SubscriptionDAO.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao; + +import org.wso2.carbon.device.application.mgt.common.ExecutionStatus; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * This interface provides the list of operations that are supported with subscription database. + * + */ +public interface SubscriptionDAO { + + void addDeviceSubscription(String subscribedBy, List deviceIds, String subscribedFrom, + String installStatus, int releaseId, int tenantId ) throws ApplicationManagementDAOException; + + void updateDeviceSubscription(String updateBy, List deviceIds, String action, String actionTriggeredFrom, + String installStatus, int releaseId, int tenantId) throws ApplicationManagementDAOException; + + void addOperationMapping (int operationId, List deviceSubscriptionId, int tenantId) throws ApplicationManagementDAOException; + + /** + * Adds a mapping between user and the application which the application is installed on. This mapping will be + * added when an enterprise installation triggered to the user. + * + * @param tenantId id of the tenant + * @param subscribedBy username of the user who subscribe the application + * @param users list of user names of the users whose devices are subscribed to the application + * @param releaseId id of the {@link ApplicationReleaseDTO} + * @throws ApplicationManagementDAOException If unable to add a mapping between device and application + */ + void addUserSubscriptions(int tenantId, String subscribedBy, List users, int releaseId) + throws ApplicationManagementDAOException; + + void addRoleSubscriptions(int tenantId, String subscribedBy, List roles, int releaseId) + throws ApplicationManagementDAOException; + + void addGroupSubscriptions(int tenantId, String subscribedBy, List groups, int releaseId) + throws ApplicationManagementDAOException; + + List getDeviceSubscriptions(int appReleaseId, int tenantId) throws + ApplicationManagementDAOException; + + Map getDeviceSubscriptions(List deviceIds, int appReleaseId, int tenantId) + throws ApplicationManagementDAOException; + + List getAppSubscribedUserNames(List users, int appReleaseId, int tenantId) throws + ApplicationManagementDAOException; + + List getAppSubscribedRoleNames(List roles, int appReleaseId, int tenantId) throws + ApplicationManagementDAOException; + + List getAppSubscribedGroupNames(List groups, int appReleaseId, int tenantId) throws + ApplicationManagementDAOException; + + void updateSubscriptions(int tenantId, String updateBy, List paramList, + int releaseId, String subType, String action) throws ApplicationManagementDAOException; + + List getDeviceSubIds(List deviceIds, int applicationReleaseId, int tenantId) + throws ApplicationManagementDAOException; + + List getDeviceSubIdsForOperation(int operationId, int deviceID, int tenantId) + throws ApplicationManagementDAOException; + + boolean updateDeviceSubStatus(int deviceId, List deviceSubIds, String status, int tenantcId) + throws ApplicationManagementDAOException; + + /** + * Creates a scheduled subscription entry in the data store. + * + * @param subscriptionDTO {@link ScheduledSubscriptionDTO} which contains the details of the subscription + * @throws ApplicationManagementDAOException if error occurred while creating an entry in the data store. + */ + boolean createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO) throws ApplicationManagementDAOException; + + /** + * Updates the existing entry of a scheduled subscription. + * + * @param id id of the existing subscription + * @param scheduledAt scheduled time + * @param scheduledBy username of the user who scheduled the subscription + * @throws ApplicationManagementDAOException if error occurred while updating the entry + */ + boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy) + throws ApplicationManagementDAOException; + + /** + * Marks A list of given scheduled subscription as deleted. + * + * @param subscriptionIdList list of ids of the subscriptions to delete + * @throws ApplicationManagementDAOException if error occurred while deleting the subscription + */ + boolean deleteScheduledSubscription(List subscriptionIdList) throws ApplicationManagementDAOException; + + /** + * Update the status of an existing subscription. + * + * @param id id of the existing subscription + * @param status changed status {@see {@link ExecutionStatus}} + * @throws ApplicationManagementDAOException if error occurs while changing the status of the subscription + */ + boolean updateScheduledSubscriptionStatus(int id, ExecutionStatus status) throws ApplicationManagementDAOException; + + /** + * Retrieve a list of scheduled subscriptions of a given state + * + * @param status status of the subscriptions + * @param deleted is the subscription marked as deleted + * @return list of {@link ScheduledSubscriptionDTO} + * @throws ApplicationManagementDAOException if error occurred while retrieving the subscriptions + */ + List getScheduledSubscriptionByStatus(ExecutionStatus status, boolean deleted) + throws ApplicationManagementDAOException; + + /** + * Retrieves a list of subscriptions that are not executed on the scheduled time. + * + * @return list of {@link ScheduledSubscriptionDTO} + * @throws ApplicationManagementDAOException if error occurred while retrieving the subscriptions. + */ + List getNonExecutedSubscriptions() throws ApplicationManagementDAOException; + + /** + * Retrieves a subscription by taskName which is in the ExecutionStatus.PENDING state. + * + * @param taskName name of the task to retrieve. + * @return {@link ScheduledSubscriptionDTO} + * @throws ApplicationManagementDAOException if error occurred while retrieving the subscription + */ + ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName) throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of users + * + * @param tenantId id of the current tenant + * @param offsetValue offset value for get paginated result + * @param limitValue limit value for get paginated result + * @param appReleaseId id of the application release. + * @return subscribedUsers - list of app subscribed users. + * @throws {@link ApplicationManagementDAOException} if connections establishment fails. + */ + List getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of roles + * + * @param tenantId id of the current tenant + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @param appReleaseId id of the application release. + * @return subscribedRoles - list of app subscribed roles. + * @throws {@link ApplicationManagementDAOException} if connections establishment fails. + */ + List getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of subscribed groups + * + * @param tenantId id of the current tenant + * @param offsetValue offset value for get paginated request. + * @param limitValue limit value for get paginated request. + * @param appReleaseId id of the application release. + * @return subscribedGroups - list of app subscribed groups. + * @throws {@link ApplicationManagementDAOException} if connections establishment fails. + */ + List getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, int tenantId) + throws ApplicationManagementDAOException; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/VisibilityDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/VisibilityDAO.java new file mode 100644 index 0000000000..27f2bebc4d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/VisibilityDAO.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao; + +import org.wso2.carbon.device.application.mgt.core.exception.VisibilityManagementDAOException; + +import java.util.List; + +/** + * This interface provides the list of operations that are performed in the database layer with respect to the + * visibility. + * + */ +public interface VisibilityDAO { + + /*** + * This method is used to add unrestricted roles for a particular application. + * + * @param unrestrictedRoles List of roles. User should have assigned at least one role from unrestricted role list + * to view the application. + * @param applicationId Id of the application. + * @param tenantId Tenant Id. + * @throws VisibilityManagementDAOException if an error occured while executing the query. + */ + void addUnrestrictedRoles(List unrestrictedRoles, int applicationId, int tenantId) + throws VisibilityManagementDAOException; + + /*** + * This method is used to get unrestricted roles of an particular application. + * + * @param applicationId Id of the application. + * @param tenantId Tenant Id. + * @return List of unrestricted roles of the application. + * @throws VisibilityManagementDAOException if an error occured while executing the query. + */ + List getUnrestrictedRoles(int applicationId, int tenantId) throws VisibilityManagementDAOException; + + /*** + * This method is used to delete unrestricted roles of an particular application. + * + * @param unrestrictedRoles List of unrestricted roles which are going to remove from the application. + * @param applicationId Id of the application. + * @param tenantId Tenant Id. + * @throws VisibilityManagementDAOException if an error occured while executing the query. + */ + void deleteUnrestrictedRoles(List unrestrictedRoles, int applicationId, int tenantId) + throws VisibilityManagementDAOException; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/ApplicationManagementDAOFactory.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/ApplicationManagementDAOFactory.java new file mode 100644 index 0000000000..62a95b7808 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/ApplicationManagementDAOFactory.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao.common; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.UnsupportedDatabaseEngineException; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; +import org.wso2.carbon.device.application.mgt.core.dao.LifecycleStateDAO; +import org.wso2.carbon.device.application.mgt.core.dao.ReviewDAO; +import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO; +import org.wso2.carbon.device.application.mgt.core.dao.VisibilityDAO; +import org.wso2.carbon.device.application.mgt.core.dao.impl.application.SQLServerApplicationDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.application.release.OracleApplicationReleaseDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.application.release.SQLServerApplicationReleaseDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.lifecyclestate.OracleLifecycleStateDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.lifecyclestate.SQLServerLifecycleStateDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.review.GenericReviewDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.application.GenericApplicationDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.application.release.GenericApplicationReleaseDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.application.OracleApplicationDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.lifecyclestate.GenericLifecycleStateDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.review.OracleReviewDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.review.SQLServerReviewDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.subscription.GenericSubscriptionDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.subscription.OracleSubscriptionDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.subscription.SQLServerSubscriptionDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.visibility.GenericVisibilityDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.visibility.OracleVisibilityDAOImpl; +import org.wso2.carbon.device.application.mgt.core.dao.impl.visibility.SQLServerVisibilityDAOImpl; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; +import org.wso2.carbon.device.application.mgt.core.util.Constants; + +import javax.sql.DataSource; +import java.sql.SQLException; + +/** + * This class intends to act as the primary entity that hides all DAO instantiation related complexities and logic so + * that the business objection handling layer doesn't need to be aware of the same providing seamless plug-ability of + * different data sources, connection acquisition mechanisms as well as different forms of DAO implementations to the + * high-level implementations that require Application management related metadata persistence. + */ +public class ApplicationManagementDAOFactory { + + private static String databaseEngine; + private static DataSource dataSource; + private static final Log log = LogFactory.getLog(ApplicationManagementDAOFactory.class); + + public static void init(String datasourceName) { + ConnectionManagerUtil.resolveDataSource(datasourceName); + databaseEngine = ConnectionManagerUtil.getDatabaseType(); + } + + public static void init(DataSource dtSource) { + dataSource = dtSource; + try { + databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + log.error("Error occurred while retrieving config.datasource connection", e); + } + } + + public static ApplicationDAO getApplicationDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case Constants.DataBaseTypes.DB_TYPE_H2: + case Constants.DataBaseTypes.DB_TYPE_MYSQL: + case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new GenericApplicationDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerApplicationDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleApplicationDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } + + public static LifecycleStateDAO getLifecycleStateDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case Constants.DataBaseTypes.DB_TYPE_H2: + case Constants.DataBaseTypes.DB_TYPE_MYSQL: + case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new GenericLifecycleStateDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerLifecycleStateDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleLifecycleStateDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } + + /** + * To get the instance of ApplicationReleaseDAOImplementation of the particular database engine. + * + * @return specific ApplicationReleaseDAOImplementation + */ + public static ApplicationReleaseDAO getApplicationReleaseDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case Constants.DataBaseTypes.DB_TYPE_H2: + case Constants.DataBaseTypes.DB_TYPE_MYSQL: + case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new GenericApplicationReleaseDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleApplicationReleaseDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerApplicationReleaseDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } + + /** + * To get the instance of VisibilityDAOImplementation of the particular database engine. + * @return specific VisibilityDAOImplementation + */ + public static VisibilityDAO getVisibilityDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case Constants.DataBaseTypes.DB_TYPE_H2: + case Constants.DataBaseTypes.DB_TYPE_MYSQL: + case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new GenericVisibilityDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleVisibilityDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerVisibilityDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } + + /** + * To get the instance of SubscriptionDAOImplementation of the particular database engine. + * @return GenericSubscriptionDAOImpl + */ + public static SubscriptionDAO getSubscriptionDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case Constants.DataBaseTypes.DB_TYPE_H2: + case Constants.DataBaseTypes.DB_TYPE_MYSQL: + case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new GenericSubscriptionDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleSubscriptionDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerSubscriptionDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } + + public static ReviewDAO getCommentDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case Constants.DataBaseTypes.DB_TYPE_H2: + case Constants.DataBaseTypes.DB_TYPE_MYSQL: + case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new GenericReviewDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleReviewDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerReviewDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/AbstractDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/AbstractDAOImpl.java new file mode 100644 index 0000000000..a9488163fc --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/AbstractDAOImpl.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao.impl; + +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; + +import java.sql.Connection; + +/** + * This class deals with getting the DB connection. + */ +public abstract class AbstractDAOImpl { + + protected Connection getDBConnection() throws DBConnectionException { + return ConnectionManagerUtil.getDBConnection(); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java new file mode 100644 index 0000000000..f860273228 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java @@ -0,0 +1,1598 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao.impl.application; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.AppLifecycleState; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.dto.CategoryDTO; +import org.wso2.carbon.device.application.mgt.common.Filter; +import org.wso2.carbon.device.application.mgt.common.dto.TagDTO; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; +import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; + +/** + * This handles Application related operations. + */ +public class GenericApplicationDAOImpl extends AbstractDAOImpl implements ApplicationDAO { + + private static final Log log = LogFactory.getLog(GenericApplicationDAOImpl.class); + + @Override + public int createApplication(ApplicationDTO applicationDTO, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to create an application"); + log.debug("ApplicationDTO Details : "); + log.debug("App Name : " + applicationDTO.getName() + " App Type : " + applicationDTO.getType()); + } + String sql = "INSERT INTO AP_APP " + + "(NAME, " + + "DESCRIPTION, " + + "TYPE, " + + "SUB_TYPE, " + + "TENANT_ID, " + + "DEVICE_TYPE_ID) VALUES (?, ?, ?, ?, ?, ?)"; + int applicationId = -1; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, applicationDTO.getName()); + stmt.setString(2, applicationDTO.getDescription()); + stmt.setString(3, applicationDTO.getType()); + stmt.setString(4, applicationDTO.getSubType()); + stmt.setInt(5, tenantId); + stmt.setInt(6, applicationDTO.getDeviceTypeId()); + stmt.executeUpdate(); + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + applicationId = rs.getInt(1); + } + return applicationId; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an application which has " + + "application name " + applicationDTO.getName(); + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application name " + + applicationDTO.getName(); + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getApplications(Filter filter,int deviceTypeId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting application data from the database"); + log.debug(String.format("Filter: limit=%s, offset=%s", filter.getLimit(), filter.getOffset())); + } + int paramIndex = 1; + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "INNER JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + + "INNER JOIN (SELECT ID FROM AP_APP LIMIT ? OFFSET ? ) AS app_data ON app_data.ID = AP_APP.ID " + + "WHERE AP_APP.TENANT_ID = ?"; + + if (filter == null) { + String msg = "Filter is not instantiated."; + log.error(msg); + throw new ApplicationManagementDAOException(msg); + } + + if (!StringUtils.isEmpty(filter.getAppType())) { + sql += " AND AP_APP.TYPE = ?"; + } + if (!StringUtils.isEmpty(filter.getAppName())) { + sql += " AND LOWER (AP_APP.NAME) "; + if (filter.isFullMatch()) { + sql += "= ?"; + } else { + sql += "LIKE ?"; + } + } + if (!StringUtils.isEmpty(filter.getSubscriptionType())) { + sql += " AND AP_APP.SUB_TYPE = ?"; + } + if (filter.getMinimumRating() > 0) { + sql += " AND AP_APP.RATING >= ?"; + } + if (!StringUtils.isEmpty(filter.getVersion())) { + sql += " AND AP_APP_RELEASE.VERSION = ?"; + } + if (!StringUtils.isEmpty(filter.getAppReleaseType())) { + sql += " AND AP_APP_RELEASE.RELEASE_TYPE = ?"; + } + if (!StringUtils.isEmpty(filter.getAppReleaseState())) { + sql += " AND AP_APP_RELEASE.CURRENT_STATE = ?"; + } + if (deviceTypeId != -1) { + sql += " AND AP_APP.DEVICE_TYPE_ID = ?"; + } + + if (filter.getLimit() == -1) { + sql = sql.replace("LIMIT ? OFFSET ?", ""); + } + + String sortingOrder = "ASC"; + if (!StringUtils.isEmpty(filter.getSortBy() )) { + sortingOrder = filter.getSortBy(); + } + sql += " ORDER BY APP_ID " + sortingOrder; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql); + ){ + if (filter.getLimit() != -1) { + if (filter.getLimit() == 0) { + stmt.setInt(paramIndex++, 100); + } else { + stmt.setInt(paramIndex++, filter.getLimit()); + } + stmt.setInt(paramIndex++, filter.getOffset()); + } + stmt.setInt(paramIndex++, tenantId); + + if (filter.getAppType() != null && !filter.getAppType().isEmpty()) { + stmt.setString(paramIndex++, filter.getAppType()); + } + if (filter.getAppName() != null && !filter.getAppName().isEmpty()) { + if (filter.isFullMatch()) { + stmt.setString(paramIndex++, filter.getAppName().toLowerCase()); + } else { + stmt.setString(paramIndex++, "%" + filter.getAppName().toLowerCase() + "%"); + } + } + if (!StringUtils.isEmpty(filter.getSubscriptionType())) { + stmt.setString(paramIndex++, filter.getSubscriptionType()); + } + if (filter.getMinimumRating() > 0) { + stmt.setInt(paramIndex++, filter.getMinimumRating()); + } + if (!StringUtils.isEmpty(filter.getVersion())) { + stmt.setString(paramIndex++, filter.getVersion()); + } + if (!StringUtils.isEmpty(filter.getAppReleaseType())) { + stmt.setString(paramIndex++, filter.getAppReleaseType()); + } + if (!StringUtils.isEmpty(filter.getAppReleaseState())) { + stmt.setString(paramIndex++, filter.getAppReleaseState()); + } + if (deviceTypeId > 0 ) { + stmt.setInt(paramIndex, deviceTypeId); + } + try (ResultSet rs = stmt.executeQuery() ) { + return DAOUtil.loadApplications(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection while getting application list for the " + + "tenant " + tenantId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting application list for the tenant " + tenantId + ". While " + + "executing " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getApplicationCount(Filter filter,int deviceTypeId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting application count for filtering app data from the database"); + } + int paramIndex = 1; + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + String sql = "SELECT count(AP_APP.ID) AS APP_COUNT " + + "FROM AP_APP " + + "INNER JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + + "INNER JOIN (SELECT ID FROM AP_APP) AS app_data ON app_data.ID = AP_APP.ID " + + "WHERE AP_APP.TENANT_ID = ?"; + + if (filter == null) { + throw new ApplicationManagementDAOException("Filter need to be instantiated"); + } + + if (!StringUtils.isEmpty(filter.getAppType())) { + sql += " AND AP_APP.TYPE = ?"; + } + if (!StringUtils.isEmpty(filter.getAppName())) { + sql += " AND LOWER (AP_APP.NAME) "; + if (filter.isFullMatch()) { + sql += "= ?"; + } else { + sql += "LIKE ?"; + } + } + if (!StringUtils.isEmpty(filter.getSubscriptionType())) { + sql += " AND AP_APP.SUB_TYPE = ?"; + } + if (filter.getMinimumRating() > 0) { + sql += " AND AP_APP.RATING >= ?"; + } + if (!StringUtils.isEmpty(filter.getVersion())) { + sql += " AND AP_APP_RELEASE.VERSION = ?"; + } + if (!StringUtils.isEmpty(filter.getAppReleaseType())) { + sql += " AND AP_APP_RELEASE.RELEASE_TYPE = ?"; + } + if (!StringUtils.isEmpty(filter.getAppReleaseState())) { + sql += " AND AP_APP_RELEASE.CURRENT_STATE = ?"; + } + if (deviceTypeId != -1) { + sql += " AND AP_APP.DEVICE_TYPE_ID = ?"; + } + + try { + conn = this.getDBConnection(); + stmt = conn.prepareStatement(sql); + stmt.setInt(paramIndex++, tenantId); + + if (filter.getAppType() != null && !filter.getAppType().isEmpty()) { + stmt.setString(paramIndex++, filter.getAppType()); + } + if (filter.getAppName() != null && !filter.getAppName().isEmpty()) { + if (filter.isFullMatch()) { + stmt.setString(paramIndex++, filter.getAppName().toLowerCase()); + } else { + stmt.setString(paramIndex++, "%" + filter.getAppName().toLowerCase() + "%"); + } + } + if (!StringUtils.isEmpty(filter.getSubscriptionType())) { + stmt.setString(paramIndex++, filter.getSubscriptionType()); + } + if (filter.getMinimumRating() > 0) { + stmt.setInt(paramIndex++, filter.getMinimumRating()); + } + if (!StringUtils.isEmpty(filter.getVersion())) { + stmt.setString(paramIndex++, filter.getVersion()); + } + if (!StringUtils.isEmpty(filter.getAppReleaseType())) { + stmt.setString(paramIndex++, filter.getAppReleaseType()); + } + if (!StringUtils.isEmpty(filter.getAppReleaseState())) { + stmt.setString(paramIndex++, filter.getAppReleaseState()); + } + if (deviceTypeId > 0 ) { + stmt.setInt(paramIndex, deviceTypeId); + } + rs = stmt.executeQuery(); + if (rs.next()) { + return rs.getInt("APP_COUNT"); + } + return 0; + } catch (SQLException e) { + String msg = "Error occurred while getting application list for the tenant" + " " + tenantId + + ". While executing " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection while getting application list for the " + + "tenant " + tenantId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } finally { + DAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public ApplicationDTO getApplication(String releaseUuid, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting application with the release UUID: " + releaseUuid + " from the database"); + } + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "INNER JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + + "WHERE " + + "AP_APP.ID = (SELECT AP_APP_RELEASE.AP_APP_ID FROM AP_APP_RELEASE WHERE AP_APP_RELEASE.UUID = ?) " + + "AND AP_APP.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, releaseUuid); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved basic details of the application for the application " + + "release UUID: " + releaseUuid); + } + return DAOUtil.loadApplication(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get application for application release " + + "UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting application details with app release uuid " + releaseUuid + + " while executing query. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "Found more than one application for application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public ApplicationDTO getAppWithRelatedRelease(String releaseUuid, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting application and releated application release for the release UUID: " + releaseUuid + + " from the database"); + } + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "INNER JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + + "WHERE " + + "AP_APP_RELEASE.UUID = ? " + + "AND AP_APP.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, releaseUuid); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved basic details of the application and related application " + + "release for the application release which has UUID: " + releaseUuid); + } + return DAOUtil.loadApplication(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get application and related application " + + "release for release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting application and related app release details for app release " + + "uuid " + releaseUuid + " while executing query. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "Found more than one application for application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public ApplicationDTO getApplication(int applicationId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting application with the id (" + applicationId + ") from the database"); + } + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "INNER JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + + "WHERE " + + "AP_APP.ID =? AND " + + "AP_APP.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, applicationId); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved basic details of the application with the id " + + applicationId); + } + return DAOUtil.loadApplication(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get application for application ID: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred to get application details with app id " + applicationId + " while executing " + + "query. Query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "Found more than one application for application ID: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean updateApplication(ApplicationDTO applicationDTO, int tenantId) + throws ApplicationManagementDAOException { + String sql = "UPDATE AP_APP " + + "SET " + + "NAME = ?, " + + "DESCRIPTION = ?, " + + "SUB_TYPE = ?, " + + "CURRENCY = ? " + + "WHERE ID = ? AND TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, applicationDTO.getName()); + stmt.setString(2, applicationDTO.getDescription()); + stmt.setString(3, applicationDTO.getSubType()); + stmt.setString(4, applicationDTO.getPaymentCurrency()); + stmt.setInt(5, applicationDTO.getId()); + stmt.setInt(6, tenantId); + return stmt.executeUpdate() > 0; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the application."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when executing SQL to update an application. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void updateApplicationRating(String uuid, double rating, int tenantId) + throws ApplicationManagementDAOException { + String sql = "UPDATE AP_APP " + + "SET " + + "RATING = ? " + + "WHERE " + + "ID = (SELECT AP_APP_ID FROM AP_APP_RELEASE WHERE UUID = ?) AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setDouble(1, rating); + stmt.setString(2, uuid); + stmt.setInt(3, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the application rating."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when obtaining database connection for updating the application rating."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + + @Override + public void retireApplication(int appId) throws ApplicationManagementDAOException { + String sql = "UPDATE " + + "AP_APP " + + "SET STATUS = ? " + + "WHERE ID = ? "; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, AppLifecycleState.RETIRED.toString()); + stmt.setInt(2, appId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retire application which has application " + + "ID: " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to retire an application which has application ID " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void addTags(List tags, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to add tags"); + } + String sql = "INSERT INTO AP_APP_TAG " + + "(TAG, " + + " TENANT_ID) " + + "VALUES (?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (String tag : tags) { + stmt.setString(1, tag); + stmt.setInt(2, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when adding tags"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while adding tags. Executed Query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAllTags(int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get all tags"); + } + String sql = "SELECT " + + "AP_APP_TAG.ID AS ID, " + + "AP_APP_TAG.TAG AS TAG " + + "FROM AP_APP_TAG " + + "WHERE TENANT_ID = ?"; + try { + List tagEntities = new ArrayList<>(); + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + TagDTO tagDTO = new TagDTO(); + tagDTO.setId(rs.getInt("ID")); + tagDTO.setTagName(rs.getString("TAG")); + tagEntities.add(tagDTO); + } + return tagEntities; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting all tags"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting all tags"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAllCategories(int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get all categories."); + } + String sql = "SELECT " + + "AP_APP_CATEGORY.ID AS ID, " + + "AP_APP_CATEGORY.CATEGORY AS CATEGORY " + + "FROM AP_APP_CATEGORY " + + "WHERE TENANT_ID = ?"; + try { + List categories = new ArrayList<>(); + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + CategoryDTO category = new CategoryDTO(); + category.setId(rs.getInt("ID")); + category.setCategoryName(rs.getString("CATEGORY")); + categories.add(category); + } + return categories; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting all categories."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting all categories. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getCategoryIdsForCategoryNames(List categoryNames, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get category ids for given category names"); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List tagIds = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT AP_APP_CATEGORY.ID AS ID FROM AP_APP_CATEGORY WHERE AP_APP_CATEGORY.CATEGORY IN (", + ") AND TENANT_ID = ?"); + categoryNames.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String categoryName : categoryNames) { + ps.setObject(index++, categoryName); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + tagIds.add(rs.getInt("ID")); + } + } + } + return tagIds; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting category ids for given " + + "category names"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting all categories."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDistinctCategoryIdsInCategoryMapping() throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get distinct category ids in category mapping."); + } + try { + Connection conn = this.getDBConnection(); + List distinctCategoryIds = new ArrayList<>(); + String sql = "SELECT DISTINCT AP_APP_CATEGORY_ID AS ID FROM AP_APP_CATEGORY_MAPPING;"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + distinctCategoryIds.add(rs.getInt("ID")); + } + } + } + return distinctCategoryIds; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting distinct category ids in " + + "category mapping"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting distinct category ids in category mapping."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public CategoryDTO getCategoryForCategoryName(String categoryName, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get category for given category name."); + } + String sql = "SELECT AP_APP_CATEGORY.ID AS ID " + + "FROM AP_APP_CATEGORY " + + "WHERE AP_APP_CATEGORY.CATEGORY = ? AND " + + "AP_APP_CATEGORY.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, categoryName); + ps.setInt(2, tenantId); + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + CategoryDTO categoryDTO = new CategoryDTO(); + categoryDTO.setId(rs.getInt("ID")); + categoryDTO.setCategoryName(categoryName); + return categoryDTO; + } + return null; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting category for given category " + + "name."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting category for category name. Executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void addCategories(List categories, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO Request received in DAO Layer to add categories."); + } + String sql = "INSERT INTO AP_APP_CATEGORY " + + "(CATEGORY," + + " TENANT_ID) " + + "VALUES (?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (String category : categories) { + stmt.setString(1, category); + stmt.setInt(2, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when adding categories."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while adding categories. Executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void addCategoryMapping(List categoryIds, int applicationId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to add category mappings"); + } + String sql = "INSERT INTO AP_APP_CATEGORY_MAPPING " + + "(AP_APP_CATEGORY_ID, " + + "AP_APP_ID, " + + " TENANT_ID) " + + "VALUES (?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer categoryId : categoryIds) { + stmt.setInt(1, categoryId); + stmt.setInt(2, applicationId); + stmt.setInt(3, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when adding data into category mapping."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while adding data into category mapping."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteAppCategories(int applicationId, int tenantId) throws ApplicationManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete Category mappings."); + } + String sql = "DELETE FROM " + + "AP_APP_CATEGORY_MAPPING " + + "WHERE " + + "AP_APP_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, applicationId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when deleting category mapping of " + + "application ID: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when deleting category mapping of application ID: " + applicationId + + " Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteAppCategories(List categoryIds, int applicationId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete application category."); + } + String sql = "DELETE FROM " + + "AP_APP_CATEGORY_MAPPING WHERE " + + "AP_APP_CATEGORY_ID = ? AND " + + "AP_APP_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + for (Integer categoryId : categoryIds){ + stmt.setInt(1, categoryId); + stmt.setInt(2, applicationId); + stmt.setInt(3, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when deleting category mapping."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when deleting category mapping. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteCategory(int categoryId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete category."); + } + String sql = "DELETE FROM " + + "AP_APP_CATEGORY " + + "WHERE " + + "ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, categoryId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when deleting category which has ID: " + + categoryId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when deleting category which has ID: " + categoryId + ". Query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void updateCategory(CategoryDTO categoryDTO, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to update a category."); + } + String sql = "UPDATE " + + "AP_APP_CATEGORY " + + "SET CATEGORY = ? " + + "WHERE " + + "ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, categoryDTO.getCategoryName()); + stmt.setInt(2, categoryDTO.getId()); + stmt.setInt(3, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when updating category which has ID: " + + categoryDTO.getId(); + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when updating category which has ID: " + categoryDTO.getId() + ". Executed " + + "query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getTagIdsForTagNames(List tagNames, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get tag ids for given tag names"); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List tagIds = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT AP_APP_TAG.ID AS ID FROM AP_APP_TAG WHERE AP_APP_TAG.TAG IN (", + ") AND TENANT_ID = ?"); + tagNames.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String tagName : tagNames) { + ps.setObject(index++, tagName); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + tagIds.add(rs.getInt("ID")); + } + } + } + return tagIds; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting tag IDs for given tag names."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting tag IDs for given tag names"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public TagDTO getTagForTagName(String tagName, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get tag for given tag name."); + } + String sql = "SELECT AP_APP_TAG.ID AS ID" + + " FROM AP_APP_TAG " + + "WHERE AP_APP_TAG.TAG = ? AND " + + "AP_APP_TAG.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, tagName); + ps.setInt(2, tenantId); + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + TagDTO tagDTO = new TagDTO(); + tagDTO.setId(rs.getInt("ID")); + tagDTO.setTagName(tagName); + return tagDTO; + } + } + } + return null; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting tag for given tag name: " + + tagName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting tag for tag name: " + tagName + ". Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDistinctTagIdsInTagMapping() throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get distinct tag ids in tag mapping."); + } + String sql = "SELECT " + + "DISTINCT " + + "tm.AP_APP_TAG_ID AS ID " + + "FROM AP_APP_TAG_MAPPING tm"; + try { + Connection conn = this.getDBConnection(); + List distinctTagIds = new ArrayList<>(); + try (PreparedStatement ps = conn.prepareStatement(sql)) { + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + distinctTagIds.add(rs.getInt("ID")); + } + } + } + return distinctTagIds; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting distinct tag ids in tag " + + "mapping"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting distinct tag ids in tag mapping. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void addTagMapping(List tagIds, int applicationId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to add application tags which has application ID: " + + applicationId); + } + String sql = "INSERT INTO AP_APP_TAG_MAPPING " + + "(AP_APP_TAG_ID, " + + "AP_APP_ID, " + + " TENANT_ID) " + + "VALUES (?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer tagId : tagIds) { + stmt.setInt(1, tagId); + stmt.setInt(2, applicationId); + stmt.setInt(3, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to add tags for application which has ID: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when adding tags for application which has the ID: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppTags(int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get tags of application which has application Id " + appId); + } + List tags = new ArrayList<>(); + String sql = "SELECT tag.TAG AS TAG " + + "FROM " + + "AP_APP_TAG tag INNER JOIN AP_APP_TAG_MAPPING tag_map ON tag.ID = tag_map.AP_APP_TAG_ID " + + "INNER JOIN AP_APP app ON tag_map.AP_APP_ID = app.ID " + + "WHERE app.ID = ? AND app.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, appId); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + tags.add(rs.getString("TAG")); + } + } + } + return tags; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get application tags. Application Id: " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL error occured while getting application tags. ApplicationId: " + appId + " Executed " + + "query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean hasTagMapping (int tagId, int applicationId, int tenantId) throws ApplicationManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to verify whether tag is associated with an application."); + } + String sql = "SELECT tm.AP_APP_ID AS ID " + + "FROM AP_APP_TAG_MAPPING tm " + + "WHERE " + + "tm.AP_APP_TAG_ID = ? AND " + + "tm.AP_APP_ID = ? AND " + + "tm.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, tagId); + stmt.setInt(2, applicationId); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when verifying the existence of a tag " + + "mapping. Application ID " + applicationId + " tag ID: " + tagId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when verifying the existence of a tag mapping. Application ID " + + applicationId + " tag ID " + tagId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean hasTagMapping (int tagId, int tenantId) throws ApplicationManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to verify whether tag is associated with at least one " + + "application."); + } + String sql = "SELECT tm.AP_APP_ID AS ID " + + "FROM AP_APP_TAG_MAPPING tm " + + "WHERE " + + "tm.AP_APP_TAG_ID = ? AND " + + "tm.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, tagId); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to verify whether tag is associated with at " + + "least one application. Tag ID " + tagId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing the query to verify whether tag is associated with at least " + + "one application. Tag ID " + tagId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteApplicationTags(List tagIds, int applicationId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete Tag mappings."); + } + String sql = "DELETE FROM " + + "AP_APP_TAG_MAPPING WHERE " + + "AP_APP_TAG_ID = ? AND " + + "AP_APP_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + for (Integer tagId : tagIds){ + stmt.setInt(1, tagId); + stmt.setInt(2, applicationId); + stmt.setInt(3, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to delete tag mapping. Application ID: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while executing the query to delete tag mapping. Application ID: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteApplicationTag (Integer tagId, int applicationId, int tenantId) throws ApplicationManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete Tag mapping."); + } + String sql = "DELETE FROM " + + "AP_APP_TAG_MAPPING " + + "WHERE " + + "AP_APP_TAG_ID = ? AND " + + "AP_APP_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, tagId); + stmt.setInt(2, applicationId); + stmt.setInt(3, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to delete a tag mapping. Application ID " + + applicationId + " tag ID " + tagId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while executing the query to delete a tag mapping. Application ID " + + applicationId + " tag ID " + tagId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteApplicationTags(int applicationId, int tenantId) throws ApplicationManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete application tags for application ID " + applicationId); + } + String sql = "DELETE FROM " + + "AP_APP_TAG_MAPPING " + + "WHERE " + + "AP_APP_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, applicationId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when deleting application tags for " + + "application ID: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when deleting application tags for application ID: " + applicationId + "." + + " Executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteTagMapping(int tagId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete application tag. Tag Id " + tagId); + } + String sql = "DELETE FROM " + + "AP_APP_TAG_MAPPING " + + "WHERE " + + "AP_APP_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, tagId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when deleting application tag which has tag" + + " ID: " + tagId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL error occurred when deleting application tag which has tag ID: " + tagId + ". executed " + + "query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteTag(int tagId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete Tag which has tag ID " + tagId); + } + String sql = "DELETE FROM " + + "AP_APP_TAG " + + "WHERE " + + "ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, tagId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when deleting tag which has ID: " + tagId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when deleting tag which has ID: " + tagId + ". Executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void updateTag(TagDTO tagDTO, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to update a Tag."); + } + String sql = "UPDATE " + + "AP_APP_TAG " + + "SET TAG = ? " + + "WHERE " + + "ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, tagDTO.getTagName()); + stmt.setInt(2, tagDTO.getId()); + stmt.setInt(3, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update tag which has ID: " + + tagDTO.getId(); + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when updating tag which has ID: " + tagDTO.getId() + ". Executed query: " + + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppCategories(int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get application categories for given application."); + } + List categories = new ArrayList<>(); + String sql = "SELECT CATEGORY " + + "FROM " + + "AP_APP_CATEGORY cat INNER JOIN AP_APP_CATEGORY_MAPPING cat_map ON cat.ID = cat_map.AP_APP_CATEGORY_ID " + + "INNER JOIN AP_APP app ON cat_map.AP_APP_ID = app.ID " + + "WHERE app.ID = ? AND app.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, appId); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + categories.add(rs.getString("CATEGORY")); + } + } + } + return categories; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get application categories for " + + "application which has ID " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL error occurred while executing query to get application categories for " + + "application which has ID " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean hasCategoryMapping (int categoryId, int tenantId) throws ApplicationManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to verify whether tag is associated with at least one application."); + } + String sql = "SELECT cm.AP_APP_ID AS ID " + + "FROM AP_APP_CATEGORY_MAPPING cm " + + "WHERE " + + "cm.AP_APP_CATEGORY_ID = ? AND " + + "cm.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, categoryId); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when verifying the existence of a category " + + "mapping for category ID " + categoryId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when verifying the existence of a category mapping for category ID " + + categoryId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean isExistingAppName(String appName, int deviceTypeId, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT AP_APP.ID AS ID " + + "FROM AP_APP " + + "WHERE " + + "AP_APP.NAME = ? AND " + + "AP_APP.DEVICE_TYPE_ID = ? AND " + + "AP_APP.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, appName); + stmt.setInt(2, deviceTypeId); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to check whether the existence of " + + "application name for device type which has device type ID " + deviceTypeId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to check whether the existence of application name for " + + "device type which has device type ID " + deviceTypeId + ". executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteApplication(int appId, int tenantId) throws ApplicationManagementDAOException { + String sql = "DELETE FROM AP_APP " + + "WHERE ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, appId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to delete application for application id::." + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while deleting application for application ID: " + appId + " Executed " + + "query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java new file mode 100644 index 0000000000..b9de2a1ac3 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.application; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.Filter; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * This handles Application operations which are specific to Oracle. + */ +public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl { + + private static final Log log = LogFactory.getLog(OracleApplicationDAOImpl.class); + + @Override + public List getApplications(Filter filter,int deviceTypeId, int tenantId) throws + ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting application data from the database"); + log.debug(String.format("Filter: limit=%s, offset=%s", filter.getLimit(), filter.getOffset())); + } + int paramIndex = 1; + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "INNER JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + + "INNER JOIN (SELECT ID FROM AP_APP ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY) AS app_data ON app_data.ID = AP_APP.ID " + + "WHERE AP_APP.TENANT_ID = ?"; + + if (filter == null) { + String msg = "Filter is not instantiated."; + log.error(msg); + throw new ApplicationManagementDAOException(msg); + } + + if (!StringUtils.isEmpty(filter.getAppType())) { + sql += " AND AP_APP.TYPE = ?"; + } + if (!StringUtils.isEmpty(filter.getAppName())) { + sql += " AND LOWER (AP_APP.NAME) "; + if (filter.isFullMatch()) { + sql += "= ?"; + } else { + sql += "LIKE ?"; + } + } + if (!StringUtils.isEmpty(filter.getSubscriptionType())) { + sql += " AND AP_APP.SUB_TYPE = ?"; + } + if (filter.getMinimumRating() > 0) { + sql += " AND AP_APP.RATING >= ?"; + } + if (!StringUtils.isEmpty(filter.getVersion())) { + sql += " AND AP_APP_RELEASE.VERSION = ?"; + } + if (!StringUtils.isEmpty(filter.getAppReleaseType())) { + sql += " AND AP_APP_RELEASE.RELEASE_TYPE = ?"; + } + if (!StringUtils.isEmpty(filter.getAppReleaseState())) { + sql += " AND AP_APP_RELEASE.CURRENT_STATE = ?"; + } + if (deviceTypeId != -1) { + sql += " AND AP_APP.DEVICE_TYPE_ID = ?"; + } + + if (filter.getLimit() == -1) { + sql = sql.replace("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", ""); + } + + String sortingOrder = "ASC"; + if (!StringUtils.isEmpty(filter.getSortBy() )) { + sortingOrder = filter.getSortBy(); + } + sql += " ORDER BY APP_ID " + sortingOrder; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql); + ){ + if (filter.getLimit() != -1) { + stmt.setInt(paramIndex++, filter.getOffset()); + if (filter.getLimit() == 0) { + stmt.setInt(paramIndex++, 100); + } else { + stmt.setInt(paramIndex++, filter.getLimit()); + } + } + stmt.setInt(paramIndex++, tenantId); + + if (filter.getAppType() != null && !filter.getAppType().isEmpty()) { + stmt.setString(paramIndex++, filter.getAppType()); + } + if (filter.getAppName() != null && !filter.getAppName().isEmpty()) { + if (filter.isFullMatch()) { + stmt.setString(paramIndex++, filter.getAppName().toLowerCase()); + } else { + stmt.setString(paramIndex++, "%" + filter.getAppName().toLowerCase() + "%"); + } + } + if (!StringUtils.isEmpty(filter.getSubscriptionType())) { + stmt.setString(paramIndex++, filter.getSubscriptionType()); + } + if (filter.getMinimumRating() > 0) { + stmt.setInt(paramIndex++, filter.getMinimumRating()); + } + if (!StringUtils.isEmpty(filter.getVersion())) { + stmt.setString(paramIndex++, filter.getVersion()); + } + if (!StringUtils.isEmpty(filter.getAppReleaseType())) { + stmt.setString(paramIndex++, filter.getAppReleaseType()); + } + if (!StringUtils.isEmpty(filter.getAppReleaseState())) { + stmt.setString(paramIndex++, filter.getAppReleaseState()); + } + if (deviceTypeId > 0 ) { + stmt.setInt(paramIndex, deviceTypeId); + } + try (ResultSet rs = stmt.executeQuery() ) { + return DAOUtil.loadApplications(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection while getting application list for the " + + "tenant " + tenantId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting application list for the tenant " + tenantId + ". While " + + "executing " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java new file mode 100644 index 0000000000..3b247d886a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java @@ -0,0 +1,189 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.application; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.Filter; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * This handles Application operations which are specific to MSSQL. + */ +public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl { + + private static final Log log = LogFactory.getLog(SQLServerApplicationDAOImpl.class); + + @Override + public List getApplications(Filter filter,int deviceTypeId, int tenantId) throws + ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting application data from the database"); + log.debug(String.format("Filter: limit=%s, offset=%s", filter.getLimit(), filter.getOffset())); + } + int paramIndex = 1; + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "INNER JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + + "INNER JOIN (SELECT ID FROM AP_APP ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY) AS app_data ON app_data.ID = AP_APP.ID " + + "WHERE AP_APP.TENANT_ID = ?"; + + if (filter == null) { + String msg = "Filter is not instantiated."; + log.error(msg); + throw new ApplicationManagementDAOException(msg); + } + + if (!StringUtils.isEmpty(filter.getAppType())) { + sql += " AND AP_APP.TYPE = ?"; + } + if (!StringUtils.isEmpty(filter.getAppName())) { + sql += " AND LOWER (AP_APP.NAME) "; + if (filter.isFullMatch()) { + sql += "= ?"; + } else { + sql += "LIKE ?"; + } + } + if (!StringUtils.isEmpty(filter.getSubscriptionType())) { + sql += " AND AP_APP.SUB_TYPE = ?"; + } + if (filter.getMinimumRating() > 0) { + sql += " AND AP_APP.RATING >= ?"; + } + if (!StringUtils.isEmpty(filter.getVersion())) { + sql += " AND AP_APP_RELEASE.VERSION = ?"; + } + if (!StringUtils.isEmpty(filter.getAppReleaseType())) { + sql += " AND AP_APP_RELEASE.RELEASE_TYPE = ?"; + } + if (!StringUtils.isEmpty(filter.getAppReleaseState())) { + sql += " AND AP_APP_RELEASE.CURRENT_STATE = ?"; + } + if (deviceTypeId != -1) { + sql += " AND AP_APP.DEVICE_TYPE_ID = ?"; + } + + if (filter.getLimit() == -1) { + sql = sql.replace("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", ""); + } + + String sortingOrder = "ASC"; + if (!StringUtils.isEmpty(filter.getSortBy() )) { + sortingOrder = filter.getSortBy(); + } + sql += " ORDER BY APP_ID " + sortingOrder; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql); + ){ + if (filter.getLimit() != -1) { + stmt.setInt(paramIndex++, filter.getOffset()); + if (filter.getLimit() == 0) { + stmt.setInt(paramIndex++, 100); + } else { + stmt.setInt(paramIndex++, filter.getLimit()); + } + } + stmt.setInt(paramIndex++, tenantId); + + if (filter.getAppType() != null && !filter.getAppType().isEmpty()) { + stmt.setString(paramIndex++, filter.getAppType()); + } + if (filter.getAppName() != null && !filter.getAppName().isEmpty()) { + if (filter.isFullMatch()) { + stmt.setString(paramIndex++, filter.getAppName().toLowerCase()); + } else { + stmt.setString(paramIndex++, "%" + filter.getAppName().toLowerCase() + "%"); + } + } + if (!StringUtils.isEmpty(filter.getSubscriptionType())) { + stmt.setString(paramIndex++, filter.getSubscriptionType()); + } + if (filter.getMinimumRating() > 0) { + stmt.setInt(paramIndex++, filter.getMinimumRating()); + } + if (!StringUtils.isEmpty(filter.getVersion())) { + stmt.setString(paramIndex++, filter.getVersion()); + } + if (!StringUtils.isEmpty(filter.getAppReleaseType())) { + stmt.setString(paramIndex++, filter.getAppReleaseType()); + } + if (!StringUtils.isEmpty(filter.getAppReleaseState())) { + stmt.setString(paramIndex++, filter.getAppReleaseState()); + } + if (deviceTypeId > 0 ) { + stmt.setInt(paramIndex, deviceTypeId); + } + try (ResultSet rs = stmt.executeQuery() ) { + return DAOUtil.loadApplications(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection while getting application list for the " + + "tenant " + tenantId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting application list for the tenant " + tenantId + ". While " + + "executing " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java new file mode 100644 index 0000000000..ffe45ba3d3 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java @@ -0,0 +1,623 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.application.release; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.Rating; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; +import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; + + /** + * GenericApplicationReleaseDAOImpl holds the implementation of ApplicationRelease related DAO operations. + */ +public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements ApplicationReleaseDAO { + + private static final Log log = LogFactory.getLog(GenericApplicationReleaseDAOImpl.class); + + @Override + public ApplicationReleaseDTO createRelease(ApplicationReleaseDTO applicationReleaseDTO, int appId, int tenantId) + throws ApplicationManagementDAOException { + String sql = "INSERT INTO AP_APP_RELEASE " + + "(DESCRIPTION," + + "VERSION," + + "TENANT_ID," + + "UUID," + + "RELEASE_TYPE," + + "PACKAGE_NAME," + + "APP_PRICE, " + + "INSTALLER_LOCATION," + + "ICON_LOCATION," + + "BANNER_LOCATION," + + "SC_1_LOCATION," + + "SC_2_LOCATION," + + "SC_3_LOCATION," + + "APP_HASH_VALUE," + + "SHARED_WITH_ALL_TENANTS," + + "APP_META_INFO," + + "SUPPORTED_OS_VERSIONS," + + "CURRENT_STATE," + + "AP_APP_ID) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)){ + statement.setString(1, applicationReleaseDTO.getDescription()); + statement.setString(2, applicationReleaseDTO.getVersion()); + statement.setInt(3, tenantId); + statement.setString(4, applicationReleaseDTO.getUuid()); + statement.setString(5, String.valueOf(applicationReleaseDTO.getReleaseType())); + statement.setString(6, String.valueOf(applicationReleaseDTO.getPackageName())); + statement.setDouble(7, applicationReleaseDTO.getPrice()); + statement.setString(8, applicationReleaseDTO.getInstallerName()); + statement.setString(9, applicationReleaseDTO.getIconName()); + statement.setString(10, applicationReleaseDTO.getBannerName()); + statement.setString(11, applicationReleaseDTO.getScreenshotName1()); + statement.setString(12, applicationReleaseDTO.getScreenshotName2()); + statement.setString(13, applicationReleaseDTO.getScreenshotName3()); + statement.setString(14, applicationReleaseDTO.getAppHashValue()); + statement.setBoolean(15, applicationReleaseDTO.getIsSharedWithAllTenants()); + statement.setString(16, applicationReleaseDTO.getMetaData()); + statement.setString(17, applicationReleaseDTO.getSupportedOsVersions()); + statement.setString(18, applicationReleaseDTO.getCurrentState().toUpperCase()); + statement.setInt(19, appId); + statement.executeUpdate(); + try(ResultSet resultSet = statement.getGeneratedKeys()){ + if (resultSet.next()) { + applicationReleaseDTO.setId(resultSet.getInt(1)); + } + return applicationReleaseDTO; + } + } + } catch (DBConnectionException e) { + String msg = "Database Connection error occurred while trying to release a new version for application which" + + " has app ID: " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Exception while trying to release an application by executing the query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public ApplicationReleaseDTO getReleaseByUUID( String uuid, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT " + + "AR.ID AS RELEASE_ID, " + + "AR.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AR.VERSION AS RELEASE_VERSION, " + + "AR.UUID AS RELEASE_UUID, " + + "AR.RELEASE_TYPE AS RELEASE_TYPE, " + + "AR.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AR.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AR.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AR.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AR.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AR.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AR.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AR.APP_PRICE AS RELEASE_PRICE, " + + "AR.APP_META_INFO AS RELEASE_META_INFO, " + + "AR.PACKAGE_NAME AS PACKAGE_NAME, " + + "AR.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AR.RATING AS RELEASE_RATING, " + + "AR.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AR.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP_RELEASE AS AR " + + "WHERE AR.UUID = ? AND AR.TENANT_ID = ?"; + + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, uuid); + statement.setInt(2, tenantId); + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + return DAOUtil.constructAppReleaseDTO(resultSet); + } + return null; + } + } + } catch (DBConnectionException e) { + String msg = "Database connection error occurred while trying to get application release details which has " + + "UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = + "Error while getting application release details which has UUID: " + uuid + " , while executing" + + " the query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void updateRatingValue(String uuid, double rating, int ratedUsers) throws ApplicationManagementDAOException { + String sql = "UPDATE " + + "AP_APP_RELEASE " + + "SET " + + "RATING = ?, " + + "RATED_USERS = ? " + + "WHERE UUID = ?"; + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)){ + statement.setDouble(1, rating); + statement.setInt(2, ratedUsers); + statement.setString(3, uuid); + statement.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Database connection error occurred while trying to update the application release rating " + + "value for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL exception occured while updating the release rating value. Executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public Rating getReleaseRating(String uuid, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT " + + "RATING, " + + "RATED_USERS " + + "FROM AP_APP_RELEASE " + + "WHERE UUID = ? AND TENANT_ID = ?"; + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, uuid); + statement.setInt(2, tenantId); + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + Rating rating = new Rating(); + rating.setRatingValue(resultSet.getDouble("RATING")); + rating.setNoOfUsers(resultSet.getInt("RATED_USERS")); + return rating; + } + } + } + return null; + } catch (DBConnectionException e) { + String msg = "Database connection error occured when try to get application release rating which has " + + "application release UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL exception occured whn processing query: " + sql + " to get application release rating " + + "which has application release uuid: " + uuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getReleaseRatings(String uuid, int tenantId) throws ApplicationManagementDAOException { + List ratingValues = new ArrayList<>(); + String sql = "SELECT " + + "RATING " + + "FROM AP_APP_RELEASE " + + "WHERE " + + "AP_APP_ID = (SELECT AP_APP_ID FROM AP_APP_RELEASE WHERE UUID = ?) AND " + + "TENANT_ID = ?"; + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, uuid); + statement.setInt(2, tenantId); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + ratingValues.add(resultSet.getDouble("RATING")); + } return ratingValues; + } + } + } catch (DBConnectionException e) { + String msg = "Database connection exception occurred when getting all release rating values for a " + + "particular application."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL exception occurred while getting all release rating values for a particular application. " + + "Executed query is" + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public ApplicationReleaseDTO updateRelease(ApplicationReleaseDTO applicationReleaseDTO, int tenantId) + throws ApplicationManagementDAOException { + String sql = "UPDATE AP_APP_RELEASE " + + "SET " + + "DESCRIPTION = ?, " + + "VERSION = ?, " + + "UUID = ?, " + + "RELEASE_TYPE = ?, " + + "PACKAGE_NAME = ?, " + + "APP_PRICE = ?, " + + "INSTALLER_LOCATION = ?, " + + "BANNER_LOCATION = ?, " + + "ICON_LOCATION = ?, " + + "SC_1_LOCATION = ?, " + + "SC_2_LOCATION = ?, " + + "SC_3_LOCATION = ?, " + + "APP_HASH_VALUE = ?, " + + "SHARED_WITH_ALL_TENANTS = ?, " + + "APP_META_INFO = ?, " + + "SUPPORTED_OS_VERSIONS = ?"; + + if (applicationReleaseDTO.getCurrentState() != null) { + sql += ", CURRENT_STATE = ? "; + } + + sql += " WHERE ID = ? AND TENANT_ID = ? "; + + int x = 17; + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, applicationReleaseDTO.getDescription()); + statement.setString(2, applicationReleaseDTO.getVersion()); + statement.setString(3, applicationReleaseDTO.getUuid()); + statement.setString(4, applicationReleaseDTO.getReleaseType()); + statement.setString(5, applicationReleaseDTO.getPackageName()); + statement.setDouble(6, applicationReleaseDTO.getPrice()); + statement.setString(7, applicationReleaseDTO.getInstallerName()); + statement.setString(8, applicationReleaseDTO.getBannerName()); + statement.setString(9, applicationReleaseDTO.getIconName()); + statement.setString(10, applicationReleaseDTO.getScreenshotName1()); + statement.setString(11, applicationReleaseDTO.getScreenshotName2()); + statement.setString(12, applicationReleaseDTO.getScreenshotName3()); + statement.setString(13, applicationReleaseDTO.getAppHashValue()); + statement.setBoolean(14, applicationReleaseDTO.getIsSharedWithAllTenants()); + statement.setString(15, applicationReleaseDTO.getMetaData()); + statement.setString(16, applicationReleaseDTO.getSupportedOsVersions()); + + if (applicationReleaseDTO.getCurrentState() != null) { + statement.setString(x++, applicationReleaseDTO.getCurrentState().toUpperCase()); + } + statement.setInt(x++, applicationReleaseDTO.getId()); + statement.setInt(x, tenantId); + if (statement.executeUpdate() == 0) { + return null; + } + } + } catch (DBConnectionException e) { + String msg = "Database connection exception occured while trying to update the application release which " + + "has application release ID: " + applicationReleaseDTO.getId(); + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL exception occured while updating the application release which has release ID: " + + applicationReleaseDTO.getId() + ". Executed query is " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + return applicationReleaseDTO; + } + + @Override + public void deleteRelease(int id) throws ApplicationManagementDAOException { + String sql = "DELETE " + + "FROM AP_APP_RELEASE " + + "WHERE ID = ?"; + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setInt(1, id); + statement.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Database connection exception occurred while trying to delete the application release which " + + "has ID: " + id; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL exception occurred while deleting the release for release ID: " + id + ",while executing" + + " the query sql " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteReleases(List applicationReleaseIds) throws ApplicationManagementDAOException{ + String sql = "DELETE " + + "FROM AP_APP_RELEASE " + + "WHERE ID = ?"; + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + for (Integer releaseId : applicationReleaseIds) { + statement.setInt(1, releaseId); + statement.addBatch(); + } + statement.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Database connection exception occurred while trying to delete application releases for given " + + "application release ids"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL exception occurred while execute delete query for deleting given application releases. " + + "Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + + @Override + public boolean verifyReleaseExistenceByHash(String hashVal, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Verifying application release existence by application hash value: " + hashVal); + } + String sql = "SELECT " + + "AR.ID AS RELEASE_ID " + + "FROM AP_APP_RELEASE AS AR " + + "WHERE AR.APP_HASH_VALUE = ? AND " + + "AR.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, hashVal); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Database connection error occurred while verifying release existence for app release hash " + + "value. Hash value: " + hashVal; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting application release details for application release hash value: " + + hashVal + " While executing query "; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public String getPackageName(String releaseUuid, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting package name of the application release by application id:" + releaseUuid); + } + String sql = "SELECT " + + "AR.PACKAGE_NAME AS PACKAGE_NAME " + + "FROM AP_APP_RELEASE AS AR " + + "WHERE AR.UUID = ? " + + "AND AR.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, releaseUuid); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved package name of the application release with the UUID: " + + releaseUuid); + } + if (rs.next()) { + return rs.getString("PACKAGE_NAME"); + } + return null; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get application release package name " + + "which has application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting package name of the application release with app UUID: " + + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public String getReleaseHashValue(String uuid, int tenantId) throws ApplicationManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("Getting application release artifact stored location paths for: " + uuid); + } + String sql = "SELECT " + + "AR.APP_HASH_VALUE AS HASH_VALUE " + + "FROM AP_APP_RELEASE AR " + + "WHERE AR.UUID = ? AND AR.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, uuid); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved application release hash value for application release " + + "which has release UUID: " + uuid); + } + if(rs.next()){ + return rs.getString("HASH_VALUE"); + } + return null; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get hash value for application release " + + "which has application release UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when executing query to get application release hash value which has " + + "application release uuid: " + uuid + ". Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean isActiveReleaseExisitForPackageName(String packageName, int tenantId, String inactiveState) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Verifying application release existence for package name:" + packageName); + } + String sql = "SELECT AR.ID AS RELEASE_ID " + + "FROM AP_APP_RELEASE AS AR " + + "WHERE AR.PACKAGE_NAME = ? AND " + + "AR.CURRENT_STATE != ? AND " + + "AR.TENANT_ID = ? LIMIT 1"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, packageName); + stmt.setString(2, inactiveState); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to verify the existence of package name for " + + "active application release. Package name: " + packageName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL error occurred while verifying the existence of package name for active application " + + "release. package name: " + packageName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean hasExistInstallableAppRelease(String releaseUuid, String installableStateName, int tenantId) + throws ApplicationManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("Verifying application release existence in the installable state: :" + installableStateName); + } + String sql = "SELECT AR.ID AS RELEASE_ID " + + "FROM AP_APP_RELEASE AS AR " + + "WHERE AR.CURRENT_STATE = ? AND " + + "AR.AP_APP_ID = (SELECT AP_APP_ID FROM AP_APP_RELEASE WHERE UUID = ?) AND " + + "AR.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, installableStateName); + stmt.setString(2, releaseUuid); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to verify the existence of app release for " + + "application release uuid ;" + releaseUuid + " and application release state " + + installableStateName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to verify the existence of app release for application " + + "release uuid ;" + releaseUuid + " and application release state " + installableStateName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getReleaseByPackages(List packages, int tenantId) throws + ApplicationManagementDAOException { + + String sql = "SELECT " + + "AR.ID AS RELEASE_ID, " + + "AR.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AR.VERSION AS RELEASE_VERSION, " + + "AR.UUID AS RELEASE_UUID, " + + "AR.RELEASE_TYPE AS RELEASE_TYPE, " + + "AR.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AR.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AR.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AR.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AR.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AR.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AR.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AR.APP_PRICE AS RELEASE_PRICE, " + + "AR.APP_META_INFO AS RELEASE_META_INFO, " + + "AR.PACKAGE_NAME AS PACKAGE_NAME, " + + "AR.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AR.RATING AS RELEASE_RATING, " + + "AR.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AR.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP_RELEASE AS AR " + + "WHERE AR.PACKAGE_NAME IN ("; + + StringJoiner joiner = new StringJoiner(",", sql, ") AND AR.TENANT_ID = ? "); + packages.stream().map(ignored -> "?").forEach(joiner::add); + sql = joiner.toString(); + + try { + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + int index = 1; + for (String packageName : packages) { + statement.setObject(index++, packageName); + } + statement.setInt(index, tenantId); + try (ResultSet resultSet = statement.executeQuery()) { + List releaseDTOs = new ArrayList<>(); + while (resultSet.next()) { + releaseDTOs.add(DAOUtil.constructAppReleaseDTO(resultSet)); + } + return releaseDTOs; + } + } + } catch (DBConnectionException e) { + String msg = "Database connection error occurred while trying to get application release details which has " + + "packages: " + String.join(", ", packages); + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = + "Error while getting application release details which has packages: " + String.join(", ", packages) + + " , while executing the query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/OracleApplicationReleaseDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/OracleApplicationReleaseDAOImpl.java new file mode 100644 index 0000000000..d030fa82b7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/OracleApplicationReleaseDAOImpl.java @@ -0,0 +1,68 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.application.release; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * This handles Application Release operations which are specific to MSSQL. + */ +public class OracleApplicationReleaseDAOImpl extends GenericApplicationReleaseDAOImpl { + private static final Log log = LogFactory.getLog(GenericApplicationReleaseDAOImpl.class); + + public boolean isActiveReleaseExisitForPackageName(String packageName, int tenantId, String inactiveState) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Verifying application release existence for package name:" + packageName); + } + String sql = "SELECT AR.ID AS RELEASE_ID " + + "FROM AP_APP_RELEASE AS AR " + + "WHERE AR.PACKAGE_NAME = ? AND " + + "AR.CURRENT_STATE != ? AND " + + "AR.TENANT_ID = ? ORDER BY AR.ID OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY;"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, packageName); + stmt.setString(2, inactiveState); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to verify the existence of package name for " + + "active application release. Package name: " + packageName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL error occurred while verifying the existence of package name for active application " + + "release. package name: " + packageName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/SQLServerApplicationReleaseDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/SQLServerApplicationReleaseDAOImpl.java new file mode 100644 index 0000000000..4afcdf0928 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/SQLServerApplicationReleaseDAOImpl.java @@ -0,0 +1,68 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.application.release; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * This handles Application Release operations which are specific to MSSQL. + */ +public class SQLServerApplicationReleaseDAOImpl extends GenericApplicationReleaseDAOImpl { + private static final Log log = LogFactory.getLog(GenericApplicationReleaseDAOImpl.class); + + public boolean isActiveReleaseExisitForPackageName(String packageName, int tenantId, String inactiveState) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Verifying application release existence for package name:" + packageName); + } + String sql = "SELECT AR.ID AS RELEASE_ID " + + "FROM AP_APP_RELEASE AS AR " + + "WHERE AR.PACKAGE_NAME = ? AND " + + "AR.CURRENT_STATE != ? AND " + + "AR.TENANT_ID = ? ORDER BY AR.ID OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY;"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, packageName); + stmt.setString(2, inactiveState); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to verify the existence of package name for " + + "active application release. Package name: " + packageName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL error occurred while verifying the existence of package name for active application " + + "release. package name: " + packageName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/GenericLifecycleStateDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/GenericLifecycleStateDAOImpl.java new file mode 100644 index 0000000000..21406dc004 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/GenericLifecycleStateDAOImpl.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao.impl.lifecyclestate; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.AppLifecycleState; +import org.wso2.carbon.device.application.mgt.common.LifecycleState; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.dao.LifecycleStateDAO; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; +import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl; +import org.wso2.carbon.device.application.mgt.core.exception.LifeCycleManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * Concrete implementation for Lifecycle related DB operations. + */ +public class GenericLifecycleStateDAOImpl extends AbstractDAOImpl implements LifecycleStateDAO { + + private static final Log log = LogFactory.getLog(GenericLifecycleStateDAOImpl.class); + + @Override + public LifecycleState getLatestLifecycleState(String uuid) throws LifeCycleManagementDAOException{ + String sql = "SELECT " + + "CURRENT_STATE, " + + "PREVIOUS_STATE, " + + "UPDATED_AT, " + + "UPDATED_BY " + + "FROM " + + "AP_APP_LIFECYCLE_STATE " + + "WHERE " + + "AP_APP_RELEASE_ID = (SELECT ID FROM AP_APP_RELEASE WHERE UUID = ?) ORDER BY UPDATED_AT DESC"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, uuid); + try (ResultSet rs = stmt.executeQuery()){ + return constructLifecycle(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get latest lifecycle state for a specific" + + " application. Application release UUID: " + uuid; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to get latest lifecycle state for a specific " + + "application. Application release UUID: " + uuid + ". Executed Query: " + sql; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } + } + + @Override + public String getAppReleaseCreatedUsername(int appId, String uuid, int tenantId) throws LifeCycleManagementDAOException{ + PreparedStatement stmt = null; + ResultSet rs = null; + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT " + + "UPDATED_BY " + + "FROM AP_APP_LIFECYCLE_STATE " + + "WHERE " + + "AP_APP_ID = ? AND " + + "AP_APP_RELEASE_ID = (SELECT ID FROM AP_APP_RELEASE WHERE UUID=?) AND " + + "CURRENT_STATE = ? AND " + + "TENANT_ID = ? ORDER BY UPDATED_AT DESC LIMIT 1"; + + stmt = conn.prepareStatement(sql); + stmt.setInt(1, appId); + stmt.setString(2, uuid); + stmt.setString(3, AppLifecycleState.CREATED.toString()); + stmt.setInt(4, tenantId); + rs = stmt.executeQuery(); + if (rs.next()) { + return rs.getString("UPDATED_BY"); + } + return null; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get the created user of a release which " + + "has APP ID " + appId + " and release UUID ." + uuid; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred when getting the created user of a release which has APP ID " + appId + + " and release UUID ." + uuid; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } finally { + DAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public List getLifecycleStates(int appReleaseId, int tenantId) throws LifeCycleManagementDAOException { + List lifecycleStates = new ArrayList<>(); + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT " + + "CURRENT_STATE, " + + "PREVIOUS_STATE, " + + "UPDATED_AT, " + + "UPDATED_BY " + + "FROM AP_APP_LIFECYCLE_STATE " + + "WHERE AP_APP_RELEASE_ID = ? AND " + + "TENANT_ID = ? " + + "ORDER BY UPDATED_AT ASC"; + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1,appReleaseId); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + while (rs.next()) { + lifecycleStates.add(constructLifecycle(rs)); + } + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting lifecycle states for an " + + "application which has application ID: " + appReleaseId; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while retrieving lifecycle states for application which has application " + + "ID: " + appReleaseId; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } + return lifecycleStates; + } + + @Override + public void addLifecycleState(LifecycleState state, int appReleaseId, int tenantId) throws LifeCycleManagementDAOException { + String sql = "INSERT INTO AP_APP_LIFECYCLE_STATE " + + "(CURRENT_STATE, " + + "PREVIOUS_STATE, " + + "TENANT_ID, " + + "UPDATED_BY, " + + "UPDATED_AT, " + + "REASON, " + + "AP_APP_RELEASE_ID) " + + "VALUES (?, ?, ?, ?, ?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, state.getCurrentState().toUpperCase()); + stmt.setString(2, state.getPreviousState().toUpperCase()); + stmt.setInt(3, tenantId); + stmt.setString(4, state.getUpdatedBy()); + stmt.setTimestamp(5, timestamp); + stmt.setString(6, state.getReasonForChange()); + stmt.setInt(7, appReleaseId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to add lifecycle state for application " + + "release which has ID " + appReleaseId + ". Lifecycle state " + state.getCurrentState(); + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing the query to add lifecycle state for application release which" + + " has ID " + appReleaseId + ". Lifecycle state " + state.getCurrentState() + ". Executed query: " + + sql; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } + } + + @Override + public void deleteLifecycleStateByReleaseId(int releaseId) throws LifeCycleManagementDAOException { + String sql = "DELETE " + + "FROM AP_APP_LIFECYCLE_STATE " + + "WHERE AP_APP_RELEASE_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, releaseId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to delete lifecycle states for application " + + "release ID: " + releaseId; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing the query to delete lifecycle states for application release" + + " ID: " + releaseId + ". Executed query " + sql; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } + } + + @Override + public void deleteLifecycleStates(List appReleaseIds) throws LifeCycleManagementDAOException{ + String sql = "DELETE " + + "FROM AP_APP_LIFECYCLE_STATE " + + "WHERE AP_APP_RELEASE_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer releaseId : appReleaseIds) { + stmt.setInt(1, releaseId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for deleting application life-cycle states " + + "for given application Ids."; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to delete application life-cycle states for given " + + "application Ids."; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } + } + + /*** + * This method is capable to construct {@link LifecycleState} object by accessing given {@link ResultSet} + * @param rs Result Set of an executed query + * @return {@link LifecycleState} + * @throws LifeCycleManagementDAOException if {@link SQLException} occurs when creating the {@link LifecycleState} + * by accessing given {@link ResultSet}. In this particular method {@link SQLException} could occurs if the + * columnLabel is not valid or if a database access error occurs or this method is called on a closed result set + * + */ + private LifecycleState constructLifecycle(ResultSet rs) throws LifeCycleManagementDAOException { + LifecycleState lifecycleState = null; + try { + if (rs !=null && rs.next()) { + lifecycleState = new LifecycleState(); + lifecycleState.setCurrentState(rs.getString("CURRENT_STATE")); + lifecycleState.setPreviousState(rs.getString("PREVIOUS_STATE")); + lifecycleState.setUpdatedAt(rs.getTimestamp("UPDATED_AT")); + lifecycleState.setUpdatedBy(rs.getString("UPDATED_BY")); + } + } catch (SQLException e) { + String msg = "Error occurred while construct lifecycle state by data which is retrieved from SQL query"; + log.error(msg, e); + throw new LifeCycleManagementDAOException(msg, e); + } + return lifecycleState; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/OracleLifecycleStateDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/OracleLifecycleStateDAOImpl.java new file mode 100644 index 0000000000..e278574c39 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/OracleLifecycleStateDAOImpl.java @@ -0,0 +1,24 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.lifecyclestate; + +/** + * This handles App Lifecycle operations which are specific to MSSQL. + */ +public class OracleLifecycleStateDAOImpl extends GenericLifecycleStateDAOImpl{ +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/SQLServerLifecycleStateDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/SQLServerLifecycleStateDAOImpl.java new file mode 100644 index 0000000000..063e3ccd56 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/lifecyclestate/SQLServerLifecycleStateDAOImpl.java @@ -0,0 +1,24 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.lifecyclestate; + +/** + * This handles App Lifecycle operations which are specific to MSSQL. + */ +public class SQLServerLifecycleStateDAOImpl extends GenericLifecycleStateDAOImpl{ +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/GenericReviewDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/GenericReviewDAOImpl.java new file mode 100644 index 0000000000..a727c52359 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/GenericReviewDAOImpl.java @@ -0,0 +1,597 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao.impl.review; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.wso2.carbon.device.application.mgt.common.PaginationRequest; +import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.dao.ReviewDAO; +import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; +import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl; +import org.wso2.carbon.device.application.mgt.core.exception.ReviewManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.util.Constants; + +import java.sql.SQLException; +import java.sql.ResultSet; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.StringJoiner; + +/** + * This handles ReviewDAO related operations. + */ + +public class GenericReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO { + + private static final Log log = LogFactory.getLog(GenericReviewDAOImpl.class); + private String sql; + + @Override + public int addReview(ReviewDTO reviewDTO, int appReleaseId, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to add review for application release. Application Release UUID: " + + appReleaseId); + } + sql = "INSERT INTO AP_APP_REVIEW " + + "(TENANT_ID, " + + "COMMENT, " + + "ROOT_PARENT_ID," + + "IMMEDIATE_PARENT_ID, " + + "RATING, " + + "USERNAME, " + + "CREATED_AT, " + + "MODIFIED_AT, " + + "AP_APP_RELEASE_ID) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ? )"; + try { + int reviewId = -1; + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + Connection conn = this.getDBConnection(); + try (PreparedStatement statement = conn.prepareStatement(sql, new String[] { "id" })) { + statement.setInt(1, tenantId); + statement.setString(2, reviewDTO.getContent()); + statement.setInt(3, reviewDTO.getRootParentId()); + statement.setInt(4, reviewDTO.getImmediateParentId()); + statement.setInt(5, reviewDTO.getRating()); + statement.setString(6, reviewDTO.getUsername()); + statement.setTimestamp(7, timestamp); + statement.setTimestamp(8, timestamp); + statement.setInt(9, appReleaseId); + statement.executeUpdate(); + try (ResultSet rs = statement.getGeneratedKeys()) { + if (rs.next()) { + reviewId = rs.getInt(1); + } + } + return reviewId; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to add a review for application release which" + + " has ID: "+ appReleaseId + " and Tenant Id: " + tenantId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL statement to add application review. Application ID: " + + appReleaseId + " and tenant " + tenantId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public boolean hasUerReviewedApp(List appReleaseIds, String username, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received to DAO Layer to check whether user have already reviewed or not for the " + + "application. Commenting user: " + username + " and tenant-id: " + tenantId); + } + try { + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT rv.ID FROM AP_APP_REVIEW rv WHERE rv.AP_APP_RELEASE_ID IN (", + ") AND rv.USERNAME = ? AND rv.TENANT_ID = ?"); + appReleaseIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + int index = 1; + for (Integer deviceId : appReleaseIds) { + ps.setObject(index++, deviceId); + } + ps.setString(index++, username); + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occured while getting the database connection when checking whether user has already " + + "commented for the application or not"; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured while executing the SQL statement to check whether user has already commented " + + "for the application or not"; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public ReviewDTO updateReview(ReviewDTO reviewDTO, int reviewId, boolean isActiveReview, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received to DAO Layer to update the Review which has ID " + reviewId); + } + sql = "UPDATE " + + "AP_APP_REVIEW " + + "SET " + + "COMMENT = ?, " + + "RATING = ?, " + + "MODIFIED_AT = ?, " + + "ACTIVE_REVIEW = ? " + + "WHERE ID = ? AND TENANT_ID = ?"; + try { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + + Connection connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)){ + statement.setString(1, reviewDTO.getContent()); + statement.setInt(2, reviewDTO.getRating()); + statement.setTimestamp(3, timestamp); + statement.setBoolean(4, isActiveReview); + statement.setInt(5, reviewId); + statement.setInt(6, tenantId); + if (statement.executeUpdate() == 1) { + reviewDTO.setModifiedAt(timestamp); + return reviewDTO; + } + return null; + } + } catch (DBConnectionException e) { + String msg = "Error occured while getting the db connection to update review for review ID: " + reviewId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing review updating query for review ID: " + reviewId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public ReviewDTO getReview(int reviewId, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received to DAO Layer to get review for review ID: " + reviewId); + } + sql = "SELECT " + + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.ID = ? AND AP_APP_REVIEW.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement statement = conn.prepareStatement(sql)) { + statement.setInt(1, reviewId); + statement.setInt(2, tenantId); + try (ResultSet rs = statement.executeQuery()) { + return DAOUtil.loadReview(rs); + } + } + } catch (DBConnectionException e) { + String msg = "DB Connection Exception occurred while retrieving information of the review for review ID: " + + reviewId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured while executing SQL statement to get review data for review ID: " + reviewId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "Found more than one review for review ID: " + reviewId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + + @Override + public List getAllReleaseReviews(int releaseId, PaginationRequest request, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting all application release reviews for the application release ID: " + releaseId); + } + sql = "SELECT " + + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID = ? AND " + + "AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement statement = conn.prepareStatement(sql)) { + statement.setInt(1, releaseId); + statement.setInt(2, Constants.REVIEW_PARENT_ID); + statement.setInt(3, tenantId); + statement.setInt(4, request.getLimit()); + statement.setInt(5, request.getOffSet()); + try (ResultSet rs = statement.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all app release reviews for " + + "application release ID: " + releaseId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing the SQL statement to get all app release reviews for " + + "application release ID: " + releaseId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getAllActiveAppReviews(List releaseIds, PaginationRequest request, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all active application reviews."); + } + try { + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT " + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID IN (", + ") AND AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.ACTIVE_REVIEW = true AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"); + releaseIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + int index = 1; + for (Integer releaseId : releaseIds) { + ps.setObject(index++, releaseId); + } + ps.setInt(index++, Constants.REVIEW_PARENT_ID); + ps.setInt(index++, tenantId); + ps.setInt(index++, request.getLimit()); + ps.setInt(index, request.getOffSet()); + try (ResultSet rs = ps.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all active app reviews."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to get all active app reviews."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getAllActiveAppReviewsOfUser(List releaseIds, PaginationRequest request, + String username, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all active application reviews of user " + username); + } + try { + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID IN (", + ") AND AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.ACTIVE_REVIEW = true AND " + + "AP_APP_REVIEW.USERNAME = ? AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"); + releaseIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + int index = 1; + for (Integer releaseId : releaseIds) { + ps.setObject(index++, releaseId); + } + ps.setInt(index++, Constants.REVIEW_PARENT_ID); + ps.setString(index++, username); + ps.setInt(index++, tenantId); + ps.setInt(index++, request.getLimit()); + ps.setInt(index, request.getOffSet()); + try (ResultSet rs = ps.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all active app reviews of user " + + username; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to get all active app reviews of user " + username; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getReplyComments(int parentId, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting all reply comments for review which has review ID: " + parentId); + } + try { + Connection conn = this.getDBConnection(); + sql = "SELECT " + + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE " + + "AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.TENANT_ID = ?"; + try (PreparedStatement statement = conn.prepareStatement(sql)) { + statement.setInt(1, parentId); + statement.setInt(2, tenantId); + try (ResultSet rs = statement.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when getting reply comments for a review " + + "which has reviw ID: " + parentId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to ge reply comments for a review which has reviw ID: " + + parentId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getAllAppReleaseRatingValues(String uuid, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting all app release rating values for app release UUID: " + uuid); + } + sql = "SELECT " + + "AP_APP_REVIEW.RATING AS RATING " + + "FROM AP_APP_REVIEW, AP_APP_RELEASE " + + "WHERE " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID AND " + + "AP_APP_RELEASE.UUID = ? AND " + + "AP_APP_REVIEW.TENANT_ID = AP_APP_RELEASE.TENANT_ID AND " + + "AP_APP_REVIEW.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement statement = conn.prepareStatement(sql)) { + statement.setString(1, uuid); + statement.setInt(2, tenantId); + try (ResultSet rs = statement.executeQuery()) { + List reviews = new ArrayList<>(); + while (rs.next()) { + reviews.add(rs.getInt("RATING")); + } + return reviews; + } + } + } catch (DBConnectionException e) { + String msg = "Error occured while getting DB connection to retrieve all rating values for the application " + + "release which has UUID:" + uuid; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured while executing SQL to retrieve all rating values for the application release " + + "which has UUID:" + uuid; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getAllAppRatingValues(List uuids, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all application rating values of an application."); + } + try { + int index = 1; + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT AP_APP_REVIEW.RATING AS RATING FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID WHERE AP_APP_RELEASE.UUID IN (", + ") AND AP_APP_REVIEW.ACTIVE_REVIEW = true AND AP_APP_REVIEW.TENANT_ID = ?"); + uuids.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String uuid : uuids) { + ps.setObject(index++, uuid); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + List reviews = new ArrayList<>(); + while (rs.next()) { + reviews.add(rs.getInt("RATING")); + } + return reviews; + } + } + } catch (DBConnectionException e) { + String msg = "Error occured while getting DB connection to retrieve all rating values for an application."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured while executing SQL to get all rating values for the application."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public void deleteReview(int reviewId, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to delete review which has review ID: " + reviewId); + } + try { + Connection conn = this.getDBConnection(); + sql = "DELETE " + + "FROM AP_APP_REVIEW " + + "WHERE " + + "ID = ? AND " + + "TENANT_ID = ?"; + try (PreparedStatement statement = conn.prepareStatement(sql)) { + statement.setInt(1, reviewId); + statement.setInt(2, tenantId); + statement.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occured while getting the database connection to delete review which has review ID: " + + reviewId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured while executing SQL to delete review which has review ID: " + reviewId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public void deleteReviews(List reviewIds, int tenantId) throws ReviewManagementDAOException{ + if (log.isDebugEnabled()) { + log.debug("DAO request is received to delete reviews for requesting review Ids."); + } + try { + Connection conn = this.getDBConnection(); + sql = "DELETE " + + "FROM AP_APP_REVIEW " + + "WHERE " + + "ID = ? AND " + + "TENANT_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer reviewId : reviewIds) { + stmt.setInt(1, reviewId); + stmt.setInt(2, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to delete reviews for given review Ids."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to delete reviews for given review Ids."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public void deleteAllChildCommentsOfReview(int rootParentId, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to delete child comments of a review."); + } + try { + Connection conn = this.getDBConnection(); + sql = "DELETE " + + "FROM AP_APP_REVIEW " + + "WHERE " + + "ROOT_PARENT_ID = ? AND " + + "TENANT_ID = ?"; + try (PreparedStatement statement = conn.prepareStatement(sql)){ + statement.setInt(1, rootParentId); + statement.setInt(2, tenantId); + statement.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occured while getting the database connection to delete all child comments of a review " + + "which has ID: " + rootParentId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured while executing SQL to delete all child comments of a review which has ID: " + + rootParentId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/OracleReviewDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/OracleReviewDAOImpl.java new file mode 100644 index 0000000000..2231560930 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/OracleReviewDAOImpl.java @@ -0,0 +1,237 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.review; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.PaginationRequest; +import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.exception.ReviewManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; + +/** + * This handles Application Review handling operations which are specific to Oracle. + */ +public class OracleReviewDAOImpl extends GenericReviewDAOImpl { + + private static final Log log = LogFactory.getLog(OracleReviewDAOImpl.class); + private String sql; + + @Override + public List getAllReleaseReviews(int releaseId, PaginationRequest request, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting all application release reviews for the application release ID: " + releaseId); + } + sql = "SELECT " + + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID = ? AND " + + "AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "ORDER BY AP_APP_REVIEW.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement statement = conn.prepareStatement(sql)) { + statement.setInt(1, releaseId); + statement.setInt(2, Constants.REVIEW_PARENT_ID); + statement.setInt(3, tenantId); + statement.setInt(4, request.getOffSet()); + statement.setInt(5, request.getLimit()); + try (ResultSet rs = statement.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all app release reviews for " + + "application release ID: " + releaseId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing the SQL statement to get all app release reviews for " + + "application release ID: " + releaseId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getAllActiveAppReviews(List releaseIds, PaginationRequest request, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all active application reviews."); + } + try { + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT " + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID IN (", + ") AND AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.ACTIVE_REVIEW = true AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "ORDER BY AP_APP_REVIEW.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"); + releaseIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + int index = 1; + for (Integer releaseId : releaseIds) { + ps.setObject(index++, releaseId); + } + ps.setInt(index++, Constants.REVIEW_PARENT_ID); + ps.setInt(index++, tenantId); + ps.setInt(index++, request.getOffSet()); + ps.setInt(index, request.getLimit()); + try (ResultSet rs = ps.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all active app reviews."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to get all active app reviews."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getAllActiveAppReviewsOfUser(List releaseIds, PaginationRequest request, + String username, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all active application reviews of user " + username); + } + try { + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID IN (", + ") AND AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.ACTIVE_REVIEW = true AND " + + "AP_APP_REVIEW.USERNAME = ? AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "ORDER BY AP_APP_REVIEW.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"); + releaseIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + int index = 1; + for (Integer releaseId : releaseIds) { + ps.setObject(index++, releaseId); + } + ps.setInt(index++, Constants.REVIEW_PARENT_ID); + ps.setString(index++, username); + ps.setInt(index++, tenantId); + ps.setInt(index++, request.getOffSet()); + ps.setInt(index, request.getLimit()); + try (ResultSet rs = ps.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all active app reviews of user " + + username; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to get all active app reviews of user " + username; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + public List getAllAppRatingValues(List uuids, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all application rating values of an application."); + } + try { + int index = 1; + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT AP_APP_REVIEW.RATING AS RATING FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID WHERE AP_APP_RELEASE.UUID IN (", + ") AND AP_APP_REVIEW.ACTIVE_REVIEW = 'true' AND AP_APP_REVIEW.TENANT_ID = ?"); + uuids.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String uuid : uuids) { + ps.setObject(index++, uuid); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + List reviews = new ArrayList<>(); + while (rs.next()) { + reviews.add(rs.getInt("RATING")); + } + return reviews; + } + } + } catch (DBConnectionException e) { + String msg = "Error occured while getting DB connection to retrieve all rating values for an application."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured while executing SQL to get all rating values for the application."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/SQLServerReviewDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/SQLServerReviewDAOImpl.java new file mode 100644 index 0000000000..d169a6190a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/SQLServerReviewDAOImpl.java @@ -0,0 +1,237 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.review; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.PaginationRequest; +import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.exception.ReviewManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; + +/** + * This handles Application Review handling operations which are specific to MsSQL. + */ +public class SQLServerReviewDAOImpl extends GenericReviewDAOImpl { + + private static final Log log = LogFactory.getLog(SQLServerReviewDAOImpl.class); + private String sql; + + @Override + public List getAllReleaseReviews(int releaseId, PaginationRequest request, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting all application release reviews for the application release ID: " + releaseId); + } + sql = "SELECT " + + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID = ? AND " + + "AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "ORDER BY AP_APP_REVIEW.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement statement = conn.prepareStatement(sql)) { + statement.setInt(1, releaseId); + statement.setInt(2, Constants.REVIEW_PARENT_ID); + statement.setInt(3, tenantId); + statement.setInt(4, request.getOffSet()); + statement.setInt(5, request.getLimit()); + try (ResultSet rs = statement.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all app release reviews for " + + "application release ID: " + releaseId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing the SQL statement to get all app release reviews for " + + "application release ID: " + releaseId; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getAllActiveAppReviews(List releaseIds, PaginationRequest request, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all active application reviews."); + } + try { + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT " + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID IN (", + ") AND AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.ACTIVE_REVIEW = 'true' AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "ORDER BY AP_APP_REVIEW.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"); + releaseIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + int index = 1; + for (Integer releaseId : releaseIds) { + ps.setObject(index++, releaseId); + } + ps.setInt(index++, Constants.REVIEW_PARENT_ID); + ps.setInt(index++, tenantId); + ps.setInt(index++, request.getOffSet()); + ps.setInt(index, request.getLimit()); + try (ResultSet rs = ps.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all active app reviews."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to get all active app reviews."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + + @Override + public List getAllActiveAppReviewsOfUser(List releaseIds, PaginationRequest request, + String username, int tenantId) + throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all active application reviews of user " + username); + } + try { + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "AP_APP_REVIEW.ID AS ID, " + + "AP_APP_REVIEW.COMMENT AS COMMENT, " + + "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, " + + "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, " + + "AP_APP_REVIEW.USERNAME AS USERNAME, " + + "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, " + + "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, " + + "AP_APP_REVIEW.RATING AS RATING, " + + "AP_APP_RELEASE.UUID AS UUID, " + + "AP_APP_RELEASE.VERSION AS VERSION " + + "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID " + + "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID IN (", + ") AND AP_APP_REVIEW.ROOT_PARENT_ID = ? AND " + + "AP_APP_REVIEW.ACTIVE_REVIEW = 'true' AND " + + "AP_APP_REVIEW.USERNAME = ? AND " + + "AP_APP_REVIEW.TENANT_ID = ? " + + "ORDER BY AP_APP_REVIEW.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"); + releaseIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + int index = 1; + for (Integer releaseId : releaseIds) { + ps.setObject(index++, releaseId); + } + ps.setInt(index++, Constants.REVIEW_PARENT_ID); + ps.setString(index++, username); + ps.setInt(index++, tenantId); + ps.setInt(index++, request.getOffSet()); + ps.setInt(index, request.getLimit()); + try (ResultSet rs = ps.executeQuery()) { + return DAOUtil.loadReviews(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get all active app reviews of user " + + username; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to get all active app reviews of user " + username; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } + public List getAllAppRatingValues(List uuids, int tenantId) throws ReviewManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("DAO request is received to Get all application rating values of an application."); + } + try { + int index = 1; + Connection conn = this.getDBConnection(); + StringJoiner joiner = new StringJoiner(",", + "SELECT AP_APP_REVIEW.RATING AS RATING FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON " + + "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID WHERE AP_APP_RELEASE.UUID IN (", + ") AND AP_APP_REVIEW.ACTIVE_REVIEW = 'true' AND AP_APP_REVIEW.TENANT_ID = ?"); + uuids.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String uuid : uuids) { + ps.setObject(index++, uuid); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + List reviews = new ArrayList<>(); + while (rs.next()) { + reviews.add(rs.getInt("RATING")); + } + return reviews; + } + } + } catch (DBConnectionException e) { + String msg = "Error occured while getting DB connection to retrieve all rating values for an application."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured while executing SQL to get all rating values for the application."; + log.error(msg, e); + throw new ReviewManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java new file mode 100644 index 0000000000..46621cb9d4 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java @@ -0,0 +1,1069 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao.impl.subscription; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.ExecutionStatus; +import org.wso2.carbon.device.application.mgt.common.SubAction; +import org.wso2.carbon.device.application.mgt.common.SubscriptionType; +import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO; +import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; + +public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements SubscriptionDAO { + private static Log log = LogFactory.getLog(GenericSubscriptionDAOImpl.class); + + @Override + public void addDeviceSubscription(String subscribedBy, List deviceIds, + String subscribedFrom, String installStatus, int releaseId, int tenantId) + throws ApplicationManagementDAOException { + String sql = "INSERT INTO " + + "AP_DEVICE_SUBSCRIPTION(" + + "SUBSCRIBED_BY, " + + "SUBSCRIBED_TIMESTAMP, " + + "ACTION_TRIGGERED_FROM, " + + "STATUS, " + + "DM_DEVICE_ID, " + + "AP_APP_RELEASE_ID," + + "TENANT_ID) " + + "VALUES (?, ?, ?, ?, ?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (Integer deviceId : deviceIds) { + stmt.setString(1, subscribedBy); + stmt.setTimestamp(2, timestamp); + stmt.setString(3, subscribedFrom); + stmt.setString(4, installStatus); + stmt.setInt(5, deviceId); + stmt.setInt(6, releaseId); + stmt.setInt(7, tenantId); + stmt.addBatch(); + if (log.isDebugEnabled()) { + log.debug("Adding a device subscription for device id " + deviceId + " and application " + + "release which has release id" + releaseId); + } + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occured while obtaining database connection to add device subscription for application " + + "release which has release Id" + releaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occured when processing SQL to add device subscription for application release which" + + " has release Id " + releaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void updateDeviceSubscription(String updateBy, List deviceIds, + String action, String actionTriggeredFrom, String installStatus, int releaseId, int tenantId) + throws ApplicationManagementDAOException { + boolean unsubscribed = false; + try { + String sql = "UPDATE AP_DEVICE_SUBSCRIPTION SET "; + + if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { + sql += "UNSUBSCRIBED = ?, UNSUBSCRIBED_BY = ?, UNSUBSCRIBED_TIMESTAMP = ?, "; + unsubscribed = true; + } else if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + sql += "UNSUBSCRIBED = ?, SUBSCRIBED_BY = ?, SUBSCRIBED_TIMESTAMP = ?, "; + } else { + String msg = "Found invalid action " + action + ". Hence can't construct the query."; + log.error(msg); + throw new ApplicationManagementDAOException(msg); + } + sql += "ACTION_TRIGGERED_FROM = ?, " + + "STATUS = ? " + + "WHERE " + + "DM_DEVICE_ID = ? AND " + + "AP_APP_RELEASE_ID = ? AND " + + "TENANT_ID = ?"; + + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (Integer deviceId : deviceIds) { + stmt.setBoolean(1, unsubscribed); + stmt.setString(2, updateBy); + stmt.setTimestamp(3, timestamp); + stmt.setString(4, actionTriggeredFrom); + stmt.setString(5, installStatus); + stmt.setInt(6, deviceId); + stmt.setInt(7, releaseId); + stmt.setInt(8, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update device subscriptions of " + + "application. Updated by: " + updateBy + " and updating action triggered from " + + actionTriggeredFrom; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to update the device subscriptions of application. " + + "Updated by: " + updateBy + " and updating action triggered from " + actionTriggeredFrom; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void addOperationMapping(int operationId, List deviceSubscriptionIds, int tenantId) + throws ApplicationManagementDAOException { + String sql = "INSERT INTO " + + "AP_APP_SUB_OP_MAPPING(" + + "OPERATION_ID, " + + "AP_DEVICE_SUBSCRIPTION_ID, " + + "TENANT_ID) " + + "VALUES (?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer subId : deviceSubscriptionIds) { + stmt.setInt(1, operationId); + stmt.setInt(2, subId); + stmt.setInt(3, tenantId); + stmt.addBatch(); + if (log.isDebugEnabled()) { + log.debug("Adding a operation mapping for subscription id " + subId); + } + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to add operation subscription mapping to DB"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to add operation subscription mapping to DB. Executed " + + "query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void addUserSubscriptions(int tenantId, String subscribedBy, List users, int releaseId) + throws ApplicationManagementDAOException { + String sql = "INSERT INTO " + + "AP_USER_SUBSCRIPTION(" + + "TENANT_ID, " + + "SUBSCRIBED_BY, " + + "SUBSCRIBED_TIMESTAMP, " + + "USER_NAME, " + + "AP_APP_RELEASE_ID) " + + "VALUES (?, ?, ?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (String user : users) { + stmt.setInt(1, tenantId); + stmt.setString(2, subscribedBy); + stmt.setTimestamp(3, timestamp); + stmt.setString(4, user); + stmt.setInt(5, releaseId); + stmt.addBatch(); + if (log.isDebugEnabled()) { + log.debug("Adding an user subscription for user " + user + " and application release which " + + "has Id " + releaseId + " to the database."); + } + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to add user subscription. Subscribing user " + + "is " + subscribedBy; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to add user subscription. Subscribing user is " + + subscribedBy + " and executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void addRoleSubscriptions(int tenantId, String subscribedBy, List roles, int releaseId) + throws ApplicationManagementDAOException { + String sql = "INSERT INTO " + + "AP_ROLE_SUBSCRIPTION(" + + "TENANT_ID, " + + "SUBSCRIBED_BY, " + + "SUBSCRIBED_TIMESTAMP, " + + "ROLE_NAME, " + + "AP_APP_RELEASE_ID) " + + "VALUES (?, ?, ?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (String role : roles) { + stmt.setInt(1, tenantId); + stmt.setString(2, subscribedBy); + stmt.setTimestamp(3, timestamp); + stmt.setString(4, role); + stmt.setInt(5, releaseId); + stmt.addBatch(); + if (log.isDebugEnabled()) { + log.debug("Adding a role subscription for role " + role + " and application release which " + + "has Id " + releaseId + " to the database."); + } + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to add role subscription. Subscribing role " + + "is " + subscribedBy; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to add role subscription. Subscribing role is " + + subscribedBy + " and executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void addGroupSubscriptions(int tenantId, String subscribedBy, List groups, int releaseId) + throws ApplicationManagementDAOException { + String sql = "INSERT INTO " + + "AP_GROUP_SUBSCRIPTION(" + + "TENANT_ID, " + + "SUBSCRIBED_BY, " + + "SUBSCRIBED_TIMESTAMP, " + + "GROUP_NAME, " + + "AP_APP_RELEASE_ID) " + + "VALUES (?, ?, ?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (String group : groups) { + stmt.setInt(1, tenantId); + stmt.setString(2, subscribedBy); + stmt.setTimestamp(3, timestamp); + stmt.setString(4, group); + stmt.setInt(5, releaseId); + stmt.addBatch(); + if (log.isDebugEnabled()) { + log.debug("Adding a group subscription for role " + group + " and application release which " + + "has Id " + releaseId + " to the database."); + } + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to add group subscription. Subscribing " + + "group is " + subscribedBy; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to add group subscription. Subscribing group is " + + subscribedBy + " and executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDeviceSubscriptions(int appReleaseId, int tenantId) throws + ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting device subscriptions for the application release id " + appReleaseId + + " from the database"); + } + String sql = "SELECT " + + "DS.ID AS ID, " + + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " + + "DS.SUBSCRIBED_TIMESTAMP AS SUBSCRIBED_AT, " + + "DS.UNSUBSCRIBED AS IS_UNSUBSCRIBED, " + + "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, " + + "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, " + + "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, " + + "DS.STATUS AS STATUS," + + "DS.DM_DEVICE_ID AS DEVICE_ID " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, appReleaseId); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved device subscriptions for application release id " + + appReleaseId); + } + return DAOUtil.loadDeviceSubscriptions(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting device subscription for " + + "application Id: " + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while while running SQL to get device subscription data for application ID: " + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public Map getDeviceSubscriptions(List deviceIds, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get device subscriptions for given device ids."); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + Map deviceSubscriptionDTOHashMap = new HashMap<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "DS.ID AS ID, " + + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " + + "DS.SUBSCRIBED_TIMESTAMP AS SUBSCRIBED_AT, " + + "DS.UNSUBSCRIBED AS IS_UNSUBSCRIBED, " + + "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, " + + "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, " + + "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, " + + "DS.DM_DEVICE_ID AS DEVICE_ID, " + + "DS.STATUS AS STATUS " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.DM_DEVICE_ID IN (", ") AND AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"); + deviceIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (Integer deviceId : deviceIds) { + ps.setObject(index++, deviceId); + } + ps.setInt(index++, appReleaseId); + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + DeviceSubscriptionDTO deviceSubscriptionDTO = DAOUtil.constructDeviceSubscriptionDTO(rs); + if (deviceSubscriptionDTOHashMap.containsKey(deviceSubscriptionDTO.getDeviceId())){ + String msg = "There shouldn't be Device ids in multiple times in AP_DEVICE_SUBSCRIPTION " + + "table."; + log.error(msg); + throw new ApplicationManagementDAOException(msg); + } + deviceSubscriptionDTOHashMap.put(deviceSubscriptionDTO.getDeviceId(), deviceSubscriptionDTO); + } + } + } + return deviceSubscriptionDTOHashMap; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get device subscriptions for given device" + + " Ids."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting device subscriptions for given device Ids."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + public List getAppSubscribedUserNames(List users, int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed users for given list of user names."); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List subscribedUsers = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT US.USER_NAME AS USER_NAME " + + "FROM AP_USER_SUBSCRIPTION US " + + "WHERE US.USER_NAME IN (", ") AND AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"); + users.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String username : users) { + ps.setObject(index++, username); + } + ps.setInt(index++, appReleaseId); + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedUsers.add(rs.getString("USER_NAME")); + } + } + } + return subscribedUsers; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already subscribed users for given " + + "user names."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed users for given user names."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + public List getAppSubscribedRoleNames(List roles, int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed role names for given list of roles."); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List subscribedUsers = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT RS.ROLE_NAME AS ROLE " + + "FROM AP_ROLE_SUBSCRIPTION RS " + + "WHERE RS.ROLE_NAME IN (", ") AND AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"); + roles.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String roleName : roles) { + ps.setObject(index++, roleName); + } + ps.setInt(index++, appReleaseId); + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedUsers.add(rs.getString("ROLE")); + } + } + } + return subscribedUsers; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to getg subscribed roles for given role " + + "names."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SWL Error occurred while getting subscribes roles for given role names."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppSubscribedGroupNames(List groups, int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed groups for given list of groups."); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List subscribedUsers = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT GS.GROUP_NAME AS GROUP_NAME " + + "FROM AP_GROUP_SUBSCRIPTION GS " + + "WHERE GS.GROUP_NAME IN (", ") AND AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"); + groups.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String groupName : groups) { + ps.setObject(index++, groupName); + } + ps.setInt(index++, appReleaseId); + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedUsers.add(rs.getString("GROUP_NAME")); + } + } + } + return subscribedUsers; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already subscribed groups for given " + + "group names."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting already subscribed groups for given group names."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDeviceSubIds(List deviceIds, int applicationReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received to DAO Layer to get already subscribed dvice Ids for given list of device Ids."); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List subscribedDevices = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT DS.ID AS DEVICE_SUBSCRIPTION_ID " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.DM_DEVICE_ID IN (", ") AND AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"); + deviceIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (Integer deviceId : deviceIds) { + ps.setObject(index++, deviceId); + } + ps.setInt(index++, applicationReleaseId); + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedDevices.add(rs.getInt("DEVICE_SUBSCRIPTION_ID")); + } + } + } + return subscribedDevices; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get subscribed device Ids for given " + + "device Id list."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting already subscribed device ids for given device Id list."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void updateSubscriptions(int tenantId, String updateBy, List paramList, int releaseId, + String subType, String action) throws ApplicationManagementDAOException { + try { + Connection conn = this.getDBConnection(); + boolean isUnsubscribed = false; + String sql = "UPDATE "; + if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + sql += "AP_USER_SUBSCRIPTION SET "; + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + sql += "AP_ROLE_SUBSCRIPTION SET "; + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + sql += "AP_GROUP_SUBSCRIPTION SET "; + } + + if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { + sql += "UNSUBSCRIBED = ?, UNSUBSCRIBED_BY = ?, UNSUBSCRIBED_TIMESTAMP = ? "; + isUnsubscribed = true; + } else { + sql += "UNSUBSCRIBED = ?, SUBSCRIBED_BY = ?, SUBSCRIBED_TIMESTAMP = ? "; + } + + if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + sql += "WHERE USER_NAME = ? "; + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + sql += "WHERE ROLE_NAME = ? "; + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + sql += "WHERE GROUP_NAME = ? "; + } + + sql += "AND AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"; + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + for (String username : paramList) { + stmt.setBoolean(1, isUnsubscribed); + stmt.setString(2, updateBy); + stmt.setTimestamp(3, timestamp); + stmt.setString(4, username); + stmt.setInt(5, releaseId); + stmt.setInt(6, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the user/role/group subscriptions " + + "of application."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while processing SQL to update the user/role/group subscriptions of " + + "application."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDeviceSubIdsForOperation(int operationId, int deviceId, int tenantId) + throws ApplicationManagementDAOException { + try { + Connection conn = this.getDBConnection(); + List deviceSubIds = new ArrayList<>(); + String sql = "SELECT AP_APP_SUB_OP_MAPPING.AP_DEVICE_SUBSCRIPTION_ID " + + "FROM " + + "AP_APP_SUB_OP_MAPPING INNER JOIN AP_DEVICE_SUBSCRIPTION " + + "ON AP_APP_SUB_OP_MAPPING.AP_DEVICE_SUBSCRIPTION_ID = AP_DEVICE_SUBSCRIPTION.ID " + + "WHERE AP_APP_SUB_OP_MAPPING.OPERATION_ID = ? AND " + + "AP_DEVICE_SUBSCRIPTION.DM_DEVICE_ID = ? AND " + + "AP_APP_SUB_OP_MAPPING.TENANT_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, operationId); + stmt.setInt(2, deviceId); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + deviceSubIds.add(rs.getInt("AP_DEVICE_SUBSCRIPTION_ID")); + } + } + return deviceSubIds; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get app device subscription ids for given " + + "operation."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to get app device subscription ids for given operation."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean updateDeviceSubStatus(int deviceId, List deviceSubIds, String status, int tenantId) + throws ApplicationManagementDAOException { + try { + Connection conn = this.getDBConnection(); + int index = 1; + StringJoiner joiner = new StringJoiner(",", + "UPDATE AP_DEVICE_SUBSCRIPTION SET STATUS = ? " + + "WHERE ID IN (", + ") AND DM_DEVICE_ID = ? AND TENANT_ID = ?"); + deviceSubIds.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(index++, status); + for (Integer deviceSubId : deviceSubIds) { + ps.setObject(index++, deviceSubId); + } + ps.setInt(index++, deviceId); + ps.setInt(index, tenantId); + return ps.executeUpdate() != 0; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the subscription status of the " + + "device subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to update the subscription status of the device " + + "subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO) + throws ApplicationManagementDAOException { + String sql = "INSERT INTO " + + "AP_SCHEDULED_SUBSCRIPTION (" + + "TASK_NAME, " + + "APPLICATION_UUID, " + + "SUBSCRIBER_LIST, " + + "STATUS, " + + "SCHEDULED_AT, " + + "SCHEDULED_TIMESTAMP," + + "SCHEDULED_BY," + + "DELETED) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + stmt.setString(1, subscriptionDTO.getTaskName()); + stmt.setString(2, subscriptionDTO.getApplicationUUID()); + stmt.setString(3, subscriptionDTO.getSubscribersString()); + stmt.setString(4, ExecutionStatus.PENDING.toString()); + stmt.setTimestamp(5, Timestamp.valueOf(subscriptionDTO.getScheduledAt())); + stmt.setTimestamp(6, new Timestamp(calendar.getTime().getTime())); + stmt.setString(7, subscriptionDTO.getScheduledBy()); + stmt.setBoolean(8, false); + return stmt.executeUpdate() > 0; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to insert the subscription status of the " + + "scheduled subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to insert the " + "subscription status of the scheduled " + + "subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy) + throws ApplicationManagementDAOException { + String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION " + + "SET " + + "SCHEDULED_AT = ?, " + + "SCHEDULED_BY = ?, " + + "SCHEDULED_TIMESTAMP = ? " + + "WHERE ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + Calendar calendar = Calendar.getInstance(); + stmt.setTimestamp(1, Timestamp.valueOf(scheduledAt)); + stmt.setString(2, scheduledBy); + stmt.setTimestamp(3, new Timestamp(calendar.getTime().getTime())); + stmt.setInt(4, id); + return stmt.executeUpdate() > 0; + } + } catch (DBConnectionException e) { + String msg = + "Error occurred while obtaining the DB connection to update the existing entry of the scheduled " + + "subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to update the existing entry of the scheduled subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean deleteScheduledSubscription(List subscriptionIdList) throws ApplicationManagementDAOException { + String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION " + + "SET DELETED = ? " + + "WHERE ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer id: subscriptionIdList) { + stmt.setBoolean(1, true); + stmt.setInt(2, id); + stmt.addBatch(); + } + int[] results = stmt.executeBatch(); + return Arrays.stream(results).allMatch(r -> r > 0); + } + } catch (DBConnectionException e) { + String msg = + "Error occurred while obtaining the DB connection to delete the existing entry of the scheduled " + + "subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to delete the existing entry of the scheduled subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean updateScheduledSubscriptionStatus(int id, ExecutionStatus status) + throws ApplicationManagementDAOException { + String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION " + + "SET STATUS = ? " + + "WHERE ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, status.toString()); + stmt.setInt(2, id); + return stmt.executeUpdate() > 0; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the status of the scheduled " + + "subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to update the status of the scheduled subscription."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed users for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedUsers = new ArrayList<>(); + String sql = "SELECT " + + "US.USER_NAME AS USER_NAME " + + "FROM AP_USER_SUBSCRIPTION US " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ? OFFSET ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, appReleaseId); + stmt.setInt(2, tenantId); + stmt.setInt(3, limitValue); + stmt.setInt(4, offsetValue); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + subscribedUsers.add(rs.getString("USER_NAME")); + } + } + return subscribedUsers; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed users for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed users for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getScheduledSubscriptionByStatus(ExecutionStatus status, boolean deleted) + throws ApplicationManagementDAOException { + String sql = "SELECT " + + "ID, " + + "TASK_NAME, " + + "APPLICATION_UUID, " + + "SUBSCRIBER_LIST, " + + "STATUS, " + + "SCHEDULED_AT, " + + "SCHEDULED_BY, " + + "DELETED " + + "FROM AP_SCHEDULED_SUBSCRIPTION " + + "WHERE STATUS = ? AND DELETED = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, status.toString()); + stmt.setBoolean(2, deleted); + try (ResultSet rs = stmt.executeQuery()) { + return DAOUtil.loadScheduledSubscriptions(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve" + status.toString() + + " subscriptions"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to retrieve" + status.toString() + " subscriptions"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getNonExecutedSubscriptions() throws ApplicationManagementDAOException { + String sql = "SELECT " + + "ID, " + + "TASK_NAME, " + + "APPLICATION_UUID, " + + "SUBSCRIBER_LIST, " + + "STATUS, " + + "SCHEDULED_AT, " + + "SCHEDULED_BY, " + + "DELETED " + + "FROM AP_SCHEDULED_SUBSCRIPTION " + + "WHERE STATUS = ? AND DELETED = ? AND SCHEDULED_AT < ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, ExecutionStatus.PENDING.toString()); + stmt.setBoolean(2, false); + stmt.setTimestamp(3, new Timestamp(Calendar.getInstance().getTime().getTime())); + try (ResultSet rs = stmt.executeQuery()) { + return DAOUtil.loadScheduledSubscriptions(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve missed subscriptions"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to retrieve missed subscriptions."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed roles for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedRoles = new ArrayList<>(); + String sql = "SELECT " + + "RS.ROLE_NAME AS ROLE " + + "FROM AP_ROLE_SUBSCRIPTION RS " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ? OFFSET ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setInt(3, limitValue); + ps.setInt(4, offsetValue); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedRoles.add(rs.getString("ROLE")); + } + } + return subscribedRoles; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed roles for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed roles for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName) + throws ApplicationManagementDAOException { + String sql = "SELECT " + + "ID, " + + "TASK_NAME, " + + "APPLICATION_UUID, " + + "SUBSCRIBER_LIST, " + + "STATUS, " + + "SCHEDULED_AT, " + + "SCHEDULED_BY, " + + "DELETED " + + "FROM AP_SCHEDULED_SUBSCRIPTION " + + "WHERE TASK_NAME = ? AND STATUS = ? AND DELETED = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, taskName); + stmt.setString(2, ExecutionStatus.PENDING.toString()); + stmt.setBoolean(3, false); + try (ResultSet rs = stmt.executeQuery()) { + return DAOUtil.loadScheduledSubscription(rs); + } + } + } catch (DBConnectionException e) { + String msg = + "Error occurred while obtaining the DB connection to retrieve pending subscriptions of " + taskName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when processing SQL to retrieve pending subscriptions of " + taskName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "More than one pending subscriptions exist for " + taskName; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed groups for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedGroups = new ArrayList<>(); + String sql = "SELECT " + + "GS.GROUP_NAME AS GROUPS " + + "FROM AP_GROUP_SUBSCRIPTION GS " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ? OFFSET ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setInt(3, limitValue); + ps.setInt(4, offsetValue); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedGroups.add(rs.getString("GROUPS")); + } + } + return subscribedGroups; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed groups for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed groups for given " + + "app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/OracleSubscriptionDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/OracleSubscriptionDAOImpl.java new file mode 100644 index 0000000000..b7932d9f9c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/OracleSubscriptionDAOImpl.java @@ -0,0 +1,159 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.subscription; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * This handles Application subscribing operations which are specific to Oracle. + */ +public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl { + + private static Log log = LogFactory.getLog(OracleSubscriptionDAOImpl.class); + + @Override + public List getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed users for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedUsers = new ArrayList<>(); + String sql = "SELECT " + + "US.USER_NAME AS USER " + + "FROM AP_USER_SUBSCRIPTION US " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY US.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, appReleaseId); + stmt.setInt(2, tenantId); + stmt.setInt(3, offsetValue); + stmt.setInt(4, limitValue); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + subscribedUsers.add(rs.getString("USER")); + } + } + return subscribedUsers; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed users for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed users for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed roles for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedRoles = new ArrayList<>(); + String sql = "SELECT " + + "RS.ROLE_NAME AS ROLE " + + "FROM AP_ROLE_SUBSCRIPTION RS " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY RS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setInt(3, offsetValue); + ps.setInt(4, limitValue); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedRoles.add(rs.getString("ROLE")); + } + } + return subscribedRoles; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed roles for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed roles for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed groups for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedGroups = new ArrayList<>(); + String sql = "SELECT " + + "GS.GROUP_NAME AS GROUPS " + + "FROM AP_GROUP_SUBSCRIPTION GS " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY GS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setInt(3, offsetValue); + ps.setInt(4, limitValue); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedGroups.add(rs.getString("GROUPS")); + } + } + return subscribedGroups; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed groups for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed groups for given " + + "app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/SQLServerSubscriptionDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/SQLServerSubscriptionDAOImpl.java new file mode 100644 index 0000000000..26a498af1b --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/subscription/SQLServerSubscriptionDAOImpl.java @@ -0,0 +1,162 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.subscription; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * This handles Application subscribing operations which are specific to MsSQL. + */ +public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl { + + private static Log log = LogFactory.getLog(SQLServerSubscriptionDAOImpl.class); + + @Override + public List getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed users for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedUsers = new ArrayList<>(); + String sql = "SELECT " + + "US.USER_NAME AS USER_NAME " + + "FROM AP_USER_SUBSCRIPTION US " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY US.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, appReleaseId); + stmt.setInt(2, tenantId); + stmt.setInt(3, offsetValue); + stmt.setInt(4, limitValue); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + subscribedUsers.add(rs.getString("USER_NAME")); + } + } + return subscribedUsers; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed users for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed users for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed roles for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedRoles = new ArrayList<>(); + String sql = "SELECT " + + "RS.ROLE_NAME AS ROLE " + + "FROM AP_ROLE_SUBSCRIPTION RS " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY RS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setInt(3, offsetValue); + ps.setInt(4, limitValue); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedRoles.add(rs.getString("ROLE")); + } + } + return subscribedRoles; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed roles for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed roles for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, + int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get already subscribed groups for " + + "given app release id."); + } + try { + Connection conn = this.getDBConnection(); + List subscribedGroups = new ArrayList<>(); + String sql = "SELECT " + + "GS.GROUP_NAME AS GROUPS " + + "FROM AP_GROUP_SUBSCRIPTION GS " + + "WHERE " + + "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY GS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setInt(3, offsetValue); + ps.setInt(4, limitValue); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + subscribedGroups.add(rs.getString("GROUPS")); + } + } + return subscribedGroups; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get already " + + "subscribed groups for given app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting subscribed groups for given " + + "app release id."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/GenericVisibilityDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/GenericVisibilityDAOImpl.java new file mode 100644 index 0000000000..2017484fd8 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/GenericVisibilityDAOImpl.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao.impl.visibility; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.core.dao.VisibilityDAO; +import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl; +import org.wso2.carbon.device.application.mgt.core.exception.VisibilityManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * Generic database level implementation for the DAO which can be used by different databases. + */ +public class GenericVisibilityDAOImpl extends AbstractDAOImpl implements VisibilityDAO { + + private static final Log log = LogFactory.getLog(GenericVisibilityDAOImpl.class); + + @Override + public void addUnrestrictedRoles(List unrestrictedRoles, int applicationId, int tenantId) throws + VisibilityManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to add unrestricted roles for application which has application" + + " ID " + applicationId); + } + String sql = "INSERT INTO " + + "AP_UNRESTRICTED_ROLE " + + "(ROLE, " + + "TENANT_ID, " + + "AP_APP_ID) " + + "VALUES (?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (String role : unrestrictedRoles) { + stmt.setString(1, role); + stmt.setInt(2, tenantId); + stmt.setInt(3, applicationId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection when adding unrestricted roles for " + + "application which has Id " + applicationId; + log.error(msg, e); + throw new VisibilityManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to add unrestricted roles for application which has Id " + + applicationId + ". Executed query " + sql; + log.error(msg, e); + throw new VisibilityManagementDAOException(msg, e); + } + } + + @Override + public List getUnrestrictedRoles(int applicationId, int tenantId) throws VisibilityManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get unrestricted roles for application which has application " + + "ID " + applicationId); + } + List unrestrictedRoles = new ArrayList<>(); + String sql = "SELECT ROLE " + + "FROM AP_UNRESTRICTED_ROLE " + + "WHERE AP_APP_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, applicationId); + stmt.setInt(2, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + unrestrictedRoles.add(rs.getString("ROLE")); + } + return unrestrictedRoles; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get unrestricted roles for application " + + "which has application Id " + applicationId; + log.error(msg, e); + throw new VisibilityManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to get unrestricted roles for application which has " + + "application Id " + applicationId + ". Executed query: " + sql; + log.error(msg, e); + throw new VisibilityManagementDAOException(msg, e); + } + } + + @Override + public void deleteUnrestrictedRoles(List unrestrictedRoles, int applicationId, int tenantId) + throws VisibilityManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete unrestricted roles of application which has " + + "application Id " + applicationId); + } + String sql = "DELETE " + + "FROM AP_UNRESTRICTED_ROLE " + + "WHERE AP_APP_ID = ? AND " + + "ROLE = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (String role : unrestrictedRoles) { + stmt.setInt(1, applicationId); + stmt.setString(2, role); + stmt.setInt(3, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to delete unrestricted roles of an " + + "application which has application Id " + applicationId; + log.error(msg, e); + throw new VisibilityManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to delete unrestricted roles of an application which has" + + " application Id " + applicationId + ". executed query: " + sql; + log.error(msg, e); + throw new VisibilityManagementDAOException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/OracleVisibilityDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/OracleVisibilityDAOImpl.java new file mode 100644 index 0000000000..8234879598 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/OracleVisibilityDAOImpl.java @@ -0,0 +1,24 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.visibility; + +/** + * This handles Application visibility handling operations which are specific to Oracle.. + */ +public class OracleVisibilityDAOImpl extends GenericVisibilityDAOImpl { +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/SQLServerVisibilityDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/SQLServerVisibilityDAOImpl.java new file mode 100644 index 0000000000..3243f24116 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/visibility/SQLServerVisibilityDAOImpl.java @@ -0,0 +1,24 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.dao.impl.visibility; + +/** + * This handles Application visibility handling operations which are specific to MsSQL. + */ +public class SQLServerVisibilityDAOImpl extends GenericVisibilityDAOImpl { +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/deployer/Property.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/deployer/Property.java new file mode 100644 index 0000000000..f9fc46b0a1 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/deployer/Property.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.deployer; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlValue; + +/** + * Represents a property of the {@link Platform}. + */ +@XmlRootElement(name = "Property") +public class Property { + + private String name; + private boolean optional; + private String defaultValue; + + @XmlValue + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @XmlAttribute(name = "optional") + public boolean isOptional() { + return optional; + } + + public void setOptional(boolean optional) { + this.optional = optional; + } + + @XmlAttribute(name = "default") + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationManagementDAOException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationManagementDAOException.java new file mode 100644 index 0000000000..d946ee3fce --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationManagementDAOException.java @@ -0,0 +1,31 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.exception; + +/** + * Exception thrown during the ApplicationDTO Management DAO operations. + */ +public class ApplicationManagementDAOException extends Exception { + + public ApplicationManagementDAOException(String message, Throwable throwable) { + super(message, throwable); + } + + public ApplicationManagementDAOException(String message) { + super(message, new Exception()); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationOperationTaskException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationOperationTaskException.java new file mode 100644 index 0000000000..bfec70afc5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ApplicationOperationTaskException.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.exception; + +public class ApplicationOperationTaskException extends Exception { + + public ApplicationOperationTaskException(String message, Throwable cause) { + super(message, cause); + } + + public ApplicationOperationTaskException(String message) { + super(message); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/BadRequestException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/BadRequestException.java similarity index 51% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/BadRequestException.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/BadRequestException.java index b3c3fda139..8930d87310 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/BadRequestException.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/BadRequestException.java @@ -1,7 +1,7 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. * - * WSO2 Inc. licenses this file to you under the Apache License, + * Entgra (pvt) Ltd. 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 @@ -16,19 +16,22 @@ * under the License. */ -package org.wso2.carbon.device.mgt.jaxrs.exception; +package org.wso2.carbon.device.application.mgt.core.exception; -import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; /** * Custom exception class for wrapping BadRequest related exceptions. */ -public class BadRequestException extends WebApplicationException { - public BadRequestException(ErrorResponse error) { - super(Response.status(Response.Status.BAD_REQUEST).entity(error).build()); +public class BadRequestException extends ApplicationManagementException { + + public BadRequestException(String message, Throwable throwable) { + super(message, throwable); } + + public BadRequestException(String message) { + setMessage(message); + } + } \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ForbiddenException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ForbiddenException.java new file mode 100644 index 0000000000..3957b5bff2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ForbiddenException.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.exception; + + +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; + +/** + * Exception class that is corresponding to 401 Forbidden response + */ + +public class ForbiddenException extends ApplicationManagementException { + + public ForbiddenException(String message, Throwable throwable) { + super(message, throwable); + } + + public ForbiddenException(String message) { + setMessage(message); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/LifeCycleManagementDAOException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/LifeCycleManagementDAOException.java new file mode 100644 index 0000000000..3b2a36da48 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/LifeCycleManagementDAOException.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.exception; + +/** + * This exception will be thrown when there is an issue with Lifecycle related DAO operations. + */ +public class LifeCycleManagementDAOException extends Exception { + + public LifeCycleManagementDAOException(String message) { + super(message); + } + + public LifeCycleManagementDAOException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/NotFoundException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/NotFoundException.java new file mode 100644 index 0000000000..2073d5a7c0 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/NotFoundException.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.exception; + +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; + +/** + * This exception will be thrown when the requested application or platform not found. + */ +public class NotFoundException extends ApplicationManagementException { + + public NotFoundException(String message, Throwable throwable) { + super(message, throwable); + } + + public NotFoundException(String message) { + setMessage(message); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ParsingException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ParsingException.java new file mode 100644 index 0000000000..543de598c4 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ParsingException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.exception; + +public class ParsingException extends Exception { + + private static final long serialVersionUID = -8935642383846122660L; + private String errorMessage; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public ParsingException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public ParsingException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public ParsingException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public ParsingException() { + super(); + } + + public ParsingException(Throwable cause) { + super(cause); + } +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ReviewManagementDAOException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ReviewManagementDAOException.java new file mode 100644 index 0000000000..e9f17065c7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ReviewManagementDAOException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.exception; + +import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; + +/** + * Exception thrown during the Review Management DAO operations. + */ +public class ReviewManagementDAOException extends ReviewManagementException { + + public ReviewManagementDAOException(String message, Throwable throwable) { + super(message, throwable); + } + + public ReviewManagementDAOException(String message) { + super(message, new Exception()); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/SubscriptionManagementDAOException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/SubscriptionManagementDAOException.java new file mode 100644 index 0000000000..8419ed643d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/SubscriptionManagementDAOException.java @@ -0,0 +1,33 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.exception; + +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; + +/** + * Exception thrown during the ApplicationDTO Management DAO operations. + */ +public class SubscriptionManagementDAOException extends ApplicationManagementException { + + public SubscriptionManagementDAOException(String message, Throwable throwable) { + super(message, throwable); + } + + public SubscriptionManagementDAOException(String message) { + super(message, new Exception()); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/UnexpectedServerErrorException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/UnexpectedServerErrorException.java new file mode 100644 index 0000000000..d17116730f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/UnexpectedServerErrorException.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.exception; + + +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; + +public class UnexpectedServerErrorException extends ApplicationManagementException { + + public UnexpectedServerErrorException(String message, Throwable throwable) { + super(message, throwable); + } + + public UnexpectedServerErrorException(String message) { + setMessage(message); + } + +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ValidationException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ValidationException.java new file mode 100644 index 0000000000..f17baee7f7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ValidationException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.exception; + +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; + +/** + * This exception will be thrown when the initial validation fails to perform an operation. + */ +public class ValidationException extends ApplicationManagementException { + + public ValidationException(String message, Throwable throwable) { + super(message, throwable); + } + + public ValidationException(String message) { + setMessage(message); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/VisibilityManagementDAOException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/VisibilityManagementDAOException.java new file mode 100644 index 0000000000..b3cc7a3a63 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/VisibilityManagementDAOException.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.exception; + +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; + +/** + * This is the specialized exception which is thrown when there are database level problems encountered + * when performing the visibility management + */ +public class VisibilityManagementDAOException extends ApplicationManagementException { + + public VisibilityManagementDAOException(String message, Throwable throwable) { + super(message, throwable); + } + + public VisibilityManagementDAOException(String message) { + super(message, new Exception()); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java new file mode 100644 index 0000000000..a937169b83 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -0,0 +1,3262 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.impl; + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.validator.routines.UrlValidator; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.ApplicationArtifact; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstaller; +import org.wso2.carbon.device.application.mgt.common.DeviceTypes; +import org.wso2.carbon.device.application.mgt.common.LifecycleChanger; +import org.wso2.carbon.device.application.mgt.common.Pagination; +import org.wso2.carbon.device.application.mgt.common.config.RatingConfiguration; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.ApplicationList; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.ApplicationSubscriptionType; +import org.wso2.carbon.device.application.mgt.common.ApplicationType; +import org.wso2.carbon.device.application.mgt.common.dto.CategoryDTO; +import org.wso2.carbon.device.application.mgt.common.Filter; +import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.LifecycleState; +import org.wso2.carbon.device.application.mgt.common.dto.TagDTO; +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.DBConnectionException; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException; +import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException; +import org.wso2.carbon.device.application.mgt.common.response.Application; +import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.response.Category; +import org.wso2.carbon.device.application.mgt.common.response.Tag; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppWrapper; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; +import org.wso2.carbon.device.application.mgt.core.dao.LifecycleStateDAO; +import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO; +import org.wso2.carbon.device.application.mgt.core.dao.VisibilityDAO; +import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; +import org.wso2.carbon.device.application.mgt.core.exception.LifeCycleManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.exception.VisibilityManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.application.mgt.core.util.StorageManagementUtil; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; + +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Default Concrete implementation of Application Management related implementations. + */ +public class ApplicationManagerImpl implements ApplicationManager { + + private static final Log log = LogFactory.getLog(ApplicationManagerImpl.class); + private VisibilityDAO visibilityDAO; + private ApplicationDAO applicationDAO; + private ApplicationReleaseDAO applicationReleaseDAO; + private LifecycleStateDAO lifecycleStateDAO; + private SubscriptionDAO subscriptionDAO; + private LifecycleStateManager lifecycleStateManager; + + public ApplicationManagerImpl() { + initDataAccessObjects(); + lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); + } + + private void initDataAccessObjects() { + this.visibilityDAO = ApplicationManagementDAOFactory.getVisibilityDAO(); + this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); + this.lifecycleStateDAO = ApplicationManagementDAOFactory.getLifecycleStateDAO(); + this.applicationReleaseDAO = ApplicationManagementDAOFactory.getApplicationReleaseDAO(); + this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO(); + } + + @Override + public Application createEntApp(ApplicationWrapper applicationWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + if (log.isDebugEnabled()) { + log.debug("Ent. Application create request is received. Application name: " + applicationWrapper.getName() + + " Device type: " + applicationWrapper.getDeviceType()); + } + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(applicationWrapper); + //uploading application artifacts + ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts( + applicationDTO.getApplicationReleaseDTOs().get(0), applicationArtifact, + applicationWrapper.getDeviceType(), tenantId, false); + applicationDTO.getApplicationReleaseDTOs().clear(); + applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); + return addAppDataIntoDB(applicationDTO, tenantId); + } + + @Override + public Application createWebClip(WebAppWrapper webAppWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException { + if (log.isDebugEnabled()) { + log.debug("Web clip create request is received. App name: " + webAppWrapper.getName() + " Device type: " + + Constants.ANY); + } + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(webAppWrapper); + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); + applicationReleaseDTO.setAppHashValue(DigestUtils.md5Hex(applicationReleaseDTO.getInstallerName())); + //uploading application artifacts + try { + applicationDTO.getApplicationReleaseDTOs().clear(); + applicationDTO.getApplicationReleaseDTOs() + .add(addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId)); + } catch (ResourceManagementException e) { + String msg = "Error Occured when uploading artifacts of the web clip: " + webAppWrapper.getName(); + log.error(msg); + throw new ApplicationManagementException(msg, e); + } + //insert application data into database + return addAppDataIntoDB(applicationDTO, tenantId); + } + + @Override + public Application createPublicApp(PublicAppWrapper publicAppWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + + if (log.isDebugEnabled()) { + log.debug("Public app creating request is received. App name: " + publicAppWrapper.getName() + + " Device Type: " + publicAppWrapper.getDeviceType()); + } + + String publicAppStorePath = ""; + if (DeviceTypes.ANDROID.toString().equalsIgnoreCase(publicAppWrapper.getDeviceType())) { + publicAppStorePath = Constants.GOOGLE_PLAY_STORE_URL; + } else if (DeviceTypes.IOS.toString().equals(publicAppWrapper.getDeviceType())) { + publicAppStorePath = Constants.APPLE_STORE_URL; + } + ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(publicAppWrapper); + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + String appInstallerUrl = publicAppStorePath + applicationReleaseDTO.getPackageName(); + applicationReleaseDTO.setInstallerName(appInstallerUrl); + applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); + applicationReleaseDTO.setAppHashValue(DigestUtils.md5Hex(appInstallerUrl)); + + try { + ConnectionManagerUtil.openDBConnection(); + List exitingPubAppReleases = applicationReleaseDAO + .getReleaseByPackages(Collections.singletonList(applicationReleaseDTO.getPackageName()), tenantId); + if (!exitingPubAppReleases.isEmpty()){ + String msg = "Public app release exists for package name " + applicationReleaseDTO.getPackageName() + + ". Hence you can't add new public app for package name " + + applicationReleaseDTO.getPackageName(); + log.error(msg); + throw new BadRequestException(msg); + } + } catch (ApplicationManagementDAOException e) { + String msg = "Error Occured when fetching release: " + publicAppWrapper.getName(); + log.error(msg); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + + try { + //uploading application artifacts + applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); + applicationDTO.getApplicationReleaseDTOs().clear(); + applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); + } catch (ResourceManagementException e) { + String msg = "Error Occured when uploading artifacts of the public app: " + publicAppWrapper.getName(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + //insert application data into database + return addAppDataIntoDB(applicationDTO, tenantId); + } + + @Override + public Application createCustomApp(CustomAppWrapper customAppWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException { + try { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); + String md5OfApp = StorageManagementUtil.getMD5(new ByteArrayInputStream(content)); + if (md5OfApp == null) { + String msg = + "Error occurred while getting md5sum value of custom app. Application name: " + customAppWrapper + .getName() + " Device type: " + customAppWrapper.getDeviceType(); + log.error(msg); + throw new ApplicationManagementException(msg); + } + try { + ConnectionManagerUtil.openDBConnection(); + if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) { + String msg = "Application release exists for the uploaded binary file. Application name: " + + customAppWrapper.getName() + " Device type: " + customAppWrapper.getDeviceType(); + log.error(msg); + throw new BadRequestException(msg); + } + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while adding application data into the database. Application name: " + + customAppWrapper.getName() + " Device type: " + customAppWrapper.getDeviceType(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + + ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(customAppWrapper); + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); + applicationReleaseDTO.setAppHashValue(md5OfApp); + applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName()); + try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { + applicationStorageManager.uploadReleaseArtifact(applicationReleaseDTO, customAppWrapper.getDeviceType(), + binaryDuplicate, tenantId); + } catch (IOException e) { + String msg = "Error occurred when uploading release artifact into the server."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); + applicationDTO.getApplicationReleaseDTOs().clear(); + applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); + return addAppDataIntoDB(applicationDTO, tenantId); + } catch (ResourceManagementException e) { + String msg = "Error occurred while uploading application artifact into the server. Application name: " + + customAppWrapper.getName() + " Device type: " + customAppWrapper.getDeviceType(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (IOException e) { + String msg = "Error occurred while getting bytes from application release artifact. Application name: " + + customAppWrapper.getName() + " Device type: " + customAppWrapper.getDeviceType(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + /** + * Delete Application release artifacts + * + * @param directoryPaths Directory paths + * @param tenantId Tenant Id + * @throws ApplicationManagementException if error occurred while deleting application release artifacts. + */ + private void deleteApplicationArtifacts(List directoryPaths, int tenantId) throws ApplicationManagementException { + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + try { + applicationStorageManager.deleteAllApplicationReleaseArtifacts(directoryPaths, tenantId); + } catch (ApplicationStorageManagementException e) { + String msg = "Error occurred when deleting application artifacts. directory paths: ." + directoryPaths + .toString(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + /** + * To add Application release artifacts + * + * @param deviceType Device Type + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Application release artifacts + * @param isNewRelease Is new release or Not + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while handling application release artifacts. + * @throws ApplicationManagementException if error occurred while handling application release data. + */ + private ApplicationReleaseDTO addApplicationReleaseArtifacts(String deviceType, + ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, boolean isNewRelease) + throws ResourceManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + + String uuid = UUID.randomUUID().toString(); + applicationReleaseDTO.setUuid(uuid); + + // The application executable artifacts such as apks are uploaded. + try { + byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); + applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName()); + try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) { + ApplicationInstaller applicationInstaller = applicationStorageManager + .getAppInstallerData(binary, deviceType); + String packagename = applicationInstaller.getPackageName(); + + try { + ConnectionManagerUtil.openDBConnection(); + if (!isNewRelease && applicationReleaseDAO + .isActiveReleaseExisitForPackageName(packagename, tenantId, + lifecycleStateManager.getEndState())) { + String msg = "Application release is already exist for the package name: " + packagename + + ". Either you can delete all application releases for package " + packagename + " or " + + "you can add this app release as an new application release, under the existing " + + "application."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + applicationReleaseDTO.setVersion(applicationInstaller.getVersion()); + applicationReleaseDTO.setPackageName(packagename); + String md5OfApp = StorageManagementUtil.getMD5(new ByteArrayInputStream(content)); + if (md5OfApp == null) { + String msg = "Error occurred while md5sum value retrieving process: application UUID " + + applicationReleaseDTO.getUuid(); + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } + if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) { + String msg = + "Application release exists for the uploaded binary file. Device Type: " + deviceType; + log.error(msg); + throw new BadRequestException(msg); + } + applicationReleaseDTO.setAppHashValue(md5OfApp); + + try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { + applicationStorageManager + .uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate, tenantId); + } + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection for verifying app release data."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = + "Error occurred when executing the query for verifying application release existence for " + + "the package."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + } catch (IOException e) { + String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact + .getInstallerName(); + log.error(msg, e); + throw new ApplicationStorageManagementException(msg, e); + } + return applicationReleaseDTO; + } + + /** + * This method could be used to update enterprise application release artifacts. + * + * @param deviceType Device Type + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Application release artifacts + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while handling application release artifacts. + * @throws ApplicationManagementException if error occurred while handling application release data. + */ + private ApplicationReleaseDTO updateEntAppReleaseArtifact(String deviceType, + ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact) + throws ResourceManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + + // The application executable artifacts such as apks are uploaded. + try { + byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); + + try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) { + String md5OfApp = StorageManagementUtil.getMD5(binaryClone); + + if (md5OfApp == null) { + String msg = "Error occurred while retrieving md5sum value from the binary file for application " + + "release UUID " + applicationReleaseDTO.getUuid(); + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } + if (!applicationReleaseDTO.getAppHashValue().equals(md5OfApp)) { + applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName()); + + try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) { + ApplicationInstaller applicationInstaller = applicationStorageManager + .getAppInstallerData(binary, deviceType); + String packageName = applicationInstaller.getPackageName(); + + try { + ConnectionManagerUtil.getDBConnection(); + if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) { + String msg = "Same binary file is in the server. Hence you can't add same file into the " + + "server. Device Type: " + deviceType + " and package name: " + packageName; + log.error(msg); + throw new BadRequestException(msg); + } + if (applicationReleaseDTO.getPackageName() == null){ + String msg = "Found null value for application release package name for application " + + "release which has UUID: " + applicationReleaseDTO.getUuid(); + log.error(msg); + throw new ApplicationManagementException(msg); + } + if (!applicationReleaseDTO.getPackageName().equals(packageName)){ + String msg = "Package name of the new artifact does not match with the package name of " + + "the exiting application release. Package name of the existing app release " + + applicationReleaseDTO.getPackageName() + " and package name of the new " + + "application release " + packageName; + log.error(msg); + throw new BadRequestException(msg); + } + + applicationReleaseDTO.setVersion(applicationInstaller.getVersion()); + applicationReleaseDTO.setPackageName(packageName); + String deletingAppHashValue = applicationReleaseDTO.getAppHashValue(); + applicationReleaseDTO.setAppHashValue(md5OfApp); + try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { + applicationStorageManager + .uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate, + tenantId); + applicationStorageManager.copyImageArtifactsAndDeleteInstaller(deletingAppHashValue, + applicationReleaseDTO, tenantId); + } + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection for verifying application " + + "release existing for new app hash value."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when executing the query for verifying application release " + + "existence for the new app hash value."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + } + + } + } catch (IOException e) { + String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact + .getInstallerName(); + log.error(msg, e); + throw new ApplicationStorageManagementException(msg, e); + } + return applicationReleaseDTO; + } + + /** + * Add image artifacts into file system + * + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Image artifacts + * @param tenantId Tenant Id + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while uploading image artifacts into file system. + */ + private ApplicationReleaseDTO addImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, + ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException { + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + + applicationReleaseDTO.setIconName(applicationArtifact.getIconName()); + applicationReleaseDTO.setBannerName(applicationArtifact.getBannerName()); + + Map screenshots = applicationArtifact.getScreenshots(); + List screenshotNames = new ArrayList<>(screenshots.keySet()); + + int counter = 1; + for (String scName : screenshotNames) { + if (counter == 1) { + applicationReleaseDTO.setScreenshotName1(scName); + } else if (counter == 2) { + applicationReleaseDTO.setScreenshotName2(scName); + } else if (counter == 3) { + applicationReleaseDTO.setScreenshotName3(scName); + } + counter++; + } + + // Upload images + applicationReleaseDTO = applicationStorageManager + .uploadImageArtifacts(applicationReleaseDTO, applicationArtifact.getIconStream(), + applicationArtifact.getBannerStream(), new ArrayList<>(screenshots.values()), tenantId); + return applicationReleaseDTO; + } + + /** + * Update Image artifacts of Application RApplication Release + * + * @param applicationArtifact Application release Artifacts + * @param tenantId Tenant Id + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while uploading application release artifacts into the file system. + */ + private ApplicationReleaseDTO updateImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, + ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException{ + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + + if (!StringUtils.isEmpty(applicationArtifact.getIconName())) { + applicationStorageManager + .deleteAppReleaseArtifact(applicationReleaseDTO.getAppHashValue(), Constants.ICON_ARTIFACT, + applicationReleaseDTO.getIconName(), tenantId); + applicationReleaseDTO.setIconName(applicationArtifact.getIconName()); + } + if (!StringUtils.isEmpty(applicationArtifact.getBannerName())){ + applicationStorageManager + .deleteAppReleaseArtifact(applicationReleaseDTO.getAppHashValue(), Constants.BANNER_ARTIFACT, + applicationReleaseDTO.getBannerName(), tenantId); + applicationReleaseDTO.setBannerName(applicationArtifact.getBannerName()); + } + + Map screenshots = applicationArtifact.getScreenshots(); + List screenshotStreams = new ArrayList<>(); + + if (screenshots != null){ + List screenshotNames = new ArrayList<>(screenshots.keySet()); + screenshotStreams = new ArrayList<>(screenshots.values()); + + int counter = 1; + for (String scName : screenshotNames) { + String folderPath = Constants.SCREENSHOT_ARTIFACT + counter; + if (counter == 1) { + applicationStorageManager + .deleteAppReleaseArtifact(applicationReleaseDTO.getAppHashValue(), folderPath, + applicationReleaseDTO.getScreenshotName1(), tenantId); + applicationReleaseDTO.setScreenshotName1(scName); + } else if (counter == 2) { + applicationStorageManager + .deleteAppReleaseArtifact(applicationReleaseDTO.getAppHashValue(), folderPath, + applicationReleaseDTO.getScreenshotName2(), tenantId); + applicationReleaseDTO.setScreenshotName2(scName); + } else if (counter == 3) { + applicationStorageManager + .deleteAppReleaseArtifact(applicationReleaseDTO.getAppHashValue(), folderPath, + applicationReleaseDTO.getScreenshotName3(), tenantId); + applicationReleaseDTO.setScreenshotName3(scName); + } + counter++; + } + } + + // Upload images + applicationReleaseDTO = applicationStorageManager + .uploadImageArtifacts(applicationReleaseDTO, applicationArtifact.getIconStream(), + applicationArtifact.getBannerStream(), screenshotStreams, tenantId); + return applicationReleaseDTO; + } + + @Override + public ApplicationList getApplications(Filter filter) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + ApplicationList applicationList = new ApplicationList(); + List appDTOs; + List applications = new ArrayList<>(); + List filteredApplications = new ArrayList<>(); + DeviceType deviceType = null; + + //set default values + if (!StringUtils.isEmpty(filter.getDeviceType())) { + deviceType = APIUtil.getDeviceTypeData(filter.getDeviceType()); + } + if (filter.getLimit() == 0) { + filter.setLimit(20); + } + + if (deviceType == null) { + deviceType = new DeviceType(); + deviceType.setId(-1); + } + + try { + ConnectionManagerUtil.openDBConnection(); + validateFilter(filter); + appDTOs = applicationDAO.getApplications(filter, deviceType.getId(), tenantId); + for (ApplicationDTO applicationDTO : appDTOs) { + boolean isSearchingApp = true; + List filteringTags = filter.getTags(); + List filteringCategories = filter.getCategories(); + List filteringUnrestrictedRoles = filter.getUnrestrictedRoles(); + + if (!lifecycleStateManager.getEndState().equals(applicationDTO.getStatus())) { + //get application categories, tags and unrestricted roles. + List appUnrestrictedRoles = visibilityDAO + .getUnrestrictedRoles(applicationDTO.getId(), tenantId); + List appCategoryList = applicationDAO.getAppCategories(applicationDTO.getId(), tenantId); + List appTagList = applicationDAO.getAppTags(applicationDTO.getId(), tenantId); + + //Set application categories, tags and unrestricted roles to the application DTO. + applicationDTO.setUnrestrictedRoles(appUnrestrictedRoles); + applicationDTO.setAppCategories(appCategoryList); + applicationDTO.setTags(appTagList); + + if ((appUnrestrictedRoles.isEmpty() || hasUserRole(appUnrestrictedRoles, userName)) && ( + filteringUnrestrictedRoles == null || filteringUnrestrictedRoles.isEmpty() + || hasAppUnrestrictedRole(appUnrestrictedRoles, filteringUnrestrictedRoles, + userName))) { + if (filteringCategories != null && !filteringCategories.isEmpty()) { + isSearchingApp = filteringCategories.stream().anyMatch(appCategoryList::contains); + } + if (filteringTags != null && !filteringTags.isEmpty() && isSearchingApp) { + isSearchingApp = filteringTags.stream().anyMatch(appTagList::contains); + } + if (isSearchingApp) { + filteredApplications.add(applicationDTO); + } + } + } + + List filteredApplicationReleaseDTOs = new ArrayList<>(); + for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) { + if (!applicationReleaseDTO.getCurrentState().equals(lifecycleStateManager.getEndState())) { + filteredApplicationReleaseDTOs.add(applicationReleaseDTO); + } + } + applicationDTO.setApplicationReleaseDTOs(filteredApplicationReleaseDTOs); + } + + for (ApplicationDTO appDTO : filteredApplications) { + applications.add(APIUtil.appDtoToAppResponse(appDTO)); + } + + Pagination pagination = new Pagination(); + pagination.setCount(applicationDAO.getApplicationCount(filter, deviceType.getId(), tenantId)); + pagination.setSize(applications.size()); + pagination.setOffset(filter.getOffset()); + pagination.setLimit(filter.getLimit()); + + applicationList.setApplications(applications); + applicationList.setPagination(pagination); + return applicationList; + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection to get applications by filtering from " + + "requested filter."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "User-store exception while checking whether the user " + userName + " of tenant " + tenantId + + " has the publisher permission"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "DAO exception while getting applications for the user " + userName + " of tenant " + tenantId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /** + * Check whether at least one filtering role is in app unrestricted roles. + * + * @param appUnrestrictedRoles Application unrestricted roles + * @param filteringUnrestrictedRoles Filtering roles + * @param userName Username + * @return True if one filtering unrestricted role is associated with application unrestricted roles. + * @throws BadRequestException if user doesn't have assigned at least one filtering role + * @throws UserStoreException if error occurred when checking whether user has assigned at least one filtering role. + */ + private boolean hasAppUnrestrictedRole(List appUnrestrictedRoles, List filteringUnrestrictedRoles, + String userName) throws BadRequestException, UserStoreException { + if (!hasUserRole(filteringUnrestrictedRoles, userName)) { + String msg = + "At least one filtering role is not assigned for the user: " + userName + ". Hence user " + userName + + " Can't filter applications by giving these unrestricted role list"; + log.error(msg); + throw new BadRequestException(msg); + } + if (!appUnrestrictedRoles.isEmpty()) { + for (String role : filteringUnrestrictedRoles) { + if (appUnrestrictedRoles.contains(role)) { + return true; + } + } + } + return false; + } + + /*** + * This method is responsible to add application data into APPM database. However, before call this method it is + * required to do the validation of request and check the existence of application releaseDTO. + * + * @param applicationDTO Application DTO object. + * @param tenantId Tenant Id + * @return {@link Application} + * @throws ApplicationManagementException which throws if error occurs while during application management. + */ + private Application addAppDataIntoDB(ApplicationDTO applicationDTO, int tenantId) throws ApplicationManagementException { + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + List unrestrictedRoles = applicationDTO.getUnrestrictedRoles(); + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + List categories = applicationDTO.getAppCategories(); + List tags = applicationDTO.getTags(); + List applicationReleaseEntities = new ArrayList<>(); + try { + ConnectionManagerUtil.beginDBTransaction(); + // Insert to application table + int appId = this.applicationDAO.createApplication(applicationDTO, tenantId); + if (appId == -1) { + log.error("Application data storing is Failed."); + ConnectionManagerUtil.rollbackDBTransaction(); + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), + tenantId); + return null; + } else { + if (log.isDebugEnabled()) { + log.debug("New ApplicationDTO entry added to AP_APP table. App Id:" + appId); + } + //add application categories + + List categoryIds = applicationDAO.getCategoryIdsForCategoryNames(categories, tenantId); + this.applicationDAO.addCategoryMapping(categoryIds, appId, tenantId); + + //adding application unrestricted roles + if (unrestrictedRoles != null && !unrestrictedRoles.isEmpty()) { + this.visibilityDAO.addUnrestrictedRoles(unrestrictedRoles, appId, tenantId); + if (log.isDebugEnabled()) { + log.debug("New restricted roles to app ID mapping added to AP_UNRESTRICTED_ROLE table." + + " App Id:" + appId); + } + } + + //adding application tags + if (tags != null && !tags.isEmpty()) { + List registeredTags = applicationDAO.getAllTags(tenantId); + List registeredTagNames = new ArrayList<>(); + List tagIds = new ArrayList<>(); + + for (TagDTO tagDTO : registeredTags) { + registeredTagNames.add(tagDTO.getTagName()); + } + List newTags = getDifference(tags, registeredTagNames); + if (!newTags.isEmpty()) { + this.applicationDAO.addTags(newTags, tenantId); + if (log.isDebugEnabled()) { + log.debug("New tags entry added to AP_APP_TAG table. App Id:" + appId); + } + tagIds = this.applicationDAO.getTagIdsForTagNames(tags, tenantId); + } else { + for (TagDTO tagDTO : registeredTags) { + for (String tagName : tags) { + if (tagName.equals(tagDTO.getTagName())) { + tagIds.add(tagDTO.getId()); + break; + } + } + } + } + this.applicationDAO.addTagMapping(tagIds, appId, tenantId); + } + + if (log.isDebugEnabled()) { + log.debug("Creating a new release. App Id:" + appId); + } + String initialLifecycleState = lifecycleStateManager.getInitialState(); + applicationReleaseDTO.setCurrentState(initialLifecycleState); + applicationReleaseDTO = this.applicationReleaseDAO + .createRelease(applicationReleaseDTO, appId, tenantId); + LifecycleState lifecycleState = getLifecycleStateInstance(initialLifecycleState, initialLifecycleState); + this.lifecycleStateDAO.addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); + applicationReleaseEntities.add(applicationReleaseDTO); + applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); + Application application = APIUtil.appDtoToAppResponse(applicationDTO); + ConnectionManagerUtil.commitDBTransaction(); + return application; + } + } catch (LifeCycleManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "Error occurred while adding lifecycle state. application name: " + applicationDTO.getName() + "."; + log.error(msg, e); + try { + applicationStorageManager.deleteAllApplicationReleaseArtifacts( + Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); + } catch (ApplicationStorageManagementException ex) { + String errorLog = + "Error occurred when deleting application artifacts. Application artifacts are tried to " + + "delete because of lifecycle state adding issue in the application creating operation."; + log.error(errorLog, ex); + throw new ApplicationManagementException(errorLog, ex); + } + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while adding application or application release. application name: " + + applicationDTO.getName() + "."; + log.error(msg, e); + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); + throw new ApplicationManagementException(msg, e); + } catch (LifecycleManagementException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "Error occurred when getting initial lifecycle state. application name: " + applicationDTO.getName() + + "."; + log.error(msg, e); + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (VisibilityManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while adding unrestricted roles. application name: " + applicationDTO.getName() + + "."; + log.error(msg, e); + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public ApplicationRelease createEntAppRelease(int applicationId, EntAppReleaseWrapper entAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (log.isDebugEnabled()) { + log.debug("Application release creating request is received for the application id: " + applicationId); + } + + ApplicationDTO applicationDTO = getApplication(applicationId); + + if (!ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) { + String msg = "It is possible to add new application release for " + ApplicationType.ENTERPRISE.toString() + + " app type. But you are requesting to add new application release for " + applicationDTO.getType() + + " app type."; + log.error(msg); + throw new BadRequestException(msg); + } + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + if (isInvalidOsVersionRange(entAppReleaseWrapper.getSupportedOsVersions(), deviceType.getName())) { + String msg = "You are trying to add application release which has invalid or unsupported OS versions in " + + "the supportedOsVersions section. Hence, please re-evaluate the request payload."; + log.error(msg); + throw new BadRequestException(msg); + } + ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts( + APIUtil.releaseWrapperToReleaseDTO(entAppReleaseWrapper), applicationArtifact, deviceType.getName(), + tenantId, true); + try { + ConnectionManagerUtil.beginDBTransaction(); + String initialstate = lifecycleStateManager.getInitialState(); + applicationReleaseDTO.setCurrentState(initialstate); + LifecycleState lifecycleState = getLifecycleStateInstance(initialstate, initialstate); + applicationReleaseDTO = this.applicationReleaseDAO + .createRelease(applicationReleaseDTO, applicationDTO.getId(), tenantId); + this.lifecycleStateDAO + .addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); + ApplicationRelease applicationRelease = APIUtil.releaseDtoToRelease(applicationReleaseDTO); + ConnectionManagerUtil.commitDBTransaction(); + return applicationRelease; + } catch (TransactionManagementException e) { + String msg = "Error occurred while staring application release creating transaction for application Id: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while adding application release into IoTS app management ApplicationDTO id of" + + " the application release: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (LifeCycleManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while adding new application release lifecycle state to the application" + + " release: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while adding new application release for application " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /** + * Get Application and all application releases associated to the application that has given application Id + * + * @param applicationId Application Id + * @return {@link ApplicationDTO} + * @throws ApplicationManagementException if error occurred application data from the databse. + */ + private ApplicationDTO getApplication(int applicationId) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO.getApplication(applicationId, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't find application for the application Id: " + applicationId; + log.error(msg); + throw new NotFoundException(msg); + } + return applicationDTO; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection for getting application for the app ID" + + " " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting application data for application ID: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /** + * Upload enterprise application release artifact into file system. + * + * @param releaseDTO Apllication Release + * @param applicationArtifact Application Release artifacts + * @param deviceTypeName Device Type name + * @param tenantId Tenant Id + * @param isNewRelease New Release or Not + * @return {@link ApplicationReleaseDTO} + * @throws ApplicationManagementException if error occurred while uploading artifacts into file system. + */ + private ApplicationReleaseDTO uploadEntAppReleaseArtifacts(ApplicationReleaseDTO releaseDTO, + ApplicationArtifact applicationArtifact, String deviceTypeName, int tenantId, boolean isNewRelease) + throws ApplicationManagementException { + try { + ApplicationReleaseDTO applicationReleaseDTO = addApplicationReleaseArtifacts(deviceTypeName, releaseDTO, + applicationArtifact, isNewRelease); + return addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); + } catch (ResourceManagementException e) { + String msg = "Error occurred while uploading application release artifacts."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + /** + * Check whether given OS range is valid or invalid + * + * @param osRange OS range + * @param deviceTypeName Device Type + * @return true if invalid OS range, Otherwise returns false + * @throws ApplicationManagementException if error occurred while getting device type version for lower OS version + * and higher OS version + */ + private boolean isInvalidOsVersionRange(String osRange, String deviceTypeName) + throws ApplicationManagementException { + String lowestSupportingOsVersion; + String highestSupportingOsVersion = null; + String[] supportedOsVersionValues = osRange.split("-"); + lowestSupportingOsVersion = supportedOsVersionValues[0].trim(); + if (!"ALL".equals(supportedOsVersionValues[1].trim())) { + highestSupportingOsVersion = supportedOsVersionValues[1].trim(); + } + + try { + DeviceManagementProviderService deviceManagementProviderService = DAOUtil.getDeviceManagementService(); + return deviceManagementProviderService.getDeviceTypeVersion(deviceTypeName, lowestSupportingOsVersion) + == null || (highestSupportingOsVersion != null + && deviceManagementProviderService.getDeviceTypeVersion(deviceTypeName, highestSupportingOsVersion) + == null); + } catch (DeviceManagementException e) { + String msg = + "Error occurred while getting supported device type versions for device type : " + deviceTypeName; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + @Override + public Application getApplicationById(int appId, String state) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + boolean isVisibleApp = false; + ApplicationDTO applicationDTO = getApplication(appId); + + try { + ConnectionManagerUtil.openDBConnection(); + List filteredApplicationReleaseDTOs = new ArrayList<>(); + for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) { + if (!applicationReleaseDTO.getCurrentState().equals(lifecycleStateManager.getEndState()) && ( + state == null || applicationReleaseDTO.getCurrentState().equals(state))) { + filteredApplicationReleaseDTOs.add(applicationReleaseDTO); + } + } + if (state != null && filteredApplicationReleaseDTOs.isEmpty()) { + return null; + } + applicationDTO.setApplicationReleaseDTOs(filteredApplicationReleaseDTOs); + + List tags = this.applicationDAO.getAppTags(appId, tenantId); + List categories = this.applicationDAO.getAppCategories(appId, tenantId); + applicationDTO.setTags(tags); + if (!categories.isEmpty()){ + applicationDTO.setAppCategories(categories); + } + + List unrestrictedRoles = this.visibilityDAO.getUnrestrictedRoles(appId, tenantId); + if (!unrestrictedRoles.isEmpty()) { + if (hasUserRole(unrestrictedRoles, userName)) { + isVisibleApp = true; + } + } else { + isVisibleApp = true; + } + + if (!isVisibleApp) { + String msg = "You are trying to access visibility restricted application. You don't have required " + + "roles to view this application,"; + log.error(msg); + throw new ForbiddenException(msg); + } + return APIUtil.appDtoToAppResponse(applicationDTO); + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection to get application for application ID: " + + appId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (LifecycleManagementException e) { + String msg = "Error occurred when getting the last state of the application lifecycle flow"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "User-store exception while getting application with the application id " + appId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occured when getting, either application tags or application categories"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public Application getApplicationByUuid(String releaseUuid) throws ApplicationManagementException{ + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + boolean isVisibleApp = false; + + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't found an application for application release UUID: " + releaseUuid; + log.error(msg); + throw new NotFoundException(msg); + } + + List tags = this.applicationDAO.getAppTags(applicationDTO.getId(), tenantId); + List categories = this.applicationDAO.getAppCategories(applicationDTO.getId(), tenantId); + applicationDTO.setTags(tags); + applicationDTO.setAppCategories(categories); + + List unrestrictedRoles = this.visibilityDAO.getUnrestrictedRoles(applicationDTO.getId(), tenantId); + if (!unrestrictedRoles.isEmpty()) { + if (hasUserRole(unrestrictedRoles, userName)) { + isVisibleApp = true; + } + } else { + isVisibleApp = true; + } + + if (!isVisibleApp) { + String msg = "You are trying to access visibility restricted application. You don't have required " + + "roles to view this application,"; + log.error(msg); + throw new ForbiddenException(msg); + } + return APIUtil.appDtoToAppResponse(applicationDTO); + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection to get application for application " + + "release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "User-store exception occurred while getting application for application release UUID " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting dta which are related to Application."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + + @Override + public Application getApplicationByUuid(String releaseUuid, String state) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + boolean isVisibleApp = false; + + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = applicationDAO.getApplication(releaseUuid, tenantId); + + if (applicationDTO == null) { + String msg = "Couldn't found an application for application release UUID: " + releaseUuid; + log.error(msg); + throw new NotFoundException(msg); + } + + List filteredApplicationReleaseDTOs = new ArrayList<>(); + for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) { + if (!applicationReleaseDTO.getCurrentState().equals(lifecycleStateManager.getEndState()) && ( + state == null || applicationReleaseDTO.getCurrentState().equals(state))) { + filteredApplicationReleaseDTOs.add(applicationReleaseDTO); + } + } + if (state != null && filteredApplicationReleaseDTOs.isEmpty()) { + return null; + } + applicationDTO.setApplicationReleaseDTOs(filteredApplicationReleaseDTOs); + + List tags = this.applicationDAO.getAppTags(applicationDTO.getId(), tenantId); + List categories = this.applicationDAO.getAppCategories(applicationDTO.getId(), tenantId); + applicationDTO.setTags(tags); + applicationDTO.setAppCategories(categories); + + List unrestrictedRoles = this.visibilityDAO.getUnrestrictedRoles(applicationDTO.getId(), tenantId); + if (!unrestrictedRoles.isEmpty()) { + if (hasUserRole(unrestrictedRoles, userName)) { + isVisibleApp = true; + } + } else { + isVisibleApp = true; + } + + if (!isVisibleApp) { + String msg = "You are trying to access visibility restricted application. You don't have required " + + "roles to view this application,"; + log.error(msg); + throw new ForbiddenException(msg); + } + return APIUtil.appDtoToAppResponse(applicationDTO); + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection to get application for application " + + "release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (LifecycleManagementException e) { + String msg = "Error occurred when getting the last state of the application lifecycle flow"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "User-store exception while getting application with the application release UUID " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting, application data."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /** + * Check whether at least one role is assigned to the given user. + * + * @param unrestrictedRoleList unrestricted role list + * @param userName Username + * @return true at least one unrestricted role has assigned to given user, otherwise returns false. + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ + private boolean hasUserRole(Collection unrestrictedRoleList, String userName) throws UserStoreException { + String[] roleList = getRolesOfUser(userName); + for (String unrestrictedRole : unrestrictedRoleList) { + for (String role : roleList) { + if (unrestrictedRole.equals(role)) { + return true; + } + } + } + return false; + } + + /** + * Check whether valid unrestricted role list or not + * + * @return true or false + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ + private boolean isValidRestrictedRole(Collection unrestrictedRoleList) throws UserStoreException { + //todo check role by role + UserRealm userRealm = CarbonContext.getThreadLocalCarbonContext().getUserRealm(); + if (userRealm != null) { + List roleList = new ArrayList<>(Arrays.asList(userRealm.getUserStoreManager().getRoleNames())); + return roleList.containsAll(unrestrictedRoleList); + } else { + String msg = "User realm is not initiated."; + log.error(msg); + throw new UserStoreException(msg); + } + } + + /** + * Get assigned role list of the given user. + * + * @param userName Username + * @return List of roles + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ + private String[] getRolesOfUser(String userName) throws UserStoreException { + UserRealm userRealm = CarbonContext.getThreadLocalCarbonContext().getUserRealm(); + String[] roleList; + if (userRealm != null) { + userRealm.getUserStoreManager().getRoleNames(); + roleList = userRealm.getUserStoreManager().getRoleListOfUser(userName); + } else { + String msg = "User realm is not initiated. Logged in user: " + userName; + log.error(msg); + throw new UserStoreException(msg); + } + return roleList; + } + + @Override + public void deleteApplication(int applicationId) throws ApplicationManagementException { + if (log.isDebugEnabled()) { + log.debug("Request is received to delete applications which are related with the application id " + + applicationId); + } + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + ApplicationDTO applicationDTO = getApplication(applicationId); + List applicationReleaseDTOs = applicationDTO.getApplicationReleaseDTOs(); + for (ApplicationReleaseDTO applicationReleaseDTO : applicationReleaseDTOs) { + if (!lifecycleStateManager.isDeletableState(applicationReleaseDTO.getCurrentState())){ + String msg = "Application release which has application release UUID: " + + applicationReleaseDTO.getUuid() + " is not in a deletable state. Therefore Application " + + "deletion is not permitted. In order to delete the application, all application releases " + + "of the application has to be in a deletable state."; + log.error(msg); + throw new ForbiddenException(msg); + } + } + + try { + ConnectionManagerUtil.beginDBTransaction(); + List deletingAppReleaseIds = new ArrayList<>(); + List deletingAppHashVals = new ArrayList<>(); + for (ApplicationReleaseDTO applicationReleaseDTO : applicationReleaseDTOs) { + List deviceSubscriptionDTOS = subscriptionDAO + .getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId); + if (!deviceSubscriptionDTOS.isEmpty()){ + String msg = "Application release which has UUID: " + applicationReleaseDTO.getUuid() + + " either subscribed to device/s or it had subscribed to device/s. Therefore you are not " + + "permitted to delete the application release."; + log.error(msg); + throw new ForbiddenException(msg); + } + deletingAppHashVals.add(applicationReleaseDTO.getAppHashValue()); + deletingAppReleaseIds.add(applicationReleaseDTO.getId()); + } + applicationStorageManager.deleteAllApplicationReleaseArtifacts(deletingAppHashVals, tenantId); + this.lifecycleStateDAO.deleteLifecycleStates(deletingAppReleaseIds); + this.applicationReleaseDAO.deleteReleases(deletingAppReleaseIds); + this.applicationDAO.deleteApplicationTags(applicationId, tenantId); + this.applicationDAO.deleteAppCategories(applicationId, tenantId); + this.applicationDAO.deleteApplication(applicationId, tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while observing the database connection to delete application which has " + + "application ID: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when deleting application which has application ID: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when getting application data for application id: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationStorageManagementException e) { + String msg = "Error occurred when deleting application artifacts in the file system. Application id: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (LifeCycleManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured while deleting life-cycle state data of application releases of the application" + + " which has application ID: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void retireApplication(int applicationId) throws ApplicationManagementException { + if (log.isDebugEnabled()) { + log.debug("Request is received to delete applications which are related with the application id " + + applicationId); + } + ApplicationDTO applicationDTO = getApplication(applicationId); + try { + ConnectionManagerUtil.beginDBTransaction(); + List applicationReleaseDTOs = applicationDTO.getApplicationReleaseDTOs(); + List activeApplicationReleaseDTOs = new ArrayList<>(); + for (ApplicationReleaseDTO applicationReleaseDTO : applicationReleaseDTOs) { + if (!applicationReleaseDTO.getCurrentState().equals(lifecycleStateManager.getEndState())) { + activeApplicationReleaseDTOs.add(applicationReleaseDTO); + } + } + if (!activeApplicationReleaseDTOs.isEmpty()) { + String msg = "There are application releases which are not in the " + lifecycleStateManager + .getEndState() + " state. Hence you are not allowed to delete the application"; + log.error(msg); + throw new ForbiddenException(msg); + } + this.applicationDAO.retireApplication(applicationId); + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while observing the database connection to retire an application which has " + + "application ID:" + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when retiring application which has application ID: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting application data for application id: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void deleteApplicationRelease(String releaseUuid) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO + .getReleaseByUUID(releaseUuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + releaseUuid; + log.error(msg); + throw new NotFoundException(msg); + } + + if (!lifecycleStateManager.isDeletableState(applicationReleaseDTO.getCurrentState())) { + String msg = "Application state is not in the deletable state. Therefore you are not permitted to " + + "delete the application release."; + log.error(msg); + throw new ForbiddenException(msg); + } + List deviceSubscriptionDTOS = subscriptionDAO + .getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId); + if (!deviceSubscriptionDTOS.isEmpty()){ + String msg = "Application release which has UUID: " + applicationReleaseDTO.getUuid() + + " either subscribed to device/s or it had subscribed to device/s. Therefore you are not " + + "permitted to delete the application release."; + log.error(msg); + throw new ForbiddenException(msg); + } + applicationStorageManager.deleteAllApplicationReleaseArtifacts( + Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); + lifecycleStateDAO.deleteLifecycleStateByReleaseId(applicationReleaseDTO.getId()); + applicationReleaseDAO.deleteRelease(applicationReleaseDTO.getId()); + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while observing the database connection to delete application release which " + + "has UUID:" + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when deleting application release which has UUID: " + + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when application release data for application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationStorageManagementException e) { + String msg = "Error occurred when deleting the application release artifact from the file system. " + + "Application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (LifeCycleManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when dleting lifecycle data for application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void updateApplicationImageArtifact(String uuid, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationReleaseDTO applicationReleaseDTO; + try { + ConnectionManagerUtil.beginDBTransaction(); + applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Application release image artifact uploading is failed. Doesn't exist a application " + + "release for application ID: application UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + + String currentState = applicationReleaseDTO.getCurrentState(); + if (!lifecycleStateManager.isUpdatableState(currentState)){ + throw new ForbiddenException( + "Can't Update the application release. Application release is in " + currentState + + " and it is not an release updatable state. Hence please move the application release" + + " into updatable state and retry the operation."); + } + applicationReleaseDTO = this.applicationReleaseDAO + .updateRelease(updateImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId), tenantId); + if (applicationReleaseDTO == null) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Application release updating count is 0 for application release UUID: " + uuid; + log.error(msg); + throw new ApplicationManagementException(msg); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = + "Error occured when getting DB connection to update image artifacts of the application release " + + "which has uuid " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when updating application release image artifacts which has " + + "UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + }catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "Error occured while getting application release data for updating image artifacts of the application release uuid " + + uuid + "."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ResourceManagementException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured while updating image artifacts of the application release uuid " + uuid + "."; + log.error(msg, e); + throw new ApplicationManagementException(msg , e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void updateApplicationArtifact(String deviceType, String releaseUuid, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean isValidDeviceType = false; + List deviceTypes; + try { + deviceTypes = DAOUtil.getDeviceManagementService().getDeviceTypes(); + + for (DeviceType dt : deviceTypes) { + if (dt.getName().equals(deviceType)) { + isValidDeviceType = true; + break; + } + } + if (!isValidDeviceType) { + String msg = "Invalid request to update application release artifact, invalid application type: " + + deviceType + " for application release uuid: " + releaseUuid; + log.error(msg); + throw new BadRequestException(msg); + } + } catch (DeviceManagementException e) { + String msg = "Error occured while getting supported device types in IoTS"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't found an application which has application release for UUID: " + releaseUuid; + log.error(msg); + throw new NotFoundException(msg); + } + if (!ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) { + String msg = "If Application type is " + applicationDTO.getType() + ", then you don't have application " + + "release artifact to update for application release UUID: " + releaseUuid; + log.error(msg); + throw new ApplicationManagementException(msg); + } + + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + if (!lifecycleStateManager.isUpdatableState(applicationReleaseDTO.getCurrentState())) { + String msg = "Application release in " + applicationReleaseDTO.getCurrentState() + + " state. Therefore you are not allowed to update the application release. Hence, " + + "please move application release from " + applicationReleaseDTO.getCurrentState() + + " to updatable state."; + log.error(msg); + throw new ForbiddenException(msg); + } + + applicationReleaseDTO = updateEntAppReleaseArtifact(deviceType,applicationReleaseDTO + , applicationArtifact); + applicationReleaseDTO = this.applicationReleaseDAO.updateRelease(applicationReleaseDTO, tenantId); + if (applicationReleaseDTO == null) { + ConnectionManagerUtil.rollbackDBTransaction(); + throw new ApplicationManagementException( + "ApplicationDTO release updating count is 0. ApplicationDTO release UUID: " + releaseUuid); + + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured while getting/updating APPM DB for updating application Installer."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occured while starting the transaction to update application release artifact which has " + + "application uuid " + releaseUuid + "."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occured when getting DB connection to update application release artifact of the " + + "application release uuid " + releaseUuid + "."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationStorageManagementException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "In order to update the artifact, couldn't find it in the system"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ResourceManagementException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured when updating application installer."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getLifecycleStateChangeFlow(String releaseUuid) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO + .getReleaseByUUID(releaseUuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't found an application release for application release UUID: " + releaseUuid; + log.error(msg); + throw new NotFoundException(msg); + } + return this.lifecycleStateDAO.getLifecycleStates(applicationReleaseDTO.getId(), tenantId); + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection to get lifecycle state change flow for " + + "application release which has UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (LifeCycleManagementDAOException e) { + String msg = "Failed to get lifecycle state for application release uuid " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = + "Error occurred while getting application release for application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public ApplicationRelease changeLifecycleState(String releaseUuid, LifecycleChanger lifecycleChanger) + throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (lifecycleChanger == null || StringUtils.isEmpty(lifecycleChanger.getAction())) { + String msg = "The Action is null or empty. Please verify the request."; + log.error(msg); + throw new BadRequestException(msg); + } + + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO + .getReleaseByUUID(releaseUuid, tenantId); + + if (applicationReleaseDTO == null) { + String msg = "Couldn't found an application release for the UUID: " + releaseUuid; + log.error(msg); + throw new NotFoundException(msg); + } + if (lifecycleStateManager + .isValidStateChange(applicationReleaseDTO.getCurrentState(), lifecycleChanger.getAction(), userName, + tenantId)) { + if (lifecycleStateManager.isInstallableState(lifecycleChanger.getAction()) && applicationReleaseDAO + .hasExistInstallableAppRelease(applicationReleaseDTO.getUuid(), + lifecycleStateManager.getInstallableState(), tenantId)) { + String msg = "Installable application release is already registered for the application. " + + "Therefore it is not permitted to change the lifecycle state from " + + applicationReleaseDTO.getCurrentState() + " to " + lifecycleChanger.getAction(); + log.error(msg); + throw new ForbiddenException(msg); + } + LifecycleState lifecycleState = new LifecycleState(); + lifecycleState.setCurrentState(lifecycleChanger.getAction()); + lifecycleState.setPreviousState(applicationReleaseDTO.getCurrentState()); + lifecycleState.setUpdatedBy(userName); + lifecycleState.setReasonForChange(lifecycleChanger.getReason()); + applicationReleaseDTO.setCurrentState(lifecycleChanger.getAction()); + if (this.applicationReleaseDAO.updateRelease(applicationReleaseDTO, tenantId) == null) { + String msg = "Application release updating is failed/."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + this.lifecycleStateDAO.addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); + ConnectionManagerUtil.commitDBTransaction(); + return APIUtil.releaseDtoToRelease(applicationReleaseDTO); + } else { + String msg = "Invalid lifecycle state transition from '" + applicationReleaseDTO.getCurrentState() + "'" + + " to '" + lifecycleChanger.getAction() + "'"; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to change lifecycle state of the " + + "application release which has UUID:" + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when changing lifecycle state of application release which " + + "has UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + }catch (LifeCycleManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Failed to add lifecycle state for Application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when accessing application release data of application release which has the " + + "application release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void addApplicationCategories(List categories) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + List existingCategories = applicationDAO.getAllCategories(tenantId); + List existingCategoryNames = existingCategories.stream().map(CategoryDTO::getCategoryName) + .collect(Collectors.toList()); + if(!existingCategoryNames.containsAll(categories)){ + List newCategories = getDifference(categories, existingCategoryNames); + applicationDAO.addCategories(newCategories, tenantId); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to add application categories."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when adding application categories."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured when getting existing categories or when inserting new application categories."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public Application updateApplication(int applicationId, ApplicationUpdateWrapper applicationUpdateWrapper) + throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + ApplicationDTO applicationDTO = getApplication(applicationId); + try { + ConnectionManagerUtil.beginDBTransaction(); + if (!StringUtils.isEmpty(applicationUpdateWrapper.getName())){ + if (applicationDAO + .isExistingAppName(applicationUpdateWrapper.getName().trim(), applicationDTO.getDeviceTypeId(), + tenantId)) { + String msg = "Already an application registered with same name " + applicationUpdateWrapper.getName() + + ". Hence you can't update the application name from " + applicationDTO.getName() + " to " + + applicationUpdateWrapper.getName(); + log.error(msg); + throw new BadRequestException(msg); + } + applicationDTO.setName(applicationUpdateWrapper.getName()); + } + if (!StringUtils.isEmpty(applicationUpdateWrapper.getSubMethod()) && !applicationDTO.getSubType() + .equals(applicationUpdateWrapper.getSubMethod())) { + if (!ApplicationSubscriptionType.PAID.toString().equals(applicationUpdateWrapper.getSubMethod()) + && !ApplicationSubscriptionType.FREE.toString().equals(applicationUpdateWrapper.getSubMethod())) { + String msg = "Invalid application subscription type is found with application updating request " + + applicationUpdateWrapper.getSubMethod(); + log.error(msg); + throw new BadRequestException(msg); + + } else if (ApplicationSubscriptionType.FREE.toString().equals(applicationUpdateWrapper.getSubMethod()) + && !StringUtils.isEmpty(applicationUpdateWrapper.getPaymentCurrency())) { + String msg = "If you are going to change paid app as Free app, " + + "currency attribute in the application updating payload should be null or \"\""; + log.error(msg); + throw new ApplicationManagementException(msg); + } else if (ApplicationSubscriptionType.PAID.toString().equals(applicationUpdateWrapper.getSubMethod()) + && StringUtils.isEmpty(applicationUpdateWrapper.getPaymentCurrency()) ){ + String msg = "If you are going to change Free app as paid app, currency attribute in the application" + + " payload should not be null or \"\""; + log.error(msg); + throw new ApplicationManagementException(msg); + } + applicationDTO.setSubType(applicationUpdateWrapper.getSubMethod()); + applicationDTO.setPaymentCurrency(applicationUpdateWrapper.getPaymentCurrency()); + } + + if (!StringUtils.isEmpty(applicationUpdateWrapper.getDescription())){ + applicationDTO.setDescription(applicationUpdateWrapper.getDescription()); + } + + List appUnrestrictedRoles = this.visibilityDAO.getUnrestrictedRoles(applicationId, tenantId); + + boolean isExistingAppRestricted = !appUnrestrictedRoles.isEmpty(); + boolean isUpdatingAppRestricted = false; + if (applicationUpdateWrapper.getUnrestrictedRoles() != null && !applicationUpdateWrapper + .getUnrestrictedRoles().isEmpty()) { + isUpdatingAppRestricted = true; + } + + if (isExistingAppRestricted && !isUpdatingAppRestricted) { + visibilityDAO.deleteUnrestrictedRoles(appUnrestrictedRoles, applicationId, tenantId); + } else if (isUpdatingAppRestricted) { + if (!hasUserRole(applicationUpdateWrapper.getUnrestrictedRoles(), userName)) { + String msg = + "You are trying to restrict the visibility of visible application.But you are trying to " + + "restrict the visibility to roles that there isn't at least one role is assigned " + + "to user: " + userName + ". Therefore, it is not allowed and you should have " + + "added at least one role that assigned to " + userName + " user into " + + "restricting role set."; + log.error(msg); + throw new BadRequestException(msg); + } + + if (!isExistingAppRestricted) { + visibilityDAO + .addUnrestrictedRoles(applicationUpdateWrapper.getUnrestrictedRoles(), applicationId, tenantId); + } else { + List addingRoleList = getDifference(applicationUpdateWrapper.getUnrestrictedRoles(), + applicationDTO.getUnrestrictedRoles()); + List removingRoleList = getDifference(applicationDTO.getUnrestrictedRoles(), + applicationUpdateWrapper.getUnrestrictedRoles()); + if (!addingRoleList.isEmpty()) { + visibilityDAO.addUnrestrictedRoles(addingRoleList, applicationId, tenantId); + } + if (!removingRoleList.isEmpty()) { + visibilityDAO.deleteUnrestrictedRoles(removingRoleList, applicationId, tenantId); + } + } + } + applicationDTO.setUnrestrictedRoles(applicationUpdateWrapper.getUnrestrictedRoles()); + List updatingAppCategries = applicationUpdateWrapper.getCategories(); + + if (updatingAppCategries != null){ + List allCategories = this.applicationDAO.getAllCategories(tenantId); + List allCategoryName = allCategories.stream().map(CategoryDTO::getCategoryName) + .collect(Collectors.toList()); + + if (!getDifference(updatingAppCategries, allCategoryName).isEmpty()){ + String msg = "Application update request contains invalid category names. Hence please verify the request payload"; + log.error(msg); + throw new BadRequestException(msg); + } + + List appCategories = this.applicationDAO.getAppCategories(applicationId, tenantId); + List addingAppCategories = getDifference(updatingAppCategries, appCategories); + List removingAppCategories = getDifference(appCategories, updatingAppCategries); + if (!addingAppCategories.isEmpty()) { + List categoryIds = this.applicationDAO.getCategoryIdsForCategoryNames(addingAppCategories, tenantId); + this.applicationDAO.addCategoryMapping(categoryIds, applicationId, tenantId); + } + if (!removingAppCategories.isEmpty()) { + List categoryIds = this.applicationDAO.getCategoryIdsForCategoryNames(removingAppCategories, tenantId); + this.applicationDAO.deleteAppCategories(categoryIds, applicationId, tenantId); + } + } + + List updatingAppTags = applicationUpdateWrapper.getTags(); + if (updatingAppTags!= null){ + List appTags = this.applicationDAO.getAppTags(applicationId, tenantId); + List addingTagList = getDifference(updatingAppTags, appTags); + List removingTagList = getDifference(appTags, updatingAppTags); + if (!addingTagList.isEmpty()) { + List allTags = this.applicationDAO.getAllTags(tenantId); + List newTags = addingTagList.stream().filter(updatingTagName -> allTags.stream() + .noneMatch(tag -> tag.getTagName().equals(updatingTagName))).collect(Collectors.toList()); + if (!newTags.isEmpty()){ + this.applicationDAO.addTags(newTags, tenantId); + } + List addingTagIds = this.applicationDAO.getTagIdsForTagNames(addingTagList, tenantId); + this.applicationDAO.addTagMapping(addingTagIds, applicationId, tenantId); + } + if (!removingTagList.isEmpty()) { + List removingTagIds = this.applicationDAO.getTagIdsForTagNames(removingTagList, tenantId); + this.applicationDAO.deleteApplicationTags(removingTagIds, applicationId, tenantId); + } + } + if (!applicationDAO.updateApplication(applicationDTO, tenantId)){ + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Any application is not updated for the application ID: " + applicationId; + log.error(msg); + throw new ApplicationManagementException(msg); + } + ConnectionManagerUtil.commitDBTransaction(); + return APIUtil.appDtoToAppResponse(applicationDTO); + } catch (UserStoreException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while checking whether logged in user is ADMIN or not when updating " + + "application of application id: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while updating the application, application id: " + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (VisibilityManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while updating the visibility restriction of the application. Application id: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while starting database transaction for application updating. Application id: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection for application updating. Application id: " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getRegisteredTags() throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + List tags = applicationDAO.getAllTags(tenantId); + List mappedTagIds = applicationDAO.getDistinctTagIdsInTagMapping(); + List responseTagList = new ArrayList<>(); + tags.forEach(tag -> { + Tag responseTag = new Tag(); + if (!mappedTagIds.contains(tag.getId())) { + responseTag.setTagDeletable(true); + } + responseTag.setTagName(tag.getTagName()); + responseTagList.add(responseTag); + }); + return responseTagList; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection to get registered tags"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting registered tags from the system."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getRegisteredCategories() throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + List categories = applicationDAO.getAllCategories(tenantId); + List mappedCategoryIds = applicationDAO.getDistinctCategoryIdsInCategoryMapping(); + List responseCategoryList = new ArrayList<>(); + categories.forEach(category -> { + Category responseCategory = new Category(); + if (!mappedCategoryIds.contains(category.getId())) { + responseCategory.setCategoryDeletable(true); + } + responseCategory.setCategoryName(category.getCategoryName()); + responseCategoryList.add(responseCategory); + }); + return responseCategoryList; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection to get registered categories."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting registered tags from the system."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void deleteApplicationTag(int appId, String tagName) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ApplicationDTO applicationDTO = getApplication(appId); + ConnectionManagerUtil.beginDBTransaction(); + TagDTO tag = applicationDAO.getTagForTagName(tagName, tenantId); + if (tag == null){ + String msg = "Couldn't found a tag for tag name " + tagName + "."; + log.error(msg); + throw new NotFoundException(msg); + } + if (applicationDAO.hasTagMapping(tag.getId(), applicationDTO.getId(), tenantId)){ + applicationDAO.deleteApplicationTag(tag.getId(), applicationDTO.getId(), tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } else { + String msg = "Tag " + tagName + " is not an application tag. Application ID: " + appId; + log.error(msg); + throw new BadRequestException(msg); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to delete application tag."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when deleting application tag."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting tag Id or deleting tag mapping from the system."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void deleteTag(String tagName) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + TagDTO tag = applicationDAO.getTagForTagName(tagName, tenantId); + if (tag == null){ + String msg = "Couldn't found a tag for tag name " + tagName + "."; + log.error(msg); + throw new NotFoundException(msg); + } + if (applicationDAO.hasTagMapping(tag.getId(), tenantId)){ + applicationDAO.deleteTagMapping(tag.getId(), tenantId); + } + applicationDAO.deleteTag(tag.getId(), tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to delete registered tag."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when deleting registered tag."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting tag Id or deleting the tag from the system."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void deleteUnusedTag(String tagName) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + TagDTO tag = applicationDAO.getTagForTagName(tagName, tenantId); + if (tag == null){ + String msg = "Couldn't found a tag for tag name " + tagName + "."; + log.error(msg); + throw new NotFoundException(msg); + } + if (applicationDAO.hasTagMapping(tag.getId(), tenantId)){ + String msg = + "Tag " + tagName + " is used for applications. Hence it is not permitted to delete the tag " + + tagName; + log.error(msg); + throw new ForbiddenException(msg); + } + applicationDAO.deleteTag(tag.getId(), tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to delete unused tag."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when deleting unused tag."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting tag Ids or deleting the tag from the system."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void updateTag(String oldTagName, String newTagName) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (StringUtils.isEmpty(oldTagName) || StringUtils.isEmpty(newTagName)) { + String msg = "Either old tag name or new tag name contains empty/null value. Hence please verify the " + + "request."; + log.error(msg); + throw new BadRequestException(msg); + } + try { + ConnectionManagerUtil.beginDBTransaction(); + if (applicationDAO.getTagForTagName(newTagName, tenantId) != null){ + String msg = + "You are trying to modify tag name into existing tag. Therefore you can't modify tag name from " + + oldTagName + " to new tag name " + newTagName; + log.error(msg); + throw new BadRequestException(msg); + } + TagDTO tag = applicationDAO.getTagForTagName(oldTagName, tenantId); + if (tag == null){ + String msg = "Couldn't found a tag for tag name " + oldTagName + "."; + log.error(msg); + throw new NotFoundException(msg); + } + tag.setTagName(newTagName); + applicationDAO.updateTag(tag, tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to update application tag."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when updating application tag."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting tag Ids or deleting the tag from the system."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List addTags(List tags) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + if (tags != null && !tags.isEmpty()) { + ConnectionManagerUtil.beginDBTransaction(); + List registeredTags = applicationDAO.getAllTags(tenantId); + List registeredTagNames = registeredTags.stream().map(TagDTO::getTagName) + .collect(Collectors.toList()); + + List newTags = getDifference(tags, registeredTagNames); + if (!newTags.isEmpty()) { + this.applicationDAO.addTags(newTags, tenantId); + ConnectionManagerUtil.commitDBTransaction(); + if (log.isDebugEnabled()) { + log.debug("New tags are added to the AP_APP_TAG table."); + } + } + return Stream.concat(registeredTagNames.stream(), newTags.stream()).collect(Collectors.toList()); + } else{ + String msg = "Tag list is either null of empty. In order to add new tags, tag list should be a list of " + + "Stings. Therefore please verify the payload."; + log.error(msg); + throw new BadRequestException(msg); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to add tags."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when adding tags."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred either getting registered tags or adding new tags."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List addApplicationTags(int appId, List tags) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ApplicationDTO applicationDTO = getApplication(appId); + if (tags != null && !tags.isEmpty()) { + ConnectionManagerUtil.beginDBTransaction(); + List registeredTags = applicationDAO.getAllTags(tenantId); + List registeredTagNames = registeredTags.stream().map(TagDTO::getTagName) + .collect(Collectors.toList()); + + List newTags = getDifference(tags, registeredTagNames); + if (!newTags.isEmpty()) { + this.applicationDAO.addTags(newTags, tenantId); + if (log.isDebugEnabled()) { + log.debug("New tags entries are added to AP_APP_TAG table. App Id:" + applicationDTO.getId()); + } + } + + List applicationTags = this.applicationDAO.getAppTags(applicationDTO.getId(), tenantId); + List newApplicationTags = getDifference(tags, applicationTags); + if (!newApplicationTags.isEmpty()) { + List newTagIds = this.applicationDAO.getTagIdsForTagNames(newApplicationTags, tenantId); + this.applicationDAO.addTagMapping(newTagIds, applicationDTO.getId(), tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } + return Stream.concat(applicationTags.stream(), newApplicationTags.stream()) + .collect(Collectors.toList()); + } else { + String msg = "Tag list is either null or empty. In order to add new tags for application which has " + + "application ID: " + appId +", tag list should be a list of Stings. Therefore please " + + "verify the payload."; + log.error(msg); + throw new BadRequestException(msg); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to add application tags."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when adding application tags."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while accessing application tags. Application ID: " + appId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List addCategories(List categories) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + if (categories != null && !categories.isEmpty()) { + ConnectionManagerUtil.beginDBTransaction(); + List registeredCategories = applicationDAO.getAllCategories(tenantId); + List registeredCategoryNames = registeredCategories.stream().map(CategoryDTO::getCategoryName) + .collect(Collectors.toList()); + + List newCategories = getDifference(categories, registeredCategoryNames); + if (!newCategories.isEmpty()) { + this.applicationDAO.addCategories(newCategories, tenantId); + ConnectionManagerUtil.commitDBTransaction(); + if (log.isDebugEnabled()) { + log.debug("New categories are added to the AP_APP_TAG table."); + } + } + return Stream.concat(registeredCategoryNames.stream(), newCategories.stream()) + .collect(Collectors.toList()); + } else{ + String msg = "Category list is either null of empty. In order to add new categories, category list " + + "should be a list of Stings. Therefore please verify the payload."; + log.error(msg); + throw new BadRequestException(msg); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to add categories."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when adding categories."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred either getting registered categories or adding new categories."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void deleteCategory(String categoryName) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + CategoryDTO category = applicationDAO.getCategoryForCategoryName(categoryName, tenantId); + if (category == null){ + String msg = "Couldn't found a category for category name " + categoryName + "."; + log.error(msg); + throw new NotFoundException(msg); + } + if (applicationDAO.hasCategoryMapping(category.getId(), tenantId)){ + String msg = "Category " + category.getCategoryName() + " is used by some applications. Therefore it " + + "is not permitted to delete the application category."; + log.error(msg); + throw new ForbiddenException(msg); + } + applicationDAO.deleteCategory(category.getId(), tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to delete category."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when deleting category."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting category Id or deleting the category from the system."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void updateCategory(String oldCategoryName, String newCategoryName) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + CategoryDTO category = applicationDAO.getCategoryForCategoryName(oldCategoryName, tenantId); + if (category == null){ + String msg = "Couldn't found a category for tag name " + oldCategoryName + "."; + log.error(msg); + throw new NotFoundException(msg); + } + category.setCategoryName(newCategoryName); + applicationDAO.updateCategory(category, tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to update category."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when updating categiry."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting tag Ids or deleting the category from the system."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public String getInstallableLifecycleState() throws ApplicationManagementException { + if (lifecycleStateManager == null) { + String msg = "Application lifecycle manager is not initialed. Please contact the administrator."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + return lifecycleStateManager.getInstallableState(); + } + + /** + * This method can be used to validate {@link Filter} object. + * + * @param filter {@link Filter} + * @throws BadRequestException if filter object contains incompatible data. + */ + private void validateFilter(Filter filter) throws BadRequestException { + if (filter == null) { + String msg = "Filter validation is failed, Filter shouldn't be null, hence please verify the request payload"; + log.error(msg); + throw new BadRequestException(msg); + } + String appType = filter.getAppType(); + + if (!StringUtils.isEmpty(appType)) { + boolean isValidAppType = false; + for (ApplicationType applicationType : ApplicationType.values()) { + if (applicationType.toString().equalsIgnoreCase(appType)) { + isValidAppType = true; + break; + } + } + if (!isValidAppType) { + String msg = + "Filter validation is failed, Invalid application type is found in filter. Application Type: " + + appType + " Please verify the request payload"; + log.error(msg); + throw new BadRequestException(msg); + } + } + + RatingConfiguration ratingConfiguration = ConfigurationManager.getInstance().getConfiguration() + .getRatingConfiguration(); + + int defaultMinRating = ratingConfiguration.getMinRatingValue(); + int defaultMaxRating = ratingConfiguration.getMaxRatingValue(); + int filteringMinRating = filter.getMinimumRating(); + + if (filteringMinRating != 0 && (filteringMinRating < defaultMinRating || filteringMinRating > defaultMaxRating)) + { + String msg = "Filter validation is failed, Minimum rating value: " + filteringMinRating + + " is not in the range of default minimum rating value " + defaultMaxRating + + " and default maximum rating " + defaultMaxRating; + log.error(msg); + throw new BadRequestException(msg); + } + + String appReleaseState = filter.getAppReleaseState(); + if (!StringUtils.isEmpty(appReleaseState) && !lifecycleStateManager.isStateExist(appReleaseState)) { + String msg = "Filter validation is failed, Requesting to filter by invalid app release state: " + + appReleaseState; + log.error(msg); + throw new BadRequestException(msg); + } + } + + /** + * This method can be used to get difference of two lists. + * + * @param list1 List of objects + * @param list2 List of object + * @param Object type + * @return return list of values which are not in the list2 but in the list1 + */ + private List getDifference(List list1, Collection list2) { + List list = new ArrayList<>(); + for (T t : list1) { + if (!list2.contains(t)) { + list.add(t); + } + } + return list; + } + + /** + * By invoking the method, it returns Lifecycle State Instance. + * @param currentState Current state of the lifecycle + * @param previousState Previouse state of the Lifecycle + * @return {@link LifecycleState} + */ + private LifecycleState getLifecycleStateInstance(String currentState, String previousState) { + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + LifecycleState lifecycleState = new LifecycleState(); + lifecycleState.setCurrentState(currentState); + lifecycleState.setPreviousState(previousState); + lifecycleState.setUpdatedBy(userName); + return lifecycleState; + } + + @Override + public ApplicationRelease updateEntAppRelease(String releaseUuid, EntAppReleaseWrapper entAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); + AtomicReference applicationReleaseDTO = new AtomicReference<>( + applicationDTO.getApplicationReleaseDTOs().get(0)); + validateAppReleaseUpdating(applicationDTO, ApplicationType.ENTERPRISE.toString()); + applicationReleaseDTO.get().setPrice(entAppReleaseWrapper.getPrice()); + applicationReleaseDTO.get().setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); + if (!StringUtils.isEmpty(entAppReleaseWrapper.getSupportedOsVersions())) { + applicationReleaseDTO.get().setSupportedOsVersions(entAppReleaseWrapper.getSupportedOsVersions()); + } + if (!StringUtils.isEmpty(entAppReleaseWrapper.getDescription())) { + applicationReleaseDTO.get().setDescription(entAppReleaseWrapper.getDescription()); + } + if (!StringUtils.isEmpty(entAppReleaseWrapper.getReleaseType())) { + applicationReleaseDTO.get().setReleaseType(entAppReleaseWrapper.getReleaseType()); + } + if (!StringUtils.isEmpty(entAppReleaseWrapper.getMetaData())) { + applicationReleaseDTO.get().setMetaData(entAppReleaseWrapper.getMetaData()); + } + + if (!StringUtils.isEmpty(applicationArtifact.getInstallerName()) + && applicationArtifact.getInstallerStream() != null) { + DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + applicationReleaseDTO + .set(updateEntAppReleaseArtifact(deviceTypeObj.getName(), applicationReleaseDTO.get(), + applicationArtifact)); + } + applicationReleaseDTO.set(updateImageArtifacts(applicationReleaseDTO.get(), applicationArtifact, tenantId)); + boolean updateStatus = applicationReleaseDAO.updateRelease(applicationReleaseDTO.get(), tenantId) != null; + if (!updateStatus) { + ConnectionManagerUtil.rollbackDBTransaction(); + return null; + } + ConnectionManagerUtil.commitDBTransaction(); + return APIUtil.releaseDtoToRelease(applicationReleaseDTO.get()); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to update enterprise app release which " + + "has release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when updating enterprise app release which has release UUID: " + + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured when updating Ent Application release of UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ResourceManagementException e) { + String msg = "Error occured when updating application release artifact in the file system. Ent App release " + + "UUID:" + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public ApplicationRelease updatePubAppRelease(String releaseUuid, PublicAppReleaseWrapper publicAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); + validateAppReleaseUpdating(applicationDTO, ApplicationType.PUBLIC.toString()); + AtomicReference applicationReleaseDTO = new AtomicReference<>( + applicationDTO.getApplicationReleaseDTOs().get(0)); + + applicationReleaseDTO.get().setPrice(publicAppReleaseWrapper.getPrice()); + applicationReleaseDTO.get().setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); + + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getPackageName())) { + applicationReleaseDTO.get().setVersion(publicAppReleaseWrapper.getVersion()); + } + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getVersion())) { + applicationReleaseDTO.get().setVersion(publicAppReleaseWrapper.getVersion()); + } + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getSupportedOsVersions())) { + applicationReleaseDTO.get().setSupportedOsVersions(publicAppReleaseWrapper.getSupportedOsVersions()); + } + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getDescription())) { + applicationReleaseDTO.get().setDescription(publicAppReleaseWrapper.getDescription()); + } + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getReleaseType())) { + applicationReleaseDTO.get().setReleaseType(publicAppReleaseWrapper.getReleaseType()); + } + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getMetaData())) { + applicationReleaseDTO.get().setMetaData(publicAppReleaseWrapper.getMetaData()); + } + + applicationReleaseDTO.set(updateImageArtifacts(applicationReleaseDTO.get(), applicationArtifact, tenantId)); + + boolean updateStatus = applicationReleaseDAO.updateRelease(applicationReleaseDTO.get(), tenantId) != null; + if (!updateStatus) { + ConnectionManagerUtil.rollbackDBTransaction(); + return null; + } + ConnectionManagerUtil.commitDBTransaction(); + return APIUtil.releaseDtoToRelease(applicationReleaseDTO.get()); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to update public app release which " + + "has release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when updating public app release which has release UUID:." + + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured when updating public app release of UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ResourceManagementException e) { + String msg = "Error occured when updating public app release artifact in the file system. Public app " + + "release UUID:" + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public ApplicationRelease updateWebAppRelease(String releaseUuid, WebAppReleaseWrapper webAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); + validateAppReleaseUpdating(applicationDTO, ApplicationType.WEB_CLIP.toString()); + AtomicReference applicationReleaseDTO = new AtomicReference<>( + applicationDTO.getApplicationReleaseDTOs().get(0)); + + applicationReleaseDTO.get().setPrice(webAppReleaseWrapper.getPrice()); + applicationReleaseDTO.get().setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); + + if (!StringUtils.isEmpty(webAppReleaseWrapper.getVersion())) { + applicationReleaseDTO.get().setVersion(webAppReleaseWrapper.getVersion()); + } + if (!StringUtils.isEmpty(webAppReleaseWrapper.getVersion())) { + applicationReleaseDTO.get().setVersion(webAppReleaseWrapper.getVersion()); + } + if (!StringUtils.isEmpty(webAppReleaseWrapper.getDescription())) { + applicationReleaseDTO.get().setDescription(webAppReleaseWrapper.getDescription()); + } + if (!StringUtils.isEmpty(webAppReleaseWrapper.getReleaseType())) { + applicationReleaseDTO.get().setReleaseType(webAppReleaseWrapper.getReleaseType()); + } + if (!StringUtils.isEmpty(webAppReleaseWrapper.getMetaData())) { + applicationReleaseDTO.get().setMetaData(webAppReleaseWrapper.getMetaData()); + } + + applicationReleaseDTO.set(updateImageArtifacts(applicationReleaseDTO.get(), applicationArtifact, tenantId)); + boolean updateStatus = applicationReleaseDAO.updateRelease(applicationReleaseDTO.get(), tenantId) != null; + if (!updateStatus) { + ConnectionManagerUtil.rollbackDBTransaction(); + return null; + } + ConnectionManagerUtil.commitDBTransaction(); + return APIUtil.releaseDtoToRelease(applicationReleaseDTO.get()); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to update web app release which " + + "has release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when updating web app release which has release UUID:." + + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured when updating web app release for web app Release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ResourceManagementException e) { + String msg = "Error occured when updating web app release artifact in the file system. Web app " + + "release UUID:" + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public ApplicationRelease updateCustomAppRelease(String releaseUuid, + CustomAppReleaseWrapper customAppReleaseWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); + AtomicReference applicationReleaseDTO = new AtomicReference<>( + applicationDTO.getApplicationReleaseDTOs().get(0)); + validateAppReleaseUpdating(applicationDTO, ApplicationType.ENTERPRISE.toString()); + applicationReleaseDTO.get().setPrice(customAppReleaseWrapper.getPrice()); + applicationReleaseDTO.get() + .setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); + if (!StringUtils.isEmpty(customAppReleaseWrapper.getPackageName())) { + applicationReleaseDTO.get().setVersion(customAppReleaseWrapper.getVersion()); + } + if (!StringUtils.isEmpty(customAppReleaseWrapper.getVersion())) { + applicationReleaseDTO.get().setVersion(customAppReleaseWrapper.getVersion()); + } + if (!StringUtils.isEmpty(customAppReleaseWrapper.getDescription())) { + applicationReleaseDTO.get().setDescription(customAppReleaseWrapper.getDescription()); + } + if (!StringUtils.isEmpty(customAppReleaseWrapper.getReleaseType())) { + applicationReleaseDTO.get().setReleaseType(customAppReleaseWrapper.getReleaseType()); + } + if (!StringUtils.isEmpty(customAppReleaseWrapper.getMetaData())) { + applicationReleaseDTO.get().setMetaData(customAppReleaseWrapper.getMetaData()); + } + + if (!StringUtils.isEmpty(applicationArtifact.getInstallerName()) + && applicationArtifact.getInstallerStream() != null) { + DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + // The application executable artifacts such as deb are uploaded. + try { + byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); + try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) { + String md5OfApp = StorageManagementUtil.getMD5(binaryClone); + if (md5OfApp == null) { + String msg = "Error occurred while retrieving md5sum value from the binary file for " + + "application release UUID " + applicationReleaseDTO.get().getUuid(); + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } + if (!applicationReleaseDTO.get().getAppHashValue().equals(md5OfApp)) { + applicationReleaseDTO.get().setInstallerName(applicationArtifact.getInstallerName()); + try { + ConnectionManagerUtil.getDBConnection(); + if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) { + String msg = + "Same binary file is in the server. Hence you can't add same file into the " + + "server. Device Type: " + deviceTypeObj.getName() + + " and package name: " + applicationDTO.getApplicationReleaseDTOs() + .get(0).getPackageName(); + log.error(msg); + throw new BadRequestException(msg); + } + + String deletingAppHashValue = applicationReleaseDTO.get().getAppHashValue(); + applicationReleaseDTO.get().setAppHashValue(md5OfApp); + try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { + applicationStorageManager + .uploadReleaseArtifact(applicationReleaseDTO.get(), deviceTypeObj.getName(), + binaryDuplicate, tenantId); + applicationStorageManager.copyImageArtifactsAndDeleteInstaller(deletingAppHashValue, + applicationReleaseDTO.get(), tenantId); + } + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection for verifying application" + + " release existing for new app hash value."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = + "Error occurred when executing the query for verifying application release " + + "existence for the new app hash value."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + } + } catch (IOException e) { + String msg = "Error occurred when getting byte array of binary file. Installer name: " + + applicationArtifact.getInstallerName(); + log.error(msg, e); + throw new ApplicationStorageManagementException(msg, e); + } + } + applicationReleaseDTO.set(updateImageArtifacts(applicationReleaseDTO.get(), applicationArtifact, tenantId)); + boolean updateStatus = applicationReleaseDAO.updateRelease(applicationReleaseDTO.get(), tenantId) != null; + if (!updateStatus) { + ConnectionManagerUtil.rollbackDBTransaction(); + return null; + } + ConnectionManagerUtil.commitDBTransaction(); + return APIUtil.releaseDtoToRelease(applicationReleaseDTO.get()); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting the database connection to update enterprise app release which " + + "has release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Database access error is occurred when updating enterprise app release which has release " + + "UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured when updating Ent Application release of UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ResourceManagementException e) { + String msg = "Error occured when updating application release artifact in the file system. Ent App release " + + "UUID:" + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private void validateAppReleaseUpdating(ApplicationDTO applicationDTO, String appType) + throws ApplicationManagementException { + if (applicationDTO == null) { + String msg = "Couldn't found an application for requested UUID."; + log.error(msg); + throw new NotFoundException(msg); + } + if (!appType.equals(applicationDTO.getType())) { + String msg = "You trying to perform " + appType + " app release update on " + applicationDTO.getType() + + " app release."; + log.error(msg); + throw new ForbiddenException(msg); + } + + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + if (!lifecycleStateManager.isUpdatableState(applicationReleaseDTO.getCurrentState())) { + String msg = "Application release in " + applicationReleaseDTO.getCurrentState() + + " state. Therefore you are not allowed to update the application release. Hence, " + + "please move application release from " + applicationReleaseDTO.getCurrentState() + + " to updatable state."; + log.error(msg); + throw new ForbiddenException(msg); + } + + String applicationSubType = applicationDTO.getSubType(); + double price = applicationReleaseDTO.getPrice(); + if (price < 0.0 || (price == 0.0 && ApplicationSubscriptionType.PAID.toString().equals(applicationSubType)) || ( + price > 0.0 && ApplicationSubscriptionType.FREE.toString().equals(applicationSubType))) { + throw new BadRequestException("Invalid app release payload for updating application release. Application " + + "price is " + price + " for " + applicationSubType + " application."); + } + + if (!ApplicationType.WEB_CLIP.toString().equals(appType) && !ApplicationType.WEB_APP.toString() + .equals(appType)) { + DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + String supportedOSVersions = applicationReleaseDTO.getSupportedOsVersions(); + if (!StringUtils.isEmpty(supportedOSVersions) && isInvalidOsVersionRange(supportedOSVersions, + deviceTypeObj.getName())) { + String msg = "You are trying to update application release which has invalid or unsupported OS " + + "versions in the supportedOsVersions section. Hence, please re-evaluate the request payload."; + log.error(msg); + throw new BadRequestException(msg); + } + } + } + + @Override + public void validateAppCreatingRequest(T param) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + int deviceTypeId = -1; + String appName; + List appCategories; + List unrestrictedRoles; + + if (param instanceof ApplicationWrapper) { + ApplicationWrapper applicationWrapper = (ApplicationWrapper) param; + appName = applicationWrapper.getName(); + if (StringUtils.isEmpty(appName)) { + String msg = "Application name cannot be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + appCategories = applicationWrapper.getCategories(); + if (appCategories == null) { + String msg = "Application category can't be null."; + log.error(msg); + throw new BadRequestException(msg); + } + if (appCategories.isEmpty()) { + String msg = "Application category can't be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(applicationWrapper.getDeviceType())) { + String msg = "Device type can't be empty for the application."; + log.error(msg); + throw new BadRequestException(msg); + } + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationWrapper.getDeviceType()); + deviceTypeId = deviceType.getId(); + + List entAppReleaseWrappers; + entAppReleaseWrappers = applicationWrapper.getEntAppReleaseWrappers(); + + if (entAppReleaseWrappers == null || entAppReleaseWrappers.size() != 1) { + String msg = "Invalid application creating request. Application creating request must have single " + + "application release. Application name:" + applicationWrapper.getName() + "."; + log.error(msg); + throw new BadRequestException(msg); + } + unrestrictedRoles = applicationWrapper.getUnrestrictedRoles(); + } else if (param instanceof WebAppWrapper) { + WebAppWrapper webAppWrapper = (WebAppWrapper) param; + appName = webAppWrapper.getName(); + if (StringUtils.isEmpty(appName)) { + String msg = "Web Clip name cannot be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + appCategories = webAppWrapper.getCategories(); + if (appCategories == null) { + String msg = "Web Clip category can't be null."; + log.error(msg); + throw new BadRequestException(msg); + } + if (appCategories.isEmpty()) { + String msg = "Web clip category can't be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(webAppWrapper.getType()) || (!ApplicationType.WEB_CLIP.toString() + .equals(webAppWrapper.getType()) && !ApplicationType.WEB_APP.toString() + .equals(webAppWrapper.getType()))) { + String msg = "Web app wrapper contains invalid application type with the request. Hence please verify " + + "the request payload.."; + log.error(msg); + throw new BadRequestException(msg); + } + + List webAppReleaseWrappers; + webAppReleaseWrappers = webAppWrapper.getWebAppReleaseWrappers(); + + if (webAppReleaseWrappers == null || webAppReleaseWrappers.size() != 1) { + String msg = "Invalid web clip creating request. Web clip creating request must have single " + + "web clip release. Web clip name:" + webAppWrapper.getName() + "."; + log.error(msg); + throw new BadRequestException(msg); + } + unrestrictedRoles = webAppWrapper.getUnrestrictedRoles(); + } else if (param instanceof PublicAppWrapper) { + PublicAppWrapper publicAppWrapper = (PublicAppWrapper) param; + appName = publicAppWrapper.getName(); + if (StringUtils.isEmpty(appName)) { + String msg = "Application name cannot be empty for public app."; + log.error(msg); + throw new BadRequestException(msg); + } + appCategories = publicAppWrapper.getCategories(); + if (appCategories == null) { + String msg = "Application category can't be null."; + log.error(msg); + throw new BadRequestException(msg); + } + if (appCategories.isEmpty()) { + String msg = "Application category can't be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(publicAppWrapper.getDeviceType())) { + String msg = "Device type can't be empty for the public application."; + log.error(msg); + throw new BadRequestException(msg); + } + DeviceType deviceType = APIUtil.getDeviceTypeData(publicAppWrapper.getDeviceType()); + deviceTypeId = deviceType.getId(); + + List publicAppReleaseWrappers; + publicAppReleaseWrappers = publicAppWrapper.getPublicAppReleaseWrappers(); + + if (publicAppReleaseWrappers == null || publicAppReleaseWrappers.size() != 1) { + String msg = "Invalid public app creating request. Request must have single release. Application name:" + + publicAppWrapper.getName() + "."; + log.error(msg); + throw new BadRequestException(msg); + } + unrestrictedRoles = publicAppWrapper.getUnrestrictedRoles(); + } else if (param instanceof CustomAppWrapper) { + CustomAppWrapper customAppWrapper = (CustomAppWrapper) param; + appName = customAppWrapper.getName(); + if (StringUtils.isEmpty(appName)) { + String msg = "Application name cannot be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + appCategories = customAppWrapper.getCategories(); + if (appCategories == null) { + String msg = "Application category can't be null."; + log.error(msg); + throw new BadRequestException(msg); + } + if (appCategories.isEmpty()) { + String msg = "Application category can't be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(customAppWrapper.getDeviceType())) { + String msg = "Device type can't be empty for the application."; + log.error(msg); + throw new BadRequestException(msg); + } + DeviceType deviceType = APIUtil.getDeviceTypeData(customAppWrapper.getDeviceType()); + deviceTypeId = deviceType.getId(); + + List customAppReleaseWrappers; + customAppReleaseWrappers = customAppWrapper.getCustomAppReleaseWrappers(); + + if (customAppReleaseWrappers == null || customAppReleaseWrappers.size() != 1) { + String msg = "Invalid custom app creating request. Application creating request must have single " + + "application release. Application name:" + customAppWrapper.getName() + "."; + log.error(msg); + throw new BadRequestException(msg); + } + unrestrictedRoles = customAppWrapper.getUnrestrictedRoles(); + } else { + String msg = "Invalid payload found with the request. Hence verify the request payload object."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + + try { + ConnectionManagerUtil.openDBConnection(); + if (unrestrictedRoles != null && !unrestrictedRoles.isEmpty()) { + if (!isValidRestrictedRole(unrestrictedRoles)) { + String msg = "Unrestricted role list contain role/roles which are not in the user store."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + if (!hasUserRole(unrestrictedRoles, userName)) { + String msg = "You are trying to restrict the visibility of the application for a role set, but " + + "in order to perform the action at least one role should be assigned to user: " + + userName; + log.error(msg); + throw new BadRequestException(msg); + } + } + + Filter filter = new Filter(); + filter.setFullMatch(true); + filter.setAppName(appName); + filter.setOffset(0); + filter.setLimit(1); + List applicationList = applicationDAO.getApplications(filter, deviceTypeId, tenantId); + if (!applicationList.isEmpty()) { + String msg = + "Already an application registered with same name - " + applicationList.get(0).getName() + "."; + log.error(msg); + throw new BadRequestException(msg); + } + + List registeredCategories = this.applicationDAO.getAllCategories(tenantId); + + if (registeredCategories.isEmpty()) { + String msg = "Registered application category set is empty. Since it is mandatory to add application " + + "category when adding new application, registered application category list shouldn't be null."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + for (String cat : appCategories) { + boolean isValidCategory = false; + for (CategoryDTO obj : registeredCategories) { + if (cat.equals(obj.getCategoryName())) { + isValidCategory = true; + break; + } + } + if (!isValidCategory) { + String msg = "Application Creating request contains invalid categories. Hence please verify the " + + "application creating payload."; + log.error(msg); + throw new BadRequestException(msg); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = + "Error occurred while getting data which is related to web clip. web clip name: " + appName + "."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "Error occurred when validating the unrestricted roles given for the web clip"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void validateReleaseCreatingRequest(T param, String deviceType) throws ApplicationManagementException { + if (param == null) { + String msg = "In order to validate release creating request param shouldn't be null."; + log.error(msg); + throw new BadRequestException(msg); + } + + if (param instanceof EntAppReleaseWrapper) { + AtomicReference entAppReleaseWrapper = new AtomicReference<>( + (EntAppReleaseWrapper) param); + if (StringUtils.isEmpty(entAppReleaseWrapper.get().getSupportedOsVersions())) { + String msg = "Supported OS Version shouldn't be null or empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (isInvalidOsVersionRange(entAppReleaseWrapper.get().getSupportedOsVersions(), deviceType)) { + String msg = "You are trying to create application which has an application release contains invalid or " + + "unsupported OS versions in the supportedOsVersions section. Hence, please re-evaluate the " + + "request payload."; + log.error(msg); + throw new BadRequestException(msg); + } + } else if (param instanceof WebAppReleaseWrapper) { + WebAppReleaseWrapper webAppReleaseWrapper = (WebAppReleaseWrapper) param; + UrlValidator urlValidator = new UrlValidator(); + if (StringUtils.isEmpty(webAppReleaseWrapper.getVersion())) { + String msg = "Version shouldn't be empty or null for the WEB CLIP release creating request."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(webAppReleaseWrapper.getUrl())) { + String msg = "URL should't be null for the application release creating request for application type " + + "WEB_CLIP"; + log.error(msg); + throw new BadRequestException(msg); + } + if (!urlValidator.isValid(webAppReleaseWrapper.getUrl())) { + String msg = "Request payload contains an invalid Web Clip URL."; + log.error(msg); + throw new BadRequestException(msg); + } + } else if (param instanceof PublicAppReleaseWrapper) { + PublicAppReleaseWrapper publicAppReleaseWrapper = (PublicAppReleaseWrapper) param; + if (StringUtils.isEmpty(publicAppReleaseWrapper.getSupportedOsVersions())) { + String msg = "Supported OS Version shouldn't be null or empty for public app release creating request."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(publicAppReleaseWrapper.getVersion())) { + String msg = "Version shouldn't be empty or null for the Public App release creating request."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(publicAppReleaseWrapper.getPackageName())) { + String msg = "Package name shouldn't be empty or null for the Public App release creating request."; + log.error(msg); + throw new BadRequestException(msg); + } + if (isInvalidOsVersionRange(publicAppReleaseWrapper.getSupportedOsVersions(), deviceType)) { + String msg = "You are trying to create application which has an application release contains invalid or " + + "unsupported OS versions in the supportedOsVersions section. Hence, please re-evaluate the " + + "request payload."; + log.error(msg); + throw new BadRequestException(msg); + } + } else if (param instanceof CustomAppReleaseWrapper) { + CustomAppReleaseWrapper customAppReleaseWrapper = (CustomAppReleaseWrapper) param; + if (StringUtils.isEmpty(customAppReleaseWrapper.getVersion())) { + String msg = "Version shouldn't be empty or null for the custom App release creating request."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(customAppReleaseWrapper.getPackageName())) { + String msg = "Package name shouldn't be empty or null for the custom App release creating request."; + log.error(msg); + throw new BadRequestException(msg); + } + } else { + String msg = "Invalid payload found with the release creating request. Hence verify the release creating " + + "request payload object."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } + + @Override + public void validateImageArtifacts(Attachment iconFile, Attachment bannerFile, + List attachmentList) throws RequestValidatingException { + if (iconFile == null) { + String msg = "Icon file is not found with the application release creating request."; + log.error(msg); + throw new RequestValidatingException(msg); + } + if (attachmentList == null || attachmentList.isEmpty()) { + String msg = "Screenshots are not found with the application release creating request."; + log.error(msg); + throw new RequestValidatingException(msg); + } + } + + @Override + public void validateBinaryArtifact(Attachment binaryFile) throws RequestValidatingException { + if (binaryFile == null) { + String msg = "Binary file is not found with the application release creating request for ENTERPRISE app " + + "creating request."; + log.error(msg); + throw new RequestValidatingException(msg); + } + } + + @Override + public void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + try { + ConnectionManagerUtil.beginDBTransaction(); + List deviceSubIds = subscriptionDAO.getDeviceSubIdsForOperation(operationId, deviceId, tenantId); + if (deviceSubIds.isEmpty()){ + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Couldn't find device subscription for operation id " + operationId; + log.error(msg); + throw new ApplicationManagementException(msg); + } + if (!subscriptionDAO.updateDeviceSubStatus(deviceId, deviceSubIds, status, tenantId)){ + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Didn't update an any app subscription of device for operation Id: " + operationId; + log.error(msg); + throw new ApplicationManagementException(msg); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occured while updating app subscription status of the device."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while obersving the database connection to update aoo subscription status of " + + "device."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while executing database transaction"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public String getPlistArtifact(String releaseUuid) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't find application for the release UUID: " + releaseUuid; + log.error(msg); + throw new NotFoundException(msg); + } + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + String artifactDownloadURL = APIUtil.getArtifactDownloadBaseURL() + applicationReleaseDTO.getUuid() + + Constants.FORWARD_SLASH + Constants.APP_ARTIFACT + Constants.FORWARD_SLASH + + applicationReleaseDTO.getInstallerName(); + String plistContent = "<!DOCTYPE plist PUBLIC "-//Apple//DTDPLIST1.0//EN" "" + + "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="" + + "1.0"><dict><key>items</key><array><dict><" + + "key>assets</key><array><dict><key>kind</key><" + + "string>software-package</string><key>url</key><string>" + + "$downloadURL</string></dict></array><key>metadata<" + + "/key><dict><key>bundle-identifier</key><string>" + + "$packageName</string><key>bundle-version</key><string>" + + "$bundleVersion</string><key>kind</key><string>" + + "software</string><key>title</key><string>$appName<" + + "/string></dict></dict></array></dict></plist>"; + plistContent = plistContent.replace("$downloadURL", artifactDownloadURL) + .replace("$packageName", applicationReleaseDTO.getPackageName()) + .replace("$bundleVersion", applicationReleaseDTO.getVersion()) + .replace("$appName", applicationDTO.getName()); + return StringEscapeUtils.unescapeXml(plistContent); + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection for getting application for the release UUID: " + + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting application data for release UUID: " + releaseUuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getReleaseByPackageNames(List packageIds) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + return this.applicationReleaseDAO.getReleaseByPackages(packageIds, tenantId); + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the database connection for getting application for the " + + "packages"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting application data for packages"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java new file mode 100644 index 0000000000..69aa1711ac --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java @@ -0,0 +1,274 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.impl; + +import com.dd.plist.NSDictionary; +import net.dongliu.apk.parser.bean.ApkMeta; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstaller; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.DeviceTypes; +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.ApplicationStorageManager; +import org.wso2.carbon.device.application.mgt.core.exception.ParsingException; +import org.wso2.carbon.device.application.mgt.core.util.ArtifactsParser; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.application.mgt.core.util.StorageManagementUtil; + +import java.io.*; +import java.util.List; + +import static org.wso2.carbon.device.application.mgt.core.util.StorageManagementUtil.saveFile; + +/** + * This class contains the default concrete implementation of ApplicationStorage Management. + */ +public class ApplicationStorageManagerImpl implements ApplicationStorageManager { + private static final Log log = LogFactory.getLog(ApplicationStorageManagerImpl.class); + private String storagePath; + private int screenShotMaxCount; + + /** + * Create a new ApplicationStorageManager Instance + * + * @param storagePath Storage Path to save the binary and image files. + * @param screenShotMaxCount Maximum Screen-shots count + */ + public ApplicationStorageManagerImpl(String storagePath, String screenShotMaxCount) { + this.storagePath = storagePath; + this.screenShotMaxCount = Integer.parseInt(screenShotMaxCount); + } + + @Override + public ApplicationReleaseDTO uploadImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, + InputStream iconFileStream, InputStream bannerFileStream, List screenShotStreams, int tenantId) + throws ResourceManagementException { + String iconStoredLocation; + String bannerStoredLocation; + String scStoredLocation = null; + + try { + String artifactStoringBaseDirPath = + storagePath + tenantId + File.separator + applicationReleaseDTO.getAppHashValue(); + StorageManagementUtil.createArtifactDirectory(artifactStoringBaseDirPath); + + if (iconFileStream != null) { + String iconStoringDir = artifactStoringBaseDirPath + File.separator + Constants.ICON_ARTIFACT; + StorageManagementUtil.createArtifactDirectory(iconStoringDir); + iconStoredLocation = iconStoringDir + File.separator + applicationReleaseDTO.getIconName(); + saveFile(iconFileStream, iconStoredLocation); + } + if (bannerFileStream != null) { + String bannerStoringDir = artifactStoringBaseDirPath + File.separator + Constants.BANNER_ARTIFACT; + StorageManagementUtil.createArtifactDirectory(bannerStoringDir); + bannerStoredLocation = bannerStoringDir + File.separator + applicationReleaseDTO.getBannerName(); + saveFile(bannerFileStream, bannerStoredLocation); + } + if (!screenShotStreams.isEmpty()) { + if (screenShotStreams.size() > screenShotMaxCount) { + String msg = "Maximum limit for the screen-shot exceeds. You can't upload more than three " + + "screenshot for an application release"; + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } + int count = 1; + for (InputStream screenshotStream : screenShotStreams) { + String scStoringDir = artifactStoringBaseDirPath + File.separator + Constants.SCREENSHOT_ARTIFACT + count; + StorageManagementUtil.createArtifactDirectory(scStoringDir); + if (count == 1) { + scStoredLocation = scStoringDir + File.separator + applicationReleaseDTO.getScreenshotName1(); + } + if (count == 2) { + scStoredLocation = scStoringDir + File.separator + applicationReleaseDTO.getScreenshotName2(); + } + if (count == 3) { + scStoredLocation = scStoringDir + File.separator + applicationReleaseDTO.getScreenshotName3(); + } + saveFile(screenshotStream, scStoredLocation); + count++; + } + } + return applicationReleaseDTO; + } catch (IOException e) { + String msg = "IO Exception occurred while saving application artifacts for the application which has UUID " + + applicationReleaseDTO.getUuid(); + log.error(msg, e); + throw new ApplicationStorageManagementException(msg, e); + } + } + + @Override + public ApplicationInstaller getAppInstallerData(InputStream binaryFile, String deviceType) + throws ApplicationStorageManagementException { + ApplicationInstaller applicationInstaller = new ApplicationInstaller(); + try { + if (DeviceTypes.ANDROID.toString().equalsIgnoreCase(deviceType)) { + ApkMeta apkMeta = ArtifactsParser.readAndroidManifestFile(binaryFile); + applicationInstaller.setVersion(apkMeta.getVersionName()); + applicationInstaller.setPackageName(apkMeta.getPackageName()); + } else if (DeviceTypes.IOS.toString().equalsIgnoreCase(deviceType)) { + NSDictionary plistInfo = ArtifactsParser.readiOSManifestFile(binaryFile); + applicationInstaller + .setVersion(plistInfo.objectForKey(ArtifactsParser.IPA_BUNDLE_VERSION_KEY).toString()); + applicationInstaller + .setPackageName(plistInfo.objectForKey(ArtifactsParser.IPA_BUNDLE_IDENTIFIER_KEY).toString()); + } else { + String msg = "Application Type doesn't match with supporting application types " + deviceType; + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } + } catch (ParsingException e){ + String msg = "Application Type doesn't match with supporting application types " + deviceType; + log.error(msg, e); + throw new ApplicationStorageManagementException(msg, e); + } + return applicationInstaller; + } + + @Override + public void uploadReleaseArtifact(ApplicationReleaseDTO applicationReleaseDTO, + String deviceType, InputStream binaryFile, int tenantId) throws ResourceManagementException { + try { + byte [] content = IOUtils.toByteArray(binaryFile); + String artifactDirectoryPath = + storagePath + tenantId + File.separator + applicationReleaseDTO.getAppHashValue() + File.separator + + Constants.APP_ARTIFACT; + StorageManagementUtil.createArtifactDirectory(artifactDirectoryPath); + String artifactPath = artifactDirectoryPath + File.separator + applicationReleaseDTO.getInstallerName(); + saveFile(new ByteArrayInputStream(content), artifactPath); + } catch (IOException e) { + String msg = "IO Exception while saving the release artifacts in the server for the application UUID " + + applicationReleaseDTO.getUuid(); + log.error(msg, e); + throw new ResourceManagementException( msg, e); + } + } + + @Override + public void copyImageArtifactsAndDeleteInstaller(String deletingAppHashValue, + ApplicationReleaseDTO applicationReleaseDTO, int tenantId) throws ApplicationStorageManagementException { + + try { + String appHashValue = applicationReleaseDTO.getAppHashValue(); + String bannerName = applicationReleaseDTO.getBannerName(); + String iconName = applicationReleaseDTO.getIconName(); + String screenshot1 = applicationReleaseDTO.getScreenshotName1(); + String screenshot2 = applicationReleaseDTO.getScreenshotName2(); + String screenshot3 = applicationReleaseDTO.getScreenshotName3(); + String basePath = storagePath + tenantId + File.separator; + + if (bannerName != null) { + StorageManagementUtil.copy(basePath + deletingAppHashValue + File.separator + Constants.BANNER_ARTIFACT + + File.separator + bannerName, + basePath + appHashValue + File.separator + Constants.BANNER_ARTIFACT + File.separator + + bannerName); + } + if (iconName != null) { + StorageManagementUtil.copy(basePath + deletingAppHashValue + File.separator + Constants.ICON_ARTIFACT + + File.separator + iconName, + basePath + appHashValue + File.separator + Constants.ICON_ARTIFACT + File.separator + iconName); + } + if (screenshot1 != null) { + StorageManagementUtil + .copy(basePath + deletingAppHashValue + File.separator + Constants.SCREENSHOT_ARTIFACT + 1 + + File.separator + screenshot1, + basePath + appHashValue + File.separator + Constants.SCREENSHOT_ARTIFACT + 1 + + File.separator + screenshot1); + } + if (screenshot2 != null) { + StorageManagementUtil + .copy(basePath + deletingAppHashValue + File.separator + Constants.SCREENSHOT_ARTIFACT + 2 + + File.separator + screenshot2, + basePath + appHashValue + File.separator + Constants.SCREENSHOT_ARTIFACT + 2 + + File.separator + screenshot2); + } + if (screenshot3 != null) { + StorageManagementUtil + .copy(basePath + deletingAppHashValue + File.separator + Constants.SCREENSHOT_ARTIFACT + 3 + + File.separator + screenshot3, + basePath + appHashValue + File.separator + Constants.SCREENSHOT_ARTIFACT + 3 + + File.separator + screenshot3); + } + deleteAppReleaseArtifact( basePath + deletingAppHashValue); + } catch (IOException e) { + String msg = "Application installer updating is failed because of I/O issue"; + log.error(msg, e); + throw new ApplicationStorageManagementException(msg, e); + } + } + + + + @Override + public void deleteAppReleaseArtifact(String appReleaseHashVal, String folderName, String fileName, int tenantId) + throws ApplicationStorageManagementException { + String artifactPath = storagePath + tenantId + File.separator + appReleaseHashVal + File.separator + folderName + + File.separator + fileName; + deleteAppReleaseArtifact(artifactPath); + } + + @Override + public void deleteAllApplicationReleaseArtifacts(List directoryPaths, int tenantId) + throws ApplicationStorageManagementException { + String basePath = storagePath + tenantId + File.separator; + for (String directoryPath : directoryPaths) { + deleteAppReleaseArtifact(basePath + directoryPath); + } + } + + @Override + public InputStream getFileStream(String hashVal, String folderName, String fileName, int tenantId) + throws ApplicationStorageManagementException { + String filePath = + storagePath + tenantId + File.separator + hashVal + File.separator + folderName + File.separator + + fileName; + try { + return StorageManagementUtil.getInputStream(filePath); + } catch (IOException e) { + String msg = "Error occured when accessing the file in file path: " + filePath; + log.error(msg, e); + throw new ApplicationStorageManagementException(msg, e); + } + } + + /*** + * This method is responsible to delete artifact file which is located in the artifact path. + * + * @param artifactPath relative path of the artifact file + * @throws ApplicationStorageManagementException when the file couldn't find in the given artifact path or if an + * IO error occured while deleting the artifact. + */ + private void deleteAppReleaseArtifact(String artifactPath) throws ApplicationStorageManagementException { + File artifact = new File(artifactPath); + if (artifact.exists()) { + try { + StorageManagementUtil.delete(artifact); + } catch (IOException e) { + throw new ApplicationStorageManagementException( + "Error occured while deleting application release artifacts", e); + } + } else { + String msg = "Tried to delete application release, but it doesn't exist in the file system"; + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/AppmDataHandlerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/AppmDataHandlerImpl.java new file mode 100644 index 0000000000..95b747a3f4 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/AppmDataHandlerImpl.java @@ -0,0 +1,97 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; +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.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; +import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; +import org.wso2.carbon.device.application.mgt.common.config.UIConfiguration; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; +import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; + +import java.io.InputStream; +import java.util.Map; + +public class AppmDataHandlerImpl implements AppmDataHandler { + + private static final Log log = LogFactory.getLog(AppmDataHandlerImpl.class); + private UIConfiguration uiConfiguration; + private LifecycleStateManager lifecycleStateManager; + + public AppmDataHandlerImpl(UIConfiguration config) { + this.uiConfiguration = config; + lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); + } + + @Override + public UIConfiguration getUIConfiguration() { + return this.uiConfiguration; + } + + @Override + public Map getLifecycleConfiguration() throws LifecycleManagementException { + return lifecycleStateManager.getLifecycleConfig(); + } + + @Override public InputStream getArtifactStream(int tenantId, String uuid, String folderName, String artifactName) + throws ApplicationManagementException { + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + ApplicationReleaseDAO applicationReleaseDAO = ApplicationManagementDAOFactory.getApplicationReleaseDAO(); + String appReleaseHashValue; + try { + ConnectionManagerUtil.openDBConnection(); + appReleaseHashValue = applicationReleaseDAO.getReleaseHashValue(uuid, tenantId); + if (appReleaseHashValue == null) { + String msg = "Could't find application release for UUID: " + uuid + ". Hence try with valid UUID."; + log.error(msg); + throw new NotFoundException(msg); + } + InputStream inputStream = applicationStorageManager + .getFileStream(appReleaseHashValue, folderName, artifactName, tenantId); + if (inputStream == null) { + String msg = "Couldn't file the file in the file system."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + return inputStream; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when retrieving application release hash value for given application release " + + "UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationStorageManagementException e) { + String msg = "Error occurred when getting input stream of the " + artifactName + " file."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java new file mode 100644 index 0000000000..92e281fd6b --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java @@ -0,0 +1,811 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.Rating; +import org.wso2.carbon.device.application.mgt.common.ReviewNode; +import org.wso2.carbon.device.application.mgt.common.PaginationRequest; +import org.wso2.carbon.device.application.mgt.common.PaginationResult; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException; +import org.wso2.carbon.device.application.mgt.common.response.Review; +import org.wso2.carbon.device.application.mgt.common.services.*; +import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; +import org.wso2.carbon.device.application.mgt.core.dao.ReviewDAO; +import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.exception.ReviewManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; +import org.wso2.carbon.device.application.mgt.core.util.Constants; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.TreeMap; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * This class is the default implementation for the Managing the reviews. + */ +public class ReviewManagerImpl implements ReviewManager { + + private static final Log log = LogFactory.getLog(ReviewManagerImpl.class); + private ReviewDAO reviewDAO; + private ApplicationReleaseDAO applicationReleaseDAO; + private ApplicationDAO applicationDAO; + + public ReviewManagerImpl() { + initDataAccessObjects(); + } + + private void initDataAccessObjects() { + this.reviewDAO = ApplicationManagementDAOFactory.getCommentDAO(); + this.applicationReleaseDAO = ApplicationManagementDAOFactory.getApplicationReleaseDAO(); + this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); + } + + @Override + public Review addReview(ReviewWrapper reviewWrapper, String uuid, boolean allowMultipleReviews) + throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + + if (reviewWrapper == null) { + String msg = "Request payload is null. Please verify the request payload."; + log.error(msg); + throw new BadRequestException(msg); + } + if (reviewWrapper.getRating() <= 0) { + String msg = "You are trying to add invalid rating value as rating. Therefore please verify the request " + + "payload."; + log.error(msg); + throw new BadRequestException(msg); + } + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationDTO applicationDTO = this.applicationDAO.getApplication(uuid, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't find an application which has the application release of UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + List applicationReleaseIds = new ArrayList<>(); + int associatedAppReleaseId = -1; + String associatedVersion = null; + String associatedReleaseUuid = null; + for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) { + if (applicationReleaseDTO.getUuid().equals(uuid)) { + associatedAppReleaseId = applicationReleaseDTO.getId(); + associatedVersion = applicationReleaseDTO.getVersion(); + associatedReleaseUuid = applicationReleaseDTO.getUuid(); + } + Integer id = applicationReleaseDTO.getId(); + applicationReleaseIds.add(id); + } + if (!allowMultipleReviews && this.reviewDAO.hasUerReviewedApp(applicationReleaseIds, username, tenantId)) { + String msg = + "User " + username + " has already reviewed the application of app release which has UUID: " + + uuid + ". Hence you can't add another review for same application. But if you have " + + "added review for same app release you can update the review that you have already " + + "added for ths application."; + log.error(msg); + throw new ForbiddenException(msg); + } + + ReviewDTO reviewDTO = reviewWrapperToDTO(reviewWrapper); + reviewDTO.setUsername(username); + reviewDTO.setRootParentId(-1); + reviewDTO.setImmediateParentId(-1); + reviewDTO.setReleaseVersion(associatedVersion); + reviewDTO.setReleaseUuid(associatedReleaseUuid); + + int reviewId = this.reviewDAO.addReview(reviewDTO, associatedAppReleaseId, tenantId); + reviewDTO.setId(reviewId); + if (reviewId != -1) { + ConnectionManagerUtil.commitDBTransaction(); + Runnable task = () -> calculateRating(reviewWrapper.getRating(), -12345, uuid, tenantId); + new Thread(task).start(); + return reviewDTOToReview(reviewDTO); + } + ConnectionManagerUtil.rollbackDBTransaction(); + return null; + } catch (DBConnectionException e) { + String msg = "DB Connection error occurs when adding Review for application release with UUID: " + uuid + + " is failed"; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "DB transaction error occurred when adding review for application release which has " + + "application UUID: " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting application release data for application release UUID:." + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ReviewManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when getting review data or adding review data for application release which " + + "has UUID: " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + //todo return object + public boolean addReplyComment(ReviewWrapper reviewWrapper, String uuid, int parentReviewId) + throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + + if (reviewWrapper == null) { + String msg = "Request payload is null. Please verify the request payload."; + log.error(msg); + throw new BadRequestException(msg); + } + + ReviewDTO parentReview = getReview(parentReviewId, tenantId); + if (parentReview == null) { + String msg = "Couldn't find an review which has review ID: " + parentReviewId + + " for application release which has UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + if (!parentReview.getReleaseUuid().equals(uuid)) { + String msg = + "Bad Request. You are trying to add reply comment for application release which has UUID: " + uuid + + "," + " but parent review is associated with application release which has UUID: " + + parentReview.getReleaseUuid() + ". Hence can't proceed this request further."; + log.error(msg); + throw new BadRequestException(msg); + } + + ReviewDTO replyComment = reviewWrapperToDTO(reviewWrapper); + replyComment.setUsername(username); + replyComment.setRating(0); + replyComment.setImmediateParentId(parentReview.getId()); + if (parentReview.getRootParentId() == -1) { + replyComment.setRootParentId(parentReview.getId()); + } else { + replyComment.setRootParentId(parentReview.getRootParentId()); + } + + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (this.reviewDAO.addReview(replyComment, applicationReleaseDTO.getId(), tenantId) != -1) { + ConnectionManagerUtil.commitDBTransaction(); + return true; + } + ConnectionManagerUtil.rollbackDBTransaction(); + return false; + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while adding reply comment for app review of application release" + + " which has UUID: " + uuid + " and review Id " + parentReviewId; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "DB transaction error occurred when adding reply comment for comment which has comment id: " + + parentReviewId; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured while verifying whether application release is exists or not for UUID " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private ReviewDTO reviewWrapperToDTO(ReviewWrapper reviewWrapper) { + ReviewDTO reviewDTO = new ReviewDTO(); + reviewDTO.setContent(reviewWrapper.getContent()); + reviewDTO.setRating(reviewWrapper.getRating()); + return reviewDTO; + } + + private List reviewDTOToReview(List reviewDTOs) { + List reviews = new ArrayList<>(); + + for (ReviewDTO reviewDTO : reviewDTOs) { + reviews.add(reviewDTOToReview(reviewDTO)); + } + return reviews; + } + + private Review reviewDTOToReview(ReviewDTO reviewDTO) { + Review review = new Review(); + review.setId(reviewDTO.getId()); + review.setContent(reviewDTO.getContent()); + review.setReleaseUuid(reviewDTO.getReleaseUuid()); + review.setReleaseVersion(reviewDTO.getReleaseVersion()); + review.setCreatedAt(reviewDTO.getCreatedAt()); + review.setModifiedAt(reviewDTO.getModifiedAt()); + review.setRating(reviewDTO.getRating()); + review.setUsername(reviewDTO.getUsername()); + review.setReplies(new ArrayList<>()); + return review; + } + + private ReviewDTO getReview(int reviewId, int tenantId) throws ReviewManagementException { + try { + ConnectionManagerUtil.openDBConnection(); + return this.reviewDAO.getReview(reviewId, tenantId); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurs updating reviewTmp with reviewTmp id " + reviewId + "."; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public Review updateReview(ReviewWrapper updatingReview, int reviewId, String uuid, + boolean isPrivilegedUser) throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + ReviewDTO reviewDTO = getReview(reviewId, tenantId); + if (reviewDTO == null) { + String msg = "Couldn't found a review for review ID: " + reviewId; + log.error(msg); + throw new NotFoundException(msg); + } + if (!isPrivilegedUser && !username.equals(reviewDTO.getUsername())) { + String msg = "You are trying to update a review which is created by " + reviewDTO.getUsername() + + ". Hence you are not permitted to update the review."; + log.error(msg); + throw new ForbiddenException(msg); + } + + boolean isActiveReview = true; + //Handle Review + if (reviewDTO.getRootParentId() == -1 && reviewDTO.getImmediateParentId() == -1) { + if (!reviewDTO.getReleaseUuid().equals(uuid)) { + isActiveReview = false; + } else { + if (updatingReview.getRating() > 0 && updatingReview.getRating() != reviewDTO.getRating()) { + Runnable task = () -> ReviewManagerImpl.this + .calculateRating(updatingReview.getRating(), reviewDTO.getRating(), uuid, tenantId); + new Thread(task).start(); + reviewDTO.setRating(updatingReview.getRating()); + } + if (!reviewDTO.getContent().equals(updatingReview.getContent())) { + reviewDTO.setContent(updatingReview.getContent()); + } + } + } else { + if (!reviewDTO.getReleaseUuid().equals(uuid)) { + String msg = "You are trying to update reply comment, but associated application release UUID and " + + "requested app release UUID are mismatched."; + throw new BadRequestException(msg); + } + reviewDTO.setContent(updatingReview.getContent()); + } + + ReviewDTO updatedReviewDTO = updateReviewInDB(reviewDTO, reviewId, isActiveReview, tenantId); + if (updatedReviewDTO != null) { + if (!isActiveReview) { + Review newReview = addReview(updatingReview, uuid, true); + if (newReview != null) { + return newReview; + } else { + ReviewDTO restoringReviewDTO = updateReviewInDB(reviewDTO, reviewId, true, tenantId); + if (restoringReviewDTO != null) { + String msg = "Review Updating Status: Adding new Review for application release which has" + + " UUID: " + uuid + " is failed and the old review is restored."; + log.error(msg); + throw new ApplicationManagementException(msg); + } else { + String msg = "Review Updating Status: Adding new Review for application release which has " + + "UUID: " + uuid + " is failed and the old review restoring is also failed."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } + } + return reviewDTOToReview(updatedReviewDTO); + } else { + String msg = "Review Updating is failed. Hence please contact the administrator."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } + + private ReviewDTO updateReviewInDB(ReviewDTO reviewDTO, int reviewId, boolean isActiveReview, int tenantId) + throws ReviewManagementException, ApplicationManagementException { + try { + ConnectionManagerUtil.beginDBTransaction(); + ReviewDTO updatedReviewDTO = this.reviewDAO.updateReview(reviewDTO, reviewId, isActiveReview, tenantId); + if (updatedReviewDTO != null) { + ConnectionManagerUtil.commitDBTransaction(); + return updatedReviewDTO; + } + ConnectionManagerUtil.rollbackDBTransaction(); + return null; + } catch (ReviewManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured while getting reviewTmp with reviewTmp id " + reviewId + "."; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurs updating reviewTmp with reviewTmp id " + reviewId + "."; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "DB transaction error occurred when updating comment which has comment id: " + reviewId; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public PaginationResult getAllReleaseReviews(PaginationRequest request, String uuid) + throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (log.isDebugEnabled()) { + log.debug("Get all release reviews of the application release uuid: " + uuid); + } + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationReleaseDTO releaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (releaseDTO == null) { + String msg = "Couldn't found an application release for UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + return getReviewTree(this.reviewDAO.getAllReleaseReviews(releaseDTO.getId(), request, tenantId)); + } catch (ReviewManagementDAOException e) { + String msg = "Error occured while getting all reviews for application uuid: " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (DBConnectionException e) { + String msg ="Error occured while getting the DB connection to get all reviews for application release which" + + " has UUID " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = + "Error occurred while getting application release details for application release UUId " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public PaginationResult getAllAppReviews(PaginationRequest request, String uuid) + throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (log.isDebugEnabled()) { + log.debug("Get all reviews of the application release uuid: " + uuid); + } + List applicationReleaseIds = getAppReleaseIdsByUUID(uuid, tenantId); + try { + ConnectionManagerUtil.openDBConnection(); + return getReviewTree(this.reviewDAO.getAllActiveAppReviews(applicationReleaseIds, request, tenantId)); + } catch (ReviewManagementDAOException e) { + String msg = "Error occured while getting all reviews for application which has an " + + "application release of uuid: " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occured while getting the DB connection to get app app reviews."; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public PaginationResult getAllAppReviewsOfUser(PaginationRequest request, String uuid) + throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (log.isDebugEnabled()) { + log.debug("Get all reviews of the application release uuid: " + uuid); + } + List applicationReleaseIds = getAppReleaseIdsByUUID(uuid, tenantId); + try { + ConnectionManagerUtil.openDBConnection(); + List reviewDtos = this.reviewDAO + .getAllActiveAppReviewsOfUser(applicationReleaseIds, request, username, tenantId); + if (!reviewDtos.isEmpty() && reviewDtos.size() > 1) { + String msg = + "User " + username + " can't have more than active application review for application which" + + " has application release of UUID: " + uuid; + log.error(msg); + throw new ApplicationManagementException(msg); + } + return getReviewTree(reviewDtos); + } catch (ReviewManagementDAOException e) { + String msg = "Error occured while getting all " + username + "'s reviews for application which has an " + + "application release of uuid: " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occured while getting DB connection to get all " + username + "'s reviews for " + + "application which has an application release of uuid: " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private List getAppReleaseIdsByUUID(String uuid, int tenantId) + throws ReviewManagementException, ApplicationManagementException { + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO.getApplication(uuid, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't find an application which has the application release of UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + return applicationDTO.getApplicationReleaseDTOs().stream().map(ApplicationReleaseDTO::getId) + .collect(Collectors.toList()); + } catch (DBConnectionException e) { + String msg = + "Error occured while getting the DB connection to get application which has application release" + + " of UUID: " + uuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting application release details for application which has an " + + "application release of UUID " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private PaginationResult getReviewTree(List reviewDTOs) throws ReviewManagementException { + TreeMap> reviewTree = new TreeMap<>(); + PaginationResult paginationResult = new PaginationResult(); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + for (ReviewDTO reviewDTO : reviewDTOs) { + ReviewNode rootNode = new ReviewNode<>(reviewDTO); + reviewTree.put(reviewDTO.getId(), rootNode); + List replyComments = this.reviewDAO.getReplyComments(reviewDTO.getId(), tenantId); + replyComments.sort(Comparator.comparing(ReviewDTO::getId)); + for (ReviewDTO reply : replyComments) { + reviewTree.put(reply.getRootParentId(), + findAndSetChild(reviewTree.get(reply.getRootParentId()), reply)); + } + } + int numOfReviews = reviewTree.size(); + List results = new ArrayList<>(); + + for (ReviewNode reviewNode : reviewTree.values()) { + results.add(constructReviewResponse(null, reviewNode)); + } + paginationResult.setData(new ArrayList<>(results)); + paginationResult.setRecordsFiltered(numOfReviews); + paginationResult.setRecordsTotal(numOfReviews); + return paginationResult; + } catch (ReviewManagementDAOException e) { + String msg = "Error occured while getting all reply comments for given review list"; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } + } + + private ReviewNode findAndSetChild(ReviewNode node, ReviewDTO reviewDTO) { + if (node.getData().getId() == reviewDTO.getImmediateParentId()) { + ReviewNode childNode = new ReviewNode<>(reviewDTO); + node.addChild(childNode); + return node; + } + for (ReviewNode each : node.getChildren()) { + findAndSetChild(each, reviewDTO); + } + return node; + } + + private Review constructReviewResponse(Review parentReview, ReviewNode node) { + Review review = reviewDTOToReview(node.getData()); + if (parentReview != null) { + parentReview.getReplies().add(review); + } + if (node.getChildren().isEmpty()) { + return review; + } + for (ReviewNode reviewDTOReviewNode : node.getChildren()) { + constructReviewResponse(review, reviewDTOReviewNode); + } + return review; + } + + private ReviewNode getReviewNode(ReviewNode node, int reviewId) { + if (node.getData().getId() == reviewId) { + return node; + } else { + for (ReviewNode each : node.getChildren()) { + ReviewNode result = getReviewNode(each, reviewId); + if (result != null) { + return result; + } + } + } + return null; + } + + private List getDeletingReviewIds(ReviewNode node, List reviewIds) { + reviewIds.add(node.getData().getId()); + if (node.getChildren().isEmpty()) { + return reviewIds; + } + for (ReviewNode each : node.getChildren()) { + getDeletingReviewIds(each, reviewIds); + } + return reviewIds; + } + + @Override public void deleteReview(String uuid, int reviewId, boolean isPriviledgedUser) + throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + try { + ConnectionManagerUtil.beginDBTransaction(); + ReviewDTO existingReview = this.reviewDAO.getReview(reviewId, tenantId); + if (existingReview == null) { + String msg = "Cannot delete a non-existing review for the application with review id" + reviewId; + log.error(msg); + throw new NotFoundException(msg); + } + if (!existingReview.getReleaseUuid().equals(uuid)) { + String msg = "You are trying to delete a review which is not associated with application release which " + + "has UUID: " + uuid; + log.error(msg); + throw new ForbiddenException(msg); + } + if (!isPriviledgedUser && !username.equals(existingReview.getUsername())) { + String msg = "You are trying to delete a comment that is owned by you. Hence you are not permitted to " + + "delete the review"; + log.error(msg); + throw new ForbiddenException(msg); + } + if (existingReview.getRootParentId() == Constants.REVIEW_PARENT_ID + && existingReview.getImmediateParentId() == Constants.REVIEW_PARENT_ID) { + this.reviewDAO.deleteAllChildCommentsOfReview(existingReview.getId(), tenantId); + this.reviewDAO.deleteReview(existingReview.getId(), tenantId); + ConnectionManagerUtil.commitDBTransaction(); + Runnable task = () -> calculateRating(0, existingReview.getRating(), uuid, tenantId); + new Thread(task).start(); + } else { + ReviewDTO rootReview = this.reviewDAO.getReview(existingReview.getRootParentId(), tenantId); + List replyComments = this.reviewDAO.getReplyComments(rootReview.getId(), tenantId); + + ReviewNode reviewNode = new ReviewNode<>(rootReview); + replyComments.sort(Comparator.comparing(ReviewDTO::getId)); + for (ReviewDTO reply : replyComments) { + reviewNode = findAndSetChild(reviewNode, reply); + } + + ReviewNode deletingRevieNode = getReviewNode(reviewNode, existingReview.getId()); + List deletingReviewIds = getDeletingReviewIds(deletingRevieNode, new ArrayList<>()); + this.reviewDAO.deleteReviews(deletingReviewIds, tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } + } catch (DBConnectionException e) { + String msg = "DB Connection error occurs deleting review with review id " + reviewId + "."; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ReviewManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured while deleting review with review id " + reviewId + "."; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred when handleing transaction to delete application reviews."; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override public Rating getAppReleaseRating(String appReleaseUuid) + throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + Rating rating = this.applicationReleaseDAO.getReleaseRating(appReleaseUuid, tenantId); + if (rating == null) { + throw new NotFoundException("Couldn't find rating for application release UUID: " + appReleaseUuid + + ". Please check the existence of the application release"); + } + + List ratingValues = this.reviewDAO.getAllAppReleaseRatingValues(appReleaseUuid, tenantId); + rating.setRatingVariety(constructRatingVariety(ratingValues)); + return rating; + } catch (ApplicationManagementDAOException e) { + String msg = + "Error occured while getting the rating value of the application release uuid: " + appReleaseUuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occured while getting the rating value of the application release uuid: " + + appReleaseUuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ReviewManagementDAOException e) { + String msg = "Error occured while getting all rating values for the application release UUID: " + + appReleaseUuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override public Rating getAppRating(String appReleaseUuid) + throws ReviewManagementException, ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO.getApplication(appReleaseUuid, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't found an application for application release UUID: " + appReleaseUuid; + log.error(msg); + throw new NotFoundException(msg); + } + + List uuids = applicationDTO.getApplicationReleaseDTOs().stream().map(ApplicationReleaseDTO::getUuid) + .collect(Collectors.toList()); + List ratingValues = this.reviewDAO.getAllAppRatingValues(uuids, tenantId); + + Rating rating = new Rating(); + rating.setRatingValue(applicationDTO.getAppRating()); + rating.setNoOfUsers(ratingValues.size()); + rating.setRatingVariety(constructRatingVariety(ratingValues)); + return rating; + } catch (DBConnectionException e) { + String msg = + "DB Connection error occured while getting app rating of the application which has application " + + "release for uuid: " + appReleaseUuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occured while getting the application DTO for the application release uuid: " + + appReleaseUuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } catch (ReviewManagementDAOException e) { + String msg = + "Error occured while getting all rating values of application which has the application release " + + "for UUID: " + appReleaseUuid; + log.error(msg, e); + throw new ReviewManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private TreeMap constructRatingVariety(List ratingValues) { + TreeMap ratingVariety = new TreeMap<>(); + ratingValues.forEach(ratingVal -> { + if (ratingVariety.containsKey(ratingVal)) { + ratingVariety.replace(ratingVal, ratingVariety.get(ratingVal) + 1); + } else { + ratingVariety.put(ratingVal, 1); + } + }); + IntStream.rangeClosed(1, Constants.MAX_RATING).filter(i -> !ratingVariety.containsKey(i)) + .forEach(i -> ratingVariety.put(i, 0)); + return ratingVariety; + } + + private void calculateRating(int newRatingVal, int oldRatingVal, String uuid, int tenantId) { + try { + ConnectionManagerUtil.beginDBTransaction(); + Rating rating = this.applicationReleaseDAO.getReleaseRating(uuid, tenantId); + if (rating == null) { + log.error("Couldn't find rating for application release uuid: " + uuid); + } else { + double updatedRating; + double newTotalRating; + int numOfUsers = rating.getNoOfUsers(); + double currentRating = rating.getRatingValue() * numOfUsers; + + if (oldRatingVal == -12345) { + newTotalRating = currentRating + newRatingVal; + numOfUsers++; + } else if (newRatingVal == 0) { + newTotalRating = currentRating - oldRatingVal; + numOfUsers--; + } else { + double tmpVal; + tmpVal = currentRating - oldRatingVal; + newTotalRating = tmpVal + newRatingVal; + } + + if (numOfUsers == 0) { + updatedRating = 0; + } else { + updatedRating = newTotalRating / numOfUsers; + } + + this.applicationReleaseDAO.updateRatingValue(uuid, updatedRating, numOfUsers); + updateAppRating(uuid, tenantId); + ConnectionManagerUtil.commitDBTransaction(); + } + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + log.error("Error occured while getting the rating value of the application release UUID: " + uuid, e); + } catch (DBConnectionException e) { + log.error("DB Connection error occured while updated the rating value of the application release UUID: " + + uuid + " can not get.", e); + } catch (TransactionManagementException e) { + log.error( + "Transaction error occured while updated the rating value of the application release UUID: " + uuid + + " can not get.", e); + } catch (ApplicationManagementException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + log.error("Error occured while updating app rating value which has application release for UUID: " + uuid, + e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private void updateAppRating(String uuid, int tenantId) throws ApplicationManagementException { + try { + ApplicationDTO applicationDTO = this.applicationDAO.getApplication(uuid, tenantId); + List uuids = applicationDTO.getApplicationReleaseDTOs().stream().map(ApplicationReleaseDTO::getUuid) + .collect(Collectors.toList()); + List appRatings = this.reviewDAO.getAllAppRatingValues(uuids, tenantId); + double appAverageRatingValue = appRatings.stream().mapToDouble(x -> x).average().orElse(0.0); + this.applicationDAO.updateApplicationRating(uuid, appAverageRatingValue, tenantId); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting application data or updating application rating value."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ReviewManagementDAOException e) { + String msg = "Error occurred when getting application rating values"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java new file mode 100644 index 0000000000..51409bef70 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -0,0 +1,1254 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.impl; + +import com.google.gson.Gson; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; +import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse; +import org.wso2.carbon.device.application.mgt.common.ApplicationType; +import org.wso2.carbon.device.application.mgt.common.DeviceSubscriptionData; +import org.wso2.carbon.device.application.mgt.common.DeviceTypes; +import org.wso2.carbon.device.application.mgt.common.ExecutionStatus; +import org.wso2.carbon.device.application.mgt.common.SubAction; +import org.wso2.carbon.device.application.mgt.common.SubscriptionType; +import org.wso2.carbon.device.application.mgt.common.SubscribingDeviceIdHolder; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationPolicyDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException; +import org.wso2.carbon.device.application.mgt.common.response.Application; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; +import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO; +import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.application.mgt.core.util.HelperUtil; +import org.wso2.carbon.device.application.mgt.core.util.OAuthUtils; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.MDMAppConstants; +import org.wso2.carbon.device.mgt.common.app.mgt.App; +import org.wso2.carbon.device.mgt.common.app.mgt.MobileAppTypes; +import org.wso2.carbon.device.mgt.common.app.mgt.android.CustomApplication; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException; +import org.wso2.carbon.device.mgt.common.exceptions.UnknownApplicationTypeException; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.common.operation.mgt.ActivityStatus; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; +import org.wso2.carbon.device.mgt.core.util.MDMAndroidOperationUtil; +import org.wso2.carbon.device.mgt.core.util.MDMIOSOperationUtil; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.device.mgt.common.PaginationResult; + +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; + +/** + * This is the default implementation for the Subscription Manager. + */ +public class SubscriptionManagerImpl implements SubscriptionManager { + + private static final Log log = LogFactory.getLog(SubscriptionManagerImpl.class); + private SubscriptionDAO subscriptionDAO; + private ApplicationDAO applicationDAO; + private LifecycleStateManager lifecycleStateManager; + + public SubscriptionManagerImpl() { + lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); + this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO(); + this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); + } + + @Override + public ApplicationInstallResponse performBulkAppOperation(String applicationUUID, List params, + String subType, String action) throws ApplicationManagementException { + if (log.isDebugEnabled()) { + log.debug("Install application release which has UUID " + applicationUUID + " to " + params.size() + + " users."); + } + try { + validateRequest(params, subType, action); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil + .getDeviceManagementProviderService(); + GroupManagementProviderService groupManagementProviderService = HelperUtil + .getGroupManagementProviderService(); + String deviceTypeName = null; + List devices = new ArrayList<>(); + List subscribers = new ArrayList<>(); + List errorDeviceIdentifiers = new ArrayList<>(); + ApplicationInstallResponse applicationInstallResponse; + + //todo validate users, groups and roles + ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID); + if (SubscriptionType.DEVICE.toString().equals(subType)) { + for (T param : params) { + DeviceIdentifier deviceIdentifier = (DeviceIdentifier) param; + if (StringUtils.isEmpty(deviceIdentifier.getId()) || StringUtils + .isEmpty(deviceIdentifier.getType())) { + log.warn("Found a device identifier which has either empty identity of the device or empty" + + " device type. Hence ignoring the device identifier. "); + continue; + } + if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType())) { + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + if (!deviceType.getName().equals(deviceIdentifier.getType())) { + log.warn("Found a device identifier which is not matched with the supported device type " + + "of the application release which has UUID " + applicationUUID + " Application " + + "supported device type is " + deviceType.getName() + " and the " + + "identifier of which has a different device type is " + deviceIdentifier.getId()); + errorDeviceIdentifiers.add(deviceIdentifier); + continue; + } + } + devices.add(deviceManagementProviderService.getDevice(deviceIdentifier, false)); + } + } else if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + for (T param : params) { + String username = (String) param; + subscribers.add(username); + devices.addAll(deviceManagementProviderService.getDevicesOfUser(username)); + } + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + for (T param : params) { + String roleName = (String) param; + subscribers.add(roleName); + devices.addAll(deviceManagementProviderService.getAllDevicesOfRole(roleName)); + } + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + for (T param : params) { + String groupName = (String) param; + subscribers.add(groupName); + devices.addAll(groupManagementProviderService.getAllDevicesOfGroup(groupName)); + } + } + + if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType()) && !SubscriptionType.DEVICE + .toString().equals(subType)) { + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + deviceTypeName = deviceType.getName(); + //filter devices by device type + String tmpDeviceTypeName = deviceTypeName; + devices.removeIf(device -> !tmpDeviceTypeName.equals(device.getType())); + } + + applicationInstallResponse = performActionOnDevices(deviceTypeName, devices, applicationDTO, + subType, subscribers, action); + applicationInstallResponse.setErrorDeviceIdentifiers(errorDeviceIdentifiers); + return applicationInstallResponse; + } catch (DeviceManagementException e) { + String msg = "Error occurred while getting devices of given users or given roles."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (GroupManagementException e) { + String msg = "Error occurred while getting devices of given groups"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + @Override + public void createScheduledSubscription(ScheduledSubscriptionDTO subscriptionDTO) + throws SubscriptionManagementException { + try { + ConnectionManagerUtil.beginDBTransaction(); + ScheduledSubscriptionDTO existingEntry = subscriptionDAO.getPendingScheduledSubscriptionByTaskName( + subscriptionDTO.getTaskName()); + boolean transactionStatus; + if (existingEntry == null) { + transactionStatus = subscriptionDAO.createScheduledSubscription(subscriptionDTO); + } else { + transactionStatus = subscriptionDAO.updateScheduledSubscription(existingEntry.getId(), + subscriptionDTO.getScheduledAt(), subscriptionDTO.getScheduledBy()); + } + if (!transactionStatus) { + ConnectionManagerUtil.rollbackDBTransaction(); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while creating the scheduled subscription entry."; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while executing database transaction"; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while observing the database connection to update subscription status."; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List cleanScheduledSubscriptions() throws SubscriptionManagementException { + try { + // Cleaning up already executed, missed and failed tasks + ConnectionManagerUtil.beginDBTransaction(); + List taskList = subscriptionDAO.getScheduledSubscriptionByStatus( + ExecutionStatus.EXECUTED, false); + taskList.addAll(subscriptionDAO.getNonExecutedSubscriptions()); + taskList.addAll(subscriptionDAO.getScheduledSubscriptionByStatus(ExecutionStatus.FAILED, false)); + List tasksToClean = taskList.stream().map(ScheduledSubscriptionDTO::getId).collect( + Collectors.toList()); + if (!subscriptionDAO.deleteScheduledSubscription(tasksToClean)) { + ConnectionManagerUtil.rollbackDBTransaction(); + } + ConnectionManagerUtil.commitDBTransaction(); + return taskList; + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while cleaning up the old subscriptions."; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while executing database transaction"; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public ScheduledSubscriptionDTO getPendingScheduledSubscription(String taskName) + throws SubscriptionManagementException { + try { + ConnectionManagerUtil.openDBConnection(); + return subscriptionDAO.getPendingScheduledSubscriptionByTaskName(taskName); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while retrieving subscription for task: " + taskName; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void updateScheduledSubscriptionStatus(int id, ExecutionStatus status) + throws SubscriptionManagementException { + try { + ConnectionManagerUtil.beginDBTransaction(); + if (!subscriptionDAO.updateScheduledSubscriptionStatus(id, status)) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Unable to update the status of the subscription: " + id; + log.error(msg); + throw new SubscriptionManagementException(msg); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while updating the status of the subscription."; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while executing database transaction."; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new SubscriptionManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public void performEntAppSubscription(String applicationUUID, List params, String subType, String action) + throws ApplicationManagementException { + if (log.isDebugEnabled()) { + log.debug("Google Ent app Install operation is received to application which has UUID " + + applicationUUID + " to perform on " + params.size() + " params."); + } + try { + if (params.isEmpty()) { + String msg = "In order to subscribe/unsubscribe application release, you should provide list of " + + "subscribers. But found an empty list of subscribers."; + log.error(msg); + throw new BadRequestException(msg); + } + + ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID); + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + //todo need to check application release status if it is not in installable state send forbidden exception + int applicationReleaseId = applicationReleaseDTO.getId(); + if (!ApplicationType.PUBLIC.toString().equals(applicationDTO.getType())) { + String msg = "Application type is not public. Hence you can't perform google ent.install operation on " + + "this application. Application name " + applicationDTO.getName() + " Application Type " + + applicationDTO.getType(); + log.error(msg); + throw new BadRequestException(msg); + } + + List categories = getApplicationCategories(applicationDTO.getId()); + if (!categories.contains("GooglePlaySyncedApp")) { + String msg = "This is not google play store synced application. Hence can't perform enteprise app " + + "installation."; + log.error(msg); + throw new BadRequestException(msg); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil + .getDeviceManagementProviderService(); + + List devices = new ArrayList<>(); + List subscribers = new ArrayList<>(); + List appSubscribingDeviceIds; + List appReSubscribingDeviceIds = new ArrayList<>(); + List deviceIdentifiers = new ArrayList<>(); + + //todo validate users, groups and roles + if (SubscriptionType.DEVICE.toString().equals(subType)) { + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + for (T param : params) { + DeviceIdentifier deviceIdentifier = (DeviceIdentifier) param; + if (StringUtils.isEmpty(deviceIdentifier.getId()) || StringUtils + .isEmpty(deviceIdentifier.getType())) { + log.warn("Found a device identifier which has either empty identity of the device or empty" + + " device type. Hence ignoring the device identifier. "); + continue; + } + if (!deviceType.getName().equals(deviceIdentifier.getType())) { + log.warn("Found a device identifier which is not matched with the supported device type " + + "of the application release which has UUID " + applicationUUID + " Application " + + "supported device type is " + deviceType.getName() + " and the " + + "identifier of which has a different device type is " + deviceIdentifier.getId()); + continue; + } + deviceIdentifiers.add(deviceIdentifier); + devices.add(deviceManagementProviderService.getDevice(deviceIdentifier, false)); + } + } else if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + for (T param : params) { + String username = (String) param; + subscribers.add(username); + devices.addAll(deviceManagementProviderService.getDevicesOfUser(username)); + } + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + for (T param : params) { + String roleName = (String) param; + subscribers.add(roleName); + devices.addAll(deviceManagementProviderService.getAllDevicesOfRole(roleName)); + } + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + GroupManagementProviderService groupManagementProviderService = HelperUtil + .getGroupManagementProviderService(); + for (T param : params) { + String groupName = (String) param; + subscribers.add(groupName); + devices.addAll(groupManagementProviderService.getAllDevicesOfGroup(groupName)); + } + } else { + String msg = "Found invalid subscription type " + subType+ " to install application release" ; + log.error(msg); + throw new BadRequestException(msg); + } + + /*If subscription type is not device we need to crete device identifiers object list by referring retrieved + list of devices.*/ + if (!SubscriptionType.DEVICE.toString().equalsIgnoreCase(subType)) { + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + String deviceTypeName = deviceType.getName(); + //filter devices by device type + devices.removeIf(device -> !deviceTypeName.equals(device.getType())); + devices.forEach(device -> { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(device.getDeviceIdentifier()); + deviceIdentifier.setType(device.getType()); + deviceIdentifiers.add(deviceIdentifier); + }); + } + + //Installing the application + ApplicationPolicyDTO applicationPolicyDTO = new ApplicationPolicyDTO(); + applicationPolicyDTO.setApplicationDTO(applicationDTO); + applicationPolicyDTO.setDeviceIdentifierList(deviceIdentifiers); + applicationPolicyDTO.setAction(action); + installEnrollmentApplications(applicationPolicyDTO); + + appSubscribingDeviceIds = devices.stream().map(Device::getId).collect(Collectors.toList()); + Map deviceSubscriptions = getDeviceSubscriptions(appSubscribingDeviceIds, + applicationReleaseId); + for (Map.Entry deviceSubscription: deviceSubscriptions.entrySet()){ + appReSubscribingDeviceIds.add(deviceSubscription.getKey()); + appSubscribingDeviceIds.remove(deviceSubscription.getKey()); + } + + updateSubscriptionsForEntInstall(applicationReleaseId, appSubscribingDeviceIds, appReSubscribingDeviceIds, + subscribers, subType, action); + } catch (DeviceManagementException e) { + String msg = "Error occurred while getting devices of given users or given roles."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (GroupManagementException e) { + String msg = "Error occurred while getting devices of given groups"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + /** + * This method is responsible to update subscription data for google enterprise install. + * + * @param applicationReleaseId Application release Id + * @param params subscribers. If subscription is performed via user, group or role, params is a list of + * {@link String} + * @param subType Subscription type. i.e USER, GROUP, ROLE or DEVICE + * @param action Performing action. (i.e INSTALL or UNINSTALL) + * @throws ApplicationManagementException if error occurred while getting or updating subscription data. + */ + private void updateSubscriptionsForEntInstall(int applicationReleaseId, List appSubscribingDeviceIds, + List appReSubscribingDeviceIds, List params, String subType, String action) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + try { + ConnectionManagerUtil.beginDBTransaction(); + List subscribedEntities = new ArrayList<>(); + if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + subscribedEntities = subscriptionDAO.getAppSubscribedUserNames(params, applicationReleaseId, tenantId); + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + subscribedEntities = subscriptionDAO.getAppSubscribedRoleNames(params, applicationReleaseId, tenantId); + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + subscribedEntities = subscriptionDAO.getAppSubscribedGroupNames(params, applicationReleaseId, tenantId); + } + + params.removeAll(subscribedEntities); + if (!params.isEmpty()) { + subscriptionDAO.addUserSubscriptions(tenantId, username, params, applicationReleaseId); + } + if (!subscribedEntities.isEmpty()) { + subscriptionDAO + .updateSubscriptions(tenantId, username, subscribedEntities, applicationReleaseId, subType, + action); + } + + if (SubAction.INSTALL.toString().equalsIgnoreCase(action) && !appSubscribingDeviceIds.isEmpty()) { + subscriptionDAO.addDeviceSubscription(username, appSubscribingDeviceIds, subType, + Operation.Status.COMPLETED.toString(), applicationReleaseId, tenantId); + } + if (!appReSubscribingDeviceIds.isEmpty()) { + subscriptionDAO.updateDeviceSubscription(username, appReSubscribingDeviceIds, action, subType, + Operation.Status.COMPLETED.toString(), applicationReleaseId, tenantId); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "Error occurred when adding subscription data for application release ID: " + applicationReleaseId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection to add new device subscriptions to application."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "SQL Error occurred when adding new device subscription to application release which has ID: " + + applicationReleaseId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + + + /** + * THis method is responsible to validate application install or uninstall request. + * + * @param params params could be either list of {@link DeviceIdentifier} or list of username or list of group + * names or list or role names. + * @param subType Subscription type. i.e DEVICE or USER or ROLE or GROUP + * @param action performing action. i.e Install or Uninstall + * @throws BadRequestException if incompatible data is found with app install/uninstall request. + */ + private void validateRequest(List params, String subType, String action) throws BadRequestException { + if (params.isEmpty()) { + String msg = "In order to subscribe/unsubscribe application release, you should provide list of " + + "subscribers. But found an empty list of subscribers."; + log.error(msg); + throw new BadRequestException(msg); + } + boolean isValidSubType = Arrays.stream(SubscriptionType.values()) + .anyMatch(sub -> sub.name().equalsIgnoreCase(subType)); + if (!isValidSubType) { + String msg = "Found invalid subscription type " + subType+ " to install application release" ; + log.error(msg); + throw new BadRequestException(msg); + } + boolean isValidAction = Arrays.stream(SubAction.values()) + .anyMatch(sub -> sub.name().equalsIgnoreCase(action)); + if (!isValidAction) { + String msg = "Found invalid action " + action +" to perform on application release"; + log.error(msg); + throw new BadRequestException(msg); + } + } + + /** + * This method perform given action (i.e APP INSTALL or APP UNINSTALL) on given set of devices. + * + * @param deviceType Application supported device type. + * @param devices List of devices that action is triggered. + * @param applicationDTO Application data + * @param subType Subscription type (i.e USER, ROLE, GROUP or DEVICE) + * @param subscribers Subscribers + * @param action Performing action. (i.e INSTALL or UNINSTALL) + * @return {@link ApplicationInstallResponse} + * @throws ApplicationManagementException if error occured when adding operation on device or updating subscription + * data. + */ + private ApplicationInstallResponse performActionOnDevices(String deviceType, List devices, + ApplicationDTO applicationDTO, String subType, List subscribers, String action) + throws ApplicationManagementException { + + SubscribingDeviceIdHolder subscribingDeviceIdHolder = getSubscribingDeviceIdHolder(devices, + applicationDTO.getApplicationReleaseDTOs().get(0).getId()); + List activityList = new ArrayList<>(); + List deviceIdentifiers = new ArrayList<>(); + List ignoredDeviceIdentifiers = new ArrayList<>(); + Map> deviceIdentifierMap = new HashMap<>(); + + if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + deviceIdentifiers.addAll(new ArrayList<>(subscribingDeviceIdHolder.getAppInstallableDevices().keySet())); + deviceIdentifiers.addAll(new ArrayList<>(subscribingDeviceIdHolder.getAppReInstallableDevices().keySet())); + deviceIdentifiers.addAll(new ArrayList<>(subscribingDeviceIdHolder.getAppInstalledDevices().keySet())); + } else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { + deviceIdentifiers.addAll(new ArrayList<>(subscribingDeviceIdHolder.getAppInstalledDevices().keySet())); + deviceIdentifiers + .addAll(new ArrayList<>(subscribingDeviceIdHolder.getAppReUnInstallableDevices().keySet())); + ignoredDeviceIdentifiers + .addAll(new ArrayList<>(subscribingDeviceIdHolder.getAppInstallableDevices().keySet())); + } + + if (deviceIdentifiers.isEmpty()) { + ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse(); + applicationInstallResponse.setIgnoredDeviceIdentifiers(ignoredDeviceIdentifiers); + return applicationInstallResponse; + } + + //device type is getting null when we try to perform action on Web Clip. + if (deviceType == null) { + for (DeviceIdentifier identifier : deviceIdentifiers) { + List identifiers; + if (!deviceIdentifierMap.containsKey(identifier.getType())) { + identifiers = new ArrayList<>(); + identifiers.add(identifier); + deviceIdentifierMap.put(identifier.getType(), identifiers); + } else { + identifiers = deviceIdentifierMap.get(identifier.getType()); + identifiers.add(identifier); + deviceIdentifierMap.put(identifier.getType(), identifiers); + } + } + for (Map.Entry> entry : deviceIdentifierMap.entrySet()) { + Activity activity = addAppOperationOnDevices(applicationDTO, new ArrayList<>(entry.getValue()), + entry.getKey(), action); + activityList.add(activity); + } + } else { + Activity activity = addAppOperationOnDevices(applicationDTO, deviceIdentifiers, deviceType, action); + activityList.add(activity); + } + + ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse(); + applicationInstallResponse.setActivities(activityList); + applicationInstallResponse.setIgnoredDeviceIdentifiers(ignoredDeviceIdentifiers); + + updateSubscriptions(applicationDTO.getApplicationReleaseDTOs().get(0).getId(), activityList, + subscribingDeviceIdHolder, subscribers, subType, action); + return applicationInstallResponse; + } + + /** + * Filter given devices and davide given list of device into two sets, those are already application installed + * devices and application installable devices. + * + * @param devices List of {@link Device} + * @param appReleaseId Application release id. + * @return {@link SubscribingDeviceIdHolder} + * @throws ApplicationManagementException if error occured while getting device subscriptions for applicaion. + */ + private SubscribingDeviceIdHolder getSubscribingDeviceIdHolder(List devices, int appReleaseId) + throws ApplicationManagementException { + + SubscribingDeviceIdHolder subscribingDeviceIdHolder = new SubscribingDeviceIdHolder(); + subscribingDeviceIdHolder.setAppInstallableDevices(new HashMap<>()); + subscribingDeviceIdHolder.setAppInstalledDevices(new HashMap<>()); + subscribingDeviceIdHolder.setAppReInstallableDevices(new HashMap<>()); + subscribingDeviceIdHolder.setAppReUnInstallableDevices(new HashMap<>()); + subscribingDeviceIdHolder.setSkippedDevices(new HashMap<>()); + + List deviceIds = devices.stream().map(Device::getId).collect(Collectors.toList()); + //get device subscriptions for given device id list. + Map deviceSubscriptions = getDeviceSubscriptions(deviceIds, appReleaseId); + for (Device device : devices) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + DeviceSubscriptionDTO deviceSubscriptionDTO = deviceSubscriptions.get(device.getId()); + if (deviceSubscriptionDTO != null) { + if (!deviceSubscriptionDTO.isUnsubscribed() && Operation.Status.COMPLETED.toString() + .equals(deviceSubscriptionDTO.getStatus())) { + subscribingDeviceIdHolder.getAppInstalledDevices().put(deviceIdentifier, device.getId()); + } else if (deviceSubscriptionDTO.isUnsubscribed() && !Operation.Status.COMPLETED.toString() + .equals(deviceSubscriptionDTO.getStatus())) { + subscribingDeviceIdHolder.getAppReUnInstallableDevices().put(deviceIdentifier, device.getId()); + } else if (Operation.Status.PENDING.toString().equals(deviceSubscriptionDTO.getStatus()) + || Operation.Status.IN_PROGRESS.toString().equals(deviceSubscriptionDTO.getStatus())) { + subscribingDeviceIdHolder.getSkippedDevices().put(deviceIdentifier, device.getId()); + } else { + subscribingDeviceIdHolder.getAppReInstallableDevices().put(deviceIdentifier, device.getId()); + } + } else { + subscribingDeviceIdHolder.getAppInstallableDevices().put(deviceIdentifier, device.getId()); + } + } + return subscribingDeviceIdHolder; + } + + /** + * This method returns the application categories of a particular application + * + * @param id Application Id + * @return List of application categories. + * @throws ApplicationManagementException if error occurred while getting application categories from the DB. + */ + private List getApplicationCategories(int id) throws ApplicationManagementException { + List categories; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + categories = this.applicationDAO.getAppCategories(id, tenantId); + return categories; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting categories for application : " + id; + log.error(msg, e); + throw new ApplicationManagementException(msg); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /*** + * Get Application with application release which has given UUID. + * + * @param uuid UUID of the application release. + * @return {@link ApplicationDTO} + * @throws ApplicationManagementException if error occurred while getting application data from database or + * verifying whether application is in installable state. + */ + private ApplicationDTO getApplicationDTO(String uuid) throws ApplicationManagementException { + ApplicationDTO applicationDTO; + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + applicationDTO = this.applicationDAO.getAppWithRelatedRelease(uuid, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't fond an application for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + if (!lifecycleStateManager.getInstallableState() + .equals(applicationDTO.getApplicationReleaseDTOs().get(0).getCurrentState())) { + String msg = "You are trying to install an application which is not in the installable state of " + + "its Life-Cycle. hence you are not permitted to install this application. If you " + + "required to install this particular application, please change the state of " + + "application release from : " + applicationDTO.getApplicationReleaseDTOs().get(0) + .getCurrentState() + " to " + lifecycleStateManager.getInstallableState(); + log.error(msg); + throw new ForbiddenException(msg); + } + return applicationDTO; + } catch (LifecycleManagementException e) { + String msg = "Error occured when getting life-cycle state from life-cycle state manager."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting application data for application release UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /** + * This method is responsible to update subscription data. + * + * @param applicationReleaseId Application release Id + * @param activities List of {@link Activity} + * @param subscribingDeviceIdHolder Subscribing device id holder. + * @param params subscribers. If subscription is performed via user, group or role, params is a list of + * {@link String} + * @param subType Subscription type. i.e USER, GROUP, ROLE or DEVICE + * @param action performing action. ie INSTALL or UNINSTALL> + * @throws ApplicationManagementException if error occurred while getting or updating subscription data. + */ + private void updateSubscriptions(int applicationReleaseId, List activities, + SubscribingDeviceIdHolder subscribingDeviceIdHolder, List params, String subType, + String action) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + try { + ConnectionManagerUtil.beginDBTransaction(); + if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + List subscribedEntities = subscriptionDAO + .getAppSubscribedUserNames(params, applicationReleaseId, tenantId); + if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + params.removeAll(subscribedEntities); + subscriptionDAO.addUserSubscriptions(tenantId, username, params, applicationReleaseId); + } + subscriptionDAO.updateSubscriptions(tenantId, username, subscribedEntities, applicationReleaseId, subType, + action); + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + List subscribedEntities = subscriptionDAO + .getAppSubscribedRoleNames(params, applicationReleaseId, tenantId); + if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + params.removeAll(subscribedEntities); + subscriptionDAO.addRoleSubscriptions(tenantId, username, params, applicationReleaseId); + } + subscriptionDAO.updateSubscriptions(tenantId, username, subscribedEntities, applicationReleaseId, subType, + action); + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + List subscribedEntities = subscriptionDAO + .getAppSubscribedGroupNames(params, applicationReleaseId, tenantId); + if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + params.removeAll(subscribedEntities); + subscriptionDAO.addGroupSubscriptions(tenantId, username, params, applicationReleaseId); + } + subscriptionDAO.updateSubscriptions(tenantId, username, subscribedEntities, applicationReleaseId, subType, + action); + } + + for (Activity activity : activities) { + int operationId = Integer.parseInt(activity.getActivityId().split("ACTIVITY_")[1]); + List subUpdatingDeviceIds = new ArrayList<>(); + List subInsertingDeviceIds = new ArrayList<>(); + + if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + subUpdatingDeviceIds.addAll(getOperationAddedDeviceIds(activity, + subscribingDeviceIdHolder.getAppReInstallableDevices())); + subUpdatingDeviceIds.addAll(getOperationAddedDeviceIds(activity, + subscribingDeviceIdHolder.getAppInstalledDevices())); + subInsertingDeviceIds.addAll(getOperationAddedDeviceIds(activity, + subscribingDeviceIdHolder.getAppInstallableDevices())); + } else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { + subUpdatingDeviceIds.addAll(getOperationAddedDeviceIds(activity, + subscribingDeviceIdHolder.getAppInstalledDevices())); + } + + subscriptionDAO.addDeviceSubscription(username, subInsertingDeviceIds, subType, + Operation.Status.PENDING.toString(), applicationReleaseId, tenantId); + if (!subUpdatingDeviceIds.isEmpty()) { + subscriptionDAO.updateDeviceSubscription(username, subUpdatingDeviceIds, action, subType, + Operation.Status.PENDING.toString(), applicationReleaseId, tenantId); + } + subUpdatingDeviceIds.addAll(subInsertingDeviceIds); + if (!subUpdatingDeviceIds.isEmpty()) { + List deviceSubIds = new ArrayList<>( + subscriptionDAO.getDeviceSubIds(subUpdatingDeviceIds, applicationReleaseId, tenantId)); + subscriptionDAO.addOperationMapping(operationId, deviceSubIds, tenantId); + } + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when adding subscription data for application release ID: " + + applicationReleaseId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection to add new device subscriptions to application."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "SQL Error occurred when adding new device subscription to application release which has ID: " + + applicationReleaseId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /** + * This method is responsible to get device IDs thta operation has added. + * + * @param activity Activity + * @param deviceMap Device map, key is device identifier and value is primary key of device. + * @return List of device primary keys + */ + private List getOperationAddedDeviceIds(Activity activity, Map deviceMap) { + List activityStatuses = activity.getActivityStatus(); + return activityStatuses.stream() + .filter(status -> deviceMap.get(status.getDeviceIdentifier()) != null) + .map(status -> deviceMap.get(status.getDeviceIdentifier())).collect(Collectors.toList()); + } + + /** + * This method is responsible to get device subscription of particular application releasee for given set of devices. + * + * @param deviceIds Set of device Ids + * @param appReleaseId Application release Id + * @return {@link HashMap} with key as device id and value as {@link DeviceSubscriptionDTO} + * @throws ApplicationManagementException if error occured while executing SQL query or if more than one data found + * for a device id. + */ + private Map getDeviceSubscriptions(List deviceIds, int appReleaseId) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + + try { + ConnectionManagerUtil.openDBConnection(); + return this.subscriptionDAO.getDeviceSubscriptions(deviceIds, appReleaseId, tenantId); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occured when getting device subscriptions for given device IDs"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occured while getting database connection for getting device subscriptions."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /** + * This method is responsible to add operation on given devices. + * + * @param applicationDTO application. + * @param deviceIdentifierList list of device identifiers. + * @param deviceType device type + * @param action action e.g :- INSTALL, UNINSTALL + * @return {@link Activity} + * @throws ApplicationManagementException if found an invalid device. + */ + private Activity addAppOperationOnDevices(ApplicationDTO applicationDTO, + List deviceIdentifierList, String deviceType, String action) + throws ApplicationManagementException { + DeviceManagementProviderService deviceManagementProviderService = HelperUtil + .getDeviceManagementProviderService(); + try { + Application application = APIUtil.appDtoToAppResponse(applicationDTO); + Operation operation = generateOperationPayloadByDeviceType(deviceType, application, action); + return deviceManagementProviderService.addOperation(deviceType, operation, deviceIdentifierList); + } catch (OperationManagementException e) { + String msg = "Error occurred while adding the application install operation to devices"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (InvalidDeviceException e) { + //This exception should not occur because the validation has already been done. + throw new ApplicationManagementException("The list of device identifiers are invalid"); + } + } + + /** + * This method constructs operation payload to install/uninstall an application. + * + * @param deviceType Device type + * @param application {@link Application} data. + * @param action Action is either ININSTALL or UNINSTALL + * @return {@link Operation} + * @throws ApplicationManagementException if unknown application type is found to generate operation payload or + * invalid action is found to generate operation payload. + */ + private Operation generateOperationPayloadByDeviceType(String deviceType, Application application, String action) + throws ApplicationManagementException { + try { + if (ApplicationType.CUSTOM.toString().equalsIgnoreCase(application.getType())) { + ProfileOperation operation = new ProfileOperation(); + if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + operation.setCode(MDMAppConstants.AndroidConstants.OPCODE_INSTALL_APPLICATION); + operation.setType(Operation.Type.PROFILE); + CustomApplication customApplication = new CustomApplication(); + customApplication.setType(application.getType()); + customApplication.setUrl(application.getApplicationReleases().get(0).getInstallerPath()); + operation.setPayLoad(customApplication.toJSON()); + return operation; + } else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { + operation.setCode(MDMAppConstants.AndroidConstants.OPCODE_UNINSTALL_APPLICATION); + operation.setType(Operation.Type.PROFILE); + CustomApplication customApplication = new CustomApplication(); + customApplication.setType(application.getType()); + customApplication.setAppIdentifier(application.getPackageName()); + operation.setPayLoad(customApplication.toJSON()); + return operation; + } else { + String msg = "Invalid Action is found. Action: " + action; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } else { + App app = new App(); + MobileAppTypes mobileAppType = MobileAppTypes.valueOf(application.getType()); + if (DeviceTypes.ANDROID.toString().equalsIgnoreCase(deviceType)) { + app.setType(mobileAppType); + app.setLocation(application.getApplicationReleases().get(0).getInstallerPath()); + app.setIdentifier(application.getPackageName()); + app.setName(application.getName()); + if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + return MDMAndroidOperationUtil.createInstallAppOperation(app); + } else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { + return MDMAndroidOperationUtil.createAppUninstallOperation(app); + } else { + String msg = "Invalid Action is found. Action: " + action; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } else if (DeviceTypes.IOS.toString().equalsIgnoreCase(deviceType)) { + if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) { + String plistDownloadEndpoint = + APIUtil.getArtifactDownloadBaseURL() + MDMAppConstants.IOSConstants.PLIST + + Constants.FORWARD_SLASH + application.getApplicationReleases().get(0) + .getUuid(); + app.setType(mobileAppType); + app.setLocation(plistDownloadEndpoint); + Properties properties = new Properties(); + properties.put(MDMAppConstants.IOSConstants.IS_PREVENT_BACKUP, true); + properties.put(MDMAppConstants.IOSConstants.IS_REMOVE_APP, true); + app.setProperties(properties); + return MDMIOSOperationUtil.createInstallAppOperation(app); + } else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) { + app.setType(mobileAppType); + app.setIdentifier(application.getPackageName()); + return MDMIOSOperationUtil.createAppUninstallOperation(app); + } else { + String msg = "Invalid Action is found. Action: " + action; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } else { + String msg = "Invalid device type is found. Device Type: " + deviceType; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } + } catch (UnknownApplicationTypeException e) { + String msg = "Unknown Application type is found."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + public int installEnrollmentApplications(ApplicationPolicyDTO applicationPolicyDTO) + throws ApplicationManagementException { + + HttpClient httpClient; + PostMethod request; + try { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + ApiApplicationKey apiApplicationKey = OAuthUtils.getClientCredentials(tenantDomain); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + Constants.ApplicationInstall.AT + tenantDomain; + AccessTokenInfo tokenInfo = OAuthUtils.getOAuthCredentials(apiApplicationKey, username); + String requestUrl = Constants.ApplicationInstall.ENROLLMENT_APP_INSTALL_PROTOCOL + + System.getProperty(Constants.ApplicationInstall.IOT_CORE_HOST) + + Constants.ApplicationInstall.COLON + + System.getProperty(Constants.ApplicationInstall.IOT_CORE_PORT) + + Constants.ApplicationInstall.GOOGLE_APP_INSTALL_URL; + Gson gson = new Gson(); + String payload = gson.toJson(applicationPolicyDTO); + + StringRequestEntity requestEntity = new StringRequestEntity(payload, MediaType.APPLICATION_JSON + , Constants.ApplicationInstall.ENCODING); + httpClient = new HttpClient(); + request = new PostMethod(requestUrl); + request.addRequestHeader(Constants.ApplicationInstall.AUTHORIZATION + , Constants.ApplicationInstall.AUTHORIZATION_HEADER_VALUE + tokenInfo.getAccessToken()); + request.setRequestEntity(requestEntity); + httpClient.executeMethod(request); + return request.getStatusCode(); + + } catch (UserStoreException e) { + String msg = "Error while accessing user store for user with Android device."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (APIManagerException e) { + String msg = "Error while retrieving access token for Android device" ; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (HttpException e) { + String msg = "Error while calling the app store to install enrollment app with id: " + + applicationPolicyDTO.getApplicationDTO().getId() + + " on device"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (IOException e) { + String msg = "Error while installing the enrollment with id: " + applicationPolicyDTO.getApplicationDTO().getId() + + " on device"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + @Override + public PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, + String status) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil + .getDeviceManagementProviderService(); + + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(appUUID, tenantId); + int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); + + List deviceSubscriptionDTOS = subscriptionDAO + .getDeviceSubscriptions(applicationReleaseId, tenantId); + if (deviceSubscriptionDTOS.isEmpty()) { + PaginationResult paginationResult = new PaginationResult(); + paginationResult.setData(new ArrayList<>()); + paginationResult.setRecordsFiltered(0); + paginationResult.setRecordsTotal(0); + return paginationResult; + } + List deviceIdList = new ArrayList<>(); + deviceSubscriptionDTOS.forEach(deviceSubscriptionDTO -> { + if ((!deviceSubscriptionDTO.isUnsubscribed() && Operation.Status.COMPLETED.toString() + .equalsIgnoreCase(deviceSubscriptionDTO.getStatus())) || (deviceSubscriptionDTO.isUnsubscribed() + && !Operation.Status.COMPLETED.toString() + .equalsIgnoreCase(deviceSubscriptionDTO.getStatus()))) { + deviceIdList.add(deviceSubscriptionDTO.getDeviceId()); + } + }); + + if (deviceIdList.isEmpty()){ + PaginationResult paginationResult = new PaginationResult(); + paginationResult.setData(deviceIdList); + paginationResult.setRecordsFiltered(0); + paginationResult.setRecordsTotal(0); + return paginationResult; + } + //pass the device id list to device manager service method + try { + PaginationResult deviceDetails = deviceManagementProviderService + .getAppSubscribedDevices(offsetValue ,limitValue, deviceIdList, status); + + if (deviceDetails == null) { + String msg = "Couldn't found an subscribed devices details for device ids: " + + deviceIdList; + log.error(msg); + throw new NotFoundException(msg); + } + return deviceDetails; + + } catch (DeviceManagementException e) { + String msg = "service error occurred while getting data from the service"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when get application release data for application" + + " release UUID: " + appUUID; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting device details that " + + "given application id"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public PaginationResult getAppInstalledSubscribers(int offsetValue, int limitValue, String appUUID, String subType) + throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + PaginationResult paginationResult = new PaginationResult(); + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO + .getAppWithRelatedRelease(appUUID, tenantId); + int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); + + List subscriptionList = new ArrayList<>(); + + if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { + subscriptionList = subscriptionDAO + .getAppSubscribedUsers(offsetValue, limitValue, applicationReleaseId, tenantId); + } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { + subscriptionList = subscriptionDAO + .getAppSubscribedRoles(offsetValue, limitValue, applicationReleaseId, tenantId); + } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { + subscriptionList = subscriptionDAO + .getAppSubscribedGroups(offsetValue, limitValue, applicationReleaseId, tenantId); + } + int count = subscriptionList.size(); + paginationResult.setData(subscriptionList); + paginationResult.setRecordsFiltered(count); + paginationResult.setRecordsTotal(count); + return paginationResult; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when get application release data for application" + + " release UUID: " + appUUID; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting category details that " + + "given application id"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public PaginationResult getAppSubscriptionDetails(int offsetValue, int limitValue, String appUUID) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil + .getDeviceManagementProviderService(); + if (offsetValue < 0 || limitValue <= 0) { + String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. " + + "Offset " + offsetValue + " limit " + limitValue; + log.error(msg); + throw new BadRequestException(msg); + } + + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(appUUID, tenantId); + if (applicationDTO == null) { + String msg = "Couldn't find an application with application release which has UUID " + appUUID; + log.error(msg); + throw new NotFoundException(msg); + } + int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); + + List deviceSubscriptionDTOS = subscriptionDAO + .getDeviceSubscriptions(applicationReleaseId, tenantId); + if (deviceSubscriptionDTOS.isEmpty()) { + PaginationResult paginationResult = new PaginationResult(); + paginationResult.setData(new ArrayList<>()); + paginationResult.setRecordsFiltered(0); + paginationResult.setRecordsTotal(0); + return paginationResult; + } + List deviceIdList = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId) + .collect(Collectors.toList()); + try { + //pass the device id list to device manager service method + PaginationResult paginationResult = deviceManagementProviderService + .getAppSubscribedDevices(offsetValue, limitValue, deviceIdList, null); + List deviceSubscriptionDataList = new ArrayList<>(); + + if (!paginationResult.getData().isEmpty()) { + List devices = (List) paginationResult.getData(); + for (Device device : devices) { + DeviceSubscriptionData deviceSubscriptionData = new DeviceSubscriptionData(); + for (DeviceSubscriptionDTO subscription : deviceSubscriptionDTOS) { + if (subscription.getDeviceId() == device.getId()) { + deviceSubscriptionData.setDevice(device); + if (subscription.isUnsubscribed()) { + deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); + deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); + deviceSubscriptionData + .setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp()); + } else { + deviceSubscriptionData.setAction(Constants.SUBSCRIBED); + deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceSubscriptionData + .setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + } + deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); + deviceSubscriptionData.setStatus(subscription.getStatus()); + deviceSubscriptionDataList.add(deviceSubscriptionData); + break; + } + } + } + } + paginationResult.setData(deviceSubscriptionDataList); + return paginationResult; + } catch (DeviceManagementException e) { + String msg = "service error occurred while getting device data from the device management service. " + + "Device ids " + deviceIdList; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when getting application release data for application release UUID: " + + appUUID; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while trying to get subscription data of application which has " + + "application release UUID " + appUUID; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ApplicationManagementServiceComponent.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ApplicationManagementServiceComponent.java new file mode 100644 index 0000000000..4189e2ec7c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ApplicationManagementServiceComponent.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; +import org.wso2.carbon.device.application.mgt.common.config.UIConfiguration; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; +import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; +import org.wso2.carbon.device.application.mgt.common.services.ReviewManager; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.impl.AppmDataHandlerImpl; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.core.task.ScheduledAppSubscriptionTaskManager; +import org.wso2.carbon.device.application.mgt.core.util.ApplicationManagementUtil; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.ndatasource.core.DataSourceService; +import org.wso2.carbon.ntask.core.service.TaskService; +import org.wso2.carbon.user.core.service.RealmService; + +import java.util.List; + +/** + * @scr.component name="org.wso2.carbon.application.mgt.service" immediate="true" + * @scr.reference name="org.wso2.carbon.device.manager" + * interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService" + * cardinality="1..1" + * policy="dynamic" + * bind="setDeviceManagementService" + * unbind="unsetDeviceManagementService" + * @scr.reference name="realm.service" + * immediate="true" + * interface="org.wso2.carbon.user.core.service.RealmService" + * cardinality="1..1" + * policy="dynamic" + * bind="setRealmService" + * unbind="unsetRealmService" + * @scr.reference name="datasource.service" + * interface="org.wso2.carbon.ndatasource.core.DataSourceService" + * cardinality="1..1" + * policy="dynamic" + * bind="setDataSourceService" + * unbind="unsetDataSourceService" + * @scr.reference name="app.mgt.ntask.component" + * interface="org.wso2.carbon.ntask.core.service.TaskService" + * cardinality="1..1" + * policy="dynamic" + * bind="setTaskService" + * unbind="unsetTaskService" + */ +@SuppressWarnings("unused") +public class ApplicationManagementServiceComponent { + + private static Log log = LogFactory.getLog(ApplicationManagementServiceComponent.class); + + + @SuppressWarnings("unused") + protected void activate(ComponentContext componentContext) { + BundleContext bundleContext = componentContext.getBundleContext(); + try { + String dataSourceName = ConfigurationManager.getInstance().getConfiguration().getDatasourceName(); + ApplicationManagementDAOFactory.init(dataSourceName); + + List lifecycleStates = ConfigurationManager.getInstance(). + getConfiguration().getLifecycleStates(); + LifecycleStateManager lifecycleStateManager = ApplicationManagementUtil.getLifecycleStateMangerInstance(); + lifecycleStateManager.init(lifecycleStates); + DataHolder.getInstance().setLifecycleStateManger(lifecycleStateManager); + bundleContext.registerService(LifecycleStateManager.class.getName(), lifecycleStateManager, null); + + ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance(); + applicationManager + .addApplicationCategories(ConfigurationManager.getInstance().getConfiguration().getAppCategories()); + DataHolder.getInstance().setApplicationManager(applicationManager); + bundleContext.registerService(ApplicationManager.class.getName(), applicationManager, null); + + ReviewManager reviewManager = ApplicationManagementUtil.getReviewManagerInstance(); + DataHolder.getInstance().setReviewManager(reviewManager); + bundleContext.registerService(ReviewManager.class.getName(), reviewManager, null); + + SubscriptionManager subscriptionManager = ApplicationManagementUtil.getSubscriptionManagerInstance(); + DataHolder.getInstance().setSubscriptionManager(subscriptionManager); + bundleContext.registerService(SubscriptionManager.class.getName(), subscriptionManager, null); + + ApplicationStorageManager applicationStorageManager = ApplicationManagementUtil + .getApplicationStorageManagerInstance(); + DataHolder.getInstance().setApplicationStorageManager(applicationStorageManager); + bundleContext.registerService(ApplicationStorageManager.class.getName(), applicationStorageManager, null); + + UIConfiguration uiConfiguration = ConfigurationManager.getInstance(). + getConfiguration().getUiConfiguration(); + AppmDataHandler configManager = new AppmDataHandlerImpl(uiConfiguration); + DataHolder.getInstance().setConfigManager(configManager); + bundleContext.registerService(AppmDataHandler.class.getName(), configManager, null); + + ScheduledAppSubscriptionTaskManager taskManager = new ScheduledAppSubscriptionTaskManager(); + taskManager.scheduleCleanupTask(); + + log.info("ApplicationManagement core bundle has been successfully initialized"); + } catch (Throwable e) { + log.error("Error occurred while initializing app management core bundle", e); + } + } + + @SuppressWarnings("unused") + protected void deactivate(ComponentContext componentContext) { + //do nothing + } + + @SuppressWarnings("unused") + protected void setDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) { + if (log.isDebugEnabled()) { + log.debug("Setting ApplicationDTO Management OSGI Manager"); + } + DataHolder.getInstance().setDeviceManagementService(deviceManagementProviderService); + } + + @SuppressWarnings("unused") + protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementProviderService) { + if (log.isDebugEnabled()) { + log.debug("Removing ApplicationDTO Management OSGI Manager"); + } + DataHolder.getInstance().setDeviceManagementService(null); + } + + @SuppressWarnings("unused") + protected void setRealmService(RealmService realmService) { + DataHolder.getInstance().setRealmService(realmService); + } + + @SuppressWarnings("unused") + protected void unsetRealmService(RealmService realmService) { + DataHolder.getInstance().setRealmService(null); + } + + @SuppressWarnings("unused") + protected void setDataSourceService(DataSourceService dataSourceService) { + /*Not implemented. Not needed but to make sure the datasource service are registered, as it is needed create + databases. */ + } + + @SuppressWarnings("unused") + protected void unsetDataSourceService(DataSourceService dataSourceService) { + /*Not implemented. Not needed but to make sure the datasource service are registered, as it is needed to create + databases.*/ + } + + @SuppressWarnings("unused") + public void setTaskService(TaskService taskService) { + if (log.isDebugEnabled()) { + log.debug("Setting the task service to Application Management SC."); + } + DataHolder.getInstance().setTaskService(taskService); + } + + @SuppressWarnings("unused") + protected void unsetTaskService(TaskService taskService) { + if (log.isDebugEnabled()) { + log.debug("Removing the task service from Application Management SC"); + } + DataHolder.getInstance().setTaskService(null); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java new file mode 100644 index 0000000000..81132a7009 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.internal; + +import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; +import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; +import org.wso2.carbon.device.application.mgt.common.services.ReviewManager; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.ntask.core.service.TaskService; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * DataHolder is responsible for holding the references to OSGI Services. + */ +public class DataHolder { + + private DeviceManagementProviderService deviceManagementService; + + private RealmService realmService; + + private ApplicationManager applicationManager; + + private ReviewManager reviewManager; + + private SubscriptionManager subscriptionManager; + + private ApplicationStorageManager applicationStorageManager; + + private LifecycleStateManager lifecycleStateManager; + + private AppmDataHandler configManager; + + private TaskService taskService; + + private static final DataHolder applicationMgtDataHolder = new DataHolder(); + + private DataHolder() { + + } + + public static DataHolder getInstance() { + return applicationMgtDataHolder; + } + + public DeviceManagementProviderService getDeviceManagementService() { + return deviceManagementService; + } + + public void setDeviceManagementService(DeviceManagementProviderService deviceManagementService) { + this.deviceManagementService = deviceManagementService; + } + + public ApplicationManager getApplicationManager() { + return applicationManager; + } + + public void setApplicationManager(ApplicationManager applicationManager) { + this.applicationManager = applicationManager; + } + + public ReviewManager getReviewManager() { + return reviewManager; + } + + public void setReviewManager(ReviewManager reviewManager) { + this.reviewManager = reviewManager; + } + + public SubscriptionManager getSubscriptionManager() { + return subscriptionManager; + } + + public void setSubscriptionManager(SubscriptionManager subscriptionManager) { + this.subscriptionManager = subscriptionManager; + } + + public RealmService getRealmService() { + return realmService; + } + + public void setRealmService(RealmService realmService) { + this.realmService = realmService; + } + + public void setApplicationStorageManager(ApplicationStorageManager applicationStorageManager) { + this.applicationStorageManager = applicationStorageManager; + } + + public ApplicationStorageManager getApplicationStorageManager() { + return applicationStorageManager; + } + + public LifecycleStateManager getLifecycleStateManager() { + return lifecycleStateManager; + } + + public void setLifecycleStateManger(LifecycleStateManager lifecycleStateManager) { + this.lifecycleStateManager = lifecycleStateManager; + } + + public AppmDataHandler getConfigManager() { + return configManager; + } + + public void setConfigManager(AppmDataHandler configManager) { + this.configManager = configManager; + } + + public TaskService getTaskService() { + return taskService; + } + + public void setTaskService(TaskService taskService) { + this.taskService = taskService; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManager.java new file mode 100644 index 0000000000..612c055867 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManager.java @@ -0,0 +1,250 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.lifecycle; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; +import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; +import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; +import org.wso2.carbon.device.mgt.core.search.mgt.Constants; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class represents the activities related to lifecycle management + */ +public class LifecycleStateManager { + + private Map lifecycleStates; + private static Log log = LogFactory.getLog(LifecycleStateManager.class); + + public void init(List states) throws LifecycleManagementException { + lifecycleStates = new HashMap<>(); + for (LifecycleState lifecycleState : states) { + if (lifecycleState.getProceedingStates() != null) { + lifecycleState.getProceedingStates().replaceAll(String::toUpperCase); + } + lifecycleStates.put(lifecycleState.getName().toUpperCase(), lifecycleState); + try { + PermissionUtils.putPermission(lifecycleState.getPermission()); + } catch (PermissionManagementException e) { + String msg = "Error when adding permission " + lifecycleState.getPermission() + " related to the " + + "state: " + lifecycleState.getName(); + log.error(msg, e); + throw new LifecycleManagementException(msg, e); + } + } + } + + public Map getLifecycleConfig() throws LifecycleManagementException { + if (lifecycleStates == null) { + String msg = "Lifecycle configuration in not initialized."; + log.error(msg); + throw new LifecycleManagementException(msg); + } + return lifecycleStates; + } + + public List getNextLifecycleStates(String currentLifecycleState) { + return lifecycleStates.get(currentLifecycleState.toUpperCase()).getProceedingStates(); + } + + public boolean isValidStateChange(String currentState, String nextState, String username, int tenantId) + throws LifecycleManagementException { + UserRealm userRealm; + String permission = getPermissionForStateChange(nextState); + if (permission != null) { + try { + userRealm = DataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); + if (userRealm != null && userRealm.getAuthorizationManager() != null && userRealm + .getAuthorizationManager() + .isUserAuthorized(username, PermissionUtils.getAbsolutePermissionPath(permission), + Constants.UI_EXECUTE)) { + if (currentState.equalsIgnoreCase(nextState)) { + return true; + } + LifecycleState matchingState = getMatchingState(currentState); + if (matchingState != null) { + return getMatchingNextState(matchingState.getProceedingStates(), nextState); + } + return false; + } + return false; + } catch (UserStoreException e) { + String msg = "UserStoreException exception from changing the state from : " + currentState + " to: " + + nextState + " with username : " + username + " and tenant Id : " + tenantId; + log.error(msg, e); + throw new LifecycleManagementException(msg, e); + } + } else { + String msg = "Required permissions cannot be found for the state : " + nextState; + log.error(msg); + throw new LifecycleManagementException(msg); + } + } + + private LifecycleState getMatchingState(String currentState) { + for (Map.Entry lifecycyleState : lifecycleStates.entrySet()) { + if (lifecycyleState.getKey().equalsIgnoreCase(currentState)) { + return lifecycyleState.getValue(); + } + } + return null; + } + + private boolean getMatchingNextState(List proceedingStates, String nextState) { + for (String stateName : proceedingStates) { + if (stateName.equalsIgnoreCase(nextState)) { + return true; + } + } + return false; + } + + private String getPermissionForStateChange(String nextState) { + for (Map.Entry lifecycyleState : lifecycleStates.entrySet()) { + if (lifecycyleState.getKey().equalsIgnoreCase(nextState)) { + return lifecycyleState.getValue().getPermission(); + } + } + return null; + } + + public boolean isDeletableState(String state) throws LifecycleManagementException { + LifecycleState currentState = getMatchingState(state); + if (currentState != null) { + return currentState.isDeletableState(); + } else { + String msg = "Couldn't find a lifecycle state that matches with " + state + " state."; + log.error(msg); + throw new LifecycleManagementException(msg); + } + } + + public boolean isUpdatableState(String state) throws LifecycleManagementException { + LifecycleState currentState = getMatchingState(state); + if (currentState != null) { + return currentState.isAppUpdatable(); + } else { + String msg = "Couldn't find a lifecycle state that matches with " + state + " state."; + log.error(msg); + throw new LifecycleManagementException(msg); + } + } + + public boolean isInstallableState(String state) throws LifecycleManagementException { + LifecycleState currentState = getMatchingState(state); + if (currentState != null) { + return currentState.isAppInstallable(); + } else { + String msg = "Couldn't find a lifecycle state that matches with " + state + " state."; + log.error(msg); + throw new LifecycleManagementException(msg); + } + } + + public boolean isInitialState(String state) throws LifecycleManagementException { + LifecycleState currentState = getMatchingState(state); + if (currentState != null) { + return currentState.isInitialState(); + } else { + String msg = "Couldn't find a lifecycle state that matches with " + state + " state."; + log.error(msg); + throw new LifecycleManagementException(msg); + } + } + + public boolean isEndState(String state) throws LifecycleManagementException { + LifecycleState currentState = getMatchingState(state); + if (currentState != null) { + return currentState.isEndState(); + } else { + String msg = "Couldn't find a lifecycle state that matches with " + state + " state."; + log.error(msg); + throw new LifecycleManagementException(msg); + } + } + + public String getInitialState() throws LifecycleManagementException { + String initialState; + for (Map.Entry lifecycleState : lifecycleStates.entrySet()) { + if (lifecycleState.getValue().isInitialState()) { + initialState = lifecycleState.getKey(); + return initialState; + } + } + String msg = "Haven't defined the initial state in the application-manager.xml. Please add initial state " + + "to the section in the app-manager.xml"; + log.error(msg); + throw new LifecycleManagementException(msg); + } + + public String getEndState() throws LifecycleManagementException { + String endState = null; + for (Map.Entry stringStateEntry : lifecycleStates.entrySet()) { + if (stringStateEntry.getValue().isEndState()) { + endState = stringStateEntry.getKey(); + break; + } + } + if (endState == null) { + String msg = "Haven't defined the end state in the application-manager.xml. Please add end state " + + "to the section in the app-manager.xml"; + log.error(msg); + throw new LifecycleManagementException(msg); + } + return endState; + } + + public String getInstallableState() throws LifecycleManagementException { + String installableState = null; + for (Map.Entry stringStateEntry : lifecycleStates.entrySet()) { + if (stringStateEntry.getValue().isAppInstallable()) { + installableState = stringStateEntry.getKey(); + break; + } + } + if (installableState == null) { + String msg = "Haven't defined the installable state in the application-manager.xml. Please add installable " + + "state to the section in the app-manager.xml"; + log.error(msg); + throw new LifecycleManagementException(msg); + } + return installableState; + } + + public boolean isStateExist(String currentState) { + for (Map.Entry stringStateEntry : lifecycleStates.entrySet()) { + if (stringStateEntry.getKey().equalsIgnoreCase(currentState)) { + return true; + } + } + return false; + } + + public void setLifecycleStates(Map lifecycleStates) { + this.lifecycleStates = lifecycleStates; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionCleanupTask.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionCleanupTask.java new file mode 100644 index 0000000000..38077daf93 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionCleanupTask.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.task; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl; +import org.wso2.carbon.ntask.core.Task; + +import java.util.Map; + +public class ScheduledAppSubscriptionCleanupTask implements Task { + private static Log log = LogFactory.getLog(ScheduledAppSubscriptionCleanupTask.class); + private SubscriptionManager subscriptionManager; + + @Override + public void setProperties(Map properties) { + //no properties required + } + + @Override + public void init() { + if (this.subscriptionManager == null) { + this.subscriptionManager = new SubscriptionManagerImpl(); + } + } + + @Override + public void execute() { + try { + subscriptionManager.cleanScheduledSubscriptions(); + } catch (SubscriptionManagementException e) { + log.error("Error occurred while cleaning up tasks."); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java new file mode 100644 index 0000000000..afbab64d6d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.task; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.apache.commons.lang.StringUtils; +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.common.ExecutionStatus; +import org.wso2.carbon.device.application.mgt.common.SubscriptionType; +import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.ntask.core.Task; + +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class ScheduledAppSubscriptionTask implements Task { + private static Log log = LogFactory.getLog(ScheduledAppSubscriptionTask.class); + private SubscriptionManager subscriptionManager; + private String subscribers; + private String subscriptionType; + private String application; + private String action; + private String subscriber; + private String tenantDomain; + private String taskName; + private int tenantId; + + @Override + public void setProperties(Map map) { + this.subscribers = map.get(Constants.SUBSCRIBERS); + this.subscriptionType = map.get(Constants.SUB_TYPE); + this.application = map.get(Constants.APP_UUID); + this.action = map.get(Constants.ACTION); + this.subscriber = map.get(Constants.SUBSCRIBER); + this.tenantDomain = map.get(Constants.TENANT_DOMAIN); + this.tenantId = Integer.parseInt(map.get(Constants.TENANT_ID)); + this.taskName = map.get(Constants.TASK_NAME); + } + + @Override + public void init() { + if (this.subscriptionManager == null) { + this.subscriptionManager = new SubscriptionManagerImpl(); + } + } + + @Override + public void execute() { + try { + ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription( + this.taskName); + if (subscriptionDTO == null) { + log.error("Unable to execute the task. Task entry for [" + this.taskName + "] cannot be retrieved " + + "from the database."); + return; + } + if (StringUtils.isNotEmpty(this.subscribers)) { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + carbonContext.setTenantDomain(this.tenantDomain); + carbonContext.setTenantId(this.tenantId); + carbonContext.setUsername(this.subscriber); + + if (this.subscriptionType.equals(SubscriptionType.DEVICE.toString())) { + List deviceIdentifiers = new Gson().fromJson(this.subscribers, + new TypeToken>() { + }.getType()); + try { + subscriptionManager.performBulkAppOperation(this.application, deviceIdentifiers, + this.subscriptionType, this.action); + subscriptionDTO.setStatus(ExecutionStatus.EXECUTED); + } catch (ApplicationManagementException e) { + log.error( + "Error occurred while " + this.action + "ing application " + this.application + + "to/from the following devices: " + this.subscribers, e); + subscriptionDTO.setStatus(ExecutionStatus.FAILED); + } + } else { + List subscriberList = Pattern.compile(",").splitAsStream(this.subscribers).collect( + Collectors.toList()); + try { + subscriptionManager.performBulkAppOperation(this.application, subscriberList, + this.subscriptionType, this.action); + subscriptionDTO.setStatus(ExecutionStatus.EXECUTED); + } catch (ApplicationManagementException e) { + log.error( + "Error occurred while " + this.action + "ing application " + this.application + + "to/from the following " + this.subscriptionType + "s: " + this.subscribers, e); + subscriptionDTO.setStatus(ExecutionStatus.FAILED); + } + } + } else { + log.warn( + "Subscriber list is empty. Therefore skipping scheduled task to " + this.action + "application " + + this.application); + subscriptionDTO.setStatus(ExecutionStatus.FAILED); + } + subscriptionManager.updateScheduledSubscriptionStatus(subscriptionDTO.getId(), subscriptionDTO.getStatus()); + } catch (SubscriptionManagementException e) { + log.error("Error occurred while executing the task: " + this.taskName, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java new file mode 100644 index 0000000000..c07053f3d5 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.task; + +import com.google.gson.Gson; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.quartz.CronExpression; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.SubAction; +import org.wso2.carbon.device.application.mgt.common.SubscriptionType; +import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.exception.ApplicationOperationTaskException; +import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.ntask.common.TaskException; +import org.wso2.carbon.ntask.core.TaskInfo; +import org.wso2.carbon.ntask.core.TaskManager; +import org.wso2.carbon.ntask.core.service.TaskService; + +import java.time.LocalDateTime; +import java.time.format.TextStyle; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +public class ScheduledAppSubscriptionTaskManager { + private static Log log = LogFactory.getLog(ScheduledAppSubscriptionTaskManager.class); + private static final String SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE = "SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE"; + private static final String NAME_SEPARATOR = "_"; + private SubscriptionManager subscriptionManager; + + public ScheduledAppSubscriptionTaskManager() { + this.subscriptionManager = new SubscriptionManagerImpl(); + } + + /** + * Schedule a task to install/uninstall application for a list of subscribers + * + * @param applicationUUID UUID of the application to install + * @param subscribers list of subscribers. This list can be of + * either {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is + * equal to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP + * @param subscriptionType subscription type. E.g. DEVICE, USER, ROLE, GROUP + * {@see {@link org.wso2.carbon.device.application.mgt.common.SubscriptionType}} + * @param action action subscription action. E.g. {@code INSTALL/UNINSTALL} + * {@see {@link org.wso2.carbon.device.application.mgt.common.SubAction}} + * @param timestamp timestamp to schedule the application subscription + * @throws ApplicationOperationTaskException if error occurred while scheduling the subscription + */ + public void scheduleAppSubscriptionTask(String applicationUUID, List subscribers, + SubscriptionType subscriptionType, SubAction action, LocalDateTime timestamp) + throws ApplicationOperationTaskException { + String space = " "; + String cronExpression = + String.valueOf(timestamp.getSecond()) + space + timestamp.getMinute() + space + timestamp.getHour() + + space + timestamp.getDayOfMonth() + space + timestamp.getMonth().getDisplayName(TextStyle.SHORT, + Locale.getDefault()).toUpperCase() + " ? " + timestamp.getYear(); + + if (!CronExpression.isValidExpression(cronExpression)) { + String msg = "The cron expression [" + cronExpression + "] generated by the" + " timestamp [" + timestamp + .toString() + "] is invalid"; + log.error(msg); + throw new ApplicationOperationTaskException(msg); + } + + try { + PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + TaskService taskService = initializeTaskType(); + + TaskManager taskManager = taskService.getTaskManager(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE); + TaskInfo.TriggerInfo triggerInfo = new TaskInfo.TriggerInfo(); + triggerInfo.setCronExpression(cronExpression); + triggerInfo.setRepeatCount(0); + + Map taskProperties = new HashMap<>(); + taskProperties.put(Constants.SUB_TYPE, subscriptionType.toString()); + taskProperties.put(Constants.ACTION, action.toString()); + taskProperties.put(Constants.APP_UUID, applicationUUID); + taskProperties.put(Constants.TENANT_DOMAIN, carbonContext.getTenantDomain(true)); + taskProperties.put(Constants.SUBSCRIBER, carbonContext.getUsername()); + + String subscribersString; + if (SubscriptionType.DEVICE.equals(subscriptionType)) { + subscribersString = new Gson().toJson(subscribers); + taskProperties.put(Constants.SUBSCRIBERS, subscribersString); + } else { + subscribersString = subscribers.stream().map(String.class::cast).collect(Collectors.joining(",")); + taskProperties.put(Constants.SUBSCRIBERS, subscribersString); + } + if (log.isDebugEnabled()) { + log.debug("Scheduling a task to " + action.toString() + " application: " + applicationUUID + + " to/from the following " + subscriptionType.toString() + "S [" + subscribersString + "] at: " + + timestamp); + } + String taskName = subscriptionType.toString() + NAME_SEPARATOR + action.toString() + NAME_SEPARATOR + + DigestUtils.md5Hex(applicationUUID + NAME_SEPARATOR + subscribersString); + taskProperties.put(Constants.TASK_NAME, taskName); + TaskInfo taskInfo = new TaskInfo(taskName, ScheduledAppSubscriptionTask.class.getName(), + taskProperties, triggerInfo); + + ScheduledSubscriptionDTO subscriptionDTO = new ScheduledSubscriptionDTO(taskName, applicationUUID, + timestamp, subscribers, carbonContext.getUsername()); + subscriptionManager.createScheduledSubscription(subscriptionDTO); + + taskManager.registerTask(taskInfo); + if (!taskManager.isTaskScheduled(taskName)) { + taskManager.scheduleTask(taskName); + } else { + taskManager.rescheduleTask(taskName); + } + } catch (TaskException e) { + String msg = "Error occurred while scheduling a task to " + action.toString() + " application: " + + applicationUUID + " to/from given " + subscriptionType.toString() + "S"; + log.error(msg, e); + throw new ApplicationOperationTaskException(msg, e); + } catch (SubscriptionManagementException e) { + String msg = "Error occurred while writing the subscription to database"; + log.error(msg, e); + throw new ApplicationOperationTaskException(msg, e); + } + } + + /** + * Schedules a task to clean up the scheduled tasks from {@link org.wso2.carbon.ntask.core.TaskRepository} + */ + public void scheduleCleanupTask() { + try { + TaskService taskService = initializeTaskType(); + TaskManager taskManager = taskService.getTaskManager(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE); + + TaskInfo.TriggerInfo triggerInfo = new TaskInfo.TriggerInfo(); + triggerInfo.setCronExpression("0 0 0/24 ? * * *"); + + String taskName = "SCHEDULED_APP_SUBSCRIPTION_CLEANUP_TASK"; + TaskInfo taskInfo = new TaskInfo(taskName, ScheduledAppSubscriptionCleanupTask.class.getName(), null, + triggerInfo); + + taskManager.registerTask(taskInfo); + if (!taskManager.isTaskScheduled(taskName)) { + taskManager.scheduleTask(taskName); + } else { + taskManager.rescheduleTask(taskName); + } + } catch (TaskException e) { + log.error("Error occurred while scheduling a cleanup task."); + } catch (ApplicationOperationTaskException e) { + log.error(e.getMessage()); + } + } + + /** + * Initialize task type. + * + * @return {@link TaskService} + * @throws TaskException if error occurred while initializing task type + * @throws ApplicationOperationTaskException if unable to load {@link TaskService} + */ + private TaskService initializeTaskType() throws TaskException, ApplicationOperationTaskException { + TaskService taskService = DataHolder.getInstance().getTaskService(); + if (taskService == null) { + String msg = "Unable to load TaskService, hence unable to schedule the task."; + log.error(msg); + throw new ApplicationOperationTaskException(msg); + } + if (!taskService.getRegisteredTaskTypes().contains(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE)) { + try { + List removedTaskList = subscriptionManager.cleanScheduledSubscriptions(); + removeScheduledSubscriptions(taskService, removedTaskList); + } catch (SubscriptionManagementException e) { + log.error("Error occurred while retrieving tasks to cleanup", e); + } + taskService.registerTaskType(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE); + } + return taskService; + } + + /** + * Cleans up already scheduled subscriptions. + * + * @param taskList list of {@link ScheduledSubscriptionDTO}s to remove + */ + private void removeScheduledSubscriptions(TaskService taskService, List taskList) { + try { + TaskManager taskManager = taskService.getTaskManager(SCHEDULED_APP_SUBSCRIPTION_TASK_TYPE); + taskManager.getAllTasks().forEach( + task -> taskList.stream().filter(t -> t.getTaskName().equals(task.getName())).forEach(t -> { + try { + taskManager.deleteTask(t.getTaskName()); + } catch (TaskException e) { + log.error("Error occurred while removing the task: " + t.getTaskName(), e); + } + })); + } catch (TaskException e) { + log.error("Error occurred while removing tasks", e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java new file mode 100644 index 0000000000..55a4f63909 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.util; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.validator.routines.UrlValidator; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.ApplicationType; +import org.wso2.carbon.device.application.mgt.common.config.MDMConfig; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.response.Application; +import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.services.*; +import org.wso2.carbon.device.application.mgt.common.ErrorResponse; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppWrapper; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Holds util methods required for ApplicationDTO-Mgt API component. + */ +public class APIUtil { + + private static Log log = LogFactory.getLog(APIUtil.class); + + private static ApplicationManager applicationManager; + private static ApplicationStorageManager applicationStorageManager; + private static SubscriptionManager subscriptionManager; + private static ReviewManager reviewManager; + private static AppmDataHandler appmDataHandler; + + 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 = "ApplicationDTO Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return applicationManager; + } + + /** + * To get the ApplicationDTO 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 = "ApplicationDTO Storage Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return applicationStorageManager; + } + + 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; + } + + /** + * To get the Review Manager from the osgi context. + * @return ReviewManager instance in the current osgi context. + */ + public static ReviewManager getReviewManager() { + if (reviewManager == null) { + synchronized (APIUtil.class) { + if (reviewManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + reviewManager = + (ReviewManager) ctx.getOSGiService(ReviewManager.class, null); + if (reviewManager == null) { + String msg = "Review Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + + return reviewManager; + } + + /** + * To get the DataHandler from the osgi context. + * @return AppmDataHandler instance in the current osgi context. + */ + public static AppmDataHandler getDataHandler() { + if (appmDataHandler == null) { + synchronized (APIUtil.class) { + if (appmDataHandler == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + appmDataHandler = + (AppmDataHandler) ctx.getOSGiService(AppmDataHandler.class, null); + if (appmDataHandler == null) { + String msg = "Config Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + + return appmDataHandler; + } + + public static DeviceType getDeviceTypeData(T deviceTypeAttr) + throws BadRequestException, UnexpectedServerErrorException { + List deviceTypes; + try { + deviceTypes = DAOUtil.getDeviceManagementService().getDeviceTypes(); + if (deviceTypeAttr instanceof String) { + for (DeviceType dt : deviceTypes) { + if (dt.getName().equals(deviceTypeAttr)) { + return dt; + } + } + } else if (deviceTypeAttr instanceof Integer) { + for (DeviceType dt : deviceTypes) { + if (dt.getId() == (Integer) deviceTypeAttr) { + return dt; + } + } + } else { + String msg = "Invalid device type class is received. Device type class: " + deviceTypeAttr.getClass() + .getName(); + log.error(msg); + throw new BadRequestException(msg); + } + String msg = "Invalid device type Attribute is found with the request. Device Type attribute: " + + deviceTypeAttr; + log.error(msg); + throw new BadRequestException(msg); + } catch (DeviceManagementException e) { + String msg = "Error occured when getting device types which are supported by the Entgra IoTS"; + log.error(msg, e); + throw new UnexpectedServerErrorException(msg, e); + } + } + + public static ApplicationDTO convertToAppDTO(T param) + throws BadRequestException, UnexpectedServerErrorException { + ApplicationDTO applicationDTO = new ApplicationDTO(); + + if (param instanceof ApplicationWrapper){ + ApplicationWrapper applicationWrapper = (ApplicationWrapper) param; + DeviceType deviceType = getDeviceTypeData(applicationWrapper.getDeviceType()); + applicationDTO.setName(applicationWrapper.getName()); + applicationDTO.setDescription(applicationWrapper.getDescription()); + applicationDTO.setAppCategories(applicationWrapper.getCategories()); + applicationDTO.setType(ApplicationType.ENTERPRISE.toString()); + applicationDTO.setSubType(applicationWrapper.getSubMethod()); + applicationDTO.setPaymentCurrency(applicationWrapper.getPaymentCurrency()); + applicationDTO.setTags(applicationWrapper.getTags()); + applicationDTO.setUnrestrictedRoles(applicationWrapper.getUnrestrictedRoles()); + applicationDTO.setDeviceTypeId(deviceType.getId()); + List applicationReleaseEntities = applicationWrapper.getEntAppReleaseWrappers() + .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); + applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); + } else if (param instanceof WebAppWrapper){ + WebAppWrapper webAppWrapper = (WebAppWrapper) param; + applicationDTO.setName(webAppWrapper.getName()); + applicationDTO.setDescription(webAppWrapper.getDescription()); + applicationDTO.setAppCategories(webAppWrapper.getCategories()); + applicationDTO.setSubType(webAppWrapper.getSubMethod()); + applicationDTO.setPaymentCurrency(webAppWrapper.getPaymentCurrency()); + applicationDTO.setType(webAppWrapper.getType()); + applicationDTO.setTags(webAppWrapper.getTags()); + applicationDTO.setUnrestrictedRoles(webAppWrapper.getUnrestrictedRoles()); + List applicationReleaseEntities = webAppWrapper.getWebAppReleaseWrappers() + .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); + applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); + } else if (param instanceof PublicAppWrapper) { + PublicAppWrapper publicAppWrapper = (PublicAppWrapper) param; + DeviceType deviceType = getDeviceTypeData(publicAppWrapper.getDeviceType()); + applicationDTO.setName(publicAppWrapper.getName()); + applicationDTO.setDescription(publicAppWrapper.getDescription()); + applicationDTO.setAppCategories(publicAppWrapper.getCategories()); + applicationDTO.setType(ApplicationType.PUBLIC.toString()); + applicationDTO.setSubType(publicAppWrapper.getSubMethod()); + applicationDTO.setPaymentCurrency(publicAppWrapper.getPaymentCurrency()); + applicationDTO.setTags(publicAppWrapper.getTags()); + applicationDTO.setUnrestrictedRoles(publicAppWrapper.getUnrestrictedRoles()); + applicationDTO.setDeviceTypeId(deviceType.getId()); + List applicationReleaseEntities = publicAppWrapper.getPublicAppReleaseWrappers() + .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); + applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); + } else if (param instanceof CustomAppWrapper){ + CustomAppWrapper customAppWrapper = (CustomAppWrapper) param; + DeviceType deviceType = getDeviceTypeData(customAppWrapper.getDeviceType()); + applicationDTO.setName(customAppWrapper.getName()); + applicationDTO.setDescription(customAppWrapper.getDescription()); + applicationDTO.setAppCategories(customAppWrapper.getCategories()); + applicationDTO.setType(ApplicationType.CUSTOM.toString()); + applicationDTO.setSubType(customAppWrapper.getSubMethod()); + applicationDTO.setPaymentCurrency(customAppWrapper.getPaymentCurrency()); + applicationDTO.setTags(customAppWrapper.getTags()); + applicationDTO.setUnrestrictedRoles(customAppWrapper.getUnrestrictedRoles()); + applicationDTO.setDeviceTypeId(deviceType.getId()); + List applicationReleaseEntities = customAppWrapper.getCustomAppReleaseWrappers() + .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); + applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); + } + return applicationDTO; + } + + public static ApplicationReleaseDTO releaseWrapperToReleaseDTO(T param){ + ApplicationReleaseDTO applicationReleaseDTO = new ApplicationReleaseDTO(); + if (param instanceof EntAppReleaseWrapper){ + EntAppReleaseWrapper entAppReleaseWrapper = (EntAppReleaseWrapper) param; + applicationReleaseDTO.setDescription(entAppReleaseWrapper.getDescription()); + applicationReleaseDTO.setReleaseType(entAppReleaseWrapper.getReleaseType()); + applicationReleaseDTO.setPrice(entAppReleaseWrapper.getPrice()); + applicationReleaseDTO.setIsSharedWithAllTenants(entAppReleaseWrapper.getIsSharedWithAllTenants()); + applicationReleaseDTO.setMetaData(entAppReleaseWrapper.getMetaData()); + applicationReleaseDTO.setSupportedOsVersions(entAppReleaseWrapper.getSupportedOsVersions()); + } else if (param instanceof WebAppReleaseWrapper){ + WebAppReleaseWrapper webAppReleaseWrapper = (WebAppReleaseWrapper) param; + applicationReleaseDTO.setDescription(webAppReleaseWrapper.getDescription()); + applicationReleaseDTO.setReleaseType(webAppReleaseWrapper.getReleaseType()); + applicationReleaseDTO.setVersion(webAppReleaseWrapper.getVersion()); + applicationReleaseDTO.setPrice(webAppReleaseWrapper.getPrice()); + applicationReleaseDTO.setInstallerName(webAppReleaseWrapper.getUrl()); + applicationReleaseDTO.setIsSharedWithAllTenants(webAppReleaseWrapper.getIsSharedWithAllTenants()); + applicationReleaseDTO.setSupportedOsVersions(Constants.ANY); + applicationReleaseDTO.setPackageName(Constants.DEFAULT_PCK_NAME); + applicationReleaseDTO.setMetaData(webAppReleaseWrapper.getMetaData()); + } else if (param instanceof PublicAppReleaseWrapper) { + PublicAppReleaseWrapper publicAppReleaseWrapper = (PublicAppReleaseWrapper) param; + applicationReleaseDTO.setDescription(publicAppReleaseWrapper.getDescription()); + applicationReleaseDTO.setReleaseType(publicAppReleaseWrapper.getReleaseType()); + applicationReleaseDTO.setVersion(publicAppReleaseWrapper.getVersion()); + applicationReleaseDTO.setPackageName(publicAppReleaseWrapper.getPackageName()); + applicationReleaseDTO.setPrice(publicAppReleaseWrapper.getPrice()); + applicationReleaseDTO.setIsSharedWithAllTenants(publicAppReleaseWrapper.getIsSharedWithAllTenants()); + applicationReleaseDTO.setMetaData(publicAppReleaseWrapper.getMetaData()); + applicationReleaseDTO.setSupportedOsVersions(publicAppReleaseWrapper.getSupportedOsVersions()); + } else if (param instanceof CustomAppReleaseWrapper) { + CustomAppReleaseWrapper customAppReleaseWrapper = (CustomAppReleaseWrapper) param; + applicationReleaseDTO.setDescription(customAppReleaseWrapper.getDescription()); + applicationReleaseDTO.setReleaseType(customAppReleaseWrapper.getReleaseType()); + applicationReleaseDTO.setVersion(customAppReleaseWrapper.getVersion()); + applicationReleaseDTO.setSupportedOsVersions(Constants.ANY); + applicationReleaseDTO.setPackageName(customAppReleaseWrapper.getPackageName()); + applicationReleaseDTO.setPrice(customAppReleaseWrapper.getPrice()); + applicationReleaseDTO.setIsSharedWithAllTenants(customAppReleaseWrapper.getIsSharedWithAllTenants()); + applicationReleaseDTO.setMetaData(customAppReleaseWrapper.getMetaData()); + } + return applicationReleaseDTO; + } + + public static Application appDtoToAppResponse(ApplicationDTO applicationDTO) throws ApplicationManagementException { + + Application application = new Application(); + if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType())) { + DeviceType deviceType = getDeviceTypeData(applicationDTO.getDeviceTypeId()); + application.setDeviceType(deviceType.getName()); + } else { + application.setDeviceType(Constants.ANY); + } + application.setId(applicationDTO.getId()); + application.setName(applicationDTO.getName()); + application.setDescription(applicationDTO.getDescription()); + application.setCategories(applicationDTO.getAppCategories()); + application.setType(applicationDTO.getType()); + application.setSubMethod(applicationDTO.getSubType()); + application.setPaymentCurrency(applicationDTO.getPaymentCurrency()); + application.setTags(applicationDTO.getTags()); + application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles()); + application.setRating(applicationDTO.getAppRating()); + List applicationReleases = new ArrayList<>(); + if (ApplicationType.PUBLIC.toString().equals(applicationDTO.getType()) && application.getCategories() + .contains("GooglePlaySyncedApp")) { + application.setAndroidEnterpriseApp(true); + } + for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) { + applicationReleases.add(releaseDtoToRelease(applicationReleaseDTO)); + } + application.setApplicationReleases(applicationReleases); + application.setPackageName(applicationDTO.getPackageName()); + return application; + } + + public static ApplicationRelease releaseDtoToRelease(ApplicationReleaseDTO applicationReleaseDTO) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String basePath = + getArtifactDownloadBaseURL() + tenantId + Constants.FORWARD_SLASH + applicationReleaseDTO.getUuid() + + Constants.FORWARD_SLASH; + + List screenshotPaths = new ArrayList<>(); + ApplicationRelease applicationRelease = new ApplicationRelease(); + UrlValidator urlValidator = new UrlValidator(); + + applicationRelease.setDescription(applicationReleaseDTO.getDescription()); + applicationRelease.setVersion(applicationReleaseDTO.getVersion()); + applicationRelease.setUuid(applicationReleaseDTO.getUuid()); + applicationRelease.setReleaseType(applicationReleaseDTO.getReleaseType()); + applicationRelease.setPrice(applicationReleaseDTO.getPrice()); + applicationRelease.setIsSharedWithAllTenants(applicationReleaseDTO.getIsSharedWithAllTenants()); + applicationRelease.setMetaData(applicationReleaseDTO.getMetaData()); + applicationRelease.setCurrentStatus(applicationReleaseDTO.getCurrentState()); + applicationRelease.setIsSharedWithAllTenants(applicationReleaseDTO.getIsSharedWithAllTenants()); + applicationRelease.setSupportedOsVersions(applicationReleaseDTO.getSupportedOsVersions()); + applicationRelease.setRating(applicationReleaseDTO.getRating()); + applicationRelease.setIconPath( + basePath + Constants.ICON_ARTIFACT + Constants.FORWARD_SLASH + applicationReleaseDTO.getIconName()); + + if (!StringUtils.isEmpty(applicationReleaseDTO.getBannerName())){ + applicationRelease.setBannerPath( + basePath + Constants.BANNER_ARTIFACT + Constants.FORWARD_SLASH + applicationReleaseDTO + .getBannerName()); + } + + if (urlValidator.isValid(applicationReleaseDTO.getInstallerName())) { + applicationRelease.setInstallerPath(applicationReleaseDTO.getInstallerName()); + } else { + applicationRelease.setInstallerPath( + basePath + Constants.APP_ARTIFACT + Constants.FORWARD_SLASH + applicationReleaseDTO + .getInstallerName()); + } + + if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName1())) { + screenshotPaths + .add(basePath + Constants.SCREENSHOT_ARTIFACT + 1 + Constants.FORWARD_SLASH + applicationReleaseDTO + .getScreenshotName1()); + } + if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName2())) { + screenshotPaths + .add(basePath + Constants.SCREENSHOT_ARTIFACT + 2 + Constants.FORWARD_SLASH + applicationReleaseDTO + .getScreenshotName2()); + } + if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName3())) { + screenshotPaths + .add(basePath + Constants.SCREENSHOT_ARTIFACT + 3 + Constants.FORWARD_SLASH + applicationReleaseDTO + .getScreenshotName3()); + } + applicationRelease.setScreenshots(screenshotPaths); + return applicationRelease; + } + + public static String getArtifactDownloadBaseURL() throws ApplicationManagementException { + String host = System.getProperty(Constants.IOT_HOST_PROPERTY); + MDMConfig mdmConfig = ConfigurationManager.getInstance().getConfiguration().getMdmConfig(); + String port; + if (Constants.HTTP_PROTOCOL.equals(mdmConfig.getArtifactDownloadProtocol())){ + port = System.getProperty(Constants.IOT_HTTP_PORT_PROPERTY); + } else if( Constants.HTTPS_PROTOCOL.equals(mdmConfig.getArtifactDownloadProtocol())){ + port = System.getProperty(Constants.IOT_HTTPS_PORT_PROPERTY); + } else { + String msg = "In order to download application artifacts invalid protocols are defined."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + String artifactDownloadEndpoint = mdmConfig.getArtifactDownloadEndpoint(); + return mdmConfig.getArtifactDownloadProtocol() + "://" + host + ":" + port + + artifactDownloadEndpoint + Constants.FORWARD_SLASH; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java new file mode 100644 index 0000000000..db4e749e93 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.InvalidConfigurationException; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; +import org.wso2.carbon.device.application.mgt.common.services.ReviewManager; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.application.mgt.core.config.Extension; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; + +import java.lang.reflect.Constructor; + +/** + * This DAOUtil class is responsible for making sure single instance of each Extension Manager is used throughout for + * all the tasks. + */ +public class ApplicationManagementUtil { + + private static Log log = LogFactory.getLog(ApplicationManagementUtil.class); + + public static ApplicationManager getApplicationManagerInstance() throws InvalidConfigurationException { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Extension extension = configurationManager.getExtension(Extension.Name.ApplicationManager); + return getInstance(extension, ApplicationManager.class); + } + + public static ReviewManager getReviewManagerInstance() throws InvalidConfigurationException { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Extension extension = configurationManager.getExtension(Extension.Name.ReviewManager); + return getInstance(extension, ReviewManager.class); + } + + public static SubscriptionManager getSubscriptionManagerInstance() throws InvalidConfigurationException { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Extension extension = configurationManager.getExtension(Extension.Name.SubscriptionManager); + return getInstance(extension, SubscriptionManager.class); + } + + public static ApplicationStorageManager getApplicationStorageManagerInstance() throws + InvalidConfigurationException { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Extension extension = configurationManager.getExtension(Extension.Name.ApplicationStorageManager); + return getInstance(extension, ApplicationStorageManager.class); + } + + public static LifecycleStateManager getLifecycleStateMangerInstance() throws InvalidConfigurationException { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Extension extension = configurationManager.getExtension(Extension.Name.LifecycleStateManager); + return getInstance(extension, LifecycleStateManager.class); + } + + private static T getInstance(Extension extension, Class cls) throws InvalidConfigurationException { + try { + Class theClass = Class.forName(extension.getClassName()); + if (extension.getParameters() != null && extension.getParameters().size() > 0) { + Class[] types = new Class[extension.getParameters().size()]; + Object[] paramValues = new String[extension.getParameters().size()]; + for (int i = 0; i < extension.getParameters().size(); i++) { + types[i] = String.class; + paramValues[i] = extension.getParameters().get(i).getValue(); + } + Constructor constructor = theClass.getConstructor(types); + return constructor.newInstance(paramValues); + } else { + Constructor constructor = theClass.getConstructor(); + return constructor.newInstance(); + } + } catch (Exception e) { + String msg = "Unable to get instance of extension - " + extension.getName() + " , for class - " + extension + .getClassName(); + log.error(msg, e); + throw new InvalidConfigurationException(msg, e); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationMgtDatabaseCreator.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationMgtDatabaseCreator.java new file mode 100644 index 0000000000..95f2119870 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationMgtDatabaseCreator.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.utils.CarbonUtils; +import org.wso2.carbon.utils.dbcreator.DatabaseCreator; +import java.io.File; + +/** + * ApplicationMgtDatabaseCreator is responsible for creating the Application Management related tables. + */ +public class ApplicationMgtDatabaseCreator extends DatabaseCreator { + private static final Log log = LogFactory.getLog(ApplicationMgtDatabaseCreator.class); + private static final String setupSQLScriptBaseLocation = + CarbonUtils.getCarbonHome() + File.separator + "dbscripts" + File.separator + "cdm" + File.separator + + "application-mgt" + File.separator; + + public ApplicationMgtDatabaseCreator(String dataSourceName) { + super(ConnectionManagerUtil.resolveDataSource(dataSourceName)); + } + + protected String getDbScriptLocation(String databaseType) { + String scriptName = databaseType + ".sql"; + if (log.isDebugEnabled()) { + log.debug("Loading application management database script from :" + scriptName); + } + return setupSQLScriptBaseLocation + scriptName; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ArtifactsParser.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ArtifactsParser.java new file mode 100644 index 0000000000..32de0f8006 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ArtifactsParser.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.util; + +import com.dd.plist.BinaryPropertyListParser; +import com.dd.plist.NSDictionary; +import com.dd.plist.PropertyListFormatException; +import com.dd.plist.PropertyListParser; +import net.dongliu.apk.parser.ApkFile; +import net.dongliu.apk.parser.bean.ApkMeta; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.io.IOUtils; +import org.wso2.carbon.device.application.mgt.core.exception.ParsingException; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.UUID; +import java.nio.file.Files; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +public class ArtifactsParser { + + //ios CF Bundle keys + public static final String IPA_BUNDLE_VERSION_KEY = "CFBundleVersion"; + public static final String IPA_BUNDLE_NAME_KEY = "CFBundleName"; + public static final String IPA_BUNDLE_IDENTIFIER_KEY = "CFBundleIdentifier"; + + private static final Log log = LogFactory.getLog(ArtifactsParser.class); + + public static ApkMeta readAndroidManifestFile(InputStream inputStream) throws ParsingException { + File tempFile = null; + ApkMeta apkMeta; + try { + tempFile = File.createTempFile("temp" + UUID.randomUUID(), ".apk"); + try (FileOutputStream out = new FileOutputStream(tempFile)) { + IOUtils.copy(inputStream, out); + try (ApkFile apkFile = new ApkFile(tempFile)) { + apkMeta = apkFile.getApkMeta(); + } + } + } catch (IOException e) { + throw new ParsingException("Error while parsing the apk.", e); + } finally { + if (tempFile != null) { + try { + Files.delete(tempFile.toPath()); + } catch (IOException e) { + log.error("Error occured while deleting the temp file", e); + } + } + } + return apkMeta; + } + + public static NSDictionary readiOSManifestFile(InputStream inputStream) throws ParsingException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + NSDictionary rootDict; + File tempFile = null; + try { + tempFile = File.createTempFile("temp" + UUID.randomUUID(), ".ipa"); + try (FileOutputStream out = new FileOutputStream(tempFile)) { + IOUtils.copy(inputStream, out); + try (ZipInputStream stream = new ZipInputStream(new FileInputStream(tempFile))) { + ZipEntry entry; + while ((entry = stream.getNextEntry()) != null) { + if (entry.getName().matches("^(Payload/)(.)+(.app/Info.plist)$")) { + InputStream is = stream; + int nRead; + byte[] data = new byte[16384]; + + while ((nRead = is.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + buffer.flush(); + break; + } + } + try { + rootDict = (NSDictionary) BinaryPropertyListParser.parse(buffer.toByteArray()); + } catch (IllegalArgumentException e) { + log.debug("Uploaded file didn't have a Binary Plist"); + try { + rootDict = (NSDictionary) PropertyListParser.parse(buffer.toByteArray()); + } catch (Exception e1) { + throw new ParsingException("Error while parsing the non binary plist.", e1); + } + } + } + } + } catch (PropertyListFormatException e1) { + throw new ParsingException("Error while parsing the plist.", e1); + } catch (FileNotFoundException e) { + throw new ParsingException("Error while creating temporary file.", e); + } catch (IOException e) { + throw new ParsingException("Error while parsing the file.", e); + } finally { + if (tempFile != null) { + try { + Files.delete(tempFile.toPath()); + } catch (IOException e) { + log.error("Error occured while deleting the temp file", e); + } + } + } + return rootDict; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ConnectionManagerUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ConnectionManagerUtil.java new file mode 100644 index 0000000000..d8c0d66f3a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ConnectionManagerUtil.java @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; +import org.wso2.carbon.device.application.mgt.common.exception.IllegalTransactionStateException; +import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException; + +import java.sql.Connection; +import java.sql.SQLException; +import javax.naming.InitialContext; +import javax.sql.DataSource; + +/** + * ConnectionManagerUtil is responsible for handling all the datasource connections utilities. + */ +public class ConnectionManagerUtil { + + private static final Log log = LogFactory.getLog(ConnectionManagerUtil.class); + + private enum TxState { + CONNECTION_NOT_BORROWED, CONNECTION_BORROWED, CONNECTION_CLOSED + } + + private static final ThreadLocal currentConnection = new ThreadLocal<>(); + private static ThreadLocal currentTxState = new ThreadLocal<>(); + private static DataSource dataSource; + + public static void openDBConnection() throws DBConnectionException { + Connection conn = currentConnection.get(); + if (conn != null) { + throw new IllegalTransactionStateException("Database connection has already been obtained."); + } + try { + conn = dataSource.getConnection(); + } catch (SQLException e) { + throw new DBConnectionException("Failed to get a database connection.", e); + } + currentConnection.set(conn); + } + + public static Connection getDBConnection() throws DBConnectionException { + Connection conn = currentConnection.get(); + if (conn == null) { + try { + conn = dataSource.getConnection(); + currentConnection.set(conn); + } catch (SQLException e) { + throw new DBConnectionException("Failed to get database connection.", e); + } + } + return conn; + } + + public static void beginDBTransaction() throws TransactionManagementException, DBConnectionException { + Connection conn = currentConnection.get(); + if (conn == null) { + conn = getDBConnection(); + } else if (inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has already been started."); + } + + try { + conn.setAutoCommit(false); + } catch (SQLException e) { + throw new TransactionManagementException("Error occurred while starting a database transaction.", e); + } + } + + public static void endDBTransaction() throws TransactionManagementException, DBConnectionException { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.setAutoCommit(true); + } catch (SQLException e) { + throw new TransactionManagementException("Error occurred while ending database transaction.", e); + } + } + + public static void commitDBTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.commit(); + } catch (SQLException e) { + log.error("Error occurred while committing the transaction", e); + } + } + + public static void rollbackDBTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.rollback(); + } catch (SQLException e) { + log.warn("Error occurred while roll-backing the transaction", e); + } + } + + public static void closeDBConnection() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + try { + conn.close(); + } catch (SQLException e) { + log.error("Error occurred while closing the connection", e); + } + currentConnection.remove(); + } + + private static boolean inTransaction(Connection conn) { + boolean inTransaction = true; + try { + if (conn.getAutoCommit()) { + inTransaction = false; + } + } catch (SQLException e) { + throw new IllegalTransactionStateException("Failed to get transaction state."); + } + return inTransaction; + } + + public static boolean isTransactionStarted() throws DBConnectionException { + Connection connection = getDBConnection(); + return inTransaction(connection); + } + + @Deprecated + public static ThreadLocal getCurrentConnection() { + return currentConnection; + } + + @Deprecated + public static Connection openConnection() throws DBConnectionException { + Connection conn = currentConnection.get(); + if (conn != null) { + throw new IllegalTransactionStateException("A transaction is already active within the context of " + + "this particular thread. Therefore, calling 'beginTransaction/openConnection' while another " + + "transaction is already active is a sign of improper transaction handling"); + } + try { + conn = dataSource.getConnection(); + } catch (SQLException e) { + currentTxState.set(TxState.CONNECTION_NOT_BORROWED); + throw new DBConnectionException(e.getMessage(), e); + } + currentConnection.set(conn); + currentTxState.set(TxState.CONNECTION_BORROWED); + return conn; + } + + @Deprecated + public static Connection getConnection() throws DBConnectionException { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new DBConnectionException("No connection is associated with the current thread. " + + "This might have ideally been caused by not properly initiating the transaction via " + + "'beginTransaction'/'openConnection' methods"); + } + return conn; + } + + @Deprecated + public static void beginTransaction() throws TransactionManagementException, DBConnectionException { + Connection conn = currentConnection.get(); + if (conn != null) { + throw new IllegalTransactionStateException("A transaction is already active within the context of " + + "this particular thread. Therefore, calling 'beginTransaction/openConnection' while another " + + "transaction is already active is a sign of improper transaction handling"); + } + try { + conn = dataSource.getConnection(); + } catch (SQLException e) { + throw new DBConnectionException("Error occurred while retrieving a data source connection", e); + } + + try { + conn.setAutoCommit(false); + } catch (SQLException e) { + try { + conn.close(); + } catch (SQLException e1) { + log.warn("Error occurred while closing the borrowed connection. " + + "Transaction has ended pre-maturely", e1); + } + currentTxState.set(TxState.CONNECTION_CLOSED); + throw new TransactionManagementException("Error occurred while setting auto-commit to false", e); + } + currentConnection.set(conn); + currentTxState.set(TxState.CONNECTION_BORROWED); + } + + @Deprecated + public static void commitTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("No connection is associated with the current transaction. " + + "This might have ideally been caused by not properly initiating the transaction via " + + "'beginTransaction'/'openConnection' methods"); + } + try { + conn.commit(); + } catch (SQLException e) { + log.error("Error occurred while committing the transaction", e); + } + } + + @Deprecated + public static void rollbackTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("No connection is associated with the current transaction. " + + "This might have ideally been caused by not properly initiating the transaction via " + + "'beginTransaction'/'openConnection' methods"); + } + try { + conn.rollback(); + } catch (SQLException e) { + log.warn("Error occurred while roll-backing the transaction", e); + } + } + + @Deprecated + public static void closeConnection() { + if (currentTxState != null) { + TxState txState = currentTxState.get(); + + if (TxState.CONNECTION_NOT_BORROWED == txState) { + if (log.isDebugEnabled()) { + log.debug("No successful connection appears to have been borrowed to perform the underlying " + + "transaction even though the 'openConnection' method has been called. Therefore, " + + "'closeConnection' method is returning silently"); + } + currentTxState.remove(); + return; + } + + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("No connection is associated with the current transaction. " + + "This might have ideally been caused by not properly initiating the transaction via " + + "'beginTransaction'/'openConnection' methods"); + } + try { + conn.close(); + } catch (SQLException e) { + log.warn("Error occurred while close the connection", e); + } + currentConnection.remove(); + currentTxState.remove(); + } + } + + /** + * Resolve the datasource from the datasource definition. + * + * @param dataSourceName Name of the datasource + * @return DataSource resolved by the datasource name + */ + public static DataSource resolveDataSource(String dataSourceName) { + try { + dataSource = InitialContext.doLookup(dataSourceName); + } catch (Exception e) { + throw new RuntimeException("Error in looking up data source: " + e.getMessage(), e); + } + return dataSource; + } + + + public static String getDatabaseType() { + try { + return dataSource.getConnection().getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + log.error("Error occurred while retrieving config.datasource connection", e); + } + return null; + } + + /** + * To check whether particular database that is used for application management supports batch query execution. + * + * @return true if batch query is supported, otherwise false. + */ + public static boolean isBatchQuerySupported() { + try { + return dataSource.getConnection().getMetaData().supportsBatchUpdates(); + } catch (SQLException e) { + log.error("Error occurred while checking whether database supports batch updates", e); + } + return false; + } + + + public static void init(DataSource dtSource) { + dataSource = dtSource; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java new file mode 100644 index 0000000000..0f58452f54 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.util; + +import org.wso2.carbon.utils.CarbonUtils; + +import java.io.File; + +/** + * Application Management related constants. + */ +public class Constants { + + public static final String APPLICATION_CONFIG_XML_FILE = "application-mgt.xml"; + + public static final String DEFAULT_CONFIG_FILE_LOCATION = CarbonUtils.getCarbonConfigDirPath() + File.separator + + Constants.APPLICATION_CONFIG_XML_FILE; + public static final String DEFAULT_VERSION = "1.0.0"; + public static final String PAYLOAD = "Payload"; + public static final String PLIST_NAME = "Info.plist"; + public static final String CF_BUNDLE_VERSION = "CFBundleVersion"; + public static final String APP_EXTENSION = ".app"; + public static final String IOT_HOST_PROPERTY = "iot.core.host"; + public static final String IOT_HTTP_PORT_PROPERTY = "iot.core.http.port"; + public static final String IOT_HTTPS_PORT_PROPERTY = "iot.core.https.port"; + public static final String HTTPS_PROTOCOL = "https"; + public static final String HTTP_PROTOCOL = "http"; + + public static final String FORWARD_SLASH = "/"; + public static final String ANY = "ANY"; + public static final String DEFAULT_PCK_NAME = "default.app.com"; + + public static final String GOOGLE_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id="; + public static final String APPLE_STORE_URL = "https://itunes.apple.com/country/app/app-name/id"; + + // Subscription task related constants + public static final String SUBSCRIBERS = "SUBSCRIBERS"; + public static final String SUB_TYPE = "SUBSCRIPTION_TYPE"; + public static final String ACTION = "ACTION"; + public static final String APP_UUID = "APP_UUID"; + public static final String SUBSCRIBER = "SUBSCRIBER"; + public static final String TENANT_DOMAIN = "TENANT_DOMAIN"; + public static final String TENANT_ID = "__TENANT_ID_PROP__"; + public static final String TASK_NAME = "TASK_NAME"; + public static final String SUBSCRIBED = "SUBSCRIBED"; + public static final String UNSUBSCRIBED = "UNSUBSCRIBED"; + + + /** + * Database types supported by Application Management. + */ + public static final class DataBaseTypes { + private DataBaseTypes() { + } + public static final String DB_TYPE_MYSQL = "MySQL"; + public static final String DB_TYPE_ORACLE = "Oracle"; + public static final String DB_TYPE_MSSQL = "Microsoft SQL Server"; + public static final String DB_TYPE_DB2 = "DB2"; + public static final String DB_TYPE_H2 = "H2"; + public static final String DB_TYPE_POSTGRESQL = "PostgreSQL"; + } + + /** + * Directory name of the icon artifact that are saved in the file system. + */ + public static final String ICON_ARTIFACT = "icon"; + + /** + * Directory name of the banner artifact that are saved in the file system. + */ + public static final String BANNER_ARTIFACT = "banner"; + + /** + * Common directory name of the screenshot artifact that are saved in the file system. + */ + public static final String SCREENSHOT_ARTIFACT = "screenshot"; + + /** + * Naming directory name of the application artifact that are saved in the file system. + */ + public static final String APP_ARTIFACT = "app"; + + public static final int REVIEW_PARENT_ID = -1; + + public static final int MAX_RATING = 5; + + public final class ApplicationInstall { + private ApplicationInstall() { + throw new AssertionError(); + } + + public static final String APPLICATION_NAME = "device_type_android"; + public static final String ENROLLMENT_APP_INSTALL_FEATURE_CODE = "ENROLLMENT_APP_INSTALL"; + public static final String DEFAULT_TOKEN_TYPE = "PRODUCTION"; + public static final String DEFAULT_VALIDITY_PERIOD = "3600"; + public static final String SUBSCRIPTION_SCOPE = "appm:subscribe"; + public static final String ENROLLMENT_APP_INSTALL_UUID = "uuid"; + public static final String GOOGLE_POLICY_PAYLOAD = "installGooglePolicyPayload"; + public static final String ENROLLMENT_APP_INSTALL_CODE = "enrollmentAppInstall"; + public static final String ENCODING = "UTF-8"; + public static final String AT = "@"; + public static final String DEVICE_TYPE_ANDROID = "android"; + public static final String COLON = ":"; + public static final String IOT_CORE_HOST = "iot.core.host"; + public static final String IOT_CORE_PORT = "iot.core.https.port"; + public static final String ENROLLMENT_APP_INSTALL_PROTOCOL = "https://"; + public static final String GOOGLE_APP_INSTALL_URL = "/api/device-mgt/android/v1.0/enterprise/change-app"; + + public static final String AUTHORIZATION = "Authorization"; + public static final String AUTHORIZATION_HEADER_VALUE = "Bearer "; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java new file mode 100644 index 0000000000..5ca4370f97 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.util; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONException; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.ExecutionStatus; +import org.wso2.carbon.device.application.mgt.common.SubscriptionType; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; + +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.dto.DeviceSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * This class is responsible for handling the utils of the Application Management DAO. + */ +public class DAOUtil { + + private static final Log log = LogFactory.getLog(DAOUtil.class); + + /** + * To create application object from the result set retrieved from the Database. + * + * @param rs ResultSet + * @return List of Applications that is retrieved from the Database. + * @throws SQLException SQL Exception + * @throws JSONException JSONException. + */ + public static List loadApplications(ResultSet rs) throws SQLException, JSONException { + + List applications = new ArrayList<>(); + ApplicationDTO application = null; + int applicationId = -1; + boolean hasNext = rs.next(); + + while (hasNext) { + if (applicationId != rs.getInt("APP_ID")) { + if (application != null) { + applications.add(application); + } + application = new ApplicationDTO(); + application.setApplicationReleaseDTOs(new ArrayList<>()); + applicationId = rs.getInt("APP_ID"); + application.setId(applicationId); + application.setName(rs.getString("APP_NAME")); + application.setDescription(rs.getString("APP_DESCRIPTION")); + application.setType(rs.getString("APP_TYPE")); + application.setSubType(rs.getString("APP_SUB_TYPE")); + application.setPaymentCurrency(rs.getString("APP_CURRENCY")); + application.setStatus(rs.getString("APP_STATUS")); + application.setAppRating(rs.getDouble("APP_RATING")); + application.setDeviceTypeId(rs.getInt("APP_DEVICE_TYPE_ID")); + application.setPackageName(rs.getString("PACKAGE_NAME")); + application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs)); + } else { + if (application != null && application.getApplicationReleaseDTOs() != null) { + application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs)); + } + } + hasNext = rs.next(); + if (!hasNext) { + applications.add(application); + } + } + return applications; + } + + /** + * To create list of device subscription objects from the result set retrieved from the Database. + * + * @param rs ResultSet + * @return List of device subscriptions that is retrieved from the Database. + * @throws SQLException SQL Exception + * @throws JSONException JSONException. + */ + public static List loadDeviceSubscriptions(ResultSet rs) throws SQLException { + List deviceSubscriptionDTOS = new ArrayList<>(); + while (rs.next()) { + deviceSubscriptionDTOS.add(constructDeviceSubscriptionDTO(rs)); + } + return deviceSubscriptionDTOS; + } + + public static DeviceSubscriptionDTO constructDeviceSubscriptionDTO(ResultSet rs ) throws SQLException { + DeviceSubscriptionDTO deviceSubscriptionDTO = new DeviceSubscriptionDTO(); + deviceSubscriptionDTO.setId(rs.getInt("ID")); + deviceSubscriptionDTO.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + deviceSubscriptionDTO.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT")); + deviceSubscriptionDTO.setUnsubscribed(rs.getBoolean("IS_UNSUBSCRIBED")); + deviceSubscriptionDTO.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + deviceSubscriptionDTO.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_AT")); + deviceSubscriptionDTO.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM")); + deviceSubscriptionDTO.setDeviceId(rs.getInt("DEVICE_ID")); + deviceSubscriptionDTO.setStatus(rs.getString("STATUS")); + return deviceSubscriptionDTO; + } + + /** + * Populates {@link ApplicationReleaseDTO} object with the result obtained from the database. + * + * @param rs {@link ResultSet} from obtained from the database + * @return {@link ApplicationReleaseDTO} object populated with the data + * @throws SQLException If unable to populate {@link ApplicationReleaseDTO} object with the data + */ + public static ApplicationReleaseDTO constructAppReleaseDTO(ResultSet rs) throws SQLException { + ApplicationReleaseDTO appRelease = new ApplicationReleaseDTO(); + appRelease.setId(rs.getInt("RELEASE_ID")); + appRelease.setDescription(rs.getString("RELEASE_DESCRIPTION")); + appRelease.setUuid(rs.getString("RELEASE_UUID")); + appRelease.setReleaseType(rs.getString("RELEASE_TYPE")); + appRelease.setVersion(rs.getString("RELEASE_VERSION")); + appRelease.setInstallerName(rs.getString("AP_RELEASE_STORED_LOC")); + appRelease.setIconName(rs.getString("AP_RELEASE_ICON_LOC")); + appRelease.setBannerName(rs.getString("AP_RELEASE_BANNER_LOC")); + appRelease.setScreenshotName1(rs.getString("AP_RELEASE_SC1")); + appRelease.setScreenshotName2(rs.getString("AP_RELEASE_SC2")); + appRelease.setScreenshotName3(rs.getString("AP_RELEASE_SC3")); + appRelease.setAppHashValue(rs.getString("RELEASE_HASH_VALUE")); + appRelease.setPrice(rs.getDouble("RELEASE_PRICE")); + appRelease.setMetaData(rs.getString("RELEASE_META_INFO")); + appRelease.setPackageName(rs.getString("PACKAGE_NAME")); + appRelease.setSupportedOsVersions(rs.getString("RELEASE_SUP_OS_VERSIONS")); + appRelease.setRating(rs.getDouble("RELEASE_RATING")); + appRelease.setCurrentState(rs.getString("RELEASE_CURRENT_STATE")); + appRelease.setRatedUsers(rs.getInt("RATED_USER_COUNT")); + return appRelease; + } + + + /** + * To create application object from the result set retrieved from the Database. + * + * @param rs ResultSet + * @return ApplicationDTO that is retrieved from the Database. + * @throws SQLException SQL Exception + * @throws JSONException JSONException. + */ + public static ApplicationDTO loadApplication(ResultSet rs) + throws SQLException, JSONException, UnexpectedServerErrorException { + List applicationDTOs = loadApplications(rs); + if (applicationDTOs.isEmpty()) { + return null; + } + if (applicationDTOs.size() > 1) { + String msg = "Internal server error. Found more than one application for requested application ID"; + log.error(msg); + throw new UnexpectedServerErrorException(msg); + } + return applicationDTOs.get(0); + } + + /** + * Populates {@link ApplicationReleaseDTO} object with the result obtained from the database. + * + * @param resultSet {@link ResultSet} from obtained from the database + * @return {@link ApplicationReleaseDTO} object populated with the data + * @throws SQLException If unable to populate {@link ApplicationReleaseDTO} object with the data + */ + public static ApplicationReleaseDTO loadApplicationRelease(ResultSet resultSet) throws SQLException { + ApplicationReleaseDTO applicationRelease = new ApplicationReleaseDTO(); + applicationRelease.setId(resultSet.getInt("RELEASE_ID")); + applicationRelease.setVersion(resultSet.getString("RELEASE_VERSION")); + applicationRelease.setUuid(resultSet.getString("UUID")); + applicationRelease.setReleaseType(resultSet.getString("RELEASE_TYPE")); + applicationRelease.setPackageName(resultSet.getString("PACKAGE_NAME")); + applicationRelease.setPrice(resultSet.getDouble("APP_PRICE")); + applicationRelease.setInstallerName(resultSet.getString("STORED_LOCATION")); + applicationRelease.setBannerName(resultSet.getString("BANNER_LOCATION")); + applicationRelease.setIconName(resultSet.getString("ICON_LOCATION")); + applicationRelease.setScreenshotName1(resultSet.getString("SCREEN_SHOT_1")); + applicationRelease.setScreenshotName2(resultSet.getString("SCREEN_SHOT_2")); + applicationRelease.setScreenshotName3(resultSet.getString("SCREEN_SHOT_3")); + applicationRelease.setAppHashValue(resultSet.getString("HASH_VALUE")); + applicationRelease.setIsSharedWithAllTenants(resultSet.getBoolean("SHARED")); + applicationRelease.setMetaData(resultSet.getString("APP_META_INFO")); + applicationRelease.setRating(resultSet.getDouble("RATING")); + return applicationRelease; + } + + public static ReviewDTO loadReview(ResultSet rs) throws SQLException, UnexpectedServerErrorException { + List reviewDTOs = loadReviews(rs); + if (reviewDTOs.isEmpty()) { + return null; + } + if (reviewDTOs.size() > 1) { + String msg = "Internal server error. Found more than one review for requested review ID"; + log.error(msg); + throw new UnexpectedServerErrorException(msg); + } + return reviewDTOs.get(0); + } + + public static List loadReviews (ResultSet rs) throws SQLException { + List reviewDTOs = new ArrayList<>(); + while (rs.next()) { + ReviewDTO reviewDTO = new ReviewDTO(); + reviewDTO.setId(rs.getInt("ID")); + reviewDTO.setContent(rs.getString("COMMENT")); + reviewDTO.setCreatedAt(rs.getTimestamp("CREATED_AT")); + reviewDTO.setModifiedAt(rs.getTimestamp("MODIFIED_AT")); + reviewDTO.setRootParentId(rs.getInt("ROOT_PARENT_ID")); + reviewDTO.setImmediateParentId(rs.getInt("IMMEDIATE_PARENT_ID")); + reviewDTO.setUsername(rs.getString("USERNAME")); + reviewDTO.setRating(rs.getInt("RATING")); + reviewDTO.setReleaseUuid(rs.getString("UUID")); + reviewDTO.setReleaseVersion(rs.getString("VERSION")); + reviewDTOs.add(reviewDTO); + } + return reviewDTOs; + } + + public static ScheduledSubscriptionDTO loadScheduledSubscription(ResultSet rs) + throws SQLException, UnexpectedServerErrorException { + List subscriptionDTOs = loadScheduledSubscriptions(rs); + + if (subscriptionDTOs.isEmpty()) { + return null; + } + if (subscriptionDTOs.size() > 1) { + String msg = "Internal server error. Found more than one subscription for requested pending subscription"; + log.error(msg); + throw new UnexpectedServerErrorException(msg); + } + return subscriptionDTOs.get(0); + } + + public static List loadScheduledSubscriptions(ResultSet rs) throws SQLException { + List subscriptionDTOS = new ArrayList<>(); + while (rs.next()) { + ScheduledSubscriptionDTO subscription = new ScheduledSubscriptionDTO(); + subscription.setId(rs.getInt("ID")); + subscription.setTaskName(rs.getString("TASK_NAME")); + subscription.setApplicationUUID(rs.getString("APPLICATION_UUID")); + + if (subscription.getTaskName().startsWith(SubscriptionType.DEVICE.toString())) { + List deviceIdentifiers = new Gson().fromJson(rs.getString("SUBSCRIBER_LIST"), + new TypeToken>() { + }.getType()); + subscription.setSubscriberList(deviceIdentifiers); + } else { + List subscriberList = Pattern.compile(",").splitAsStream(rs.getString("SUBSCRIBER_LIST")) + .collect(Collectors.toList()); + subscription.setSubscriberList(subscriberList); + } + + subscription.setStatus(ExecutionStatus.valueOf(rs.getString("STATUS"))); + subscription.setScheduledAt(rs.getTimestamp("SCHEDULED_AT").toLocalDateTime()); + subscription.setScheduledBy(rs.getString("SCHEDULED_BY")); + subscription.setDeleted(rs.getBoolean("DELETED")); + subscriptionDTOS.add(subscription); + } + return subscriptionDTOS; + } + + /** + * Cleans up the statement and resultset after executing the query + * + * @param stmt Statement executed. + * @param rs Resultset retrived. + */ + public static void cleanupResources(PreparedStatement stmt, ResultSet rs) { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing result set", e); + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing prepared statement", e); + } + } + } + + private static ApplicationManager applicationManager; + private static ApplicationStorageManager applicationStorageManager; + private static SubscriptionManager subscriptionManager; + + public static ApplicationManager getApplicationManager() { + if (applicationManager == null) { + synchronized (DAOUtil.class) { + if (applicationManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + applicationManager = + (ApplicationManager) ctx.getOSGiService(ApplicationManager.class, null); + if (applicationManager == null) { + String msg = "ApplicationDTO Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return applicationManager; + } + + /** + * To get the ApplicationDTO Storage Manager from the osgi context. + * @return ApplicationStoreManager instance in the current osgi context. + */ + public static ApplicationStorageManager getApplicationStorageManager() { + + try { + if (applicationStorageManager == null) { + synchronized (DAOUtil.class) { + if (applicationStorageManager == null) { + applicationStorageManager = ApplicationManagementUtil + .getApplicationStorageManagerInstance(); + if (applicationStorageManager == null) { + String msg = "ApplicationDTO Storage Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + } catch (Exception e) { + String msg = "Error occurred while getting the application store manager"; + log.error(msg); + throw new IllegalStateException(msg); + } + return applicationStorageManager; + } + + + /** + * 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 (DAOUtil.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; + } + + public static DeviceManagementProviderService getDeviceManagementService() { +// PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); +// DeviceManagementProviderService deviceManagementProviderService = +// (DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null); +// if (deviceManagementProviderService == null) { +// String msg = "DeviceImpl Management provider service has not initialized."; +// log.error(msg); +// throw new IllegalStateException(msg); +// } + // return deviceManagementProviderService; + + return new DeviceManagementProviderServiceImpl(); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/HelperUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/HelperUtil.java new file mode 100644 index 0000000000..d748dc25ea --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/HelperUtil.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; + +import java.util.List; +import java.util.UUID; + +/** + * Utility methods used in the Application Management. + */ +public class HelperUtil { + + private static Log log = LogFactory.getLog(HelperUtil.class); + + private static DeviceManagementProviderService deviceManagementProviderService; + private static GroupManagementProviderService groupManagementProviderService; + + public static String generateApplicationUuid() { + return UUID.randomUUID().toString(); + } + + public static DeviceManagementProviderService getDeviceManagementProviderService() { + if (deviceManagementProviderService == null) { + synchronized (HelperUtil.class) { + if (deviceManagementProviderService == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + deviceManagementProviderService = (DeviceManagementProviderService) ctx + .getOSGiService(DeviceManagementProviderService.class, null); + if (deviceManagementProviderService == null) { + String msg = "Device management provider service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return deviceManagementProviderService; + } + + public static GroupManagementProviderService getGroupManagementProviderService() { + if (groupManagementProviderService == null) { + synchronized (HelperUtil.class) { + if (groupManagementProviderService == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + groupManagementProviderService = (GroupManagementProviderService) ctx + .getOSGiService(GroupManagementProviderService.class, null); + if (groupManagementProviderService == null) { + String msg = "Group management provider service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return groupManagementProviderService; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/JSONUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/JSONUtil.java new file mode 100644 index 0000000000..34fedf190e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/JSONUtil.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.util; + +import org.json.JSONArray; +import org.json.JSONException; + +import java.util.ArrayList; +import java.util.List; + +/** + * This utility class handles the JSON manipulation related tasks. + */ +public class JSONUtil { + + public static List jsonArrayStringToList(String value) throws JSONException { + JSONArray jsonArray = new JSONArray(value); + List list = new ArrayList<>(); + int len = jsonArray.length(); + for (int i = 0; i < len; i++) { + list.add(jsonArray.get(i).toString()); + } + return list; + } + + public static String listToJsonArrayString(List list) { + JSONArray jsonArray = new JSONArray(); + if (list != null) { + for (String listItem : list) { + jsonArray.put(listItem); + } + } + return jsonArray.toString(); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/MDMAppConstants.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/MDMAppConstants.java new file mode 100644 index 0000000000..0892f0909d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/MDMAppConstants.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.util; + +public class MDMAppConstants { + public static final String USER = "user"; + public static final String ROLE = "role"; + public static final String IOS = "ios"; + public static final String ANDROID = "android"; + public static final String WEBAPP = "webapp"; + public static final String INSTALL = "install"; + public static final String UPDATE = "update"; + public static final String ACTIVE = "active"; + public static final String ENTERPRISE = "enterprise"; + public static final String DEVICE = "device"; + public static final String MOBILE_DEVICE = "mobileDevice"; + public static final String NEXUS = "nexus"; + public static final String IPHONE = "iphone"; + public static final String NONE = "none"; + public static final String IMAGE_URL = "ImageURL"; + public static final String TYPE = "type"; + public static final String ID = "id"; + + public class IOSConstants { + + private IOSConstants() { + throw new AssertionError(); + } + + public static final String IS_REMOVE_APP = "isRemoveApp"; + public static final String IS_PREVENT_BACKUP = "isPreventBackup"; + public static final String I_TUNES_ID = "iTunesId"; + public static final String LABEL = "label"; + public static final String PUBLIC = "public"; + public static final String OPCODE_INSTALL_ENTERPRISE_APPLICATION = + "INSTALL_ENTERPRISE_APPLICATION"; + public static final String OPCODE_INSTALL_STORE_APPLICATION = "INSTALL_STORE_APPLICATION"; + public static final String OPCODE_INSTALL_WEB_APPLICATION = "WEB_CLIP"; + public static final String OPCODE_REMOVE_APPLICATION = "REMOVE_APPLICATION"; + } + + public class AndroidConstants { + private AndroidConstants() { + throw new AssertionError(); + } + + public static final String OPCODE_INSTALL_APPLICATION = "INSTALL_APPLICATION"; + public static final String OPCODE_UPDATE_APPLICATION = "UPDATE_APPLICATION"; + public static final String OPCODE_UNINSTALL_APPLICATION = "UNINSTALL_APPLICATION"; + } + + public class RegistryConstants { + private RegistryConstants() { + throw new AssertionError(); + } + + public static final String GENERAL_CONFIG_RESOURCE_PATH = "general"; + } + + public class APPManagerConstants { + private static final String APP_MANAGER_MDM_SERVICE_NAME = + "org.wso2.carbon.appmgt.mobile.interfaces.MDMOperations"; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/OAuthUtils.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/OAuthUtils.java new file mode 100644 index 0000000000..b57ffebeb7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/OAuthUtils.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; +import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; +import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.dto.ApiRegistrationProfile; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; + +public class OAuthUtils { + + private static final Log log = LogFactory.getLog(OAuthUtils.class); + + public static ApiApplicationKey getClientCredentials(String tenantDomain) + throws UserStoreException, APIManagerException { + ApiRegistrationProfile registrationProfile = new ApiRegistrationProfile(); + registrationProfile.setApplicationName(Constants.ApplicationInstall.APPLICATION_NAME); + registrationProfile.setTags(new String[]{Constants.ApplicationInstall.DEVICE_TYPE_ANDROID}); + registrationProfile.setAllowedToAllDomains(false); + registrationProfile.setMappingAnExistingOAuthApp(false); + return getCredentials(registrationProfile, tenantDomain); + } + + public static ApiApplicationKey getCredentials(ApiRegistrationProfile registrationProfile, String tenantDomain) + throws UserStoreException, APIManagerException { + ApiApplicationKey apiApplicationKeyInfo; + if (tenantDomain == null || tenantDomain.isEmpty()) { + tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; + } + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(PrivilegedCarbonContext. + getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration().getAdminUserName()); + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + APIManagementProviderService apiManagementProviderService = (APIManagementProviderService) ctx. + getOSGiService(APIManagementProviderService.class, null); + apiApplicationKeyInfo = apiManagementProviderService. + generateAndRetrieveApplicationKeys(registrationProfile.getApplicationName(), + registrationProfile.getTags(), Constants.ApplicationInstall.DEFAULT_TOKEN_TYPE, + registrationProfile.getApplicationName(), registrationProfile.isAllowedToAllDomains(), + Constants.ApplicationInstall.DEFAULT_VALIDITY_PERIOD); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + return apiApplicationKeyInfo; + } + + public static AccessTokenInfo getOAuthCredentials(ApiApplicationKey apiApplicationKey, String username) + throws APIManagerException { + try { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + JWTClientManagerService jwtClientManagerService = (JWTClientManagerService) ctx. + getOSGiService(JWTClientManagerService.class, null); + JWTClient jwtClient = jwtClientManagerService.getJWTClient(); + return jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(), apiApplicationKey.getConsumerSecret(), + username, Constants.ApplicationInstall.SUBSCRIPTION_SCOPE); + } catch (JWTClientException e) { + String errorMsg = "Error while generating an OAuth token for user " + username; + log.error(errorMsg, e); + throw new APIManagerException(errorMsg, e); + } + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/StorageManagementUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/StorageManagementUtil.java new file mode 100644 index 0000000000..97b36aba28 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/StorageManagementUtil.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.ImageArtifact; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagementException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; + +/** + * This is a util class that handles Storage Management related tasks. + */ +public class StorageManagementUtil { + + private static Log log = LogFactory.getLog(StorageManagementUtil.class); + + /** + * This method is responsible for creating artifact parent directories in the given path. + * + * @param artifactDirectoryPath Path for the artifact directory. + * @throws ResourceManagementException Resource Management Exception. + */ + public static void createArtifactDirectory(String artifactDirectoryPath) throws ResourceManagementException { + File artifactDirectory = new File(artifactDirectoryPath); + + if (!artifactDirectory.exists() && !artifactDirectory.mkdirs()) { + throw new ResourceManagementException( + "Cannot create directories in the path to save the application related artifacts"); + } + } + + /** + * To delete a directory recursively + * + * @param artifactDirectory Artifact Directory that need to be deleted. + */ + public static void delete(File artifactDirectory) throws IOException { + File[] contents = artifactDirectory.listFiles(); + if (contents != null) { + for (File file : contents) { + delete(file); + } + } + Files.delete(artifactDirectory.toPath()); + } + + public static void copy(String source, String destination) throws IOException { + File sourceFile = new File(source); + File destinationFile = new File(destination); + if (sourceFile.exists() && destinationFile.exists()) { + Files.copy(sourceFile.toPath(), destinationFile.toPath()); + } else { + String msg = "Source file " + source + " or destination file " + destination + " doesn't exist"; + log.error(msg); + throw new IOException(msg); + } + } + + /** + * To save a file in a given location. + * + * @param inputStream Stream of the file. + * @param path Path the file need to be saved in. + */ + public static void saveFile(InputStream inputStream, String path) throws IOException { + try (OutputStream outStream = new FileOutputStream(new File(path))) { + byte[] buffer = new byte[inputStream.available()]; + if (inputStream.read(buffer) != -1) { + outStream.write(buffer); + } + } finally { + inputStream.close(); + } + } + + /** + * To create {@link ImageArtifact}. + * + * @param imageFile Image File. + * @param imageArtifactPath Path of the image artifact file. + * @return Image Artifact. + * @throws IOException IO Exception. + */ + public static ImageArtifact createImageArtifact(File imageFile, String imageArtifactPath) throws IOException { + ImageArtifact imageArtifact = new ImageArtifact(); + imageArtifact.setName(imageFile.getName()); + imageArtifact.setType(Files.probeContentType(imageFile.toPath())); + byte[] imageBytes = IOUtils.toByteArray(new FileInputStream(imageArtifactPath)); + imageArtifact.setEncodedImage(Base64.encodeBase64URLSafeString(imageBytes)); + return imageArtifact; + } + + /*** + * Get the fine input stream + * @param filePath File path + * @return {@link InputStream} + * @throws IOException throws if error occured when reading file or if couldn't find a file in the filePath + */ + public static InputStream getInputStream (String filePath) throws IOException { + File sourceFile = new File(filePath); + if (!sourceFile.exists()){ + return null; + } + try { + return new FileInputStream(sourceFile); + } catch (FileNotFoundException e) { + String msg = "Couldn't file the file in file path: " + filePath; + log.error(msg, e); + throw new IOException(msg, e); + } + } + + public static String getMD5(InputStream binaryFile) throws ApplicationStorageManagementException { + String md5; + try { + md5 = DigestUtils.md5Hex(binaryFile); + } catch (IOException e) { + String msg = "IO Exception occurred while trying to get the md5sum value of application"; + log.error(msg, e); + throw new ApplicationStorageManagementException(msg, e); + } + return md5; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/resources/META-INF/component.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/resources/META-INF/component.xml new file mode 100644 index 0000000000..2f5770f0bf --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/resources/META-INF/component.xml @@ -0,0 +1,40 @@ + + + + + platforms + xml + org.wso2.carbon.device.application.mgt.core.deployer.PlatformDeployer + + + + + Application + /permission/admin/manage/device-mgt/application + + + Create + /permission/admin/manage/device-mgt/application/create + + + Review + /permission/admin/manage/device-mgt/application/review + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/ArtifactParserTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/ArtifactParserTest.java new file mode 100644 index 0000000000..f252a882b1 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/ArtifactParserTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core; + +import com.dd.plist.NSDictionary; +import net.dongliu.apk.parser.bean.ApkMeta; +import org.testng.Assert; +import org.testng.annotations.Test; +import org.wso2.carbon.device.application.mgt.core.exception.ParsingException; +import org.wso2.carbon.device.application.mgt.core.util.ArtifactsParser; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +public class ArtifactParserTest { + private static final String APK_FILE = "src/test/resources/util/app-debug.apk"; + private static final String APK_FILE_INVALID = "src/test/resources/util/app-debug1.apk"; + private static final String IPA_FILE = "src/test/resources/util/iOSMDMAgent.ipa"; + private static final String IPA_FILE_INVALID = "src/test/resources/util/iOSMDMAgent1.ipa"; + + @Test + public void testReadAndroidManifestFile() throws FileNotFoundException, ParsingException { + InputStream apk = new FileInputStream(APK_FILE); + ApkMeta apkMeta = ArtifactsParser.readAndroidManifestFile(apk); + Assert.assertEquals(apkMeta.getVersionName(), "1.0", "APK version name extraction failed."); + Assert.assertEquals(apkMeta.getPackageName(), "com.games.inosh.myapplication", + "APK package name extraction failed."); + } + + @Test(expectedExceptions = java.io.FileNotFoundException.class) + public void testReadAndroidManifestInvalidFile() throws FileNotFoundException, ParsingException { + InputStream apk = new FileInputStream(APK_FILE_INVALID); + ArtifactsParser.readAndroidManifestFile(apk); + } + + @Test + public void testReadiOSManifestFile() throws FileNotFoundException, ParsingException { + InputStream ipa = new FileInputStream(IPA_FILE); + NSDictionary ipaDictionary = ArtifactsParser.readiOSManifestFile(ipa); + Assert.assertEquals(ipaDictionary.objectForKey(ArtifactsParser.IPA_BUNDLE_IDENTIFIER_KEY).toString(), + "org.wso2.carbon.emm.ios.agent.inosh", "IPA bundle ID extraction failed."); + Assert.assertEquals(ipaDictionary.objectForKey(ArtifactsParser.IPA_BUNDLE_VERSION_KEY).toString(), + "GA", "IPA file version name extraction failed."); + } + + @Test(expectedExceptions = java.io.FileNotFoundException.class) + public void testReadiOSManifestInvalidFile() throws FileNotFoundException, ParsingException { + InputStream ipa = new FileInputStream(IPA_FILE_INVALID); + ArtifactsParser.readiOSManifestFile(ipa); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/BaseTestCase.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/BaseTestCase.java new file mode 100644 index 0000000000..c757724712 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/BaseTestCase.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tomcat.jdbc.pool.PoolProperties; +import org.testng.annotations.BeforeSuite; +import org.w3c.dom.Document; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.core.common.DataSourceConfig; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.core.util.ApplicationManagementUtil; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; +import org.wso2.carbon.device.mgt.core.authorization.DeviceAccessAuthorizationServiceImpl; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; +import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderServiceImpl; +import org.wso2.carbon.registry.core.config.RegistryContext; +import org.wso2.carbon.registry.core.exceptions.RegistryException; +import org.wso2.carbon.registry.core.internal.RegistryDataHolder; +import org.wso2.carbon.registry.core.jdbc.realm.InMemoryRealmService; +import org.wso2.carbon.registry.core.service.RegistryService; +import org.wso2.carbon.user.core.service.RealmService; + +import javax.sql.DataSource; +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.io.InputStream; +import java.sql.Connection; +import java.sql.Statement; +import java.util.List; + +public abstract class BaseTestCase { + + private DataSource dataSource; + private static final Log log = LogFactory.getLog(BaseTestCase.class); + + + @BeforeSuite + public void setupDataSource() throws Exception { + log.debug("Setting up the databases and initializing the privilege carbon context...................."); + this.initDatSource(); + this.initSQLScript(); + this.initiatePrivilegedCaronContext(); + DeviceConfigurationManager.getInstance().initConfig(); + + DeviceManagementDataHolder.getInstance().setRegistryService(getRegistryService()); + + LifecycleStateManager lifecycleStateManager = ApplicationManagementUtil.getLifecycleStateMangerInstance(); + DataHolder.getInstance().setLifecycleStateManger(lifecycleStateManager); + + List lifecycleStates = ConfigurationManager.getInstance(). + getConfiguration().getLifecycleStates(); + lifecycleStateManager.init(lifecycleStates); + } + + + protected void initializeServices() throws Exception { + log.debug("Calling initializing Services....................."); + initDatSource(); + initSQLScript(); + + } + + + public void initDatSource() throws Exception { + this.dataSource = this.getDataSource(this.readDataSourceConfig()); + ApplicationManagementDAOFactory.init(dataSource); + ConnectionManagerUtil.init(dataSource); + DeviceManagementDAOFactory.init(dataSource); +// PolicyManagementDAOFactory.init(dataSource); +// OperationManagementDAOFactory.init(dataSource); +// GroupManagementDAOFactory.init(dataSource); + } + + private DataSource getDataSource(DataSourceConfig config) { + PoolProperties properties = new PoolProperties(); + properties.setUrl(config.getUrl()); + properties.setDriverClassName(config.getDriverClassName()); + properties.setUsername(config.getUser()); + properties.setPassword(config.getPassword()); + return new org.apache.tomcat.jdbc.pool.DataSource(properties); + } + + private DataSourceConfig readDataSourceConfig() throws ApplicationManagementException { + try { + File file = new File("src/test/resources/datasource/data-source-config.xml"); + Document doc = this.convertToDocument(file); + JAXBContext testDBContext = JAXBContext.newInstance(DataSourceConfig.class); + Unmarshaller unmarshaller = testDBContext.createUnmarshaller(); + return (DataSourceConfig) unmarshaller.unmarshal(doc); + } catch (JAXBException e) { + throw new ApplicationManagementException("Error occurred while reading data source configuration", e); + } + } + + protected void initSQLScript() throws Exception { + Connection conn = null; + Statement stmt = null; + try { + conn = this.getDataSource().getConnection(); + stmt = conn.createStatement(); + stmt.executeUpdate("RUNSCRIPT FROM '../../../features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql'"); + stmt.executeUpdate("RUNSCRIPT FROM '../../../features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql'"); + + } finally { + TestUtils.cleanupResources(conn, stmt, null); + } + } + + public static Document convertToDocument(File file) throws ApplicationManagementException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + try { + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + DocumentBuilder docBuilder = factory.newDocumentBuilder(); + return docBuilder.parse(file); + } catch (Exception e) { + throw new ApplicationManagementException("Error occurred while parsing file, while converting " + + "to a org.w3c.dom.Document : " + e.getMessage(), e); + } + } + + + public void initiatePrivilegedCaronContext() throws Exception { + + + if (System.getProperty("carbon.home") == null) { + File file = new File("src/test/resources/carbon-home"); + if (file.exists()) { + System.setProperty("carbon.home", file.getAbsolutePath()); + } + file = new File("../resources/carbon-home"); + if (file.exists()) { + System.setProperty("carbon.home", file.getAbsolutePath()); + } + file = new File("../../resources/carbon-home"); + if (file.exists()) { + System.setProperty("carbon.home", file.getAbsolutePath()); + } + file = new File("../../../resources/carbon-home"); + if (file.exists()) { + System.setProperty("carbon.home", file.getAbsolutePath()); + } + } + + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(MultitenantConstants + .SUPER_TENANT_DOMAIN_NAME); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID); + + PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername("admin"); + + + } + + public DataSource getDataSource() { + return dataSource; + } + + protected RegistryService getRegistryService() throws RegistryException { + RealmService realmService = new InMemoryRealmService(); + RegistryDataHolder.getInstance().setRealmService(realmService); + DeviceManagementDataHolder.getInstance().setRealmService(realmService); + InputStream is = this.getClass().getClassLoader().getResourceAsStream( + "carbon-home/repository/conf/registry.xml"); + RegistryContext context = RegistryContext.getBaseInstance(is, realmService); + context.setSetup(true); + return context.getEmbeddedRegistryService(); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/ConfigurationTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/ConfigurationTest.java new file mode 100644 index 0000000000..b14958f105 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/ConfigurationTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core; + +import org.junit.Assert; +import org.testng.annotations.Test; +import org.wso2.carbon.device.application.mgt.core.config.Configuration; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; + +import java.util.List; + +public class ConfigurationTest { + + @Test + public void validateConfiguration() { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Configuration configuration = configurationManager.getConfiguration(); + Assert.assertNotNull("Invalid app manager configuration", configuration); + } + + @Test + public void validateLifecycleStateConfiguration() { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Configuration configuration = configurationManager.getConfiguration(); + List lifecycleStates = configuration.getLifecycleStates(); + Assert.assertNotNull("Invalid lifecycle states configuration", lifecycleStates); + Assert.assertTrue("Invalid lifecycle states configuration. Lifecycle states cannot be empty", + !lifecycleStates.isEmpty()); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/InitTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/InitTest.java new file mode 100644 index 0000000000..8d207b555c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/InitTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core; + +import org.testng.annotations.BeforeSuite; +import org.wso2.carbon.device.application.mgt.common.exception.InvalidConfigurationException; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; + +import java.io.File; + +/** + * This class initializes the required configurations prior running the tests + */ +public class InitTest { + + @BeforeSuite + public void init() throws InvalidConfigurationException { + File configPath = new File("src/test/resources/repository/conf/application-mgt.xml"); + ConfigurationManager.setConfigLocation(configPath.getAbsolutePath()); + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifeCycleStateManagerTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifeCycleStateManagerTest.java new file mode 100644 index 0000000000..75a3d3d04d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifeCycleStateManagerTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core; + +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; + +import java.util.HashMap; +import java.util.List; + + +class LifeCycleStateManagerTest extends LifecycleStateManager { + + void initializeLifeCycleDetails(List lifecycleStates) { + HashMap lifecycleStatesMap = new HashMap<>(); + for (LifecycleState lifecycleState : lifecycleStates) { + if (lifecycleState.getProceedingStates() != null) { + lifecycleState.getProceedingStates().replaceAll(String::toUpperCase); + } + lifecycleStatesMap.put(lifecycleState.getName().toUpperCase(), lifecycleState); + } + setLifecycleStates(lifecycleStatesMap); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifecycleManagementTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifecycleManagementTest.java new file mode 100644 index 0000000000..a0b816489f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifecycleManagementTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core; + +import org.junit.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.core.config.Configuration; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.common.config.LifecycleState; + +import java.util.List; + +public class LifecycleManagementTest { + + private List lifecycleStates; + private LifecycleStateManager lifecycleStateManager; + + private final String CURRENT_STATE = "Approved"; + private final String NEXT_STATE = "Published"; + private final String BOGUS_STATE = "Retired"; + private final String UPDATABLE_STATE = "Created"; + private final String NON_UPDATABLE_STATE = "Retired"; + private final String INSTALLABLE_STATE = "Published"; + private final String INITIAL_STATE = "Created"; + private final String END_STATE = "Retired"; + + + @BeforeClass + public void init() { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Configuration configuration = configurationManager.getConfiguration(); + lifecycleStates = configuration.getLifecycleStates(); + lifecycleStateManager = new LifeCycleStateManagerTest(); + ((LifeCycleStateManagerTest) lifecycleStateManager).initializeLifeCycleDetails(lifecycleStates); + } + + @Test + public void checkValidNextLifecycleState() { + List proceedingStates = lifecycleStateManager.getNextLifecycleStates(CURRENT_STATE); + Assert.assertTrue("Invalid proceeding state of: " + CURRENT_STATE, + proceedingStates.contains(NEXT_STATE.toUpperCase())); + } + + @Test + public void checkInvalidNextLifecycleState() { + List proceedingStates = lifecycleStateManager.getNextLifecycleStates(CURRENT_STATE); + Assert.assertFalse("Invalid proceeding state of: " + CURRENT_STATE, + proceedingStates.contains(BOGUS_STATE.toUpperCase())); + } + + @Test + public void CheckUpdatableState() throws LifecycleManagementException { + boolean isUpdatable = lifecycleStateManager.isUpdatableState(UPDATABLE_STATE); + System.out.println(isUpdatable); + Assert.assertTrue("Updatable state: " + UPDATABLE_STATE, isUpdatable); + } + + @Test + public void CheckNonUpdatableState() throws LifecycleManagementException { + boolean isUpdatable = lifecycleStateManager.isUpdatableState(NON_UPDATABLE_STATE); + Assert.assertFalse("Non Updatable state: " + NON_UPDATABLE_STATE, isUpdatable); + } + + @Test + public void CheckInstallableState() throws LifecycleManagementException { + boolean isInstallable = lifecycleStateManager.isInstallableState(INSTALLABLE_STATE); + Assert.assertTrue("Installable state: " + INSTALLABLE_STATE, isInstallable); + } + + @Test + public void CheckGetInitialState() throws LifecycleManagementException { + boolean isInitialState = lifecycleStateManager.getInitialState().equalsIgnoreCase(INITIAL_STATE); + Assert.assertTrue("Initial state: " + INITIAL_STATE, isInitialState); + } + + @Test + public void CheckGetNonInitialState() throws LifecycleManagementException { + boolean isInitialState = lifecycleStateManager.getInitialState().equalsIgnoreCase(END_STATE); + Assert.assertFalse("Non initial state: " + END_STATE, isInitialState); + } + + @Test + public void CheckGetEndState() throws LifecycleManagementException { + boolean isEndState = lifecycleStateManager.getEndState().equalsIgnoreCase(END_STATE); + Assert.assertTrue("End State: " + END_STATE, isEndState); + } + + @Test + public void CheckGetNonEndState() throws LifecycleManagementException { + boolean isEndState = lifecycleStateManager.getEndState().equalsIgnoreCase(INITIAL_STATE); + Assert.assertFalse("Non End State : " + INITIAL_STATE, isEndState); + } + + @Test + public void CheckIsInitialState() throws LifecycleManagementException { + boolean isInitialState = lifecycleStateManager.isInitialState(INITIAL_STATE); + Assert.assertTrue("Initial state: " + INITIAL_STATE, isInitialState); + } + + @Test + public void CheckIsNonInitialState() throws LifecycleManagementException { + boolean isInitialState = lifecycleStateManager.isInitialState(END_STATE); + Assert.assertFalse("Non Initial state: " + END_STATE, isInitialState); + } + + @Test + public void CheckIsEndState() throws LifecycleManagementException { + boolean isEndState = lifecycleStateManager.isEndState(END_STATE); + Assert.assertTrue("End state: " + END_STATE, isEndState); + } + + @Test + public void CheckIsNonEndState() throws LifecycleManagementException { + boolean isEndState = lifecycleStateManager.isEndState(INITIAL_STATE); + Assert.assertFalse("Non End state: " + INITIAL_STATE, isEndState); + } + + @Test + public void check() { + List proceedingStates = lifecycleStateManager.getNextLifecycleStates(CURRENT_STATE); + Assert.assertFalse("Invalid proceeding state of: " + CURRENT_STATE, + proceedingStates.contains(BOGUS_STATE.toUpperCase())); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/StorageManagementUtilTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/StorageManagementUtilTest.java new file mode 100644 index 0000000000..88d3fa4ecb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/StorageManagementUtilTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core; + +import org.junit.Assert; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagementException; +import org.wso2.carbon.device.application.mgt.core.util.StorageManagementUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class StorageManagementUtilTest { + private static final String TEMP_FOLDER = "src/test/resources/util/temp"; + private static final String APK_FILE = "src/test/resources/util/app-debug.apk"; + private static final String APK_FILE_NAME = "/app-debug.apk"; + + @BeforeMethod + public void before() throws IOException { + File file = new File(TEMP_FOLDER); + if (file.exists()) { + StorageManagementUtil.delete(file); + } + } + + @Test + public void testCreateArtifactDirectory() { + try { + StorageManagementUtil.createArtifactDirectory(TEMP_FOLDER); + } catch (ResourceManagementException e) { + e.printStackTrace(); + Assert.fail("Directory creation failed."); + } + } + + @Test + public void testSaveFile() throws IOException, ResourceManagementException { + StorageManagementUtil.createArtifactDirectory(TEMP_FOLDER); + InputStream apk = new FileInputStream(APK_FILE); + StorageManagementUtil.saveFile(apk, TEMP_FOLDER + APK_FILE_NAME); + File file = new File(TEMP_FOLDER + APK_FILE_NAME); + if (!file.exists()) { + Assert.fail("File saving failed."); + } + } + + @AfterMethod + public void deleteFileTest() throws IOException, ResourceManagementException { + File file = new File(TEMP_FOLDER); + StorageManagementUtil.delete(file); + if (file.exists()) { + Assert.fail("File deleting failed."); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/TestUtils.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/TestUtils.java new file mode 100644 index 0000000000..ceeb41902a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/TestUtils.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +public class TestUtils { + + private static final Log log = LogFactory.getLog(TestUtils.class); + + public static void cleanupResources(Connection conn, Statement stmt, ResultSet rs) { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing result set", e); + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing prepared statement", e); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing database connection", e); + } + } + } + +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dao/ApplicationManagementDAOTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dao/ApplicationManagementDAOTest.java new file mode 100644 index 0000000000..bee26a37b8 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dao/ApplicationManagementDAOTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dao; + +import junit.framework.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.wso2.carbon.device.application.mgt.core.BaseTestCase; +import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.dto.ApplicationsDTO; +import org.wso2.carbon.device.application.mgt.core.dto.DeviceTypeCreator; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; +import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; +import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; +import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.dao.DeviceTypeDAO; + +public class ApplicationManagementDAOTest extends BaseTestCase { + + private static final Log log = LogFactory.getLog(ApplicationManagementDAOTest.class); + + @BeforeClass + public void initialize() throws Exception { + log.info("Initializing ApplicationManagementDAOTest tests"); + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); +// super.initializeServices(); + } + + @Test + public void testAddApplication() throws Exception { + ApplicationDAO applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); + ConnectionManagerUtil.beginDBTransaction(); + applicationDAO.createApplication(ApplicationsDTO.getApp1(), -1234); + ConnectionManagerUtil.commitDBTransaction(); + ConnectionManagerUtil.closeDBConnection(); + } + + @Test + public void addDeviceType() throws DeviceManagementDAOException { + try { + DeviceManagementDAOFactory.beginTransaction(); + DeviceTypeDAO deviceTypeDAO = DeviceManagementDAOFactory.getDeviceTypeDAO(); + deviceTypeDAO.addDeviceType(DeviceTypeCreator.getDeviceType(), -1234, true); + } catch (DeviceManagementDAOException e) { + DeviceManagementDAOFactory.rollbackTransaction(); + log.error("Error occurred while adding dummy device type", e); + Assert.fail(); + } catch (TransactionManagementException e) { + log.error("Error occurred while initiating a transaction to add dummy device type", e); + Assert.fail(); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dto/ApplicationsDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dto/ApplicationsDTO.java new file mode 100644 index 0000000000..74f598a831 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dto/ApplicationsDTO.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.dto; + +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; + +import java.util.ArrayList; +import java.util.List; + +public class ApplicationsDTO { + + public static ApplicationDTO getApp1() { + ApplicationDTO app = new ApplicationDTO(); + List categories = new ArrayList<>(); + + categories.add("Test Category"); + app.setAppCategories(categories); + app.setDescription("Test app Description"); + app.setDeviceTypeId(1); + app.setName("First Test App"); + app.setSubType("I dont Know"); + app.setType("Idontknow"); + return app; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorHandler.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dto/DeviceTypeCreator.java similarity index 50% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorHandler.java rename to components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dto/DeviceTypeCreator.java index 35c18c199f..3ecd1aa675 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorHandler.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/dto/DeviceTypeCreator.java @@ -1,7 +1,7 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. * - * WSO2 Inc. licenses this file to you under the Apache License, + * Entgra (pvt) Ltd. 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 @@ -16,17 +16,18 @@ * under the License. */ -package org.wso2.carbon.device.mgt.jaxrs.common; +package org.wso2.carbon.device.application.mgt.core.dto; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.ExceptionMapper; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; -@Produces({"application/json"}) -public class ErrorHandler implements ExceptionMapper { +public class DeviceTypeCreator { - public Response toResponse(Throwable e) { - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); + public static DeviceType getDeviceType(){ + + DeviceType deviceType = new DeviceType(); + deviceType.setName("android"); + deviceType.setId(1); + + return deviceType; } - } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/management/ApplicationManagementTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/management/ApplicationManagementTest.java new file mode 100644 index 0000000000..c684f6fd01 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/management/ApplicationManagementTest.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.management; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.testng.annotations.Test; +import org.wso2.carbon.device.application.mgt.common.*; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException; +import org.wso2.carbon.device.application.mgt.common.response.Application; +import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.response.Category; +import org.wso2.carbon.device.application.mgt.common.response.Tag; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.core.BaseTestCase; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; +import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.dto.ApplicationsDTO; +import org.wso2.carbon.device.application.mgt.core.impl.ApplicationManagerImpl; +import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ApplicationManagementTest extends BaseTestCase { + + private static final Log log = LogFactory.getLog(ApplicationManagementTest.class); + + @Test + public void testAddApplication() throws Exception { + + ApplicationDAO applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); + ConnectionManagerUtil.beginDBTransaction(); + applicationDAO.createApplication(ApplicationsDTO.getApp1(), -1234); + ConnectionManagerUtil.commitDBTransaction(); + ConnectionManagerUtil.closeDBConnection(); + } + + @Test(dependsOnMethods = ("addApplicationCategories")) + public void createApplication() throws Exception { + + log.debug("Creating the first application ....!"); + + ApplicationWrapper applicationWrapper = new ApplicationWrapper(); + + List categories = new ArrayList<>(); + categories.add("Test Category"); + applicationWrapper.setCategories(categories); + + applicationWrapper.setDescription("Test Description"); + applicationWrapper.setDeviceType("android"); + applicationWrapper.setName("Test Application"); + applicationWrapper.setSubMethod("Test Sub type"); + + List tags = new ArrayList<>(); + tags.add("abc"); + tags.add("pqr"); + tags.add("xyz"); + applicationWrapper.setTags(tags); + applicationWrapper.setPaymentCurrency("USD"); + + List entAppReleaseWrappers = new ArrayList<>(); + EntAppReleaseWrapper releaseWrapper = new EntAppReleaseWrapper(); + releaseWrapper.setDescription("First release"); + releaseWrapper.setIsSharedWithAllTenants(false); + releaseWrapper.setMetaData("Just meta data"); + releaseWrapper.setReleaseType("free"); + releaseWrapper.setPrice(5.7); + releaseWrapper.setSupportedOsVersions("4.0-7.0"); + entAppReleaseWrappers.add(releaseWrapper); + + applicationWrapper.setEntAppReleaseWrappers(entAppReleaseWrappers); + + ApplicationArtifact applicationArtifact = new ApplicationArtifact(); + applicationArtifact.setBannerName("My First Banner"); + File banner = new File("src/test/resources/samples/app1/banner1.jpg"); + InputStream bannerStream = new FileInputStream(banner); + applicationArtifact.setBannerStream(bannerStream); + applicationArtifact.setIconName("My First Icon"); + applicationArtifact.setIconStream(new FileInputStream(new File("src/test/resources/samples/app1/icon.png"))); + applicationArtifact.setInstallerName("Test Android App"); + applicationArtifact.setInstallerStream(new FileInputStream(new File("src/test/resources/samples/app1/sample.apk"))); + + Map screenshots = new HashMap<>(); + screenshots.put("shot1", new FileInputStream(new File("src/test/resources/samples/app1/shot1.png"))); + screenshots.put("shot2", new FileInputStream(new File("src/test/resources/samples/app1/shot2.png"))); + screenshots.put("shot3", new FileInputStream(new File("src/test/resources/samples/app1/shot3.png"))); + + applicationArtifact.setScreenshots(screenshots); + + ApplicationManager manager = new ApplicationManagerImpl(); + manager.createEntApp(applicationWrapper, applicationArtifact); + } + + @Test + public void updateApplication(int applicationId, ApplicationUpdateWrapper applicationUpdateWrapper) throws ApplicationManagementException { + + } + + @Test + public void deleteApplication(int applicationId) throws ApplicationManagementException { + + } + + @Test + public void retireApplication(int applicationId) throws ApplicationManagementException { + + } + + @Test + public void deleteApplicationRelease(String releaseUuid) throws ApplicationManagementException { + + } + + @Test + public ApplicationList getApplications(Filter filter) throws ApplicationManagementException { + return null; + } + + @Test + public Application getApplicationById(int id, String state) throws ApplicationManagementException { + return null; + } + + @Test + public ApplicationRelease getApplicationReleaseByUUID(String uuid) throws ApplicationManagementException { + return null; + } + + @Test + public ApplicationDTO getApplicationByUuid(String uuid, String state) throws ApplicationManagementException { + return null; + } + + @Test + public ApplicationDTO getApplicationByRelease(String appReleaseUUID) throws ApplicationManagementException { + return null; + } + + @Test + public List getLifecycleStateChangeFlow(String releaseUuid) throws ApplicationManagementException { + return null; + } + + @Test + public void changeLifecycleState(String releaseUuid, String stateName) throws ApplicationManagementException { + + } + + @Test + public void updateApplicationImageArtifact(String uuid, ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + + } + + @Test + public void updateApplicationArtifact(String deviceType, String appType, String uuid, ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + + } + + @Test + public ApplicationRelease createRelease(int applicationId, EntAppReleaseWrapper entAppReleaseWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + return null; + } + + @Test + public boolean updateRelease(String deviceType, String applicationType, String releaseUuid, EntAppReleaseWrapper entAppReleaseWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + return false; + } + + @Test + public void validateAppCreatingRequest(ApplicationWrapper applicationWrapper) throws RequestValidatingException { + + } + + @Test + public void validateReleaseCreatingRequest(EntAppReleaseWrapper entAppReleaseWrapper, String applicationType) throws RequestValidatingException { + + } + + @Test + public void validateImageArtifacts(Attachment iconFile, Attachment bannerFile, List attachmentList) throws RequestValidatingException { + + } + + @Test + public void validateBinaryArtifact(Attachment binaryFile, String applicationType) throws RequestValidatingException { + + } + + @Test(dependsOnMethods = ("addDeviceVersions")) + public void addApplicationCategories() throws ApplicationManagementException { + List categories = new ArrayList<>(); + categories.add("Test Category"); + categories.add("Test Category2"); + ApplicationManager manager = new ApplicationManagerImpl(); + manager.addApplicationCategories(categories); + + } + + @Test + public void addDeviceVersions() throws ApplicationManagementException { + List deviceTypeVersions = new ArrayList<>(); + List supportingVersions = new ArrayList<>(); + + //add supporting versions + supportingVersions.add("4.0"); + supportingVersions.add("5.0"); + supportingVersions.add("6.0"); + supportingVersions.add("7.0"); + supportingVersions.add("8.0"); + + DeviceManagementProviderServiceImpl deviceManagementProviderService = new DeviceManagementProviderServiceImpl(); + try { + List deviceTypes = deviceManagementProviderService.getDeviceTypes(); + + for (DeviceType deviceType: deviceTypes){ + for (String version : supportingVersions){ + DeviceTypeVersion deviceTypeVersion = new DeviceTypeVersion(); + deviceTypeVersion.setDeviceTypeId(deviceType.getId()); + deviceTypeVersion.setVersionName(version); + deviceTypeVersions.add(deviceTypeVersion); + } + } + + for (DeviceTypeVersion deviceTypeVersion : deviceTypeVersions){ + deviceManagementProviderService.addDeviceTypeVersion(deviceTypeVersion); + } + } catch (DeviceManagementException e) { + String msg = "Error Occured while adding device type versions"; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } + + @Test + public List getRegisteredTags() throws ApplicationManagementException { + return null; + } + + @Test + public List getRegisteredCategories() throws ApplicationManagementException { + return null; + } + + @Test + public void deleteTagMapping(int appId, String tagName) throws ApplicationManagementException { + + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org/wso2/carbon/device/application/mgt/core/common/DataSourceConfig.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org/wso2/carbon/device/application/mgt/core/common/DataSourceConfig.java new file mode 100644 index 0000000000..7b1f2c32bc --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org/wso2/carbon/device/application/mgt/core/common/DataSourceConfig.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.core.common; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "DataSourceConfig") +public class DataSourceConfig { + + private String url; + private String driverClassName; + private String user; + private String password; + + @Override public String toString() { + return "DataSourceConfig[" + + " Url ='" + url + '\'' + + ", DriverClassName ='" + driverClassName + '\'' + + ", UserName ='" + user + '\'' + + ", Password ='" + password + '\'' + + "]"; + } + + @XmlElement(name = "Url", nillable = false) + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + @XmlElement(name = "DriverClassName", nillable = false) + public String getDriverClassName() { + return driverClassName; + } + + public void setDriverClassName(String driverClassName) { + this.driverClassName = driverClassName; + } + + @XmlElement(name = "User", nillable = false) + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + @XmlElement(name = "Password", nillable = false) + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/Platform.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/Platform.xml new file mode 100644 index 0000000000..8c06d41c88 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/Platform.xml @@ -0,0 +1,6 @@ + + + test + number + + \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/application-mgt.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/application-mgt.xml new file mode 100644 index 0000000000..8d447c9327 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/application-mgt.xml @@ -0,0 +1,190 @@ + + + + + + jdbc/APPM_DS + + + + org.wso2.carbon.device.application.mgt.core.impl.ApplicationManagerImpl + + + org.wso2.carbon.device.application.mgt.core.impl.ReviewManagerImpl + + + org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager + + + org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl + + + org.wso2.carbon.device.application.mgt.core.impl.ApplicationStorageManagerImpl + + repository/resources/apps/ + 6 + + + + + + + + + + + true + true + true + /app-mgt/life-cycle/application/create + + In-Review + + + + /app-mgt/life-cycle/application/review + + Rejected + Approved + Created + + + + /app-mgt/life-cycle/application/approve + + In-Review + Published + + + + true + /app-mgt/life-cycle/application/reject + + In-Review + + + + true + /app-mgt/life-cycle/application/publish + + Blocked + Deprecated + + + + /app-mgt/life-cycle/application/block + + Published + Deprecated + + + + /app-mgt/life-cycle/application/deprecate + + Published + Retired + + + + true + /app-mgt/life-cycle/application/retire + + + + + true + false + + + application_management + device_management + subscription_management + review_management + + true + + + perm:app:review:view + perm:app:review:update + perm:app:publisher:view + perm:app:publisher:update + perm:app:store:view + perm:app:subscription:install + perm:app:subscription:uninstall + perm:admin:app:review:update + perm:admin:app:review:view + perm:admin:app:publisher:update + perm:admin:app:review:update + + + app-mgt + + + /pages/error/client-errors/400 + /pages/error/client-errors/401 + /pages/error/client-errors/403 + /pages/error/client-errors/404 + /pages/error/client-errors/405 + /pages/error/client-errors/406 + /pages/error/client-errors/415 + /pages/error/server-errors/500 + /pages/error/default + + + + + EMM + IoT + + + + 1 + 10 + + + + https + /api/application-mgt/v1.0/artifact + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/dbscripts/h2.sql b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/dbscripts/h2.sql new file mode 100644 index 0000000000..f6b31c78d9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/dbscripts/h2.sql @@ -0,0 +1,429 @@ +CREATE TABLE IF NOT EXISTS REG_CLUSTER_LOCK ( + REG_LOCK_NAME VARCHAR (20), + REG_LOCK_STATUS VARCHAR (20), + REG_LOCKED_TIME TIMESTAMP, + REG_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (REG_LOCK_NAME) +); + +CREATE TABLE IF NOT EXISTS REG_LOG ( + REG_LOG_ID INTEGER AUTO_INCREMENT, + REG_PATH VARCHAR (2000), + REG_USER_ID VARCHAR (31) NOT NULL, + REG_LOGGED_TIME TIMESTAMP NOT NULL, + REG_ACTION INTEGER NOT NULL, + REG_ACTION_DATA VARCHAR (500), + REG_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (REG_LOG_ID, REG_TENANT_ID) +); + +CREATE INDEX IF NOT EXISTS REG_LOG_IND_BY_REG_LOGTIME ON REG_LOG(REG_LOGGED_TIME, REG_TENANT_ID); + +CREATE TABLE IF NOT EXISTS REG_PATH( + REG_PATH_ID INTEGER NOT NULL AUTO_INCREMENT, + REG_PATH_VALUE VARCHAR(2000) NOT NULL, + REG_PATH_PARENT_ID INT, + REG_TENANT_ID INTEGER DEFAULT 0, + CONSTRAINT PK_REG_PATH PRIMARY KEY(REG_PATH_ID, REG_TENANT_ID) +); +CREATE INDEX IF NOT EXISTS REG_PATH_IND_BY_NAME ON REG_PATH(REG_PATH_VALUE, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_PATH_IND_BY_PARENT_ID ON REG_PATH(REG_PATH_PARENT_ID, REG_TENANT_ID); + + +CREATE TABLE IF NOT EXISTS REG_CONTENT ( + REG_CONTENT_ID INTEGER NOT NULL AUTO_INCREMENT, + REG_CONTENT_DATA LONGBLOB, + REG_TENANT_ID INTEGER DEFAULT 0, + CONSTRAINT PK_REG_CONTENT PRIMARY KEY(REG_CONTENT_ID, REG_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS REG_CONTENT_HISTORY ( + REG_CONTENT_ID INTEGER NOT NULL, + REG_CONTENT_DATA LONGBLOB, + REG_DELETED SMALLINT, + REG_TENANT_ID INTEGER DEFAULT 0, + CONSTRAINT PK_REG_CONTENT_HISTORY PRIMARY KEY(REG_CONTENT_ID, REG_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS REG_RESOURCE ( + REG_PATH_ID INTEGER NOT NULL, + REG_NAME VARCHAR(256), + REG_VERSION INTEGER NOT NULL AUTO_INCREMENT, + REG_MEDIA_TYPE VARCHAR(500), + REG_CREATOR VARCHAR(31) NOT NULL, + REG_CREATED_TIME TIMESTAMP NOT NULL, + REG_LAST_UPDATOR VARCHAR(31), + REG_LAST_UPDATED_TIME TIMESTAMP NOT NULL, + REG_DESCRIPTION VARCHAR(1000), + REG_CONTENT_ID INTEGER, + REG_TENANT_ID INTEGER DEFAULT 0, + REG_UUID VARCHAR(100) NOT NULL, + CONSTRAINT PK_REG_RESOURCE PRIMARY KEY(REG_VERSION, REG_TENANT_ID) +); + +ALTER TABLE REG_RESOURCE ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_FK_BY_PATH_ID FOREIGN KEY (REG_PATH_ID, REG_TENANT_ID) REFERENCES REG_PATH (REG_PATH_ID, REG_TENANT_ID); +ALTER TABLE REG_RESOURCE ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_FK_BY_CONTENT_ID FOREIGN KEY (REG_CONTENT_ID, REG_TENANT_ID) REFERENCES REG_CONTENT (REG_CONTENT_ID, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_IND_BY_NAME ON REG_RESOURCE(REG_NAME, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_IND_BY_PATH_ID_NAME ON REG_RESOURCE(REG_PATH_ID, REG_NAME, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_IND_BY_UUID ON REG_RESOURCE(REG_UUID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_IND_BY_TENANT ON REG_RESOURCE(REG_TENANT_ID, REG_UUID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_IND_BY_TYPE ON REG_RESOURCE(REG_TENANT_ID, REG_MEDIA_TYPE); + +CREATE TABLE IF NOT EXISTS REG_RESOURCE_HISTORY ( + REG_PATH_ID INTEGER NOT NULL, + REG_NAME VARCHAR(256), + REG_VERSION INTEGER NOT NULL, + REG_MEDIA_TYPE VARCHAR(500), + REG_CREATOR VARCHAR(31) NOT NULL, + REG_CREATED_TIME TIMESTAMP NOT NULL, + REG_LAST_UPDATOR VARCHAR(31), + REG_LAST_UPDATED_TIME TIMESTAMP NOT NULL, + REG_DESCRIPTION VARCHAR(1000), + REG_CONTENT_ID INTEGER, + REG_DELETED SMALLINT, + REG_TENANT_ID INTEGER DEFAULT 0, + REG_UUID VARCHAR(100) NOT NULL, + CONSTRAINT PK_REG_RESOURCE_HISTORY PRIMARY KEY(REG_VERSION, REG_TENANT_ID) +); + +ALTER TABLE REG_RESOURCE_HISTORY ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_HIST_FK_BY_PATHID FOREIGN KEY (REG_PATH_ID, REG_TENANT_ID) REFERENCES REG_PATH (REG_PATH_ID, REG_TENANT_ID); +ALTER TABLE REG_RESOURCE_HISTORY ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_HIST_FK_BY_CONTENT_ID FOREIGN KEY (REG_CONTENT_ID, REG_TENANT_ID) REFERENCES REG_CONTENT_HISTORY (REG_CONTENT_ID, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_HISTORY_IND_BY_NAME ON REG_RESOURCE_HISTORY(REG_NAME, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_HISTORY_IND_BY_PATH_ID_NAME ON REG_RESOURCE(REG_PATH_ID, REG_NAME, REG_TENANT_ID); + +CREATE TABLE IF NOT EXISTS REG_COMMENT ( + REG_ID INTEGER NOT NULL AUTO_INCREMENT, + REG_COMMENT_TEXT VARCHAR(500) NOT NULL, + REG_USER_ID VARCHAR(31) NOT NULL, + REG_COMMENTED_TIME TIMESTAMP NOT NULL, + REG_TENANT_ID INTEGER DEFAULT 0, + CONSTRAINT PK_REG_COMMENT PRIMARY KEY(REG_ID, REG_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS REG_RESOURCE_COMMENT ( + REG_COMMENT_ID INTEGER NOT NULL, + REG_VERSION INTEGER, + REG_PATH_ID INTEGER, + REG_RESOURCE_NAME VARCHAR(256), + REG_TENANT_ID INTEGER DEFAULT 0 +); + +ALTER TABLE REG_RESOURCE_COMMENT ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_COMMENT_FK_BY_PATH_ID FOREIGN KEY (REG_PATH_ID, REG_TENANT_ID) REFERENCES REG_PATH (REG_PATH_ID, REG_TENANT_ID); +ALTER TABLE REG_RESOURCE_COMMENT ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_COMMENT_FK_BY_COMMENT_ID FOREIGN KEY (REG_COMMENT_ID, REG_TENANT_ID) REFERENCES REG_COMMENT (REG_ID, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_COMMENT_IND_BY_PATH_ID_AND_RESOURCE_NAME ON REG_RESOURCE_COMMENT(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_COMMENT_IND_BY_VERSION ON REG_RESOURCE_COMMENT(REG_VERSION, REG_TENANT_ID); + +CREATE TABLE IF NOT EXISTS REG_RATING ( + REG_ID INTEGER NOT NULL AUTO_INCREMENT, + REG_RATING INTEGER NOT NULL, + REG_USER_ID VARCHAR(31) NOT NULL, + REG_RATED_TIME TIMESTAMP NOT NULL, + REG_TENANT_ID INTEGER DEFAULT 0, + CONSTRAINT PK_REG_RATING PRIMARY KEY(REG_ID, REG_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS REG_RESOURCE_RATING ( + REG_RATING_ID INTEGER NOT NULL, + REG_VERSION INTEGER, + REG_PATH_ID INTEGER, + REG_RESOURCE_NAME VARCHAR(256), + REG_TENANT_ID INTEGER DEFAULT 0 +); + +ALTER TABLE REG_RESOURCE_RATING ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_RATING_FK_BY_PATH_ID FOREIGN KEY (REG_PATH_ID, REG_TENANT_ID) REFERENCES REG_PATH (REG_PATH_ID, REG_TENANT_ID); +ALTER TABLE REG_RESOURCE_RATING ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_RATING_FK_BY_RATING_ID FOREIGN KEY (REG_RATING_ID, REG_TENANT_ID) REFERENCES REG_RATING (REG_ID, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_RATING_IND_BY_PATH_ID_AND_RESOURCE_NAME ON REG_RESOURCE_RATING(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_RATING_IND_BY_VERSION ON REG_RESOURCE_RATING(REG_VERSION, REG_TENANT_ID); + + +CREATE TABLE IF NOT EXISTS REG_TAG ( + REG_ID INTEGER NOT NULL AUTO_INCREMENT, + REG_TAG_NAME VARCHAR(500) NOT NULL, + REG_USER_ID VARCHAR(31) NOT NULL, + REG_TAGGED_TIME TIMESTAMP NOT NULL, + REG_TENANT_ID INTEGER DEFAULT 0, + CONSTRAINT PK_REG_TAG PRIMARY KEY(REG_ID, REG_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS REG_RESOURCE_TAG ( + REG_TAG_ID INTEGER NOT NULL, + REG_VERSION INTEGER, + REG_PATH_ID INTEGER, + REG_RESOURCE_NAME VARCHAR(256), + REG_TENANT_ID INTEGER DEFAULT 0 +); + +ALTER TABLE REG_RESOURCE_TAG ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_TAG_FK_BY_PATH_ID FOREIGN KEY (REG_PATH_ID, REG_TENANT_ID) REFERENCES REG_PATH (REG_PATH_ID, REG_TENANT_ID); +ALTER TABLE REG_RESOURCE_TAG ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_TAG_FK_BY_TAG_ID FOREIGN KEY (REG_TAG_ID, REG_TENANT_ID) REFERENCES REG_TAG (REG_ID, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_TAG_IND_BY_PATH_ID_AND_RESOURCE_NAME ON REG_RESOURCE_TAG(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_TAG_IND_BY_VERSION ON REG_RESOURCE_TAG(REG_VERSION, REG_TENANT_ID); + +CREATE TABLE IF NOT EXISTS REG_PROPERTY ( + REG_ID INTEGER NOT NULL AUTO_INCREMENT, + REG_NAME VARCHAR(100) NOT NULL, + REG_VALUE VARCHAR(1000), + REG_TENANT_ID INTEGER DEFAULT 0, + CONSTRAINT PK_REG_PROPERTY PRIMARY KEY(REG_ID, REG_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS REG_RESOURCE_PROPERTY ( + REG_PROPERTY_ID INTEGER NOT NULL, + REG_VERSION INTEGER, + REG_PATH_ID INTEGER, + REG_RESOURCE_NAME VARCHAR(256), + REG_TENANT_ID INTEGER DEFAULT 0 +); + +ALTER TABLE REG_RESOURCE_PROPERTY ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_PROPERTY_FK_BY_PATH_ID FOREIGN KEY (REG_PATH_ID, REG_TENANT_ID) REFERENCES REG_PATH (REG_PATH_ID, REG_TENANT_ID); +ALTER TABLE REG_RESOURCE_PROPERTY ADD CONSTRAINT IF NOT EXISTS REG_RESOURCE_PROPERTY_FK_BY_TAG_ID FOREIGN KEY (REG_PROPERTY_ID, REG_TENANT_ID) REFERENCES REG_PROPERTY (REG_ID, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_PROPERTY_IND_BY_PATH_ID_AND_RESOURCE_NAME ON REG_RESOURCE_PROPERTY(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_RESOURCE_PROPERTY_IND_BY_VERSION ON REG_RESOURCE_PROPERTY(REG_VERSION, REG_TENANT_ID); + +CREATE TABLE IF NOT EXISTS REG_ASSOCIATION ( + REG_ASSOCIATION_ID INTEGER AUTO_INCREMENT, + REG_SOURCEPATH VARCHAR (2000) NOT NULL, + REG_TARGETPATH VARCHAR (2000) NOT NULL, + REG_ASSOCIATION_TYPE VARCHAR (2000) NOT NULL, + REG_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (REG_ASSOCIATION_ID, REG_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS REG_SNAPSHOT ( + REG_SNAPSHOT_ID INTEGER NOT NULL AUTO_INCREMENT, + REG_PATH_ID INTEGER NOT NULL, + REG_RESOURCE_NAME VARCHAR (256), + REG_RESOURCE_VIDS LONGBLOB NOT NULL, + REG_TENANT_ID INTEGER DEFAULT 0, + CONSTRAINT PK_REG_SNAPSHOT PRIMARY KEY(REG_SNAPSHOT_ID, REG_TENANT_ID) +); + +ALTER TABLE REG_SNAPSHOT ADD CONSTRAINT IF NOT EXISTS REG_SNAPSHOT_FK_BY_PATH_ID FOREIGN KEY (REG_PATH_ID, REG_TENANT_ID) REFERENCES REG_PATH (REG_PATH_ID, REG_TENANT_ID); +CREATE INDEX IF NOT EXISTS REG_SNAPSHOT_IND_BY_PATH_ID_AND_RESOURCE_NAME ON REG_SNAPSHOT(REG_PATH_ID, REG_RESOURCE_NAME, REG_TENANT_ID); + +-- ################################ +-- USER MANAGER TABLES +-- ################################ + +CREATE TABLE IF NOT EXISTS UM_TENANT ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_DOMAIN_NAME VARCHAR(255) NOT NULL, + UM_EMAIL VARCHAR(255), + UM_ACTIVE BOOLEAN DEFAULT FALSE, + UM_CREATED_DATE TIMESTAMP NOT NULL, + UM_USER_CONFIG LONGBLOB NOT NULL, + PRIMARY KEY (UM_ID), + UNIQUE(UM_DOMAIN_NAME)); + +CREATE TABLE IF NOT EXISTS UM_DOMAIN( + UM_DOMAIN_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_DOMAIN_NAME VARCHAR(255), + UM_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (UM_DOMAIN_ID, UM_TENANT_ID) +); + +CREATE INDEX IF NOT EXISTS INDEX_UM_TENANT_UM_DOMAIN_NAME ON UM_TENANT (UM_DOMAIN_NAME); + +CREATE TABLE IF NOT EXISTS UM_USER ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_USER_NAME VARCHAR(255) NOT NULL, + UM_USER_PASSWORD VARCHAR(255) NOT NULL, + UM_SALT_VALUE VARCHAR(31), + UM_REQUIRE_CHANGE BOOLEAN DEFAULT FALSE, + UM_CHANGED_TIME TIMESTAMP NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (UM_ID, UM_TENANT_ID), + UNIQUE(UM_USER_NAME, UM_TENANT_ID)); + +CREATE TABLE IF NOT EXISTS UM_SYSTEM_USER ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_USER_NAME VARCHAR(255) NOT NULL, + UM_USER_PASSWORD VARCHAR(255) NOT NULL, + UM_SALT_VALUE VARCHAR(31), + UM_REQUIRE_CHANGE BOOLEAN DEFAULT FALSE, + UM_CHANGED_TIME TIMESTAMP NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (UM_ID, UM_TENANT_ID), + UNIQUE(UM_USER_NAME, UM_TENANT_ID)); + +CREATE TABLE IF NOT EXISTS UM_USER_ATTRIBUTE ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_ATTR_NAME VARCHAR(255) NOT NULL, + UM_ATTR_VALUE VARCHAR(1024), + UM_PROFILE_ID VARCHAR(255), + UM_USER_ID INTEGER, + UM_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (UM_ID, UM_TENANT_ID), + FOREIGN KEY (UM_USER_ID, UM_TENANT_ID) REFERENCES UM_USER(UM_ID, UM_TENANT_ID)); + +CREATE INDEX IF NOT EXISTS UM_USER_ID_INDEX ON UM_USER_ATTRIBUTE(UM_USER_ID); + +CREATE TABLE IF NOT EXISTS UM_ROLE ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_ROLE_NAME VARCHAR(255) NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + UM_SHARED_ROLE BOOLEAN DEFAULT FALSE, + PRIMARY KEY (UM_ID, UM_TENANT_ID), + UNIQUE(UM_ROLE_NAME, UM_TENANT_ID)); + +CREATE TABLE IF NOT EXISTS UM_MODULE( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_MODULE_NAME VARCHAR(100), + UNIQUE(UM_MODULE_NAME), + PRIMARY KEY(UM_ID) +); + +CREATE TABLE IF NOT EXISTS UM_MODULE_ACTIONS( + UM_ACTION VARCHAR(255) NOT NULL, + UM_MODULE_ID INTEGER NOT NULL, + PRIMARY KEY(UM_ACTION, UM_MODULE_ID), + FOREIGN KEY (UM_MODULE_ID) REFERENCES UM_MODULE(UM_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS UM_PERMISSION ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_RESOURCE_ID VARCHAR(255) NOT NULL, + UM_ACTION VARCHAR(255) NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + UM_MODULE_ID INTEGER DEFAULT 0, + UNIQUE(UM_RESOURCE_ID,UM_ACTION, UM_TENANT_ID), + PRIMARY KEY (UM_ID, UM_TENANT_ID)); + +CREATE INDEX IF NOT EXISTS INDEX_UM_PERMISSION_UM_RESOURCE_ID_UM_ACTION ON UM_PERMISSION (UM_RESOURCE_ID, UM_ACTION, UM_TENANT_ID); + +CREATE TABLE IF NOT EXISTS UM_ROLE_PERMISSION ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_PERMISSION_ID INTEGER NOT NULL, + UM_ROLE_NAME VARCHAR(255) NOT NULL, + UM_IS_ALLOWED SMALLINT NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + UM_DOMAIN_ID INTEGER, + FOREIGN KEY (UM_PERMISSION_ID, UM_TENANT_ID) REFERENCES UM_PERMISSION(UM_ID, UM_TENANT_ID) ON DELETE CASCADE, + FOREIGN KEY (UM_DOMAIN_ID, UM_TENANT_ID) REFERENCES UM_DOMAIN(UM_DOMAIN_ID, UM_TENANT_ID) ON DELETE CASCADE, + PRIMARY KEY (UM_ID, UM_TENANT_ID)); + +CREATE TABLE IF NOT EXISTS UM_USER_PERMISSION ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_PERMISSION_ID INTEGER NOT NULL, + UM_USER_NAME VARCHAR(255) NOT NULL, + UM_IS_ALLOWED SMALLINT NOT NULL, + UNIQUE (UM_PERMISSION_ID, UM_USER_NAME, UM_TENANT_ID), + UM_TENANT_ID INTEGER DEFAULT 0, + FOREIGN KEY (UM_PERMISSION_ID, UM_TENANT_ID) REFERENCES UM_PERMISSION(UM_ID, UM_TENANT_ID) ON DELETE CASCADE, + PRIMARY KEY (UM_ID, UM_TENANT_ID)); + +CREATE TABLE IF NOT EXISTS UM_USER_ROLE ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_ROLE_ID INTEGER NOT NULL, + UM_USER_ID INTEGER NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + UNIQUE (UM_USER_ID, UM_ROLE_ID, UM_TENANT_ID), + FOREIGN KEY (UM_ROLE_ID, UM_TENANT_ID) REFERENCES UM_ROLE(UM_ID, UM_TENANT_ID), + FOREIGN KEY (UM_USER_ID, UM_TENANT_ID) REFERENCES UM_USER(UM_ID, UM_TENANT_ID), + PRIMARY KEY (UM_ID, UM_TENANT_ID)); + + +CREATE TABLE IF NOT EXISTS UM_SHARED_USER_ROLE( + UM_ROLE_ID INTEGER NOT NULL, + UM_USER_ID INTEGER NOT NULL, + UM_USER_TENANT_ID INTEGER NOT NULL, + UM_ROLE_TENANT_ID INTEGER NOT NULL, + UNIQUE(UM_USER_ID,UM_ROLE_ID,UM_USER_TENANT_ID, UM_ROLE_TENANT_ID), + FOREIGN KEY(UM_ROLE_ID,UM_ROLE_TENANT_ID) REFERENCES UM_ROLE(UM_ID,UM_TENANT_ID) ON DELETE CASCADE , + FOREIGN KEY(UM_USER_ID,UM_USER_TENANT_ID) REFERENCES UM_USER(UM_ID,UM_TENANT_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS UM_ACCOUNT_MAPPING( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_USER_NAME VARCHAR(255) NOT NULL, + UM_TENANT_ID INTEGER NOT NULL, + UM_USER_STORE_DOMAIN VARCHAR(100), + UM_ACC_LINK_ID INTEGER NOT NULL, + UNIQUE(UM_USER_NAME, UM_TENANT_ID, UM_USER_STORE_DOMAIN, UM_ACC_LINK_ID), + FOREIGN KEY (UM_TENANT_ID) REFERENCES UM_TENANT(UM_ID) ON DELETE CASCADE, + PRIMARY KEY (UM_ID) +); + + +CREATE TABLE IF NOT EXISTS UM_DIALECT( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_DIALECT_URI VARCHAR(255) NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + UNIQUE(UM_DIALECT_URI, UM_TENANT_ID), + PRIMARY KEY (UM_ID, UM_TENANT_ID) +); + + +CREATE TABLE IF NOT EXISTS UM_CLAIM( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_DIALECT_ID INTEGER NOT NULL, + UM_CLAIM_URI VARCHAR(255) NOT NULL, + UM_DISPLAY_TAG VARCHAR(255), + UM_DESCRIPTION VARCHAR(255), + UM_MAPPED_ATTRIBUTE_DOMAIN VARCHAR(255), + UM_MAPPED_ATTRIBUTE VARCHAR(255), + UM_REG_EX VARCHAR(255), + UM_SUPPORTED SMALLINT, + UM_REQUIRED SMALLINT, + UM_DISPLAY_ORDER INTEGER, + UM_CHECKED_ATTRIBUTE SMALLINT, + UM_READ_ONLY SMALLINT, + UM_TENANT_ID INTEGER DEFAULT 0, + UNIQUE(UM_DIALECT_ID, UM_CLAIM_URI,UM_MAPPED_ATTRIBUTE_DOMAIN, UM_TENANT_ID), + FOREIGN KEY(UM_DIALECT_ID, UM_TENANT_ID) REFERENCES UM_DIALECT(UM_ID, UM_TENANT_ID), + PRIMARY KEY (UM_ID, UM_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS UM_PROFILE_CONFIG( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_DIALECT_ID INTEGER, + UM_PROFILE_NAME VARCHAR(255), + UM_TENANT_ID INTEGER DEFAULT 0, + FOREIGN KEY(UM_DIALECT_ID, UM_TENANT_ID) REFERENCES UM_DIALECT(UM_ID, UM_TENANT_ID), + PRIMARY KEY (UM_ID, UM_TENANT_ID) +); + + +CREATE TABLE IF NOT EXISTS UM_HYBRID_ROLE( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_ROLE_NAME VARCHAR(255), + UM_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (UM_ID, UM_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS UM_HYBRID_USER_ROLE( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_USER_NAME VARCHAR(255), + UM_ROLE_ID INTEGER NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + UM_DOMAIN_ID INTEGER, + UNIQUE (UM_USER_NAME, UM_ROLE_ID, UM_TENANT_ID,UM_DOMAIN_ID), + FOREIGN KEY (UM_ROLE_ID, UM_TENANT_ID) REFERENCES UM_HYBRID_ROLE(UM_ID, UM_TENANT_ID) ON DELETE CASCADE, + FOREIGN KEY (UM_DOMAIN_ID, UM_TENANT_ID) REFERENCES UM_DOMAIN(UM_DOMAIN_ID, UM_TENANT_ID) ON DELETE CASCADE, + PRIMARY KEY (UM_ID, UM_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS UM_HYBRID_REMEMBER_ME ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_USER_NAME VARCHAR(255) NOT NULL, + UM_COOKIE_VALUE VARCHAR(1024), + UM_CREATED_TIME TIMESTAMP, + UM_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (UM_ID, UM_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS UM_SYSTEM_ROLE( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_ROLE_NAME VARCHAR(255), + UM_TENANT_ID INTEGER DEFAULT 0, + PRIMARY KEY (UM_ID, UM_TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS UM_SYSTEM_USER_ROLE( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_USER_NAME VARCHAR(255), + UM_ROLE_ID INTEGER NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + UNIQUE (UM_USER_NAME, UM_ROLE_ID, UM_TENANT_ID), + FOREIGN KEY (UM_ROLE_ID, UM_TENANT_ID) REFERENCES UM_SYSTEM_ROLE(UM_ID, UM_TENANT_ID), + PRIMARY KEY (UM_ID, UM_TENANT_ID) +); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/application-mgt.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/application-mgt.xml new file mode 100644 index 0000000000..37c7a0a1d7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/application-mgt.xml @@ -0,0 +1,190 @@ + + + + + + jdbc/APPM_DS + + + + org.wso2.carbon.device.application.mgt.core.impl.ApplicationManagerImpl + + + org.wso2.carbon.device.application.mgt.core.impl.ReviewManagerImpl + + + org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager + + + org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl + + + org.wso2.carbon.device.application.mgt.core.impl.ApplicationStorageManagerImpl + + /tmp/apps/ + 6 + + + + + + + + + + + true + true + true + /app-mgt/life-cycle/application/create + + In-Review + + + + /app-mgt/life-cycle/application/review + + Rejected + Approved + Created + + + + /app-mgt/life-cycle/application/approve + + In-Review + Published + + + + true + /app-mgt/life-cycle/application/reject + + In-Review + + + + true + /app-mgt/life-cycle/application/publish + + Blocked + Deprecated + + + + /app-mgt/life-cycle/application/block + + Published + Deprecated + + + + /app-mgt/life-cycle/application/deprecate + + Published + Retired + + + + true + /app-mgt/life-cycle/application/retire + + + + + true + false + + + application_management + device_management + subscription_management + review_management + + true + + + perm:app:review:view + perm:app:review:update + perm:app:publisher:view + perm:app:publisher:update + perm:app:store:view + perm:app:subscription:install + perm:app:subscription:uninstall + perm:admin:app:review:update + perm:admin:app:review:view + perm:admin:app:publisher:update + perm:admin:app:review:update + + + app-mgt + + + /pages/error/client-errors/400 + /pages/error/client-errors/401 + /pages/error/client-errors/403 + /pages/error/client-errors/404 + /pages/error/client-errors/405 + /pages/error/client-errors/406 + /pages/error/client-errors/415 + /pages/error/server-errors/500 + /pages/error/default + + + + + EMM + IoT + + + + 1 + 10 + + + + https + /api/application-mgt/v1.0/artifact + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/axis2.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/axis2.xml new file mode 100644 index 0000000000..733d328fbd --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/axis2.xml @@ -0,0 +1,725 @@ + + + + + + + + + + + + + ${hotdeployment} + ${hotupdate} + optional + true + work/mtom + 4000 + + ${childfirstCL} + + + true + + + true + + + + false + + inmemory + + + + + + + services + + + axis2services + + + axis2modules + + + @product.name@-@product.version@ + + + @product.name@-@product.version@ + + + + + + + false + + + + + + false + + + true + + + repository/deployment/server/synapse-configs + + + . + + + . + + + WSO2 Carbon Server + + + + + + + ${jaxwsparam} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9763 + + + + + + + + + + + + 9443 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HTTP/1.1 + chunked + + true + + + HTTP/1.1 + chunked + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + multicast + + + + + wso2.carbon.domain + + + + + + 45564 + + 100 + + 60 + + + + + + 127.0.0.1 + + + + + + 4000 + + + + + + + + + + + + + + + + + + 127.0.0.1 + 4000 + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/axis2_client.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/axis2_client.xml new file mode 100644 index 0000000000..059892ecf7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/axis2_client.xml @@ -0,0 +1,302 @@ + + + + + + + true + false + false + + + 500 + + 15000 + + + false + + + + true + + + + + + false + + + admin + axis2 + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6071 + + + + + + + + + + + + + + + + + + + + + + HTTP/1.1 + chunked + 60000 + 60000 + + + HTTP/1.1 + chunked + 60000 + 60000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/tenant-axis2.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/tenant-axis2.xml new file mode 100644 index 0000000000..dbf45777f2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/axis2/tenant-axis2.xml @@ -0,0 +1,287 @@ + + + + + + + + + true + true + optional + + + true + + + false + + + + true + + + + + + false + + + false + + + axis2services + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/carbon.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/carbon.xml new file mode 100644 index 0000000000..9b1d88cd00 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/carbon.xml @@ -0,0 +1,658 @@ + + + + + + + + + ${product.name} + + + ${product.key} + + + ${product.version} + + + + + + + + + local:/${carbon.context}/services/ + + + + + + + ${default.server.role} + + + + + + + org.wso2.carbon + + + / + + + + + + + + + 15 + + + + + + + + + 0 + + + + + 9999 + + 11111 + + + + + + 10389 + + 8000 + + + + + + 10500 + + + + + + + org.wso2.carbon.tomcat.jndi.CarbonJavaURLContextFactory + + + + + + + + + java + + + + + + + + + + false + + + false + + + 600 + + + + false + + + + + + + + 30 + + + + + + + + + 15 + + + + + + ${carbon.home}/repository/deployment/server/ + + + 15 + + + ${carbon.home}/repository/conf/axis2/axis2.xml + + + 30000 + + + ${carbon.home}/repository/deployment/client/ + + ${carbon.home}/repository/conf/axis2/axis2_client.xml + + true + + + + + + + + + + admin + Default Administrator Role + + + user + Default User Role + + + + + + + + + + + + ${carbon.home}/repository/resources/security/wso2carbon.jks + + JKS + + wso2carbon + + wso2carbon + + wso2carbon + + + + + + ${carbon.home}/repository/resources/security/client-truststore.jks + + JKS + + wso2carbon + + + + + + + + + + + + + + + + + + + UserManager + + + false + + + + + + + ${carbon.home}/tmp/work + + + + + + true + + + 10 + + + 30 + + + + + + 100 + + + + keystore + certificate + * + + org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor + + + + + jarZip + + org.wso2.carbon.ui.transports.fileupload.JarZipUploadExecutor + + + + dbs + + org.wso2.carbon.ui.transports.fileupload.DBSFileUploadExecutor + + + + tools + + org.wso2.carbon.ui.transports.fileupload.ToolsFileUploadExecutor + + + + toolsAny + + org.wso2.carbon.ui.transports.fileupload.ToolsAnyFileUploadExecutor + + + + + + + info + org.wso2.carbon.core.transports.util.InfoProcessor + + + wsdl + org.wso2.carbon.core.transports.util.Wsdl11Processor + + + wsdl2 + org.wso2.carbon.core.transports.util.Wsdl20Processor + + + xsd + org.wso2.carbon.core.transports.util.XsdProcessor + + + + + + false + false + true + svn + http://svnrepo.example.com/repos/ + username + password + true + + + + + + + + + + + + + + + ${require.carbon.servlet} + + + + + true + + + + + + + default repository + ${p2.repo.url} + + + + + + + + true + + + + + + true + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/cdm-config.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/cdm-config.xml new file mode 100644 index 0000000000..b0a30601ae --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/cdm-config.xml @@ -0,0 +1,152 @@ + + + + + + + + jdbc/DM_DS + + + + + 1000 + 60000 + 60000 + true + + org.wso2.carbon.device.mgt.extensions.push.notification.provider.fcm.FCMBasedPushNotificationProvider + + org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider + org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.HTTPBasedPushNotificationProvider + org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider + + + + false + + + https://localhost:9443 + admin + admin + + + https://localhost:9443 + admin + admin + + + org.wso2.carbon.policy.mgt + true + 60000 + 5 + 8 + 20 + + + + Simple + true + + + + 20 + 20 + 20 + 20 + 20 + 20 + + + + true + + + + false + 600 + + 10000 + + + false + 86400 + + + + + jdbc/DM_ARCHIVAL_DS + + + + false + org.wso2.carbon.device.mgt.core.task.impl.ArchivalTask + + 0 0 0 1/1 * ? * + + 30 + 1000 + + false + org.wso2.carbon.device.mgt.core.task.impl.ArchivedDataDeletionTask + + 0 0 3 1/1 * ? * + + 365 + + + + + false + + + false + false + + false + + + + + * + + + + + + true + wss://localhost:9443 + 2 + 100 + 20 + 15 + 640 + + BYOD,COPE + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/datasources/master-datasources.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/datasources/master-datasources.xml new file mode 100644 index 0000000000..897e33581c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/datasources/master-datasources.xml @@ -0,0 +1,68 @@ + + + + org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader + + + + + + WSO2_CARBON_DB + The datasource used for registry and user manager + + jdbc/WSO2CarbonDB + + + + jdbc:h2:repository/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000 + wso2carbon + wso2carbon + org.h2.Driver + 50 + 60000 + true + SELECT 1 + 30000 + false + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/bundle-config/README.txt b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/bundle-config/README.txt new file mode 100644 index 0000000000..ffa7c79264 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/bundle-config/README.txt @@ -0,0 +1,12 @@ +This directory supports adding third-pary config files to specific bundles during runtime. + +Explanation: Each OSGi bundle has its own classLoader. Some thirdpary libs read configs from classPath. This scenario fails in OSGi runtime, since OSGi runtime does not share a common classPath for individual bundles. Bundling config files during the bundle creation process itself will solve the issue. However it limits the ability to edit the configs during restarts. + +Here we are providing a workaround for such scenarios. The given config file will get resolved to a fragment bundle and will get attached to the specified host bundle. The host bundle name(symbolic name) is resolved by looking at the directory structure. Hence host bundle name should be directory name of the config file directory. + + +Example: The bundle with symbolic name, 'org.foo.bar' expects a config file named 'foobar.properties' from its classPath. + +create a directory named 'org.foo.bar' inside 'repository/conf/etc/bundle-config' - (this directory) and place the foobar.properties file. + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/carboncontext-osgi-services.properties b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/carboncontext-osgi-services.properties new file mode 100644 index 0000000000..f52d194001 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/carboncontext-osgi-services.properties @@ -0,0 +1,3 @@ +#osgi.service.1 = org.wso2.carbon.client.configcontext.provider.Axis2ClientConfigContextProvider +#osgi.service.2 = org.wso2.carbon.user.core.UserManager +#osgi.service.3 = org.wso2.carbon.user.api.UserRealmService \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/config-validation.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/config-validation.xml new file mode 100644 index 0000000000..3b5b3484bb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/config-validation.xml @@ -0,0 +1,37 @@ + + + + + + 800 + 2047 + 2047 + 1024 + 4096 + 02:FB:AA:5F:20:64:49:4A:27:29:55:71:83:F7:46:CD + + + 256 + 512 + 256 + + + carbon.home + carbon.config.dir.path + axis2.home + + + Linux + Unix + Mac OS + Windows Server 2003 + Windows XP + Windows Vista + Windows 7 + Mac OS X + Windows Server 2008 + Windows Server 2008 R2 + AIX + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/jmx.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/jmx.xml new file mode 100644 index 0000000000..28e7a30ceb --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/jmx.xml @@ -0,0 +1,34 @@ + + + + + true + + + localhost + + + ${Ports.JMX.RMIRegistryPort} + + + ${Ports.JMX.RMIServerPort} + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/launch.ini b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/launch.ini new file mode 100644 index 0000000000..8b9f5ad190 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/launch.ini @@ -0,0 +1,258 @@ +# Eclipse Runtime Configuration Overrides +# These properties are loaded prior to starting the framework and can also be used to override System Properties +# @null is a special value used to override and clear the framework's copy of a System Property prior to starting the framework +# "*" can be used together with @null to clear System Properties that match a prefix name. + +osgi.*=@null +org.osgi.*=@null +eclipse.*=@null + +osgi.parentClassloader=app +osgi.contextClassLoaderParent=app + +# When osgi.clean is set to "true", any cached data used by the OSGi framework +# will be wiped clean. This will clean the caches used to store bundle +# dependency resolution and eclipse extension registry data. Using this +# option will force OSGi framework to reinitialize these caches. +# The following setting is put in place to get rid of the problems +# faced when re-starting the system. Please note that, when this setting is +# true, if you manually start a bundle, it would not be available when +# you re-start the system. To avid this, copy the bundle jar to the plugins +# folder, before you re-start the system. +osgi.clean=true + +# Uncomment the following line to turn on Eclipse Equinox debugging. +# You may also edit the osgi-debug.options file and fine tune the debugging +# options to suite your needs. +#osgi.debug=./repository/conf/osgi-debug.options + +# Following system property allows us to control the public JDK packages exported through the system bundle. +org.osgi.framework.system.packages=javax.accessibility,\ +javax.activity,\ +javax.crypto,\ +javax.crypto.interfaces,\ +javax.crypto.spec,\ +javax.imageio,\ +javax.imageio.event,\ +javax.imageio.metadata,\ +javax.imageio.plugins.bmp,\ +javax.imageio.plugins.jpeg,\ +javax.imageio.spi,\ +javax.imageio.stream,\ +javax.jms,\ +javax.management,\ +javax.management.loading,\ +javax.management.modelmbean,\ +javax.management.monitor,\ +javax.management.openmbean,\ +javax.management.relation,\ +javax.management.remote,\ +javax.management.remote.rmi,\ +javax.management.timer,\ +javax.naming,\ +javax.naming.directory,\ +javax.naming.event,\ +javax.naming.ldap,\ +javax.naming.spi,\ +javax.net,\ +javax.net.ssl,\ +javax.print,\ +javax.print.attribute,\ +javax.print.attribute.standard,\ +javax.print.event,\ +javax.rmi,\ +javax.rmi.CORBA,\ +javax.rmi.ssl,\ +javax.script,\ +javax.security.auth,\ +javax.security.auth.callback,\ +javax.security.auth.kerberos,\ +javax.security.auth.login,\ +javax.security.auth.spi,\ +javax.security.auth.x500,\ +javax.security.cert,\ +javax.security.sasl,\ +javax.sound.midi,\ +javax.sound.midi.spi,\ +javax.sound.sampled,\ +javax.sound.sampled.spi,\ +javax.sql,\ +javax.sql.rowset,\ +javax.sql.rowset.serial,\ +javax.sql.rowset.spi,\ +javax.swing,\ +javax.swing.border,\ +javax.swing.colorchooser,\ +javax.swing.event,\ +javax.swing.filechooser,\ +javax.swing.plaf,\ +javax.swing.plaf.basic,\ +javax.swing.plaf.metal,\ +javax.swing.plaf.multi,\ +javax.swing.plaf.synth,\ +javax.swing.table,\ +javax.swing.text,\ +javax.swing.text.html,\ +javax.swing.text.html.parser,\ +javax.swing.text.rtf,\ +javax.swing.tree,\ +javax.swing.undo,\ +javax.transaction,\ +javax.transaction.xa,\ +javax.xml.namespace,\ +javax.xml.parsers,\ +javax.xml.stream,\ +javax.xml.stream.events,\ +javax.xml.stream.util,\ +javax.xml.transform,\ +javax.xml.transform.stream,\ +javax.xml.transform.dom,\ +javax.xml.transform.sax,\ +javax.xml,\ +javax.xml.validation,\ +javax.xml.datatype,\ +javax.xml.xpath,\ +javax.activation,\ +com.sun.activation.registries,\ +com.sun.activation.viewers,\ +org.ietf.jgss,\ +org.omg.CORBA,\ +org.omg.CORBA_2_3,\ +org.omg.CORBA_2_3.portable,\ +org.omg.CORBA.DynAnyPackage,\ +org.omg.CORBA.ORBPackage,\ +org.omg.CORBA.portable,\ +org.omg.CORBA.TypeCodePackage,\ +org.omg.CosNaming,\ +org.omg.CosNaming.NamingContextExtPackage,\ +org.omg.CosNaming.NamingContextPackage,\ +org.omg.Dynamic,\ +org.omg.DynamicAny,\ +org.omg.DynamicAny.DynAnyFactoryPackage,\ +org.omg.DynamicAny.DynAnyPackage,\ +org.omg.IOP,\ +org.omg.IOP.CodecFactoryPackage,\ +org.omg.IOP.CodecPackage,\ +org.omg.Messaging,\ +org.omg.PortableInterceptor,\ +org.omg.PortableInterceptor.ORBInitInfoPackage,\ +org.omg.PortableServer,\ +org.omg.PortableServer.CurrentPackage,\ +org.omg.PortableServer.POAManagerPackage,\ +org.omg.PortableServer.POAPackage,\ +org.omg.PortableServer.portable,\ +org.omg.PortableServer.ServantLocatorPackage,\ +org.omg.SendingContext,\ +org.omg.stub.java.rmi,\ +org.w3c.dom,\ +org.w3c.dom.bootstrap,\ +org.w3c.dom.css,\ +org.w3c.dom.events,\ +org.w3c.dom.html,\ +org.w3c.dom.ls,\ +org.w3c.dom.ranges,\ +org.w3c.dom.stylesheets,\ +org.w3c.dom.traversal,\ +org.w3c.dom.views ,\ +org.xml.sax,\ +org.xml.sax.ext,\ +org.xml.sax.helpers,\ +org.apache.xerces.xpointer,\ +org.apache.xerces.xni.grammars,\ +org.apache.xerces.impl.xs.util,\ +org.apache.xerces.jaxp.validation,\ +org.apache.xerces.impl.dtd.models,\ +org.apache.xerces.impl.xpath,\ +org.apache.xerces.dom3.as,\ +org.apache.xerces.impl.dv.xs,\ +org.apache.xerces.util,\ +org.apache.xerces.impl.xs.identity,\ +org.apache.xerces.impl.xs.opti,\ +org.apache.xerces.jaxp,\ +org.apache.xerces.impl.dv,\ +org.apache.xerces.xs.datatypes,\ +org.apache.xerces.dom.events,\ +org.apache.xerces.impl.msg,\ +org.apache.xerces.xni,\ +org.apache.xerces.impl.xs,\ +org.apache.xerces.impl,\ +org.apache.xerces.impl.io,\ +org.apache.xerces.xinclude,\ +org.apache.xerces.jaxp.datatype,\ +org.apache.xerces.parsers,\ +org.apache.xerces.impl.dv.util,\ +org.apache.xerces.xni.parser,\ +org.apache.xerces.impl.xs.traversers,\ +org.apache.xerces.impl.dv.dtd,\ +org.apache.xerces.xs,\ +org.apache.xerces.impl.dtd,\ +org.apache.xerces.impl.validation,\ +org.apache.xerces.impl.xs.models,\ +org.apache.xerces.impl.xpath.regex,\ +org.apache.xml.serialize,\ +org.apache.xerces.dom,\ +org.apache.xalan,\ +org.apache.xalan.xslt,\ +org.apache.xalan.templates,\ +org.apache.xalan.xsltc,\ +org.apache.xalan.xsltc.cmdline,\ +org.apache.xalan.xsltc.cmdline.getopt,\ +org.apache.xalan.xsltc.trax,\ +org.apache.xalan.xsltc.dom,\ +org.apache.xalan.xsltc.runtime,\ +org.apache.xalan.xsltc.runtime.output,\ +org.apache.xalan.xsltc.util,\ +org.apache.xalan.xsltc.compiler,\ +org.apache.xalan.xsltc.compiler.util,\ +org.apache.xalan.serialize,\ +org.apache.xalan.client,\ +org.apache.xalan.res,\ +org.apache.xalan.transformer,\ +org.apache.xalan.extensions,\ +org.apache.xalan.lib,\ +org.apache.xalan.lib.sql,\ +org.apache.xalan.processor,\ +org.apache.xalan.trace,\ +org.apache.xml.dtm,\ +org.apache.xml.dtm.ref,\ +org.apache.xml.dtm.ref.sax2dtm,\ +org.apache.xml.dtm.ref.dom2dtm,\ +org.apache.xml.utils,\ +org.apache.xml.utils.res,\ +org.apache.xml.res,\ +org.apache.xml.serializer,\ +org.apache.xml.serializer.utils,\ +org.apache.xpath,\ +org.apache.xpath.domapi,\ +org.apache.xpath.objects,\ +org.apache.xpath.patterns,\ +org.apache.xpath.jaxp,\ +org.apache.xpath.res,\ +org.apache.xpath.operations,\ +org.apache.xpath.functions,\ +org.apache.xpath.axes,\ +org.apache.xpath.compiler,\ +org.apache.xml.resolver,\ +org.apache.xml.resolver.tools,\ +org.apache.xml.resolver.helpers,\ +org.apache.xml.resolver.readers,\ +org.apache.xml.resolver.etc,\ +org.apache.xml.resolver.apps,\ +javax.xml.ws,\ +javax.xml.ws.handler,\ +javax.xml.ws.handler.soap,\ +javax.xml.ws.http,\ +javax.xml.ws.soap,\ +javax.xml.ws.spi,\ +javax.xml.ws.spi.http,\ +javax.xml.ws.wsaddressing,\ +javax.xml.bind,\ +javax.xml.bind.annotation,\ +javax.xml.bind.annotation.adapters,\ +javax.annotation,\ +javax.jws,\ +javax.jws.soap,\ +com.sun.xml.internal.messaging.saaj.soap.ver1_1,\ +com.sun.xml.internal.messaging.saaj.soap,\ +com.sun.tools.internal.ws.spi,\ +org.wso2.carbon.bootstrap diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/logging-bridge.properties b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/logging-bridge.properties new file mode 100644 index 0000000000..7b63190ae4 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/logging-bridge.properties @@ -0,0 +1,65 @@ +############################################################ +# Default Logging Configuration File +# +# You can use a different file by specifying a filename +# with the java.util.logging.config.file system property. +# For example java -Djava.util.logging.config.file=myfile +############################################################ + +############################################################ +# Global properties +# NOTE: this configuration file use to get the handler list, +# Properties(except level property) define for each handler +# may be not available because LogRecords handover to log4j +# appenders in runtime. +############################################################ + +# "handlers" specifies a comma separated list of log Handler +# classes. These handlers will be installed during VM startup. +# Note that these classes must be on the system classpath. +# By default we only configure a ConsoleHandler, which will only +# show messages at the INFO and above levels. +#handlers= java.util.logging.ConsoleHandler + +# To also add the FileHandler, use the following line instead. +#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler +# Add org.wso2.carbon.bootstrap.logging.handlers.LogEventHandler to handlers if you need to push java logs to LOGEVENT appender + +handlers= org.wso2.carbon.bootstrap.logging.handlers.LoggingConsoleHandler, org.wso2.carbon.bootstrap.logging.handlers.LoggingFileHandler + +# Default global logging level. +# This specifies which kinds of events are logged across +# all loggers. For any given facility this global level +# can be overriden by a facility specific level +# Note that the ConsoleHandler also has a separate level +# setting to limit messages printed to the console. +.level= INFO + +############################################################ +# Handler specific properties. +# Describes specific configuration info for Handlers. +# + +############################################################ +# This FileHandler pushed LogRecords to a log4j FileAppander in runtime +org.wso2.carbon.bootstrap.logging.handlers.LoggingFileHandler.level = INFO +#org.wso2.carbon.bootstrap.logging.handlers.LoggingFileHandler.formatter = java.util.logging.SimpleFormatter + +# This ConsoleHandler pushed LogRecords to q log4j ConsoleAppander in runtime +org.wso2.carbon.bootstrap.logging.handlers.LoggingConsoleHandler.level = INFO +#org.wso2.carbon.bootstrap.logging.handlers.LoggingConsoleHandler.formatter = java.util.logging.SimpleFormatter + + +############################################################ +# Facility specific properties. +# Provides extra control for each logger. +############################################################ + +# For example, set the com.xyz.foo logger to only log SEVERE +# messages: +#com.xyz.foo.level = SEVERE +org.apache.coyote.level = SEVERE +org.apache.catalina.level = SEVERE +com.hazelcast.level = SEVERE + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/mime.mappings b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/mime.mappings new file mode 100755 index 0000000000..97a5c5a5fc --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/mime.mappings @@ -0,0 +1,27 @@ +# +# Copyright 2005-2011 WSO2, Inc. (http://wso2.com) +# +# Licensed 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. +# + +# This file is to define the human readable media type for a mime type. +# Eg:- +# text/plain txt text +application/wsdl+xml WSDL +application/x-xsd+xml Schema +application/policy+xml Policy +application/vnd.wso2-service+xml Service +application/vnd.wso2-hyperlink Hyperlink +application/vnd.wso2.endpoint Endpoint +application/vnd.wso2-api+xml API +application/vnd.wso2-uri+xml URI diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/mime.types b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/mime.types new file mode 100644 index 0000000000..21c386da00 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/mime.types @@ -0,0 +1,734 @@ +# +# Copyright 2005-2009 WSO2, Inc. (http://wso2.com) +# +# Licensed 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. +# + +# Media type for wsdl files. This is not defined in the original mime.types file. +chemical/x-alchemy alc +application/andrew-inset ez +application/wsdl+xml wsdl +application/vnd.sun.wadl+xml wadl +application/activemessage +application/applefile +application/atomicmail +application/batch-SMTP +application/beep+xml +application/cals-1840 +application/commonground +application/cu-seeme cu +application/cybercash +application/dca-rft +application/dec-dx +application/docbook+xml +application/dsptype tsp +application/dvcs +application/edi-consent +application/edi-x12 +application/edifact +application/eshop +application/font-tdpfr +application/futuresplash spl +application/ghostview +application/hta hta +application/http +application/hyperstudio +application/iges +application/index +application/index.cmd +application/index.obj +application/index.response +application/index.vnd +application/iotp +application/ipp +application/isup +application/java-archive jar +application/java-serialized-object ser +application/java-vm class +application/mac-binhex40 hqx +application/mac-compactpro cpt +application/macwriteii +application/marc +application/mathematica nb +application/mathematica-old +application/msaccess mdb +application/msword doc dot +application/news-message-id +application/news-transmission +application/ocsp-request +application/ocsp-response +application/octet-stream bin +application/oda oda +application/ogg ogg +application/parityfec +application/pdf pdf +application/pgp-encrypted +application/pgp-keys key +application/pgp-signature pgp +application/pics-rules prf +application/pkcs10 +application/pkcs7-mime +application/pkcs7-signature +application/pkix-cert +application/pkix-crl +application/pkixcmp +application/policy+xml +application/postscript ps ai eps +application/prs.alvestrand.titrax-sheet +application/prs.cww +application/prs.nprend +application/qsig +application/rar rar +application/rdf+xml rdf +application/remote-printing +application/riscos +application/rss+xml rss +application/rtf +application/sdp +application/set-payment +application/set-payment-initiation +application/set-registration +application/set-registration-initiation +application/sgml +application/sgml-open-catalog +application/sieve +application/slate +application/smil smi smil +application/timestamp-query +application/timestamp-reply +application/vemmi +application/whoispp-query +application/whoispp-response +application/wita +application/wordperfect wpd +application/wordperfect5.1 wp5 +application/x400-bp +application/xhtml+xml xhtml xht +application/xml xml xsl xslt jrxml +application/xml-dtd +application/xml-external-parsed-entity +application/zip zip +application/vnd.3M.Post-it-Notes +application/vnd.accpac.simply.aso +application/vnd.accpac.simply.imp +application/vnd.acucobol +application/vnd.aether.imp +application/vnd.anser-web-certificate-issue-initiation +application/vnd.anser-web-funds-transfer-initiation +application/vnd.audiograph +application/vnd.bmi +application/vnd.businessobjects +application/vnd.canon-cpdl +application/vnd.canon-lips +application/vnd.cinderella cdy +application/vnd.claymore +application/vnd.commerce-battelle +application/vnd.commonspace +application/vnd.comsocaller +application/vnd.contact.cmsg +application/vnd.cosmocaller +application/vnd.ctc-posml +application/vnd.cups-postscript +application/vnd.cups-raster +application/vnd.cups-raw +application/vnd.cybank +application/vnd.dna +application/vnd.dpgraph +application/vnd.dxr +application/vnd.ecdis-update +application/vnd.ecowin.chart +application/vnd.ecowin.filerequest +application/vnd.ecowin.fileupdate +application/vnd.ecowin.series +application/vnd.ecowin.seriesrequest +application/vnd.ecowin.seriesupdate +application/vnd.enliven +application/vnd.epson.esf +application/vnd.epson.msf +application/vnd.epson.quickanime +application/vnd.epson.salt +application/vnd.epson.ssf +application/vnd.ericsson.quickcall +application/vnd.eudora.data +application/vnd.fdf +application/vnd.ffsns +application/vnd.flographit +application/vnd.framemaker +application/vnd.fsc.weblaunch +application/vnd.fujitsu.oasys +application/vnd.fujitsu.oasys2 +application/vnd.fujitsu.oasys3 +application/vnd.fujitsu.oasysgp +application/vnd.fujitsu.oasysprs +application/vnd.fujixerox.ddd +application/vnd.fujixerox.docuworks +application/vnd.fujixerox.docuworks.binder +application/vnd.fut-misnet +application/vnd.grafeq +application/vnd.groove-account +application/vnd.groove-identity-message +application/vnd.groove-injector +application/vnd.groove-tool-message +application/vnd.groove-tool-template +application/vnd.groove-vcard +application/vnd.hhe.lesson-player +application/vnd.hp-HPGL +application/vnd.hp-PCL +application/vnd.hp-PCLXL +application/vnd.hp-hpid +application/vnd.hp-hps +application/vnd.httphone +application/vnd.hzn-3d-crossword +application/vnd.ibm.MiniPay +application/vnd.ibm.afplinedata +application/vnd.ibm.modcap +application/vnd.informix-visionary +application/vnd.intercon.formnet +application/vnd.intertrust.digibox +application/vnd.intertrust.nncp +application/vnd.intu.qbo +application/vnd.intu.qfx +application/vnd.irepository.package+xml +application/vnd.is-xpr +application/vnd.japannet-directory-service +application/vnd.japannet-jpnstore-wakeup +application/vnd.japannet-payment-wakeup +application/vnd.japannet-registration +application/vnd.japannet-registration-wakeup +application/vnd.japannet-setstore-wakeup +application/vnd.japannet-verification +application/vnd.japannet-verification-wakeup +application/vnd.koan +application/vnd.lotus-1-2-3 +application/vnd.lotus-approach +application/vnd.lotus-freelance +application/vnd.lotus-notes +application/vnd.lotus-organizer +application/vnd.lotus-screencam +application/vnd.lotus-wordpro +application/vnd.mcd +application/vnd.mediastation.cdkey +application/vnd.meridian-slingshot +application/vnd.mif +application/vnd.minisoft-hp3000-save +application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf +application/vnd.mobius.dis +application/vnd.mobius.msl +application/vnd.mobius.plc +application/vnd.mobius.txf +application/vnd.motorola.flexsuite +application/vnd.motorola.flexsuite.adsi +application/vnd.motorola.flexsuite.fis +application/vnd.motorola.flexsuite.gotap +application/vnd.motorola.flexsuite.kmr +application/vnd.motorola.flexsuite.ttc +application/vnd.motorola.flexsuite.wem +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry +application/vnd.ms-asf +application/vnd.ms-excel xls xlb xlt +application/vnd.ms-lrm +application/vnd.ms-pki.seccat cat +application/vnd.ms-pki.stl stl +application/vnd.ms-powerpoint ppt pps +application/vnd.ms-project +application/vnd.ms-tnef +application/vnd.ms-works +application/vnd.mseq +application/vnd.msign +application/vnd.music-niff +application/vnd.musician +application/vnd.netfpx +application/vnd.noblenet-directory +application/vnd.noblenet-sealer +application/vnd.noblenet-web +application/vnd.novadigm.EDM +application/vnd.novadigm.EDX +application/vnd.novadigm.EXT +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.database odb +application/vnd.oasis.opendocument.formula odf +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master odm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +application/vnd.osa.netdeploy +application/vnd.palm +application/vnd.pg.format +application/vnd.pg.osasli +application/vnd.powerbuilder6 +application/vnd.powerbuilder6-s +application/vnd.powerbuilder7 +application/vnd.powerbuilder7-s +application/vnd.powerbuilder75 +application/vnd.powerbuilder75-s +application/vnd.previewsystems.box +application/vnd.publishare-delta-tree +application/vnd.pvi.ptid1 +application/vnd.pwg-xhtml-print+xml +application/vnd.rapid +application/vnd.rim.cod cod +application/vnd.s3sms +application/vnd.seemail +application/vnd.shana.informed.formdata +application/vnd.shana.informed.formtemplate +application/vnd.shana.informed.interchange +application/vnd.shana.informed.package +application/vnd.smaf mmf +application/vnd.sss-cod +application/vnd.sss-dtf +application/vnd.sss-ntf +application/vnd.stardivision.calc sdc +application/vnd.stardivision.draw sda +application/vnd.stardivision.impress sdd sdp +application/vnd.stardivision.math smf +application/vnd.stardivision.writer sdw vor +application/vnd.stardivision.writer-global sgl +application/vnd.street-stream +application/vnd.sun.xml.calc sxc +application/vnd.sun.xml.calc.template stc +application/vnd.sun.xml.draw sxd +application/vnd.sun.xml.draw.template std +application/vnd.sun.xml.impress sxi +application/vnd.sun.xml.impress.template sti +application/vnd.sun.xml.math sxm +application/vnd.sun.xml.writer sxw +application/vnd.sun.xml.writer.global sxg +application/vnd.sun.xml.writer.template stw +application/vnd.svd +application/vnd.swiftview-ics +application/vnd.symbian.install sis +application/vnd.triscape.mxs +application/vnd.trueapp +application/vnd.truedoc +application/vnd.tve-trigger +application/vnd.ufdl +application/vnd.uplanet.alert +application/vnd.uplanet.alert-wbxml +application/vnd.uplanet.bearer-choice +application/vnd.uplanet.bearer-choice-wbxml +application/vnd.uplanet.cacheop +application/vnd.uplanet.cacheop-wbxml +application/vnd.uplanet.channel +application/vnd.uplanet.channel-wbxml +application/vnd.uplanet.list +application/vnd.uplanet.list-wbxml +application/vnd.uplanet.listcmd +application/vnd.uplanet.listcmd-wbxml +application/vnd.uplanet.signal +application/vnd.vcx +application/vnd.vectorworks +application/vnd.vidsoft.vidconference +application/vnd.visio vsd +application/vnd.vividence.scriptfile +application/vnd.wap.sic +application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo +application/vnd.wrq-hp3000-labelled +application/vnd.wso2.bpel+xml bpel +application/vnd.wso2.bpmn+xml bpmn +application/vnd.wso2.endpoint +application/vnd.wso2.governance-archive gar +application/vnd.wso2-hyperlink +application/vnd.wso2.registry-ext-type+xml rxt +application/vnd.wso2-service+xml +application/vnd.wso2.xpdl+xml xpdl +application/vnd.wt.stf +application/vnd.xara +application/vnd.xfdl +application/vnd.yellowriver-custom-menu +application/x-123 wk +application/x-abiword abw +application/x-apple-diskimage dmg +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-cdf cdf +application/x-cdlink vcd +application/x-chess-pgn pgn +application/x-core +application/x-cpio cpio +application/x-csh csh +application/x-debian-package deb udeb +application/x-director dcr dir dxr +application/x-dms dms +application/x-doom wad +application/x-dvi dvi +application/x-executable +application/x-flac flac +application/x-font pfa pfb gsf pcf pcf.Z +application/x-freemind mm +application/x-futuresplash spl +application/x-gnumeric gnumeric +application/x-go-sgf sgf +application/x-graphing-calculator gcf +application/x-gtar gtar tgz taz +application/x-hdf hdf +application/x-httpd-php phtml pht php +application/x-httpd-php-source phps +application/x-httpd-php3 php3 +application/x-httpd-php3-preprocessed php3p +application/x-httpd-php4 php4 +application/x-httpd-eruby rhtml +application/x-ica ica +application/x-internet-signup ins isp +application/x-iphone iii +application/x-iso9660-image iso +application/x-java-applet +application/x-java-bean +application/x-java-jnlp-file jnlp +application/x-javascript js +application/x-jmol jmz +application/x-kchart chrt +application/x-kdelnk +application/x-killustrator kil +application/x-koan skp skd skt skm +application/x-kpresenter kpr kpt +application/x-kspread ksp +application/x-kword kwd kwt +application/x-latex latex +application/x-lha lha +application/x-lzh lzh +application/x-lzx lzx +application/x-maker frm maker frame fm fb book fbdoc +application/x-mif mif +application/x-ms-wmd wmd +application/x-ms-wmz wmz +application/x-msdos-program com exe bat dll +application/x-msi msi +application/x-netcdf nc +application/x-ns-proxy-autoconfig pac +application/x-nwc nwc +application/x-object o +application/x-oz-application oza +application/x-pkcs7-certreqresp p7r +application/x-pkcs7-crl crl +application/x-python-code pyc pyo +application/x-quicktimeplayer qtl +application/x-redhat-package-manager rpm +application/x-rx +application/x-sh sh +application/x-shar shar +application/x-shellscript +application/x-shockwave-flash swf swfl +application/x-stuffit sit +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex-gf gf +application/x-tex-pk pk +application/x-texinfo texinfo texi +application/x-trash ~ % bak old sik +application/x-troff t tr roff +application/x-troff-man man +application/x-troff-me me +application/x-troff-ms ms +application/x-ustar ustar +application/x-videolan +application/x-wais-source src +application/x-wingz wz +application/x-x509-ca-cert crt +application/x-xcf xcf +application/x-xfig fig +application/x-xpinstall xpi +application/x-xsd+xml xsd + +audio/32kadpcm +audio/basic au snd +audio/g.722.1 +audio/l16 +audio/midi mid midi kar +audio/mp4a-latm +audio/mpa-robust +audio/mpeg mpga mpega mp2 mp3 m4a +audio/mpegurl m3u +audio/parityfec +audio/prs.sid sid +audio/telephone-event +audio/tone +audio/vnd.cisco.nse +audio/vnd.cns.anp1 +audio/vnd.cns.inf1 +audio/vnd.digital-winds +audio/vnd.everad.plj +audio/vnd.lucent.voice +audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 +audio/vnd.nuera.ecelp7470 +audio/vnd.nuera.ecelp9600 +audio/vnd.octel.sbc +audio/vnd.qcelp +audio/vnd.rhetorex.32kadpcm +audio/vnd.vmx.cvsd +audio/x-aiff aif aiff aifc +audio/x-gsm gsm +audio/x-mpegurl m3u +audio/x-ms-wma wma +audio/x-ms-wax wax +audio/x-pn-realaudio-plugin +audio/x-pn-realaudio ra rm ram +audio/x-realaudio ra +audio/x-scpls pls +audio/x-sd2 sd2 +audio/x-wav wav + +chemical/x-alchemy alc +chemical/x-cache cac cache +chemical/x-cache-csf csf +chemical/x-cactvs-binary cbin cascii ctab +chemical/x-cdx cdx +chemical/x-cerius cer +chemical/x-chem3d c3d +chemical/x-chemdraw chm +chemical/x-cif cif +chemical/x-cmdf cmdf +chemical/x-cml cml +chemical/x-compass cpa +chemical/x-crossfire bsd +chemical/x-csml csml csm +chemical/x-ctx ctx +chemical/x-cxf cxf cef +#chemical/x-daylight-smiles smi +chemical/x-embl-dl-nucleotide emb embl +chemical/x-galactic-spc spc +chemical/x-gamess-input inp gam gamin +chemical/x-gaussian-checkpoint fch fchk +chemical/x-gaussian-cube cub +chemical/x-gaussian-input gau gjc gjf +chemical/x-gaussian-log gal +chemical/x-gcg8-sequence gcg +chemical/x-genbank gen +chemical/x-hin hin +chemical/x-isostar istr ist +chemical/x-jcamp-dx jdx dx +chemical/x-kinemage kin +chemical/x-macmolecule mcm +chemical/x-macromodel-input mmd mmod +chemical/x-mdl-molfile mol +chemical/x-mdl-rdfile rd +chemical/x-mdl-rxnfile rxn +chemical/x-mdl-sdfile sd sdf +chemical/x-mdl-tgf tgf +#chemical/x-mif mif +chemical/x-mmcif mcif +chemical/x-mol2 mol2 +chemical/x-molconn-Z b +chemical/x-mopac-graph gpt +chemical/x-mopac-input mop mopcrt mpc dat zmt +chemical/x-mopac-out moo +chemical/x-mopac-vib mvb +chemical/x-ncbi-asn1 asn +chemical/x-ncbi-asn1-ascii prt ent +chemical/x-ncbi-asn1-binary val aso +chemical/x-ncbi-asn1-spec asn +chemical/x-pdb pdb ent +chemical/x-rosdal ros +chemical/x-swissprot sw +chemical/x-vamas-iso14976 vms +chemical/x-vmd vmd +chemical/x-xtel xtel +chemical/x-xyz xyz + +image/cgm +image/g3fax +image/gif gif +image/ief ief +image/jpeg jpeg jpg jpe +image/naplps +image/pcx pcx +image/png png +image/prs.btif +image/prs.pti +image/svg+xml svg svgz +image/tiff tiff tif +image/vnd.cns.inf2 +image/vnd.djvu djvu djv +image/vnd.dwg +image/vnd.dxf +image/vnd.fastbidsheet +image/vnd.fpx +image/vnd.fst +image/vnd.fujixerox.edmics-mmr +image/vnd.fujixerox.edmics-rlc +image/vnd.mix +image/vnd.net-fpx +image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff +image/x-cmu-raster ras +image/x-coreldraw cdr +image/x-coreldrawpattern pat +image/x-coreldrawtemplate cdt +image/x-corelphotopaint cpt +image/x-icon ico +image/x-jg art +image/x-jng jng +image/x-ms-bmp bmp +image/x-photoshop psd +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd + +inode/chardevice +inode/blockdevice +inode/directory-locked +inode/directory +inode/fifo +inode/socket + +message/delivery-status +message/disposition-notification +message/external-body +message/http +message/s-http +message/news +message/partial +message/rfc822 + +model/iges igs iges +model/mesh msh mesh silo +model/vnd.dwf +model/vnd.flatland.3dml +model/vnd.gdl +model/vnd.gs-gdl +model/vnd.gtw +model/vnd.mts +model/vnd.vtu +model/vrml wrl vrml + +multipart/alternative +multipart/appledouble +multipart/byteranges +multipart/digest +multipart/encrypted +multipart/form-data +multipart/header-set +multipart/mixed +multipart/parallel +multipart/related +multipart/report +multipart/signed +multipart/voice-message + +text/calendar ics icz +text/comma-separated-values csv +text/css css +text/directory +text/english +text/enriched +text/h323 323 +text/html html htm shtml +text/iuls uls +text/mathml mml +text/parityfec +text/plain asc txt text diff pot sql +text/prs.lines.tag +text/rfc822-headers +text/richtext rtx +text/rtf rtf +text/scriptlet sct wsc +text/t140 +text/texmacs tm ts +text/tab-separated-values tsv +text/uri-list +text/vnd.abc +text/vnd.curl +text/vnd.DMClientScript +text/vnd.flatland.3dml +text/vnd.fly +text/vnd.fmi.flexstor +text/vnd.in3d.3dml +text/vnd.in3d.spot +text/vnd.IPTC.NewsML +text/vnd.IPTC.NITF +text/vnd.latex-z +text/vnd.motorola.reflex +text/vnd.ms-mediapackage +text/vnd.sun.j2me.app-descriptor jad +text/vnd.wap.si +text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-bibtex bib +text/x-boo boo +text/x-c++hdr h++ hpp hxx hh +text/x-c++src c++ cpp cxx cc +text/x-chdr h +text/x-component htc +text/x-crontab +text/x-csh csh +text/x-csrc c +text/x-dsrc d +text/x-haskell hs +text/x-java java +text/x-literate-haskell lhs +text/x-makefile +text/x-moc moc +text/x-pascal p pas +text/x-pcs-gcd gcd +text/x-perl pl pm +text/x-python py +text/x-server-parsed-html +text/x-setext etx +text/x-sh sh +text/x-tcl tcl tk +text/x-tex tex ltx sty cls +text/x-vcalendar vcs +text/x-vcard vcf + +video/dl dl +video/dv dif dv +video/fli fli +video/gl gl +video/mpeg mpeg mpg mpe +video/mp4 mp4 +video/quicktime qt mov +video/mp4v-es +video/parityfec +video/pointer +video/vnd.fvt +video/vnd.motorola.video +video/vnd.motorola.videop +video/vnd.mpegurl mxu +video/vnd.mts +video/vnd.nokia.interleaved-multimedia +video/vnd.vivo +video/x-la-asf lsf lsx +video/x-mng mng +video/x-ms-asf asf asx +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie + +x-conference/x-cooltalk ice + +x-world/x-vrml vrm vrml wrl diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/osgi-debug.options b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/osgi-debug.options new file mode 100644 index 0000000000..80e56b83f2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/osgi-debug.options @@ -0,0 +1,95 @@ +#### Debugging options for org.eclipse.osgi + +# Turn on general debugging for org.eclipse.osgi +org.eclipse.osgi/debug=true +# Prints out class loading debug information +org.eclipse.osgi/debug/loader=false +# Prints out event (FrameworkEvent/BundleEvent/ServiceEvent) and listener debug information +org.eclipse.osgi/debug/events=false +# Prints out OSGi service debug information (registration/getting/ungetting etc.) +org.eclipse.osgi/debug/services=false +# Prints out bundle manifest parsing debug information +org.eclipse.osgi/debug/manifest=false +# Prints out LDAP filter debug information +org.eclipse.osgi/debug/filter=false +# Prints out security (PermissionAdmin service) debug information +org.eclipse.osgi/debug/security=false +# Prints out start level service debug information +org.eclipse.osgi/debug/startlevel=true +# Prints out package admin service debug information +org.eclipse.osgi/debug/packageadmin=false +# Prints out timing information for bundle activation +org.eclipse.osgi/debug/bundleTime=false +# Debug the loading of message bundles +org.eclipse.osgi/debug/messageBundles=false + +# Eclipse adaptor options +org.eclipse.osgi/eclipseadaptor/debug = false +org.eclipse.osgi/eclipseadaptor/debug/location = false +org.eclipse.osgi/eclipseadaptor/debug/platformadmin=false +org.eclipse.osgi/eclipseadaptor/debug/platformadmin/resolver=false +org.eclipse.osgi/eclipseadaptor/converter/debug = false + +### OSGi resolver options +# Turns on debugging for the resolver +org.eclipse.osgi/resolver/debug = false +# Prints out wiring information after the resolver has completed the resolve process +org.eclipse.osgi/resolver/wiring = false +# Prints out Import-Package information +org.eclipse.osgi/resolver/imports = false +# Prints out Require-Bundle information +org.eclipse.osgi/resolver/requires = false +# Prints out package grouping information form the "uses" clause +org.eclipse.osgi/resolver/grouping = false +# Prints out cycle information +org.eclipse.osgi/resolver/cycles = false +# Prints out Eclipse-GenericRequire information +org.eclipse.osgi/resolver/generics = false + +#### Profile settings +org.eclipse.osgi/profile/startup = false +org.eclipse.osgi/profile/benchmark = false +org.eclipse.osgi/profile/debug = true + +# Override the default implemenation +org.eclipse.osgi/profile/impl = org.eclipse.osgi.internal.profile.DefaultProfileLogger + +# Append all profile messages to the filename specified +org.eclipse.osgi/defaultprofile/logfilename = + +# Output all profile log messages synchronously to the jvm console. +# By default, all log messages are cached until the log buffer is +# requested. +org.eclipse.osgi/defaultprofile/logsynchronously = false + +# Specify the length of the default profile implementation log buffer. +org.eclipse.osgi/defaultprofile/buffersize = 256 + +#### Monitoring settings +# monitor class loading +org.eclipse.osgi/monitor/classes=false + +# monitor bundle activation +org.eclipse.osgi/monitor/activation=false + +# monitor resource bundle (*.properties) loading +org.eclipse.osgi/monitor/resources=false + + +#### Trace settings +# trace class loading - snapshot the execution stack when a class is loaded +org.eclipse.osgi/trace/classLoading=false + +# trace location - file in which execution traces are written +org.eclipse.osgi/trace/filename=runtime.traces + +# trace filters - Java properties file defining which classes should +# be traced (if trace/classLoading is true) +# File format: +# plugins= +# packages= +# Note that there may be many 'plugins' and 'packages' lines in one file. +org.eclipse.osgi/trace/filters=trace.properties + +# trace bundle activation - snapshot the execution stack when a bundle is activated +org.eclipse.osgi/trace/activation=false diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/tasks-config.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/tasks-config.xml new file mode 100644 index 0000000000..0a9289da70 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/etc/tasks-config.xml @@ -0,0 +1,51 @@ + + + + STANDALONE + + + 2 + + + + org.wso2.carbon.ntask.core.impl.RoundRobinTaskLocationResolver + + + + + + + https://localhost:9448 + + + https://localhost:9443 + + + admin + + + admin + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/log4j.properties b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/log4j.properties new file mode 100644 index 0000000000..9cff0ddf72 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/log4j.properties @@ -0,0 +1,165 @@ +# +# Copyright 2009 WSO2, Inc. (http://wso2.com) +# +# Licensed 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. +# + +# +# This is the log4j configuration file used by WSO2 Carbon +# +# IMPORTANT : Please do not remove or change the names of any +# of the Appenders defined here. The layout pattern & log file +# can be changed using the WSO2 Carbon Management Console, and those +# settings will override the settings in this file. +# + +log4j.rootLogger=INFO, CARBON_CONSOLE, CARBON_LOGFILE, CARBON_MEMORY, CARBON_SYS_LOG + +log4j.logger.AUDIT_LOG=INFO, AUDIT_LOGFILE +log4j.logger.org.apache.axis2.wsdl.codegen.writer.PrettyPrinter=ERROR, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.axis2.clustering=INFO, CARBON_CONSOLE, CARBON_LOGFILE +log4j.logger.org.apache=INFO, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.catalina=WARN +log4j.logger.org.apache.tomcat=WARN +log4j.logger.org.wso2.carbon.apacheds=WARN +log4j.logger.org.apache.directory.server.ldap=ERROR +log4j.logger.org.apache.directory.server.core.event=WARN +log4j.logger.com.atomikos=INFO,ATOMIKOS +log4j.logger.org.quartz=WARN +log4j.logger.org.apache.jackrabbit.webdav=WARN +log4j.logger.org.apache.juddi=ERROR +log4j.logger.org.apache.commons.digester.Digester=WARN +log4j.logger.org.apache.jasper.compiler.TldLocationsCache=WARN +log4j.logger.org.apache.qpid=WARN +log4j.logger.org.apache.qpid.server.Main=INFO +log4j.logger.qpid.message=WARN +log4j.logger.qpid.message.broker.listening=INFO +log4j.logger.org.apache.tiles=WARN +log4j.logger.org.apache.commons.httpclient=ERROR +log4j.logger.org.apache.coyote=WARN +log4j.logger.org.apache.solr=ERROR +log4j.logger.me.prettyprint.cassandra.hector.TimingLogger=ERROR +log4j.logger.org.wso2=INFO +log4j.logger.org.apache.axis2.enterprise=FATAL, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.opensaml.xml=WARN, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.directory.shared.ldap=WARN, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.directory.server.ldap.handlers=WARN, CARBON_LOGFILE, CARBON_MEMORY +#Following are to remove false error messages from startup (IS) +log4j.logger.org.apache.directory.shared.ldap.entry.DefaultServerAttribute=FATAL, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.directory.server.core.DefaultDirectoryService=ERROR, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.directory.shared.ldap.ldif.LdifReader=ERROR, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.directory.server.ldap.LdapProtocolHandler=ERROR, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.directory.server.core=ERROR, CARBON_LOGFILE, CARBON_MEMORY +log4j.logger.org.apache.directory.server.ldap.LdapSession=ERROR, CARBON_LOGFILE, CARBON_MEMORY +#Hive Related Log configurations +log4j.logger.DataNucleus=ERROR +log4j.logger.Datastore=ERROR +log4j.logger.Datastore.Schema=ERROR +log4j.logger.JPOX.Datastore=ERROR +log4j.logger.JPOX.Plugin=ERROR +log4j.logger.JPOX.MetaData=ERROR +log4j.logger.JPOX.Query=ERROR +log4j.logger.JPOX.General=ERROR +log4j.logger.JPOX.Enhancer=ERROR +log4j.logger.org.apache.hadoop.hive=WARN +log4j.logger.hive=WARN +log4j.logger.ExecMapper=WARN +log4j.logger.ExecReducer=WARN +log4j.logger.net.sf.ehcache.config.ConfigurationFactory=ERROR + +log4j.logger.trace.messages=TRACE,CARBON_TRACE_LOGFILE + +log4j.additivity.org.apache.axis2.clustering=false +log4j.additivity.com.atomikos=false +log4j.additivity.org.apache=false + +# CARBON_CONSOLE is set to be a ConsoleAppender using a PatternLayout. +log4j.appender.CARBON_CONSOLE=org.wso2.carbon.utils.logging.appenders.CarbonConsoleAppender +log4j.appender.CARBON_CONSOLE.layout=org.wso2.carbon.utils.logging.TenantAwarePatternLayout +# ConversionPattern will be overridden by the configuration setting in the DB +log4j.appender.CARBON_CONSOLE.layout.ConversionPattern=[%d] %P%5p {%c} - %x %m%n +log4j.appender.CARBON_CONSOLE.layout.TenantPattern=%U%@%D[%T] +log4j.appender.CARBON_CONSOLE.threshold=DEBUG + +# CARBON_MEMORY is set to be a MemoryAppender using a PatternLayout. +log4j.appender.CARBON_MEMORY=org.wso2.carbon.utils.logging.appenders.MemoryAppender +log4j.appender.CARBON_MEMORY.layout=org.apache.log4j.PatternLayout +log4j.appender.CARBON_MEMORY.bufferSize=200 +# ConversionPattern will be overridden by the configuration setting in the DB +#log4j.appender.CARBON_MEMORY.layout.ConversionPattern=[%d] %5p - %x %m {%c}%n +log4j.appender.CARBON_MEMORY.layout.ConversionPattern=[%d] %5p {%c} - %x %m %n +log4j.appender.CARBON_MEMORY.threshold=DEBUG + + +# CARBON_LOGFILE is set to be a DailyRollingFileAppender using a PatternLayout. +log4j.appender.CARBON_LOGFILE=org.wso2.carbon.utils.logging.appenders.CarbonDailyRollingFileAppender +# Log file will be overridden by the configuration setting in the DB +# This path should be relative to WSO2 Carbon Home +log4j.appender.CARBON_LOGFILE.File=${carbon.home}/repository/logs/${instance.log}/wso2carbon${instance.log}.log +log4j.appender.CARBON_LOGFILE.Append=true +log4j.appender.CARBON_LOGFILE.layout=org.wso2.carbon.utils.logging.TenantAwarePatternLayout +# ConversionPattern will be overridden by the configuration setting in the DB +log4j.appender.CARBON_LOGFILE.layout.ConversionPattern=TID: [%T] [%S] [%d] %P%5p {%c} - %x %m %n +log4j.appender.CARBON_LOGFILE.layout.TenantPattern=%U%@%D [%T] [%S] +log4j.appender.CARBON_LOGFILE.threshold=DEBUG + +log4j.appender.CARBON_SYS_LOG = org.apache.log4j.net.SyslogAppender +log4j.appender.CARBON_SYS_LOG.layout=org.apache.log4j.PatternLayout +log4j.appender.CARBON_SYS_LOG.layout.ConversionPattern=[%d] %5p {%c} - %x %m %n +log4j.appender.CARBON_SYS_LOG.SyslogHost=localhost +log4j.appender.CARBON_SYS_LOG.Facility=USER +log4j.appender.CARBON_SYS_LOG.threshold=DEBUG + +# LOGEVENT is set to be a LogEventAppender using a PatternLayout to send logs to LOGEVENT +log4j.appender.LOGEVENT=org.wso2.carbon.logging.service.appender.LogEventAppender +log4j.appender.LOGEVENT.url=tcp://10.100.3.103:7611 +log4j.appender.LOGEVENT.layout=org.wso2.carbon.utils.logging.TenantAwarePatternLayout +log4j.appender.LOGEVENT.columnList=%T,%S,%A,%d,%c,%p,%m,%H,%I,%Stacktrace +log4j.appender.LOGEVENT.userName=admin +log4j.appender.LOGEVENT.password=admin +#log4j.appender.LOGEVENT.password=secretAlias:Log4j.Appender.LOGEVENT.Password + +# Appender config to CARBON_TRACE_LOGFILE +log4j.appender.CARBON_TRACE_LOGFILE=org.apache.log4j.DailyRollingFileAppender +log4j.appender.CARBON_TRACE_LOGFILE.File=${carbon.home}/repository/logs/${instance.log}/wso2carbon-trace-messages${instance.log}.log +log4j.appender.CARBON_TRACE_LOGFILE.Append=true +log4j.appender.CARBON_TRACE_LOGFILE.layout=org.wso2.carbon.utils.logging.TenantAwarePatternLayout +log4j.appender.CARBON_TRACE_LOGFILE.layout.ConversionPattern=[%d] %P%5p {%c} - %x %m %n +log4j.appender.CARBON_TRACE_LOGFILE.layout.TenantPattern=%U%@%D [%T] [%S] +log4j.appender.CARBON_TRACE_LOGFILE.threshold=TRACE +log4j.additivity.trace.messages=false + +# Appender config to AUDIT_LOGFILE +log4j.appender.AUDIT_LOGFILE=org.apache.log4j.DailyRollingFileAppender +log4j.appender.AUDIT_LOGFILE.File=${carbon.home}/repository/logs/audit.log +log4j.appender.AUDIT_LOGFILE.Append=true +log4j.appender.AUDIT_LOGFILE.layout=org.wso2.carbon.utils.logging.TenantAwarePatternLayout +log4j.appender.AUDIT_LOGFILE.layout.ConversionPattern=[%d] %P%5p {%c}- %x %m %n +log4j.appender.AUDIT_LOGFILE.layout.TenantPattern=%U%@%D [%T] [%S] +log4j.appender.AUDIT_LOGFILE.threshold=INFO +log4j.additivity.AUDIT_LOG=false + +# Appender config to send Atomikos transaction logs to new log file tm.out. +log4j.appender.ATOMIKOS = org.apache.log4j.RollingFileAppender +log4j.appender.ATOMIKOS.File = repository/logs/tm.out +log4j.appender.ATOMIKOS.Append = true +log4j.appender.ATOMIKOS.layout = org.apache.log4j.PatternLayout +log4j.appender.ATOMIKOS.layout.ConversionPattern=%p %t %c - %m%n + +# This file is used to override the default logger settings, and is used to remove unwanted logs from Shindig appearing on the console. + +# Specification of Handler used by Console Logger +handlers=java.util.logging.ConsoleHandler + +# Replacing default INFO level with SEVERE +java.util.logging.ConsoleHandler.level=SEVERE diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/registry.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/registry.xml new file mode 100644 index 0000000000..791daac83d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/registry.xml @@ -0,0 +1,108 @@ + + + + + + + + wso2registry + false + true + / + + + jdbc:h2:./target/databasetest/CARBON_TEST + + org.h2.Driver + 80 + 60000 + 5 + + + + + + + + + + + + false + + + + true + true + true + true + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/security/authenticators.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/security/authenticators.xml new file mode 100644 index 0000000000..765d0b8e13 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/security/authenticators.xml @@ -0,0 +1,75 @@ + + + + + + + + + + 5 + + + + + 10 + + /carbon/admin/login.jsp + carbonServer + https://localhost:9443/samlsso + urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/carbon/META-INF/context.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/carbon/META-INF/context.xml new file mode 100644 index 0000000000..42e0d7fc1e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/carbon/META-INF/context.xml @@ -0,0 +1,33 @@ + + + + + + + WEB-INF/web.xml + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/carbon/WEB-INF/web.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/carbon/WEB-INF/web.xml new file mode 100644 index 0000000000..16ec925053 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/carbon/WEB-INF/web.xml @@ -0,0 +1,61 @@ + + + + + + + bridgeservlet + Carbon Bridge Servlet + Carbon Bridge Servlet + org.wso2.carbon.tomcat.ext.servlet.DelegationServlet + + 1 + + + bridgeservlet + /* + + + + bridgeservlet + *.jsp + + + + + CharsetFilter + org.wso2.carbon.tomcat.ext.filter.CharacterSetFilter + + requestEncoding + UTF-8 + + + + + CharsetFilter + /* + + + + 15 + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/catalina-server.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/catalina-server.xml new file mode 100644 index 0000000000..8347929309 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/catalina-server.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/tomcat-users.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/tomcat-users.xml new file mode 100644 index 0000000000..7ef7dbb0a1 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/tomcat-users.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/web.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/web.xml new file mode 100644 index 0000000000..db1c2af366 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/tomcat/web.xml @@ -0,0 +1,1222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + org.apache.catalina.servlets.DefaultServlet + + debug + 0 + + + sendfileSize + -1 + + + listings + false + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jsp + org.apache.jasper.servlet.JspServlet + + fork + false + + + xpoweredBy + false + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jsp + *.jsp + + + + jsp + *.jspx + + + + default + / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 30 + + + + + + + + + + + + abs + audio/x-mpeg + + + ai + application/postscript + + + aif + audio/x-aiff + + + aifc + audio/x-aiff + + + aiff + audio/x-aiff + + + aim + application/x-aim + + + art + image/x-jg + + + asf + video/x-ms-asf + + + asx + video/x-ms-asf + + + au + audio/basic + + + avi + video/x-msvideo + + + avx + video/x-rad-screenplay + + + bcpio + application/x-bcpio + + + bin + application/octet-stream + + + bmp + image/bmp + + + body + text/html + + + cdf + application/x-cdf + + + cer + application/x-x509-ca-cert + + + class + application/java + + + cpio + application/x-cpio + + + csh + application/x-csh + + + css + text/css + + + dib + image/bmp + + + doc + application/msword + + + dtd + application/xml-dtd + + + dv + video/x-dv + + + dvi + application/x-dvi + + + eps + application/postscript + + + etx + text/x-setext + + + exe + application/octet-stream + + + gif + image/gif + + + gtar + application/x-gtar + + + gz + application/x-gzip + + + hdf + application/x-hdf + + + hqx + application/mac-binhex40 + + + htc + text/x-component + + + htm + text/html + + + html + text/html + + + ief + image/ief + + + jad + text/vnd.sun.j2me.app-descriptor + + + jar + application/java-archive + + + java + text/plain + + + jnlp + application/x-java-jnlp-file + + + jpe + image/jpeg + + + jpeg + image/jpeg + + + jpg + image/jpeg + + + js + application/javascript + + + jsf + text/plain + + + jspf + text/plain + + + kar + audio/x-midi + + + latex + application/x-latex + + + m3u + audio/x-mpegurl + + + mac + image/x-macpaint + + + man + application/x-troff-man + + + mathml + application/mathml+xml + + + me + application/x-troff-me + + + mid + audio/x-midi + + + midi + audio/x-midi + + + mif + application/x-mif + + + mov + video/quicktime + + + movie + video/x-sgi-movie + + + mp1 + audio/x-mpeg + + + mp2 + audio/x-mpeg + + + mp3 + audio/x-mpeg + + + mp4 + video/mp4 + + + mpa + audio/x-mpeg + + + mpe + video/mpeg + + + mpeg + video/mpeg + + + mpega + audio/x-mpeg + + + mpg + video/mpeg + + + mpv2 + video/mpeg2 + + + ms + application/x-wais-source + + + nc + application/x-netcdf + + + oda + application/oda + + + + odb + application/vnd.oasis.opendocument.database + + + + odc + application/vnd.oasis.opendocument.chart + + + + odf + application/vnd.oasis.opendocument.formula + + + + odg + application/vnd.oasis.opendocument.graphics + + + + odi + application/vnd.oasis.opendocument.image + + + + odm + application/vnd.oasis.opendocument.text-master + + + + odp + application/vnd.oasis.opendocument.presentation + + + + ods + application/vnd.oasis.opendocument.spreadsheet + + + + odt + application/vnd.oasis.opendocument.text + + + + otg + application/vnd.oasis.opendocument.graphics-template + + + + oth + application/vnd.oasis.opendocument.text-web + + + + otp + application/vnd.oasis.opendocument.presentation-template + + + + ots + application/vnd.oasis.opendocument.spreadsheet-template + + + + ott + application/vnd.oasis.opendocument.text-template + + + + ogx + application/ogg + + + ogv + video/ogg + + + oga + audio/ogg + + + ogg + audio/ogg + + + spx + audio/ogg + + + flac + audio/flac + + + anx + application/annodex + + + axa + audio/annodex + + + axv + video/annodex + + + xspf + application/xspf+xml + + + pbm + image/x-portable-bitmap + + + pct + image/pict + + + pdf + application/pdf + + + pgm + image/x-portable-graymap + + + pic + image/pict + + + pict + image/pict + + + pls + audio/x-scpls + + + png + image/png + + + pnm + image/x-portable-anymap + + + pnt + image/x-macpaint + + + ppm + image/x-portable-pixmap + + + ppt + application/vnd.ms-powerpoint + + + pps + application/vnd.ms-powerpoint + + + ps + application/postscript + + + psd + image/x-photoshop + + + qt + video/quicktime + + + qti + image/x-quicktime + + + qtif + image/x-quicktime + + + ras + image/x-cmu-raster + + + rdf + application/rdf+xml + + + rgb + image/x-rgb + + + rm + application/vnd.rn-realmedia + + + roff + application/x-troff + + + rtf + application/rtf + + + rtx + text/richtext + + + sh + application/x-sh + + + shar + application/x-shar + + + + smf + audio/x-midi + + + sit + application/x-stuffit + + + snd + audio/basic + + + src + application/x-wais-source + + + sv4cpio + application/x-sv4cpio + + + sv4crc + application/x-sv4crc + + + svg + image/svg+xml + + + svgz + image/svg+xml + + + swf + application/x-shockwave-flash + + + t + application/x-troff + + + tar + application/x-tar + + + tcl + application/x-tcl + + + tex + application/x-tex + + + texi + application/x-texinfo + + + texinfo + application/x-texinfo + + + tif + image/tiff + + + tiff + image/tiff + + + tr + application/x-troff + + + tsv + text/tab-separated-values + + + txt + text/plain + + + ulw + audio/basic + + + ustar + application/x-ustar + + + vxml + application/voicexml+xml + + + xbm + image/x-xbitmap + + + xht + application/xhtml+xml + + + xhtml + application/xhtml+xml + + + xls + application/vnd.ms-excel + + + xml + application/xml + + + xpm + image/x-xpixmap + + + xsl + application/xml + + + xslt + application/xslt+xml + + + xul + application/vnd.mozilla.xul+xml + + + xwd + image/x-xwindowdump + + + vsd + application/x-visio + + + wav + audio/x-wav + + + + wbmp + image/vnd.wap.wbmp + + + + wml + text/vnd.wap.wml + + + + wmlc + application/vnd.wap.wmlc + + + + wmls + text/vnd.wap.wmlscript + + + + wmlscriptc + application/vnd.wap.wmlscriptc + + + wmv + video/x-ms-wmv + + + wrl + x-world/x-vrml + + + wspolicy + application/wspolicy+xml + + + Z + application/x-compress + + + z + application/x-compress + + + zip + application/zip + + + + + + + + + + + + + + + + + + index.html + index.htm + index.jsp + + + \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/user-mgt.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/user-mgt.xml new file mode 100644 index 0000000000..76099de1c3 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/carbon-home/repository/conf/user-mgt.xml @@ -0,0 +1,382 @@ + + + + + + true + admin + + admin + admin + + everyone + jdbc/WSO2CarbonDB + + + + + + + org.wso2.carbon.user.core.tenant.JDBCTenantManager + false + 100 + false + default + SHA-256 + true + true + true + false + ^[\S]{5,30}$ + Password length should be between 5 to 30 characters + + ^[\S]{5,30}$ + [a-zA-Z0-9._-|//]{3,30}$ + ^[\S]{3,30}$ + ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$ + ^[\S]{3,30}$ + true + 100 + 100 + false + false + true + , + true + + + + + + + + + + + + + + + + + + + /permission + true + true + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/datasource/data-source-config.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/datasource/data-source-config.xml new file mode 100644 index 0000000000..0f4970c669 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/datasource/data-source-config.xml @@ -0,0 +1,40 @@ + + + + + + + + + + jdbc:h2:mem:app-test-db;DB_CLOSE_DELAY=-1 + org.h2.Driver + wso2carbon + wso2carbon + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/h2.sql b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/h2.sql new file mode 100644 index 0000000000..15221c81d0 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/h2.sql @@ -0,0 +1,30 @@ +CREATE TABLE APPM_PLATFORM ( +ID INT NOT NULL AUTO_INCREMENT, +IDENTIFIER VARCHAR (100) NOT NULL, +TENANT_DOMAIN VARCHAR (100) NOT NULL , +NAME VARCHAR (255), +FILE_BASED BOOLEAN, +DESCRIPTION LONGVARCHAR, +IS_SHARED BOOLEAN, +ICON_NAME VARCHAR (100), +PRIMARY KEY (ID, IDENTIFIER, TENANT_DOMAIN) +); + +CREATE TABLE APPM_PLATFORM_PROPERTIES ( +ID INT NOT NULL AUTO_INCREMENT, +PLATFORM_ID INTEGER NOT NULL, +PROP_NAME VARCHAR (100) NOT NULL, +OPTIONAL BOOLEAN, +DEFAUL_VALUE VARCHAR (255), +FOREIGN KEY(PLATFORM_ID) REFERENCES APPM_PLATFORM(ID) ON DELETE CASCADE, +PRIMARY KEY (ID, PLATFORM_ID, PROP_NAME) +); + +CREATE TABLE APPM_PLATFORM_TENANT_MAPPING ( +ID INT NOT NULL AUTO_INCREMENT, +TENANT_DOMAIN VARCHAR (100) NOT NULL , +PLATFORM_ID VARCHAR (100) NOT NULL, +FOREIGN KEY(PLATFORM_ID) REFERENCES APPM_PLATFORM(ID) ON DELETE CASCADE, +PRIMARY KEY (ID, TENANT_DOMAIN, PLATFORM_ID) +) + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/log4j.properties b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/log4j.properties similarity index 88% rename from components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/log4j.properties rename to components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/log4j.properties index 90c5d0edce..3bc6b301e2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/log4j.properties +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/log4j.properties @@ -1,7 +1,7 @@ # -# Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +# Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. # -# WSO2 Inc. licenses this file to you under the Apache License, +# Entgra (pvt) Ltd. 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 diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/banner1.jpg b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/banner1.jpg new file mode 100644 index 0000000000..e8c57421c2 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/banner1.jpg differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/icon.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/icon.png new file mode 100644 index 0000000000..df25ec4e45 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/icon.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/sample.apk b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/sample.apk new file mode 100644 index 0000000000..10dfe26209 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/sample.apk differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot1.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot1.png new file mode 100644 index 0000000000..df25ec4e45 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot1.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot2.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot2.png new file mode 100644 index 0000000000..df25ec4e45 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot2.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot3.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot3.png new file mode 100644 index 0000000000..df25ec4e45 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app1/shot3.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/banner1.jpg b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/banner1.jpg new file mode 100644 index 0000000000..e8c57421c2 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/banner1.jpg differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/icon.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/icon.png new file mode 100644 index 0000000000..df25ec4e45 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/icon.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/sample_4.0.6.apk b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/sample_4.0.6.apk new file mode 100644 index 0000000000..4f507832be Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/sample_4.0.6.apk differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot1.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot1.png new file mode 100644 index 0000000000..df25ec4e45 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot1.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot2.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot2.png new file mode 100644 index 0000000000..df25ec4e45 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot2.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot3.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot3.png new file mode 100644 index 0000000000..df25ec4e45 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/samples/app2/shot3.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/testng.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/testng.xml new file mode 100644 index 0000000000..b9fad1fe6a --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/testng.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/user-test/user-mgt-registry-test.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/user-test/user-mgt-registry-test.xml new file mode 100644 index 0000000000..41968aab7e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/user-test/user-mgt-registry-test.xml @@ -0,0 +1,101 @@ + + + + + true + admin + + admin + admin + + everyone + false + 500 + jdbc:h2:target/databasetest/CARBON_TEST + org.h2.Driver + 50 + 60000 + 5 + + + [\S]{5,30}$ + [\\S]{5,30} + SELECT * FROM UM_USER WHERE UM_USER_NAME=? AND UM_TENANT_ID=? + + + + + + + + + + + + + + + + SHA-256 + true + false + false + wso2.com + true + 100 + + + INSERT INTO UM_ROLE (UM_ROLE_NAME, UM_TENANT_ID) VALUES (?, ?) + + + + + + + + + + + + + + + + + org.wso2.carbon.user.core.tenant.JDBCTenantManager + + + true + + + + login + manage-configuration + manage-security + upload-services + manage-services + manage-lc-configuration + manage-mediation + monitor-system + delegate-identity + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/util/app-debug.apk b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/util/app-debug.apk new file mode 100644 index 0000000000..52bb95ed21 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/util/app-debug.apk differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/util/iOSMDMAgent.ipa b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/util/iOSMDMAgent.ipa new file mode 100644 index 0000000000..13af8f3cdb Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/util/iOSMDMAgent.ipa differ diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/pom.xml similarity index 65% rename from components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/pom.xml rename to components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/pom.xml index c769eec465..4235a691d1 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/pom.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/pom.xml @@ -1,82 +1,48 @@ +~ Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. +~ +~ Entgra (pvt) Ltd. 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. +--> - certificate-mgt + application-mgt org.wso2.carbon.devicemgt 4.0.0-SNAPSHOT ../pom.xml 4.0.0 - org.wso2.carbon.certificate.mgt.v09.api + org.wso2.carbon.device.application.mgt.publisher.api + 4.0.0-SNAPSHOT war - WSO2 Carbon - Certificate Management v09 API - WSO2 Carbon - Certificate Management v09 API - http://wso2.org + WSO2 Carbon - Application Management Publisher API + WSO2 Carbon - Application Management Publisher API + https://entgra.io - - maven-compiler-plugin - - 1.8 - 1.8 - - maven-war-plugin WEB-INF/lib/*cxf*.jar - api#scep-mgt#v0.9 + api#application-mgt-publisher#v1.0 - - org.jacoco - jacoco-maven-plugin - - ${basedir}/target/coverage-reports/jacoco-unit.exec - - - - jacoco-initialize - - prepare-agent - - - - jacoco-site - test - - report - - - ${basedir}/target/coverage-reports/jacoco-unit.exec - ${basedir}/target/coverage-reports/site - - - - @@ -89,7 +55,7 @@ org.apache.maven.plugins maven-antrun-plugin - 1.7 + 1.8 compile @@ -100,7 +66,7 @@ - + @@ -119,7 +85,7 @@ org.codehaus.mojo exec-maven-plugin - 1.2.1 + 1.5.0 test @@ -138,43 +104,63 @@ org.apache.cxf cxf-rt-frontend-jaxws - - - commons-codec.wso2 - commons-codec - - - commons-codec - commons-codec - - + 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.certificate.mgt.core + org.wso2.carbon.device.application.mgt.core + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.application.mgt.common provided @@ -186,13 +172,17 @@ swagger-core - org.wso2.orbit.com.fasterxml.jackson.core - jackson-annotations + com.fasterxml.jackson.module + jackson-module-jaxb-annotations org.slf4j slf4j-api + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-core + @@ -207,11 +197,15 @@ org.slf4j slf4j-api + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-core + javax.servlet - servlet-api + javax.servlet-api provided @@ -219,6 +213,13 @@ org.wso2.carbon.apimgt.annotations provided + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-annotations + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.application.mgt.addons + - - + \ No newline at end of file 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/ApplicationManagementPublisherAPI.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/ApplicationManagementPublisherAPI.java new file mode 100644 index 0000000000..f157e98cba --- /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/ApplicationManagementPublisherAPI.java @@ -0,0 +1,1439 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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.common.ApplicationList; +import org.wso2.carbon.device.application.mgt.common.ErrorResponse; +import org.wso2.carbon.device.application.mgt.common.Filter; +import org.wso2.carbon.device.application.mgt.common.LifecycleChanger; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; +import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; +import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppWrapper; + +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 Publisher Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ApplicationManagementPublisherService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt-publisher/v1.0/applications"), + }) + } + ), + tags = { + @Tag(name = "application_management, device_management", description = "App publisher related APIs") + } +) +@Scopes( + scopes = { + @Scope( + name = "Get ApplicationDTO Details", + description = "Get application details", + key = "perm:app:publisher:view", + permissions = {"/app-mgt/publisher/application/view"} + ), + @Scope( + name = "Update an ApplicationDTO", + description = "Update an application", + key = "perm:app:publisher:update", + permissions = {"/app-mgt/publisher/application/update"} + ) + } +) +@Path("/applications") +@Api(value = "ApplicationDTO Management") +@Produces(MediaType.APPLICATION_JSON) +public interface ApplicationManagementPublisherAPI { + + String SCOPE = "scope"; + + @POST + @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 = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully got application list.", + response = ApplicationList.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Application retrieving request payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the application list.", + response = ErrorResponse.class) + }) Response getApplications( + @ApiParam( + name = "Filter", + value = "Get application filter", + required = true) + @Valid Filter filter); + + @GET + @Path("/{appId}") + @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 id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved relevant application.", + response = ApplicationDTO.class), + @ApiResponse( + code = 403, + message = "Don't have permission to access the application"), + @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 = "appId", + value = "application Id", + required = true) + @PathParam("appId") int appId, + @ApiParam( + name = "state", + value = "state") + @QueryParam("state") String state + ); + + @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 the application release of requesting application UUID and state", + notes = "This will get the application release identified by the application release uuid and state.", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved relevant application release.", + response = ApplicationDTO.class), + @ApiResponse( + code = 403, + message = "Don't have permission to access the application release"), + @ApiResponse( + code = 404, + message = "Application release not found"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting relevant application release.", + response = ErrorResponse.class) + }) + Response getApplicationByUUID( + @ApiParam( + name = "uuid", + value = "application release uuid", + required = true) + @PathParam("uuid") String uuid + ); + + @PUT + @Path("/{appId}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Edit an application", + notes = "This will edit the new application", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully edited the application.", + response = ApplicationDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO updating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while editing the application.", + response = ErrorResponse.class) + }) + Response updateApplication( + @ApiParam( + name = "appId", + value = "application Id", + required = true) + @PathParam("appId") int appId, + @ApiParam( + name = "application", + value = "Application data that need to be edited.", + required = true) + @Valid ApplicationUpdateWrapper applicationUpdateWrapper + ); + + @POST + @Path("/ent-app") + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an application", + notes = "This will create a new application", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application.", + response = ApplicationDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the application.", + response = ErrorResponse.class) + }) + Response createEntApp( + @ApiParam( + name = "application", + value = "The application that need to be created.", + required = true) + @Multipart("application") ApplicationWrapper application, + @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") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading application", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + + @POST + @Path("/web-app") + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an web app", + notes = "This will create a new web app", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created a web application.", + response = ApplicationDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Web app creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the web app.", + response = ErrorResponse.class) + }) + Response createWebApp( + @ApiParam( + name = "webapp", + value = "The web app that need to be created.", + required = true) + @Multipart("webapp") WebAppWrapper webAppWrapper, + @ApiParam( + name = "icon", + value = "Icon of the uploading web app", + required = true) + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading web app") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading web app", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading web app", + required = false) + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading web app", + required = false) + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + + @POST + @Path("/public-app") + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an public app", + notes = "This will create a new public app", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created a public app.", + response = ApplicationDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "public app creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the public app.", + response = ErrorResponse.class) + }) + Response createPubApp( + @ApiParam( + name = "public-app", + value = "The public app that need to be created.", + required = true) + @Multipart("public-app") PublicAppWrapper publicAppWrapper, + @ApiParam( + name = "icon", + value = "Icon of the uploading public app", + required = true) + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading public app") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading public app", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading public app") + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading public app") + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + + @POST + @Path("/custom-app") + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an custom application", + notes = "This will create a new custom application", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application.", + response = ApplicationDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the application.", + response = ErrorResponse.class) + }) + Response createCustomApp( + @ApiParam( + name = "application", + value = "The application that need to be created.", + required = true) + @Multipart("application") CustomAppWrapper customAppWrapper, + @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") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading application", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/{deviceType}/ent-app/{appId}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an application", + notes = "This will create a new application", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application.", + response = ApplicationRelease.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the application.", + response = ErrorResponse.class) + }) + Response createEntAppRelease( + @ApiParam( + name = "deviceType", + value = "Device type that application is compatible with.", + required = true) + @PathParam("deviceType") String deviceType, + @ApiParam( + name = "appId", + value = "Id of the application.", + required = true) + @PathParam("appId") int appId, + @ApiParam( + name = "applicationRelease", + value = "The application release that need to be created.", + required = true) + @Multipart("applicationRelease") EntAppReleaseWrapper entAppReleaseWrapper, + @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") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading application", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + + @PUT + @Consumes("application/json") + @Path("/retire/{appId}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Retire the application with the given UUID", + notes = "This will retire the application with the given UUID", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the application identified by UUID.", + response = List.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting the application.", + response = ErrorResponse.class), + @ApiResponse( + code = 403, + message = "Don't have permission to delete the application"), + @ApiResponse( + code = 404, + message = "Application not found"), + }) + Response retireApplication( + @ApiParam( + name = "UUID", + value = "Unique identifier of the ApplicationDTO", + required = true) + @PathParam("appId") int applicationId + ); + + @PUT + @Path("/image-artifacts/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", 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 = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated artifacts."), + @ApiResponse( + code = 403, + message = "FORBIDDEN. \n Can't Update the application release in PUBLISHED or DEPRECATED " + + "state. Hence please demote the application and update the application release"), + @ApiResponse( + code = 404, + message = "NOT FOUND. \n Error occurred while updating the application."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the application list.", + response = ErrorResponse.class) + }) + Response updateApplicationImageArtifacts( + @ApiParam( + name = "uuid", + value = "UUID of the application", + required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "icon", + value = "Icon of the uploading application") + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading application") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading application") + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading application") + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading application") + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + + @PUT + @Path("/ent-app-artifacts/{deviceType}/{appId}/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", 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 = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully uploaded artifacts."), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO artifact updating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 404, + message = "NOT FOUND. \n Couldn't found application/application release to update applocation release artifact."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the application list.", + response = ErrorResponse.class) + }) + Response updateApplicationArtifact( + @ApiParam( + name = "deviceType", + value = "Type of the device i.e Android, IOS etc", + required = true) + @PathParam("deviceType") String deviceType, + @ApiParam( + name = "uuid", + value = "UUID of the application", + required = true) + @PathParam("uuid") String applicationUUID, + @Multipart("binaryFile") Attachment binaryFile + ); + + @PUT + @Path("/ent-app-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:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application release.", + response = ApplicationReleaseDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO release updating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + Response updateEntAppRelease( + @ApiParam( + name = "UUID", + value = "Unique identifier of the ApplicationDTO Release", + required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "entAppReleaseWrapper", + value = "Application release wrapper which is going to update.", + required = true) + @Multipart( + value = "entAppReleaseWrapper", + type = "application/json") EntAppReleaseWrapper entAppReleaseWrapper, + @ApiParam( + name = "binaryFile", + value = "Application installer file.", + required = true) + @Multipart(value = "binaryFile") Attachment binaryFile, + @ApiParam( + name = "icon", + value = "Icon file of the application release.") + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "banner file of the application release.") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "First screenshot of the uploading application") + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Second screenshot 2 of the uploading application") + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Third screenshot of the uploading application") + @Multipart(value = "screenshot3") Attachment screenshot3); + + @PUT + @Path("/public-app-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 public app release", + notes = "This will update the public app release", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully update an app release.", + response = ApplicationReleaseDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Public app release updating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + Response updatePubAppRelease( + @ApiParam( + name = "UUID", + value = "Unique identifier of the ApplicationDTO Release", + required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "pubAppReleaseWrapper", + value = "Application release wrapper which is going to update.", + required = true) + @Multipart( + value = "pubAppReleaseWrapper", + type = "application/json") PublicAppReleaseWrapper publicAppReleaseWrapper, + @ApiParam( + name = "icon", + value = "Icon file of the application release.") + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "banner file of the application release.") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "First screenshot of the uploading application") + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Second screenshot 2 of the uploading application") + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Third screenshot of the uploading application") + @Multipart(value = "screenshot3") Attachment screenshot3); + + @PUT + @Path("/web-app-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 public app release", + notes = "This will update the public app release", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully update an app release.", + response = ApplicationReleaseDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Public app release updating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + Response updateWebAppRelease( + @ApiParam( + name = "UUID", + value = "Unique identifier of the ApplicationDTO Release", + required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "pubAppReleaseWrapper", + value = "Application release wrapper which is going to update.", + required = true) + @Multipart( + value = "pubAppReleaseWrapper", + type = "application/json") WebAppReleaseWrapper webAppReleaseWrapper, + @ApiParam( + name = "icon", + value = "Icon file of the application release.") + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "banner file of the application release.") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "First screenshot of the uploading application") + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Second screenshot 2 of the uploading application") + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Third screenshot of the uploading application") + @Multipart(value = "screenshot3") Attachment screenshot3); + + @PUT + @Path("/custom-app-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 custom application release", + notes = "This will update a custom app release", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application release.", + response = ApplicationReleaseDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO release updating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + Response updateCustomAppRelease( + @ApiParam( + name = "UUID", + value = "Unique identifier of the ApplicationDTO Release", + required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "entAppReleaseWrapper", + value = "Application release wrapper which is going to update.", + required = true) + @Multipart( + value = "entAppReleaseWrapper", + type = "application/json") CustomAppReleaseWrapper customAppReleaseWrapper, + @ApiParam( + name = "binaryFile", + value = "Application installer file.", + required = true) + @Multipart(value = "binaryFile") Attachment binaryFile, + @ApiParam( + name = "icon", + value = "Icon file of the application release.") + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "banner file of the application release.") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "First screenshot of the uploading application") + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Second screenshot 2 of the uploading application") + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Third screenshot of the uploading application") + @Multipart(value = "screenshot3") Attachment screenshot3); + + @GET + @Path("/life-cycle/state-changes/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get lifecycle states", + notes = "Get all lifecycle states", + tags = "Lifecycle Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved lifecycle states.", + response = List.class, + responseContainer = "List"), + @ApiResponse( + code = 404, + message = "NOT FOUND. \n Couldn't found an application release for application release UUID."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the lifecycle list.", + response = ErrorResponse.class) + }) + Response getLifecycleStates( + @ApiParam( + name = "uuid", + value = "UUID of the application release.") + @PathParam("uuid") String applicationUuid); + + @POST + @Path("/life-cycle/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Add a lifecycle state", + notes = "This will add a new lifecycle state", + tags = "Lifecycle Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully add a lifecycle state.", + response = ApplicationDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Lifecycle State changing request contains unacceptable or vulnerable data"), + @ApiResponse( + code = 403, + message = "Don't have permission to move the lifecycle state of a given application release" + + " to the given lifecycle state."), + @ApiResponse( + code = 404, + message = "NOT FOUND. \n Error occurred while adding new lifecycle state.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred adding a lifecycle state.", + response = ErrorResponse.class) + }) + Response addLifecycleState( + @ApiParam( + name = "uuid", + value = "UUID of the ApplicationDTO Release", + required = true) + @PathParam("uuid") String applicationUuid, + @ApiParam( + name = "LifecycleChanger", + value = "Lifecycle Changer which contains the action and the reason for the lifecycle change.", + required = true) + @Valid LifecycleChanger lifecycleChanger + ); + + @GET + @Path("/lifecycle-config") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get application management UI configuration", + notes = "This will get all UI configuration of application management", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully got Lifecycle Config.", + response = ApplicationList.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the lifecycle config.", + response = ErrorResponse.class) + }) + Response getLifecycleConfig(); + + @GET + @Path("/tags") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get registered application tags", + notes = "This will get registered application tags", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully got Application tags.", + response = ApplicationList.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting application tags.", + response = ErrorResponse.class) + }) + Response getTags(); + + @DELETE + @Path("/{appId}/tags/{tagName}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get registered application tags", + notes = "This will get registered application tags", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully delete Application tags.", + response = ApplicationList.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Given tag is not an associated tag for the given application."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting application tags.", + response = ErrorResponse.class) + }) + Response deleteApplicationTag( + @ApiParam( + name = "appId", + value = "ID of the Application", + required = true) + @PathParam("appId") int applicationId, + @ApiParam( + name = "tagName", + value = "Tag Name", + required = true) + @PathParam("tagName") String tagName + ); + + @DELETE + @Path("/tags/{tagName}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Delete application tag", + notes = "This will delete application tag", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully delete registered tag.", + response = ApplicationList.class), + @ApiResponse( + code = 403, + message = "Don't have permission to delete the application tag."), + @ApiResponse( + code = 404, + message = "NOT FOUND. \n Couldn't found a tag for the given tag name.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting registered tag.", + response = ErrorResponse.class) + }) + Response deleteUnusedTag( + @ApiParam( + name = "tagName", + value = "Tag Name", + required = true) + @PathParam("tagName") String tagName + ); + + @PUT + @Path("/tags/rename") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "update an application tag", + notes = "This will update application tag", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully update the registered tag.", + response = ApplicationList.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Request contains unaccepted values for query parameters."), + @ApiResponse( + code = 404, + message = "NOT FOUND. \n Couldn't found a tag for the given tag name.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while updating registered tag.", + response = ErrorResponse.class) + }) + Response modifyTagName( + @ApiParam( + name = "oldTagName", + value = "Existing Tag Name", + required = true) + @QueryParam("from") String oldTagName, + @ApiParam( + name = "newTagName", + value = "Modifying Tag Name", + required = true) + @QueryParam("to") String newTagName + ); + + @POST + @Path("/tags") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Add new tags.", + notes = "This will add new tags for the system", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully add tags.", + response = ApplicationList.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Tag adding request contains unacceptable payload."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while adding new tags.", + response = ErrorResponse.class) + }) + Response addTags( + @ApiParam( + name = "oldTagName", + value = "Existing Tag Name", + required = true) + List tagNames + ); + + @POST + @Path("/{appId}/tags") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Add new application tags", + notes = "This will add new application tags", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully add application tags.", + response = ApplicationList.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Application tag adding request contains unacceptable payload."), + @ApiResponse( + code = 404, + message = "NOT FOUND. \n Couldn't found an application for the given application id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while adding new application tags.", + response = ErrorResponse.class) + }) + Response addApplicationTags( + @ApiParam( + name = "oldTagName", + value = "Existing Tag Name", + required = true) + @PathParam("appId") int appId, + @ApiParam( + name = "appId", + value = "application Id", + required = true) + List tagNames + ); + + @GET + @Path("/categories") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get registered application categories", + notes = "This will get registered application categories.", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully got application categories.", + response = ApplicationList.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting application categories.", + response = ErrorResponse.class) + }) + Response getCategories(); + +} 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/admin/ApplicationManagementPublisherAdminAPI.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/admin/ApplicationManagementPublisherAdminAPI.java new file mode 100644 index 0000000000..8b3a1117f3 --- /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/admin/ApplicationManagementPublisherAdminAPI.java @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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.admin; + +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.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.application.mgt.common.ApplicationList; +import org.wso2.carbon.device.application.mgt.common.ErrorResponse; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +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; +import java.util.List; + +/** + * APIs to handle application management related tasks. + */ +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "ApplicationDTO Management Publisher Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ApplicationManagementPublisherAdminService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt-publisher/v1.0/admin/applications"), + }) + } + ), + tags = { + @Tag(name = "application_management, device_management", description = "App publisher related Admin APIs") + } +) +@Scopes( + scopes = { + @Scope( + name = "Delete Application Release", + description = "Delete Application Release", + key = "perm:admin:app:publisher:update", + permissions = {"/app-mgt/publisher/admin/application/update"} + ) + } +) +@Path("/admin/applications") +@Api(value = "ApplicationDTO Management") +@Produces(MediaType.APPLICATION_JSON) +public interface ApplicationManagementPublisherAdminAPI { + + String SCOPE = "scope"; + + @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 application release.", + notes = "This will delete application release for given UUID", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully delete application release.", + response = ApplicationList.class), + @ApiResponse( + code = 404, + message = "Not Found. There doesn't have an application release for UUID" + + "query."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting application release.", + response = ErrorResponse.class) + }) Response deleteApplicationRelease( + @ApiParam( + name = "uuid", + value = "application release UUID", + required = true) + @PathParam("uuid") String releaseUuid); + + @DELETE + @Path("/{appId}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Delete application release.", + notes = "This will delete application release for given UUID", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully delete application release.", + response = ApplicationList.class), + @ApiResponse( + code = 404, + message = "Not Found. There doesn't have an application release for UUID" + + "query."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting application release.", + response = ErrorResponse.class) + }) Response deleteApplication( + @ApiParam( + name = "appId", + value = "application ID", + required = true) + @PathParam("appId") int applicatioId); + + @DELETE + @Path("/tags/{tagName}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Delete application tag", + notes = "This will delete application tag", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully delete registered tag.", + response = ApplicationList.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting registered tag.", + response = ErrorResponse.class) + }) + Response deleteTag( + @ApiParam( + name = "tagName", + value = "Tag Name", + required = true) + @PathParam("tagName") String tagName + ); + + @POST + @Path("/categories") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Add new application categories.", + notes = "This will add new application categories", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully delete registered tag.", + response = ApplicationList.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Category list is either empty or null"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting registered tag.", + response = ErrorResponse.class) + }) + Response addCategories( + @ApiParam( + name = "tagName", + value = "Tag Name", + required = true) List categorynames + ); + + @PUT + @Path("/categories/rename") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update application category", + notes = "This will update application category.", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully delete registered category.", + response = ApplicationList.class), + @ApiResponse( + code = 404, + message = "Not Found. There doesn't have an category for given category name.."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting registered category.", + response = ErrorResponse.class) + }) + Response renameCategory( + @ApiParam( + name = "oldCategoryName", + value = "Existing Category Name", + required = true) + @QueryParam("from") String oldCategoryName, + @ApiParam( + name = "newCategoryName", + value = "Modifying Category Name", + required = true) + @QueryParam("to") String newCategoryName + ); + + @DELETE + @Path("/categories/{categoryName}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Delete application category", + notes = "This will delete application category.", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted registered category.", + response = ApplicationList.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting registered category.", + response = ErrorResponse.class) + }) + Response deleteCategory( + @ApiParam( + name = "categoryName", + value = "Category Name", + required = true) + @PathParam("categoryName") String categoryName + ); +} 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/admin/ReviewManagementPublisherAdminAPI.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/admin/ReviewManagementPublisherAdminAPI.java new file mode 100644 index 0000000000..286b979dca --- /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/admin/ReviewManagementPublisherAdminAPI.java @@ -0,0 +1,214 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.admin; + +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.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.application.mgt.common.ErrorResponse; +import org.wso2.carbon.device.application.mgt.common.PaginationResult; + +import javax.ws.rs.GET; +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; +import java.util.List; + +/** +* APIs to handle admin review management related tasks in publisher. +*/ + +@SwaggerDefinition( +info = @Info( + version = "1.0.0", + title = "Publisher Review Management Admin Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "PublisherReviewManagementAdminService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt-publisher/v1.0/admin/reviews"), + }) + } +), +tags = { + @Tag(name = "review_management", description = "Publisher Review Management related Admin APIs") +} +) +@Scopes( +scopes = { + @Scope( + name = "Update a Review", + description = "Update a Review of application.", + key = "perm:admin:app:review:update", + permissions = {"/app-mgt/publisher/admin/review/update"} + ), + @Scope( + name = "Get Review Details", + description = "Get review details of application.", + key = "perm:admin:app:review:view", + permissions = {"/app-mgt/publisher/admin/review/view"} + ) +} +) + +@Path("/admin/reviews") +@Api(value = "Publisher Review Management Admin API") +@Produces(MediaType.APPLICATION_JSON) +public interface ReviewManagementPublisherAdminAPI { +String SCOPE = "scope"; + + @GET + @Path("/release/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get app release reviews", + notes = "Get all app release reviews", + tags = "Review Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:review:view") + }) + } + ) + + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved app release reviews.", + response = PaginationResult.class, + responseContainer = "PaginationResult"), + @ApiResponse( + code = 404, + message = "Not Found. \n Not found an application release for requested UUID."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting the review list.", + response = ErrorResponse.class) + }) + + Response getAllReleaseReviews( + @ApiParam( + name = "uuid", + value = "uuid of the application release.", + required = true) + @PathParam("uuid") String uuid, + @ApiParam( + name = "offset", + value = "Starting review number.", + defaultValue = "0") + @QueryParam("offSet") int offSet, + @ApiParam( + name = "limit", + value = "Limit of paginated reviews", + defaultValue = "20") + @QueryParam("limit") int limit); + + @GET + @Path("/{uuid}/release-rating") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get ratings", + notes = "Get all ratings", + tags = "Review Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:review:view") + }) + } + ) + + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved ratings.", + response = List.class, + responseContainer = "List"), + @ApiResponse( + code = 404, + message = "Not Found. \n No Application release found for application release UUID.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting ratings", + response = ErrorResponse.class) + }) + + Response getAppReleaseRating( + @ApiParam( + name = "uuid", + value = "uuid of the application release", + required = true) + @PathParam("uuid") String uuid); + + @GET + @Path("/{uuid}/app-rating") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get app ratings", + notes = "Get all app ratings", + tags = "Store Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:review:view") + }) + } + ) + + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved ratings.", + response = List.class, + responseContainer = "List"), + @ApiResponse( + code = 404, + message = "Not Found. \n No Application found which has application release of UUID.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while getting ratings", + response = ErrorResponse.class) + }) + + Response getAppRating( + @ApiParam( + name = "uuid", + value = "uuid of the application release", + required = true) + @PathParam("uuid") + String uuid); +} 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/ApplicationManagementPublisherAPIImpl.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/ApplicationManagementPublisherAPIImpl.java new file mode 100644 index 0000000000..ae864cb52e --- /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/ApplicationManagementPublisherAPIImpl.java @@ -0,0 +1,1033 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.LifecycleState; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException; +import org.wso2.carbon.device.application.mgt.common.response.Application; +import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease; +import org.wso2.carbon.device.application.mgt.common.response.Category; +import org.wso2.carbon.device.application.mgt.common.response.Tag; +import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.CustomAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppWrapper; +import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; +import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; +import org.wso2.carbon.device.application.mgt.core.util.Constants; +import org.wso2.carbon.device.application.mgt.publisher.api.services.ApplicationManagementPublisherAPI; +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 java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import javax.activation.DataHandler; +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("/applications") +public class ApplicationManagementPublisherAPIImpl implements ApplicationManagementPublisherAPI { + + private static Log log = LogFactory.getLog(ApplicationManagementPublisherAPIImpl.class); + + @POST + @Override + @Consumes("application/json") + public Response getApplications( + @Valid Filter filter) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + if (filter == null) { + String msg = "Request Payload is null"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + ApplicationList applications = applicationManager.getApplications(filter); + return Response.status(Response.Status.OK).entity(applications).build(); + } catch (BadRequestException e) { + String msg = "Incompatible request payload is found. Please try with valid request payload."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (UnexpectedServerErrorException e) { + String msg = "Error Occured when getting supported device types by Entgra IoTS"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting the application list for publisher "; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Consumes("application/json") + @Path("/{appId}") + public Response getApplication( + @PathParam("appId") int appId, + @QueryParam("state") String state) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + Application application = applicationManager.getApplicationById(appId, state); + if (application == null){ + String msg = "Could not found an application release which is in " + state + " state."; + log.error(msg); + return Response.status(Response.Status.OK).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(application).build(); + } catch (NotFoundException e) { + String msg = "ApplicationDTO with application id: " + appId + " not found"; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch(ForbiddenException e){ + String msg = "You don't have permission to access the application. application id: " + appId; + log.error(msg); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } + catch (ApplicationManagementException e) { + String msg = "Error occurred while getting application with the id " + appId; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Consumes("application/json") + @Path("/release/{uuid}") + public Response getApplicationByUUID( + @PathParam("uuid") String uuid) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + Application application = applicationManager.getApplicationByUuid(uuid); + if (application == null){ + String msg = "Application release is in the end state of the application lifecycle flow."; + log.error(msg); + return Response.status(Response.Status.OK).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(application).build(); + } catch (NotFoundException e) { + String msg = "Application Release with UUID: " + uuid + " is not found"; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch(ForbiddenException e){ + String msg = "You don't have permission to access the application release. application release UUID: : " + + uuid; + log.error(msg); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } + catch (ApplicationManagementException e) { + String msg = "Error occurred while getting application release for UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/ent-app") + public Response createEntApp( + @Multipart("application") ApplicationWrapper applicationWrapper, + @Multipart("binaryFile") Attachment binaryFile, + @Multipart("icon") Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + applicationManager.validateAppCreatingRequest(applicationWrapper); + applicationManager.validateReleaseCreatingRequest(applicationWrapper.getEntAppReleaseWrappers().get(0), + applicationWrapper.getDeviceType()); + applicationManager.validateBinaryArtifact(binaryFile); + applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); + + // Created new Ent App + Application application = applicationManager.createEntApp(applicationWrapper, + constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList)); + if (application != null) { + return Response.status(Response.Status.CREATED).entity(application).build(); + } else { + String msg = "Application creation is failed"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with ent. app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating the ent. application"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (RequestValidatingException e) { + String msg = "Couldn't find the required artifacts to create new ent. application with the request"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } + + @POST + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/web-app") + public Response createWebApp( + @Multipart("webapp") WebAppWrapper webAppWrapper, + @Multipart("icon") Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + applicationManager.validateAppCreatingRequest(webAppWrapper); + applicationManager + .validateReleaseCreatingRequest(webAppWrapper.getWebAppReleaseWrappers().get(0), Constants.ANY); + applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); + + // Created new Web App + Application application = applicationManager.createWebClip(webAppWrapper, + constructApplicationArtifact(null, iconFile, bannerFile, attachmentList)); + if (application != null) { + return Response.status(Response.Status.CREATED).entity(application).build(); + } else { + String msg = "Web app creation is failed"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with web app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating the web application"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (RequestValidatingException e) { + String msg = "Couldn't find the required artifacts to create new web application with the request"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } + + @POST + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/public-app") + public Response createPubApp( + @Multipart("public-app") PublicAppWrapper publicAppWrapper, + @Multipart("icon") Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + applicationManager.validateAppCreatingRequest(publicAppWrapper); + applicationManager.validateReleaseCreatingRequest(publicAppWrapper.getPublicAppReleaseWrappers().get(0), + publicAppWrapper.getDeviceType()); + applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); + + // Created new Public App + Application application = applicationManager.createPublicApp(publicAppWrapper, + constructApplicationArtifact(null, iconFile, bannerFile, attachmentList)); + if (application != null) { + return Response.status(Response.Status.CREATED).entity(application).build(); + } else { + String msg = "Web app creation is failed"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with pub app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating the public app."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (RequestValidatingException e) { + String msg = "Couldn't find the required artifacts to create new public application with the request"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } + + @POST + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/custom-app") + public Response createCustomApp( + @Multipart("application") CustomAppWrapper customAppWrapper, + @Multipart("binaryFile") Attachment binaryFile, + @Multipart("icon") Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + applicationManager.validateAppCreatingRequest(customAppWrapper); + applicationManager.validateReleaseCreatingRequest(customAppWrapper.getCustomAppReleaseWrappers().get(0), + customAppWrapper.getDeviceType()); + applicationManager.validateBinaryArtifact(binaryFile); + applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); + + // Created new Ent App + Application application = applicationManager.createCustomApp(customAppWrapper, + constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList)); + if (application != null) { + return Response.status(Response.Status.CREATED).entity(application).build(); + } else { + String msg = "Application creation is failed"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with pub custom creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating the application"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (RequestValidatingException e) { + String msg = "Couldn't find the required artifacts to create new custom application with the request"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } + + @POST + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/{deviceType}/ent-app/{appId}") + public Response createEntAppRelease( + @PathParam("deviceType") String deviceType, + @PathParam("appId") int appId, + @Multipart("applicationRelease") EntAppReleaseWrapper entAppReleaseWrapper, + @Multipart("binaryFile") Attachment binaryFile, + @Multipart("icon") Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + applicationManager.validateReleaseCreatingRequest(entAppReleaseWrapper, deviceType); + applicationManager.validateBinaryArtifact(binaryFile); + applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); + + // Created new Ent App release + ApplicationRelease release = applicationManager.createEntAppRelease(appId, entAppReleaseWrapper, + constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList)); + if (release != null) { + return Response.status(Response.Status.CREATED).entity(release).build(); + } else { + log.error("ApplicationDTO Creation Failed"); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating the application"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (RequestValidatingException e) { + String msg = "Error occurred while handling the application creating request"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } + + @Override + @PUT + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Produces(MediaType.APPLICATION_JSON) + @Path("/image-artifacts/{uuid}") + public Response updateApplicationImageArtifacts( + @PathParam("uuid") String applicationReleaseUuid, + @Multipart(value = "icon", required = false) Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart(value = "screenshot1", required = false) Attachment screenshot1, + @Multipart(value = "screenshot2", required = false) Attachment screenshot2, + @Multipart(value = "screenshot3", required = false) Attachment screenshot3) { + try { + List attachments = constructAttachmentList(screenshot1, screenshot2, screenshot3); + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + applicationManager.updateApplicationImageArtifact(applicationReleaseUuid, + constructApplicationArtifact(null, iconFile, bannerFile, attachments)); + return Response.status(Response.Status.OK) + .entity("Successfully uploaded artifacts for the application " + applicationReleaseUuid).build(); + } catch (NotFoundException e) { + log.error(e.getMessage(), e); + return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build(); + } catch (ForbiddenException e) { + log.error(e.getMessage(), e); + return Response.status(Response.Status.FORBIDDEN).entity(e.getMessage()).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while updating the application image artifacts for application release uuid: " + + applicationReleaseUuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + @PUT + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/ent-app-artifact/{deviceType}//{uuid}") + public Response updateApplicationArtifact( + @PathParam("deviceType") String deviceType, + @PathParam("uuid") String applicationReleaseUuid, + @Multipart("binaryFile") Attachment binaryFile) { + + try { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + applicationManager.validateBinaryArtifact(binaryFile); + applicationManager.updateApplicationArtifact(deviceType, applicationReleaseUuid, + constructApplicationArtifact(binaryFile, null, null, null)); + return Response.status(Response.Status.OK) + .entity("Successfully uploaded artifacts for the application release. UUID is " + + applicationReleaseUuid).build(); + } catch (RequestValidatingException e) { + log.error(e.getMessage(), e); + return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } catch (NotFoundException e) { + log.error(e.getMessage(), e); + return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build(); + } catch (ApplicationManagementException e) { + log.error("Error occurred while updating the image artifacts of the application with the uuid " + + applicationReleaseUuid, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); + } + } + + @PUT + @Consumes("application/json") + @Path("/{appId}") + public Response updateApplication( + @PathParam("appId") int applicationId, + @Valid ApplicationUpdateWrapper applicationUpdateWrapper) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + Application application = applicationManager.updateApplication(applicationId, applicationUpdateWrapper); + return Response.status(Response.Status.OK).entity(application).build(); + } catch (NotFoundException e) { + log.error(e.getMessage()); + return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build(); + } catch (BadRequestException e) { + String msg = "Error occurred while modifying the application. Found bad request payload for updating the " + + "application"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Internal Error occurred while modifying the application."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + @PUT + @Path("/ent-app-release/{uuid}") + public Response updateEntAppRelease( + @PathParam("uuid") String applicationUUID, + @Multipart("applicationRelease") EntAppReleaseWrapper entAppReleaseWrapper, + @Multipart(value = "binaryFile", required = false) Attachment binaryFile, + @Multipart(value = "icon", required = false) Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart(value = "screenshot1", required = false) Attachment screenshot1, + @Multipart(value = "screenshot2", required = false) Attachment screenshot2, + @Multipart(value = "screenshot3", required = false) Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + ApplicationRelease applicationRelease = applicationManager + .updateEntAppRelease(applicationUUID, entAppReleaseWrapper, + constructApplicationArtifact(binaryFile, iconFile, bannerFile, screenshots)); + if (applicationRelease == null) { + String msg ="Ent app release updating is failed. Please contact the administrator. Application release " + + "UUID: " + applicationUUID; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(applicationRelease).build(); + } catch (BadRequestException e) { + String msg = + "Invalid request to update ent app release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (NotFoundException e) { + String msg = + "Couldn't found an ent app or ent app release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to update the ent app release which has UUID " + + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while updating the ent app release which has UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + @PUT + @Path("/public-app-release/{uuid}") + public Response updatePubAppRelease( + @PathParam("uuid") String applicationUUID, + @Multipart("applicationRelease") PublicAppReleaseWrapper publicAppReleaseWrapper, + @Multipart(value = "icon", required = false) Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart(value = "screenshot1", required = false) Attachment screenshot1, + @Multipart(value = "screenshot2", required = false) Attachment screenshot2, + @Multipart(value = "screenshot3", required = false) Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + ApplicationRelease applicationRelease = applicationManager + .updatePubAppRelease(applicationUUID, publicAppReleaseWrapper, + constructApplicationArtifact(null, iconFile, bannerFile, screenshots)); + if (applicationRelease == null) { + String msg ="Public app release updating is failed. Please contact the administrator. " + + "Application release UUID: " + applicationUUID + ", Supported device type:"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(applicationRelease).build(); + } catch (BadRequestException e) { + String msg = "Invalid request to update public app release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (NotFoundException e) { + String msg = "Couldn't found public app or public app release for application release UUID " + + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to update the public app release which has UUID " + + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while updating the public app release which has UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + @PUT + @Path("/web-app-release/{uuid}") + public Response updateWebAppRelease( + @PathParam("uuid") String applicationUUID, + @Multipart("applicationRelease") WebAppReleaseWrapper webAppReleaseWrapper, + @Multipart(value = "icon", required = false) Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart(value = "screenshot1", required = false) Attachment screenshot1, + @Multipart(value = "screenshot2", required = false) Attachment screenshot2, + @Multipart(value = "screenshot3", required = false) Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + ApplicationRelease applicationRelease = applicationManager + .updateWebAppRelease(applicationUUID, webAppReleaseWrapper, + constructApplicationArtifact(null, iconFile, bannerFile, screenshots)); + if (applicationRelease == null) { + String msg ="web app release updating is failed. Please contact the administrator. Application " + + "release UUID: " + applicationUUID; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(applicationRelease).build(); + } catch (BadRequestException e) { + String msg = "Invalid request to update web app release for web app release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (NotFoundException e) { + String msg = "Couldn't found web app or web app release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to update the web app release which has UUID " + + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while updating the web app release which has UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + @PUT + @Path("/custom-app-release/{uuid}") + public Response updateCustomAppRelease( + @PathParam("uuid") String applicationUUID, + @Multipart("applicationRelease") CustomAppReleaseWrapper customAppReleaseWrapper, + @Multipart(value = "binaryFile", required = false) Attachment binaryFile, + @Multipart(value = "icon", required = false) Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart(value = "screenshot1", required = false) Attachment screenshot1, + @Multipart(value = "screenshot2", required = false) Attachment screenshot2, + @Multipart(value = "screenshot3", required = false) Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + ApplicationRelease applicationRelease = applicationManager + .updateCustomAppRelease(applicationUUID, customAppReleaseWrapper, + constructApplicationArtifact(binaryFile, iconFile, bannerFile, screenshots)); + if (applicationRelease == null) { + String msg ="Custom app release updating is failed. Please contact the administrator. Application " + + "release UUID: " + applicationUUID; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(applicationRelease).build(); + } catch (BadRequestException e) { + String msg = + "Invalid request to update ent app release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (NotFoundException e) { + String msg = + "Couldn't found an ent app or ent app release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to update the ent app release which has UUID " + + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while updating the ent app release which has UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @PUT + @Path("/retire/{appId}") + public Response retireApplication( + @PathParam("appId") int applicationId) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.retireApplication(applicationId); + return Response.status(Response.Status.OK) + .entity("Successfully deleted the application for application ID: " + applicationId).build(); + } catch (NotFoundException e) { + String msg = + "Couldn't found application for application id: " + applicationId + " to delete the application"; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to delete the application which has ID " + applicationId; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while deleting the application: " + applicationId; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Path("/life-cycle/state-changes/{uuid}") + public Response getLifecycleStates( + @PathParam("uuid") String releaseUuid) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + List lifecycleStates = applicationManager.getLifecycleStateChangeFlow(releaseUuid); + return Response.status(Response.Status.OK).entity(lifecycleStates).build(); + } catch (NotFoundException e) { + String msg = "Couldn't found an application release for UUID: " + releaseUuid; + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = + "Error occurred while getting lifecycle states for application release UUID: " + releaseUuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } + + @POST + @Path("/life-cycle/{uuid}") + public Response addLifecycleState( + @PathParam("uuid") String applicationUuid, + @Valid LifecycleChanger lifecycleChanger) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + ApplicationRelease applicationRelease = applicationManager + .changeLifecycleState(applicationUuid, lifecycleChanger); + return Response.status(Response.Status.CREATED).entity(applicationRelease).build(); + } catch (BadRequestException e) { + String msg = "Request payload contains invalid data, hence veryfy the request payload."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).build(); + } catch (ForbiddenException e) { + String msg = "You are trying to move the application release into incompatible state for application " + + "which has application ID: " + applicationUuid; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).build(); + } catch (NotFoundException e) { + String msg = "Could,t find application release for application release uuid: " + applicationUuid; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while adding lifecycle state."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } + + @GET + @Override + @Consumes("application/json") + @Path("/lifecycle-config") + public Response getLifecycleConfig() { + AppmDataHandler dataHandler = APIUtil.getDataHandler(); + try { + return Response.status(Response.Status.OK).entity(dataHandler.getLifecycleConfiguration()).build(); + } catch (LifecycleManagementException e) { + String msg = "Error Occurred while accessing lifecycle manager."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Override + @Consumes("application/json") + @Path("/tags") + public Response getTags() { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + List tags = applicationManager.getRegisteredTags(); + return Response.status(Response.Status.OK).entity(tags).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while getting registered tags."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @DELETE + @Override + @Consumes(MediaType.WILDCARD) + @Path("/{appId}/tags/{tagName}") + public Response deleteApplicationTag( + @PathParam("appId") int appId, + @PathParam("tagName") String tagName) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.deleteApplicationTag(appId, tagName); + String msg = "Tag " + tagName + " is deleted successfully."; + return Response.status(Response.Status.OK).entity(msg).build(); + } catch (NotFoundException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (BadRequestException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while deleting registered tag."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @DELETE + @Override + @Consumes(MediaType.WILDCARD) + @Path("/tags/{tagName}") + public Response deleteUnusedTag( + @PathParam("tagName") String tagName) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.deleteUnusedTag(tagName); + String msg = "Tag " + tagName + " is deleted successfully."; + return Response.status(Response.Status.OK).entity(msg).build(); + } catch (NotFoundException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while deleting unused tag."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @PUT + @Override + @Consumes("application/json") + @Path("/tags/rename") + public Response modifyTagName( + @QueryParam("from") String oldTagName, + @QueryParam("to") String newTagName) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.updateTag(oldTagName, newTagName); + String msg = "Tag " + oldTagName + " is updated to " + newTagName + " successfully."; + return Response.status(Response.Status.OK).entity(msg).build(); + } catch (BadRequestException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (NotFoundException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while updating registered tag."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Override + @Consumes("application/json") + @Path("/tags") + public Response addTags( + List tagNames) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + List tags = applicationManager.addTags(tagNames); + return Response.status(Response.Status.OK).entity(tags).build(); + } catch (BadRequestException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while adding new tag."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Override + @Consumes("application/json") + @Path("/{appId}/tags") + public Response addApplicationTags( + @PathParam("appId") int appId, + List tagNames) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + List applicationTags = applicationManager.addApplicationTags(appId, tagNames); + return Response.status(Response.Status.OK).entity(applicationTags).build(); + } catch (NotFoundException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while adding new tags for application which has application ID: " + appId + "."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Override + @Consumes("application/json") + @Path("/categories") + public Response getCategories() { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + List categories = applicationManager.getRegisteredCategories(); + return Response.status(Response.Status.OK).entity(categories).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while getting registered categories."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + /*** + * Construct the screenshot list by evaluating the availability of each screenshot. + * + * @param screenshot1 First Screenshot + * @param screenshot2 Second Screenshot + * @param screenshot3 Third Screenshot + * @return List of {@link Attachment} + */ + private List constructAttachmentList(Attachment screenshot1, Attachment screenshot2, + Attachment screenshot3) { + List attachments = new ArrayList<>(); + if (screenshot1 != null) { + attachments.add(screenshot1); + } + if (screenshot2 != null) { + attachments.add(screenshot2); + } + if (screenshot3 != null) { + attachments.add(screenshot3); + } + return attachments; + } + + /*** + * This method can be used to construct {@link ApplicationArtifact} + * + * @param binaryFile binary file of the application release + * @param iconFile icon file of the application release + * @param bannerFile banner file of the application release + * @param attachmentList list of screenshot of the application release + * @return {@link ApplicationArtifact} + * @throws ApplicationManagementException if an error occurs when reading the attached data. + */ + private ApplicationArtifact constructApplicationArtifact(Attachment binaryFile, Attachment iconFile, + Attachment bannerFile, List attachmentList) throws ApplicationManagementException { + try { + ApplicationArtifact applicationArtifact = new ApplicationArtifact(); + DataHandler dataHandler; + if (binaryFile != null) { + dataHandler = binaryFile.getDataHandler(); + InputStream installerStream = dataHandler.getInputStream(); + String installerFileName = dataHandler.getName(); + if (installerStream == null) { + String msg = "Stream of the application release installer is null. Hence can't proceed. Please " + + "verify the installer file."; + log.error(msg); + throw new BadRequestException(msg); + } + if (installerFileName == null) { + String msg = "Installer file name retrieving is failed.. Hence can't proceed. Please verify the " + + "installer file."; + log.error(msg); + throw new BadRequestException(msg); + } + applicationArtifact.setInstallerName(installerFileName.replaceAll("\\s", "")); + applicationArtifact.setInstallerStream(installerStream); + } + + if (iconFile != null) { + dataHandler = iconFile.getDataHandler(); + String iconFileName = dataHandler.getName(); + InputStream iconStream = dataHandler.getInputStream(); + + if (iconStream == null) { + String msg = "Stream of the application release icon is null. Hence can't proceed. Please " + + "verify the uploaded icon file."; + log.error(msg); + throw new BadRequestException(msg); + } + if (iconFileName == null) { + String msg = "Icon file name retrieving is failed.. Hence can't proceed. Please verify the " + + "icon file."; + log.error(msg); + throw new BadRequestException(msg); + } + applicationArtifact.setIconName(iconFileName); + applicationArtifact.setIconStream(iconStream); + } + + if (bannerFile != null) { + dataHandler = bannerFile.getDataHandler(); + String bannerFileName = dataHandler.getName(); + InputStream bannerStream = dataHandler.getInputStream(); + if (bannerStream == null) { + String msg = "Stream of the application release banner is null. Hence can't proceed. Please " + + "verify the uploaded banner file."; + log.error(msg); + throw new BadRequestException(msg); + } + if (bannerFileName == null) { + String msg = "Banner file name retrieving is failed.. Hence can't proceed. Please verify the " + + "banner file."; + log.error(msg); + throw new BadRequestException(msg); + } + applicationArtifact.setBannerName(bannerFileName); + applicationArtifact.setBannerStream(bannerStream); + } + + if (attachmentList != null && !attachmentList.isEmpty()) { + Map scrrenshotData = new TreeMap<>(); + for (Attachment sc : attachmentList) { + dataHandler = sc.getDataHandler(); + String screenshotrFileName = dataHandler.getName(); + InputStream screenshotStream = dataHandler.getInputStream(); + if (screenshotStream == null) { + String msg = + "Stream of one of the application release screenshot is null. Hence can't proceed. Please " + + "verify the uploaded screenshots."; + log.error(msg); + throw new BadRequestException(msg); + } + if (screenshotrFileName == null) { + String msg = + "Screenshot file name retrieving is failed for one screenshot. Hence can't proceed. " + + "Please verify the screenshots."; + log.error(msg); + throw new BadRequestException(msg); + } + scrrenshotData.put(screenshotrFileName, screenshotStream); + } + applicationArtifact.setScreenshots(scrrenshotData); + } + return applicationArtifact; + } catch (IOException e) { + String msg = "Error occurred when reading attachment data."; + log.error(msg, e); + throw new ApplicationManagementException(msg); + } + } +} 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/admin/ApplicationManagementPublisherAdminAPIImpl.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/admin/ApplicationManagementPublisherAdminAPIImpl.java new file mode 100644 index 0000000000..000816cba8 --- /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/admin/ApplicationManagementPublisherAdminAPIImpl.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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.admin; + +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.BadRequestException; +import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; +import org.wso2.carbon.device.application.mgt.publisher.api.services.admin.ApplicationManagementPublisherAdminAPI; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +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; +import java.util.List; + +/** + * Implementation of Application Management related APIs. + */ +@Produces({"application/json"}) +@Path("/admin/applications") +public class ApplicationManagementPublisherAdminAPIImpl implements ApplicationManagementPublisherAdminAPI { + + private static Log log = LogFactory.getLog(ApplicationManagementPublisherAdminAPIImpl.class); + + @DELETE + @Consumes(MediaType.WILDCARD) + @Path("/release/{uuid}") + public Response deleteApplicationRelease( + @PathParam("uuid") String releaseUuid) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.deleteApplicationRelease(releaseUuid); + String responseMsg = "Successfully deleted the application release for uuid: " + releaseUuid + ""; + return Response.status(Response.Status.OK).entity(responseMsg).build(); + } catch (NotFoundException e) { + String msg = + "Couldn't found application release which is having application release UUID:" + releaseUuid; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to delete the application release which has UUID " + + releaseUuid; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while deleting the application release for application release UUID:: " + + releaseUuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @DELETE + @Consumes(MediaType.WILDCARD) + @Path("/{appId}") + public Response deleteApplication( + @PathParam("appId") int applicationId) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.deleteApplication(applicationId); + String responseMsg = "Successfully deleted the application which has ID: " + applicationId + ""; + return Response.status(Response.Status.OK).entity(responseMsg).build(); + } catch (NotFoundException e) { + String msg = + "Couldn't found application release which is having the ID:" + applicationId; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to delete the application which has ID: " + applicationId; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while deleting the application which has application ID:: " + applicationId; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @DELETE + @Override + @Consumes(MediaType.WILDCARD) + @Path("/tags/{tagName}") + public Response deleteTag( + @PathParam("tagName") String tagName) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.deleteTag(tagName); + String msg = "Tag " + tagName + " is deleted successfully."; + return Response.status(Response.Status.OK).entity(msg).build(); + } catch (NotFoundException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while deleting registered tag."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Override + @Consumes("application/json") + @Path("/categories") + public Response addCategories( + List categoryNames) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + List categories = applicationManager.addCategories(categoryNames); + return Response.status(Response.Status.OK).entity(categories).build(); + } catch (BadRequestException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while adding new categories."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @PUT + @Override + @Consumes("application/json") + @Path("/categories/rename") + public Response renameCategory( + @QueryParam("from") String oldCategoryName, + @QueryParam("to") String newCategoryName) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.updateCategory(oldCategoryName, newCategoryName); + String msg = "Category is updated from " + oldCategoryName + " to " + newCategoryName; + return Response.status(Response.Status.OK).entity(msg).build(); + } catch (NotFoundException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while rename registered category."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @DELETE + @Override + @Consumes(MediaType.WILDCARD) + @Path("/categories/{categoryName}") + public Response deleteCategory( + @PathParam("categoryName") String categoryName) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + try { + applicationManager.deleteCategory(categoryName); + String msg = "Category " + categoryName + " is deleted successfully."; + return Response.status(Response.Status.OK).entity(msg).build(); + } catch (NotFoundException e) { + String msg = e.getMessage(); + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error Occurred while deleting registered category."; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } +} 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/admin/ReviewManagementPublisherAdminAPIImpl.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/admin/ReviewManagementPublisherAdminAPIImpl.java new file mode 100644 index 0000000000..87aab15997 --- /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/admin/ReviewManagementPublisherAdminAPIImpl.java @@ -0,0 +1,114 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.admin; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.PaginationRequest; +import org.wso2.carbon.device.application.mgt.common.PaginationResult; +import org.wso2.carbon.device.application.mgt.common.Rating; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; +import org.wso2.carbon.device.application.mgt.common.services.ReviewManager; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; +import org.wso2.carbon.device.application.mgt.publisher.api.services.admin.ReviewManagementPublisherAdminAPI; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +/** + * Review Management related jax-rs APIs. + */ +@Path("/admin/reviews") +public class ReviewManagementPublisherAdminAPIImpl implements ReviewManagementPublisherAdminAPI { + + private static Log log = LogFactory.getLog(ReviewManagementPublisherAdminAPIImpl.class); + + @Override + @GET + @Path("/release/{uuid}") + public Response getAllReleaseReviews( + @PathParam("uuid") String uuid, + @DefaultValue("0") @QueryParam("offset") int offSet, + @DefaultValue("20") @QueryParam("limit") int limit) { + ReviewManager reviewManager = APIUtil.getReviewManager(); + PaginationRequest request = new PaginationRequest(offSet, limit); + try { + PaginationResult paginationResult = reviewManager.getAllReleaseReviews(request, uuid); + return Response.status(Response.Status.OK).entity(paginationResult).build(); + } catch (NotFoundException e) { + String msg = "Couldn't find an application release for UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ReviewManagementException e) { + String msg = "Error occurred while retrieving reviews for application UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while retrieving application release details for application UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + @GET + @Path("/{uuid}/release-rating") + public Response getAppReleaseRating( + @PathParam("uuid") String uuid) { + ReviewManager reviewManager = APIUtil.getReviewManager(); + Rating rating; + try { + rating = reviewManager.getAppReleaseRating(uuid); + } catch (NotFoundException e) { + String msg = "Couldn't found an application release for UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ReviewManagementException | ApplicationManagementException e) { + String msg = "Error occured while getting review data for application release UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + return Response.status(Response.Status.OK).entity(rating).build(); + } + + @Override + @GET + @Path("/{uuid}/app-rating") + public Response getAppRating( + @PathParam("uuid") String uuid) { + ReviewManager reviewManager = APIUtil.getReviewManager(); + Rating rating; + try { + rating = reviewManager.getAppRating(uuid); + } catch (NotFoundException e) { + String msg = "Couldn't found an application for application release UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ReviewManagementException | ApplicationManagementException e) { + String msg = "Error occured while getting review data for application release UUID: " + uuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + return Response.status(Response.Status.OK).entity(rating).build(); + } +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.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 new file mode 100644 index 0000000000..e03ee8d50b --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,65 @@ + + + + + + + + + + Get Application Details + /device-mgt/application/get + /application-mgt/applications + GET + + + Create an Application + /device-mgt/application/create + /application-mgt/applications + POST + + + Update an Application + /device-mgt/application/update + /application-mgt/applications + PUT + + + Login to Application Management + /device-mgt/application-mgt/login + /application-mgt/applications + PUT + + + Delete an Application + device-mgt/application/delete + /application-mgt/applications/* + DELETE + + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.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 53% rename from components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.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 index 8ec4d9fa45..da8baef61f 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.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 @@ -1,22 +1,22 @@ +~ Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. +~ +~ Entgra (pvt) Ltd. 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. +--> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.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 75% rename from components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.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 index 64908014e5..fb8b266948 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.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 @@ -1,38 +1,39 @@ +~ Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. +~ +~ Entgra (pvt) Ltd. 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. +--> - Certificate-Webapp + Application Management Webapp - JAX-WS/JAX-RS Certificate Management Endpoint + JAX-WS/JAX-RS Application Management Endpoint JAX-WS/JAX-RS Servlet CXFServlet org.apache.cxf.transport.servlet.CXFServlet + swagger.security.filter ApiAuthorizationFilterImpl 1 - + CXFServlet /* @@ -44,10 +45,17 @@ doAuthentication true - - isDefault - false - + + + + + ApplicationMgt-Admin + /* + + + CONFIDENTIAL + + @@ -63,19 +71,9 @@ true - - - CertificateMgt-Admin - /* - - - CONFIDENTIAL - - - ApiOriginFilter - org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.ApiOriginFilter + org.wso2.carbon.device.application.mgt.addons.ApiOriginFilter @@ -119,5 +117,4 @@ /* - - + \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/pom.xml new file mode 100644 index 0000000000..0cbf7a9e81 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/pom.xml @@ -0,0 +1,161 @@ + + + + 4.0.0 + + + org.wso2.carbon.devicemgt + application-mgt + 4.0.0-SNAPSHOT + + org.wso2.carbon.device.application.mgt.publisher.ui + 4.0.0-SNAPSHOT + war + WSO2 Carbon - Application Management Publisher UI Component + https://entgra.io + This Component contains Application Management publisher UI + + + + maven-war-plugin + + WEB-INF/lib/*cxf*.jar + publisher + + + ${npm.output.directory}/dist + + + ${npm.output.directory}/public + public + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend.mave.version} + + ${npm.working.dir} + + ${npm.install.dir} + + + + install node and npm + + install-node-and-npm + + generate-resources + + ${node.version} + ${npm.version} + + + + npm install + + npm + + + + install + + + + prod + + npm + + + run-script ${npm.build.command} + + generate-resources + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + platform-windows + + + windows + + + + + npm.cmd + + + + + false + npm + build_prod + ./react-app + ./react-app/tmp + UTF-8 + react-app + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/babel.config.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/babel.config.js new file mode 100644 index 0000000000..7ec6d0936b --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/babel.config.js @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +module.exports = function (api) { + api.cache(true); + const presets = [ "@babel/preset-env", + "@babel/preset-react" ]; + const plugins = ["@babel/plugin-proposal-class-properties"]; + + return { + presets, + plugins + }; +}; \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json new file mode 100644 index 0000000000..dbba25e052 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json @@ -0,0 +1,101 @@ +{ + "name": "publisher", + "version": "1.0.0", + "description": "WSO2 IoT Server App Publisher", + "main": "App.js", + "proxy": "http://localhost:3001", + "repository": { + "type": "git", + "url": "git://github.com/wso2/carbon-devicemgt" + }, + "license": "Apache License 2.0", + "dependencies": { + "@ant-design/dark-theme": "^0.2.2", + "@babel/polyfill": "^7.6.0", + "acorn": "^6.2.0", + "antd": "^3.23.6", + "axios": "^0.19.0", + "babel-eslint": "^9.0.0", + "d3": "^5.9.7", + "dagre": "^0.8.4", + "eslint": "^5.16.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-react": "^7.16.0", + "fetch": "^1.1.0", + "imagemin": "^6.1.0", + "keymirror": "^0.1.1", + "rc-tween-one": "^2.4.1", + "react-d3-graph": "^2.1.0", + "react-highlight-words": "^0.16.0", + "react-html-parser": "^2.0.2", + "react-infinite-scroller": "^1.2.4", + "react-quill": "^1.3.3", + "react-router": "latest", + "react-router-config": "^5.0.1", + "react-router-dom": "^5.0.1", + "react-scripts": "2.1.8", + "react-star-ratings": "^2.3.0", + "redux-thunk": "^2.3.0", + "shade-blend-color": "^1.0.0", + "storm-react-diagrams": "^5.2.1", + "typescript": "^3.6.4", + "lodash.debounce": "latest" + }, + "devDependencies": { + "@babel/core": "^7.5.0", + "@babel/plugin-proposal-class-properties": "^7.5.0", + "@babel/preset-env": "^7.5.0", + "@babel/preset-react": "^7.0.0", + "@babel/register": "^7.4.4", + "babel-core": "^6.26.3", + "babel-loader": "^8.0.6", + "babel-polyfill": "^6.26.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-stage-0": "^6.24.1", + "body-parser": "^1.19.0", + "chai": "^4.1.2", + "css-loader": "^0.28.11", + "express": "^4.17.1", + "express-pino-logger": "^4.0.0", + "file-loader": "^2.0.0", + "html-loader": "^0.5.5", + "html-webpack-plugin": "^3.2.0", + "img-loader": "^3.0.1", + "json-loader": "^0.5.7", + "less": "^3.10.3", + "less-loader": "^4.1.0", + "mini-css-extract-plugin": "^0.5.0", + "mocha": "^5.2.0", + "mock-local-storage": "^1.0.5", + "node-env-run": "^3.0.2", + "node-sass": "^4.12.0", + "nodemon": "^1.19.1", + "npm-run-all": "^4.1.5", + "pino-colada": "^1.4.5", + "postcss-loader": "^3.0.0", + "react": "^16.8.6", + "react-dom": "^16.8.6", + "react-intl": "^2.9.0", + "react-redux": "^7.1.0", + "redux": "^4.0.1", + "sass-loader": "^6.0.7", + "style-loader": "^0.18.2", + "url-loader": "^1.1.2", + "webpack": "^4.39.3", + "webpack-cli": "^3.3.7", + "webpack-dev-server": "^3.7.2" + }, + "scripts": { + "start": "webpack-dev-server --mode development --open", + "dev": "webpack --mode development", + "build": "webpack --mode production", + "watch": "webpack --watch --mode development", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject", + "build_prod": "NODE_ENV=production NODE_OPTIONS=--max_old_space_size=4096 webpack -p --display errors-only --hide-modules", + "build_dev": "NODE_ENV=development webpack -d --watch ", + "server": "node-env-run server --exec nodemon | pino-colada", + "dev2": "run-p server start" + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json new file mode 100644 index 0000000000..65013996e0 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json @@ -0,0 +1,68 @@ +{ + "theme": { + "logo": "https://entgra.io/assets/images/svg/logo.svg", + "primaryColor": "rgb(24, 144, 255)" + }, + "serverConfig": { + "invoker": { + "uri": "/publisher-ui-request-handler/invoke", + "publisher": "/application-mgt-publisher/v1.0", + "store": "/application-mgt-store/v1.0", + "deviceMgt": "/device-mgt/v1.0" + }, + "loginUri": "/publisher-ui-request-handler/login", + "logoutUri": "/publisher-ui-request-handler/logout", + "platform": "publisher" + }, + "defaultPlatformIcons": { + "default": { + "icon": "global", + "color": "#535c68", + "theme": "outlined" + }, + "android": { + "icon": "android", + "color": "#7db343", + "theme": "filled" + }, + "ios": { + "icon": "apple", + "color": "#535c68", + "theme": "filled" + }, + "windows": { + "icon": "windows", + "color": "#008cc4", + "theme": "filled" + } + }, + "lifecycle": { + "CREATED": { + "text": "The initial most state of an application." + }, + "IN-REVIEW": { + "text": "This state can be applied when the application is being reviewed by approvers." + }, + "APPROVED": { + "text": "The approved state is a compulsory state prior to publishing the application." + }, + "REJECTED": { + "text": "The Approvers can reject an application due to a faulty of the app or not being in compliance with company policies." + }, + "PUBLISHED": { + "text": "The state which is applied for applications which are qualified for your Corporate App Store. Only the applications of Published state can be installed to your corporate devices." + }, + "BLOCKED": { + "text": "This state allows you to block your application either to publish or deprecate at a future date." + }, + "DEPRECATED": { + "text": "The applications which are outdated and no longer suit your app store." + }, + "RETIRED": { + "text": "The final state of an application, where no transition of states will be allowed after this." + } + }, + "deviceTypes": { + "mobileTypes": ["android", "ios"] + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/icons.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/icons.json new file mode 100644 index 0000000000..0bd52ef51e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/icons.json @@ -0,0 +1,306 @@ +{ + "airplay": "", + "api": "", + "apn": "", + "vpn": "", + "apple": "", + "windows": "", + "android": "", + "wifi": "", + "application": "", + "configarations": "", + "battery": "", + "notification": "", + "blank-document": "", + "bookmark": "", + "bpel": "", + "bpmn": "", + "compare": "", + "bug": "", + "calendar": "", + "camera": "", + "contract": "", + "add": "", + "minus": "", + "check": "", + "cancel": "", + "checklist": "", + "circle": "", + "clear": "", + "expand": "", + "clock": "", + "cloud": "", + "circle-outline": "", + "contact": "", + "copy": "", + "dashboard": "", + "database": "", + "delete": "", + "deploy": "", + "display": "", + "dial-up": "", + "document": "", + "ellipsis": "", + "dss": "", + "ebook": "", + "edit": "", + "endpoint": "", + "folder": "", + "faq": "", + "error": "", + "export": "", + "factory-reset": "", + "file-browse": "", + "filter": "", + "message": "", + "forum": "", + "gadget": "", + "grid": "", + "hdd": "", + "home": "", + "hour-glass": "", + "import": "", + "incoming-call": "", + "info": "", + "invitation": "", + "jaggery": "", + "java": "", + "javaee": "", + "javascript": "", + "java-spring": "", + "jaxrs": "", + "jquery": "", + "key": "", + "laptop": "", + "ldap": "", + "lifecycle": "", + "sort-up": "", + "list": "", + "list-sort": "", + "lock": "", + "mail": "", + "map-location": "", + "menu": "", + "mobile": "", + "computer": "", + "ms-document": "", + "mute": "", + "nodejs": "", + "success": "", + "paste": "", + "pdf": "", + "pie-chart": "", + "chat": "", + "publish": "", + "redo": "", + "register": "", + "download": "", + "resource": "", + "rest-api": "", + "rest-service": "", + "sort-down": "", + "rules": "", + "save": "", + "scep": "", + "schema": "", + "search": "", + "security": "", + "send": "", + "sequence": "", + "server": "", + "service": "", + "service-provider": "", + "settings": "", + "share": "", + "sign-in": "", + "soap": "", + "sort": "", + "star": "", + "statistics": "", + "store": "", + "subscribe": "", + "fan": "", + "swagger": "", + "tag": "", + "task": "", + "text": "", + "policy": "", + "security-policy": "", + "throttling-policy": "", + "light": "", + "tiles": "", + "uncheck": "", + "undo": "", + "up": "", + "down": "", + "left": "", + "right": "", + "up-arrow": "", + "down-arrow": "", + "left-arrow": "", + "right-arrow": "", + "upload": "", + "uri": "", + "usb-drive": "", + "user": "", + "bar-chart": "", + "view": "", + "refresh": "", + "warning": "", + "ringing": "", + "block": "", + "web-app": "", + "globe": "", + "web-clip": "", + "proxy": "", + "web-service": "", + "website": "", + "xml": "", + "html": "\t\t\t\t", + "war": "", + "xacml": "", + "wsdl": "", + "wadl": "", + "xq": "", + "xsd": "", + "xslt": "", + "zoom-in": "", + "zoom-out": "", + "wso2-logo": "", + "wso2": "", + "hardware": "", + "raspberry": "", + "arduino": "", + "organization": "", + "public": "", + "unmute": "", + "group": "", + "question": "", + "square": "", + "square-outline": "", + "sync": "", + "loader": "", + "ungroup": "", + "enterprise": "", + "grip": "", + "sign-out": "", + "retweet": "", + "loader2": "", + "loader3": "", + "loader4": "", + "loader5": "", + "alert": "", + "layout": "", + "pages": "", + "build": "", + "alarm": "", + "heart": "", + "table": "", + "carbon": "", + "depend": "", + "jaxws": "", + "own": "", + "php": "", + "use": "", + "deprecate": "", + "prototype": "", + "retire": "", + "micro-services": "", + "activate": "", + "disabled": "", + "hide": "", + "facebook": "", + "github": "", + "google": "", + "google-docs": "", + "google-sheets": "", + "google-slides": "", + "google-plus": "", + "google-drive": "", + "instagram": "", + "linkedin": "", + "pinterest": "", + "skype": "", + "twitter": "", + "youtube": "", + "slash": "", + "analytics-extensions": "", + "esb-connector": "", + "extensions": "", + "is-connector": "", + "annotation": "", + "dgm-fork": "", + "dgm-header": "", + "dgm-if-else": "", + "dgm-lifeline": "", + "dgm-logger": "\t", + "dgm-try-catch": "", + "invoke": "", + "variable": "", + "worker": "", + "code": "", + "cut": "", + "type-converter": "", + "dgm-connector": "", + "dgm-constant-definition": "", + "dgm-resource": "", + "dgm-service": "", + "dgm-type-convertor": "", + "dgm-type": "", + "format": "", + "function": "", + "rename": "", + "package": "", + "action-invoke": "", + "assign": "", + "connector": "", + "constant": "", + "logical": "", + "try-catch": "", + "devices": "", + "http": "", + "main-function": "", + "dgm-while": "", + "run": "", + "action": "", + "image": "", + "folder-open": "", + "docker": "", + "polygon": "", + "code-view": "", + "design-view": "", + "comment": "", + "dgm-action": "", + "dgm-action-invoke": "", + "function-invoke": "", + "reply": "", + "return": "", + "struct": "", + "dgm-import": "", + "start": "", + "stepin": "", + "stepout": "", + "stepover": "", + "stop": "", + "console": "", + "resume": "", + "iterate": "", + "fork-join": "", + "break": "", + "throw": "", + "worker-invoke": "", + "worker-reply": "", + "shortcut": "", + "theme": "", + "pending": "", + "ballerina": "", + "ballerina-service": "", + "abort": "", + "transaction": "", + "android-logcat": "", + "android-sense": "", + "geo-fence-inbound": "", + "geo-fence-outbound": "", + "shell": "", + "speed-alert": "" +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/manifest.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/manifest.json new file mode 100644 index 0000000000..2a700bb50e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "App Publisher", + "name": "WSO2 IoT App Publisher", + "icons": [ + { + "src": "images/favicon.png", + "sizes": "16x16", + "type": "image/png" + } + ], + "start_url": "./index.html", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/css/font-wso2.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/css/font-wso2.css new file mode 100644 index 0000000000..abb8cc1eb0 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/css/font-wso2.css @@ -0,0 +1,1506 @@ +/*! +~ Copyright (c) 2017 WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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. +*/ + + +@font-face { + font-family:"font-wso2"; + src:local("font-wso2"), url("../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223"); + src:local("font-wso2"), + url("../fonts/font-wso2.eot?#iefix") format("embedded-opentype"), + url("../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223") format("woff2"), + url("../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223") format("woff"), + url("../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223") format("truetype"), + url("../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2") format("svg"); + font-weight:normal; + font-style:normal; +} + +.fw, [class^="fw-"], [class*=" fw-"] { + font: normal normal normal 14px/1 font-wso2; + display: inline-block; + font-weight: normal; + font-style: normal; + font-size: inherit; + font-variant: normal; + speak: none; + text-decoration: inherit; + + /* Better Font Rendering =========== */ + text-transform: none; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + + +/* ======================================================================== + * font options + * ======================================================================== */ + +.fw-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fw-2x { + font-size: 2em; +} +.fw-3x { + font-size: 3em; +} +.fw-4x { + font-size: 4em; +} +.fw-5x { + font-size: 5em; +} +.fw-fw { + width: 1.28571429em; + text-align: center; +} +.fw-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fw-ul > li { + position: relative; +} +.fw-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fw-li.fw-lg { + left: -1.85714286em; +} +.fw-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fw-background { + background: #888; + border-radius: .3em; + padding: .4em .50em .45em; +} +.fw-pull-left { + float: left; +} +.fw-pull-right { + float: right; +} +.fw.fw-pull-left { + margin-right: .3em; +} +.fw.fw-pull-right { + margin-left: .3em; +} +.fw-spin { + -webkit-animation: fw-spin 2s infinite linear; + animation: fw-spin 2s infinite linear; +} +@-webkit-keyframes fw-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fw-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fw-pulse { + -webkit-animation: fw-pulse 2s ease-out infinite; + animation: fw-pulse 2s ease-out infinite; +} +@-webkit-keyframes fw-pulse { + 0%, 30% { + opacity: 0.3; + } + 40% { + opacity: 1; + } + 100% { + opacity: 0.3; + } +} +@keyframes fw-pulse { + 0%, 30% { + opacity: 0.3; + } + 40% { + opacity: 1; + } + 100% { + opacity: 0.3; + } +} +.fw-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fw-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fw-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fw-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fw-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fw-rotate-90, +:root .fw-rotate-180, +:root .fw-rotate-270, +:root .fw-flip-horizontal, +:root .fw-flip-vertical { + filter: none; +} +.fw-stack, +.fw-helper { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 1.85em; + vertical-align: middle; +} +.fw-stack-1x, +.fw-stack-2x, +.fw-helper:before, +.fw-helper:after { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fw-stack-1x, +.fw-helper:before { + line-height: inherit; +} +.fw-stack-2x, +.fw-helper:after { + font-size: 1.9em; +} +.fw-helper-slash:before { + font-size: 1.4em; +} +.fw-helper-circle:before, +.fw-helper-square:before { + z-index: 1; +} +.fw-helper-circle-outline:after { + content: "\e61f"; +} +.fw-helper-circle:after { + content: "\e61a"; +} +.fw-helper-square-outline:after { + content: "\e6b2"; +} +.fw-helper-square:after { + content: "\e6b1"; +} +.fw-helper-slash:after { + content: "\e6e1"; +} +.fw-stack > .fw-stack { + position: absolute; + font-size: 0.5em; +} +.fw-stack > .fw-stack.fw-move-top { + top: -0.2em; +} +.fw-stack > .fw-stack.fw-move-bottom { + bottom: -0.2em; +} +.fw-stack > .fw.stack.fw-move-left { + left: -0.5em; +} +.fw-stack > .fw-stack.fw-move-right { + right: -0.5em; +} +.fw-inverse:before, +.fw-helper-inverse:after, +.fw-number { + color: #ffffff; +} +.fw-shadow:before, +.fw-helper-shadow:after { + text-shadow: #ffffff 1px 1px 0; +} +.fw-stroke:before, +.fw-helper-stroke:after { + text-shadow: -2px -2px 0 #ffffff, + 2px -2px 0 #ffffff, + -2px 2px 0 #ffffff, + 2px 2px 0 #ffffff; +} +.fw-number { + line-height: 2em; + font-family: Arial, Helvetica, sans-serif; +} + + +/* ======================================================================== + * font icons + * ======================================================================== */ + +.fw-abort:before { + content:"\e72a"; +} + +.fw-action-invoke:before { + content:"\e6fe"; +} + +.fw-action:before { + content:"\e709"; +} + +.fw-activate:before { + content:"\e6cf"; +} + +.fw-add:before { + content:"\e615"; +} + +.fw-airplay:before { + content:"\e600"; +} + +.fw-alarm:before { + content:"\e6c2"; +} + +.fw-alert:before { + content:"\e6be"; +} + +.fw-analytics-extensions:before { + content:"\e6e2"; +} + +.fw-android-logcat:before { + content:"\e72c"; +} + +.fw-android-sense:before { + content:"\e72d"; +} + +.fw-android:before { + content:"\e606"; +} + +.fw-annotation:before { + content:"\e6e6"; +} + +.fw-api:before { + content:"\e601"; +} + +.fw-apn:before { + content:"\e602"; +} + +.fw-apple:before { + content:"\e604"; +} + +.fw-application:before { + content:"\e608"; +} + +.fw-arduino:before { + content:"\e6ab"; +} + +.fw-assign:before { + content:"\e6ff"; +} + +.fw-ballerina-service:before { + content:"\e729"; +} + +.fw-ballerina:before { + content:"\e728"; +} + +.fw-bar-chart:before { + content:"\e690"; +} + +.fw-battery:before { + content:"\e60a"; +} + +.fw-blank-document:before { + content:"\e60c"; +} + +.fw-block:before { + content:"\e695"; +} + +.fw-bookmark:before { + content:"\e60d"; +} + +.fw-bpel:before { + content:"\e60e"; +} + +.fw-bpmn:before { + content:"\e60f"; +} + +.fw-break:before { + content:"\e721"; +} + +.fw-bug:before { + content:"\e611"; +} + +.fw-build:before { + content:"\e6c1"; +} + +.fw-calendar:before { + content:"\e612"; +} + +.fw-camera:before { + content:"\e613"; +} + +.fw-cancel:before { + content:"\e618"; +} + +.fw-carbon:before { + content:"\e6c5"; +} + +.fw-chat:before { + content:"\e65b"; +} + +.fw-check:before { + content:"\e617"; +} + +.fw-checklist:before { + content:"\e619"; +} + +.fw-circle-outline:before { + content:"\e61f"; +} + +.fw-circle:before { + content:"\e61a"; +} + +.fw-clear:before { + content:"\e61b"; +} + +.fw-clock:before { + content:"\e61d"; +} + +.fw-cloud:before { + content:"\e61e"; +} + +.fw-code-view:before { + content:"\e70e"; +} + +.fw-code:before { + content:"\e6f1"; +} + +.fw-comment:before { + content:"\e710"; +} + +.fw-compare:before { + content:"\e610"; +} + +.fw-computer:before { + content:"\e653"; +} + +.fw-configarations:before { + content:"\e609"; +} + +.fw-connector:before { + content:"\e700"; +} + +.fw-console:before { + content:"\e71d"; +} + +.fw-constant:before { + content:"\e701"; +} + +.fw-contact:before { + content:"\e620"; +} + +.fw-contract:before { + content:"\e614"; +} + +.fw-copy:before { + content:"\e621"; +} + +.fw-cut:before { + content:"\e6f2"; +} + +.fw-dashboard:before { + content:"\e622"; +} + +.fw-database:before { + content:"\e623"; +} + +.fw-delete:before { + content:"\e624"; +} + +.fw-depend:before { + content:"\e6c6"; +} + +.fw-deploy:before { + content:"\e625"; +} + +.fw-deprecate:before { + content:"\e6cb"; +} + +.fw-design-view:before { + content:"\e70f"; +} + +.fw-devices:before { + content:"\e704"; +} + +.fw-dgm-action-invoke:before { + content:"\e712"; +} + +.fw-dgm-action:before { + content:"\e711"; +} + +.fw-dgm-connector:before { + content:"\e6f4"; +} + +.fw-dgm-constant-definition:before { + content:"\e6f5"; +} + +.fw-dgm-fork:before { + content:"\e6e7"; +} + +.fw-dgm-header:before { + content:"\e6e8"; +} + +.fw-dgm-if-else:before { + content:"\e6e9"; +} + +.fw-dgm-import:before { + content:"\e717"; +} + +.fw-dgm-lifeline:before { + content:"\e6ea"; +} + +.fw-dgm-logger:before { + content:"\e6eb"; +} + +.fw-dgm-resource:before { + content:"\e6f6"; +} + +.fw-dgm-service:before { + content:"\e6f7"; +} + +.fw-dgm-try-catch:before { + content:"\e6ec"; +} + +.fw-dgm-type-convertor:before { + content:"\e6f8"; +} + +.fw-dgm-type:before { + content:"\e6f9"; +} + +.fw-dgm-while:before { + content:"\e707"; +} + +.fw-dial-up:before { + content:"\e627"; +} + +.fw-disabled:before { + content:"\e6d1"; +} + +.fw-display:before { + content:"\e626"; +} + +.fw-docker:before { + content:"\e70c"; +} + +.fw-document:before { + content:"\e628"; +} + +.fw-down-arrow:before { + content:"\e689"; +} + +.fw-down:before { + content:"\e685"; +} + +.fw-download:before { + content:"\e65f"; +} + +.fw-dss:before { + content:"\e62a"; +} + +.fw-ebook:before { + content:"\e62b"; +} + +.fw-edit:before { + content:"\e62c"; +} + +.fw-ellipsis:before { + content:"\e629"; +} + +.fw-endpoint:before { + content:"\e62d"; +} + +.fw-enterprise:before { + content:"\e6b6"; +} + +.fw-error:before { + content:"\e630"; +} + +.fw-esb-connector:before { + content:"\e6e3"; +} + +.fw-expand:before { + content:"\e61c"; +} + +.fw-export:before { + content:"\e631"; +} + +.fw-extensions:before { + content:"\e6e4"; +} + +.fw-facebook:before { + content:"\e6d3"; +} + +.fw-factory-reset:before { + content:"\e632"; +} + +.fw-fan:before { + content:"\e678"; +} + +.fw-faq:before { + content:"\e62f"; +} + +.fw-file-browse:before { + content:"\e633"; +} + +.fw-filter:before { + content:"\e634"; +} + +.fw-folder-open:before { + content:"\e70b"; +} + +.fw-folder:before { + content:"\e62e"; +} + +.fw-fork-join:before { + content:"\e720"; +} + +.fw-format:before { + content:"\e6fa"; +} + +.fw-forum:before { + content:"\e636"; +} + +.fw-function-invoke:before { + content:"\e713"; +} + +.fw-function:before { + content:"\e6fb"; +} + +.fw-gadget:before { + content:"\e637"; +} + +.fw-geo-fence-inbound:before { + content:"\e72e"; +} + +.fw-geo-fence-outbound:before { + content:"\e72f"; +} + +.fw-github:before { + content:"\e6d4"; +} + +.fw-globe:before { + content:"\e697"; +} + +.fw-google-docs:before { + content:"\e6d6"; +} + +.fw-google-drive:before { + content:"\e6da"; +} + +.fw-google-plus:before { + content:"\e6d9"; +} + +.fw-google-sheets:before { + content:"\e6d7"; +} + +.fw-google-slides:before { + content:"\e6d8"; +} + +.fw-google:before { + content:"\e6d5"; +} + +.fw-grid:before { + content:"\e638"; +} + +.fw-grip:before { + content:"\e6b7"; +} + +.fw-group:before { + content:"\e6af"; +} + +.fw-hardware:before { + content:"\e6a9"; +} + +.fw-hdd:before { + content:"\e639"; +} + +.fw-heart:before { + content:"\e6c3"; +} + +.fw-hide:before { + content:"\e6d2"; +} + +.fw-home:before { + content:"\e63a"; +} + +.fw-hour-glass:before { + content:"\e63b"; +} + +.fw-html:before { + content:"\e69d"; +} + +.fw-http:before { + content:"\e705"; +} + +.fw-image:before { + content:"\e70a"; +} + +.fw-import:before { + content:"\e63c"; +} + +.fw-incoming-call:before { + content:"\e63d"; +} + +.fw-info:before { + content:"\e63e"; +} + +.fw-instagram:before { + content:"\e6db"; +} + +.fw-invitation:before { + content:"\e63f"; +} + +.fw-invoke:before { + content:"\e6ed"; +} + +.fw-is-connector:before { + content:"\e6e5"; +} + +.fw-iterate:before { + content:"\e71f"; +} + +.fw-jaggery:before { + content:"\e640"; +} + +.fw-java-spring:before { + content:"\e644"; +} + +.fw-java:before { + content:"\e641"; +} + +.fw-javaee:before { + content:"\e642"; +} + +.fw-javascript:before { + content:"\e643"; +} + +.fw-jaxrs:before { + content:"\e645"; +} + +.fw-jaxws:before { + content:"\e6c7"; +} + +.fw-jquery:before { + content:"\e646"; +} + +.fw-key:before { + content:"\e647"; +} + +.fw-laptop:before { + content:"\e648"; +} + +.fw-layout:before { + content:"\e6bf"; +} + +.fw-ldap:before { + content:"\e649"; +} + +.fw-left-arrow:before { + content:"\e68a"; +} + +.fw-left:before { + content:"\e686"; +} + +.fw-lifecycle:before { + content:"\e64a"; +} + +.fw-light:before { + content:"\e680"; +} + +.fw-linkedin:before { + content:"\e6dc"; +} + +.fw-list-sort:before { + content:"\e64d"; +} + +.fw-list:before { + content:"\e64c"; +} + +.fw-loader:before { + content:"\e6b4"; +} + +.fw-loader2:before { + content:"\e6ba"; +} + +.fw-loader3:before { + content:"\e6bb"; +} + +.fw-loader4:before { + content:"\e6bc"; +} + +.fw-loader5:before { + content:"\e6bd"; +} + +.fw-lock:before { + content:"\e64e"; +} + +.fw-logical:before { + content:"\e702"; +} + +.fw-mail:before { + content:"\e64f"; +} + +.fw-main-function:before { + content:"\e706"; +} + +.fw-map-location:before { + content:"\e650"; +} + +.fw-menu:before { + content:"\e651"; +} + +.fw-message:before { + content:"\e635"; +} + +.fw-micro-services:before { + content:"\e6ce"; +} + +.fw-minus:before, .fw-hyphen:before, .fw-dash:before { + content:"\e616"; +} + +.fw-mobile:before { + content:"\e652"; +} + +.fw-ms-document:before { + content:"\e654"; +} + +.fw-mute:before { + content:"\e655"; +} + +.fw-nodejs:before { + content:"\e656"; +} + +.fw-notification:before { + content:"\e60b"; +} + +.fw-organization:before { + content:"\e6ac"; +} + +.fw-own:before { + content:"\e6c8"; +} + +.fw-package:before { + content:"\e6fd"; +} + +.fw-pages:before { + content:"\e6c0"; +} + +.fw-paste:before { + content:"\e658"; +} + +.fw-pdf:before { + content:"\e659"; +} + +.fw-pending:before { + content:"\e727"; +} + +.fw-php:before { + content:"\e6c9"; +} + +.fw-pie-chart:before { + content:"\e65a"; +} + +.fw-pinterest:before { + content:"\e6dd"; +} + +.fw-policy:before { + content:"\e67d"; +} + +.fw-polygon:before { + content:"\e70d"; +} + +.fw-prototype:before { + content:"\e6cc"; +} + +.fw-proxy:before { + content:"\e699"; +} + +.fw-public:before { + content:"\e6ad"; +} + +.fw-publish:before { + content:"\e65c"; +} + +.fw-question:before { + content:"\e6b0"; +} + +.fw-raspberry:before { + content:"\e6aa"; +} + +.fw-redo:before { + content:"\e65d"; +} + +.fw-refresh:before { + content:"\e692"; +} + +.fw-register:before { + content:"\e65e"; +} + +.fw-rename:before { + content:"\e6fc"; +} + +.fw-reply:before { + content:"\e714"; +} + +.fw-resource:before { + content:"\e660"; +} + +.fw-rest-api:before { + content:"\e661"; +} + +.fw-rest-service:before { + content:"\e662"; +} + +.fw-resume:before { + content:"\e71e"; +} + +.fw-retire:before { + content:"\e6cd"; +} + +.fw-return:before { + content:"\e715"; +} + +.fw-retweet:before { + content:"\e6b9"; +} + +.fw-right-arrow:before { + content:"\e68b"; +} + +.fw-right:before { + content:"\e687"; +} + +.fw-ringing:before { + content:"\e694"; +} + +.fw-rules:before { + content:"\e664"; +} + +.fw-run:before { + content:"\e708"; +} + +.fw-save:before { + content:"\e665"; +} + +.fw-scep:before { + content:"\e666"; +} + +.fw-schema:before { + content:"\e667"; +} + +.fw-search:before { + content:"\e668"; +} + +.fw-security-policy:before { + content:"\e67e"; +} + +.fw-security:before { + content:"\e669"; +} + +.fw-send:before, .fw-paper-rocket:before { + content:"\e66a"; +} + +.fw-sequence:before { + content:"\e66b"; +} + +.fw-server:before { + content:"\e66c"; +} + +.fw-service-provider:before { + content:"\e66e"; +} + +.fw-service:before, .fw-cogwheels:before, .fw-gears:before, .fw-sprockets:before { + content:"\e66d"; +} + +.fw-settings:before, .fw-cogwheel:before, .fw-gear:before, .fw-sprocket:before { + content:"\e66f"; +} + +.fw-share:before { + content:"\e670"; +} + +.fw-shell:before { + content:"\e730"; +} + +.fw-shortcut:before { + content:"\e725"; +} + +.fw-sign-in:before { + content:"\e671"; +} + +.fw-sign-out:before { + content:"\e6b8"; +} + +.fw-skype:before { + content:"\e6de"; +} + +.fw-slash:before { + content:"\e6e1"; +} + +.fw-soap:before { + content:"\e672"; +} + +.fw-sort-down:before { + content:"\e663"; +} + +.fw-sort-up:before { + content:"\e64b"; +} + +.fw-sort:before { + content:"\e673"; +} + +.fw-speed-alert:before { + content:"\e731"; +} + +.fw-square-outline:before { + content:"\e6b2"; +} + +.fw-square:before { + content:"\e6b1"; +} + +.fw-star:before { + content:"\e674"; +} + +.fw-start:before { + content:"\e718"; +} + +.fw-statistics:before { + content:"\e675"; +} + +.fw-stepin:before { + content:"\e719"; +} + +.fw-stepout:before { + content:"\e71a"; +} + +.fw-stepover:before { + content:"\e71b"; +} + +.fw-stop:before { + content:"\e71c"; +} + +.fw-store:before, .fw-cart:before { + content:"\e676"; +} + +.fw-struct:before { + content:"\e716"; +} + +.fw-subscribe:before { + content:"\e677"; +} + +.fw-success:before { + content:"\e657"; +} + +.fw-swagger:before { + content:"\e679"; +} + +.fw-sync:before { + content:"\e6b3"; +} + +.fw-table:before { + content:"\e6c4"; +} + +.fw-tag:before { + content:"\e67a"; +} + +.fw-task:before { + content:"\e67b"; +} + +.fw-text:before { + content:"\e67c"; +} + +.fw-theme:before { + content:"\e726"; +} + +.fw-throttling-policy:before { + content:"\e67f"; +} + +.fw-throw:before { + content:"\e722"; +} + +.fw-tiles:before { + content:"\e681"; +} + +.fw-transaction:before { + content:"\e72b"; +} + +.fw-try-catch:before { + content:"\e703"; +} + +.fw-twitter:before { + content:"\e6df"; +} + +.fw-type-converter:before { + content:"\e6f3"; +} + +.fw-uncheck:before { + content:"\e682"; +} + +.fw-undo:before { + content:"\e683"; +} + +.fw-ungroup:before { + content:"\e6b5"; +} + +.fw-unmute:before { + content:"\e6ae"; +} + +.fw-up-arrow:before { + content:"\e688"; +} + +.fw-up:before { + content:"\e684"; +} + +.fw-upload:before { + content:"\e68c"; +} + +.fw-uri:before { + content:"\e68d"; +} + +.fw-usb-drive:before { + content:"\e68e"; +} + +.fw-use:before { + content:"\e6ca"; +} + +.fw-user:before { + content:"\e68f"; +} + +.fw-variable:before { + content:"\e6ee"; +} + +.fw-view:before { + content:"\e691"; +} + +.fw-vpn:before { + content:"\e603"; +} + +.fw-wadl:before { + content:"\e6a1"; +} + +.fw-war:before { + content:"\e69e"; +} + +.fw-warning:before { + content:"\e693"; +} + +.fw-web-app:before { + content:"\e696"; +} + +.fw-web-clip:before { + content:"\e698"; +} + +.fw-web-service:before { + content:"\e69a"; +} + +.fw-website:before { + content:"\e69b"; +} + +.fw-wifi:before { + content:"\e607"; +} + +.fw-windows:before { + content:"\e605"; +} + +.fw-worker-invoke:before { + content:"\e723"; +} + +.fw-worker-reply:before { + content:"\e724"; +} + +.fw-worker:before { + content:"\e6ef"; +} + +.fw-wsdl:before { + content:"\e6a0"; +} + +.fw-wso2-logo:before { + content:"\e6a7"; +} + +.fw-wso2:before { + content:"\e6a8"; +} + +.fw-xacml:before { + content:"\e69f"; +} + +.fw-xml:before { + content:"\e69c"; +} + +.fw-xq:before { + content:"\e6a2"; +} + +.fw-xsd:before { + content:"\e6a3"; +} + +.fw-xslt:before { + content:"\e6a4"; +} + +.fw-youtube:before { + content:"\e6e0"; +} + +.fw-zoom-in:before { + content:"\e6a5"; +} + +.fw-zoom-out:before { + content:"\e6a6"; +} + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/css/font-wso2.min.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/css/font-wso2.min.css new file mode 100644 index 0000000000..6d229b71da --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/css/font-wso2.min.css @@ -0,0 +1,15 @@ +/*! +~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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. +*/.fw-fw,.fw-li{text-align:center}@font-face{font-family:font-wso2;src:local("font-wso2"),url(../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223);src:local("font-wso2"),url(../fonts/font-wso2.eot?#iefix) format("embedded-opentype"),url(../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223) format("woff2"),url(../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223) format("woff"),url(../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223) format("truetype"),url(../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2) format("svg");font-weight:400;font-style:normal}.fw,[class*=" fw-"],[class^=fw-]{font:normal normal normal 14px/1 font-wso2;display:inline-block;font-weight:400;font-style:normal;font-size:inherit;font-variant:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fw-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fw-2x{font-size:2em}.fw-3x{font-size:3em}.fw-4x{font-size:4em}.fw-5x{font-size:5em}.fw-fw{width:1.28571429em}.fw-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fw-ul>li{position:relative}.fw-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em}.fw-li.fw-lg{left:-1.85714286em}.fw-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fw-background{background:#888;border-radius:.3em;padding:.4em .5em .45em}.fw-pull-left{float:left}.fw-pull-right{float:right}.fw.fw-pull-left{margin-right:.3em}.fw.fw-pull-right{margin-left:.3em}.fw-spin{-webkit-animation:fw-spin 2s infinite linear;animation:fw-spin 2s infinite linear}@-webkit-keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fw-pulse{-webkit-animation:fw-pulse 2s ease-out infinite;animation:fw-pulse 2s ease-out infinite}@-webkit-keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}@keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}.fw-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fw-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fw-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fw-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fw-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fw-flip-horizontal,:root .fw-flip-vertical,:root .fw-rotate-180,:root .fw-rotate-270,:root .fw-rotate-90{filter:none}.fw-helper,.fw-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:1.85em;vertical-align:middle}.fw-helper:after,.fw-helper:before,.fw-stack-1x,.fw-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fw-helper:before,.fw-stack-1x{line-height:inherit}.fw-helper:after,.fw-stack-2x{font-size:1.9em}.fw-helper-slash:before{font-size:1.4em}.fw-helper-circle:before,.fw-helper-square:before{z-index:1}.fw-helper-circle-outline:after{content:"\e61f"}.fw-helper-circle:after{content:"\e61a"}.fw-helper-square-outline:after{content:"\e6b2"}.fw-helper-square:after{content:"\e6b1"}.fw-helper-slash:after{content:"\e6e1"}.fw-stack>.fw-stack{position:absolute;font-size:.5em}.fw-stack>.fw-stack.fw-move-top{top:-.2em}.fw-stack>.fw-stack.fw-move-bottom{bottom:-.2em}.fw-stack>.fw.stack.fw-move-left{left:-.5em}.fw-stack>.fw-stack.fw-move-right{right:-.5em}.fw-helper-inverse:after,.fw-inverse:before,.fw-number{color:#fff}.fw-helper-shadow:after,.fw-shadow:before{text-shadow:#fff 1px 1px 0}.fw-helper-stroke:after,.fw-stroke:before{text-shadow:-2px -2px 0 #fff,2px -2px 0 #fff,-2px 2px 0 #fff,2px 2px 0 #fff}.fw-number{line-height:2em;font-family:Arial,Helvetica,sans-serif}.fw-abort:before{content:"\e72a"}.fw-action-invoke:before{content:"\e6fe"}.fw-action:before{content:"\e709"}.fw-activate:before{content:"\e6cf"}.fw-add:before{content:"\e615"}.fw-airplay:before{content:"\e600"}.fw-alarm:before{content:"\e6c2"}.fw-alert:before{content:"\e6be"}.fw-analytics-extensions:before{content:"\e6e2"}.fw-android-logcat:before{content:"\e72c"}.fw-android-sense:before{content:"\e72d"}.fw-android:before{content:"\e606"}.fw-annotation:before{content:"\e6e6"}.fw-api:before{content:"\e601"}.fw-apn:before{content:"\e602"}.fw-apple:before{content:"\e604"}.fw-application:before{content:"\e608"}.fw-arduino:before{content:"\e6ab"}.fw-assign:before{content:"\e6ff"}.fw-ballerina-service:before{content:"\e729"}.fw-ballerina:before{content:"\e728"}.fw-bar-chart:before{content:"\e690"}.fw-battery:before{content:"\e60a"}.fw-blank-document:before{content:"\e60c"}.fw-block:before{content:"\e695"}.fw-bookmark:before{content:"\e60d"}.fw-bpel:before{content:"\e60e"}.fw-bpmn:before{content:"\e60f"}.fw-break:before{content:"\e721"}.fw-bug:before{content:"\e611"}.fw-build:before{content:"\e6c1"}.fw-calendar:before{content:"\e612"}.fw-camera:before{content:"\e613"}.fw-cancel:before{content:"\e618"}.fw-carbon:before{content:"\e6c5"}.fw-chat:before{content:"\e65b"}.fw-check:before{content:"\e617"}.fw-checklist:before{content:"\e619"}.fw-circle-outline:before{content:"\e61f"}.fw-circle:before{content:"\e61a"}.fw-clear:before{content:"\e61b"}.fw-clock:before{content:"\e61d"}.fw-cloud:before{content:"\e61e"}.fw-code-view:before{content:"\e70e"}.fw-code:before{content:"\e6f1"}.fw-comment:before{content:"\e710"}.fw-compare:before{content:"\e610"}.fw-computer:before{content:"\e653"}.fw-configarations:before{content:"\e609"}.fw-connector:before{content:"\e700"}.fw-console:before{content:"\e71d"}.fw-constant:before{content:"\e701"}.fw-contact:before{content:"\e620"}.fw-contract:before{content:"\e614"}.fw-copy:before{content:"\e621"}.fw-cut:before{content:"\e6f2"}.fw-dashboard:before{content:"\e622"}.fw-database:before{content:"\e623"}.fw-delete:before{content:"\e624"}.fw-depend:before{content:"\e6c6"}.fw-deploy:before{content:"\e625"}.fw-deprecate:before{content:"\e6cb"}.fw-design-view:before{content:"\e70f"}.fw-devices:before{content:"\e704"}.fw-dgm-action-invoke:before{content:"\e712"}.fw-dgm-action:before{content:"\e711"}.fw-dgm-connector:before{content:"\e6f4"}.fw-dgm-constant-definition:before{content:"\e6f5"}.fw-dgm-fork:before{content:"\e6e7"}.fw-dgm-header:before{content:"\e6e8"}.fw-dgm-if-else:before{content:"\e6e9"}.fw-dgm-import:before{content:"\e717"}.fw-dgm-lifeline:before{content:"\e6ea"}.fw-dgm-logger:before{content:"\e6eb"}.fw-dgm-resource:before{content:"\e6f6"}.fw-dgm-service:before{content:"\e6f7"}.fw-dgm-try-catch:before{content:"\e6ec"}.fw-dgm-type-convertor:before{content:"\e6f8"}.fw-dgm-type:before{content:"\e6f9"}.fw-dgm-while:before{content:"\e707"}.fw-dial-up:before{content:"\e627"}.fw-disabled:before{content:"\e6d1"}.fw-display:before{content:"\e626"}.fw-docker:before{content:"\e70c"}.fw-document:before{content:"\e628"}.fw-down-arrow:before{content:"\e689"}.fw-down:before{content:"\e685"}.fw-download:before{content:"\e65f"}.fw-dss:before{content:"\e62a"}.fw-ebook:before{content:"\e62b"}.fw-edit:before{content:"\e62c"}.fw-ellipsis:before{content:"\e629"}.fw-endpoint:before{content:"\e62d"}.fw-enterprise:before{content:"\e6b6"}.fw-error:before{content:"\e630"}.fw-esb-connector:before{content:"\e6e3"}.fw-expand:before{content:"\e61c"}.fw-export:before{content:"\e631"}.fw-extensions:before{content:"\e6e4"}.fw-facebook:before{content:"\e6d3"}.fw-factory-reset:before{content:"\e632"}.fw-fan:before{content:"\e678"}.fw-faq:before{content:"\e62f"}.fw-file-browse:before{content:"\e633"}.fw-filter:before{content:"\e634"}.fw-folder-open:before{content:"\e70b"}.fw-folder:before{content:"\e62e"}.fw-fork-join:before{content:"\e720"}.fw-format:before{content:"\e6fa"}.fw-forum:before{content:"\e636"}.fw-function-invoke:before{content:"\e713"}.fw-function:before{content:"\e6fb"}.fw-gadget:before{content:"\e637"}.fw-geo-fence-inbound:before{content:"\e72e"}.fw-geo-fence-outbound:before{content:"\e72f"}.fw-github:before{content:"\e6d4"}.fw-globe:before{content:"\e697"}.fw-google-docs:before{content:"\e6d6"}.fw-google-drive:before{content:"\e6da"}.fw-google-plus:before{content:"\e6d9"}.fw-google-sheets:before{content:"\e6d7"}.fw-google-slides:before{content:"\e6d8"}.fw-google:before{content:"\e6d5"}.fw-grid:before{content:"\e638"}.fw-grip:before{content:"\e6b7"}.fw-group:before{content:"\e6af"}.fw-hardware:before{content:"\e6a9"}.fw-hdd:before{content:"\e639"}.fw-heart:before{content:"\e6c3"}.fw-hide:before{content:"\e6d2"}.fw-home:before{content:"\e63a"}.fw-hour-glass:before{content:"\e63b"}.fw-html:before{content:"\e69d"}.fw-http:before{content:"\e705"}.fw-image:before{content:"\e70a"}.fw-import:before{content:"\e63c"}.fw-incoming-call:before{content:"\e63d"}.fw-info:before{content:"\e63e"}.fw-instagram:before{content:"\e6db"}.fw-invitation:before{content:"\e63f"}.fw-invoke:before{content:"\e6ed"}.fw-is-connector:before{content:"\e6e5"}.fw-iterate:before{content:"\e71f"}.fw-jaggery:before{content:"\e640"}.fw-java-spring:before{content:"\e644"}.fw-java:before{content:"\e641"}.fw-javaee:before{content:"\e642"}.fw-javascript:before{content:"\e643"}.fw-jaxrs:before{content:"\e645"}.fw-jaxws:before{content:"\e6c7"}.fw-jquery:before{content:"\e646"}.fw-key:before{content:"\e647"}.fw-laptop:before{content:"\e648"}.fw-layout:before{content:"\e6bf"}.fw-ldap:before{content:"\e649"}.fw-left-arrow:before{content:"\e68a"}.fw-left:before{content:"\e686"}.fw-lifecycle:before{content:"\e64a"}.fw-light:before{content:"\e680"}.fw-linkedin:before{content:"\e6dc"}.fw-list-sort:before{content:"\e64d"}.fw-list:before{content:"\e64c"}.fw-loader:before{content:"\e6b4"}.fw-loader2:before{content:"\e6ba"}.fw-loader3:before{content:"\e6bb"}.fw-loader4:before{content:"\e6bc"}.fw-loader5:before{content:"\e6bd"}.fw-lock:before{content:"\e64e"}.fw-logical:before{content:"\e702"}.fw-mail:before{content:"\e64f"}.fw-main-function:before{content:"\e706"}.fw-map-location:before{content:"\e650"}.fw-menu:before{content:"\e651"}.fw-message:before{content:"\e635"}.fw-micro-services:before{content:"\e6ce"}.fw-dash:before,.fw-hyphen:before,.fw-minus:before{content:"\e616"}.fw-mobile:before{content:"\e652"}.fw-ms-document:before{content:"\e654"}.fw-mute:before{content:"\e655"}.fw-nodejs:before{content:"\e656"}.fw-notification:before{content:"\e60b"}.fw-organization:before{content:"\e6ac"}.fw-own:before{content:"\e6c8"}.fw-package:before{content:"\e6fd"}.fw-pages:before{content:"\e6c0"}.fw-paste:before{content:"\e658"}.fw-pdf:before{content:"\e659"}.fw-pending:before{content:"\e727"}.fw-php:before{content:"\e6c9"}.fw-pie-chart:before{content:"\e65a"}.fw-pinterest:before{content:"\e6dd"}.fw-policy:before{content:"\e67d"}.fw-polygon:before{content:"\e70d"}.fw-prototype:before{content:"\e6cc"}.fw-proxy:before{content:"\e699"}.fw-public:before{content:"\e6ad"}.fw-publish:before{content:"\e65c"}.fw-question:before{content:"\e6b0"}.fw-raspberry:before{content:"\e6aa"}.fw-redo:before{content:"\e65d"}.fw-refresh:before{content:"\e692"}.fw-register:before{content:"\e65e"}.fw-rename:before{content:"\e6fc"}.fw-reply:before{content:"\e714"}.fw-resource:before{content:"\e660"}.fw-rest-api:before{content:"\e661"}.fw-rest-service:before{content:"\e662"}.fw-resume:before{content:"\e71e"}.fw-retire:before{content:"\e6cd"}.fw-return:before{content:"\e715"}.fw-retweet:before{content:"\e6b9"}.fw-right-arrow:before{content:"\e68b"}.fw-right:before{content:"\e687"}.fw-ringing:before{content:"\e694"}.fw-rules:before{content:"\e664"}.fw-run:before{content:"\e708"}.fw-save:before{content:"\e665"}.fw-scep:before{content:"\e666"}.fw-schema:before{content:"\e667"}.fw-search:before{content:"\e668"}.fw-security-policy:before{content:"\e67e"}.fw-security:before{content:"\e669"}.fw-paper-rocket:before,.fw-send:before{content:"\e66a"}.fw-sequence:before{content:"\e66b"}.fw-server:before{content:"\e66c"}.fw-service-provider:before{content:"\e66e"}.fw-cogwheels:before,.fw-gears:before,.fw-service:before,.fw-sprockets:before{content:"\e66d"}.fw-cogwheel:before,.fw-gear:before,.fw-settings:before,.fw-sprocket:before{content:"\e66f"}.fw-share:before{content:"\e670"}.fw-shell:before{content:"\e730"}.fw-shortcut:before{content:"\e725"}.fw-sign-in:before{content:"\e671"}.fw-sign-out:before{content:"\e6b8"}.fw-skype:before{content:"\e6de"}.fw-slash:before{content:"\e6e1"}.fw-soap:before{content:"\e672"}.fw-sort-down:before{content:"\e663"}.fw-sort-up:before{content:"\e64b"}.fw-sort:before{content:"\e673"}.fw-speed-alert:before{content:"\e731"}.fw-square-outline:before{content:"\e6b2"}.fw-square:before{content:"\e6b1"}.fw-star:before{content:"\e674"}.fw-start:before{content:"\e718"}.fw-statistics:before{content:"\e675"}.fw-stepin:before{content:"\e719"}.fw-stepout:before{content:"\e71a"}.fw-stepover:before{content:"\e71b"}.fw-stop:before{content:"\e71c"}.fw-cart:before,.fw-store:before{content:"\e676"}.fw-struct:before{content:"\e716"}.fw-subscribe:before{content:"\e677"}.fw-success:before{content:"\e657"}.fw-swagger:before{content:"\e679"}.fw-sync:before{content:"\e6b3"}.fw-table:before{content:"\e6c4"}.fw-tag:before{content:"\e67a"}.fw-task:before{content:"\e67b"}.fw-text:before{content:"\e67c"}.fw-theme:before{content:"\e726"}.fw-throttling-policy:before{content:"\e67f"}.fw-throw:before{content:"\e722"}.fw-tiles:before{content:"\e681"}.fw-transaction:before{content:"\e72b"}.fw-try-catch:before{content:"\e703"}.fw-twitter:before{content:"\e6df"}.fw-type-converter:before{content:"\e6f3"}.fw-uncheck:before{content:"\e682"}.fw-undo:before{content:"\e683"}.fw-ungroup:before{content:"\e6b5"}.fw-unmute:before{content:"\e6ae"}.fw-up-arrow:before{content:"\e688"}.fw-up:before{content:"\e684"}.fw-upload:before{content:"\e68c"}.fw-uri:before{content:"\e68d"}.fw-usb-drive:before{content:"\e68e"}.fw-use:before{content:"\e6ca"}.fw-user:before{content:"\e68f"}.fw-variable:before{content:"\e6ee"}.fw-view:before{content:"\e691"}.fw-vpn:before{content:"\e603"}.fw-wadl:before{content:"\e6a1"}.fw-war:before{content:"\e69e"}.fw-warning:before{content:"\e693"}.fw-web-app:before{content:"\e696"}.fw-web-clip:before{content:"\e698"}.fw-web-service:before{content:"\e69a"}.fw-website:before{content:"\e69b"}.fw-wifi:before{content:"\e607"}.fw-windows:before{content:"\e605"}.fw-worker-invoke:before{content:"\e723"}.fw-worker-reply:before{content:"\e724"}.fw-worker:before{content:"\e6ef"}.fw-wsdl:before{content:"\e6a0"}.fw-wso2-logo:before{content:"\e6a7"}.fw-wso2:before{content:"\e6a8"}.fw-xacml:before{content:"\e69f"}.fw-xml:before{content:"\e69c"}.fw-xq:before{content:"\e6a2"}.fw-xsd:before{content:"\e6a3"}.fw-xslt:before{content:"\e6a4"}.fw-youtube:before{content:"\e6e0"}.fw-zoom-in:before{content:"\e6a5"}.fw-zoom-out:before{content:"\e6a6"} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.ttf b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.ttf new file mode 100644 index 0000000000..aa00de0ef9 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.ttf differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.woff b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.woff new file mode 100644 index 0000000000..ced7907e94 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.woff differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.woff2 b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.woff2 new file mode 100644 index 0000000000..723a32343b Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Medium.woff2 differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.ttf b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.ttf new file mode 100644 index 0000000000..3e6e2e7613 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.ttf differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.woff b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.woff new file mode 100644 index 0000000000..e401bcf528 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.woff differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.woff2 b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.woff2 new file mode 100644 index 0000000000..5bd7bd6500 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/Roboto-Regular.woff2 differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.svg b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.svg new file mode 100644 index 0000000000..91614ea75e --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.svg @@ -0,0 +1,2326 @@ + + + + + +Created by FontForge 20161004 at Wed Jun 21 08:31:03 2017 + By dimal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.ttf b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.ttf new file mode 100644 index 0000000000..27735b2820 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.ttf differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.woff b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.woff new file mode 100644 index 0000000000..80fd5a7fc2 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.woff differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.woff2 b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.woff2 new file mode 100644 index 0000000000..6087330889 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/fonts/font-wso2.woff2 differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/images/favicon.png b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/images/favicon.png new file mode 100644 index 0000000000..a1deab3581 Binary files /dev/null and b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/images/favicon.png differ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/images/logo.svg b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/images/logo.svg new file mode 100644 index 0000000000..05742db887 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/images/logo.svg @@ -0,0 +1,798 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/locales/en.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/locales/en.json new file mode 100644 index 0000000000..5be6f63bd4 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/locales/en.json @@ -0,0 +1,67 @@ +{ + "Title" : "Title", + "Description" : "Description", + "ShortDescription" : "Short Description", + "Category" : "Category", + "Visibility" : "Visibility", + "Devices" : "Devices", + "Roles" : "Roles", + "Groups" : "Groups", + "Tags" : "Tags", + "Platform" : "Platform", + "Platforms" : "Platforms", + "Applications": "Applications", + "No.Platform" : "No Platforms", + "Screenshots" : "Screenshots", + "Icon" : "Icon", + "Info" : "Info", + "Banner" : "Banner", + "Create.Application" : "Create Application", + "Back" : "Back", + "Cancel" : "Cancel", + "Finish" : "Finish", + "Continue" : "Continue", + "Name" : "Name", + "Application.Name" : "Application Name", + "General" : "General", + "App.Releases" : "Application Releases", + "Package.Manager" : "Package Manager", + "Save" : "Save", + "Create.Release" : "Create Release", + "Release.Channel" : "Release Channel", + "Release" : "Release", + "New.Release.For" : "New Release for", + "Upload.Package.File" : "Upload Package File", + "Upload" : "Upload", + "Select.from.package.library" : "Select from package library", + "Release.Name" : "Release Name", + "Release.Notes" : "Release Notes", + "Send.for.Review" : "Send for Review", + "Production.Releases" : "Production Releases", + "Beta.Releases" : "Beta Releases", + "Alpha.Releases" : "Alpha Releases", + "Version" : "Version", + "Status" : "Status", + "App.Publisher" : "Application Publisher", + "Search.Apps" : "Search for Applications", + "View.In.Store" : "View in Store", + "Last.Updated" : "Last updated on", + "Installs" : "Installs", + "General.Info" : "General Info", + "Select.Platform": "Select Platform", + "Add.Release" : "Add Release to Application", + "Share.With.Tenants" : "Share with Tenants", + "Disable" : "Disable", + "File.Based" : "File Based", + "Activate" : "Activate", + "Yes" : "Yes", + "No" : "No", + "No.Platform.Tags" : "No Platform Tags", + "Create.Platform" : "Create Platform", + "Optional": "Optional", + "Identifier": "Identifier", + "Next": "Next", + "Platform.Enable": "Enable Platform", + "Share.with.Tenants": "Share between all tenants", + "Platform.Properties": "Platform Properties" +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/scss/_mixin.scss b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/scss/_mixin.scss new file mode 100644 index 0000000000..5b40942bef --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/scss/_mixin.scss @@ -0,0 +1,1252 @@ +/*! +~ Copyright (c) 2017 WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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. +*/ + +%icon-base { + &:before { + font-family: "font-wso2"; + -webkit-font-smoothing: antialiased; + } + b { + // hide text + height: 0; + display: block; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } +} + +@mixin font-wso2($icon) { + @extend %icon-base; + + + @if ($icon == "abort") { + content:"\e72a"; + } + + @else if ($icon == "action-invoke") { + content:"\e6fe"; + } + + @else if ($icon == "action") { + content:"\e709"; + } + + @else if ($icon == "activate") { + content:"\e6cf"; + } + + @else if ($icon == "add") { + content:"\e615"; + } + + @else if ($icon == "airplay") { + content:"\e600"; + } + + @else if ($icon == "alarm") { + content:"\e6c2"; + } + + @else if ($icon == "alert") { + content:"\e6be"; + } + + @else if ($icon == "analytics-extensions") { + content:"\e6e2"; + } + + @else if ($icon == "android-logcat") { + content:"\e72c"; + } + + @else if ($icon == "android-sense") { + content:"\e72d"; + } + + @else if ($icon == "android") { + content:"\e606"; + } + + @else if ($icon == "annotation") { + content:"\e6e6"; + } + + @else if ($icon == "api") { + content:"\e601"; + } + + @else if ($icon == "apn") { + content:"\e602"; + } + + @else if ($icon == "apple") { + content:"\e604"; + } + + @else if ($icon == "application") { + content:"\e608"; + } + + @else if ($icon == "arduino") { + content:"\e6ab"; + } + + @else if ($icon == "assign") { + content:"\e6ff"; + } + + @else if ($icon == "ballerina-service") { + content:"\e729"; + } + + @else if ($icon == "ballerina") { + content:"\e728"; + } + + @else if ($icon == "bar-chart") { + content:"\e690"; + } + + @else if ($icon == "battery") { + content:"\e60a"; + } + + @else if ($icon == "blank-document") { + content:"\e60c"; + } + + @else if ($icon == "block") { + content:"\e695"; + } + + @else if ($icon == "bookmark") { + content:"\e60d"; + } + + @else if ($icon == "bpel") { + content:"\e60e"; + } + + @else if ($icon == "bpmn") { + content:"\e60f"; + } + + @else if ($icon == "break") { + content:"\e721"; + } + + @else if ($icon == "bug") { + content:"\e611"; + } + + @else if ($icon == "build") { + content:"\e6c1"; + } + + @else if ($icon == "calendar") { + content:"\e612"; + } + + @else if ($icon == "camera") { + content:"\e613"; + } + + @else if ($icon == "cancel") { + content:"\e618"; + } + + @else if ($icon == "carbon") { + content:"\e6c5"; + } + + @else if ($icon == "chat") { + content:"\e65b"; + } + + @else if ($icon == "check") { + content:"\e617"; + } + + @else if ($icon == "checklist") { + content:"\e619"; + } + + @else if ($icon == "circle-outline") { + content:"\e61f"; + } + + @else if ($icon == "circle") { + content:"\e61a"; + } + + @else if ($icon == "clear") { + content:"\e61b"; + } + + @else if ($icon == "clock") { + content:"\e61d"; + } + + @else if ($icon == "cloud") { + content:"\e61e"; + } + + @else if ($icon == "code-view") { + content:"\e70e"; + } + + @else if ($icon == "code") { + content:"\e6f1"; + } + + @else if ($icon == "comment") { + content:"\e710"; + } + + @else if ($icon == "compare") { + content:"\e610"; + } + + @else if ($icon == "computer") { + content:"\e653"; + } + + @else if ($icon == "configarations") { + content:"\e609"; + } + + @else if ($icon == "connector") { + content:"\e700"; + } + + @else if ($icon == "console") { + content:"\e71d"; + } + + @else if ($icon == "constant") { + content:"\e701"; + } + + @else if ($icon == "contact") { + content:"\e620"; + } + + @else if ($icon == "contract") { + content:"\e614"; + } + + @else if ($icon == "copy") { + content:"\e621"; + } + + @else if ($icon == "cut") { + content:"\e6f2"; + } + + @else if ($icon == "dashboard") { + content:"\e622"; + } + + @else if ($icon == "database") { + content:"\e623"; + } + + @else if ($icon == "delete") { + content:"\e624"; + } + + @else if ($icon == "depend") { + content:"\e6c6"; + } + + @else if ($icon == "deploy") { + content:"\e625"; + } + + @else if ($icon == "deprecate") { + content:"\e6cb"; + } + + @else if ($icon == "design-view") { + content:"\e70f"; + } + + @else if ($icon == "devices") { + content:"\e704"; + } + + @else if ($icon == "dgm-action-invoke") { + content:"\e712"; + } + + @else if ($icon == "dgm-action") { + content:"\e711"; + } + + @else if ($icon == "dgm-connector") { + content:"\e6f4"; + } + + @else if ($icon == "dgm-constant-definition") { + content:"\e6f5"; + } + + @else if ($icon == "dgm-fork") { + content:"\e6e7"; + } + + @else if ($icon == "dgm-header") { + content:"\e6e8"; + } + + @else if ($icon == "dgm-if-else") { + content:"\e6e9"; + } + + @else if ($icon == "dgm-import") { + content:"\e717"; + } + + @else if ($icon == "dgm-lifeline") { + content:"\e6ea"; + } + + @else if ($icon == "dgm-logger") { + content:"\e6eb"; + } + + @else if ($icon == "dgm-resource") { + content:"\e6f6"; + } + + @else if ($icon == "dgm-service") { + content:"\e6f7"; + } + + @else if ($icon == "dgm-try-catch") { + content:"\e6ec"; + } + + @else if ($icon == "dgm-type-convertor") { + content:"\e6f8"; + } + + @else if ($icon == "dgm-type") { + content:"\e6f9"; + } + + @else if ($icon == "dgm-while") { + content:"\e707"; + } + + @else if ($icon == "dial-up") { + content:"\e627"; + } + + @else if ($icon == "disabled") { + content:"\e6d1"; + } + + @else if ($icon == "display") { + content:"\e626"; + } + + @else if ($icon == "docker") { + content:"\e70c"; + } + + @else if ($icon == "document") { + content:"\e628"; + } + + @else if ($icon == "down-arrow") { + content:"\e689"; + } + + @else if ($icon == "down") { + content:"\e685"; + } + + @else if ($icon == "download") { + content:"\e65f"; + } + + @else if ($icon == "dss") { + content:"\e62a"; + } + + @else if ($icon == "ebook") { + content:"\e62b"; + } + + @else if ($icon == "edit") { + content:"\e62c"; + } + + @else if ($icon == "ellipsis") { + content:"\e629"; + } + + @else if ($icon == "endpoint") { + content:"\e62d"; + } + + @else if ($icon == "enterprise") { + content:"\e6b6"; + } + + @else if ($icon == "error") { + content:"\e630"; + } + + @else if ($icon == "esb-connector") { + content:"\e6e3"; + } + + @else if ($icon == "expand") { + content:"\e61c"; + } + + @else if ($icon == "export") { + content:"\e631"; + } + + @else if ($icon == "extensions") { + content:"\e6e4"; + } + + @else if ($icon == "facebook") { + content:"\e6d3"; + } + + @else if ($icon == "factory-reset") { + content:"\e632"; + } + + @else if ($icon == "fan") { + content:"\e678"; + } + + @else if ($icon == "faq") { + content:"\e62f"; + } + + @else if ($icon == "file-browse") { + content:"\e633"; + } + + @else if ($icon == "filter") { + content:"\e634"; + } + + @else if ($icon == "folder-open") { + content:"\e70b"; + } + + @else if ($icon == "folder") { + content:"\e62e"; + } + + @else if ($icon == "fork-join") { + content:"\e720"; + } + + @else if ($icon == "format") { + content:"\e6fa"; + } + + @else if ($icon == "forum") { + content:"\e636"; + } + + @else if ($icon == "function-invoke") { + content:"\e713"; + } + + @else if ($icon == "function") { + content:"\e6fb"; + } + + @else if ($icon == "gadget") { + content:"\e637"; + } + + @else if ($icon == "geo-fence-inbound") { + content:"\e72e"; + } + + @else if ($icon == "geo-fence-outbound") { + content:"\e72f"; + } + + @else if ($icon == "github") { + content:"\e6d4"; + } + + @else if ($icon == "globe") { + content:"\e697"; + } + + @else if ($icon == "google-docs") { + content:"\e6d6"; + } + + @else if ($icon == "google-drive") { + content:"\e6da"; + } + + @else if ($icon == "google-plus") { + content:"\e6d9"; + } + + @else if ($icon == "google-sheets") { + content:"\e6d7"; + } + + @else if ($icon == "google-slides") { + content:"\e6d8"; + } + + @else if ($icon == "google") { + content:"\e6d5"; + } + + @else if ($icon == "grid") { + content:"\e638"; + } + + @else if ($icon == "grip") { + content:"\e6b7"; + } + + @else if ($icon == "group") { + content:"\e6af"; + } + + @else if ($icon == "hardware") { + content:"\e6a9"; + } + + @else if ($icon == "hdd") { + content:"\e639"; + } + + @else if ($icon == "heart") { + content:"\e6c3"; + } + + @else if ($icon == "hide") { + content:"\e6d2"; + } + + @else if ($icon == "home") { + content:"\e63a"; + } + + @else if ($icon == "hour-glass") { + content:"\e63b"; + } + + @else if ($icon == "html") { + content:"\e69d"; + } + + @else if ($icon == "http") { + content:"\e705"; + } + + @else if ($icon == "image") { + content:"\e70a"; + } + + @else if ($icon == "import") { + content:"\e63c"; + } + + @else if ($icon == "incoming-call") { + content:"\e63d"; + } + + @else if ($icon == "info") { + content:"\e63e"; + } + + @else if ($icon == "instagram") { + content:"\e6db"; + } + + @else if ($icon == "invitation") { + content:"\e63f"; + } + + @else if ($icon == "invoke") { + content:"\e6ed"; + } + + @else if ($icon == "is-connector") { + content:"\e6e5"; + } + + @else if ($icon == "iterate") { + content:"\e71f"; + } + + @else if ($icon == "jaggery") { + content:"\e640"; + } + + @else if ($icon == "java-spring") { + content:"\e644"; + } + + @else if ($icon == "java") { + content:"\e641"; + } + + @else if ($icon == "javaee") { + content:"\e642"; + } + + @else if ($icon == "javascript") { + content:"\e643"; + } + + @else if ($icon == "jaxrs") { + content:"\e645"; + } + + @else if ($icon == "jaxws") { + content:"\e6c7"; + } + + @else if ($icon == "jquery") { + content:"\e646"; + } + + @else if ($icon == "key") { + content:"\e647"; + } + + @else if ($icon == "laptop") { + content:"\e648"; + } + + @else if ($icon == "layout") { + content:"\e6bf"; + } + + @else if ($icon == "ldap") { + content:"\e649"; + } + + @else if ($icon == "left-arrow") { + content:"\e68a"; + } + + @else if ($icon == "left") { + content:"\e686"; + } + + @else if ($icon == "lifecycle") { + content:"\e64a"; + } + + @else if ($icon == "light") { + content:"\e680"; + } + + @else if ($icon == "linkedin") { + content:"\e6dc"; + } + + @else if ($icon == "list-sort") { + content:"\e64d"; + } + + @else if ($icon == "list") { + content:"\e64c"; + } + + @else if ($icon == "loader") { + content:"\e6b4"; + } + + @else if ($icon == "loader2") { + content:"\e6ba"; + } + + @else if ($icon == "loader3") { + content:"\e6bb"; + } + + @else if ($icon == "loader4") { + content:"\e6bc"; + } + + @else if ($icon == "loader5") { + content:"\e6bd"; + } + + @else if ($icon == "lock") { + content:"\e64e"; + } + + @else if ($icon == "logical") { + content:"\e702"; + } + + @else if ($icon == "mail") { + content:"\e64f"; + } + + @else if ($icon == "main-function") { + content:"\e706"; + } + + @else if ($icon == "map-location") { + content:"\e650"; + } + + @else if ($icon == "menu") { + content:"\e651"; + } + + @else if ($icon == "message") { + content:"\e635"; + } + + @else if ($icon == "micro-services") { + content:"\e6ce"; + } + + @else if ($icon == "minus") { + content:"\e616"; + } + + @else if ($icon == "mobile") { + content:"\e652"; + } + + @else if ($icon == "ms-document") { + content:"\e654"; + } + + @else if ($icon == "mute") { + content:"\e655"; + } + + @else if ($icon == "nodejs") { + content:"\e656"; + } + + @else if ($icon == "notification") { + content:"\e60b"; + } + + @else if ($icon == "organization") { + content:"\e6ac"; + } + + @else if ($icon == "own") { + content:"\e6c8"; + } + + @else if ($icon == "package") { + content:"\e6fd"; + } + + @else if ($icon == "pages") { + content:"\e6c0"; + } + + @else if ($icon == "paste") { + content:"\e658"; + } + + @else if ($icon == "pdf") { + content:"\e659"; + } + + @else if ($icon == "pending") { + content:"\e727"; + } + + @else if ($icon == "php") { + content:"\e6c9"; + } + + @else if ($icon == "pie-chart") { + content:"\e65a"; + } + + @else if ($icon == "pinterest") { + content:"\e6dd"; + } + + @else if ($icon == "policy") { + content:"\e67d"; + } + + @else if ($icon == "polygon") { + content:"\e70d"; + } + + @else if ($icon == "prototype") { + content:"\e6cc"; + } + + @else if ($icon == "proxy") { + content:"\e699"; + } + + @else if ($icon == "public") { + content:"\e6ad"; + } + + @else if ($icon == "publish") { + content:"\e65c"; + } + + @else if ($icon == "question") { + content:"\e6b0"; + } + + @else if ($icon == "raspberry") { + content:"\e6aa"; + } + + @else if ($icon == "redo") { + content:"\e65d"; + } + + @else if ($icon == "refresh") { + content:"\e692"; + } + + @else if ($icon == "register") { + content:"\e65e"; + } + + @else if ($icon == "rename") { + content:"\e6fc"; + } + + @else if ($icon == "reply") { + content:"\e714"; + } + + @else if ($icon == "resource") { + content:"\e660"; + } + + @else if ($icon == "rest-api") { + content:"\e661"; + } + + @else if ($icon == "rest-service") { + content:"\e662"; + } + + @else if ($icon == "resume") { + content:"\e71e"; + } + + @else if ($icon == "retire") { + content:"\e6cd"; + } + + @else if ($icon == "return") { + content:"\e715"; + } + + @else if ($icon == "retweet") { + content:"\e6b9"; + } + + @else if ($icon == "right-arrow") { + content:"\e68b"; + } + + @else if ($icon == "right") { + content:"\e687"; + } + + @else if ($icon == "ringing") { + content:"\e694"; + } + + @else if ($icon == "rules") { + content:"\e664"; + } + + @else if ($icon == "run") { + content:"\e708"; + } + + @else if ($icon == "save") { + content:"\e665"; + } + + @else if ($icon == "scep") { + content:"\e666"; + } + + @else if ($icon == "schema") { + content:"\e667"; + } + + @else if ($icon == "search") { + content:"\e668"; + } + + @else if ($icon == "security-policy") { + content:"\e67e"; + } + + @else if ($icon == "security") { + content:"\e669"; + } + + @else if ($icon == "send") { + content:"\e66a"; + } + + @else if ($icon == "sequence") { + content:"\e66b"; + } + + @else if ($icon == "server") { + content:"\e66c"; + } + + @else if ($icon == "service-provider") { + content:"\e66e"; + } + + @else if ($icon == "service") { + content:"\e66d"; + } + + @else if ($icon == "settings") { + content:"\e66f"; + } + + @else if ($icon == "share") { + content:"\e670"; + } + + @else if ($icon == "shell") { + content:"\e730"; + } + + @else if ($icon == "shortcut") { + content:"\e725"; + } + + @else if ($icon == "sign-in") { + content:"\e671"; + } + + @else if ($icon == "sign-out") { + content:"\e6b8"; + } + + @else if ($icon == "skype") { + content:"\e6de"; + } + + @else if ($icon == "slash") { + content:"\e6e1"; + } + + @else if ($icon == "soap") { + content:"\e672"; + } + + @else if ($icon == "sort-down") { + content:"\e663"; + } + + @else if ($icon == "sort-up") { + content:"\e64b"; + } + + @else if ($icon == "sort") { + content:"\e673"; + } + + @else if ($icon == "speed-alert") { + content:"\e731"; + } + + @else if ($icon == "square-outline") { + content:"\e6b2"; + } + + @else if ($icon == "square") { + content:"\e6b1"; + } + + @else if ($icon == "star") { + content:"\e674"; + } + + @else if ($icon == "start") { + content:"\e718"; + } + + @else if ($icon == "statistics") { + content:"\e675"; + } + + @else if ($icon == "stepin") { + content:"\e719"; + } + + @else if ($icon == "stepout") { + content:"\e71a"; + } + + @else if ($icon == "stepover") { + content:"\e71b"; + } + + @else if ($icon == "stop") { + content:"\e71c"; + } + + @else if ($icon == "store") { + content:"\e676"; + } + + @else if ($icon == "struct") { + content:"\e716"; + } + + @else if ($icon == "subscribe") { + content:"\e677"; + } + + @else if ($icon == "success") { + content:"\e657"; + } + + @else if ($icon == "swagger") { + content:"\e679"; + } + + @else if ($icon == "sync") { + content:"\e6b3"; + } + + @else if ($icon == "table") { + content:"\e6c4"; + } + + @else if ($icon == "tag") { + content:"\e67a"; + } + + @else if ($icon == "task") { + content:"\e67b"; + } + + @else if ($icon == "text") { + content:"\e67c"; + } + + @else if ($icon == "theme") { + content:"\e726"; + } + + @else if ($icon == "throttling-policy") { + content:"\e67f"; + } + + @else if ($icon == "throw") { + content:"\e722"; + } + + @else if ($icon == "tiles") { + content:"\e681"; + } + + @else if ($icon == "transaction") { + content:"\e72b"; + } + + @else if ($icon == "try-catch") { + content:"\e703"; + } + + @else if ($icon == "twitter") { + content:"\e6df"; + } + + @else if ($icon == "type-converter") { + content:"\e6f3"; + } + + @else if ($icon == "uncheck") { + content:"\e682"; + } + + @else if ($icon == "undo") { + content:"\e683"; + } + + @else if ($icon == "ungroup") { + content:"\e6b5"; + } + + @else if ($icon == "unmute") { + content:"\e6ae"; + } + + @else if ($icon == "up-arrow") { + content:"\e688"; + } + + @else if ($icon == "up") { + content:"\e684"; + } + + @else if ($icon == "upload") { + content:"\e68c"; + } + + @else if ($icon == "uri") { + content:"\e68d"; + } + + @else if ($icon == "usb-drive") { + content:"\e68e"; + } + + @else if ($icon == "use") { + content:"\e6ca"; + } + + @else if ($icon == "user") { + content:"\e68f"; + } + + @else if ($icon == "variable") { + content:"\e6ee"; + } + + @else if ($icon == "view") { + content:"\e691"; + } + + @else if ($icon == "vpn") { + content:"\e603"; + } + + @else if ($icon == "wadl") { + content:"\e6a1"; + } + + @else if ($icon == "war") { + content:"\e69e"; + } + + @else if ($icon == "warning") { + content:"\e693"; + } + + @else if ($icon == "web-app") { + content:"\e696"; + } + + @else if ($icon == "web-clip") { + content:"\e698"; + } + + @else if ($icon == "web-service") { + content:"\e69a"; + } + + @else if ($icon == "website") { + content:"\e69b"; + } + + @else if ($icon == "wifi") { + content:"\e607"; + } + + @else if ($icon == "windows") { + content:"\e605"; + } + + @else if ($icon == "worker-invoke") { + content:"\e723"; + } + + @else if ($icon == "worker-reply") { + content:"\e724"; + } + + @else if ($icon == "worker") { + content:"\e6ef"; + } + + @else if ($icon == "wsdl") { + content:"\e6a0"; + } + + @else if ($icon == "wso2-logo") { + content:"\e6a7"; + } + + @else if ($icon == "wso2") { + content:"\e6a8"; + } + + @else if ($icon == "xacml") { + content:"\e69f"; + } + + @else if ($icon == "xml") { + content:"\e69c"; + } + + @else if ($icon == "xq") { + content:"\e6a2"; + } + + @else if ($icon == "xsd") { + content:"\e6a3"; + } + + @else if ($icon == "xslt") { + content:"\e6a4"; + } + + @else if ($icon == "youtube") { + content:"\e6e0"; + } + + @else if ($icon == "zoom-in") { + content:"\e6a5"; + } + + @else if ($icon == "zoom-out") { + content:"\e6a6"; + } + +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/themes/default/default-theme.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/themes/default/default-theme.css new file mode 100644 index 0000000000..32cb3c22b9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/themes/default/default-theme.css @@ -0,0 +1,903 @@ +/* + * 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. + */ + +@font-face { + font-family: "Roboto-Medium"; + src: url('../../fonts/Roboto-Medium.woff'); + src: local("Roboto-Medium"), url("../../fonts/Roboto-Medium.ttf") format("ttf"); + src: local("Roboto-Medium"), url("../../fonts/Roboto-Medium.woff") format("woff"); + src: local("Roboto-Medium"), url("../../fonts/Roboto-Medium.woff2") format("woff2"); +} + +@font-face { + font-family: "Roboto-Regular"; + src: url("../../fonts/Roboto-Regular.woff"); + src: local("Roboto-Regular"), url("../../fonts/Roboto-Regular.ttf") format("ttf"); + src: local("Roboto-Regular"), url("../../fonts/Roboto-Regular.woff") format("woff"); + src: local("Roboto-Regular"), url("../../fonts/Roboto-Regular.woff2") format("woff2"); +} + +/*Colors*/ +.primary { + color: white; + background-color: #2196f3 !important; +} + +.primary-flat { + color: #2196F3 !important; +} + +.danger { + color: white; + background-color: #e91e63 !important; +} + +.danger-flat { + color: #e91e63 !important; +} + +.grey { + color: #b3b3b3 !important; +} + +/* ==================================================================== */ +/* Custom button styles based on material design specs. */ + +.custom-raised { + font-family: Roboto-Medium; + text-transform: uppercase !important; + font-size: 14px !important; + padding-left: 16px !important; + border-radius: 2px !important; + padding-right: 16px !important; + height: 36px !important; + border: none !important; +} + +.custom-raised:hover { + cursor: pointer; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08) !important; + -webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08) !important; + background-color: #1976D2 !important; +} + +.custom-raised:focus { + box-shadow: none !important; + -webkit-box-shadow: none !important; + background-color: #1976D2 !important; +} + +.custom-flat { + font-family: Roboto-Medium; + height: 36px !important; + border-radius: 2px !important; + margin-left: 8px !important; + margin-right: 8px !important; + padding-left: 8px !important; + padding-right: 8px !important; + background-color: transparent !important; + text-transform: uppercase; + outline: none !important; + border: none !important; +} + +.custom-flat:hover { + cursor: pointer; + background-color: rgba(0, 0, 0, 0.12) !important; +} + +.custom-flat:focus { + outline: none !important; + border: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + background-color: rgba(0, 0, 0, 0.40) !important; +} + +.circle-button { + border-radius: 100% !important; + height: 36px !important; + width: 36px; +} + +/* ==================================================================== */ + +/* Body Styling */ +body { + width: 100%; + font-family: "Roboto-Regular" !important; + font-size: 14px !important; + background-color: #e8e8e8 !important; +} + +.app-manager-title { + font-family: "Roboto-Medium"; + font-size: 20px; +} + +.app-manager-sub-title { + font-family: "Roboto-Regular"; + font-size: 18px; +} + +#app-mgt-footer { + clear: both; + position: relative; + height: 50px; + width: 100%; + color: white; + background-color: #334d88; +} + +/* Login page styles*/ +#userName { + border-radius: 0; +} + +#password { + border-radius: 0; +} + +.login-btn { + float: right; +} + +.login-header { + background-color: #3f50b5; + color: white; + height: 128px; + width: 100%; + margin: 0 !important; + padding: 20px; + box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); +} + +#login-card { + width: 25%; + height: 50%; + margin: 10% auto; + font-family: Roboto-Regular; + font-size: 14px; + border-radius: 0; + background-color: #ffffff; + box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); +} + +.login-header-title { + font-family: Roboto-Medium; + font-size: 20px; + font-weight: 500; +} + +.login-header-logo { + height: 70px; + width: 150px; +} + +.login-form { + margin: 0 !important; + padding: 40px; +} + +/* Base layout container */ + +/* Base layout header content*/ +.header-content { + height: 128px !important; + width: 100% !important; + margin: 0 10px 0 0; + background-color: #3f50b5 !important; + position: fixed; /* Set the navbar to fixed position */ + top: 0; /* Position the navbar at the top of the page */ + z-index: 2; + box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); +} + +/* Contains the header styles.*/ +.header { + padding: 24px 24px 10px 24px; + /*margin: 16px 16px 20px 16px;*/ + position: relative; +} + +#header-text { + color: #ffffff; + font-size: 20px; + font-family: Roboto-Medium; + top: 10px; + margin-left: 10px; +} + +/* The buttons in the header (User and Notification)*/ +.header-button-container { + display: flex; + justify-content: flex-end; +} + +.header-user-name { + font-family: Roboto-Medium; + font-size: 14px; + padding-top: 15px; + color: white; +} + +.header-image { + height: 43px; + width: 100px; + margin-right: 24px; +} + +#header-button { + border-radius: 50%; + background-color: transparent; + border: none; + height: 50px; + width: 50px; + margin-right: 10px; + position: relative; + outline: none; +} + +#header-button:hover { + background-color: #4353bd; + cursor: pointer; +} + +#header-button i { + position: absolute; + bottom: 19px; + left: 17px; +} + +.btn-header { + margin-top: 15px; + margin-right: 20px; + color: white; +} + +#sub-title { + font-family: Roboto-Regular; + font-size: 18px; + font-weight: 600; + padding-top: 5px; + padding-left: 18px; + color: RGBA(0, 0, 0, 1); +} + +/* Search box styles */ +.search-box { + display: flex; + float: right; +} + +.search-box i { + position: absolute; + top: 5px; + color: #BaBaBa; +} + +#search { + position: relative; + color: white; + background-color: transparent; + left: 15px; + top: 0px; + height: 25px; + outline: none; + border: none; + border-radius: 0%; +} + +/* Application Add button */ +#add-btn-container { + position: absolute; + top: 98px; +} + +.add-btn { + background-color: #ff5722; +} + +.add-btn:hover { + background-color: #E64A19; +} + +#sub-title-container { + height: 100px; + padding: 50px 0 20px 0; +} + +.application-container { + padding: 0 !important; + min-height: 100% !important; + margin-top: 128px !important; +} + +/* Holds the app publisher pages. */ +.publisher-card { + height: auto; + background-color: white; + box-shadow: 2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + padding: 24px; +} + +.platform-link-placeholder { + color: #888888; + float: right; + padding-bottom: 10px; +} + +.platform-link-placeholder i { + margin-right: 4px; +} + +.application-list { + transition: margin-right .5s; +} + +#batch-content { + display: flex; + margin-top: 5px; +} + +.app-list-icon { + border-radius: 50%; + height: 50px; + width: 50px +} + +.app-table-row { + height: 62px; + cursor: pointer; + padding-top: 6px; + font-family: "Roboto-Regular"; + font-size: medium; +} + +.app-table-row:hover { + color: white; + background-color: #3f50b5; +} + +.app-list-table-header { + margin-top: 30px; + margin-bottom: 10px; + font-family: "Roboto-Medium"; + font-size: 15px; +} + +.app-view-image { + height: 100px; + width: 100px; + border-radius: 50%; +} + +#app-visibility-default { + display: none; +} + +#app-image-screenshot { + width: 300px; + height: 300px; +} + +#app-image-icon { + width: 300px; + height: 300px; +} + +#app-image-banner { + width: 400px; + height: 300px; +} + +#form-error { + color: red; +} + +.application-create-banner-dropzone { + width: 300px; + height: 150px; + border-radius: 5%; + position: relative; + border: dashed #888888 2px; +} + +.application-create-banner-dropzone i { + position: absolute; + top: 65px; + left: 145px; +} + +.application-create-screenshot-dropzone { + width: 150px; + height: 150px; + margin: 0 5px 0 5px; + border-radius: 10%; + position: relative; + border: dashed #888888 2px; +} + +.application-create-screenshot-dropzone i { + position: absolute; + top: 65px; + left: 65px; +} + +.application-create-icon-dropzone { + width: 150px; + height: 150px; + border-radius: 10%; + position: relative; + border: dashed #888888 2px; +} + +.application-create-icon-dropzone i { + position: absolute; + top: 65px; + left: 65px; +} + +#screenshot-container { + max-width: 600px; + display: flex; + overflow-x: auto; + height: 200px; +} + +#app-icon-container { + height: 300px; + overflow-x: auto; +} + +#modal-body-content { + max-height: 700px; + padding-left: 24px; + overflow-y: auto; +} + +.custom-footer { + justify-content: inherit !important; + margin: 0 !important; +} + +.footer-main-btn { + display: flex; + justify-content: flex-end; +} + +#img-btn-screenshot { + margin: 0 5px 0 5px; +} + +#app-create-modal { + max-width: 850px; + border-radius: 0% !important; +} + +.app-create-modal-header { + background-color: #4353bd; + color: white; + padding: 24px !important; +} + +.app-create-modal-content { + padding: 0 !important; +} + +#store { + border: none; + border-bottom: solid #BDBDBD 1px; + border-radius: 0px; + width: 200px; +} + +#version { + border: none; + border-bottom: solid #BDBDBD 1px; + border-radius: 0px; + width: 200px; +} + +#app-release-switch-content { + display: flex; +} + +#app-release-switch-label { + position: absolute; + float: left; +} + +#app-release-switch { + position: absolute; + right: 10px; +} + +.image-sub-title { + font-style: italic; + font-size: 12px; + color: #818181; +} + +/* Application View */ + +#application-view-content { + width: 100%; +} + +#application-view-row { + margin: 10px 10px 0 20px; +} + +#app-icon { + height: 100px; + width: 100px; + border: solid 1px black; + border-radius: 50%; +} + +.app-updated-date { + color: #888888; +} + +.app-install-count { + font-style: italic; +} + +.app-details-tbl { + outline: none; + border-color: #2196F3; +} + +.app-details-tbl tr { + margin: 20px 0 0 0; +} + +.app-details-tbl td { + margin-left: 10px; + max-width: 400px; +} + +/* Application Edit Base Layout */ + +#application-edit-header { + height: 40px; + width: 100%; + margin-top: 20px; + margin-bottom: 20px; + font-size: 25px; +} + +.application-header-text { + margin: 10px 0px 0px 10px; +} + +#save-btn-content { + float: right; + +} + +#app-save-btn { + border-radius: 0%; +} + +.save-btn { + margin: 5px 5px 5px 0px; + height: 70%; + width: 50%; + float: right; +} + +.save-btn:hover { + cursor: pointer; +} + +/*Tab styling*/ + +div.tab { + float: left; + border-right: 1px solid #d8d8d8; + height: 100%; +} + +/* Style the tab buttons */ + +div.tab button { + display: block; + background-color: inherit; + color: black; + padding: 15px 16px; + width: 100%; + border: none; + outline: none; + text-align: left; + cursor: pointer; + transition: 0.3s; +} + +/* Change background color of buttons on hover */ + +div.tab button:hover { + background-color: #ddd6d7; + cursor: pointer; +} + +/* Create an active/current "tab button" class */ + +div.tab button.active { + background-color: #1b3bcc; + color: white; +} + +#application-edit-main-container { + display: flex; +} + +#application-edit-outer-content { + height: auto; +} + +#app-edit-content { + height: 100%; + position: relative; +} + +.back-to-app { + position: absolute; + height: 50px; + width: 50px; + border-radius: 50%; +} + +.back-to-app i { + padding: 12px 10px 10px 12px; +} + +.back-to-app:hover { + cursor: pointer; + background-color: #dedede; + transition: .5s; +} + +/* Create Release and Release management */ + +.release-header { + margin-top: 20px; + margin-bottom: 20px; +} + +.release-create { + height: 150px; + margin-bottom: 20px; +} + +.release-detail-content { + width: 100%; + margin-top: 20%; + height: 300px; +} + +.form-btn { + float: right; + margin-bottom: 10px; +} + +.release-content { + height: 180px; + width: 95%; + border: dashed 1px #626262; + border-radius: 2%; + position: relative; + background-color: #e8e8e8; +} + +.release-content:after { + content: ""; + letter-spacing: 4px; +} + +.release { + margin: 30px 10px 20px 30px; +} + +.no-release-content { + position: absolute; + margin-top: 10px; + left: 40%; +} + +.button-add:hover { + cursor: pointer; +} + +.release-inner { + margin-top: 5%; +} + +/* Application Edit General Info */ + +.app-edit-general-info { + margin-top: 20px; + max-width: 100%; +} + +.save-info { + float: right; + margin-bottom: 10px; +} + +.app-view-field { + font-family: Roboto-Medium; + font-size: 14px; +} + +.app-view-text { + font-family: Roboto-Regular; + font-size: 14px; +} + +/* Platform Specific Styles. */ +#platform-listing { + margin: 10px; +} + +.create-platform i { + margin-right: 10px; +} + +#platform-list { + margin-top: 20px; + display: flex; + flex-flow: wrap; +} + +.platform-content { + margin: 10px; + padding-top: 16px; + box-shadow: 2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); +} + +.platform-content .row { + margin: 0; +} + +.platform-content .col { + padding: 0; +} + +.platform-content-basic { + padding: 0 16px 0 16px; + display: flex; +} + +.platform-content-more-outer { + +} + +.platform-content-more { + padding: 16px 16px 24px 16px; +} + +.platform-content-footer { + display: flex; + padding: 8px 8px 8px 8px; +} + +.platform-text-container { + padding: 8px 16px 0 16px; +} + +.circle-button { + float: right; +} + +.platform-icon-letter { + text-align: center; + text-transform: uppercase; + font-family: Roboto-Medium; + font-size: 70px; + color: white; + padding-top: 15px; +} + +.platform-icon-container { + height: 120px; + width: 120px; + background-color: #01579B; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08) !important; + -webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08) !important; +} + +.platform-property-container { + padding-top: 20px; + font-family: Roboto-Regular; + font-size: 14px; +} + +.platform-property-row { + align-items: center; +} + +.circle-btn-clear { + background-color: white !important; + color: rgba(0, 0, 0, 0.50) !important; +} + +.circle-btn-clear:hover { + background-color: white !important; + color: rgba(0, 0, 0, 0.38) !important; +} + +.circle-btn-clear:focus { + background-color: white !important; + color: rgba(0, 0, 0, 0.60) !important; +} + +.data-table-row-cell { + padding-top: 14px; +} + +.error-code { + text-align: center; + font-family: Roboto-Medium; + font-weight: 800; + font-size: 15em; + color: #BaBaBa; +} + +.error-code p { + +} + +.error-text { + text-align: center; + font-family: Roboto-Regular; + font-size: 14px; + font-weight: 500; + color: #9e9e9e; +} + +.circle-btn-add { + background-color: #bababa !important; + border-radius: 50% !important; + height: 30px !important; + width: 30px; + text-align: -webkit-center; + font-size: 18px; + padding: 6px !important; +} + +.circle-btn-add:hover { + background-color: #828282 !important; +} + +/** + If you need to change the color of active steps in stepper, + uncomment the following and set the background color and font color as needed. +*/ +/* +.stepper-active-index { + background-color: #0a6eff !important; + color: white !important; +} + +.stepper-passed-index { + background-color: #0a6eff !important; + color: green !important; +} +*/ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/server/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/server/index.js new file mode 100644 index 0000000000..1f8cf6c4d7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/server/index.js @@ -0,0 +1,17 @@ +const express = require('express'); +const bodyParser = require('body-parser'); +const pino = require('express-pino-logger')(); + +const app = express(); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(pino); + +app.get('/api/greeting', (req, res) => { + const name = req.query.name || 'World'; +res.setHeader('Content-Type', 'application/json'); +res.send(JSON.stringify({ greeting: `Hello ${name}!` })); +}); + +app.listen(3001, () => +console.log('Express server is running on localhost:3001') +); \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.css new file mode 100644 index 0000000000..d52de9d8dc --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.css @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +.ant-upload.ant-upload-drag { + height: 170px; +} + +.release .release-icon{ + margin-right: 15px; +} + +.release .release-icon img{ + width: 100%; + border-radius: 28%; +} + +.release .release-title{ + margin-left: 15px; +} + +.release .release-screenshot img{ + height:450px; + border-radius: 25px; + padding: 15px; +} + +.release .release-images{ + overflow-x: auto; + overflow-y: hidden; +} + +.release .release-images::-webkit-scrollbar-track{ + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + background-color: #F5F5F5; + border-radius: 10px; +} + +.release .release-images::-webkit-scrollbar{ + height: 8px; + background-color: #F5F5F5; +} + +.release .release-images::-webkit-scrollbar-thumb{ + background-color: #aaaaaa; + border-radius: 10px; +} + +.release .release-screenshot{ + display: table-cell; +} + +.main-container{ + background: #f0f2f5; + min-height: 780px +} + +@media only screen and (min-width: 768px) { + + .main-container{ + padding: 24px; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.js new file mode 100644 index 0000000000..69ecede98c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.js @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from "react"; +import "antd/dist/antd.less"; +import RouteWithSubRoutes from "./components/RouteWithSubRoutes"; +import { + BrowserRouter as Router, + Redirect, Switch, +} from 'react-router-dom'; +import axios from "axios"; +import {Layout, Spin, Result, notification} from "antd"; +import ConfigContext from "./context/ConfigContext"; + +const {Content} = Layout; +const loadingView = ( + + + + + +); + +const errorView = ( + +); + +class App extends React.Component { + + constructor(props) { + super(props); + this.state = { + loading: true, + error: false, + config: {} + } + } + + componentDidMount() { + this.updateFavicon(); + axios.get( + window.location.origin + "/publisher/public/conf/config.json", + ).then(res => { + const config = res.data; + this.checkUserLoggedIn(config); + }).catch((error) => { + this.setState({ + loading: false, + error: true + }) + }); + } + + getAndroidEnterpriseToken = (config) => { + axios.get( + window.location.origin + config.serverConfig.invoker.uri + + "/device-mgt/android/v1.0/enterprise/store-url?approveApps=true" + + "&searchEnabled=true&isPrivateAppsEnabled=true&isWebAppEnabled=true&isOrganizeAppPageVisible=true&isManagedConfigEnabled=true" + + "&host=" + window.location.origin, + ).then(res => { + config.androidEnterpriseToken = res.data.data.token; + this.setState({ + loading: false, + config: config + }); + }).catch((error) => { + config.androidEnterpriseToken = null; + this.setState({ + loading: false, + config: config + }) + }); + }; + + checkUserLoggedIn = (config) => { + axios.post( + window.location.origin + "/publisher-ui-request-handler/user", + "platform=publisher" + ).then(res => { + config.user = res.data.data; + const pageURL = window.location.pathname; + const lastURLSegment = pageURL.substr(pageURL.lastIndexOf('/') + 1); + if (lastURLSegment === "login") { + window.location.href = window.location.origin + `/publisher/`; + } else { + this.getAndroidEnterpriseToken(config); + } + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + const redirectUrl = encodeURI(window.location.href); + const pageURL = window.location.pathname; + const lastURLSegment = pageURL.substr(pageURL.lastIndexOf('/') + 1); + if (lastURLSegment !== "login") { + window.location.href = window.location.origin + `/publisher/login?redirect=${redirectUrl}`; + } else { + this.getAndroidEnterpriseToken(config); + } + } else { + this.setState({ + loading: false, + error: true + }) + } + }); + }; + + updateFavicon = () =>{ + const link = document.querySelector("link[rel*='icon']") || document.createElement('link'); + link.type = 'image/x-icon'; + link.rel = 'shortcut icon'; + link.href = window.location.origin+'/devicemgt/public/uuf.unit.favicon/img/favicon.png'; + document.getElementsByTagName('head')[0].appendChild(link); + }; + + render() { + const {loading, error} = this.state; + + const applicationView = ( + + +
+ + + {this.props.routes.map((route) => ( + + ))} + +
+
+
+ ); + + return ( +
+ {loading && loadingView} + {!loading && !error && applicationView} + {error && errorView} +
+ ); + } +} + +export default App; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.test.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.test.js new file mode 100644 index 0000000000..0b509e08c1 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.test.js @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/RouteWithSubRoutes.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/RouteWithSubRoutes.js new file mode 100644 index 0000000000..2dc80f8145 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/RouteWithSubRoutes.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from 'react'; +import {Route} from 'react-router-dom'; +class RouteWithSubRoutes extends React.Component{ + props; + constructor(props){ + super(props); + this.props = props; + } + render() { + return( + ( + + )}/> + ); + } + +} + +export default RouteWithSubRoutes; \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.css new file mode 100644 index 0000000000..34c484c34f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.css @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +.d-rating .numeric-data{ + box-sizing: border-box; + display: inline-block; + padding: 20px 0 20px 0; + vertical-align: top; + text-align: center; + width: 30%; +} + +.d-rating .bar-containers{ + box-sizing: border-box; + display: inline-block; + padding: 20px 20px 20px 30px; + vertical-align: top; + width: 70%; +} + +@media screen and (max-width: 768px) { + + .d-rating .bar-containers{ + width: 100%; + } + + .d-rating .numeric-data{ + width: 50%; + } + +} + +.d-rating .bar-containers .bar-container{ + color: #737373; + font-weight: 400; + height: 20px; + margin-bottom: 4px; + position: relative; + width: 100%; +} + +.d-rating .bar-containers .bar-container .number{ + font-size: 11px; + left: -16px; + letter-spacing: 1px; + position: absolute; +} + +.d-rating .bar-containers .bar-container .bar{ + transition: width .25s ease; + display: inline-block; + height: 100%; + opacity: .8; + border-radius: 5px; +} + +.bar-container .rate-5{ + background: #57bb8a; +} + +.bar-container .rate-4{ + background: #9ace6a; +} + +.bar-container .rate-3{ + background: #ffcf02; +} + +.bar-container .rate-2{ + background: #ff9f02; +} + +.bar-container .rate-1{ + background: #ff6f31; +} + +.d-rating .numeric-data .rate{ + color: #333; + font-size: 64px; + font-weight: 100; + line-height: 64px; + padding-bottom: 6px; +} + +.d-rating .numeric-data .people-count{ + padding-top: 6px; +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.js new file mode 100644 index 0000000000..dba024f2ed --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.js @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from "react"; +import {Row, Typography, Icon, notification} from "antd"; +import StarRatings from "react-star-ratings"; +import "./DetailedRating.css"; +import axios from "axios"; +import {withConfigContext} from "../../../context/ConfigContext"; +import {handleApiError} from "../../../js/Utils"; + +const { Text } = Typography; + + +class DetailedRating extends React.Component{ + + constructor(props){ + super(props); + this.state={ + detailedRating: null + } + } + + componentDidMount() { + const {type,uuid} = this.props; + this.getData(type,uuid); + } + + componentDidUpdate(prevProps, prevState) { + if (prevProps.uuid !== this.props.uuid) { + const {type,uuid} = this.props; + this.getData(type,uuid); + } + } + + getData = (type, uuid)=>{ + const config = this.props.context; + return axios.get( + window.location.origin+ config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/admin/reviews/"+uuid+"/"+type+"-rating", + ).then(res => { + if (res.status === 200) { + let detailedRating = res.data.data; + this.setState({ + detailedRating + }) + } + + }).catch(function (error) { + handleApiError(error, "Error occurred while trying to load rating for the release.", true); + }); + }; + + render() { + const detailedRating = this.state.detailedRating; + + + if(detailedRating ==null){ + return null; + } + + const totalCount = detailedRating.noOfUsers; + const ratingVariety = detailedRating.ratingVariety; + + const ratingArray = []; + + for (let [key, value] of Object.entries(ratingVariety)) { + ratingArray.push(value); + } + + const maximumRating = Math.max(...ratingArray); + + const ratingBarPercentages = [0,0,0,0,0]; + + if(maximumRating>0){ + for(let i = 0; i<5; i++){ + ratingBarPercentages[i] = (ratingVariety[(i+1).toString()])/maximumRating*100; + } + } + + + return ( + +
+
{detailedRating.ratingValue.toFixed(1)}
+ +
+ {totalCount} total +
+
+
+ 5 + +
+
+ 4 + +
+
+ 3 + +
+
+ 2 + +
+
+ 1 + +
+
+
+ ); + } +} + + +export default withConfigContext(DetailedRating); \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.css new file mode 100644 index 0000000000..3aadbfe3d6 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.css @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +.release-card{ + margin-top: 16px; +} + +.release-card:hover { + background-color: rgba(15, 188, 249,0.1); +} + +@media screen and (max-width: 700px) { + + .release-card{ + width: 210%; + } + + .app-release-cards{ + display: grid; + } + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js new file mode 100644 index 0000000000..7eaea07d32 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js @@ -0,0 +1,710 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from 'react'; +import { + Drawer, + Select, + Avatar, + Typography, + Divider, + Tag, + notification, + List, + Button, + Spin, + message, + Icon, + Card, Badge +} from 'antd'; +import DetailedRating from "../../detailed-rating/DetailedRating"; +import {Link} from "react-router-dom"; +import axios from "axios"; +import ReactQuill from "react-quill"; +import ReactHtmlParser from 'react-html-parser'; +import "./AppDetailsDrawer.css"; +import pSBC from "shade-blend-color"; +import {withConfigContext} from "../../../../context/ConfigContext"; +import ManagedConfigurationsIframe + from "../../../manage/android-enterprise/ManagedConfigurationsIframe/ManagedConfigurationsIframe"; +import {handleApiError} from "../../../../js/Utils"; + +const {Meta} = Card; +const {Text, Title} = Typography; +const {Option} = Select; + +const IconText = ({type, text}) => ( + + + {text} + +); + +const modules = { + toolbar: [ + ['bold', 'italic', 'underline', 'strike', 'blockquote'], + [{'list': 'ordered'}, {'list': 'bullet'}], + ['link'] + ], +}; + +const formats = [ + 'bold', 'italic', 'underline', 'strike', 'blockquote', + 'list', 'bullet', + 'link' +]; + +class AppDetailsDrawer extends React.Component { + constructor(props) { + super(props); + const drawerWidth = window.innerWidth <= 770 ? '80%' : '40%'; + + this.state = { + loading: false, + name: "", + description: null, + globalCategories: [], + globalTags: [], + categories: [], + tags: [], + temporaryDescription: null, + temporaryCategories: [], + temporaryTags: [], + isDescriptionEditEnabled: false, + isCategoriesEditEnabled: false, + isTagsEditEnabled: false, + drawer: null, + drawerWidth + }; + } + + componentDidMount() { + this.getCategories(); + } + + componentDidUpdate(prevProps, prevState, snapshot) { + if (prevProps.app !== this.props.app) { + const {name, description, tags, categories} = this.props.app; + this.setState({ + name, + description, + tags, + categories, + isDescriptionEditEnabled: false, + isCategoriesEditEnabled: false, + isTagsEditEnabled: false, + }); + } + } + + getCategories = () => { + const config = this.props.context; + axios.get( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories" + ).then(res => { + if (res.status === 200) { + const categories = JSON.parse(res.data.data); + this.getTags(); + const globalCategories = categories.map(category => { + return ( + + ) + }); + + this.setState({ + globalCategories, + loading: false + }); + } + + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load categories.", true); + this.setState({ + loading: false + }); + }); + }; + + getTags = () => { + const config = this.props.context; + axios.get( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags" + ).then(res => { + if (res.status === 200) { + const tags = JSON.parse(res.data.data); + + const globalTags = tags.map(tag => { + return ( + + ) + }); + + this.setState({ + globalTags, + loading: false + }); + } + + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load tags."); + this.setState({ + loading: false + }); + }); + }; + + + // change the app name + handleNameSave = name => { + const config = this.props.context; + const {id} = this.props.app; + if (name !== this.state.name && name !== "") { + const data = {name: name}; + axios.put( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/" + id, + data + ).then(res => { + this.props.onUpdateApp("name", name); + if (res.status === 200) { + notification["success"]({ + message: 'Saved!', + description: 'App name updated successfully!' + }); + this.setState({ + loading: false, + name: name, + }); + + } + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + message.error('You are not logged in'); + window.location.href = window.location.origin + '/publisher/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description: + "Error occurred while trying to save the app name.", + }); + } + + this.setState({loading: false}); + }); + } + }; + + // handle description change + handleDescriptionChange = (temporaryDescription) => { + this.setState({temporaryDescription}) + }; + + enableDescriptionEdit = () => { + this.setState({ + isDescriptionEditEnabled: true, + temporaryDescription: this.state.description + }); + }; + + disableDescriptionEdit = () => { + this.setState({ + isDescriptionEditEnabled: false, + }); + }; + + enableCategoriesEdit = () => { + this.setState({ + isCategoriesEditEnabled: true, + temporaryCategories: this.state.categories + }); + }; + + disableCategoriesEdit = () => { + this.setState({ + isCategoriesEditEnabled: false, + }); + }; + + // handle description change + handleCategoryChange = (temporaryCategories) => { + this.setState({temporaryCategories}) + }; + + // change app categories + handleCategorySave = () => { + const config = this.props.context; + const {id} = this.props.app; + const {temporaryCategories, categories} = this.state; + + const difference = temporaryCategories + .filter(x => !categories.includes(x)) + .concat(categories.filter(x => !temporaryCategories.includes(x))); + + if (difference.length !== 0 && temporaryCategories.length !== 0) { + const data = {categories: temporaryCategories}; + axios.put( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/" + id, + data + ).then(res => { + if (res.status === 200) { + this.props.onUpdateApp("categories", temporaryCategories); + notification["success"]({ + message: 'Saved!', + description: 'App categories updated successfully!' + }); + this.setState({ + loading: false, + categories: temporaryCategories, + isCategoriesEditEnabled: false + }); + + } + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + message.error('You are not logged in'); + window.location.href = window.location.origin + '/publisher/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description: + "Error occurred while trying to updating categories.", + }); + } + + this.setState({loading: false}); + }); + } + }; + + enableTagsEdit = () => { + this.setState({ + isTagsEditEnabled: true, + temporaryTags: this.state.tags + }); + }; + + disableTagsEdit = () => { + this.setState({ + isTagsEditEnabled: false, + }); + }; + + // handle description change + handleTagsChange = (temporaryTags) => { + this.setState({temporaryTags}) + }; + + // change app tags + handleTagsSave = () => { + const config = this.props.context; + const {id} = this.props.app; + const {temporaryTags, tags} = this.state; + + + const difference = temporaryTags + .filter(x => !tags.includes(x)) + .concat(tags.filter(x => !temporaryTags.includes(x))); + + if (difference.length !== 0 && temporaryTags.length !== 0) { + const data = {tags: temporaryTags}; + axios.put( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/" + id, + data + ).then(res => { + if (res.status === 200) { + notification["success"]({ + message: 'Saved!', + description: 'App tags updated successfully!' + }); + this.setState({ + loading: false, + tags: temporaryTags, + isTagsEditEnabled: false + }); + } + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + message.error('You are not logged in'); + window.location.href = window.location.origin + '/publisher/login'; + } else { + notification["error"]({ + message: "There was a problem", + duration: 0, + description: + "Error occurred while trying to update tags", + }); + } + + this.setState({loading: false}); + }); + } + }; + + //handle description save + handleDescriptionSave = () => { + const config = this.props.context; + const {id} = this.props.app; + const {description, temporaryDescription} = this.state; + + if (temporaryDescription !== description && temporaryDescription !== "


") { + const data = {description: temporaryDescription}; + axios.put( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/" + id, + data + ).then(res => { + if (res.status === 200) { + notification["success"]({ + message: 'Saved!', + description: 'App description updated successfully!' + }); + this.setState({ + loading: false, + description: temporaryDescription, + isDescriptionEditEnabled: false + }); + } + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + message.error('You are not logged in'); + window.location.href = window.location.origin + '/publisher/login'; + } else { + message.error('Something went wrong... :('); + } + + this.setState({loading: false}); + }); + } else { + this.setState({isDescriptionEditEnabled: false}); + } + }; + + + render() { + const config = this.props.context; + const {app, visible, onClose} = this.props; + const { + name, loading, description, isDescriptionEditEnabled, isCategoriesEditEnabled, + isTagsEditEnabled, temporaryDescription, temporaryCategories, temporaryTags, + globalCategories, globalTags, categories, tags + } = this.state; + if (app == null) { + return null; + } + + let avatar = null; + + if (app.applicationReleases.length === 0) { + const avatarLetter = name.charAt(0).toUpperCase(); + avatar = ( + + {avatarLetter} + + ); + } else { + avatar = ( + + ) + } + + return ( +
+ + +
+ {avatar} + {name} +
+ + + + {/*display manage config button only if the app is public android app*/} + {(app.type === "PUBLIC") && (app.deviceType === "android") && + (config.androidEnterpriseToken !== null) && + ( +
+
+ Set up managed configurations +
+
+ + If you are developing apps for the enterprise market, you may need to satisfy + particular requirements set by a organization's policies. Managed + configurations, + previously known as application restrictions, allow the organization's IT admin + to + remotely specify settings for apps. This capability is particularly useful for + organization-approved apps deployed to a work profile. + +
+
+ + +
+ )} + + Releases +
+ ( +
+ + + + + {(release.currentStatus === "PUBLISHED") ? ( + + }> + + + ) : ( + + )} +
+ } + title={release.version} + description={ +
+ + + + + +
+ } + /> + + + +
+ )} + /> +
+ + {/*display add new release only if app type is enterprise*/} + {(app.type === "ENTERPRISE") && ( +
+ +
+ + Add new release for the application + +
+ + + +
)} + + + Description + {!isDescriptionEditEnabled && ( + + + + )} + + {!isDescriptionEditEnabled && ( +
{ReactHtmlParser(description)}
+ )} + + {isDescriptionEditEnabled && ( +
+ + + +
+ )} + + + Categories + {!isCategoriesEditEnabled && ( + + + )} +
+
+ {isCategoriesEditEnabled && ( +
+ +
+ + +
+
+ )} + {!isCategoriesEditEnabled && ( + { + categories.map(category => { + return ( + + {category} + + ); + }) + } + )} + + + + Tags + {!isTagsEditEnabled && ( + + + )} +
+
+ {isTagsEditEnabled && ( +
+ +
+ + +
+
+ )} + {!isTagsEditEnabled && ( + { + tags.map(tag => { + return ( + + {tag} + + ); + }) + } + )} + + + +
+ {app.applicationReleases.length > 0 && ( + )} +
+ + + + ); + } +} + +export default withConfigContext(AppDetailsDrawer); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js new file mode 100644 index 0000000000..14c76e24a7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from "react"; +import { + Card, + Col, + Row, + Typography, + Input, + Divider, + Icon, + Select, + Button, + Form, + message, + Radio, + notification, Alert +} from "antd"; +import axios from "axios"; +import {withConfigContext} from "../../../context/ConfigContext"; +import {handleApiError} from "../../../js/Utils"; + +const {Option} = Select; +const {Title} = Typography; + + +class FiltersForm extends React.Component { + constructor(props) { + super(props); + this.state = { + categories: [], + tags: [], + deviceTypes: [], + forbiddenErrors: { + categories: false, + tags: false, + deviceTypes: false + } + }; + } + + handleSubmit = e => { + e.preventDefault(); + this.props.form.validateFields((err, values) => { + for (const [key, value] of Object.entries(values)) { + if (value === undefined) { + delete values[key]; + } + } + + if (values.hasOwnProperty("deviceType") && values.deviceType === "ALL") { + delete values["deviceType"]; + } + + if (values.hasOwnProperty("appType") && values.appType === "ALL") { + delete values["appType"]; + } + + this.props.setFilters(values); + }); + }; + + componentDidMount() { + this.getCategories(); + this.getTags(); + this.getDeviceTypes(); + } + + getCategories = () => { + const config = this.props.context; + axios.get( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories" + ).then(res => { + if (res.status === 200) { + let categories = JSON.parse(res.data.data); + this.setState({ + categories: categories, + loading: false + }); + } + + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load categories.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.categories = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } + }); + }; + + getTags = () => { + const config = this.props.context; + axios.get( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags" + ).then(res => { + if (res.status === 200) { + let tags = JSON.parse(res.data.data); + this.setState({ + tags: tags, + loading: false, + }); + } + + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load tags.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.tags = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } + }); + }; + + + getDeviceTypes = () => { + const config = this.props.context; + axios.get( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt + "/device-types" + ).then(res => { + if (res.status === 200) { + const deviceTypes = JSON.parse(res.data.data); + this.setState({ + deviceTypes, + loading: false, + }); + } + + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load device types.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.deviceTypes = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } + }); + }; + + render() { + const {categories, tags, deviceTypes, forbiddenErrors} = this.state; + const {getFieldDecorator} = this.props.form; + + return ( + + +
+ + + Filter + + + + + + + + {(forbiddenErrors.categories) && ( + + )} + + {getFieldDecorator('categories', { + rules: [{ + required: false, + message: 'Please select categories' + }], + })( + + )} + + + {(forbiddenErrors.deviceTypes) && ( + + )} + + {getFieldDecorator('deviceType', { + rules: [{ + required: false, + message: 'Please select device types' + }], + })( + + )} + + {(forbiddenErrors.tags) && ( + + )} + + {getFieldDecorator('tags', { + rules: [{ + required: false, + message: 'Please select tags' + }], + })( + + )} + + + + {getFieldDecorator('appType', {})( + + )} + + + +
+ ); + } +} + + +const Filters = withConfigContext(Form.create({name: 'filter-apps'})(FiltersForm)); + + +export default withConfigContext(Filters); \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/ListApps.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/ListApps.js new file mode 100644 index 0000000000..401b35b79d --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/ListApps.js @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from "react"; +import {Card, Col, Row, Typography, Input, Divider, notification} from "antd"; +import AppsTable from "./appsTable/AppsTable"; +import Filters from "./Filters"; +import AppDetailsDrawer from "./AppDetailsDrawer/AppDetailsDrawer"; +import axios from "axios"; + +const {Title} = Typography; +const Search = Input.Search; + +class ListApps extends React.Component { + constructor(props) { + super(props); + this.state = { + filters: {} + } + } + + setFilters = (filters) => { + this.setState({ + filters + }); + }; + + setSearchText = (appName) => { + const filters = {...this.state.filters}; + if (appName === '' && filters.hasOwnProperty("appName")) { + delete filters["appName"]; + } else { + filters.appName = appName; + } + this.setState({ + filters + }); + }; + + render() { + const {isDrawerVisible, filters} = this.state; + return ( + + + + + + + + + Apps + + + + + + + + + + + ); + } +} + +export default ListApps; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.css new file mode 100644 index 0000000000..030832abea --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.css @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +.app-row{ + cursor: pointer; +} + +.apps-table{ + display: block; + overflow: auto; + width: 100%; +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js new file mode 100644 index 0000000000..01d6c8c159 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from "react"; +import {Avatar, Table, Tag, Icon, message, notification, Col, Badge, Alert} from "antd"; +import axios from "axios"; +import pSBC from 'shade-blend-color'; +import "./AppsTable.css"; +import {withConfigContext} from "../../../../context/ConfigContext"; +import AppDetailsDrawer from "../AppDetailsDrawer/AppDetailsDrawer"; +import {handleApiError} from "../../../../js/Utils"; + +let config = null; + +const columns = [ + { + title: '', + dataIndex: 'name', + render: (name, row) => { + let avatar = null; + if (row.applicationReleases.length === 0) { + const avatarLetter = name.charAt(0).toUpperCase(); + avatar = ( + + {avatarLetter} + + ); + } else { + const {applicationReleases} = row; + let hasPublishedRelease = false; + for (let i = 0; i < applicationReleases.length; i++) { + if (applicationReleases[i].currentStatus === "PUBLISHED") { + hasPublishedRelease = true; + break; + } + } + avatar = (hasPublishedRelease) ? ( + + }> + + + ) : ( + + ); + } + + return ( +
+ {avatar} + {name} +
); + } + }, + { + title: 'Categories', + dataIndex: 'categories', + render: categories => ( + + {categories.map(category => { + return ( + + {category} + + ); + })} + + ) + }, + { + title: 'Platform', + dataIndex: 'deviceType', + render: platform => { + const defaultPlatformIcons = config.defaultPlatformIcons; + let icon = defaultPlatformIcons.default.icon; + let color = defaultPlatformIcons.default.color; + let theme = defaultPlatformIcons.default.theme; + if (defaultPlatformIcons.hasOwnProperty(platform)) { + icon = defaultPlatformIcons[platform].icon; + color = defaultPlatformIcons[platform].color; + theme = defaultPlatformIcons[platform].theme; + } + return ( + + + + ); + } + }, + { + title: 'Type', + dataIndex: 'type' + }, + { + title: 'Subscription', + dataIndex: 'subMethod' + }, +]; + +class AppsTable extends React.Component { + constructor(props) { + super(props); + this.state = { + pagination: {}, + apps: [], + filters: {}, + isDrawerVisible: false, + selectedApp: null, + selectedAppIndex: -1, + loading: false, + isForbiddenErrorVisible: false + }; + config = this.props.context; + } + + componentDidMount() { + const {filters} = this.props; + this.setState({ + filters + }); + this.fetch(filters); + + } + + componentDidUpdate(prevProps, prevState, snapshot) { + const {filters} = this.props; + if (prevProps.filters !== this.props.filters) { + this.setState({ + filters + }); + this.fetch(filters); + } + } + + //handler to show app drawer + showDrawer = (app, appIndex) => { + this.setState({ + isDrawerVisible: true, + selectedApp: app, + selectedAppIndex: appIndex + }); + }; + + // handler to close the app drawer + closeDrawer = () => { + this.setState({ + isDrawerVisible: false + }) + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = {...this.state.pagination}; + pager.current = pagination.current; + + this.setState({ + pagination: pager, + }); + this.fetch(this.state.filters, { + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + fetch = (filters, params = {}) => { + this.setState({loading: true}); + const config = this.props.context; + + if (!params.hasOwnProperty("page")) { + params.page = 1; + } + + const data = { + offset: 10 * (params.page - 1), + limit: 10, + ...filters + }; + + axios.post( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications", + data, + ).then(res => { + if (res.status === 200) { + const data = res.data.data; + let apps = []; + + if (res.data.data.hasOwnProperty("applications")) { + apps = data.applications; + } + const pagination = {...this.state.pagination}; + // Read total count from server + // pagination.total = data.totalCount; + pagination.total = data.pagination.count; + this.setState({ + loading: false, + apps: apps, + pagination, + }); + } + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load apps.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + this.setState({ + isForbiddenErrorVisible: true + }) + } + this.setState({loading: false}); + }); + }; + + onUpdateApp = (key, value) => { + const apps = [...this.state.apps]; + apps[this.state.selectedAppIndex][key] = value; + this.setState({ + apps + }); + }; + + render() { + const {isDrawerVisible, loading} = this.state; + return ( +
+ {(this.state.isForbiddenErrorVisible) && ( + + )} +
+ record.id} + dataSource={this.state.apps} + columns={columns} + pagination={this.state.pagination} + onChange={this.handleTableChange} + rowClassName="app-row" + loading={loading} + onRow={(record, rowIndex) => { + return { + onClick: event => { + this.showDrawer(record, rowIndex); + }, + }; + }}/> + + + + ); + } +} + +export default withConfigContext(AppsTable); \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/ReleaseView.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/ReleaseView.js new file mode 100644 index 0000000000..6ea67eee20 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/ReleaseView.js @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from "react"; +import {Divider, Row, Col, Typography, Button, Drawer, Icon, Tooltip, Empty} from "antd"; +import StarRatings from "react-star-ratings"; +import Reviews from "./review/Reviews"; +import "../../../App.css"; +import DetailedRating from "../detailed-rating/DetailedRating"; +import EditRelease from "./edit-release/EditRelease"; +import {withConfigContext} from "../../../context/ConfigContext"; +import NewAppUploadForm from "../../new-app/subForms/NewAppUploadForm"; + +const {Title, Text, Paragraph} = Typography; + +class ReleaseView extends React.Component { + constructor(props) { + super(props); + this.state = { + + } + } + + componentDidMount() { + console.log("mounted: Release view"); + } + + render() { + const {app, release} = this.props; + const config = this.props.context; + const {lifecycle, currentLifecycleStatus} = this.props; + + if (release == null || lifecycle == null) { + return null; + } + + const {isAppUpdatable, isAppInstallable} = lifecycle[currentLifecycleStatus]; + + const platform = app.deviceType; + const defaultPlatformIcons = config.defaultPlatformIcons; + let icon = defaultPlatformIcons.default.icon; + let color = defaultPlatformIcons.default.color; + let theme = defaultPlatformIcons.default.theme; + + if (defaultPlatformIcons.hasOwnProperty(platform)) { + icon = defaultPlatformIcons[platform].icon; + color = defaultPlatformIcons[platform].color; + theme = defaultPlatformIcons[platform].theme; + } + let metaData = []; + try{ + metaData = JSON.parse(release.metaData); + }catch (e) { + + } + + return ( +
+
+ +
+ icon + + + {app.name} + +
+ Platform : + + + + + Version : {release.version}
+ + + + +
+
+ + + +
+ + + + + {release.screenshots.map((screenshotUrl, index) => { + return ( +
+ +
+ ) + })} +
+ + + {release.description} + + + META DATA + + { + metaData.map((data, index)=>{ + return ( +
+ {data.key}
+ {data.value} + + ) + }) + } + {(metaData.length===0) && (No meta data available.)} + + + REVIEWS + + + + + + + + + ); + } +} + +export default withConfigContext(ReleaseView); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/edit-release/EditRelease.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/edit-release/EditRelease.js new file mode 100644 index 0000000000..f4c6e84670 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/edit-release/EditRelease.js @@ -0,0 +1,678 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. 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. + */ + +import React from "react"; +import { + Modal, + Button, + Icon, + notification, + Spin, + Tooltip, + Upload, + Input, + Switch, + Form, + Divider, + Row, + Col, + Select, Alert +} from 'antd'; +import axios from "axios"; +import "@babel/polyfill"; +import {withConfigContext} from "../../../../context/ConfigContext"; + +const {TextArea} = Input; +const InputGroup = Input.Group; +const {Option} = Select; + +const formItemLayout = { + labelCol: { + span: 8, + }, + wrapperCol: { + span: 16, + }, +}; + +function getBase64(file) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => resolve(reader.result); + reader.onerror = error => reject(error); + }); +} + +class EditReleaseModal extends React.Component { + // To add subscription type & tenancy sharing, refer https://gitlab.com/entgra/carbon-device-mgt/merge_requests/331 + constructor(props) { + super(props); + this.state = { + visible: false, + current: 0, + categories: [], + tags: [], + icons: [], + screenshots: [], + loading: false, + binaryFiles: [], + metaData: [], + formConfig: { + specificElements: {} + } + }; + this.lowerOsVersion = null; + this.upperOsVersion = null; + } + + componentDidMount = () => { + this.generateConfig(); + }; + + generateConfig = () => { + const {type} = this.props; + const formConfig = { + type + }; + + switch (type) { + case "ENTERPRISE": + formConfig.endpoint = "/ent-app-release"; + formConfig.specificElements = { + binaryFile: { + required: true + } + }; + break; + case "PUBLIC": + formConfig.endpoint = "/public-app-release"; + formConfig.specificElements = { + packageName: { + required: true + }, + version: { + required: true + } + }; + break; + case "WEB_CLIP": + formConfig.endpoint = "/web-app-release"; + formConfig.specificElements = { + version: { + required: true + }, + url: { + required: true + } + }; + break; + case "CUSTOM": + formConfig.endpoint = "/custom-app-release"; + formConfig.specificElements = { + binaryFile: { + required: true + }, + packageName: { + required: true + }, + version: { + required: true + } + }; + break; + } + + this.setState({ + formConfig + }); + }; + + + showModal = () => { + const config = this.props.context; + const {app, release} = this.props; + const {formConfig} = this.state; + const {specificElements} = formConfig; + let metaData = []; + + try { + metaData = JSON.parse(release.metaData); + } catch (e) { + + } + + this.props.form.setFields({ + releaseType: { + value: release.releaseType + }, + releaseDescription: { + value: release.description + } + }); + + if ((config.deviceTypes.mobileTypes.includes(this.props.deviceType))) { + const osVersions = release.supportedOsVersions.split("-"); + this.lowerOsVersion = osVersions[0]; + this.upperOsVersion = osVersions[1]; + this.props.form.setFields({ + lowerOsVersion: { + value: osVersions[0] + }, + upperOsVersion: { + value: osVersions[1] + } + }); + } + if (specificElements.hasOwnProperty("version")) { + this.props.form.setFields({ + version: { + value: release.version + } + }); + } + + if (specificElements.hasOwnProperty("url")) { + this.props.form.setFields({ + url: { + value: release.url + } + }); + } + + if (specificElements.hasOwnProperty("packageName")) { + this.props.form.setFields({ + packageName: { + value: release.packageName + } + }); + } + + this.setState({ + visible: true, + metaData + }); + }; + + handleOk = e => { + this.setState({ + visible: false, + }); + }; + + handleCancel = e => { + this.setState({ + visible: false, + }); + }; + + normFile = e => { + if (Array.isArray(e)) { + return e; + } + return e && e.fileList; + }; + + handleIconChange = ({fileList}) => this.setState({icons: fileList}); + handleBinaryFileChange = ({fileList}) => this.setState({binaryFiles: fileList}); + + handleScreenshotChange = ({fileList}) => this.setState({screenshots: fileList}); + + + handleSubmit = e => { + e.preventDefault(); + const {uuid} = this.props.release; + const config = this.props.context; + + const {formConfig} = this.state; + const {specificElements} = formConfig; + + this.props.form.validateFields((err, values) => { + if (!err) { + this.setState({ + loading: true + }); + const {releaseDescription, releaseType} = values; + + const {icons, screenshots, binaryFiles} = this.state; + + const data = new FormData(); + + //add release data + const release = { + description: releaseDescription, + price: 0, + isSharedWithAllTenants: false, + metaData: JSON.stringify(this.state.metaData), + releaseType: releaseType, + }; + + if ((config.deviceTypes.mobileTypes.includes(this.props.deviceType))) { + release.supportedOsVersions = `${this.lowerOsVersion}-${this.upperOsVersion}`; + } + + if (specificElements.hasOwnProperty("binaryFile") && binaryFiles.length === 1) { + data.append('binaryFile', binaryFiles[0].originFileObj); + } + + if (specificElements.hasOwnProperty("version")) { + release.version = values.version; + } + + if (specificElements.hasOwnProperty("url")) { + release.url = values.url; + } + + if (icons.length === 1) { + data.append('icon', icons[0].originFileObj); + } + + if (screenshots.length > 0) { + data.append('screenshot1', screenshots[0].originFileObj); + } + + if (screenshots.length > 1) { + data.append('screenshot2', screenshots[1].originFileObj); + } + + if (screenshots.length > 2) { + data.append('screenshot3', screenshots[2].originFileObj); + } + + const json = JSON.stringify(release); + const blob = new Blob([json], { + type: 'application/json' + }); + + data.append("applicationRelease", blob); + + const url = window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications" + formConfig.endpoint + "/" + uuid; + + axios.put( + url, + data + ).then(res => { + if (res.status === 200) { + + const updatedRelease = res.data.data; + + this.setState({ + loading: false, + visible: false, + }); + + notification["success"]({ + message: "Done!", + description: + "Saved!", + }); + // console.log(updatedRelease); + this.props.updateRelease(updatedRelease); + } + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + window.location.href = window.location.origin + '/publisher/login'; + } else { + notification["error"]({ + message: "Something went wrong!", + description: + "Sorry, we were unable to complete your request.", + }); + + } + this.setState({ + loading: false + }); + }); + } + }); + }; + + addNewMetaData = () => { + this.setState({ + metaData: this.state.metaData.concat({'key': '', 'value': ''}) + }) + }; + + handlePreviewCancel = () => this.setState({previewVisible: false}); + + handlePreview = async file => { + if (!file.url && !file.preview) { + file.preview = await getBase64(file.originFileObj); + } + + this.setState({ + previewImage: file.url || file.preview, + previewVisible: true, + }); + }; + + handleLowerOsVersionChange = (lowerOsVersion) => { + this.lowerOsVersion = lowerOsVersion; + }; + + handleUpperOsVersionChange = (upperOsVersion) => { + this.upperOsVersion = upperOsVersion; + }; + + render() { + const { + formConfig, + icons, + screenshots, + loading, + binaryFiles, + metaData, + previewImage, + previewVisible, + binaryFileHelperText, + iconHelperText, + screenshotHelperText + } = this.state; + const {getFieldDecorator} = this.props.form; + const {isAppUpdatable, supportedOsVersions, deviceType} = this.props; + const config = this.props.context; + const uploadButton = ( +
+ +
Select
+
+ ); + + return ( +
+ + + + +
+ +
+ {formConfig.specificElements.hasOwnProperty("binaryFile") && ( + + {getFieldDecorator('binaryFile', { + valuePropName: 'binaryFile', + getValueFromEvent: this.normFile, + required: true, + message: 'Please select application' + })( + false} + > + {binaryFiles.length !== 1 && ( + + )} + , + )} + + )} + + {formConfig.specificElements.hasOwnProperty("url") && ( + + {getFieldDecorator('url', { + rules: [{ + required: true, + message: 'Please input the url' + }], + })( + + )} + + )} + + {formConfig.specificElements.hasOwnProperty("version") && ( + + {getFieldDecorator('version', { + rules: [{ + required: true, + message: 'Please input the version' + }], + })( + + )} + + )} + + + {getFieldDecorator('icon', { + valuePropName: 'icon', + getValueFromEvent: this.normFile, + required: true, + message: 'Please select a icon' + })( + false} + onPreview={this.handlePreview}> + {icons.length === 1 ? null : uploadButton} + , + )} + + + + {getFieldDecorator('screenshots', { + valuePropName: 'icon', + getValueFromEvent: this.normFile, + required: true, + message: 'Please select a icon' + })( + false} + onPreview={this.handlePreview}> + {screenshots.length >= 3 ? null : uploadButton} + , + )} + + + + {getFieldDecorator('releaseType', { + rules: [{ + required: true, + message: 'Please input the Release Type' + }], + })( + + )} + + + + {getFieldDecorator('releaseDescription', { + rules: [{ + required: true, + message: 'Please enter a description for release' + }], + })( +