Merge pull request #1186 from madawas/application-mgt-new

Enhancing the application install and enterprise install mobile application
feature/appm-store/pbac
Madawa Soysa 7 years ago committed by GitHub
commit 8b4e3ec051
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -58,6 +58,7 @@
org.apache.commons.codec.binary;version="${commons-codec.wso2.osgi.version.range}",
org.wso2.carbon.device.mgt.core.dto.*;version="${carbon.device.mgt.version}",
org.wso2.carbon.device.mgt.core.dao.*;version="${carbon.device.mgt.version}",
org.wso2.carbon.device.mgt.common.operation.mgt.*;version="${carbon.device.mgt.version}",
org.w3c.dom,
org.json,
org.xml.sax,
@ -114,6 +115,10 @@
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,71 @@
/*
* 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.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 = "successfulDevices",
value = "List of successful devices",
dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]"
)
private List<DeviceIdentifier> successfulDevices;
@ApiModelProperty(
name = "failedDevices",
value = "List of failed devices",
dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]"
)
private List<DeviceIdentifier> failedDevices;
@ApiModelProperty(
name = "activity",
value = "Activity corresponding to the operation"
)
private Activity activity;
public List<DeviceIdentifier> getSuccessfulDevices() {
return successfulDevices;
}
public void setSuccessfulDevices(List<DeviceIdentifier> successfulDevices) {
this.successfulDevices = successfulDevices;
}
public List<DeviceIdentifier> getFailedDevices() {
return failedDevices;
}
public void setFailedDevices(List<DeviceIdentifier> failedDevices) {
this.failedDevices = failedDevices;
}
public Activity getActivity() {
return activity;
}
public void setActivity(Activity activity) {
this.activity = activity;
}
}

@ -1,71 +0,0 @@
/*
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.application.mgt.common;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "DeviceIdentifier", description = "This contains device details that is used to identify a device " +
"uniquely.")
public class DeviceIdentifier {
@ApiModelProperty(
name = "id",
value = "Identity of the device.",
required = true,
example = "d24f870f390352a4")
private String id;
@ApiModelProperty(
name = "type",
value = "Type of the device.",
required = true,
example = "android")
private String type;
public DeviceIdentifier() {}
public DeviceIdentifier(String id, String type) {
this.id = id;
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type.trim();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "deviceId {" +
"id='" + id + '\'' +
", type='" + type + '\'' +
'}';
}
}

@ -0,0 +1,85 @@
/*
* 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.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 = "Application 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<String> 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<String> getEntityValueList() {
return entityValueList;
}
public void setEntityValueList(List<String> entityValueList) {
this.entityValueList = entityValueList;
}
}

@ -18,6 +18,7 @@
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;
@ -25,30 +26,16 @@ public class InstallationDetails {
@ApiModelProperty(
name = "applicationUUID",
value = "Application ID",
required = true)
required = true
)
private String applicationUUID;
@ApiModelProperty(
name = "versionName",
value = "Version name",
required = true)
private String versionName;
@ApiModelProperty(
name = "userNameList",
value = "List of user names.",
required = true)
private List<String> userNameList;
@ApiModelProperty(
name = "roleNameList",
value = "List of role names.",
required = true)
private List<String> roleNameList;
@ApiModelProperty(
name = "deviceIdentifiers",
value = "List of device identifiers.",
required = true,
dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]")
dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]"
)
private List<DeviceIdentifier> deviceIdentifiers;
public String getApplicationUUID() {
@ -59,30 +46,6 @@ public class InstallationDetails {
this.applicationUUID = applicationUUID;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public List<String> getUserNameList() {
return userNameList;
}
public void setUserNameList(List<String> userNameList) {
this.userNameList = userNameList;
}
public List<String> getRoleNameList() {
return roleNameList;
}
public void setRoleNameList(List<String> roleNameList) {
this.roleNameList = roleNameList;
}
public List<DeviceIdentifier> getDeviceIdentifiers() {
return deviceIdentifiers;
}

@ -18,10 +18,15 @@
*/
package org.wso2.carbon.device.application.mgt.common.services;
import org.wso2.carbon.device.application.mgt.common.*;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
import org.wso2.carbon.device.application.mgt.common.ApplicationRelease;
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.LifecycleStateTransition;
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.LifecycleManagementException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import java.util.List;
@ -123,6 +128,14 @@ public interface ApplicationManager {
*/
Application getApplicationById(int applicationId) throws ApplicationManagementException;
/**
* To get an application associated with the release.
*
* @param appReleaseUUID UUID of the app release
* @return {@link Application} associated with the release
* @throws ApplicationManagementException If unable to retrieve {@link Application} associated with the given UUID
*/
Application getApplicationByRelease(String appReleaseUUID) throws ApplicationManagementException;
/**
* To get Application with the given UUID.

@ -18,8 +18,9 @@
*/
package org.wso2.carbon.device.application.mgt.common.services;
import org.wso2.carbon.device.application.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import java.util.List;
@ -29,35 +30,42 @@ import java.util.List;
public interface SubscriptionManager {
/**
* To install an application to given list of devices.
* @param applicationUUID Application ID
* @param deviceList Device list
* @return Failed Device List which the application was unable to install
* @throws ApplicationManagementException Application Management Exception
* @param applicationUUID ID of the application to install
* @param deviceList list of device ID's to install the application
* @return {@link ApplicationInstallResponse} object which contains installed application and devices
* @throws ApplicationManagementException if unable to install the application to the given devices
*/
List<DeviceIdentifier> installApplicationForDevices(String applicationUUID, String versionName,
List<DeviceIdentifier> deviceList)
ApplicationInstallResponse installApplicationForDevices(String applicationUUID, List<DeviceIdentifier> deviceList)
throws ApplicationManagementException;
/**
* To install an application to given list of users.
* @param applicationUUID Application ID
* @param userList User list
* @return Failed Device List which the application was unable to install
* @throws ApplicationManagementException Application Management Exception
* @param applicationUUID ID of the application to install
* @param userList list of users to install the application
* @return {@link ApplicationInstallResponse} object which contains installed application and devices
* @throws ApplicationManagementException if unable to install the application to devices belong to given users
*/
List<DeviceIdentifier> installApplicationForUsers(String applicationUUID,
List<String> userList, String versionName)
ApplicationInstallResponse installApplicationForUsers(String applicationUUID, List<String> userList)
throws ApplicationManagementException;
/**
* To install an application to given list of users.
* @param applicationUUID Application ID
* @param roleList Role list
* @return Failed Device List which the application was unable to install
* @throws ApplicationManagementException Application Management Exception
* To install an application to given list of roles.
* @param applicationUUID ID of the application to install
* @param roleList list of roles to install the application
* @return {@link ApplicationInstallResponse} object which contains installed application and devices
* @throws ApplicationManagementException if unable to install the application to devices belong to given roles
*/
ApplicationInstallResponse installApplicationForRoles(String applicationUUID, List<String> roleList)
throws ApplicationManagementException;
/**
* To install an application to given list of roles.
* @param applicationUUID ID of the application to install
* @param deviceGroupList list of device groups to install the application
* @return {@link ApplicationInstallResponse} object which contains installed application and devices
* @throws ApplicationManagementException if unable to install the application to devices belong to given groups
*/
List<DeviceIdentifier> installApplicationForRoles(String applicationUUID,
List<String> roleList, String versionName)
ApplicationInstallResponse installApplicationForGroups(String applicationUUID, List<String> deviceGroupList)
throws ApplicationManagementException;
/**
@ -67,8 +75,6 @@ public interface SubscriptionManager {
* @return Failed Device List which the application was unable to uninstall
* @throws ApplicationManagementException Application Management Exception
*/
List<DeviceIdentifier> uninstallApplication(String applicationUUID,
List<DeviceIdentifier> deviceList)
List<DeviceIdentifier> uninstallApplication(String applicationUUID, List<DeviceIdentifier> deviceList)
throws ApplicationManagementException;
}

@ -42,7 +42,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.0</version>
<version>3.0.1</version>
<extensions>true</extensions>
<configuration>
<instructions>

@ -150,5 +150,15 @@ public interface ApplicationDAO {
* @throws ApplicationManagementDAOException Application Management DAO Exception.
*/
void deleteTags(int applicationId) throws ApplicationManagementDAOException;
/**
* To get an {@link Application} associated with the given release
*
* @param appReleaseUUID UUID of the {@link ApplicationRelease}
* @param tenantId ID of the tenant
* @return {@link Application} associated with the given release UUID
* @throws ApplicationManagementDAOException if unable to fetch the Application from the data store.
*/
Application getApplicationByRelease(String appReleaseUUID, int tenantId) throws ApplicationManagementDAOException;
}

@ -18,12 +18,71 @@
*/
package org.wso2.carbon.device.application.mgt.core.dao;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import java.util.List;
/**
* This interface provides the list of operations that are supported with subscription database.
*
*/
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
public interface SubscriptionDAO {
int addDeviceApplicationMapping(String deviceIdentifier, String applicationUUID, boolean installed) throws ApplicationManagementException;
/**
* Adds a mapping between devices and the application which the application is installed on.
*
* @param tenantId id of the tenant
* @param subscribedBy username of the user who subscribe the application
* @param deviceList List of {@link Device} which the application is installed on
* @param appId id of the {@link Application} which installs
* @param releaseId id of the {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease}
* @throws ApplicationManagementDAOException If unable to add a mapping between device and application
*/
void subscribeDeviceToApplication(int tenantId, String subscribedBy, List<Device> deviceList, int appId,
int releaseId) 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 userList list of user names of the users whose devices are subscribed to the application
* @param appId id of the {@link Application} which installs
* @param releaseId id of the {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease}
* @throws ApplicationManagementDAOException If unable to add a mapping between device and application
*/
void subscribeUserToApplication(int tenantId, String subscribedBy, List<String> userList, int appId, int releaseId)
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 role.
*
* @param tenantId id of the tenant
* @param subscribedBy username of the user who subscribe the application
* @param roleList list of roles which belongs devices are subscribed to the application
* @param appId id of the {@link Application} which installs
* @param releaseId id of the {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease}
* @throws ApplicationManagementDAOException If unable to add a mapping between device and application
*/
void subscribeRoleToApplication(int tenantId, String subscribedBy, List<String> roleList, int appId, int releaseId)
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 role.
*
* @param tenantId id of the tenant
* @param subscribedBy username of the user who subscribe the application
* @param groupList list of {@link DeviceGroup} which belongs the devices that are subscribed to the application
* @param appId id of the {@link Application} which installs
* @param releaseId id of the {@link org.wso2.carbon.device.application.mgt.common.ApplicationRelease}
* @throws ApplicationManagementDAOException If unable to add a mapping between device and application
*/
void subscribeGroupToApplication(int tenantId, String subscribedBy, List<DeviceGroup> groupList, int appId,
int releaseId) throws ApplicationManagementDAOException;
}

@ -146,6 +146,39 @@ public class Util {
return application;
}
/**
* Populates {@link ApplicationRelease} object with the result obtained from the database.
*
* @param rs {@link ResultSet} from obtained from the database
* @return {@link ApplicationRelease} object populated with the data
* @throws SQLException If unable to populate {@link ApplicationRelease} object with the data
*/
public static ApplicationRelease readApplicationRelease(ResultSet rs) throws SQLException {
ApplicationRelease appRelease = new ApplicationRelease();
appRelease.setId(rs.getInt("RELEASE_ID"));
appRelease.setVersion(rs.getString("VERSION"));
appRelease.setTenantId(rs.getString("TENANT_ID"));
appRelease.setUuid(rs.getString("UUID"));
appRelease.setReleaseType(rs.getString("RELEASE_TYPE"));
appRelease.setPrice(rs.getDouble("APP_PRICE"));
appRelease.setAppHashValue(rs.getString("APP_HASH_VALUE"));
appRelease.setAppStoredLoc(rs.getString("STORED_LOCATION"));
appRelease.setBannerLoc(rs.getString("BANNER_LOCATION"));
appRelease.setApplicationCreator(rs.getString("CREATED_BY"));
appRelease.setCreatedAt(rs.getTimestamp("CREATED_AT"));
appRelease.setPublishedBy(rs.getString("PUBLISHED_BY"));
appRelease.setPublishedAt(rs.getTimestamp("PUBLISHED_AT"));
appRelease.setStars(rs.getInt("STARS"));
appRelease.setIsSharedWithAllTenants(rs.getInt("SHARED_WITH_ALL_TENANTS"));
appRelease.setMetaData(rs.getString("APP_META_INFO"));
appRelease.setScreenshotLoc1(rs.getString("SC_1_LOCATION"));
appRelease.setScreenshotLoc2(rs.getString("SC_2_LOCATION"));
appRelease.setScreenshotLoc3(rs.getString("SC_3_LOCATION"));
return appRelease;
}
/**
* Cleans up the statement and resultset after executing the query
*

@ -21,7 +21,13 @@ package org.wso2.carbon.device.application.mgt.core.dao.impl.application;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.wso2.carbon.device.application.mgt.common.*;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
import org.wso2.carbon.device.application.mgt.common.ApplicationRelease;
import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.common.Pagination;
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.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO;
@ -29,7 +35,12 @@ import org.wso2.carbon.device.application.mgt.core.dao.common.Util;
import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import java.sql.*;
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;
/**
@ -122,7 +133,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
ResultSet rs = null;
int isExist = 0;
int index = 0;
String sql = "SELECT * FROM AP_APP WHERE NAME = ? AND TYPE = ? TENANT_ID = ?";
String sql = "SELECT * FROM AP_APP WHERE NAME = ? AND TYPE = ? AND TENANT_ID = ?";
try{
conn = this.getDBConnection();
conn.setAutoCommit(false);
@ -525,6 +536,75 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
}
}
@Override
public Application getApplicationByRelease(String appReleaseUUID, int tenantId)
throws ApplicationManagementDAOException {
if (log.isDebugEnabled()){
log.debug("Getting application with the UUID (" + appReleaseUUID + ") from the database");
}
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = this.getDBConnection();
String sql = "SELECT AP_APP_RELEASE.ID AS RELEASE_ID, AP_APP_RELEASE.VERSION, AP_APP_RELEASE.TENANT_ID,"
+ "AP_APP_RELEASE.UUID, AP_APP_RELEASE.RELEASE_TYPE, AP_APP_RELEASE.APP_PRICE, "
+ "AP_APP_RELEASE.STORED_LOCATION, AP_APP_RELEASE.BANNER_LOCATION, AP_APP_RELEASE.SC_1_LOCATION,"
+ "AP_APP_RELEASE.SC_2_LOCATION, AP_APP_RELEASE.SC_3_LOCATION, AP_APP_RELEASE.APP_HASH_VALUE,"
+ "AP_APP_RELEASE.SHARED_WITH_ALL_TENANTS, AP_APP_RELEASE.APP_META_INFO, AP_APP_RELEASE.CREATED_BY,"
+ "AP_APP_RELEASE.CREATED_AT, AP_APP_RELEASE.PUBLISHED_BY, AP_APP_RELEASE.PUBLISHED_AT, "
+ "AP_APP_RELEASE.STARS,"
+ "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.IS_FREE, AP_UNRESTRICTED_ROLES.ROLE AS ROLE "
+ "FROM AP_APP, AP_UNRESTRICTED_ROLES, AP_APP_RELEASE "
+ "WHERE AP_APP_RELEASE.UUID=? AND AP_APP.TENANT_ID=?;";
stmt = conn.prepareStatement(sql);
stmt.setString(1, appReleaseUUID);
stmt.setInt(2, tenantId);
rs = stmt.executeQuery();
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved details of the application with the UUID " + appReleaseUUID);
}
Application application = null;
while(rs.next()) {
ApplicationRelease appRelease = Util.readApplicationRelease(rs);
application = new Application();
application.setId(rs.getInt("APP_ID"));
application.setName(rs.getString("APP_NAME"));
application.setType(rs.getString("APP_TYPE"));
application.setAppCategory(rs.getString("APP_CATEGORY"));
application.setIsFree(rs.getInt("IS_FREE"));
application.setIsRestricted(rs.getInt("RESTRICTED"));
UnrestrictedRole unrestrictedRole = new UnrestrictedRole();
unrestrictedRole.setRole(rs.getString("ROLE"));
List<UnrestrictedRole> unrestrictedRoleList = new ArrayList<>();
unrestrictedRoleList.add(unrestrictedRole);
application.setUnrestrictedRoles(unrestrictedRoleList);
List<ApplicationRelease> applicationReleaseList = new ArrayList<>();
applicationReleaseList.add(appRelease);
application.setApplicationReleases(applicationReleaseList);
}
return application;
} catch (SQLException e) {
throw new ApplicationManagementDAOException("Error occurred while getting application details with UUID "
+ appReleaseUUID + " While executing query ", e);
} catch (JSONException e) {
throw new ApplicationManagementDAOException("Error occurred while parsing JSON", e);
} catch (DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while obtaining the DB connection.", e);
} finally {
Util.cleanupResources(stmt, rs);
}
}
@Override
public int getApplicationId(String appName, String appType, int tenantId) throws ApplicationManagementDAOException {
Connection conn;

@ -19,55 +19,152 @@ 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.ApplicationManagementException;
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.common.Util;
import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import java.sql.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements SubscriptionDAO {
private static Log log = LogFactory.getLog(GenericSubscriptionDAOImpl.class);
@Override
public int addDeviceApplicationMapping(String deviceIdentifier, String applicationUUID, boolean installed) throws
ApplicationManagementException {
public void subscribeDeviceToApplication(int tenantId, String subscribedBy, List<Device> deviceList, int appId,
int releaseId) throws ApplicationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
int mappingId = -1;
try {
conn = this.getDBConnection();
String sql = "SELECT ID FROM APPM_DEVICE_APPLICATION_MAPPING WHERE DEVICE_IDENTIFIER = ? AND " +
"APPLICATION_UUID = ?";
long time = System.currentTimeMillis() / 1000;
String sql = "INSERT INTO AP_DEVICE_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, "
+ "DM_DEVICE_ID, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier);
stmt.setString(2, applicationUUID);
rs = stmt.executeQuery();
for (Device device : deviceList) {
stmt.setInt(1, tenantId);
stmt.setString(2, subscribedBy);
stmt.setLong(3, time);
stmt.setInt(4, device.getId());
stmt.setInt(5, releaseId);
stmt.setInt(6, appId);
stmt.addBatch();
if (log.isDebugEnabled()) {
log.debug("Adding a mapping to device ID[" + device.getId() + "] to the application [" + appId
+ "], release[" + releaseId + "]");
}
}
stmt.executeBatch();
} catch (SQLException | DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB",
e);
} finally {
Util.cleanupResources(stmt, null);
}
}
if (!rs.next()) {
sql = "INSERT INTO APPM_DEVICE_APPLICATION_MAPPING (DEVICE_IDENTIFIER, APPLICATION_UUID, " +
"INSTALLED) VALUES (?, ?, ?)";
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt.setString(1, deviceIdentifier);
stmt.setString(2, applicationUUID);
stmt.setBoolean(3, installed);
stmt.executeUpdate();
@Override
public void subscribeUserToApplication(int tenantId, String subscribedBy, List<String> userList, int appId,
int releaseId) throws ApplicationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getDBConnection();
long time = System.currentTimeMillis() / 1000;
String sql = "INSERT INTO AP_USER_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, "
+ "USER_NAME, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
for (String user : userList) {
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setString(2, subscribedBy);
stmt.setLong(3, time);
stmt.setString(4, user);
stmt.setInt(5, releaseId);
stmt.setInt(6, appId);
stmt.addBatch();
if (log.isDebugEnabled()) {
log.debug("Adding a mapping to user[" + user + "] to the application [" + appId + "], release["
+ releaseId + "]");
}
}
stmt.executeBatch();
} catch (SQLException | DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB",
e);
} finally {
Util.cleanupResources(stmt, null);
}
}
rs = stmt.getGeneratedKeys();
if (rs.next()) {
mappingId = rs.getInt(1);
}
return mappingId;
} else {
log.warn("Device[" + deviceIdentifier + "] application[" + applicationUUID + "] mapping already " +
"exists in the DB");
return -1;
}
} catch (SQLException e) {
throw new ApplicationManagementException("Error occurred while adding device application mapping to DB", e);
@Override
public void subscribeRoleToApplication(int tenantId, String subscribedBy, List<String> roleList, int appId,
int releaseId) throws ApplicationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getDBConnection();
long time = System.currentTimeMillis() / 1000;
String sql = "INSERT INTO AP_ROLE_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, "
+ "ROLE_NAME, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
for (String role : roleList) {
stmt.setInt(1, tenantId);
stmt.setString(2, subscribedBy);
stmt.setLong(3, time);
stmt.setString(4, role);
stmt.setInt(5, releaseId);
stmt.setInt(6, appId);
stmt.addBatch();
if (log.isDebugEnabled()) {
log.debug("Adding a mapping to role[" + role + "] to the application [" + appId + "], release["
+ releaseId + "]");
}
}
stmt.executeBatch();
} catch (SQLException | DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB",
e);
} finally {
Util.cleanupResources(stmt, null);
}
}
@Override
public void subscribeGroupToApplication(int tenantId, String subscribedBy, List<DeviceGroup> groupList, int appId,
int releaseId) throws ApplicationManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getDBConnection();
long time = System.currentTimeMillis() / 1000;
String sql = "INSERT INTO AP_GROUP_SUBSCRIPTION(TENANT_ID, SUBSCRIBED_BY, SUBSCRIBED_TIMESTAMP, "
+ "DM_GROUP_ID, AP_APP_RELEASE_ID, AP_APP_ID) VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
for (DeviceGroup group : groupList) {
stmt.setInt(1, tenantId);
stmt.setString(2, subscribedBy);
stmt.setLong(3, time);
stmt.setInt(4, group.getGroupId());
stmt.setInt(5, releaseId);
stmt.setInt(6, appId);
stmt.addBatch();
if (log.isDebugEnabled()) {
log.debug("Adding a mapping to group ID[" + group.getGroupId() + "] to the application [" + appId
+ "], release[" + releaseId + "]");
}
}
stmt.executeBatch();
} catch (SQLException | DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while adding device application mapping to DB",
e);
} finally {
Util.cleanupResources(stmt, rs);
Util.cleanupResources(stmt, null);
}
}
}

@ -23,7 +23,15 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.application.mgt.common.*;
import org.wso2.carbon.device.application.mgt.common.AppLifecycleState;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
import org.wso2.carbon.device.application.mgt.common.ApplicationRelease;
import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.common.LifecycleState;
import org.wso2.carbon.device.application.mgt.common.LifecycleStateTransition;
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.LifecycleManagementException;
@ -38,16 +46,17 @@ import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException;
import org.wso2.carbon.device.application.mgt.core.exception.ValidationException;
import org.wso2.carbon.device.application.mgt.core.internal.DataHolder;
import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
import org.wso2.carbon.device.mgt.core.dao.*;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceTypeDAO;
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.util.ArrayList;
import java.util.List;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Default Concrete implementation of Application Management related implementations.
@ -273,6 +282,29 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
@Override
public Application getApplicationByRelease(String appReleaseUUID) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
Application application;
try {
ConnectionManagerUtil.openDBConnection();
application = ApplicationManagementDAOFactory.getApplicationDAO()
.getApplicationByRelease(appReleaseUUID, tenantId);
if (application.getUnrestrictedRoles().isEmpty() || isRoleExists(application.getUnrestrictedRoles(),
userName)) {
return application;
}
return null;
} catch (UserStoreException e) {
throw new ApplicationManagementException(
"User-store exception while getting application with the application UUID " + appReleaseUUID);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
public Boolean verifyApplicationExistenceById(int appId) throws ApplicationManagementException {
try {
Boolean isAppExist;

@ -19,22 +19,35 @@ package org.wso2.carbon.device.application.mgt.core.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.common.DeviceIdentifier;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
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.SubscriptionManager;
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.util.ApplicationManagementUtil;
import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
import org.wso2.carbon.device.application.mgt.core.util.HelperUtil;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.app.mgt.DeviceApplicationMapping;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
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.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
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.DeviceManagerUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* This is the default implementation for the Subscription Manager.
@ -43,108 +56,262 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
private static final Log log = LogFactory.getLog(SubscriptionManagerImpl.class);
private static final String INSTALL_APPLICATION = "INSTALL_APPLICATION";
private SubscriptionDAO subscriptionDAO;
public SubscriptionManagerImpl() {
this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO();
}
@Override
public List<DeviceIdentifier> installApplicationForDevices(String applicationUUID, String versionName,
List<DeviceIdentifier> deviceList)
throws ApplicationManagementException {
return installApplication(applicationUUID, deviceList, versionName);
public ApplicationInstallResponse installApplicationForDevices(String applicationUUID,
List<DeviceIdentifier> deviceList) throws ApplicationManagementException {
if (log.isDebugEnabled()) {
log.debug("Install application: " + applicationUUID + " to " + deviceList.size() + "devices.");
}
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
return installApplication(application, deviceList);
}
@Override
public List<DeviceIdentifier> installApplicationForUsers(String applicationUUID, List<String> userList,
String versionName) throws ApplicationManagementException {
log.info("Install application: " + applicationUUID + " to: " + userList.size() + " users.");
public ApplicationInstallResponse installApplicationForUsers(String applicationUUID, List<String> userList)
throws ApplicationManagementException {
if (log.isDebugEnabled()) {
log.debug("Install application: " + applicationUUID + " to " + userList.size() + " users.");
}
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
List<DeviceIdentifier> deviceList = new ArrayList<>();
for (String user : userList) {
try {
List<Device> devicesOfUser = HelperUtil.getDeviceManagementProviderService().getDevicesOfUser(user);
for (Device device : devicesOfUser) {
deviceList.add(new DeviceIdentifier(device
.getDeviceIdentifier(), device.getType()));
devicesOfUser.stream()
.map(device -> new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()))
.forEach(deviceList::add);
if (log.isDebugEnabled()) {
log.debug(devicesOfUser.size() + " found for the provided user list");
}
} catch (DeviceManagementException e) {
log.error("Error when extracting the device list from user[" + user + "].", e);
throw new ApplicationManagementException("Error when extracting the device list of user[" + user + "].",
e);
}
}
return installApplication(applicationUUID, deviceList, versionName);
ApplicationInstallResponse response = installApplication(application, deviceList);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int applicationReleaseId = application.getApplicationReleases().get(0).getId();
try {
ConnectionManagerUtil.openDBConnection();
subscriptionDAO.subscribeUserToApplication(tenantId, subscriber, userList, application.getId(),
applicationReleaseId);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return response;
}
@Override
public List<DeviceIdentifier> installApplicationForRoles(String applicationUUID, List<String> roleList,
String versionName) throws ApplicationManagementException {
log.info("Install application: " + applicationUUID + " to: " + roleList.size() + " roles.");
public ApplicationInstallResponse installApplicationForRoles(String applicationUUID, List<String> roleList)
throws ApplicationManagementException {
if (log.isDebugEnabled()) {
log.debug("Install application: " + applicationUUID + " to " + roleList.size() + " roles.");
}
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
List<DeviceIdentifier> deviceList = new ArrayList<>();
for (String role : roleList) {
try {
List<Device> devicesOfRole = HelperUtil.getDeviceManagementProviderService().getAllDevicesOfRole(role);
for (Device device : devicesOfRole) {
deviceList.add(new DeviceIdentifier(device
.getDeviceIdentifier(), device.getType()));
devicesOfRole.stream()
.map(device -> new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()))
.forEach(deviceList::add);
if (log.isDebugEnabled()) {
log.debug(devicesOfRole.size() + " found for role: " + role);
}
} catch (DeviceManagementException e) {
log.error("Error when extracting the device list from role[" + role + "].", e);
throw new ApplicationManagementException(
"Error when extracting the device list from role[" + role + "].", e);
}
}
return installApplication(applicationUUID, deviceList, versionName);
ApplicationInstallResponse response = installApplication(application, deviceList);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int applicationReleaseId = application.getApplicationReleases().get(0).getId();
try {
ConnectionManagerUtil.openDBConnection();
subscriptionDAO.subscribeRoleToApplication(tenantId, subscriber, roleList, application.getId(),
applicationReleaseId);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return response;
}
@Override
public List<DeviceIdentifier> uninstallApplication(String applicationUUID,
List<DeviceIdentifier> deviceList)
public ApplicationInstallResponse installApplicationForGroups(String applicationUUID, List<String> deviceGroupList)
throws ApplicationManagementException {
return null;
if (log.isDebugEnabled()) {
log.debug("Install application: " + applicationUUID + " to " + deviceGroupList.size() + " groups.");
}
ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance();
Application application = applicationManager.getApplicationByRelease(applicationUUID);
GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService();
List<DeviceGroup> groupList = new ArrayList<>();
List<DeviceIdentifier> deviceList = new ArrayList<>();
for (String groupName : deviceGroupList) {
try {
DeviceGroup deviceGroup = groupManagementProviderService.getGroup(groupName);
groupList.add(deviceGroup);
int deviceCount = groupManagementProviderService.getDeviceCount(deviceGroup.getGroupId());
List<Device> devicesOfGroups = groupManagementProviderService
.getDevices(deviceGroup.getGroupId(), 0, deviceCount);
devicesOfGroups.stream()
.map(device -> new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()))
.forEach(deviceList::add);
} catch (GroupManagementException e) {
throw new ApplicationManagementException(
"Error when extracting the device list from group[" + groupName + "].", e);
}
}
ApplicationInstallResponse response = installApplication(application, deviceList);
private List<DeviceIdentifier> installApplication(String applicationUUID, List<DeviceIdentifier> deviceList,
String versionName) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int applicationReleaseId = application.getApplicationReleases().get(0).getId();
try {
ConnectionManagerUtil.openDBConnection();
subscriptionDAO.subscribeGroupToApplication(tenantId, subscriber, groupList, application.getId(),
applicationReleaseId);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return response;
}
@Override
public List<DeviceIdentifier> uninstallApplication(String applicationUUID, List<DeviceIdentifier> deviceList)
throws ApplicationManagementException {
return null;
// List<DeviceIdentifier> failedDeviceList = new ArrayList<>(deviceList);
// // Todo: try whether we can optimise this by sending bulk inserts to db
// // Todo: atomicity is not maintained as deveice managment provider service uses separate db connection. fix this??
// log.info("Install application: " + applicationUUID + "[" + versionName + "]" + " to: "
// + deviceList.size() + " devices.");
// for (DeviceIdentifier device : deviceList) {
// org.wso2.carbon.device.mgt.common.DeviceIdentifier deviceIdentifier = new org.wso2.carbon.device.mgt
// .common.DeviceIdentifier(device.getId(), device.getType());
// try {
// DeviceManagementProviderService dmpService = HelperUtil.getDeviceManagementProviderService();
// if (!dmpService.isEnrolled(deviceIdentifier)) {
// log.error("Device with ID: [" + device.getId() + "] is not enrolled to install the application.");
// } else {
// if (log.isDebugEnabled()) {
// log.debug("Installing application to : " + device.getId());
// }
// //Todo: generating one time download link for the application and put install operation to device.
//
// // put app install operation to the device
// ProfileOperation operation = new ProfileOperation();
// operation.setCode(INSTALL_APPLICATION);
// operation.setType(Operation.Type.PROFILE);
// operation.setPayLoad("{'type':'enterprise', 'url':'http://10.100.5.76:8000/app-debug.apk', 'app':'"
// + applicationUUID + "'}");
// List<org.wso2.carbon.device.mgt.common.DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
// deviceIdentifiers.add(deviceIdentifier);
// dmpService.addOperation(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID,
// operation, deviceIdentifiers);
//
// DeviceApplicationMapping deviceApp = new DeviceApplicationMapping();
// deviceApp.setDeviceIdentifier(device.getId());
// deviceApp.setApplicationUUID(applicationUUID);
// deviceApp.setVersionName(versionName);
// deviceApp.setInstalled(false);
// dmpService.addDeviceApplicationMapping(deviceApp);
//// DeviceManagementDAOFactory.openConnection();
//// ApplicationManagementDAOFactory.getSubscriptionDAO().addDeviceApplicationMapping(device.getId(), applicationUUID, false);
// failedDeviceList.remove(device);
// }
// } catch (DeviceManagementException | OperationManagementException | InvalidDeviceException e) {
// log.error("Error while installing application to device[" + deviceIdentifier.getId() + "]", e);
// }
// finally {
// DeviceManagementDAOFactory.closeConnection();
// }
// }
// return failedDeviceList;
}
private ApplicationInstallResponse installApplication(Application application,
List<DeviceIdentifier> deviceIdentifierList) throws ApplicationManagementException {
DeviceManagementProviderService deviceManagementProviderService = HelperUtil
.getDeviceManagementProviderService();
ApplicationInstallResponse response = validateDevices(deviceIdentifierList, application.getType());
/*
Group the valid device list by device type. Following lambda expression produces a map containing device type
as the key and the list of device identifiers as the corresponding value.
*/
Map<String, List<DeviceIdentifier>> deviceTypeIdentifierMap = response.getSuccessfulDevices().stream()
.collect(Collectors.groupingBy(DeviceIdentifier::getType));
for (Map.Entry<String, List<DeviceIdentifier>> entry : deviceTypeIdentifierMap.entrySet()) {
Operation operation = generateOperationPayloadByDeviceType(entry.getKey(), application);
try {
Activity activity = deviceManagementProviderService
.addOperation(entry.getKey(), operation, entry.getValue());
response.setActivity(activity);
} catch (OperationManagementException e) {
response.setSuccessfulDevices(null);
response.setFailedDevices(deviceIdentifierList);
throw new ApplicationManagementException("Error occurred while adding the application install "
+ "operation to devices", 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");
}
}
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
int applicationReleaseId = application.getApplicationReleases().get(0).getId();
try {
ConnectionManagerUtil.openDBConnection();
List<Device> deviceList = new ArrayList<>();
for (DeviceIdentifier deviceIdentifier : response.getSuccessfulDevices()) {
try {
deviceList.add(deviceManagementProviderService.getDevice(deviceIdentifier));
} catch (DeviceManagementException e) {
log.error("Unable to fetch device for device identifier: " + deviceIdentifier.toString());
}
}
subscriptionDAO.subscribeDeviceToApplication(tenantId, subscriber, deviceList, application.getId(),
applicationReleaseId);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return response;
}
private Operation generateOperationPayloadByDeviceType(String deviceType, Application application) {
ProfileOperation operation = new ProfileOperation();
operation.setCode(INSTALL_APPLICATION);
operation.setType(Operation.Type.PROFILE);
//todo: generate operation payload correctly for all types of devices.
operation.setPayLoad(
"{'type':'enterprise', 'url':'" + application.getApplicationReleases().get(0).getAppStoredLoc()
+ "', 'app':'" + application.getApplicationReleases().get(0).getUuid() + "'}");
return operation;
}
/**
* Validates the preconditions which is required to satisfy from the device which is required to install the
* application.
*
* This method check two preconditions whether the application type is compatible to install in the device and
* whether the device is enrolled in the system.
*
* @param deviceIdentifierList List of {@link DeviceIdentifier} which the validation happens
* @param appPlatform type of the application
* @return {@link ApplicationInstallResponse} which contains compatible and incompatible device identifiers
*/
private ApplicationInstallResponse validateDevices(List<DeviceIdentifier> deviceIdentifierList,
String appPlatform) {
ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse();
List<DeviceIdentifier> failedDevices = new ArrayList<>();
List<DeviceIdentifier> compatibleDevices = new ArrayList<>();
for (DeviceIdentifier deviceIdentifier : deviceIdentifierList) {
try {
if (appPlatform == null || !(appPlatform.equals("WEB_CLIP") || appPlatform
.equals(deviceIdentifier.getType()))) {
log.error("Device with ID: [" + deviceIdentifier.getId() + "] of type: ["
+ deviceIdentifier.getType() + "] is not compatible with the application of type: ["
+ appPlatform + "]");
failedDevices.add(deviceIdentifier);
continue;
}
if (!DeviceManagerUtil.isValidDeviceIdentifier(deviceIdentifier)) {
log.error("Device with ID: [" + deviceIdentifier.getId() + "] is not valid to install the "
+ "application.");
applicationInstallResponse.getFailedDevices().add(deviceIdentifier);
}
} catch (DeviceManagementException e) {
log.error("Error occurred while validating the device: [" + deviceIdentifier.getId() + "]", e);
failedDevices.add(deviceIdentifier);
}
compatibleDevices.add(deviceIdentifier);
}
applicationInstallResponse.setFailedDevices(failedDevices);
applicationInstallResponse.setSuccessfulDevices(compatibleDevices);
return applicationInstallResponse;
}
}

@ -21,8 +21,11 @@ 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;
/**
@ -33,6 +36,7 @@ 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();
@ -56,4 +60,21 @@ public class HelperUtil {
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;
}
}

@ -163,6 +163,10 @@
<artifactId>org.wso2.carbon.device.application.mgt.common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>

@ -21,6 +21,7 @@ package org.wso2.carbon.device.application.mgt.publisher.api.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.application.mgt.publisher.api.beans.ErrorListItem;
import java.util.ArrayList;
import java.util.List;

@ -17,14 +17,29 @@
*/
package org.wso2.carbon.device.application.mgt.publisher.api.services;
import io.swagger.annotations.*;
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.Scopes;
import org.wso2.carbon.device.application.mgt.publisher.api.beans.ErrorResponse;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
import org.wso2.carbon.device.application.mgt.common.EnterpriseInstallationDetails;
import org.wso2.carbon.device.application.mgt.common.InstallationDetails;
import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -43,9 +58,8 @@ import javax.ws.rs.core.Response;
}
),
tags = {
@Tag(name = "subscription_management, device_management", description = "Subscription Management " +
"related "
+ "APIs")
@Tag(name = "subscription_management, device_management", description = "Subscription Management "
+ "related APIs")
}
)
@Scopes(
@ -82,7 +96,7 @@ public interface SubscriptionManagementAPI {
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Install an application",
notes = "This will install an application to a given list of devices/users/roles",
notes = "This will install an application to a given list of devices",
tags = "Subscription Management",
extensions = {
@Extension(properties = {
@ -94,24 +108,74 @@ public interface SubscriptionManagementAPI {
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully installed the application.",
response = Application.class),
message = "OK. \n Successfully sent the install application operation.",
response = ApplicationInstallResponse.class
),
@ApiResponse(
code = 304,
message = "Not Modified. \n " +
"Empty body because the application is already installed."),
message = "Not Modified. \n Empty body because the application is already installed."
),
@ApiResponse(
code = 404,
message = "Not Found. \n Application cannot be found to install."
),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while installing the application.",
response = ErrorResponse.class)
message = "Internal Server Error. \n Error occurred while installing the application."
)
})
Response installApplication(
@ApiParam(
name = "installationDetails",
value = "The application ID and list of devices/users/roles",
required = true)
required = true
)
@Valid InstallationDetails installationDetails);
@POST
@Path("/enterprise-install-application")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Install an application to the devices belong to an enterprise entity",
notes = "This will install an application to a given list of groups/users/roles",
tags = "Subscription Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:subscription:install")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully sent the install application operation.",
response = ApplicationInstallResponse.class
),
@ApiResponse(
code = 304,
message = "Not Modified. \n Empty body because the application is already installed."
),
@ApiResponse(
code = 404,
message = "Not Found. \n Application cannot be found to install."
),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while installing the application."
)
})
Response enterpriseInstallApplication(
@ApiParam(
name = "enterpriseInstallationDetails",
value = "The application ID and list of devices/users/roles",
required = true)
@Valid EnterpriseInstallationDetails enterpriseInstallationDetails);
@POST
@Path("/uninstall-application")
@Produces(MediaType.APPLICATION_JSON)
@ -121,7 +185,7 @@ public interface SubscriptionManagementAPI {
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Uninstall an application",
notes = "This will uninstall an application to a given list of devices/users/roles",
notes = "This will uninstall an application from given list of devices",
tags = "Subscription Management",
extensions = {
@Extension(properties = {
@ -134,23 +198,73 @@ public interface SubscriptionManagementAPI {
@ApiResponse(
code = 200,
message = "OK. \n Successfully uninstalled the application.",
response = Application.class),
response = Application.class
),
@ApiResponse(
code = 304,
message = "Not Modified. \n " +
"Empty body because the application is already uninstalled."),
message = "Not Modified. \n Empty body because the application is already uninstalled."
),
@ApiResponse(
code = 404,
message = "Not Found. \n Application cannot be found to uninstall."
),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while installing the application.",
response = ErrorResponse.class)
message = "Internal Server Error. \n Error occurred while uninstalling the application."
)
})
Response uninstallApplication(
@ApiParam(
name = "installationDetails",
value = "The application ID and list of devices/users/roles",
value = "The application ID and list of devices",
required = true)
@Valid InstallationDetails installationDetails);
@POST
@Path("/enterprise-uninstall-application")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Uninstall an application from the devices belong to an enterprise entity",
notes = "This will uninstall an application from devices belong to given list of groups/users/roles",
tags = "Subscription Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:subscription:uninstall")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully uninstalled the application.",
response = Application.class
),
@ApiResponse(
code = 304,
message = "Not Modified. \n Empty body because the application is already uninstalled."
),
@ApiResponse(
code = 404,
message = "Not Found. \n Application cannot be found to uninstall."
),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while uninstalling the application."
)
})
Response enterpriseUninstallApplication(
@ApiParam(
name = "enterpriseInstallationDetails",
value = "The application ID and list of groups/users/roles",
required = true
)
@Valid EnterpriseInstallationDetails enterpriseInstallationDetails);
@GET
@Path("/application/{applicationUUID}/device/{deviceId}")
@Produces(MediaType.APPLICATION_JSON)
@ -173,23 +287,27 @@ public interface SubscriptionManagementAPI {
@ApiResponse(
code = 200,
message = "OK. \n Successfully installed the application.",
response = Application.class),
response = Application.class
),
@ApiResponse(
code = 304,
message = "Not Modified. \n " +
"Empty body because the application is already installed."),
"Empty body because the application is already installed."
),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while fetching the application.",
response = ErrorResponse.class)
message = "Internal Server Error. \n Error occurred while fetching the application."
)
})
Response getApplication(
@ApiParam(
name = "applicationUUID",
value = "Application ID")
value = "Application ID"
)
@QueryParam("applicationUUID") String applicationUUID,
@ApiParam(
name = "deviceId",
value = "The device ID")
value = "The device ID"
)
@QueryParam("deviceId") String deviceId);
}

