Merge pull request #957 from amalhub/application-mgt

Adding Device-Application mapping implementation
feature/appm-store/pbac
chathurace 7 years ago committed by GitHub
commit e09e1ec68a

@ -24,10 +24,7 @@ import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.InstallationDetails;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -111,7 +108,88 @@ public interface SubscriptionManagementAPI {
Response installApplication(
@ApiParam(
name = "installationDetails",
value = "The application ID and list the devices/users/roles",
value = "The application ID and list of devices/users/roles",
required = true)
@Valid InstallationDetails installationDetails);
@POST
@Path("/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",
notes = "This will uninstall an application to a given list of devices/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 = 500,
message = "Internal Server Error. \n Error occurred while installing the application.",
response = ErrorResponse.class)
})
Response uninstallApplication(
@ApiParam(
name = "installationDetails",
value = "The application ID and list of devices/users/roles",
required = true)
@Valid InstallationDetails installationDetails);
@GET
@Path("/application/{applicationUUID}/device/{deviceId}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get an application",
notes = "This will return an application to a given valid token",
tags = "Subscription Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:subscription:getApplication")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully installed the application.",
response = Application.class),
@ApiResponse(
code = 304,
message = "Not Modified. \n " +
"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)
})
Response getApplication(
@ApiParam(
name = "applicationUUID",
value = "Application ID")
@QueryParam("applicationUUID") String applicationUUID,
@ApiParam(
name = "deviceId",
value = "The device ID")
@QueryParam("deviceId") String deviceId);
}

@ -64,9 +64,22 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
}
return Response.status(Response.Status.OK).entity(response).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while creating the application";
String msg = "Error occurred while installing the application";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).build();
}
}
@Override
public Response uninstallApplication(@ApiParam(name = "installationDetails", value = "The application ID and list" +
" of devices/users/roles", required = true) @Valid InstallationDetails installationDetails) {
return null;
}
@Override
public Response getApplication(@ApiParam(name = "applicationUUID", value = "Application ID") String
applicationUUID, @ApiParam(name = "deviceId", value = "The device ID")
String deviceId) {
return null;
}
}

@ -95,4 +95,16 @@
<url>/application-mgt/subscription</url>
<method>POST</method>
</Permission>
<Permission>
<name>Uninstall Application</name>
<path>/device-mgt/subscription/uninstall</path>
<url>/application-mgt/subscription</url>
<method>POST</method>
</Permission>
<Permission>
<name>Get Application</name>
<path>/device-mgt/subscription/getApplication</path>
<url>/application-mgt/subscription</url>
<method>GET</method>
</Permission>
</PermissionConfiguration>

@ -29,7 +29,7 @@ public class DeviceIdentifier {
name = "id",
value = "Identity of the device.",
required = true,
example = "123456")
example = "d24f870f390352a4")
private String id;
@ApiModelProperty(

@ -22,5 +22,8 @@ package org.wso2.carbon.device.application.mgt.core.dao;
* 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;
}

