diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml index 85d7e5d014..412879e98c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml @@ -225,6 +225,5 @@ javax.ws.rs javax.ws.rs-api - \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java index 5c6e52837e..5d5831893c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/APIUtil.java @@ -28,6 +28,7 @@ import org.wso2.carbon.device.application.mgt.common.services.ApplicationRelease import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; import org.wso2.carbon.device.application.mgt.common.services.LifecycleStateManager; import org.wso2.carbon.device.application.mgt.common.services.PlatformManager; +import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; import javax.ws.rs.core.Response; @@ -44,6 +45,7 @@ public class APIUtil { private static LifecycleStateManager lifecycleStateManager; private static ApplicationReleaseManager applicationReleaseManager; private static ApplicationStorageManager applicationStorageManager; + private static SubscriptionManager subscriptionManager; public static ApplicationManager getApplicationManager() { if (applicationManager == null) { @@ -157,4 +159,27 @@ public class APIUtil { errorMessage.setCode(status.getStatusCode()); return Response.status(status).entity(errorMessage).build(); } + + /** + * To get the Subscription Manager from the osgi context. + * @return SubscriptionManager instance in the current osgi context. + */ + public static SubscriptionManager getSubscriptionManager() { + if (subscriptionManager == null) { + synchronized (APIUtil.class) { + if (subscriptionManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + subscriptionManager = + (SubscriptionManager) ctx.getOSGiService(SubscriptionManager.class, null); + if (subscriptionManager == null) { + String msg = "Subscription Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + + return subscriptionManager; + } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/SubscriptionManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/SubscriptionManagementAPI.java new file mode 100644 index 0000000000..d68cfb9235 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/SubscriptionManagementAPI.java @@ -0,0 +1,117 @@ +/* + * 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.api.services; + +import io.swagger.annotations.*; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.application.mgt.api.beans.ErrorResponse; +import org.wso2.carbon.device.application.mgt.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.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * API to handle subscription management related tasks. + */ +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "Subscription Management Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "SubscriptionManagementService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt/v1.0/subscription"), + }) + } + ), + tags = { + @Tag(name = "Subscription_management, device_management", description = "Subscription Management " + + "related " + + "APIs") + } +) +@Scopes( + scopes = { + @org.wso2.carbon.apimgt.annotations.api.Scope( + name = "Install an Application", + description = "Install an application", + key = "perm:subscription:install", + permissions = {"/device-mgt/subscription/install"} + ), + @org.wso2.carbon.apimgt.annotations.api.Scope( + name = "Install an Application", + description = "Install an application", + key = "perm:application-mgt:login", + permissions = {"/device-mgt/application-mgt/login"} + ) + } +) +@Path("/subscription") +@Api(value = "Subscription Management", description = "This API carries all subscription management related " + + "operations " + + "such as install application to device, uninstall application from device, etc.") +@Produces(MediaType.APPLICATION_JSON) +public interface SubscriptionManagementAPI { + + String SCOPE = "scope"; + + @POST + @Path("/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", + notes = "This will install an application to a given list of devices/users/roles", + tags = "Subscription Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:subscription:install") + }) + } + ) + @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 installing the application.", + response = ErrorResponse.class) + }) + Response installApplication( + @ApiParam( + name = "installationDetails", + value = "The application ID and list the devices/users/roles", + required = true) + @Valid InstallationDetails installationDetails); +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/SubscriptionManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/SubscriptionManagementAPIImpl.java new file mode 100644 index 0000000000..5c521487de --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/java/org/wso2/carbon/device/application/mgt/api/services/impl/SubscriptionManagementAPIImpl.java @@ -0,0 +1,72 @@ +/* + * 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.api.services.impl; + +import io.swagger.annotations.ApiParam; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.api.APIUtil; +import org.wso2.carbon.device.application.mgt.api.services.SubscriptionManagementAPI; +import org.wso2.carbon.device.application.mgt.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 javax.validation.Valid; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import java.util.List; + +/** + * Implementation of Subscription Management related APIs. + */ +@Produces({"application/json"}) +@Path("/subscription") +public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{ + + private static Log log = LogFactory.getLog(SubscriptionManagementAPIImpl.class); + + @Override + public Response installApplication(@ApiParam(name = "installationDetails", value = "The application ID and list" + + " the devices/users/roles", required = true) @Valid InstallationDetails installationDetails) { + Object response; + SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); + try { + String applicationUUTD = installationDetails.getApplicationUUID(); + if (!installationDetails.getDeviceIdentifiers().isEmpty()) { + List deviceList = installationDetails.getDeviceIdentifiers(); + response = subscriptionManager.installApplicationForDevices(applicationUUTD, deviceList); + } else if (!installationDetails.getUserNameList().isEmpty()) { + List userList = installationDetails.getUserNameList(); + response = subscriptionManager.installApplicationForUsers(applicationUUTD, userList); + } else if (!installationDetails.getRoleNameList().isEmpty()) { + List roleList = installationDetails.getRoleNameList(); + response = subscriptionManager.installApplicationForRoles(applicationUUTD, roleList); + } else { + response = "Missing request data!"; + return Response.status(Response.Status.BAD_REQUEST).entity(response).build(); + } + return Response.status(Response.Status.OK).entity(response).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating the application"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/permissions.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/permissions.xml index 8cc36248a1..27df5059a3 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/permissions.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/META-INF/permissions.xml @@ -87,4 +87,12 @@ /application-mgt/platforms/* DELETE + + + + Install Application + /device-mgt/subscription/install + /application-mgt/subscription + POST + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 1dacaaef3e..88a47764f3 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -28,6 +28,7 @@ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> + @@ -38,6 +39,7 @@ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceIdentifier.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceIdentifier.java new file mode 100644 index 0000000000..3da016bf04 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/DeviceIdentifier.java @@ -0,0 +1,71 @@ +/* + * 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 = "123456") + 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 + '\'' + + '}'; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/InstallationDetails.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/InstallationDetails.java new file mode 100644 index 0000000000..51b068efa1 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/InstallationDetails.java @@ -0,0 +1,80 @@ +/* + * 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.common; + +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +public class InstallationDetails { + @ApiModelProperty( + name = "applicationUUID", + value = "Application ID", + required = true) + private String applicationUUID; + @ApiModelProperty( + name = "userNameList", + value = "List of user names.", + required = true) + private List userNameList; + + @ApiModelProperty( + name = "roleNameList", + value = "List of role names.", + required = true) + private List roleNameList; + + @ApiModelProperty( + name = "deviceIdentifiers", + value = "List of device identifiers.", + required = true, + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]") + private List deviceIdentifiers; + + public String getApplicationUUID() { + return applicationUUID; + } + + public void setApplicationUUID(String applicationUUID) { + this.applicationUUID = applicationUUID; + } + + public List getUserNameList() { + return userNameList; + } + + public void setUserNameList(List userNameList) { + this.userNameList = userNameList; + } + + public List getRoleNameList() { + return roleNameList; + } + + public void setRoleNameList(List roleNameList) { + this.roleNameList = roleNameList; + } + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java index 3babe0f814..cb555606d9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java @@ -18,8 +18,49 @@ */ 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.exception.ApplicationManagementException; + +import java.util.List; + /** * This interface manages all the operations related with Application Subscription. */ public interface SubscriptionManager { + /** + * To install an application to given list of devices. + * @param applicationUUID Application ID + * @param deviceList Device list + * @return DeviceList which the application has been installed + * @throws ApplicationManagementException Application Management Exception + */ + List installApplicationForDevices(String applicationUUID, List deviceList) throws ApplicationManagementException; + + /** + * To install an application to given list of users. + * @param applicationUUID Application ID + * @param userList User list + * @return User list which the application has been installed + * @throws ApplicationManagementException Application Management Exception + */ + List installApplicationForUsers(String applicationUUID, List userList) throws ApplicationManagementException; + + /** + * To install an application to given list of users. + * @param applicationUUID Application ID + * @param roleList Role list + * @return Role list which the application has been installed + * @throws ApplicationManagementException Application Management Exception + */ + List installApplicationForRoles(String applicationUUID, List roleList) throws ApplicationManagementException; + + /** + * To uninstall an application from a given list of devices. + * @param applicationUUID Application ID + * @param deviceList Device list + * @return DeviceList which the application has been uninstalled + * @throws ApplicationManagementException Application Management Exception + */ + List uninstallApplication(String applicationUUID, List deviceList) throws ApplicationManagementException; + } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java index d0f3433fb6..29adbbab6c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -17,7 +17,50 @@ */ 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.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; +import java.util.List; + public class SubscriptionManagerImpl implements SubscriptionManager { + + private static final Log log = LogFactory.getLog(SubscriptionManagerImpl.class); + + @Override + public List installApplicationForDevices(String applicationUUID, List deviceList) throws ApplicationManagementException { + log.info("Install application: " + applicationUUID + " to: " + deviceList.size() + " devices."); + 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. + } + return deviceList; + } + + @Override + public List installApplicationForUsers(String applicationUUID, List userList) throws ApplicationManagementException { + log.info("Install application: " + applicationUUID + " to: " + userList.size() + " users."); + for (String user : userList) { + //Todo: implementation + } + return userList; + } + + @Override + public List installApplicationForRoles(String applicationUUID, List roleList) throws ApplicationManagementException { + log.info("Install application: " + applicationUUID + " to: " + roleList.size() + " users."); + for (String role : roleList) { + //Todo: implementation + } + return roleList; + } + + @Override + public List uninstallApplication(String applicationUUID, List deviceList) throws ApplicationManagementException { + return null; + } }