@ -20,12 +20,14 @@ package org.wso2.carbon.device.application.mgt.store.api.services.impl;
import io.swagger.annotations.ApiParam;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponse;
import org.wso2.carbon.device.application.mgt.common.EnterpriseInstallationDetails;
import org.wso2.carbon.device.application.mgt.store.api.APIUtil;
import org.wso2.carbon.device.application.mgt.publisher.api.services.SubscriptionManagementAPI;
import org.wso2.carbon.device.application.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.application.mgt.common.InstallationDetails;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import javax.validation.Valid;
import javax.ws.rs.POST;
@ -47,33 +49,70 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@Override
@POST
@Path("/install-application")
public Response installApplication(@ApiParam(name = "installationDetails", value = "The application ID and list" +
" the devices/users/roles", required = true) @Valid InstallationDetails installationDetails) {
Object result;
public Response installApplication(@ApiParam(name = "installationDetails", value = "Application ID and list of" +
"devices", required = true) @Valid InstallationDetails installationDetails) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
try {
String applicationUUID = installationDetails.getApplicationUUID();
String versionName = installationDetails.getVersionName();
if (!installationDetails.getDeviceIdentifiers().isEmpty()) {
List<DeviceIdentifier> deviceList = installationDetails.getDeviceIdentifiers();
result = subscriptionManager.installApplicationForDevices(applicationUUID, versionName, deviceList);
} else if (!installationDetails.getUserNameList().isEmpty()) {
List<String> userList = installationDetails.getUserNameList();
result = subscriptionManager.installApplicationForUsers(applicationUUID, userList, versionName);
} else if (!installationDetails.getRoleNameList().isEmpty()) {
List<String> roleList = installationDetails.getRoleNameList();
result = subscriptionManager.installApplicationForRoles(applicationUUID, roleList, versionName);
if (applicationUUID.isEmpty() || installationDetails.getDeviceIdentifiers().isEmpty()) {
String msg = "Some or all data in the incoming request is empty. Therefore unable to proceed with the "
+ "installation.";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
try {
ApplicationInstallResponse response = subscriptionManager.installApplicationForDevices(applicationUUID,
installationDetails.getDeviceIdentifiers());
return Response.status(Response.Status.OK).entity(response).build();
} catch (ApplicationManagementException e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error occurred while installing the application for devices" + ": " + e.getMessage())
.build();
}
}
@Override
public Response enterpriseInstallApplication(EnterpriseInstallationDetails enterpriseInstallationDetails) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
String msg;
String applicationUUID = enterpriseInstallationDetails.getApplicationUUID();
EnterpriseInstallationDetails.EnterpriseEntity enterpriseEntity = enterpriseInstallationDetails.getEntityType();
List<String> entityValueList = enterpriseInstallationDetails.getEntityValueList();
ApplicationInstallResponse response;
if (applicationUUID.isEmpty()) {
msg = "Application UUID is empty in the incoming request. Therefore unable to proceed with the "
+ "installation.";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
if (enterpriseEntity == null || entityValueList.isEmpty()) {
msg = "Some or all details of the entity is empty in the incoming request. Therefore unable to proceed "
+ "with the installation.";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
try {
if (EnterpriseInstallationDetails.EnterpriseEntity.USER.equals(enterpriseEntity)) {
response = subscriptionManager.installApplicationForUsers(applicationUUID, entityValueList);
} else if (EnterpriseInstallationDetails.EnterpriseEntity.ROLE.equals(enterpriseEntity)) {
response = subscriptionManager.installApplicationForRoles(applicationUUID, entityValueList);
} else if (EnterpriseInstallationDetails.EnterpriseEntity.DEVICE_GROUP.equals(enterpriseEntity)) {
response = subscriptionManager.installApplicationForGroups(applicationUUID, entityValueList);
} else {
result = "Missing request data!";
return Response.status(Response.Status.BAD_REQUEST).entity(result).build();
msg = "Entity type does not match either USER, ROLE or DEVICE_GROUP. Therefore unable to proceed with "
+ "the installation";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
HashMap<String, Object> response = new HashMap<>();
response.put("failedDevices", result);
return Response.status(Response.Status.OK).entity(response).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while installing the application";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).build();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error occurred while installing the application for devices" + ": " + e.getMessage())
.build();
}
}
@ -83,6 +122,12 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
return null;
}
@Override
public Response enterpriseUninstallApplication(
EnterpriseInstallationDetails enterpriseInstallationDetails) {
return null;
}
@Override
public Response getApplication(@ApiParam(name = "applicationUUID", value = "Application ID") String
applicationUUID, @ApiParam(name = "deviceId", value = "The device ID")

Loading…
Cancel
Save