diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Application.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Application.java index ed0864599d..87daa4eb5b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Application.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/Application.java @@ -76,6 +76,10 @@ public class Application { value = "If unrestricted roles are defined then isRestricted value is true otherwise it is false") private boolean isRestricted; + @ApiModelProperty(name = "deviceTypeId", + value = "Id of the Related device type of the application", + example = "1, 2, 3") + private int deviceTypeId; @ApiModelProperty(name = "deviceType", value = "Related device type of the application", required = true, @@ -180,4 +184,12 @@ public class Application { public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public int getDeviceTypeId() { + return deviceTypeId; + } + + public void setDeviceTypeId(int deviceTypeId) { + this.deviceTypeId = deviceTypeId; + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java index cc5a50681c..33a05562ae 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java @@ -25,7 +25,11 @@ 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.UnrestrictedRole; 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.exception.ResourceManagementException; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import java.io.InputStream; import java.util.List; /** @@ -64,9 +68,11 @@ public interface ApplicationManager { * * @param applicationId ID of tha application * @param releaseUuid UUID of tha application release + * @param handleConnections Whether it is necessary handle DB connections. * @throws ApplicationManagementException Application Management Exception */ - String deleteApplicationRelease(int applicationId, String releaseUuid) throws ApplicationManagementException; + String deleteApplicationRelease(int applicationId, String releaseUuid, boolean handleConnections) throws + ApplicationManagementException; /** * To get the applications based on the search filter. @@ -90,11 +96,14 @@ public interface ApplicationManager { * To get Application with the given Id. * * @param id id of the Application - * @param requirePublishedReleases If it is required to have only published application release set to True, otherwise set to false - * @return the Application identified by the UUID + * @param state state of the Application + * @param handleConnections Whether it is required to handle DB connections within(true), or if there are + * existing connection(false) + * @return the Application identified by the ID * @throws ApplicationManagementException Application Management Exception. */ - Application getApplicationById(int id, boolean requirePublishedReleases) throws ApplicationManagementException; + Application getApplicationById(int id, String state, boolean handleConnections) throws + ApplicationManagementException; /** * To get an application associated with the release. @@ -122,6 +131,16 @@ public interface ApplicationManager { */ Boolean isUserAllowable(List unrestrictedRoles, String userName) throws ApplicationManagementException; + /** + * To get the release of a particular Application. + * + * @param applicationId ID of the Application. + * @param state state of the Application. + * @return the List of the Application releases related with the particular Application. + * @throws ApplicationManagementException Application Management Exception. + */ + List getReleaseInState(int applicationId, String state) throws ApplicationManagementException; + /** * To get all the releases of a particular Application. * @@ -139,9 +158,11 @@ public interface ApplicationManager { * @param releaseUuid UUID of the Application Release. * @param state Lifecycle state to change the app * @param checkExist whether it is needed to check if the app and release already exist in the database + * @param handleDBConnections Whether it is necessary to open connections * @throws ApplicationManagementException Application Management Exception. */ - void changeLifecycleState(int applicationId, String releaseUuid, LifecycleState state, Boolean checkExist) + void changeLifecycleState(int applicationId, String releaseUuid, LifecycleState state, Boolean checkExist, + Boolean handleDBConnections) throws ApplicationManagementException; /** @@ -153,24 +174,33 @@ public interface ApplicationManager { Application getApplicationIfAccessible(int applicationId) throws ApplicationManagementException; /** - * Get the application release for given UUID if application release is exists and application id is valid one. + * To update release images such as icons, banner and screenshots. * - * @param releaseUuid UUID of the Application Release. + * @param appId ID of the Application + * @param uuid uuid of the Application + * @param iconFileStream icon file of the release + * @param bannerFileStream bannerFileStream of the release. + * @param attachments screenshot attachments of the release + * @return Updated Application Release. * @throws ApplicationManagementException Application Management Exception. */ - ApplicationRelease getAppReleaseIfExists(int applicationId, String releaseUuid) throws - ApplicationManagementException; + ApplicationRelease updateApplicationImageArtifact(int appId, String uuid, InputStream iconFileStream, InputStream + bannerFileStream, List attachments) + throws ApplicationManagementException, ResourceManagementException; + /** - * To update with a new release for an Application. + * To update release images. * * @param appId ID of the Application - * @param applicationRelease ApplicationRelease + * @param uuid uuid of the Application + * @param binaryFile binaryFile of the release. * @return Updated Application Release. * @throws ApplicationManagementException Application Management Exception. */ - ApplicationRelease updateRelease(int appId, ApplicationRelease applicationRelease) - throws ApplicationManagementException; + ApplicationRelease updateApplicationArtifact(int appId, String uuid, InputStream binaryFile) + throws ApplicationManagementException, ResourceManagementException, RequestValidatingException, DeviceManagementException; + /** * To verify whether application release is acceptable to update or not. diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java index d08af3c8c4..706f81fa6d 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java @@ -66,6 +66,18 @@ public interface ApplicationReleaseDAO { List getReleases(int applicationId, int tenantId) throws ApplicationManagementDAOException; + /** + * To get the release by state. + * + * @param appId Id of the Application + * @param tenantId tenant id of the application + * @param state state of the application + * @return list of the application releases + * @throws ApplicationManagementDAOException Application Management DAO Exception. + */ + List getReleaseByState(int appId, int tenantId, String state) + throws ApplicationManagementDAOException; + /** * To update an Application release. * 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/Util.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/Util.java index 3ee7b01b2b..1722a42070 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/Util.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/common/Util.java @@ -21,13 +21,18 @@ package org.wso2.carbon.device.application.mgt.core.dao.common; 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.*; import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.PaginationRequest; import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; +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.config.Configuration; import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -131,6 +136,7 @@ public class Util { application.setSubType(rs.getString("SUB_TYPE")); application.setPaymentCurrency(rs.getString("CURRENCY")); application.setIsRestricted(rs.getBoolean("RESTRICTED")); + application.setDeviceTypeId(rs.getInt("DEVICE_TYPE_ID")); } Tag tag = new Tag(); @@ -201,4 +207,99 @@ public class Util { } } } + + public static PaginationRequest validateCommentListPageSize(PaginationRequest paginationRequest) throws + ReviewManagementException { + if (paginationRequest.getLimit() == 0) { + Configuration commentManagementConfig = ConfigurationManager.getInstance().getConfiguration(); + if (commentManagementConfig != null) { + paginationRequest.setLimit( + commentManagementConfig.getPaginationConfiguration().getCommentListPageSize()); + } else { + throw new ReviewManagementException( + "Application Management configuration has not initialized. Please check the application-mgt.xml file."); + } + } + return paginationRequest; + } + + private static ApplicationManager applicationManager; + private static ApplicationStorageManager applicationStorageManager; + private static SubscriptionManager subscriptionManager; + + public static ApplicationManager getApplicationManager() { + if (applicationManager == null) { + synchronized (Util.class) { + if (applicationManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + applicationManager = + (ApplicationManager) ctx.getOSGiService(ApplicationManager.class, null); + if (applicationManager == null) { + String msg = "Application Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return applicationManager; + } + + /** + * To get the Application Storage Manager from the osgi context. + * @return ApplicationStoreManager instance in the current osgi context. + */ + public static ApplicationStorageManager getApplicationStorageManager() { + if (applicationStorageManager == null) { + synchronized (Util.class) { + if (applicationStorageManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + applicationStorageManager = (ApplicationStorageManager) ctx + .getOSGiService(ApplicationStorageManager.class, null); + if (applicationStorageManager == null) { + String msg = "Application Storage Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return applicationStorageManager; + } + + + /** + * To get the Subscription Manager from the osgi context. + * @return SubscriptionManager instance in the current osgi context. + */ + public static SubscriptionManager getSubscriptionManager() { + if (subscriptionManager == null) { + synchronized (Util.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; + } } 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 index f2d417ee44..1f365f86ff 100644 --- 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 @@ -401,11 +401,12 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic try { conn = this.getDBConnection(); String sql = - "SELECT AP_APP.ID AS APP_ID, AP_APP.NAME AS APP_NAME, AP_APP.TYPE AS APP_TYPE, AP_APP.APP_CATEGORY " - + "AS APP_CATEGORY, AP_APP.SUB_TYPE AS SUB_TYPE ,AP_APP.CURRENCY AS CURRENCY, " - + "AP_APP.RESTRICTED AS RESTRICTED, AP_APP_TAG.TAG AS APP_TAG, AP_UNRESTRICTED_ROLE.ROLE " - + "AS ROLE FROM AP_APP, AP_APP_TAG, AP_UNRESTRICTED_ROLE WHERE AP_APP.ID=? AND " - + "AP_APP.TENANT_ID=?;"; + "SELECT AP_APP.ID AS APP_ID, AP_APP.NAME AS APP_NAME, AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.APP_CATEGORY AS APP_CATEGORY, AP_APP.SUB_TYPE AS SUB_TYPE ," + + "AP_APP.CURRENCY AS CURRENCY, AP_APP.RESTRICTED AS RESTRICTED, " + + "DM_DEVICE_TYPE_ID AS DEVICE_TYPE_ID " + + "FROM AP_APP " + + "WHERE AP_APP.ID=? AND AP_APP.TENANT_ID=?;"; stmt = conn.prepareStatement(sql); stmt.setInt(1, applicationId); 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 index 68d934d9a8..50a2e8e4a0 100644 --- 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 @@ -57,9 +57,10 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements PreparedStatement statement = null; ResultSet resultSet = null; - String sql = "INSERT INTO AP_APP_RELEASE (VERSION,TENANT_ID,UUID,RELEASE_TYPE, PACKAGE_NAME, APP_PRICE," - + "STORED_LOCATION, BANNER_LOCATION, SC_1_LOCATION,SC_2_LOCATION,SC_3_LOCATION, APP_HASH_VALUE," - + "SHARED_WITH_ALL_TENANTS, APP_META_INFO,AP_APP_ID) " + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"; + String sql = "INSERT INTO AP_APP_RELEASE (VERSION,TENANT_ID,UUID,RELEASE_TYPE, PACKAGE_NAME, APP_PRICE, " + + "STORED_LOCATION, ICON_LOCATION, BANNER_LOCATION, SC_1_LOCATION,SC_2_LOCATION,SC_3_LOCATION," + + "APP_HASH_VALUE, SHARED_WITH_ALL_TENANTS, APP_META_INFO,AP_APP_ID) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"; int index = 0; String generatedColumns[] = { "ID" }; @@ -73,6 +74,7 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements statement.setString(++index, String.valueOf(applicationRelease.getPackageName())); statement.setDouble(++index, applicationRelease.getPrice()); statement.setString(++index, applicationRelease.getAppStoredLoc()); + statement.setString(++index, applicationRelease.getIconLoc()); statement.setString(++index, applicationRelease.getBannerLoc()); statement.setString(++index, applicationRelease.getScreenshotLoc1()); statement.setString(++index, applicationRelease.getScreenshotLoc2()); @@ -116,7 +118,8 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements ResultSet resultSet = null; String sql = "SELECT AR.ID AS RELEASE_ID, AR.VERSION AS RELEASE_VERSION, AR.UUID AS UUID, AR.RELEASE_TYPE AS " + "RELEASE_TYPE, AR.PACKAGE_NAME AS PACKAGE_NAME, AR.APP_PRICE AS APP_PRICE, AR.STORED_LOCATION AS " - + "STORED_LOCATION, AR.BANNER_LOCATION AS BANNER_LOCATION, AR.SC_1_LOCATION AS SCREEN_SHOT_1, " + + "STORED_LOCATION, AR.BANNER_LOCATION AS BANNER_LOCATION, ICON_LOCATION, AR.SC_1_LOCATION AS " + + "SCREEN_SHOT_1, " + "AR.SC_2_LOCATION AS SCREEN_SHOT_2, AR.SC_3_LOCATION AS SCREEN_SHOT_3, AR.APP_HASH_VALUE AS " + "HASH_VALUE, AR.SHARED_WITH_ALL_TENANTS AS SHARED, AR.APP_META_INFO AS APP_META_INFO , " + "AR.RATING AS RATING, AL.CURRENT_STATE, AL.PREVIOUS_STATE, AL.UPDATED_BY, AL.UPDATED_AT FROM " @@ -165,7 +168,7 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements ResultSet resultSet = null; String sql = "SELECT AR.ID AS RELEASE_ID, AR.VERSION AS RELEASE_VERSION, AR.UUID, AR.RELEASE_TYPE, AR.APP_PRICE, " - + "AR.STORED_LOCATION, AR.BANNER_LOCATION, AR.SC_1_LOCATION AS SCREEN_SHOT_1, " + + "AR.STORED_LOCATION, AR.BANNER_LOCATION, AR.SC_1_LOCATION AS SCREEN_SHOT_1, ICON_LOCATION," + "AR.SC_2_LOCATION AS SCREEN_SHOT_2, AR.SC_3_LOCATION AS SCREEN_SHOT_3, AR.PACKAGE_NAME AS " + "PACKAGE_NAME, AR.APP_HASH_VALUE AS HASH_VALUE, AR.SHARED_WITH_ALL_TENANTS AS SHARED, " + "AR.APP_META_INFO AS APP_META_INFO, AR.RATING AS RATING, AL.CURRENT_STATE, AL.PREVIOUS_STATE, " @@ -212,7 +215,7 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements ResultSet resultSet = null; List applicationReleases = new ArrayList<>(); String sql = "SELECT AR.ID AS RELEASE_ID, AR.VERSION AS RELEASE_VERSION, AR.UUID, AR.RELEASE_TYPE " - + "AS RELEASE_TYPE, AR.PACKAGE_NAME AS PACKAGE_NAME, AR.APP_PRICE, AR.STORED_LOCATION, " + + "AS RELEASE_TYPE, AR.PACKAGE_NAME AS PACKAGE_NAME, AR.APP_PRICE, AR.STORED_LOCATION, ICON_LOCATION" + "AR.BANNER_LOCATION, AR.SC_1_LOCATION AS SCREEN_SHOT_1, AR.SC_2_LOCATION AS SCREEN_SHOT_2, " + "AR.SC_3_LOCATION AS SCREEN_SHOT_3, AR.APP_HASH_VALUE AS HASH_VALUE, " + "AR.SHARED_WITH_ALL_TENANTS AS SHARED, AR.APP_META_INFO AS APP_META_INFO, " @@ -243,6 +246,46 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements } } + @Override + public List getReleaseByState(int appId, int tenantId, String state) throws + ApplicationManagementDAOException { + Connection connection; + PreparedStatement statement = null; + ResultSet resultSet = null; + List applicationReleases = new ArrayList<>(); + String sql = "SELECT AR.ID AS RELEASE_ID, AR.VERSION AS RELEASE_VERSION, AR.UUID, AR.RELEASE_TYPE, AR.APP_PRICE," + + " AR.STORED_LOCATION, AR.ICON_LOCATION, AR.BANNER_LOCATION, AR.SC_1_LOCATION AS SCREEN_SHOT_1, AR" + + ".SC_2_LOCATION AS SCREEN_SHOT_2, AR.SC_3_LOCATION AS SCREEN_SHOT_3, AR.APP_HASH_VALUE AS HASH_VALUE, " + + "AR.SHARED_WITH_ALL_TENANTS AS SHARED, AR.APP_META_INFO, AR.RATING FROM AP_APP_RELEASE AS " + + "AR where AR.TENANT_ID = ? AND AR.AP_APP_ID=(SELECT AP_APP_ID" + + " FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_ID = ? AND CURRENT_STATE = ? AND TENANT_ID = ?);"; + + try { + connection = this.getDBConnection(); + statement = connection.prepareStatement(sql); + statement.setInt(1, tenantId); + statement.setInt(2, appId); + statement.setString(3, state); + statement.setInt(4, tenantId); + resultSet = statement.executeQuery(); + + while (resultSet.next()) { + ApplicationRelease appRelease = constructApplicationRelease(resultSet); + applicationReleases.add(appRelease); + } + return applicationReleases; + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException("Database connection exception while trying to get the " + + "release details of the application with id " + appId, e); + } catch (SQLException e) { + throw new ApplicationManagementDAOException( + "Error while getting all the release details of the app id" + appId + " application" + + ", while executing the query " + sql, e); + } finally { + Util.cleanupResources(statement, resultSet); + } + } + /** * To Update starts of an application release. * @@ -320,7 +363,8 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements Connection connection; PreparedStatement statement = null; String sql = "UPDATE AP_APP_RELEASE SET VERSION = ?, UUID = ?, RELEASE_TYPE = ?, PACKAGE_NAME = ?," - + " APP_PRICE = ?, STORED_LOCATION = ?, BANNER_LOCATION = ?, SC_1_LOCATION = ?, SC_2_LOCATION = ?," + + " APP_PRICE = ?, STORED_LOCATION = ?, BANNER_LOCATION = ?, ICON_LOCATION =?, SC_1_LOCATION = ?, " + + "SC_2_LOCATION = ?," + " SC_3_LOCATION = ?, APP_HASH_VALUE = ?, SHARED_WITH_ALL_TENANTS = ?, APP_META_INFO = ? " + "WHERE AP_APP_ID = ? AND TENANT_ID = ? AND ID = ?;"; try { @@ -333,16 +377,16 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements statement.setDouble(5, applicationRelease.getPrice()); statement.setString(6, applicationRelease.getAppStoredLoc()); statement.setString(7, applicationRelease.getBannerLoc()); - statement.setString(8, applicationRelease.getScreenshotLoc1()); - statement.setString(9, applicationRelease.getScreenshotLoc2()); - statement.setString(10, applicationRelease.getScreenshotLoc3()); - statement.setString(11, applicationRelease.getAppHashValue()); - statement.setInt(12, applicationRelease.getIsSharedWithAllTenants()); - statement.setString(13, applicationRelease.getMetaData()); - statement.setInt(14, applicationId); - statement.setInt(15, tenantId); - statement.setInt(16, applicationRelease.getId()); - + statement.setString(8, applicationRelease.getIconLoc()); + statement.setString(9, applicationRelease.getScreenshotLoc1()); + statement.setString(10, applicationRelease.getScreenshotLoc2()); + statement.setString(11, applicationRelease.getScreenshotLoc3()); + statement.setString(12, applicationRelease.getAppHashValue()); + statement.setInt(13, applicationRelease.getIsSharedWithAllTenants()); + statement.setString(14, applicationRelease.getMetaData()); + statement.setInt(15, applicationId); + statement.setInt(16, tenantId); + statement.setInt(17, applicationRelease.getId()); statement.executeUpdate(); } catch (DBConnectionException e) { throw new ApplicationManagementDAOException( @@ -438,6 +482,7 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements applicationRelease.setPrice(resultSet.getDouble("APP_PRICE")); applicationRelease.setAppStoredLoc(resultSet.getString("STORED_LOCATION")); applicationRelease.setBannerLoc(resultSet.getString("BANNER_LOCATION")); + applicationRelease.setIconLoc(resultSet.getString("ICON_LOCATION")); applicationRelease.setScreenshotLoc1(resultSet.getString("SCREEN_SHOT_1")); applicationRelease.setScreenshotLoc2(resultSet.getString("SCREEN_SHOT_2")); applicationRelease.setScreenshotLoc3(resultSet.getString("SCREEN_SHOT_3")); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/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 new file mode 100644 index 0000000000..3bdd8a8d9c --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/BadRequestException.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.exception; + +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; + +/** + * Custom exception class for wrapping BadRequest related exceptions. + */ + +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..9618d8bf50 --- /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) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.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/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..0409520cd1 --- /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,34 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.device.application.mgt.core.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/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index 1013f98fa6..8733402785 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -35,14 +35,18 @@ import org.wso2.carbon.device.application.mgt.common.Tag; import org.wso2.carbon.device.application.mgt.common.UnrestrictedRole; import org.wso2.carbon.device.application.mgt.common.User; 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.RequestValidatingException; +import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagementException; import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; +import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; 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.VisibilityDAO; import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.dao.common.Util; import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; +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.ValidationException; @@ -50,12 +54,14 @@ import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManger; import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; import org.wso2.carbon.device.mgt.common.DeviceManagementException; + import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.user.api.UserRealm; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -160,7 +166,7 @@ public class ApplicationManagerImpl implements ApplicationManager { LifecycleState lifecycleState = new LifecycleState(); lifecycleState.setCurrentState(AppLifecycleState.CREATED.toString()); lifecycleState.setPreviousState(AppLifecycleState.CREATED.toString()); - changeLifecycleState(appId, applicationRelease.getUuid(), lifecycleState, false); + changeLifecycleState(appId, applicationRelease.getUuid(), lifecycleState, false, false); applicationRelease.setLifecycleState(lifecycleState); applicationReleases.add(applicationRelease); @@ -238,18 +244,16 @@ public class ApplicationManagerImpl implements ApplicationManager { log.debug("Application release request is received for the application " + application.toString()); } try { - ConnectionManagerUtil.beginDBTransaction(); + ConnectionManagerUtil.getDBConnection(); applicationRelease = this.applicationReleaseDAO .createRelease(applicationRelease, application.getId(), tenantId); LifecycleState lifecycleState = new LifecycleState(); lifecycleState.setCurrentState(AppLifecycleState.CREATED.toString()); lifecycleState.setPreviousState(AppLifecycleState.CREATED.toString()); - changeLifecycleState(application.getId(), applicationRelease.getUuid(), lifecycleState, true); - - ConnectionManagerUtil.commitDBTransaction(); + changeLifecycleState(application.getId(), applicationRelease.getUuid(), lifecycleState, true, + false); return applicationRelease; } catch (ApplicationManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); throw new ApplicationManagementException( "Error occurred while adding application release into IoTS app management Application id of the " + "application release: " + applicationId, e); @@ -270,17 +274,20 @@ public class ApplicationManagerImpl implements ApplicationManager { } @Override - public Application getApplicationById(int id, boolean requirePublishedReleases) throws ApplicationManagementException { + public Application getApplicationById(int appId, String state, boolean handleConnections) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); Application application; boolean isAppAllowed = false; - List applicationReleases; + List applicationReleases = null; try { - ConnectionManagerUtil.openDBConnection(); - application = this.applicationDAO.getApplicationById(id, tenantId); + if (handleConnections) { + ConnectionManagerUtil.openDBConnection(); + } + application = ApplicationManagementDAOFactory.getApplicationDAO() + .getApplicationById(appId, tenantId); if (isAdminUser(userName, tenantId, CarbonConstants.UI_ADMIN_PERMISSION_COLLECTION)) { - applicationReleases = getReleases(application, requirePublishedReleases); + applicationReleases = getReleaseInState(appId, state); application.setApplicationReleases(applicationReleases); return application; } @@ -296,15 +303,18 @@ public class ApplicationManagerImpl implements ApplicationManager { if (!isAppAllowed) { return null; } - - applicationReleases = getReleases(application, requirePublishedReleases); + if (state != null) { + applicationReleases = getReleaseInState(appId, state); + } application.setApplicationReleases(applicationReleases); return application; } catch (UserStoreException e) { throw new ApplicationManagementException( - "User-store exception while getting application with the application id " + id); + "User-store exception while getting application with the application id " + appId); } finally { - ConnectionManagerUtil.closeDBConnection(); + if (handleConnections) { + ConnectionManagerUtil.closeDBConnection(); + } } } @@ -463,6 +473,20 @@ public class ApplicationManagerImpl implements ApplicationManager { + @Override + public List getReleaseInState(int applicationId, String state) throws + ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + + Application application = getApplicationIfAccessible(applicationId); + if (log.isDebugEnabled()) { + log.debug("Request is received to retrieve all the releases related with the application " + application + .toString()); + } + ConnectionManagerUtil.getDBConnection(); + return this.applicationReleaseDAO.getReleaseByState(applicationId, tenantId, state); + } + @Override public List deleteApplication(int applicationId) throws ApplicationManagementException { String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); @@ -476,7 +500,7 @@ public class ApplicationManagerImpl implements ApplicationManager { "You don't have permission to delete this application. In order to delete an application you " + "need to have admin permission"); } - + ConnectionManagerUtil.openDBConnection(); application = getApplicationIfAccessible(applicationId); if ( application == null) { throw new ApplicationManagementException("Invalid Application"); @@ -486,16 +510,17 @@ public class ApplicationManagerImpl implements ApplicationManager { log.debug("Request is received to delete applications which are related with the application id " + applicationId); } + ConnectionManagerUtil.beginDBTransaction(); for (ApplicationRelease applicationRelease : applicationReleases) { LifecycleState appLifecycleState = getLifecycleState(applicationId, applicationRelease.getUuid()); LifecycleState newAppLifecycleState = new LifecycleState(); newAppLifecycleState.setPreviousState(appLifecycleState.getCurrentState()); newAppLifecycleState.setCurrentState(AppLifecycleState.REMOVED.toString()); - changeLifecycleState(applicationId, applicationRelease.getUuid(), newAppLifecycleState, true); + changeLifecycleState(applicationId, applicationRelease.getUuid(), newAppLifecycleState, true, false); storedLocations.add(applicationRelease.getAppHashValue()); } - ConnectionManagerUtil.openDBConnection(); this.applicationDAO.deleteApplication(applicationId); + ConnectionManagerUtil.commitDBTransaction(); } catch (UserStoreException e) { String msg = "Error occured while check whether current user has the permission to delete an application"; log.error(msg); @@ -507,28 +532,37 @@ public class ApplicationManagerImpl implements ApplicationManager { } @Override - public String deleteApplicationRelease(int applicationId, String releaseUuid) + public String deleteApplicationRelease(int applicationId, String releaseUuid, boolean handleConnections) throws ApplicationManagementException { Application application = getApplicationIfAccessible(applicationId); if (application == null) { throw new ApplicationManagementException("Invalid Application ID is received"); } - ApplicationRelease applicationRelease = getAppReleaseIfExists(applicationId, releaseUuid); - LifecycleState appLifecycleState = getLifecycleState(applicationId, applicationRelease.getUuid()); - String currentState = appLifecycleState.getCurrentState(); - if (AppLifecycleState.DEPRECATED.toString().equals(currentState) || AppLifecycleState - .REJECTED.toString().equals(currentState) || AppLifecycleState.UNPUBLISHED.toString().equals - (currentState) ) { - LifecycleState newAppLifecycleState = new LifecycleState(); - newAppLifecycleState.setPreviousState(appLifecycleState.getCurrentState()); - newAppLifecycleState.setCurrentState(AppLifecycleState.REMOVED.toString()); - changeLifecycleState(applicationId, applicationRelease.getUuid(), newAppLifecycleState, true); - }else{ - throw new ApplicationManagementException("Can't delete the application release, You have to move the " + - "lifecycle state from "+ currentState + " to acceptable " + - "state") ; + if (handleConnections) { + ConnectionManagerUtil.openDBConnection(); + } + try { + ApplicationRelease applicationRelease = getAppReleaseIfExists(applicationId, releaseUuid); + LifecycleState appLifecycleState = getLifecycleState(applicationId, applicationRelease.getUuid()); + String currentState = appLifecycleState.getCurrentState(); + if (AppLifecycleState.DEPRECATED.toString().equals(currentState) || AppLifecycleState + .REJECTED.toString().equals(currentState) || AppLifecycleState.UNPUBLISHED.toString().equals + (currentState)) { + LifecycleState newAppLifecycleState = new LifecycleState(); + newAppLifecycleState.setPreviousState(appLifecycleState.getCurrentState()); + newAppLifecycleState.setCurrentState(AppLifecycleState.REMOVED.toString()); + changeLifecycleState(applicationId, applicationRelease.getUuid(), newAppLifecycleState, true, false); + } else { + throw new ApplicationManagementException("Can't delete the application release, You have to move the " + + "lifecycle state from " + currentState + " to acceptable " + + "state"); + } + return applicationRelease.getAppHashValue(); + } finally { + if (handleConnections) { + ConnectionManagerUtil.closeDBConnection(); + } } - return applicationRelease.getAppHashValue(); } /** @@ -659,7 +693,7 @@ public class ApplicationManagerImpl implements ApplicationManager { * @param applicationUuid UUID of the Application. * @return Application related with the UUID */ - public ApplicationRelease getAppReleaseIfExists(int applicationId, String applicationUuid) throws + private ApplicationRelease getAppReleaseIfExists(int applicationId, String applicationUuid) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); ApplicationRelease applicationRelease; @@ -673,19 +707,16 @@ public class ApplicationManagerImpl implements ApplicationManager { throw new ApplicationManagementException("Application UUID is null. Application UUID is a required " + "parameter to get the relevant application."); } - ConnectionManagerUtil.getDBConnection(); applicationRelease = this.applicationReleaseDAO.getReleaseByIds(applicationId, applicationUuid, tenantId); if (applicationRelease == null) { - throw new ApplicationManagementException("Doesn't exist a application release for application ID: " + - applicationId + "and application UUID: " + - applicationUuid); + log.error("Doesn't exist a application release for application ID: " + applicationId + + "and application UUID: " + applicationUuid); } return applicationRelease; } - @Override - public ApplicationRelease updateRelease(int appId, ApplicationRelease applicationRelease) throws + private ApplicationRelease updateRelease(int appId, ApplicationRelease applicationRelease) throws ApplicationManagementException { validateAppReleasePayload(applicationRelease); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); @@ -693,9 +724,63 @@ public class ApplicationManagerImpl implements ApplicationManager { log.debug("Updating the Application release. UUID: " + applicationRelease.getUuid() + ", " + "Application Id: " + appId); } + + applicationRelease = this.applicationReleaseDAO.updateRelease(appId, applicationRelease, tenantId); + return applicationRelease; + + } + + @Override + public ApplicationRelease updateApplicationImageArtifact(int appId, String uuid, InputStream iconFileStream, InputStream + bannerFileStream, List attachments) + throws ApplicationManagementException, ResourceManagementException { + ApplicationStorageManager applicationStorageManager = Util.getApplicationStorageManager(); + ApplicationRelease applicationRelease; try { - ConnectionManagerUtil.openDBConnection(); - applicationRelease = this.applicationReleaseDAO.updateRelease(appId, applicationRelease, tenantId); + ConnectionManagerUtil.getDBConnection(); + applicationRelease = getAppReleaseIfExists(appId, uuid); + if (applicationRelease == null) { + throw new NotFoundException("No App release associated with the app Id " + appId + "and UUID "+ uuid); + } + LifecycleState lifecycleState = getLifecycleState(appId, applicationRelease.getUuid()); + if (AppLifecycleState.PUBLISHED.toString().equals(lifecycleState.getCurrentState()) || + AppLifecycleState.DEPRECATED.toString().equals(lifecycleState.getCurrentState())) { + throw new ForbiddenException("Can't Update the application release in " + + "PUBLISHED or DEPRECATED state. Hence please demote the application and update " + + "the application release"); + } + ApplicationRelease updatedRelease = applicationStorageManager + .updateImageArtifacts(applicationRelease, iconFileStream, bannerFileStream, attachments); + return updateRelease(appId, updatedRelease); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public ApplicationRelease updateApplicationArtifact(int appId, String uuid, InputStream binaryFile) + throws ApplicationManagementException, ResourceManagementException, RequestValidatingException, DeviceManagementException { + ApplicationStorageManager applicationStorageManager = Util.getApplicationStorageManager(); + ApplicationRelease applicationRelease; + try { + ConnectionManagerUtil.getDBConnection(); + applicationRelease = getAppReleaseIfExists(appId, uuid); + + Application application = getApplicationById(appId, null, false); + + List deviceTypes = Util.getDeviceManagementService().getDeviceTypes(); + for (DeviceType deviceType:deviceTypes) { + if (deviceType.getId() == application.getDeviceTypeId()) { + application.setDeviceType(deviceType.getName()); + } + } + if (applicationRelease == null) { + throw new NotFoundException("No App release associated with the app Id " + appId + "and UUID "+ uuid); + } + applicationStorageManager + .updateReleaseArtifacts(applicationRelease, application.getType(), application.getDeviceType(), + binaryFile); + updateRelease(appId, applicationRelease); return applicationRelease; } finally { ConnectionManagerUtil.closeDBConnection(); @@ -769,21 +854,24 @@ public class ApplicationManagerImpl implements ApplicationManager { } lifecycleState.setNextStates(new ArrayList<>(getLifecycleManagementService(). getNextLifecycleStates(lifecycleState.getCurrentState()))); + + } catch (ApplicationManagementException e) { + throw new ApplicationManagementException("Failed to get application and application management", e); } catch (LifeCycleManagementDAOException e) { throw new ApplicationManagementException("Failed to get lifecycle state from database", e); - } finally { - ConnectionManagerUtil.closeDBConnection(); } return lifecycleState; } @Override - public void changeLifecycleState(int applicationId, String releaseUuid, LifecycleState state, Boolean checkExist) - throws ApplicationManagementException { + public void changeLifecycleState(int applicationId, String releaseUuid, LifecycleState state, Boolean checkExist, + Boolean handleDBConnections) throws ApplicationManagementException { try { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); if (checkExist) { - ConnectionManagerUtil.openDBConnection(); + if (handleDBConnections) { + ConnectionManagerUtil.openDBConnection(); + } if (!this.applicationDAO.verifyApplicationExistenceById(applicationId, tenantId)){ throw new NotFoundException( "Couldn't found application for the application Id: " + applicationId); @@ -801,11 +889,9 @@ public class ApplicationManagerImpl implements ApplicationManager { if (state.getCurrentState() != null && state.getPreviousState() != null) { if (getLifecycleManagementService() .isValidStateChange(state.getPreviousState(), state.getCurrentState())) { - ConnectionManagerUtil.beginDBTransaction(); //todo if current state of the adding lifecycle state is PUBLISHED, need to check whether is there //todo any other application release in PUBLISHED state for the application( i.e for the appid) this.lifecycleStateDAO.addLifecycleState(state, applicationId, releaseUuid, tenantId); - ConnectionManagerUtil.commitDBTransaction(); } else { log.error("Invalid lifecycle state transition from '" + state.getPreviousState() + "'" + " to '" + state.getCurrentState() + "'"); @@ -814,12 +900,13 @@ public class ApplicationManagerImpl implements ApplicationManager { } } } catch (LifeCycleManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); throw new ApplicationManagementException( "Failed to add lifecycle state. Application Id: " + applicationId + " Application release UUID: " + releaseUuid, e); } finally { - ConnectionManagerUtil.closeDBConnection(); + if (handleDBConnections) { + 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 index ccce9dddfe..37e17821ce 100644 --- 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 @@ -133,8 +133,8 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager } @Override - public ApplicationRelease updateImageArtifacts(ApplicationRelease applicationRelease, InputStream iconFileStream, - InputStream bannerFileStream, List screenShotStreams) + public ApplicationRelease updateImageArtifacts(ApplicationRelease applicationRelease, InputStream + iconFileStream, InputStream bannerFileStream, List screenShotStreams) throws ResourceManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); @@ -164,9 +164,8 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager count++; } } - return uploadImageArtifacts(applicationRelease, iconFileStream, bannerFileStream, screenShotStreams); + return applicationRelease; } catch (ApplicationStorageManagementException e) { - ConnectionManagerUtil.rollbackDBTransaction(); throw new ApplicationStorageManagementException("Application Storage exception while trying to" + " update the screen-shot count for the application Release " + applicationRelease.getUuid() + " for the tenant " + tenantId, e); @@ -235,7 +234,7 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager + applicationRelease.getUuid(), e); } catch (ParsingException e) { throw new ApplicationStorageManagementException( - "Error occured while parsing the artifact file. Application release UUID is " + applicationRelease + "Error occurred while parsing the artifact file. Application release UUID is " + applicationRelease .getUuid(), e); } @@ -295,8 +294,7 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager @Override public void deleteApplicationReleaseArtifacts(String directoryPath) throws ApplicationStorageManagementException { - String artifactPath = storagePath + directoryPath; - File artifact = new File(artifactPath); + File artifact = new File(directoryPath); if (artifact.exists()) { try { 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/ApplicationManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationManagementAPI.java index 57b35871e1..4f5aa6ad7c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationManagementAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/ApplicationManagementAPI.java @@ -170,8 +170,8 @@ public interface ApplicationManagementAPI { consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, httpMethod = "GET", - value = "get the application of requesting application type", - notes = "This will get the application identified by the application type and name, if exists", + 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 = "Application Management", extensions = { @Extension(properties = { @@ -194,15 +194,16 @@ public interface ApplicationManagementAPI { response = ErrorResponse.class) }) Response getApplication( - @ApiParam( - name = "published-release", - value = "If set to True, only get published release for the application") - @QueryParam("published-release") boolean requirePublishedReleases, @ApiParam( name = "appId", value = "application Id", required = true) - @PathParam("appId") int appId + @PathParam("appId") int appId, + @ApiParam( + name = "state", + value = "state", + defaultValue = "PUBLISHED") + @QueryParam("state") String state ); @PUT @@ -348,10 +349,10 @@ public interface ApplicationManagementAPI { @PathParam("appid") int applicationId ); - @POST + @PUT @Path("/image-artifacts/{appId}/{uuid}") @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.MULTIPART_FORM_DATA) + @Consumes("multipart/mixed") @ApiOperation( consumes = MediaType.MULTIPART_FORM_DATA, produces = MediaType.APPLICATION_JSON, @@ -383,19 +384,47 @@ public interface ApplicationManagementAPI { response = ErrorResponse.class) }) Response updateApplicationImageArtifacts( - @ApiParam(name = "appId", value = "ID of the application", required = true) + @ApiParam( + name = "appId", + value = "ID of the application", + required = true) @PathParam("appId") int applicatioId, - @ApiParam(name = "uuid", value = "UUID of the application", required = true) + @ApiParam( + name = "uuid", + value = "UUID of the application", + required = true) @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "icon", + value = "Icon of the uploading application", + required = true) @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading application", + required = true) @Multipart(value = "banner") Attachment bannerFile, - @Multipart(value = "screenshot") List screenshots + @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 @Path("/app-artifacts/{deviceType}/{appType}/{appId}/{uuid}") @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.MULTIPART_FORM_DATA) + @Consumes("multipart/mixed") @ApiOperation( consumes = MediaType.MULTIPART_FORM_DATA, produces = MediaType.APPLICATION_JSON, diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java index f3b93e84c3..1751b2a11a 100644 --- 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/ApplicationManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java @@ -32,6 +32,7 @@ import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagemen 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.core.exception.NotFoundException; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; import java.io.IOException; import java.io.InputStream; @@ -49,6 +50,7 @@ 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; /** @@ -108,11 +110,11 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { @Consumes("application/json") @Path("/{appId}") public Response getApplication( - @QueryParam("published-release") boolean requirePublishedReleases, - @PathParam("appId") int appId) { + @PathParam("appId") int appId, + @QueryParam("state") String state) { ApplicationManager applicationManager = APIUtil.getApplicationManager(); try { - Application application = applicationManager.getApplicationById(appId, requirePublishedReleases); + Application application = applicationManager.getApplicationById(appId, state, true); if (application == null) { return Response.status(Response.Status.NOT_FOUND).entity ("Application with application id: " + appId + " not found").build(); @@ -217,22 +219,22 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { @Override @PUT + @Consumes("multipart/mixed") + @Produces(MediaType.APPLICATION_JSON) @Path("/image-artifacts/{appId}/{uuid}") public Response updateApplicationImageArtifacts( @PathParam("appId") int appId, @PathParam("uuid") String applicationUuid, @Multipart("icon") Attachment iconFile, @Multipart("banner") Attachment bannerFile, - @Multipart("screenshot") List attachmentList) { - - ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); - ApplicationManager applicationManager = APIUtil.getApplicationManager(); - ApplicationRelease applicationRelease; + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { try { InputStream iconFileStream = null; InputStream bannerFileStream = null; - List attachments = new ArrayList<>(); + List attachments = new ArrayList<>();; if (iconFile != null) { iconFileStream = iconFile.getDataHandler().getInputStream(); @@ -240,29 +242,22 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { if (bannerFile != null) { bannerFileStream = bannerFile.getDataHandler().getInputStream(); } - if (attachmentList != null && !attachmentList.isEmpty()) { - for (Attachment screenshot : attachmentList) { - attachments.add(screenshot.getDataHandler().getInputStream()); - } + + attachments.add(screenshot1.getDataHandler().getInputStream()); + if(screenshot2 != null) { + attachments.add(screenshot2.getDataHandler().getInputStream()); } - applicationRelease = applicationManager.getAppReleaseIfExists(appId, applicationUuid); - LifecycleState lifecycleState = applicationManager.getLifecycleState(appId, applicationRelease.getUuid()); - if (AppLifecycleState.PUBLISHED.toString().equals(lifecycleState.getCurrentState()) || - AppLifecycleState.DEPRECATED.toString().equals(lifecycleState.getCurrentState())) { - return Response.status(Response.Status.FORBIDDEN).entity("Can't Update the application release in " + - "PUBLISHED or DEPRECATED state. Hence please demote the application and update the application " + - "release").build(); + if(screenshot3 != null) { + attachments.add(screenshot3.getDataHandler().getInputStream()); } - applicationRelease = applicationStorageManager - .updateImageArtifacts(applicationRelease, iconFileStream, bannerFileStream, attachments); - applicationManager.updateRelease(appId, applicationRelease); - return Response.status(Response.Status.OK) - .entity("Successfully uploaded artifacts for the application " + applicationUuid).build(); + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + applicationManager.updateApplicationImageArtifact(appId, + applicationUuid, iconFileStream, bannerFileStream, attachments); + + return Response.status(Response.Status.OK).entity("Successfully uploaded artifacts for the application " + + applicationUuid).build(); } catch (NotFoundException e) { - String msg = - "Couldn't found application release details or storage details or lifecycle details. Application id: " - + appId + " App release uuid: " + applicationUuid; - log.error(msg, e); + log.error(e.getMessage(), e); return APIUtil.getResponse(e, Response.Status.NOT_FOUND); } catch (ApplicationManagementException e) { String msg = "Error occurred while updating the application."; @@ -282,6 +277,7 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { @Override @PUT + @Consumes("multipart/mixed") @Path("/app-artifacts/{deviceType}/{appType}/{appId}/{uuid}") public Response updateApplicationArtifact( @PathParam("deviceType") String deviceType, @@ -289,9 +285,6 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { @PathParam("appId") int applicationId, @PathParam("uuid") String applicationUuid, @Multipart("binaryFile") Attachment binaryFile) { - ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); - ApplicationManager applicationManager = APIUtil.getApplicationManager(); - ApplicationRelease applicationRelease; try { @@ -299,16 +292,14 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { return APIUtil.getResponse("Uploading artifacts for the application is failed " + applicationUuid, Response.Status.BAD_REQUEST); } - applicationRelease = applicationManager.getAppReleaseIfExists(applicationId, applicationUuid); - applicationRelease = applicationStorageManager - .updateReleaseArtifacts(applicationRelease, appType, deviceType, - binaryFile.getDataHandler().getInputStream()); - applicationManager.updateRelease(applicationId, applicationRelease); + APIUtil.getApplicationManager().updateApplicationArtifact(applicationId, applicationUuid, + binaryFile.getDataHandler().getInputStream()); return Response.status(Response.Status.OK) .entity("Successfully uploaded artifacts for the application release. UUID is " + applicationUuid).build(); } catch (IOException e) { String msg = - "Error occured while trying to read icon, banner files for the application release" + applicationUuid; + "Error occurred while trying to read icon, banner files for the application release" + + applicationUuid; log.error(msg); return APIUtil.getResponse(new ApplicationManagementException(msg, e), Response.Status.BAD_REQUEST); @@ -324,6 +315,10 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { log.error("Error occured while handling the application artifact updating request. application release UUID: " + applicationUuid); return APIUtil.getResponse(e, Response.Status.BAD_REQUEST); + } catch (DeviceManagementException e) { + log.error("Error occurred while updating the image artifacts of the application with the uuid " + + applicationUuid, e); + return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); } } @@ -388,9 +383,9 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { } } - applicationRelease = applicationStorageManager - .updateImageArtifacts(applicationRelease, iconFileStream, bannerFileStream, attachments); - applicationRelease = applicationManager.updateRelease(applicationId, applicationRelease); +// applicationRelease = applicationStorageManager +// .updateImageArtifacts(applicationRelease, iconFileStream, bannerFileStream, attachments); +// applicationRelease = applicationManager.updateRelease(applicationId, applicationRelease); return Response.status(Response.Status.OK).entity(applicationRelease).build(); } catch (ApplicationManagementException e) { @@ -442,7 +437,7 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { ApplicationManager applicationManager = APIUtil.getApplicationManager(); ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); try { - String storedLocation = applicationManager.deleteApplicationRelease(applicationId, releaseUuid); + String storedLocation = applicationManager.deleteApplicationRelease(applicationId, releaseUuid, true); applicationStorageManager.deleteApplicationReleaseArtifacts(storedLocation); String responseMsg = "Successfully deleted the application release of: " + applicationId + ""; return Response.status(Response.Status.OK).entity(responseMsg).build(); @@ -488,7 +483,7 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { LifecycleState state) { ApplicationManager applicationManager = APIUtil.getApplicationManager(); try { - applicationManager.changeLifecycleState(applicationId, applicationUuid, state, true); + applicationManager.changeLifecycleState(applicationId, applicationUuid, state, true, true); } catch (NotFoundException e) { String msg = "Could,t find application release for application id: " + applicationId + " and application release uuid: " + applicationUuid; diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql index 6bada31a2a..a3c9512ab9 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql @@ -28,6 +28,7 @@ CREATE TABLE IF NOT EXISTS AP_APP_RELEASE ( APP_PRICE DECIMAL(6,2) NULL DEFAULT NULL, STORED_LOCATION VARCHAR(100) NOT NULL, BANNER_LOCATION VARCHAR(100) NOT NULL, + ICON_LOCATION VARCHAR(100) NOT NULL, SC_1_LOCATION VARCHAR(100) NOT NULL, SC_2_LOCATION VARCHAR(100) NULL DEFAULT NULL, SC_3_LOCATION VARCHAR(100) NULL DEFAULT NULL, @@ -73,7 +74,7 @@ CREATE INDEX fk_AP_APP_COMMENT_AP_APP_RELEASE1_idx ON AP_APP_REVIEW (AP_APP_RELE CREATE TABLE IF NOT EXISTS AP_APP_LIFECYCLE_STATE ( ID INT(11) NOT NULL AUTO_INCREMENT, CURRENT_STATE VARCHAR(45) NOT NULL, - PREVIOUSE_STATE VARCHAR(45) NOT NULL, + PREVIOUS_STATE VARCHAR(45) NOT NULL, TENANT_ID VARCHAR(45) NOT NULL, UPDATED_BY VARCHAR(100) NOT NULL, UPDATED_AT TIMESTAMP NOT NULL,