@ -26,6 +26,7 @@ import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO;
import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO;
import org.wso2.carbon.device.application.mgt.core.dao.LifecycleStateDAO;
import org.wso2.carbon.device.application.mgt.core.dao.PlatformDAO;
import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO;
import org.wso2.carbon.device.application.mgt.core.dao.VisibilityDAO;
import org.wso2.carbon.device.application.mgt.core.dao.impl.application.GenericApplicationDAOImpl;
import org.wso2.carbon.device.application.mgt.core.dao.impl.application.release.GenericApplicationReleaseDAOImpl;
@ -34,6 +35,7 @@ import org.wso2.carbon.device.application.mgt.core.dao.impl.lifecyclestate.Gener
import org.wso2.carbon.device.application.mgt.core.dao.impl.platform.GenericPlatformDAOImpl;
import org.wso2.carbon.device.application.mgt.core.dao.impl.platform.OracleMsSQLPlatformDAOImpl;
import org.wso2.carbon.device.application.mgt.core.dao.impl.visibility.GenericVisibilityDAOImpl;
import org.wso2.carbon.device.application.mgt.core.dao.impl.subscription.GenericSubscriptionDAOImpl;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import org.wso2.carbon.device.application.mgt.core.util.ApplicationMgtDatabaseCreator;
import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
@ -144,6 +146,24 @@ public class DAOFactory {
throw new IllegalStateException("Database engine has not initialized properly.");
}
/**
* To get the instance of SubscriptionDAOImplementation of the particular database engine.
* @return GenericSubscriptionDAOImpl
*/
public static SubscriptionDAO getSubscriptionDAO() {
if (databaseEngine != null) {
switch (databaseEngine) {
case Constants.DataBaseTypes.DB_TYPE_H2:
case Constants.DataBaseTypes.DB_TYPE_MYSQL:
case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL:
return new GenericSubscriptionDAOImpl();
default:
throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine);
}
}
throw new IllegalStateException("Database engine has not initialized properly.");
}
/**
* This method initializes the databases by creating the database.
*

@ -0,0 +1,73 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.application.mgt.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.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 java.sql.*;
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 {
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 = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier);
stmt.setString(2, applicationUUID);
rs = stmt.executeQuery();
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();
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);
} finally {
Util.cleanupResources(stmt, rs);
}
}
}

@ -22,7 +22,12 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.common.DeviceIdentifier;
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.application.mgt.core.dao.common.DAOFactory;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
@ -37,13 +42,29 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
List<DeviceIdentifier> deviceList)
throws ApplicationManagementException {
log.info("Install application: " + applicationUUID + " to: " + deviceList.size() + " devices.");
List<DeviceIdentifier> failedDeviceList = new ArrayList<>(deviceList);
for (DeviceIdentifier device : deviceList) {
String deviceId = device.getId();
//Todo: implementation, validations
//Todo: generating one time download link for the application and put install operation to device.
//Todo: Store the mappings in DB.
org.wso2.carbon.device.mgt.common.DeviceIdentifier deviceIdentifier = new org.wso2.carbon.device.mgt
.common.DeviceIdentifier(device.getId(), device.getType());
try {
DeviceManagementDAOFactory.openConnection();
if (DeviceManagementDAOFactory.getDeviceDAO().getDevice(deviceIdentifier).isEmpty()) {
log.error("Device with ID: " + device.getId() + " not found 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.
DAOFactory.getSubscriptionDAO().addDeviceApplicationMapping(device.getId(), applicationUUID, false);
failedDeviceList.remove(device);
}
} catch (DeviceManagementDAOException | SQLException e) {
throw new ApplicationManagementException("Error locating device.", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
return deviceList;
return failedDeviceList;
}
@Override
@ -52,6 +73,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
log.info("Install application: " + applicationUUID + " to: " + userList.size() + " users.");
for (String user : userList) {
//Todo: implementation
//Todo: get the device list and call installApplicationForDevices
}
return userList;
}
@ -62,6 +84,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
log.info("Install application: " + applicationUUID + " to: " + roleList.size() + " users.");
for (String role : roleList) {
//Todo: implementation
//Todo: get the device list and call installApplicationForDevices
}
return roleList;
}

@ -390,6 +390,20 @@ CREATE TABLE IF NOT EXISTS `APPM_SUBSCRIPTION_PROPERTIES` (
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `APPM_DEVICE_APPLICATION_MAPPING`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `APPM_DEVICE_APPLICATION_MAPPING` (
`ID` INT AUTO_INCREMENT NOT NULL,
`DEVICE_IDENTIFIER` VARCHAR(255) NOT NULL,
`APPLICATION_UUID` VARCHAR(100) NOT NULL,
`INSTALLED` BOOLEAN NOT NULL,
`SENT_AT` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (ID),
CONSTRAINT `fk_appm_application` FOREIGN KEY (`APPLICATION_UUID`) REFERENCES
APPM_APPLICATION (`UUID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
UNIQUE KEY `device_app_mapping` (`DEVICE_IDENTIFIER`, `APPLICATION_UUID`)
) ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;

Loading…
Cancel
Save