Merge branch 'master' into fix-access-authorization

fix-access-authorization
Charitha Goonetilleke 3 months ago
commit 500b3e62ec

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -107,6 +107,23 @@ public interface GrafanaAPIProxyService {
)
Response frontendMetrics(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/user/auth-tokens/rotate")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Rotate authentication tokens",
tags = "Analytics",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "grafana:api:view")
})
}
)
Response rotateAuthToken(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/dashboards/uid/{uid}")
@ -123,6 +140,22 @@ public interface GrafanaAPIProxyService {
)
Response getDashboard(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException;
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/folders/{uid}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Grafana dashboard folder information",
tags = "Analytics",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "grafana:api:view")
})
}
)
Response getFolders(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException;
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ -140,6 +173,23 @@ public interface GrafanaAPIProxyService {
)
Response getAnnotations(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException;
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/prometheus/grafana/api/v1/rules")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Accessing Grafana Prometheus rule information",
tags = "Analytics",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "grafana:api:view")
})
}
)
Response prometheusRuleInfo(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException;
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/alerts/states-for-dashboard")

@ -26,6 +26,8 @@ import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util.Grafa
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util.GrafanaRequestHandlerUtil;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.GrafanaConfiguration;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.GrafanaConfigurationManager;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.exception.MaliciousQueryAttempt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -56,9 +58,13 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService {
@Override
public Response queryDatasource(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
try {
GrafanaConfiguration configuration = GrafanaConfigurationManager.getInstance().getGrafanaConfiguration();
GrafanaPanelIdentifier panelIdentifier = GrafanaRequestHandlerUtil.getPanelIdentifier(headers);
GrafanaMgtAPIUtils.getGrafanaQueryService().buildSafeQuery(body, panelIdentifier.getDashboardId(),
panelIdentifier.getPanelId(), requestUriInfo.getRequestUri());
boolean queryValidationConfig = configuration.getValidationConfig().getDSQueryValidation();
if (queryValidationConfig) {
GrafanaMgtAPIUtils.getGrafanaQueryService().buildSafeQuery(body, panelIdentifier.getDashboardId(),
panelIdentifier.getPanelId(), requestUriInfo.getRequestUri());
}
return GrafanaRequestHandlerUtil.proxyPassPostRequest(body, requestUriInfo, panelIdentifier.getOrgId());
} catch (MaliciousQueryAttempt e) {
return Response.status(Response.Status.BAD_REQUEST).entity(
@ -83,6 +89,15 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService {
return proxyPassPostRequest(body, headers, requestUriInfo);
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/user/auth-tokens/rotate")
@Override
public Response rotateAuthToken(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
return proxyPassPostRequest(body, headers, requestUriInfo);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/dashboards/uid/{uid}")
@ -91,6 +106,14 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService {
return proxyPassGetRequest(headers, requestUriInfo);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/folders/{uid}")
@Override
public Response getFolders(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
return proxyPassGetRequest(headers, requestUriInfo);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ -99,6 +122,16 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService {
public Response getAnnotations(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
return proxyPassGetRequest(headers, requestUriInfo);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/prometheus/grafana/api/v1/rules")
@Override
public Response prometheusRuleInfo(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
return proxyPassGetRequest(headers, requestUriInfo);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/alerts/states-for-dashboard")

@ -22,6 +22,8 @@ import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.bean.ErrorRespo
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.exception.RefererNotValid;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.GrafanaConfiguration;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.GrafanaConfigurationManager;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.exception.GrafanaEnvVariablesNotDefined;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.util.GrafanaConstants;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.util.GrafanaUtil;
@ -120,19 +122,23 @@ public class GrafanaRequestHandlerUtil {
return path;
}
public static GrafanaPanelIdentifier getPanelIdentifier(HttpHeaders headers) throws RefererNotValid {
public static GrafanaPanelIdentifier getPanelIdentifier(HttpHeaders headers) throws RefererNotValid, GrafanaManagementException {
String referer = headers.getHeaderString(GrafanaConstants.REFERER_HEADER);
if(referer == null) {
if (referer == null) {
String errMsg = "Request does not contain Referer header";
log.error(errMsg);
throw new RefererNotValid(errMsg);
}
GrafanaConfiguration configuration = GrafanaConfigurationManager.getInstance().getGrafanaConfiguration();
boolean dashboardIntegrationConfig = configuration.getValidationConfig().getDashboardIntegration();
GrafanaPanelIdentifier panelIdentifier = GrafanaUtil.getPanelIdentifierFromReferer(referer);
if(panelIdentifier.getDashboardId() == null ||
panelIdentifier.getPanelId() == null || panelIdentifier.getOrgId() == null) {
String errMsg = "Referer must contain dashboardId, panelId and orgId";
log.error(errMsg);
throw new RefererNotValid(errMsg);
if (!dashboardIntegrationConfig) {
if (panelIdentifier.getDashboardId() == null ||
panelIdentifier.getPanelId() == null || panelIdentifier.getOrgId() == null) {
String errMsg = "Referer must contain dashboardId, panelId, and orgId";
log.error(errMsg);
throw new RefererNotValid(errMsg);
}
}
return panelIdentifier;
}

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>grafana-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -19,6 +19,7 @@
package io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.xml.bean.CacheConfiguration;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.xml.bean.ValidationConfig;
import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.xml.bean.User;
import javax.xml.bind.annotation.XmlElement;
@ -30,6 +31,7 @@ import java.util.List;
public class GrafanaConfiguration {
private User adminUser;
private ValidationConfig validationConfig;
private List<CacheConfiguration> caches;
@XmlElement(name = "AdminUser")
@ -37,6 +39,15 @@ public class GrafanaConfiguration {
return adminUser;
}
@XmlElement(name = "ValidationConfig")
public ValidationConfig getValidationConfig() {
return validationConfig;
}
public void setValidationConfig(ValidationConfig validationConfig) {
this.validationConfig = validationConfig;
}
public void setAdminUser(User user) {
this.adminUser = user;
}

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.xml.bean;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "ValidationConfig")
public class ValidationConfig {
private boolean dsQueryValidation;
private boolean dashboardIntegration;
@XmlElement(name = "DSQueryValidation")
public boolean getDSQueryValidation() {
return dsQueryValidation;
}
public void setDSQueryValidation(boolean dsQueryValidation) {
this.dsQueryValidation = dsQueryValidation;
}
@XmlElement(name = "DashboardIntegration")
public boolean getDashboardIntegration() {
return dashboardIntegration;
}
public void setDashboardIntegration(boolean dashboardIntegration) {
this.dashboardIntegration = dashboardIntegration;
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>analytics-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -120,7 +120,9 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices {
throw new BadRequestException(msg);
} else if (HttpStatus.SC_NOT_FOUND == response.code()) {
String msg = "Shared scope key not found : " + key;
log.info(msg);
if (log.isDebugEnabled()) {
log.debug(msg);
}
return false;
} else {
String msg = "Response : " + response.code() + response.body();

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -21,7 +21,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -205,7 +205,9 @@
org.wso2.carbon.utils;version="4.6",
org.wso2.carbon.utils.multitenancy;version="4.6",
org.apache.commons.lang,
org.json
org.json,
io.entgra.device.mgt.core.device.mgt.common.permission.mgt,
io.entgra.device.mgt.core.device.mgt.core.permission.mgt
</Import-Package>
<Embed-Dependency>
jsr311-api;scope=compile|runtime;inline=false

@ -46,6 +46,7 @@ import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig;
import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermission;
import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermissions;
import io.entgra.device.mgt.core.device.mgt.core.config.permission.ScopeMapping;
import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -68,6 +69,8 @@ import org.wso2.carbon.user.core.tenant.TenantSearchResult;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionUtils;
import io.entgra.device.mgt.core.device.mgt.common.permission.mgt.PermissionManagementException;
import java.io.BufferedReader;
import java.io.File;
@ -610,9 +613,17 @@ public class APIPublisherServiceImpl implements APIPublisherService {
if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) {
publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope);
// todo: permission changed in update path, is not handled yet.
} else {
// todo: come to this level means, that scope is removed from API, but haven't removed from the scope-role-permission-mappings list
log.warn(scope.getName() + " not available as shared scope");
// This scope doesn't have an api attached.
log.warn(scope.getName() + " not available as shared, add as new scope");
publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope);
// add permission if not exist
try {
PermissionUtils.putPermission(permission);
} catch(PermissionManagementException e) {
log.error("Error when adding permission ", e);
}
}
}
for (String role : rolePermissions.keySet()) {

@ -18,12 +18,24 @@
package io.entgra.device.mgt.core.apimgt.webapp.publisher;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig;
import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermission;
import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermissions;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
import org.wso2.carbon.core.ServerStartupObserver;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class APIPublisherStartupHandler implements ServerStartupObserver {
@ -34,6 +46,7 @@ public class APIPublisherStartupHandler implements ServerStartupObserver {
private static final int MAX_RETRY_COUNT = 5;
private static Stack<APIConfig> failedAPIsStack = new Stack<>();
private static Stack<APIConfig> currentAPIsStack;
private static final Gson gson = new Gson();
private APIPublisherService publisher;
@ -91,6 +104,8 @@ public class APIPublisherStartupHandler implements ServerStartupObserver {
log.error("failed to update scope role mapping.", e);
}
updateScopeMetadataEntryWithDefaultScopes();
// execute after api publishing
for (PostApiPublishingObsever observer : APIPublisherDataHolder.getInstance().getPostApiPublishingObseverList()) {
if (log.isDebugEnabled()) {
@ -116,4 +131,39 @@ public class APIPublisherStartupHandler implements ServerStartupObserver {
}
}
/**
* Update permission scope mapping entry with default scopes if perm-scope-mapping entry exists, otherwise this function
* will create that entry and update the value with default permissions.
*/
private void updateScopeMetadataEntryWithDefaultScopes() {
MetadataManagementService metadataManagementService = APIPublisherDataHolder.getInstance().getMetadataManagementService();
try {
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
DefaultPermissions defaultPermissions = deviceManagementConfig.getDefaultPermissions();
Metadata permScopeMapping = metadataManagementService.retrieveMetadata(Constants.PERM_SCOPE_MAPPING_META_KEY);
Map<String, String> permScopeMap = (permScopeMapping != null) ? gson.fromJson(permScopeMapping.getMetaValue(), HashMap.class) :
new HashMap<>();
for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) {
permScopeMap.putIfAbsent(defaultPermission.getName(),
defaultPermission.getScopeMapping().getKey());
}
APIPublisherDataHolder.getInstance().setPermScopeMapping(permScopeMap);
if (permScopeMapping != null) {
permScopeMapping.setMetaValue(gson.toJson(permScopeMap));
metadataManagementService.updateMetadata(permScopeMapping);
return;
}
permScopeMapping = new Metadata();
permScopeMapping.setMetaKey(Constants.PERM_SCOPE_MAPPING_META_KEY);
permScopeMapping.setMetaValue(gson.toJson(permScopeMap));
metadataManagementService.createMetadata(permScopeMapping);
} catch (MetadataManagementException e) {
log.error("Error encountered while updating permission scope mapping metadata with default scopes");
} catch (MetadataKeyAlreadyExistsException e) {
log.error("Metadata entry already exists for " + Constants.PERM_SCOPE_MAPPING_META_KEY);
}
}
}

@ -22,10 +22,6 @@ import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig;
import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermission;
import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermissions;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
@ -131,19 +127,13 @@ public class APIPublisherLifecycleListener implements LifecycleListener {
Metadata existingMetaData = metadataManagementService.retrieveMetadata("perm-scope" +
"-mapping");
if (existingMetaData != null) {
existingMetaData.setMetaValue(new Gson().toJson(permScopeMap));
metadataManagementService.updateMetadata(existingMetaData);
} else {
Metadata newMetaData = new Metadata();
newMetaData.setMetaKey("perm-scope-mapping");
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
DefaultPermissions defaultPermissions = deviceManagementConfig.getDefaultPermissions();
for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) {
permScopeMap.put(defaultPermission.getName(), defaultPermission.getScopeMapping().getKey());
}
newMetaData.setMetaValue(new Gson().toJson(permScopeMap));
metadataManagementService.createMetadata(newMetaData);
}

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>application-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -25,16 +25,52 @@ public class ApplicationArtifact {
private String installerName;
private InputStream installerStream;
private String installerPath;
private String bannerName;
private InputStream bannerStream;
private String bannerPath;
private String iconName;
private InputStream iconStream;
private String iconPath;
private Map<String , InputStream> screenshots;
private Map<String, String> screenshotPaths;
public String getInstallerPath() {
return installerPath;
}
public void setInstallerPath(String installerPath) {
this.installerPath = installerPath;
}
public String getBannerPath() {
return bannerPath;
}
public void setBannerPath(String bannerPath) {
this.bannerPath = bannerPath;
}
public String getIconPath() {
return iconPath;
}
public void setIconPath(String iconPath) {
this.iconPath = iconPath;
}
public Map<String, String> getScreenshotPaths() {
return screenshotPaths;
}
public void setScreenshotPaths(Map<String, String> screenshotPaths) {
this.screenshotPaths = screenshotPaths;
}
public String getInstallerName() {
return installerName;

@ -0,0 +1,217 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common;
import java.util.ArrayList;
import java.util.List;
public class CategorizedSubscriptionResult {
private List<DeviceSubscriptionData> installedDevices;
private int installedDevicesCount;
private List<DeviceSubscriptionData> pendingDevices;
private int pendingDevicesCount;
private List<DeviceSubscriptionData> errorDevices;
private int errorDevicesCount;
private List<DeviceSubscriptionData> newDevices;
private int newDevicesCount;
private List<DeviceSubscriptionData> subscribedDevices;
private int subscribedDevicesCount;
public CategorizedSubscriptionResult(List<DeviceSubscriptionData> installedDevices,
List<DeviceSubscriptionData> pendingDevices,
List<DeviceSubscriptionData> errorDevices) {
this.installedDevices = installedDevices;
this.pendingDevices = pendingDevices;
this.errorDevices = errorDevices;
this.newDevices = null;
this.subscribedDevices = null;
}
public CategorizedSubscriptionResult(List<DeviceSubscriptionData> installedDevices,
List<DeviceSubscriptionData> pendingDevices,
List<DeviceSubscriptionData> errorDevices,
List<DeviceSubscriptionData> newDevices) {
this.installedDevices = installedDevices;
this.pendingDevices = pendingDevices;
this.errorDevices = errorDevices;
this.newDevices = newDevices;
this.subscribedDevices = null;
}
public CategorizedSubscriptionResult(List<DeviceSubscriptionData> installedDevices,
List<DeviceSubscriptionData> pendingDevices,
List<DeviceSubscriptionData> errorDevices,
List<DeviceSubscriptionData> newDevices,
List<DeviceSubscriptionData> subscribedDevices) {
this.installedDevices = installedDevices;
this.pendingDevices = pendingDevices;
this.errorDevices = errorDevices;
this.newDevices = newDevices;
this.subscribedDevices = subscribedDevices;
}
public CategorizedSubscriptionResult(List<DeviceSubscriptionData> installedDevices,
List<DeviceSubscriptionData> pendingDevices,
List<DeviceSubscriptionData> errorDevices,
List<DeviceSubscriptionData> newDevices,
int installedDevicesCount,
int pendingDevicesCount,
int errorDevicesCount,
int newDevicesCount
) {
this.installedDevices = installedDevices;
this.pendingDevices = pendingDevices;
this.errorDevices = errorDevices;
this.newDevices = newDevices;
this.subscribedDevices = null;
this.installedDevicesCount = installedDevicesCount;
this.pendingDevicesCount = pendingDevicesCount;
this.errorDevicesCount = errorDevicesCount;
this.newDevicesCount = newDevicesCount;
this.subscribedDevicesCount = 0;
}
public CategorizedSubscriptionResult(List<DeviceSubscriptionData> installedDevices,
List<DeviceSubscriptionData> pendingDevices,
List<DeviceSubscriptionData> errorDevices,
List<DeviceSubscriptionData> newDevices,
List<DeviceSubscriptionData> subscribedDevices, int installedDevicesCount,
int pendingDevicesCount,
int errorDevicesCount,
int newDevicesCount,
int subscribedDevicesCount) {
this.installedDevices = installedDevices;
this.pendingDevices = pendingDevices;
this.errorDevices = errorDevices;
this.newDevices = newDevices;
this.subscribedDevices = subscribedDevices;
this.installedDevicesCount = installedDevicesCount;
this.pendingDevicesCount = pendingDevicesCount;
this.errorDevicesCount = errorDevicesCount;
this.newDevicesCount = newDevicesCount;
this.subscribedDevicesCount = subscribedDevicesCount;
}
public CategorizedSubscriptionResult(List<DeviceSubscriptionData> devices, String tabActionStatus) {
switch (tabActionStatus) {
case "COMPLETED":
this.installedDevices = devices;
break;
case "PENDING":
this.pendingDevices = devices;
break;
case "ERROR":
this.errorDevices = devices;
break;
case "NEW":
this.newDevices = devices;
break;
case "SUBSCRIBED":
this.subscribedDevices = devices;
break;
default:
this.installedDevices = new ArrayList<>();
this.pendingDevices = new ArrayList<>();
this.errorDevices = new ArrayList<>();
this.newDevices = new ArrayList<>();
this.subscribedDevices = new ArrayList<>();
break;
}
}
public List<DeviceSubscriptionData> getInstalledDevices() {
return installedDevices;
}
public void setInstalledDevices(List<DeviceSubscriptionData> installedDevices) {
this.installedDevices = installedDevices;
}
public List<DeviceSubscriptionData> getPendingDevices() {
return pendingDevices;
}
public void setPendingDevices(List<DeviceSubscriptionData> pendingDevices) {
this.pendingDevices = pendingDevices;
}
public List<DeviceSubscriptionData> getErrorDevices() {
return errorDevices;
}
public void setErrorDevices(List<DeviceSubscriptionData> errorDevices) {
this.errorDevices = errorDevices;
}
public List<DeviceSubscriptionData> getNewDevices() {
return newDevices;
}
public void setNewDevices(List<DeviceSubscriptionData> newDevices) {
this.newDevices = newDevices;
}
public List<DeviceSubscriptionData> getSubscribedDevices() {
return subscribedDevices;
}
public void setSubscribedDevices(List<DeviceSubscriptionData> subscribedDevices) {
this.subscribedDevices = subscribedDevices;
}
public int getInstalledDevicesCount() {
return installedDevicesCount;
}
public void setInstalledDevicesCount(int installedDevicesCount) {
this.installedDevicesCount = installedDevicesCount;
}
public int getPendingDevicesCount() {
return pendingDevicesCount;
}
public void setPendingDevicesCount(int pendingDevicesCount) {
this.pendingDevicesCount = pendingDevicesCount;
}
public int getErrorDevicesCount() {
return errorDevicesCount;
}
public void setErrorDevicesCount(int errorDevicesCount) {
this.errorDevicesCount = errorDevicesCount;
}
public int getNewDevicesCount() {
return newDevicesCount;
}
public void setNewDevicesCount(int newDevicesCount) {
this.newDevicesCount = newDevicesCount;
}
public int getSubscribedDevicesCount() {
return subscribedDevicesCount;
}
public void setSubscribedDevicesCount(int subscribedDevicesCount) {
this.subscribedDevicesCount = subscribedDevicesCount;
}
}

@ -0,0 +1,115 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common;
import java.sql.Timestamp;
public class DeviceSubscription {
private int deviceId;
private int subscriptionId;
private String deviceName;
private String deviceIdentifier;
private String deviceStatus;
private String deviceOwner;
private String deviceType;
private String ownershipType;
private Timestamp dateOfLastUpdate;
private SubscriptionData subscriptionData;
public int getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(int subscriptionId) {
this.subscriptionId = subscriptionId;
}
public int getDeviceId() {
return deviceId;
}
public void setDeviceId(int deviceId) {
this.deviceId = deviceId;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getDeviceIdentifier() {
return deviceIdentifier;
}
public void setDeviceIdentifier(String deviceIdentifier) {
this.deviceIdentifier = deviceIdentifier;
}
public String getDeviceStatus() {
return deviceStatus;
}
public void setDeviceStatus(String deviceStatus) {
this.deviceStatus = deviceStatus;
}
public String getDeviceOwner() {
return deviceOwner;
}
public void setDeviceOwner(String deviceOwner) {
this.deviceOwner = deviceOwner;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public String getOwnershipType() {
return ownershipType;
}
public void setOwnershipType(String ownershipType) {
this.ownershipType = ownershipType;
}
public Timestamp getDateOfLastUpdate() {
return dateOfLastUpdate;
}
public void setDateOfLastUpdate(Timestamp dateOfLastUpdate) {
this.dateOfLastUpdate = dateOfLastUpdate;
}
public SubscriptionData getSubscriptionData() {
return subscriptionData;
}
public void setSubscriptionData(SubscriptionData subscriptionData) {
this.subscriptionData = subscriptionData;
}
}

@ -26,12 +26,22 @@ public class DeviceSubscriptionData {
private int subId;
private String action;
private long actionTriggeredTimestamp;
private Timestamp actionTriggeredTimestamp;
private String actionTriggeredFrom;
private String actionTriggeredBy;
private String actionType;
private String status;
private Device device;
private String currentInstalledVersion;
private int deviceId;
private String deviceOwner;
private String deviceStatus;
private boolean unsubscribed;
private String unsubscribedBy;
private Timestamp unsubscribedTimestamp;
private String deviceName;
private String deviceIdentifier;
private String type;
public String getAction() {
return action;
@ -41,14 +51,6 @@ public class DeviceSubscriptionData {
this.action = action;
}
public long getActionTriggeredTimestamp() {
return actionTriggeredTimestamp;
}
public void setActionTriggeredTimestamp(long actionTriggeredTimestamp) {
this.actionTriggeredTimestamp = actionTriggeredTimestamp;
}
public String getActionTriggeredBy() {
return actionTriggeredBy;
}
@ -81,9 +83,13 @@ public class DeviceSubscriptionData {
this.device = device;
}
public String getCurrentInstalledVersion() { return currentInstalledVersion; }
public String getCurrentInstalledVersion() {
return currentInstalledVersion;
}
public void setCurrentInstalledVersion(String currentInstalledVersion) { this.currentInstalledVersion = currentInstalledVersion; }
public void setCurrentInstalledVersion(String currentInstalledVersion) {
this.currentInstalledVersion = currentInstalledVersion;
}
public int getSubId() {
return subId;
@ -92,4 +98,92 @@ public class DeviceSubscriptionData {
public void setSubId(int subId) {
this.subId = subId;
}
public int getDeviceId() {
return deviceId;
}
public void setDeviceId(int deviceId) {
this.deviceId = deviceId;
}
public String getActionTriggeredFrom() {
return actionTriggeredFrom;
}
public void setActionTriggeredFrom(String actionTriggeredFrom) {
this.actionTriggeredFrom = actionTriggeredFrom;
}
public Timestamp getActionTriggeredTimestamp() {
return actionTriggeredTimestamp;
}
public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) {
this.actionTriggeredTimestamp = actionTriggeredTimestamp;
}
public String getDeviceOwner() {
return deviceOwner;
}
public void setDeviceOwner(String deviceOwner) {
this.deviceOwner = deviceOwner;
}
public String getDeviceStatus() {
return deviceStatus;
}
public void setDeviceStatus(String deviceStatus) {
this.deviceStatus = deviceStatus;
}
public boolean isUnsubscribed() {
return unsubscribed;
}
public void setUnsubscribed(boolean unsubscribed) {
this.unsubscribed = unsubscribed;
}
public String getUnsubscribedBy() {
return unsubscribedBy;
}
public void setUnsubscribedBy(String unsubscribedBy) {
this.unsubscribedBy = unsubscribedBy;
}
public Timestamp getUnsubscribedTimestamp() {
return unsubscribedTimestamp;
}
public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) {
this.unsubscribedTimestamp = unsubscribedTimestamp;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDeviceIdentifier() {
return deviceIdentifier;
}
public void setDeviceIdentifier(String deviceIdentifier) {
this.deviceIdentifier = deviceIdentifier;
}
}

@ -0,0 +1,68 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common;
public class DeviceSubscriptionFilterCriteria {
private String name;
private String owner;
private String deviceStatus;
private String filteringDeviceSubscriptionStatus; // COMPLETE, PENDING ...
private String triggeredBy;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getDeviceStatus() {
return deviceStatus;
}
public void setDeviceStatus(String deviceStatus) {
this.deviceStatus = deviceStatus;
}
public String getFilteringDeviceSubscriptionStatus() {
return filteringDeviceSubscriptionStatus;
}
public void setFilteringDeviceSubscriptionStatus(String filteringDeviceSubscriptionStatus) {
this.filteringDeviceSubscriptionStatus = filteringDeviceSubscriptionStatus;
}
public String getTriggeredBy() {
return triggeredBy;
}
public void setTriggeredBy(String triggeredBy) {
this.triggeredBy = triggeredBy;
}
}

@ -118,6 +118,11 @@ public class Filter {
*/
private boolean isNotRetired;
/**
* To check whether web applications should be returned
*/
private boolean withWebApps;
public int getLimit() {
return limit;
}
@ -221,4 +226,12 @@ public class Filter {
public void setNotRetired(boolean notRetired) {
isNotRetired = notRetired;
}
public boolean isWithWebApps() {
return withWebApps;
}
public void setWithWebApps(boolean withWebApps) {
this.withWebApps = withWebApps;
}
}

@ -0,0 +1,70 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common;
import java.sql.Timestamp;
public class SubscriptionData {
private String deviceSubscriptionStatus;
private String triggeredBy;
private String subscriptionType;
private Timestamp triggeredAt;
private int subscriptionId;
public String getDeviceSubscriptionStatus() {
return deviceSubscriptionStatus;
}
public void setDeviceSubscriptionStatus(String deviceSubscriptionStatus) {
this.deviceSubscriptionStatus = deviceSubscriptionStatus;
}
public String getTriggeredBy() {
return triggeredBy;
}
public void setTriggeredBy(String triggeredBy) {
this.triggeredBy = triggeredBy;
}
public String getSubscriptionType() {
return subscriptionType;
}
public void setSubscriptionType(String subscriptionType) {
this.subscriptionType = subscriptionType;
}
public Timestamp getTriggeredAt() {
return triggeredAt;
}
public void setTriggeredAt(Timestamp triggeredAt) {
this.triggeredAt = triggeredAt;
}
public int getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(int subscriptionId) {
this.subscriptionId = subscriptionId;
}
}

@ -0,0 +1,88 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common;
import java.sql.Timestamp;
public class SubscriptionEntity {
private String identity;
private String subscribedBy;
private Timestamp subscribedTimestamp;
private boolean unsubscribed;
private String unsubscribedBy;
private Timestamp unsubscribedTimestamp;
private int applicationReleaseId;
public String getIdentity() {
return identity;
}
public void setIdentity(String identity) {
this.identity = identity;
}
public String getSubscribedBy() {
return subscribedBy;
}
public void setSubscribedBy(String subscribedBy) {
this.subscribedBy = subscribedBy;
}
public Timestamp getSubscribedTimestamp() {
return subscribedTimestamp;
}
public void setSubscribedTimestamp(Timestamp subscribedTimestamp) {
this.subscribedTimestamp = subscribedTimestamp;
}
public boolean getUnsubscribed() {
return unsubscribed;
}
public void setUnsubscribed(boolean unsubscribed) {
this.unsubscribed = unsubscribed;
}
public String getUnsubscribedBy() {
return unsubscribedBy;
}
public void setUnsubscribedBy(String unsubscribedBy) {
this.unsubscribedBy = unsubscribedBy;
}
public Timestamp getUnsubscribedTimestamp() {
return unsubscribedTimestamp;
}
public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) {
this.unsubscribedTimestamp = unsubscribedTimestamp;
}
public int getApplicationReleaseId() {
return applicationReleaseId;
}
public void setApplicationReleaseId(int applicationReleaseId) {
this.applicationReleaseId = applicationReleaseId;
}
}

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common;
public class SubscriptionInfo {
private String applicationUUID;
private String subscriptionType;
private String deviceSubscriptionStatus;
private String identifier;
private String subscriptionStatus;
private DeviceSubscriptionFilterCriteria deviceSubscriptionFilterCriteria;
public String getApplicationUUID() {
return applicationUUID;
}
public void setApplicationUUID(String applicationUUID) {
this.applicationUUID = applicationUUID;
}
public String getSubscriptionType() {
return subscriptionType;
}
public void setSubscriptionType(String subscriptionType) {
this.subscriptionType = subscriptionType;
}
public String getDeviceSubscriptionStatus() {
return deviceSubscriptionStatus;
}
public void setDeviceSubscriptionStatus(String deviceSubscriptionStatus) {
this.deviceSubscriptionStatus = deviceSubscriptionStatus;
}
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getSubscriptionStatus() {
return subscriptionStatus;
}
public void setSubscriptionStatus(String subscriptionStatus) {
this.subscriptionStatus = subscriptionStatus;
}
public DeviceSubscriptionFilterCriteria getDeviceSubscriptionFilterCriteria() {
return deviceSubscriptionFilterCriteria;
}
public void setDeviceSubscriptionFilterCriteria(DeviceSubscriptionFilterCriteria deviceSubscriptionFilterCriteria) {
this.deviceSubscriptionFilterCriteria = deviceSubscriptionFilterCriteria;
}
}

@ -0,0 +1,69 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SubscriptionMetadata {
public static final String SUBSCRIPTION_STATUS_UNSUBSCRIBED = "unsubscribed";
public static final class DeviceSubscriptionStatus {
public static final String NEW = "NEW";
public static final String PENDING = "PENDING";
public static final String COMPLETED = "COMPLETED";
public static final String ERROR = "ERROR";
public static final String INVALID = "INVALID";
public static final String UNAUTHORIZED = "UNAUTHORIZED";
public static final String IN_PROGRESS = "IN_PROGRESS";
public static final String REPEATED = "REPEATED";
}
public static final class SubscriptionTypes {
public static final String ROLE = "role";
public static final String DEVICE = "device";
public static final String GROUP = "group";
public static final String USER = "user";
}
public static final class DBSubscriptionStatus {
public static final List<String> COMPLETED_STATUS_LIST =
Collections.singletonList(DeviceSubscriptionStatus.COMPLETED);
public static final List<String> ERROR_STATUS_LIST =
Arrays.asList(DeviceSubscriptionStatus.ERROR, DeviceSubscriptionStatus.INVALID, DeviceSubscriptionStatus.UNAUTHORIZED);
public static final List<String> PENDING_STATUS_LIST =
Arrays.asList(DeviceSubscriptionStatus.PENDING, DeviceSubscriptionStatus.IN_PROGRESS, DeviceSubscriptionStatus.REPEATED);
}
public static Map<String, List<String>> deviceSubscriptionStatusToDBSubscriptionStatusMap;
static {
Map<String, List<String>> statusMap = new HashMap<>();
statusMap.put(DeviceSubscriptionStatus.COMPLETED, DBSubscriptionStatus.COMPLETED_STATUS_LIST);
statusMap.put(DeviceSubscriptionStatus.PENDING, DBSubscriptionStatus.PENDING_STATUS_LIST);
statusMap.put(DeviceSubscriptionStatus.IN_PROGRESS, Collections.singletonList(DeviceSubscriptionStatus.IN_PROGRESS));
statusMap.put(DeviceSubscriptionStatus.REPEATED, Collections.singletonList(DeviceSubscriptionStatus.REPEATED));
statusMap.put(DeviceSubscriptionStatus.ERROR, DBSubscriptionStatus.ERROR_STATUS_LIST);
statusMap.put(DeviceSubscriptionStatus.INVALID,Collections.singletonList(DeviceSubscriptionStatus.INVALID));
statusMap.put(DeviceSubscriptionStatus.UNAUTHORIZED,Collections.singletonList(DeviceSubscriptionStatus.UNAUTHORIZED));
deviceSubscriptionStatusToDBSubscriptionStatusMap = Collections.unmodifiableMap(statusMap);
}
}

@ -0,0 +1,63 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common;
import java.util.List;
public class SubscriptionResponse {
private String applicationUUID;
private int count;
private List<?> data;
public SubscriptionResponse(String applicationUUID, int count, List<?> data) {
this.applicationUUID = applicationUUID;
this.count = count;
this.data = data;
}
public SubscriptionResponse(String applicationUUID, List<?> data) {
this.applicationUUID = applicationUUID;
this.data = data;
}
public String getApplicationUUID() {
return applicationUUID;
}
public void setApplicationUUID(String applicationUUID) {
this.applicationUUID = applicationUUID;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<?> getData() {
return data;
}
public void setData(List<?> data) {
this.data = data;
}
}

@ -0,0 +1,68 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common;
public class SubscriptionStatistics {
private float completedPercentage;
private float failedPercentage;
private float pendingPercentage;
private float newDevicesPercentage;
public SubscriptionStatistics() {}
public SubscriptionStatistics(float completedPercentage, float failedPercentage, float pendingPercentage,
float newDevicesPercentage) {
this.completedPercentage = completedPercentage;
this.failedPercentage = failedPercentage;
this.pendingPercentage = pendingPercentage;
this.newDevicesPercentage = newDevicesPercentage;
}
public float getCompletedPercentage() {
return completedPercentage;
}
public void setCompletedPercentage(float completedPercentage) {
this.completedPercentage = completedPercentage;
}
public float getFailedPercentage() {
return failedPercentage;
}
public void setFailedPercentage(float failedPercentage) {
this.failedPercentage = failedPercentage;
}
public float getPendingPercentage() {
return pendingPercentage;
}
public void setPendingPercentage(float pendingPercentage) {
this.pendingPercentage = pendingPercentage;
}
public float getNewDevicesPercentage() {
return newDevicesPercentage;
}
public void setNewDevicesPercentage(float newDevicesPercentage) {
this.newDevicesPercentage = newDevicesPercentage;
}
}

@ -0,0 +1,55 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class CategorizedSubscriptionCountsDTO {
private String subscriptionType;
private int subscriptionCount;
private int unsubscriptionCount;
public CategorizedSubscriptionCountsDTO(String subscriptionType, int subscriptionCount, int unsubscriptionCount) {
this.subscriptionType = subscriptionType;
this.subscriptionCount = subscriptionCount;
this.unsubscriptionCount = unsubscriptionCount;
}
public String getSubscriptionType() {
return subscriptionType;
}
public void setSubscriptionType(String subscriptionType) {
this.subscriptionType = subscriptionType;
}
public int getSubscriptionCount() {
return subscriptionCount;
}
public void setSubscriptionCount(int subscriptionCount) {
this.subscriptionCount = subscriptionCount;
}
public int getUnsubscriptionCount() {
return unsubscriptionCount;
}
public void setUnsubscriptionCount(int unsubscriptionCount) {
this.unsubscriptionCount = unsubscriptionCount;
}
}

@ -0,0 +1,126 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
import io.entgra.device.mgt.core.device.mgt.core.dto.OperationResponseDTO;
import java.sql.Timestamp;
import java.util.List;
public class DeviceOperationDTO {
private int deviceId;
private String uuid;
private String status;
private int operationId;
private String actionTriggeredFrom;
private Timestamp actionTriggeredAt;
private int appReleaseId;
private String operationCode;
private Object operationDetails;
private Object operationProperties;
private List<OperationResponseDTO> operationResponses;
public int getDeviceId() {
return deviceId;
}
public void setDeviceId(int deviceId) {
this.deviceId = deviceId;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public int getOperationId() {
return operationId;
}
public void setOperationId(int operationId) {
this.operationId = operationId;
}
public String getActionTriggeredFrom() {
return actionTriggeredFrom;
}
public void setActionTriggeredFrom(String actionTriggeredFrom) {
this.actionTriggeredFrom = actionTriggeredFrom;
}
public Timestamp getActionTriggeredAt() {
return actionTriggeredAt;
}
public void setActionTriggeredAt(Timestamp actionTriggeredAt) {
this.actionTriggeredAt = actionTriggeredAt;
}
public int getAppReleaseId() {
return appReleaseId;
}
public void setAppReleaseId(int appReleaseId) {
this.appReleaseId = appReleaseId;
}
public String getOperationCode() {
return operationCode;
}
public void setOperationCode(String operationCode) {
this.operationCode = operationCode;
}
public Object getOperationDetails() {
return operationDetails;
}
public void setOperationDetails(Object operationDetails) {
this.operationDetails = operationDetails;
}
public Object getOperationProperties() {
return operationProperties;
}
public void setOperationProperties(Object operationProperties) {
this.operationProperties = operationProperties;
}
public List<OperationResponseDTO> getOperationResponses() {
return operationResponses;
}
public void setOperationResponses(List<OperationResponseDTO> operationResponses) {
this.operationResponses = operationResponses;
}
}

@ -19,6 +19,7 @@
package io.entgra.device.mgt.core.application.mgt.common.dto;
import java.sql.Timestamp;
import java.util.Objects;
public class DeviceSubscriptionDTO {
@ -31,44 +32,120 @@ public class DeviceSubscriptionDTO {
private String actionTriggeredFrom;
private String status;
private int deviceId;
private int appReleaseId;
private String appUuid;
public int getId() { return id; }
public DeviceSubscriptionDTO() {
public void setId(int id) { this.id = id; }
}
public DeviceSubscriptionDTO(int deviceId) {
this.deviceId = deviceId;
}
public DeviceSubscriptionDTO(int deviceId, String status) {
this.deviceId = deviceId;
this.status = status;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSubscribedBy() { return subscribedBy; }
public String getSubscribedBy() {
return subscribedBy;
}
public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; }
public void setSubscribedBy(String subscribedBy) {
this.subscribedBy = subscribedBy;
}
public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; }
public Timestamp getSubscribedTimestamp() {
return subscribedTimestamp;
}
public void setSubscribedTimestamp(Timestamp subscribedTimestamp) {
this.subscribedTimestamp = subscribedTimestamp;
}
public boolean isUnsubscribed() { return isUnsubscribed; }
public boolean isUnsubscribed() {
return isUnsubscribed;
}
public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; }
public void setUnsubscribed(boolean unsubscribed) {
isUnsubscribed = unsubscribed;
}
public String getUnsubscribedBy() { return unsubscribedBy; }
public String getUnsubscribedBy() {
return unsubscribedBy;
}
public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; }
public void setUnsubscribedBy(String unsubscribedBy) {
this.unsubscribedBy = unsubscribedBy;
}
public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; }
public Timestamp getUnsubscribedTimestamp() {
return unsubscribedTimestamp;
}
public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) {
this.unsubscribedTimestamp = unsubscribedTimestamp;
}
public String getActionTriggeredFrom() { return actionTriggeredFrom; }
public String getActionTriggeredFrom() {
return actionTriggeredFrom;
}
public void setActionTriggeredFrom(String actionTriggeredFrom) { this.actionTriggeredFrom = actionTriggeredFrom; }
public void setActionTriggeredFrom(String actionTriggeredFrom) {
this.actionTriggeredFrom = actionTriggeredFrom;
}
public String getStatus() { return status; }
public String getStatus() {
return status;
}
public void setStatus(String status) { this.status = status; }
public void setStatus(String status) {
this.status = status;
}
public int getDeviceId() { return deviceId; }
public int getDeviceId() {
return deviceId;
}
public void setDeviceId(int deviceId) { this.deviceId = deviceId; }
public void setDeviceId(int deviceId) {
this.deviceId = deviceId;
}
public int getAppReleaseId() {
return appReleaseId;
}
public void setAppReleaseId(int appReleaseId) {
this.appReleaseId = appReleaseId;
}
public String getAppUuid() {
return appUuid;
}
public void setAppUuid(String appUuid) {
this.appUuid = appUuid;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DeviceSubscriptionDTO that = (DeviceSubscriptionDTO) o;
return deviceId == that.deviceId;
}
@Override
public int hashCode() {
return Objects.hash(deviceId);
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult;
import java.util.Map;
public class DeviceSubscriptionResponseDTO {
private int deviceCount;
private Map<String, Double> statusPercentages;
private CategorizedSubscriptionResult devices;
public DeviceSubscriptionResponseDTO(int deviceCount, Map<String, Double> statusPercentages,
CategorizedSubscriptionResult devices) {
this.deviceCount = deviceCount;
this.statusPercentages = statusPercentages;
this.devices = devices;
}
public int getDeviceCount() {
return deviceCount;
}
public void setDeviceCount(int deviceCount) {
this.deviceCount = deviceCount;
}
public Map<String, Double> getStatusPercentages() {
return statusPercentages;
}
public void setStatusPercentages(Map<String, Double> statusPercentages) {
this.statusPercentages = statusPercentages;
}
public CategorizedSubscriptionResult getDevices() {
return devices;
}
public void setDevices(CategorizedSubscriptionResult devices) {
this.devices = devices;
}
}

@ -22,6 +22,7 @@ import java.sql.Timestamp;
public class GroupSubscriptionDTO {
private int id;
private String groupName;
private String subscribedBy;
private Timestamp subscribedTimestamp;
private boolean isUnsubscribed;
@ -29,6 +30,7 @@ public class GroupSubscriptionDTO {
private Timestamp unsubscribedTimestamp;
private String subscribedFrom;
private int groupdId;
private int appReleaseId;
public int getId() { return id; }
@ -61,4 +63,20 @@ public class GroupSubscriptionDTO {
public int getGroupdId() { return groupdId; }
public void setGroupdId(int groupdId) { this.groupdId = groupdId; }
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public int getAppReleaseId() {
return appReleaseId;
}
public void setAppReleaseId(int appReleaseId) {
this.appReleaseId = appReleaseId;
}
}

@ -18,51 +18,115 @@
package io.entgra.device.mgt.core.application.mgt.common.dto;
import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult;
import java.sql.Timestamp;
import java.util.Map;
public class RoleSubscriptionDTO {
private int id;
private String subscribedBy;
private Timestamp subscribedTimestamp;
private boolean isUnsubscribed;
private boolean unsubscribed;
private String unsubscribedBy;
private Timestamp unsubscribedTimestamp;
private String subscribedFrom;
private String roleName;
private int appReleaseId;
private int deviceCount;
private Map<String, Double> statusPercentages;
private CategorizedSubscriptionResult devices;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getSubscribedBy() { return subscribedBy; }
public String getSubscribedBy() {
return subscribedBy;
}
public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; }
public void setSubscribedBy(String subscribedBy) {
this.subscribedBy = subscribedBy;
}
public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; }
public Timestamp getSubscribedTimestamp() {
return subscribedTimestamp;
}
public void setSubscribedTimestamp(Timestamp subscribedTimestamp) {
this.subscribedTimestamp = subscribedTimestamp;
}
public boolean isUnsubscribed() { return isUnsubscribed; }
public boolean getUnsubscribed() {
return unsubscribed;
}
public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; }
public void setUnsubscribed(boolean unsubscribed) {
this.unsubscribed = unsubscribed;
}
public String getUnsubscribedBy() { return unsubscribedBy; }
public boolean isUnsubscribed() {
return isUnsubscribed;
}
public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; }
public String getUnsubscribedBy() {
return unsubscribedBy;
}
public void setUnsubscribedBy(String unsubscribedBy) {
this.unsubscribedBy = unsubscribedBy;
}
public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; }
public Timestamp getUnsubscribedTimestamp() {
return unsubscribedTimestamp;
}
public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) {
this.unsubscribedTimestamp = unsubscribedTimestamp;
}
public String getSubscribedFrom() { return subscribedFrom; }
public String getSubscribedFrom() {
return subscribedFrom;
}
public void setSubscribedFrom(String subscribedFrom) {
this.subscribedFrom = subscribedFrom;
}
public String getRoleName() {
return roleName;
}
public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; }
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleName() { return roleName; }
public int getAppReleaseId() {
return appReleaseId;
}
public void setAppReleaseId(int appReleaseId) {
this.appReleaseId = appReleaseId;
}
public int getDeviceCount() {
return deviceCount;
}
public void setDeviceCount(int deviceCount) {
this.deviceCount = deviceCount;
}
public Map<String, Double> getStatusPercentages() {
return statusPercentages;
}
public void setStatusPercentages(Map<String, Double> statusPercentages) {
this.statusPercentages = statusPercentages;
}
public CategorizedSubscriptionResult getDevices() {
return devices;
}
public void setDevices(CategorizedSubscriptionResult devices) {
this.devices = devices;
}
public void setRoleName(String roleName) { this.roleName = roleName; }
}

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
import java.util.List;
public class SubscriptionResponseDTO {
private String UUID;
private List<SubscriptionsDTO> subscriptions;
private List<DeviceOperationDTO> DevicesOperations;
public String getUUID() {
return UUID;
}
public void setUUID(String UUID) {
this.UUID = UUID;
}
public List<DeviceOperationDTO> getDevicesOperations() {
return DevicesOperations;
}
public void setDevicesOperations(List<DeviceOperationDTO> devicesOperations) {
DevicesOperations = devicesOperations;
}
public List<SubscriptionsDTO> getSubscriptions() {
return subscriptions;
}
public void setSubscriptions(List<SubscriptionsDTO> subscriptions) {
this.subscriptions = subscriptions;
}
}

@ -0,0 +1,62 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
public class SubscriptionStatisticDTO {
private int completedDeviceCount = 0;
private int pendingDevicesCount = 0;
private int failedDevicesCount = 0;
public void addToComplete(int count) {
completedDeviceCount += count;
}
public void addToPending(int count) {
pendingDevicesCount += count;
}
public void addToFailed(int count) {
failedDevicesCount += count ;
}
public int getCompletedDeviceCount() {
return completedDeviceCount;
}
public void setCompletedDeviceCount(int completedDeviceCount) {
this.completedDeviceCount = completedDeviceCount;
}
public int getPendingDevicesCount() {
return pendingDevicesCount;
}
public void setPendingDevicesCount(int pendingDevicesCount) {
this.pendingDevicesCount = pendingDevicesCount;
}
public int getFailedDevicesCount() {
return failedDevicesCount;
}
public void setFailedDevicesCount(int failedDevicesCount) {
this.failedDevicesCount = failedDevicesCount;
}
}

@ -0,0 +1,162 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.application.mgt.common.dto;
import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult;
import java.sql.Timestamp;
import java.util.Map;
public class SubscriptionsDTO {
private int id;
private String owner;
private String name;
private String subscribedBy;
private Timestamp subscribedTimestamp;
private boolean unsubscribed;
private String unsubscribedBy;
private Timestamp unsubscribedTimestamp;
private String subscribedFrom;
private int appReleaseId;
private int deviceCount;
private String deviceOwner;
private String deviceStatus;
private Map<String, Double> statusPercentages;
private CategorizedSubscriptionResult devices;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubscribedBy() {
return subscribedBy;
}
public void setSubscribedBy(String subscribedBy) {
this.subscribedBy = subscribedBy;
}
public Timestamp getSubscribedTimestamp() {
return subscribedTimestamp;
}
public void setSubscribedTimestamp(Timestamp subscribedTimestamp) {
this.subscribedTimestamp = subscribedTimestamp;
}
public String getUnsubscribedBy() {
return unsubscribedBy;
}
public void setUnsubscribedBy(String unsubscribedBy) {
this.unsubscribedBy = unsubscribedBy;
}
public Timestamp getUnsubscribedTimestamp() {
return unsubscribedTimestamp;
}
public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) {
this.unsubscribedTimestamp = unsubscribedTimestamp;
}
public String getSubscribedFrom() {
return subscribedFrom;
}
public void setSubscribedFrom(String subscribedFrom) {
this.subscribedFrom = subscribedFrom;
}
public int getAppReleaseId() {
return appReleaseId;
}
public void setAppReleaseId(int appReleaseId) {
this.appReleaseId = appReleaseId;
}
public int getDeviceCount() {
return deviceCount;
}
public void setDeviceCount(int deviceCount) {
this.deviceCount = deviceCount;
}
public String getDeviceOwner() {
return deviceOwner;
}
public void setDeviceOwner(String deviceOwner) {
this.deviceOwner = deviceOwner;
}
public String getDeviceStatus() {
return deviceStatus;
}
public void setDeviceStatus(String deviceStatus) {
this.deviceStatus = deviceStatus;
}
public Map<String, Double> getStatusPercentages() {
return statusPercentages;
}
public void setStatusPercentages(Map<String, Double> statusPercentages) {
this.statusPercentages = statusPercentages;
}
public CategorizedSubscriptionResult getDevices() {
return devices;
}
public void setDevices(CategorizedSubscriptionResult devices) {
this.devices = devices;
}
public boolean getUnsubscribed() {
return unsubscribed;
}
public void setUnsubscribed(boolean unsubscribed) {
this.unsubscribed = unsubscribed;
}
}

@ -546,5 +546,20 @@ public interface ApplicationManager {
* @throws ApplicationManagementException thrown if an error occurs when deleting data
*/
void deleteApplicationDataOfTenant(int tenantId) throws ApplicationManagementException;
/**
* Delete all application related data of a tenant by tenant Domain
*
* @param tenantDomain Domain of the Tenant
* @throws ApplicationManagementException thrown if an error occurs when deleting data
*/
void deleteApplicationDataByTenantDomain(String tenantDomain) throws ApplicationManagementException;
/**
* Delete all Application artifacts related to a tenant by Tenant Domain
*
* @param tenantDomain Domain of the Tenant
* @throws ApplicationManagementException thrown if an error occurs when deleting app folders
*/
void deleteApplicationArtifactsByTenantDomain(String tenantDomain) throws ApplicationManagementException;
}

@ -140,4 +140,14 @@ public interface ApplicationStorageManager {
* @throws ApplicationStorageManagementException thrown if
*/
void deleteAppFolderOfTenant(int tenantId) throws ApplicationStorageManagementException;
/**
* Get absolute path of a file describe by hashVal, folder, file name and tenantId
* @param hashVal Hash value of the application release.
* @param folderName Folder name file resides.
* @param fileName File name of the file.
* @param tenantId Tenant ID
* @return Absolute path
*/
String getAbsolutePathOfFile(String hashVal, String folderName, String fileName, int tenantId);
}

@ -18,11 +18,23 @@
package io.entgra.device.mgt.core.application.mgt.common.services;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse;
import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscription;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData;
import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionEntity;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionResponse;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionStatistics;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType;
import io.entgra.device.mgt.core.application.mgt.common.dto.CategorizedSubscriptionCountsDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionsDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionResponseDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
@ -194,7 +206,7 @@ public interface SubscriptionManager {
* application release for given UUID, if an error occurred while getting device details of subscribed device ids,
* if an error occurred while getting subscription details of given application release UUID.
*/
PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion)
CategorizedSubscriptionResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion)
throws ApplicationManagementException;
/***
@ -217,4 +229,57 @@ public interface SubscriptionManager {
* @throws {@link SubscriptionManagementException} Exception of the subscription management
*/
Activity getOperationAppDetails(String id) throws SubscriptionManagementException;
/**
* Get subscription data describes by {@link SubscriptionInfo} entity
* @param subscriptionInfo {@link SubscriptionInfo}
* @param limit Limit value
* @param offset Offset value
* @return {@link SubscriptionResponse}
* @throws ApplicationManagementException Throws when error encountered while getting subscription data
*/
SubscriptionResponse getSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException;
/**
* Get status based subscription data describes by {@link SubscriptionInfo} entity
* @param subscriptionInfo {@link SubscriptionInfo}
* @param limit Limit value
* @param offset Offset value
* @return {@link SubscriptionResponse}
* @throws ApplicationManagementException Throws when error encountered while getting subscription data
*/
SubscriptionResponse getStatusBaseSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException;
/**
* Get subscription statistics related data describes by the {@link SubscriptionInfo}
* @param subscriptionInfo {@link SubscriptionInfo}
* @return {@link SubscriptionStatistics}
* @throws ApplicationManagementException Throws when error encountered while getting statistics
*/
SubscriptionStatistics getStatistics(SubscriptionInfo subscriptionInfo) throws ApplicationManagementException;
/**
* This method is responsible for retrieving device subscription details related to the given UUID.
*
* @param deviceId the deviceId of the device that need to get operation details.
* @param uuid the UUID of the application release.
* @return {@link DeviceOperationDTO} which contains the details of device subscriptions.
* @throws SubscriptionManagementException if there is an error while fetching the details.
*/
List<DeviceOperationDTO> getSubscriptionOperationsByUUIDAndDeviceID(int deviceId, String uuid)
throws ApplicationManagementException;
/**
* This method is responsible for retrieving device counts details related to the given UUID.
*
* @param uuid the UUID of the application release.
* @return {@link List<CategorizedSubscriptionCountsDTO>} which contains counts of subscriptions
and unsubscription for each subscription type.
* @throws SubscriptionManagementException if there is an error while fetching the details.
*/
List<CategorizedSubscriptionCountsDTO> getSubscriptionCountsByUUID(String uuid)
throws ApplicationManagementException;
}

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>application-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -81,6 +81,7 @@
com.dd.*,
io.entgra.device.mgt.core.identity.jwt.client.extension.*,
io.entgra.device.mgt.core.apimgt.application.extension.*,
io.entgra.device.mgt.core.tenant.mgt.common.*,
org.apache.commons.httpclient,
org.apache.commons.httpclient.methods,
org.apache.commons.validator.routines
@ -389,6 +390,10 @@
<artifactId>org.wso2.carbon.tenant.mgt</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.tenant.mgt.common</artifactId>
</dependency>
</dependencies>
</project>

@ -18,8 +18,13 @@
package io.entgra.device.mgt.core.application.mgt.core.dao;
import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionEntity;
import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionStatisticDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionsDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
@ -312,4 +317,227 @@ public interface SubscriptionDAO {
* @throws ApplicationManagementDAOException thrown if an error occurs while deleting data
*/
void deleteScheduledSubscriptionByTenant(int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the details of group subscriptions related to a appReleaseId.
*
* @param appReleaseId the appReleaseId of the application release.
* @param unsubscribe the Status of the subscription.
* @param tenantId id of the current tenant.
* @param offset the offset for the data set
* @param limit the limit for the data set
* @return {@link GroupSubscriptionDTO} which contains the details of group subscriptions.
* @throws ApplicationManagementDAOException if connection establishment fails.
*/
List<SubscriptionEntity> getGroupsSubscriptionDetailsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit)
throws ApplicationManagementDAOException;
/**
* This method is used to get the details of user subscriptions related to a appReleaseId.
*
* @param appReleaseId the appReleaseId of the application release.
* @param unsubscribe the Status of the subscription.
* @param tenantId id of the current tenant.
* @param offset the offset for the data set
* @param limit the limit for the data set
* @return {@link SubscriptionsDTO} which contains the details of subscriptions.
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
List<SubscriptionEntity> getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId,
int offset, int limit) throws ApplicationManagementDAOException;
/**
* This method is used to get the details of role subscriptions related to a appReleaseId.
*
* @param appReleaseId the appReleaseId of the application release.
* @param unsubscribe the Status of the subscription.
* @param tenantId id of the current tenant.
* @param offset the offset for the data set
* @param limit the limit for the data set
* @return {@link SubscriptionsDTO} which contains the details of subscriptions.
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
List<SubscriptionEntity> getRoleSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit)
throws ApplicationManagementDAOException;
/**
* This method is used to get the details of device subscriptions related to a appReleaseId.
*
* @param appReleaseId the appReleaseId of the application release.
* @param unsubscribe the Status of the subscription.
* @param tenantId id of the current tenant.
* @param offset the offset for the data set
* @param limit the limit for the data set
* @return {@link DeviceSubscriptionDTO} which contains the details of device subscriptions.
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
List<DeviceSubscriptionDTO> getDeviceSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit)
throws ApplicationManagementDAOException;
/**
* This method is used to get the details of device subscriptions related to a UUID.
*
* @param appReleaseId the appReleaseId of the application release.
* @param deviceId the deviceId of the device that need to get operation details.
* @param tenantId id of the current tenant.
* @return {@link DeviceOperationDTO} which contains the details of device subscriptions.
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
List<DeviceOperationDTO> getSubscriptionOperationsByAppReleaseIDAndDeviceID(int appReleaseId, int deviceId, int tenantId)
throws ApplicationManagementDAOException;
/**
* This method is used to get the details of device subscriptions related to a UUID.
*
* @param appReleaseId the appReleaseId of the application release.
* @param unsubscribe the Status of the subscription.
* @param tenantId id of the current tenant.
* @param actionStatus Status of the action
* @param actionType type of the action
* @param actionTriggeredBy subscribed by
* @param deviceIds deviceIds deviceIds to retrieve data.
* @return {@link DeviceOperationDTO} which contains the details of device subscriptions.
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
List<DeviceSubscriptionDTO> getSubscriptionDetailsByDeviceIds(int appReleaseId, boolean unsubscribe, int tenantId,
List<Integer> deviceIds, List<String> actionStatus, String actionType,
String actionTriggeredBy, int limit, int offset) throws ApplicationManagementDAOException;
int getDeviceSubscriptionCount(int appReleaseId, boolean unsubscribe, int tenantId,
List<Integer> deviceIds, List<String> actionStatus, String actionType,
String actionTriggeredBy) throws ApplicationManagementDAOException;
/**
* This method is used to get the details of device subscriptions related to a UUID.
*
* @param appReleaseId the appReleaseId of the application release.
* @param unsubscribe the Status of the subscription.
* @param tenantId id of the current tenant.
* @param actionStatus Status of the action
* @param actionType type of the action
* @param actionTriggeredBy subscribed by
* @param offset the offset for the data set
* @param limit the limit for the data set
* @return {@link DeviceOperationDTO} which contains the details of device subscriptions.
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
List<DeviceSubscriptionDTO> getAllSubscriptionsDetails(int appReleaseId, boolean unsubscribe, int tenantId, List<String> actionStatus, String actionType,
String actionTriggeredBy, int offset, int limit) throws ApplicationManagementDAOException;
int getAllSubscriptionsCount(int appReleaseId, boolean unsubscribe, int tenantId,
List<String> actionStatus, String actionType, String actionTriggeredBy)
throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of all subscription types related to a UUID.
*
* @param appReleaseId the appReleaseId of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getAllSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of all unsubscription types related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getAllUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of device subscriptions related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getDeviceSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of device unsubscription related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getDeviceUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of group subscriptions related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getGroupSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of group unsubscription related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getGroupUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of role subscriptions related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getRoleSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of role unsubscription related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getRoleUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of user subscriptions related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getUserSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of user unsubscription related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int getUserUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException;
SubscriptionStatisticDTO getSubscriptionStatistic(List<Integer> deviceIds, boolean isUnsubscribed,
int tenantId, int appReleaseId) throws ApplicationManagementDAOException;
/**
* This method is used to get the counts of devices related to a UUID.
*
* @param appReleaseId the UUID of the application release.
* @param tenantId id of the current tenant.
* @param actionStatus categorized status.
* @param actionTriggeredFrom type of the action.
* @return {@link int} which contains the count of the subscription type
* @throws ApplicationManagementDAOException if connection establishment or SQL execution fails.
*/
int countSubscriptionsByStatus(int appReleaseId, int tenantId, String actionStatus, String actionTriggeredFrom) throws ApplicationManagementDAOException;
}

@ -178,7 +178,11 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
sql += "AND AP_APP_RELEASE.CURRENT_STATE = ? ";
}
if (deviceTypeId != -1) {
sql += "AND AP_APP.DEVICE_TYPE_ID = ? ";
sql += "AND (AP_APP.DEVICE_TYPE_ID = ? ";
if (filter.isWithWebApps()) {
sql += "OR AP_APP.DEVICE_TYPE_ID = 0 ";
}
sql += ") ";
}
if (filter.isNotRetired()) {
sql += "AND AP_APP.STATUS != 'RETIRED' ";
@ -309,7 +313,11 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
sql += " AND AP_APP_RELEASE.CURRENT_STATE = ?";
}
if (deviceTypeId != -1) {
sql += " AND AP_APP.DEVICE_TYPE_ID = ?";
sql += " AND (AP_APP.DEVICE_TYPE_ID = ? ";
if (filter.isWithWebApps()) {
sql += "OR AP_APP.DEVICE_TYPE_ID = 0 ";
}
sql += ") ";
}
if (filter.isNotRetired()) {
sql += " AND AP_APP.STATUS != 'RETIRED'";

@ -18,6 +18,8 @@
package io.entgra.device.mgt.core.application.mgt.core.dao.impl.subscription;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionEntity;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
@ -28,7 +30,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* This handles Application subscribing operations which are specific to Oracle.
@ -157,4 +161,379 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
throw new ApplicationManagementDAOException(msg, e);
}
}
// passed the required list for the action status
@Override
public List<DeviceSubscriptionDTO> getSubscriptionDetailsByDeviceIds(int appReleaseId, boolean unsubscribe, int tenantId,
List<Integer> deviceIds, List<String> actionStatus, String actionType,
String actionTriggeredBy, int limit, int offset) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting device subscriptions for the application release id " + appReleaseId
+ " and device ids " + deviceIds + " from the database");
}
if (deviceIds == null || deviceIds.isEmpty()) {
return Collections.emptyList();
}
try {
Connection conn = this.getDBConnection();
String subscriptionStatusTime = unsubscribe ? "DS.UNSUBSCRIBED_TIMESTAMP" : "DS.SUBSCRIBED_TIMESTAMP";
StringBuilder sql = new StringBuilder("SELECT "
+ "DS.ID AS ID, "
+ "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, "
+ "DS.SUBSCRIBED_TIMESTAMP AS SUBSCRIBED_AT, "
+ "DS.UNSUBSCRIBED AS IS_UNSUBSCRIBED, "
+ "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, "
+ "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, "
+ "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, "
+ "DS.STATUS AS STATUS, "
+ "DS.DM_DEVICE_ID AS DEVICE_ID "
+ "FROM AP_DEVICE_SUBSCRIPTION DS "
+ "WHERE DS.AP_APP_RELEASE_ID = ? "
+ "AND DS.UNSUBSCRIBED = ? "
+ "AND DS.TENANT_ID = ? "
+ "AND DS.DM_DEVICE_ID IN ("
+ deviceIds.stream().map(id -> "?").collect(Collectors.joining(",")) + ") ");
if (actionStatus != null && !actionStatus.isEmpty()) {
sql.append(" AND DS.STATUS IN (").
append(actionStatus.stream().map(status -> "?").collect(Collectors.joining(","))).append(") ");
}
if (actionType != null && !actionType.isEmpty()) {
sql.append(" AND DS.ACTION_TRIGGERED_FROM = ? ");
}
if (actionTriggeredBy != null && !actionTriggeredBy.isEmpty()) {
sql.append(" AND DS.SUBSCRIBED_BY LIKE ? ");
}
sql.append("ORDER BY ").append(subscriptionStatusTime).
append(" DESC ");
if (offset >= 0 && limit >= 0) {
sql.append("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
}
try (PreparedStatement ps = conn.prepareStatement(sql.toString())) {
int paramIdx = 1;
ps.setInt(paramIdx++, appReleaseId);
ps.setBoolean(paramIdx++, unsubscribe);
ps.setInt(paramIdx++, tenantId);
for (Integer deviceId : deviceIds) {
ps.setInt(paramIdx++, deviceId);
}
if (actionStatus != null && !actionStatus.isEmpty()) {
for (String status : actionStatus) {
ps.setString(paramIdx++, status);
}
}
if (actionType != null && !actionType.isEmpty()) {
ps.setString(paramIdx++, actionType);
}
if (actionTriggeredBy != null && !actionTriggeredBy.isEmpty()) {
ps.setString(paramIdx++, "%" + actionTriggeredBy + "%");
}
if (offset >= 0 && limit >= 0) {
ps.setInt(paramIdx++, offset);
ps.setInt(paramIdx, limit);
}
try (ResultSet rs = ps.executeQuery()) {
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved device subscriptions for application release id "
+ appReleaseId + " and device ids " + deviceIds);
}
List<DeviceSubscriptionDTO> subscriptions = new ArrayList<>();
while (rs.next()) {
DeviceSubscriptionDTO subscription = new DeviceSubscriptionDTO();
subscription.setId(rs.getInt("ID"));
subscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY"));
subscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT"));
subscription.setUnsubscribed(rs.getBoolean("IS_UNSUBSCRIBED"));
subscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY"));
subscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_AT"));
subscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM"));
subscription.setStatus(rs.getString("STATUS"));
subscription.setDeviceId(rs.getInt("DEVICE_ID"));
subscriptions.add(subscription);
}
return subscriptions;
}
} catch (SQLException e) {
String msg = "Error occurred while running SQL to get device subscription data for application ID: " + appReleaseId
+ " and device ids: " + deviceIds + ".";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection for getting device subscriptions for "
+ "application Id: " + appReleaseId + " and device ids: " + deviceIds + ".";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public List<SubscriptionEntity> getRoleSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset,
int limit) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get role subscriptions related to the given AppReleaseID.");
}
try {
Connection conn = this.getDBConnection();
List<SubscriptionEntity> subscriptionEntities = new ArrayList<>();
String subscriptionStatusTime = unsubscribe ? "ARS.UNSUBSCRIBED_TIMESTAMP" : "ARS.SUBSCRIBED_TIMESTAMP";
String sql = "SELECT ARS.ROLE_NAME, " +
"ARS.SUBSCRIBED_BY, " +
"ARS.SUBSCRIBED_TIMESTAMP, " +
"ARS.UNSUBSCRIBED, " +
"ARS.UNSUBSCRIBED_BY, " +
"ARS.UNSUBSCRIBED_TIMESTAMP, " +
"ARS.AP_APP_RELEASE_ID " +
"FROM AP_ROLE_SUBSCRIPTION ARS " +
"WHERE ARS.AP_APP_RELEASE_ID = ? " +
"AND ARS.UNSUBSCRIBED = ? " +
"AND ARS.TENANT_ID = ? " +
"ORDER BY " + subscriptionStatusTime + " DESC " +
"OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId);
ps.setBoolean(2, unsubscribe);
ps.setInt(3, tenantId);
ps.setInt(4, offset);
ps.setInt(5, limit);
try (ResultSet rs = ps.executeQuery()) {
SubscriptionEntity subscriptionEntity;
while (rs.next()) {
subscriptionEntity = new SubscriptionEntity();
subscriptionEntity.setIdentity(rs.getString("ROLE_NAME"));
subscriptionEntity.setSubscribedBy(rs.getString("SUBSCRIBED_BY"));
subscriptionEntity.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP"));
subscriptionEntity.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED"));
subscriptionEntity.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY"));
subscriptionEntity.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP"));
subscriptionEntity.setApplicationReleaseId(rs.getInt("AP_APP_RELEASE_ID"));
subscriptionEntities.add(subscriptionEntity);
}
}
return subscriptionEntities;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get role subscriptions for the given UUID.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "SQL Error occurred while getting role subscriptions for the given UUID.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public List<SubscriptionEntity> getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId,
int offset, int limit) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get user subscriptions related to the given UUID.");
}
try {
Connection conn = this.getDBConnection();
List<SubscriptionEntity> subscriptionEntities = new ArrayList<>();
String subscriptionStatusTime = unsubscribe ? "US.UNSUBSCRIBED_TIMESTAMP" : "US.SUBSCRIBED_TIMESTAMP";
String sql = "SELECT US.USER_NAME, " +
"US.SUBSCRIBED_BY, " +
"US.SUBSCRIBED_TIMESTAMP, " +
"US.UNSUBSCRIBED, " +
"US.UNSUBSCRIBED_BY, " +
"US.UNSUBSCRIBED_TIMESTAMP, " +
"US.AP_APP_RELEASE_ID " +
"FROM AP_USER_SUBSCRIPTION US " +
"WHERE US.AP_APP_RELEASE_ID = ? " +
"AND US.UNSUBSCRIBED = ? " +
"AND US.TENANT_ID = ? " +
"ORDER BY " + subscriptionStatusTime + " DESC " +
"OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId);
ps.setBoolean(2, unsubscribe);
ps.setInt(3, tenantId);
ps.setInt(4, offset);
ps.setInt(5, limit);
try (ResultSet rs = ps.executeQuery()) {
SubscriptionEntity subscriptionEntity;
while (rs.next()) {
subscriptionEntity = new SubscriptionEntity();
subscriptionEntity.setIdentity(rs.getString("USER_NAME"));
subscriptionEntity.setSubscribedBy(rs.getString("SUBSCRIBED_BY"));
subscriptionEntity.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP"));
subscriptionEntity.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED"));
subscriptionEntity.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY"));
subscriptionEntity.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP"));
subscriptionEntity.setApplicationReleaseId(rs.getInt("AP_APP_RELEASE_ID"));
subscriptionEntities.add(subscriptionEntity);
}
}
return subscriptionEntities;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get user subscriptions for the given UUID.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "SQL Error occurred while getting user subscriptions for the given UUID.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public List<SubscriptionEntity> getGroupsSubscriptionDetailsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit)
throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get groups related to the given AppReleaseID.");
}
try {
Connection conn = this.getDBConnection();
List<SubscriptionEntity> subscriptionEntities = new ArrayList<>();
String subscriptionStatusTime = unsubscribe ? "GS.UNSUBSCRIBED_TIMESTAMP" : "GS.SUBSCRIBED_TIMESTAMP";
String sql = "SELECT GS.GROUP_NAME, " +
"GS.SUBSCRIBED_BY, " +
"GS.SUBSCRIBED_TIMESTAMP, " +
"GS.UNSUBSCRIBED, " +
"GS.UNSUBSCRIBED_BY, " +
"GS.UNSUBSCRIBED_TIMESTAMP, " +
"GS.AP_APP_RELEASE_ID " +
"FROM AP_GROUP_SUBSCRIPTION GS " +
"WHERE GS.AP_APP_RELEASE_ID = ? " +
"AND GS.UNSUBSCRIBED = ? AND GS.TENANT_ID = ? " +
"ORDER BY " + subscriptionStatusTime + " DESC " +
"OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId);
ps.setBoolean(2, unsubscribe);
ps.setInt(3, tenantId);
ps.setInt(4, offset);
ps.setInt(5, limit);
try (ResultSet rs = ps.executeQuery()) {
SubscriptionEntity subscriptionEntity;
while (rs.next()) {
subscriptionEntity = new SubscriptionEntity();
subscriptionEntity.setIdentity(rs.getString("GROUP_NAME"));
subscriptionEntity.setSubscribedBy(rs.getString("SUBSCRIBED_BY"));
subscriptionEntity.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP"));
subscriptionEntity.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED"));
subscriptionEntity.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY"));
subscriptionEntity.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP"));
subscriptionEntity.setApplicationReleaseId(rs.getInt("AP_APP_RELEASE_ID"));
subscriptionEntities.add(subscriptionEntity);
}
}
return subscriptionEntities;
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get groups for the given UUID.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "SQL Error occurred while getting groups for the given UUID.";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
@Override
public List<DeviceSubscriptionDTO> getAllSubscriptionsDetails(int appReleaseId, boolean unsubscribe, int tenantId,
List<String> actionStatus, String actionType, String actionTriggeredBy,
int offset, int limit) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting device subscriptions for the application release id " + appReleaseId + " from the database");
}
String subscriptionStatusTime = unsubscribe ? "DS.UNSUBSCRIBED_TIMESTAMP" : "DS.SUBSCRIBED_TIMESTAMP";
String actionTriggeredColumn = unsubscribe ? "DS.UNSUBSCRIBED_BY" : "DS.SUBSCRIBED_BY";
StringBuilder sql = new StringBuilder("SELECT "
+ "DS.ID AS ID, "
+ "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, "
+ "DS.SUBSCRIBED_TIMESTAMP AS SUBSCRIBED_AT, "
+ "DS.UNSUBSCRIBED AS IS_UNSUBSCRIBED, "
+ "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, "
+ "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, "
+ "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, "
+ "DS.STATUS AS STATUS, "
+ "DS.DM_DEVICE_ID AS DEVICE_ID "
+ "FROM AP_DEVICE_SUBSCRIPTION DS "
+ "WHERE DS.AP_APP_RELEASE_ID = ? "
+ "AND DS.UNSUBSCRIBED = ? "
+ "AND DS.TENANT_ID = ? ");
if (actionStatus != null && !actionStatus.isEmpty()) {
sql.append(" AND DS.STATUS IN (")
.append(actionStatus.stream().map(status -> "?").collect(Collectors.joining(","))).append(") ");
}
if (actionType != null && !actionType.isEmpty()) {
sql.append(" AND DS.ACTION_TRIGGERED_FROM = ? ");
}
if (actionTriggeredBy != null && !actionTriggeredBy.isEmpty()) {
sql.append(" AND ").append(actionTriggeredColumn).append(" LIKE ? ");
}
sql.append("ORDER BY ").append(subscriptionStatusTime).append(" DESC ");
if (limit >= 0 && offset >= 0) {
sql.append("OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
}
try {
Connection conn = this.getDBConnection();
try (PreparedStatement ps = conn.prepareStatement(sql.toString())) {
int paramIdx = 1;
ps.setInt(paramIdx++, appReleaseId);
ps.setBoolean(paramIdx++, unsubscribe);
ps.setInt(paramIdx++, tenantId);
if (actionStatus != null && !actionStatus.isEmpty()) {
for (String status : actionStatus) {
ps.setString(paramIdx++, status);
}
}
if (actionType != null && !actionType.isEmpty()) {
ps.setString(paramIdx++, actionType);
}
if (actionTriggeredBy != null && !actionTriggeredBy.isEmpty()) {
ps.setString(paramIdx++, "%" + actionTriggeredBy + "%");
}
if (limit >= 0 && offset >= 0) {
ps.setInt(paramIdx++, offset);
ps.setInt(paramIdx, limit);
}
try (ResultSet rs = ps.executeQuery()) {
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved device subscriptions for application release id "
+ appReleaseId);
}
List<DeviceSubscriptionDTO> deviceSubscriptions = new ArrayList<>();
while (rs.next()) {
DeviceSubscriptionDTO subscription = new DeviceSubscriptionDTO();
subscription.setId(rs.getInt("ID"));
subscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY"));
subscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT"));
subscription.setUnsubscribed(rs.getBoolean("IS_UNSUBSCRIBED"));
subscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY"));
subscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_AT"));
subscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM"));
subscription.setStatus(rs.getString("STATUS"));
subscription.setDeviceId(rs.getInt("DEVICE_ID"));
deviceSubscriptions.add(subscription);
}
return deviceSubscriptions;
}
}
} catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection for getting device subscription for application Id: "
+ appReleaseId + ".";
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while running SQL to get device subscription data for application ID: " + appReleaseId;
log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e);
}
}
}

@ -30,6 +30,7 @@ import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.app.mgt.App;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.tenant.mgt.common.exception.TenantMgtException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
@ -96,17 +97,19 @@ import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementEx
import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceType;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.stratos.common.beans.TenantInfoBean;
import org.wso2.carbon.tenant.mgt.services.TenantMgtAdminService;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import javax.ws.rs.core.Response;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -723,24 +726,29 @@ public class ApplicationManagerImpl implements ApplicationManager {
* @throws ResourceManagementException if error occurred while uploading
*/
private ApplicationReleaseDTO uploadCustomAppReleaseArtifacts(ApplicationReleaseDTO releaseDTO, ApplicationArtifact applicationArtifact,
String deviceType)
String deviceType)
throws ResourceManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager();
byte[] content = getByteContentOfApp(applicationArtifact);
String md5OfApp = generateMD5OfApp(applicationArtifact, content);
validateReleaseBinaryFileHash(md5OfApp);
releaseDTO.setUuid(UUID.randomUUID().toString());
releaseDTO.setAppHashValue(md5OfApp);
releaseDTO.setInstallerName(applicationArtifact.getInstallerName());
try {
String md5OfApp = applicationStorageManager.
getMD5(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())));
validateReleaseBinaryFileHash(md5OfApp);
releaseDTO.setUuid(UUID.randomUUID().toString());
releaseDTO.setAppHashValue(md5OfApp);
releaseDTO.setInstallerName(applicationArtifact.getInstallerName());
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
applicationStorageManager.uploadReleaseArtifact(releaseDTO, deviceType,
binaryDuplicate, tenantId);
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), tenantId);
} catch (IOException e) {
String msg = "Error occurred when uploading release artifact into the server";
log.error(msg);
throw new ApplicationManagementException(msg, e);
} catch (StorageManagementException e) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ releaseDTO.getUuid();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
return addImageArtifacts(releaseDTO, applicationArtifact, tenantId);
}
@ -769,6 +777,8 @@ public class ApplicationManagerImpl implements ApplicationManager {
return Constants.GOOGLE_PLAY_STORE_URL;
} else if (DeviceTypes.IOS.toString().equalsIgnoreCase(deviceType)) {
return Constants.APPLE_STORE_URL;
} else if (DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
return Constants.MICROSOFT_STORE_URL;
} else {
throw new IllegalArgumentException("No such device with the name " + deviceType);
}
@ -856,82 +866,77 @@ public class ApplicationManagerImpl implements ApplicationManager {
String uuid = UUID.randomUUID().toString();
applicationReleaseDTO.setUuid(uuid);
// The application executable artifacts such as apks are uploaded.
try {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName());
try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) {
if (!DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
ApplicationInstaller applicationInstaller = applicationStorageManager
.getAppInstallerData(binary, deviceType);
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
applicationReleaseDTO.setPackageName(applicationInstaller.getPackageName());
} else {
String windowsInstallerName = applicationArtifact.getInstallerName();
String extension = windowsInstallerName.substring(windowsInstallerName.lastIndexOf(".") + 1);
if (!extension.equalsIgnoreCase(Constants.MSI) &&
!extension.equalsIgnoreCase(Constants.APPX)) {
String msg = "Application Type doesn't match with supporting application types of " +
deviceType + "platform which are APPX and MSI";
log.error(msg);
throw new BadRequestException(msg);
}
if (!DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
ApplicationInstaller applicationInstaller = applicationStorageManager
.getAppInstallerData(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), deviceType);
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
applicationReleaseDTO.setPackageName(applicationInstaller.getPackageName());
} else {
String windowsInstallerName = applicationArtifact.getInstallerName();
String extension = windowsInstallerName.substring(windowsInstallerName.lastIndexOf(".") + 1);
if (!extension.equalsIgnoreCase(Constants.MSI) &&
!extension.equalsIgnoreCase(Constants.APPX)) {
String msg = "Application Type doesn't match with supporting application types of " +
deviceType + "platform which are APPX and MSI";
log.error(msg);
throw new BadRequestException(msg);
}
}
String packageName = applicationReleaseDTO.getPackageName();
try {
ConnectionManagerUtil.openDBConnection();
if (!isNewRelease && applicationReleaseDAO
.isActiveReleaseExisitForPackageName(packageName, tenantId,
lifecycleStateManager.getEndState())) {
String msg = "Application release is already exist for the package name: " + packageName
+ ". Either you can delete all application releases for package " + packageName + " or "
+ "you can add this app release as an new application release, under the existing "
+ "application.";
log.error(msg);
throw new ApplicationManagementException(msg);
}
String md5OfApp = applicationStorageManager.getMD5(new ByteArrayInputStream(content));
if (md5OfApp == null) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ applicationReleaseDTO.getUuid();
log.error(msg);
throw new ApplicationStorageManagementException(msg);
}
if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) {
String msg =
"Application release exists for the uploaded binary file. Device Type: " + deviceType;
log.error(msg);
throw new BadRequestException(msg);
}
applicationReleaseDTO.setAppHashValue(md5OfApp);
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
applicationStorageManager
.uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate, tenantId);
}
} catch (StorageManagementException e) {
String packageName = applicationReleaseDTO.getPackageName();
try {
ConnectionManagerUtil.openDBConnection();
if (!isNewRelease && applicationReleaseDAO
.isActiveReleaseExisitForPackageName(packageName, tenantId,
lifecycleStateManager.getEndState())) {
String msg = "Application release is already exist for the package name: " + packageName
+ ". Either you can delete all application releases for package " + packageName + " or "
+ "you can add this app release as an new application release, under the existing "
+ "application.";
log.error(msg);
throw new ApplicationManagementException(msg);
}
String md5OfApp = applicationStorageManager.
getMD5(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())));
if (md5OfApp == null) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ applicationReleaseDTO.getUuid();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying app release data.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
log.error(msg);
throw new ApplicationStorageManagementException(msg);
}
if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) {
String msg =
"Error occurred when executing the query for verifying application release existence for "
+ "the package.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
"Application release exists for the uploaded binary file. Device Type: " + deviceType;
log.error(msg);
throw new BadRequestException(msg);
}
applicationReleaseDTO.setAppHashValue(md5OfApp);
applicationStorageManager
.uploadReleaseArtifact(applicationReleaseDTO, deviceType,
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), tenantId);
} catch (StorageManagementException e) {
String msg = "Error occurred while md5sum value retrieving process: application UUID "
+ applicationReleaseDTO.getUuid();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying app release data.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg =
"Error occurred when executing the query for verifying application release existence for "
+ "the package.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
} catch (IOException e) {
String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact
String msg = "Error occurred when getting file input stream. Installer name: " + applicationArtifact
.getInstallerName();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
@ -957,73 +962,64 @@ public class ApplicationManagerImpl implements ApplicationManager {
// The application executable artifacts such as apks are uploaded.
try {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) {
String md5OfApp = applicationStorageManager.getMD5(binaryClone);
if (md5OfApp == null) {
String msg = "Error occurred while retrieving md5sum value from the binary file for application "
+ "release UUID " + applicationReleaseDTO.getUuid();
log.error(msg);
throw new ApplicationStorageManagementException(msg);
}
if (!applicationReleaseDTO.getAppHashValue().equals(md5OfApp)) {
applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName());
String md5OfApp = applicationStorageManager.getMD5(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())));
if (md5OfApp == null) {
String msg = "Error occurred while retrieving md5sum value from the binary file for application "
+ "release UUID " + applicationReleaseDTO.getUuid();
log.error(msg);
throw new ApplicationStorageManagementException(msg);
}
try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) {
ApplicationInstaller applicationInstaller = applicationStorageManager
.getAppInstallerData(binary, deviceType);
String packageName = applicationInstaller.getPackageName();
if (!applicationReleaseDTO.getAppHashValue().equals(md5OfApp)) {
applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName());
ApplicationInstaller applicationInstaller = applicationStorageManager
.getAppInstallerData(Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), deviceType);
String packageName = applicationInstaller.getPackageName();
try {
ConnectionManagerUtil.getDBConnection();
if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) {
String msg = "Same binary file is in the server. Hence you can't add same file into the "
+ "server. Device Type: " + deviceType + " and package name: " + packageName;
log.error(msg);
throw new BadRequestException(msg);
}
if (applicationReleaseDTO.getPackageName() == null){
String msg = "Found null value for application release package name for application "
+ "release which has UUID: " + applicationReleaseDTO.getUuid();
log.error(msg);
throw new ApplicationManagementException(msg);
}
if (!applicationReleaseDTO.getPackageName().equals(packageName)){
String msg = "Package name of the new artifact does not match with the package name of "
+ "the exiting application release. Package name of the existing app release "
+ applicationReleaseDTO.getPackageName() + " and package name of the new "
+ "application release " + packageName;
log.error(msg);
throw new BadRequestException(msg);
}
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
applicationReleaseDTO.setPackageName(packageName);
String deletingAppHashValue = applicationReleaseDTO.getAppHashValue();
applicationReleaseDTO.setAppHashValue(md5OfApp);
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
applicationStorageManager
.uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate,
tenantId);
applicationStorageManager.copyImageArtifactsAndDeleteInstaller(deletingAppHashValue,
applicationReleaseDTO, tenantId);
}
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying application "
+ "release existing for new app hash value.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred when executing the query for verifying application release "
+ "existence for the new app hash value.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
try {
ConnectionManagerUtil.getDBConnection();
if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) {
String msg = "Same binary file is in the server. Hence you can't add same file into the "
+ "server. Device Type: " + deviceType + " and package name: " + packageName;
log.error(msg);
throw new BadRequestException(msg);
}
if (applicationReleaseDTO.getPackageName() == null) {
String msg = "Found null value for application release package name for application "
+ "release which has UUID: " + applicationReleaseDTO.getUuid();
log.error(msg);
throw new ApplicationManagementException(msg);
}
if (!applicationReleaseDTO.getPackageName().equals(packageName)) {
String msg = "Package name of the new artifact does not match with the package name of "
+ "the exiting application release. Package name of the existing app release "
+ applicationReleaseDTO.getPackageName() + " and package name of the new "
+ "application release " + packageName;
log.error(msg);
throw new BadRequestException(msg);
}
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
applicationReleaseDTO.setPackageName(packageName);
String deletingAppHashValue = applicationReleaseDTO.getAppHashValue();
applicationReleaseDTO.setAppHashValue(md5OfApp);
applicationStorageManager.uploadReleaseArtifact(applicationReleaseDTO, deviceType,
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())),
tenantId);
applicationStorageManager.copyImageArtifactsAndDeleteInstaller(deletingAppHashValue,
applicationReleaseDTO, tenantId);
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying application "
+ "release existing for new app hash value.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred when executing the query for verifying application release "
+ "existence for the new app hash value.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
} catch (StorageManagementException e) {
@ -1032,7 +1028,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
} catch (IOException e) {
String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact
String msg = "Error occurred when getting file input stream. Installer name: " + applicationArtifact
.getInstallerName();
log.error(msg, e);
throw new ApplicationStorageManagementException(msg, e);
@ -3607,52 +3603,49 @@ public class ApplicationManagerImpl implements ApplicationManager {
DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId());
// The application executable artifacts such as deb are uploaded.
try {
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
try (ByteArrayInputStream binaryClone = new ByteArrayInputStream(content)) {
String md5OfApp = applicationStorageManager.getMD5(binaryClone);
if (md5OfApp == null) {
String msg = "Error occurred while retrieving md5sum value from the binary file for "
+ "application release UUID " + applicationReleaseDTO.get().getUuid();
log.error(msg);
throw new ApplicationStorageManagementException(msg);
}
if (!applicationReleaseDTO.get().getAppHashValue().equals(md5OfApp)) {
try {
ConnectionManagerUtil.getDBConnection();
if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) {
String msg =
"Same binary file is in the server. Hence you can't add same file into the "
+ "server. Device Type: " + deviceTypeObj.getName()
+ " and package name: " + applicationDTO.getApplicationReleaseDTOs()
.get(0).getPackageName();
log.error(msg);
throw new BadRequestException(msg);
}
String md5OfApp = applicationStorageManager.getMD5(
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())));
if (md5OfApp == null) {
String msg = "Error occurred while retrieving md5sum value from the binary file for "
+ "application release UUID " + applicationReleaseDTO.get().getUuid();
log.error(msg);
throw new ApplicationStorageManagementException(msg);
}
applicationReleaseDTO.get().setInstallerName(applicationArtifact.getInstallerName());
String deletingAppHashValue = applicationReleaseDTO.get().getAppHashValue();
applicationReleaseDTO.get().setAppHashValue(md5OfApp);
try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) {
applicationStorageManager
.uploadReleaseArtifact(applicationReleaseDTO.get(), deviceTypeObj.getName(),
binaryDuplicate, tenantId);
applicationStorageManager.copyImageArtifactsAndDeleteInstaller(deletingAppHashValue,
applicationReleaseDTO.get(), tenantId);
}
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying application"
+ " release existing for new app hash value.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
if (!applicationReleaseDTO.get().getAppHashValue().equals(md5OfApp)) {
try {
ConnectionManagerUtil.getDBConnection();
if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) {
String msg =
"Error occurred when executing the query for verifying application release "
+ "existence for the new app hash value.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
"Same binary file is in the server. Hence you can't add same file into the "
+ "server. Device Type: " + deviceTypeObj.getName()
+ " and package name: " + applicationDTO.getApplicationReleaseDTOs()
.get(0).getPackageName();
log.error(msg);
throw new BadRequestException(msg);
}
applicationReleaseDTO.get().setInstallerName(applicationArtifact.getInstallerName());
String deletingAppHashValue = applicationReleaseDTO.get().getAppHashValue();
applicationReleaseDTO.get().setAppHashValue(md5OfApp);
applicationStorageManager.
uploadReleaseArtifact(applicationReleaseDTO.get(), deviceTypeObj.getName(),
Files.newInputStream(Paths.get(applicationArtifact.getInstallerPath())), tenantId);
applicationStorageManager.copyImageArtifactsAndDeleteInstaller(deletingAppHashValue,
applicationReleaseDTO.get(), tenantId);
} catch (DBConnectionException e) {
String msg = "Error occurred when getting database connection for verifying application"
+ " release existing for new app hash value.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg =
"Error occurred when executing the query for verifying application release "
+ "existence for the new app hash value.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
} catch (StorageManagementException e) {
@ -4424,7 +4417,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
spApplicationDAO.deleteSPApplicationMappingByTenant(tenantId);
spApplicationDAO.deleteIdentityServerByTenant(tenantId);
applicationDAO.deleteApplicationsByTenant(tenantId);
APIUtil.getApplicationStorageManager().deleteAppFolderOfTenant(tenantId);
ConnectionManagerUtil.commitDBTransaction();
} catch (DBConnectionException e) {
@ -4449,12 +4441,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
+ " of tenant ID: " + tenantId ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationStorageManagementException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while deleting App folder of tenant"
+ " of tenant ID: " + tenantId ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
@ -4463,19 +4449,9 @@ public class ApplicationManagerImpl implements ApplicationManager {
@Override
public void deleteApplicationDataByTenantDomain(String tenantDomain) throws ApplicationManagementException {
int tenantId;
try{
TenantMgtAdminService tenantMgtAdminService = new TenantMgtAdminService();
TenantInfoBean tenantInfoBean = tenantMgtAdminService.getTenant(tenantDomain);
tenantId = tenantInfoBean.getTenantId();
} catch (Exception e) {
String msg = "Error getting tenant ID from domain: "
+ tenantDomain;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
try {
tenantId = DataHolder.getInstance().getTenantManagerAdminService().getTenantId(tenantDomain);
ConnectionManagerUtil.beginDBTransaction();
vppApplicationDAO.deleteAssociationByTenant(tenantId);
@ -4499,40 +4475,54 @@ public class ApplicationManagerImpl implements ApplicationManager {
spApplicationDAO.deleteSPApplicationMappingByTenant(tenantId);
spApplicationDAO.deleteIdentityServerByTenant(tenantId);
applicationDAO.deleteApplicationsByTenant(tenantId);
APIUtil.getApplicationStorageManager().deleteAppFolderOfTenant(tenantId);
ConnectionManagerUtil.commitDBTransaction();
} catch (DBConnectionException e) {
String msg = "Error occurred while observing the database connection to delete applications for tenant with ID: "
+ tenantId;
String msg = "Error occurred while observing the database connection to delete applications for tenant with " +
"domain: " + tenantDomain;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Database access error is occurred when getting applications for tenant with ID: " + tenantId;
String msg = "Database access error is occurred when getting applications for tenant with domain: "
+ tenantDomain;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (LifeCycleManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while deleting life-cycle state data of application releases of the tenant"
+ " of ID: " + tenantId ;
+ " of domain: " + tenantDomain ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ReviewManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while deleting reviews of application releases of the applications"
+ " of tenant ID: " + tenantId ;
+ " of tenant of domain: " + tenantDomain ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationStorageManagementException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while deleting App folder of tenant"
+ " of tenant ID: " + tenantId ;
} catch (Exception e) {
String msg = "Error getting tenant ID from domain: "
+ tenantDomain;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public void deleteApplicationArtifactsByTenantDomain(String tenantDomain) throws ApplicationManagementException {
int tenantId;
try {
tenantId = DataHolder.getInstance().getTenantManagerAdminService().getTenantId(tenantDomain);
DataHolder.getInstance().getApplicationStorageManager().deleteAppFolderOfTenant(tenantId);
} catch (ApplicationStorageManagementException e) {
String msg = "Error deleting app artifacts of tenant of domain: " + tenantDomain ;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TenantMgtException e) {
String msg = "Error getting tenant ID from domain: "
+ tenantDomain + " when trying to delete application artifacts of tenant";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
}

@ -37,6 +37,7 @@ import io.entgra.device.mgt.core.device.mgt.core.common.exception.StorageManagem
import io.entgra.device.mgt.core.device.mgt.core.common.util.StorageManagementUtil;
import java.io.*;
import java.nio.file.Paths;
import java.util.List;
import static io.entgra.device.mgt.core.device.mgt.core.common.util.StorageManagementUtil.saveFile;
@ -155,13 +156,12 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager
public void uploadReleaseArtifact(ApplicationReleaseDTO applicationReleaseDTO,
String deviceType, InputStream binaryFile, int tenantId) throws ResourceManagementException {
try {
byte [] content = IOUtils.toByteArray(binaryFile);
String artifactDirectoryPath =
storagePath + tenantId + File.separator + applicationReleaseDTO.getAppHashValue() + File.separator
+ Constants.APP_ARTIFACT;
StorageManagementUtil.createArtifactDirectory(artifactDirectoryPath);
String artifactPath = artifactDirectoryPath + File.separator + applicationReleaseDTO.getInstallerName();
saveFile(new ByteArrayInputStream(content), artifactPath);
saveFile(binaryFile, artifactPath);
} catch (IOException e) {
String msg = "IO Exception while saving the release artifacts in the server for the application UUID "
+ applicationReleaseDTO.getUuid();
@ -324,4 +324,12 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager
}
}
}
@Override
public String getAbsolutePathOfFile(String hashVal, String folderName, String fileName, int tenantId) {
String filePath =
storagePath + tenantId + File.separator + hashVal + File.separator + folderName + File.separator
+ fileName;
return Paths.get(filePath).toAbsolutePath().toString();
}
}

@ -31,6 +31,7 @@ import io.entgra.device.mgt.core.device.mgt.common.exceptions.NotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.FileSystems;
@ -103,8 +104,13 @@ public class FileTransferServiceImpl implements FileTransferService {
@Override
public boolean isExistsOnLocal(URL downloadUrl) throws FileTransferServiceException {
try {
return FileTransferServiceHelperUtil.resolve(downloadUrl) != null;
} catch (FileTransferServiceHelperUtilException e) {
FileDescriptor fileDescriptor = FileTransferServiceHelperUtil.resolve(downloadUrl);
if (fileDescriptor != null && fileDescriptor.getFile() != null) {
fileDescriptor.getFile().close();
return true;
}
return false;
} catch (FileTransferServiceHelperUtilException | IOException e) {
String msg = "Error occurred while checking the existence of artifact on the local environment";
log.error(msg, e);
throw new FileTransferServiceException(msg, e);

@ -19,17 +19,42 @@
package io.entgra.device.mgt.core.application.mgt.core.impl;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationType;
import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionResponse;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionStatistics;
import io.entgra.device.mgt.core.application.mgt.common.dto.CategorizedSubscriptionCountsDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO;
import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes;
import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus;
import io.entgra.device.mgt.core.application.mgt.common.SubAction;
import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO;
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationReleaseDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.SubscriptionManagementServiceProvider;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.service.SubscriptionManagementHelperService;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants;
import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException;
import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO;
import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger;
import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext;
import io.entgra.device.mgt.core.notification.logger.impl.EntgraAppInstallLoggerImpl;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
@ -45,20 +70,6 @@ import org.json.JSONObject;
import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey;
import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.ApplicationType;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData;
import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes;
import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus;
import io.entgra.device.mgt.core.application.mgt.common.SubAction;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType;
import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.common.exception.LifecycleManagementException;
@ -131,12 +142,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
private SubscriptionDAO subscriptionDAO;
private ApplicationDAO applicationDAO;
private VppApplicationDAO vppApplicationDAO;
private ApplicationReleaseDAO applicationReleaseDAO;
private LifecycleStateManager lifecycleStateManager;
public SubscriptionManagerImpl() {
this.lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager();
this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO();
this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO();
this.applicationReleaseDAO = ApplicationManagementDAOFactory.getApplicationReleaseDAO();
this.vppApplicationDAO = ApplicationManagementDAOFactory.getVppApplicationDAO();
}
@ -1505,16 +1518,19 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
}
@Override
public PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus,
String action, String installedVersion) throws ApplicationManagementException {
public CategorizedSubscriptionResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus,
String action, String installedVersion) throws ApplicationManagementException {
int limitValue = request.getRowCount();
int offsetValue = request.getStartIndex();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
DeviceManagementProviderService deviceManagementProviderService = HelperUtil
.getDeviceManagementProviderService();
DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService();
List<DeviceSubscriptionData> installedDevices = new ArrayList<>();
List<DeviceSubscriptionData> pendingDevices = new ArrayList<>();
List<DeviceSubscriptionData> errorDevices = new ArrayList<>();
if (offsetValue < 0 || limitValue <= 0) {
String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. "
+ "Offset " + offsetValue + " limit " + limitValue;
String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. " +
"Offset " + offsetValue + " limit " + limitValue;
log.error(msg);
throw new BadRequestException(msg);
}
@ -1532,31 +1548,26 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = subscriptionDAO
.getDeviceSubscriptions(applicationReleaseId, tenantId, actionStatus, action);
if (deviceSubscriptionDTOS.isEmpty()) {
PaginationResult paginationResult = new PaginationResult();
paginationResult.setData(new ArrayList<>());
paginationResult.setRecordsFiltered(0);
paginationResult.setRecordsTotal(0);
return paginationResult;
return new CategorizedSubscriptionResult(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
}
List<Integer> deviceIdList = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId)
.collect(Collectors.toList());
Map<Integer,String> currentVersionsMap = subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(),deviceIdList, installedVersion);
Map<Integer, String> currentVersionsMap =
subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(), deviceIdList, installedVersion);
try {
//pass the device id list to device manager service method
PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices
(request, deviceIdList);
List<DeviceSubscriptionData> deviceSubscriptionDataList = new ArrayList<>();
// Pass the device id list to device manager service method
PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices(request, deviceIdList);
if (!paginationResult.getData().isEmpty()) {
List<Device> devices = (List<Device>) paginationResult.getData();
for (Device device : devices) {
if(installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())){
if (installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())) {
continue;
}
DeviceSubscriptionData deviceSubscriptionData = new DeviceSubscriptionData();
if(currentVersionsMap.containsKey(device.getId())){
if (currentVersionsMap.containsKey(device.getId())) {
deviceSubscriptionData.setCurrentInstalledVersion(currentVersionsMap.get(device.getId()));
}else{
} else {
deviceSubscriptionData.setCurrentInstalledVersion("-");
}
for (DeviceSubscriptionDTO subscription : deviceSubscriptionDTOS) {
@ -1565,39 +1576,51 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
if (subscription.isUnsubscribed()) {
deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED);
deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy());
deviceSubscriptionData
.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000);
deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp());
} else {
deviceSubscriptionData.setAction(Constants.SUBSCRIBED);
deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy());
deviceSubscriptionData
.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000);
deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp());
}
deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom());
deviceSubscriptionData.setStatus(subscription.getStatus());
deviceSubscriptionData.setSubId(subscription.getId());
deviceSubscriptionDataList.add(deviceSubscriptionData);
// Categorize the subscription data based on its status
switch (subscription.getStatus()) {
case "COMPLETED":
installedDevices.add(deviceSubscriptionData);
break;
case "ERROR":
case "INVALID":
case "UNAUTHORIZED":
errorDevices.add(deviceSubscriptionData);
break;
case "IN_PROGRESS":
case "PENDING":
case "REPEATED":
pendingDevices.add(deviceSubscriptionData);
break;
}
break;
}
}
}
}
paginationResult.setData(deviceSubscriptionDataList);
return paginationResult;
return new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices);
} catch (DeviceManagementException e) {
String msg = "service error occurred while getting device data from the device management service. "
+ "Device ids " + deviceIdList;
String msg = "Service error occurred while getting device data from the device management service. " +
"Device ids " + deviceIdList;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
} catch (ApplicationManagementDAOException e) {
String msg =
"Error occurred when getting application release data for application release UUID: " + appUUID;
String msg = "Error occurred when getting application release data for application release UUID: " + appUUID;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "DB Connection error occurred while trying to get subscription data of application which has "
+ "application release UUID " + appUUID;
String msg = "DB Connection error occurred while trying to get subscription data of application which has " +
"application release UUID " + appUUID;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
@ -1675,4 +1698,148 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
}
}
/**
* Get subscription data describes by {@link SubscriptionInfo} entity
* @param subscriptionInfo {@link SubscriptionInfo}
* @param limit Limit value
* @param offset Offset value
* @return {@link SubscriptionResponse}
* @throws ApplicationManagementException Throws when error encountered while getting subscription data
*/
@Override
public SubscriptionResponse getSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
SubscriptionManagementHelperService subscriptionManagementHelperService =
SubscriptionManagementServiceProvider.getInstance().getSubscriptionManagementHelperService(subscriptionInfo);
return subscriptionManagementHelperService.getSubscriptions(subscriptionInfo, limit, offset);
}
/**
* Get status based subscription data describes by {@link SubscriptionInfo} entity
* @param subscriptionInfo {@link SubscriptionInfo}
* @param limit Limit value
* @param offset Offset value
* @return {@link SubscriptionResponse}
* @throws ApplicationManagementException Throws when error encountered while getting subscription data
*/
@Override
public SubscriptionResponse getStatusBaseSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
SubscriptionManagementHelperService subscriptionManagementHelperService =
SubscriptionManagementServiceProvider.getInstance().getSubscriptionManagementHelperService(subscriptionInfo);
return subscriptionManagementHelperService.getStatusBaseSubscriptions(subscriptionInfo, limit, offset);
}
/**
* Get subscription statistics related data describes by the {@link SubscriptionInfo}
* @param subscriptionInfo {@link SubscriptionInfo}
* @return {@link SubscriptionStatistics}
* @throws ApplicationManagementException Throws when error encountered while getting statistics
*/
@Override
public SubscriptionStatistics getStatistics(SubscriptionInfo subscriptionInfo) throws ApplicationManagementException {
return SubscriptionManagementServiceProvider.getInstance().getSubscriptionManagementHelperService(subscriptionInfo).
getSubscriptionStatistics(subscriptionInfo);
}
@Override
public List<DeviceOperationDTO> getSubscriptionOperationsByUUIDAndDeviceID(int deviceId, String uuid)
throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (uuid == null || uuid.isEmpty()) {
throw new IllegalArgumentException("UUID cannot be null or empty.");
}
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " + uuid;
log.error(msg);
throw new NotFoundException(msg);
}
int appReleaseId = applicationReleaseDTO.getId();
DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService();
List<DeviceOperationDTO> deviceSubscriptions =
subscriptionDAO.getSubscriptionOperationsByAppReleaseIDAndDeviceID(appReleaseId, deviceId, tenantId);
for (DeviceOperationDTO deviceSubscription : deviceSubscriptions) {
Integer operationId = deviceSubscription.getOperationId();
if (operationId != null) {
OperationDTO operationDetails = deviceManagementProviderService.getOperationDetailsById(operationId);
if (operationDetails != null) {
deviceSubscription.setOperationCode(operationDetails.getOperationCode());
deviceSubscription.setOperationDetails(operationDetails.getOperationDetails());
deviceSubscription.setOperationProperties(operationDetails.getOperationProperties());
deviceSubscription.setOperationResponses(operationDetails.getOperationResponses());
}
}
}
return deviceSubscriptions;
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while retrieving device subscriptions for UUID: " + uuid;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (OperationManagementException e) {
throw new RuntimeException(e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public List<CategorizedSubscriptionCountsDTO> getSubscriptionCountsByUUID(String uuid)
throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (uuid == null || uuid.isEmpty()) {
throw new IllegalArgumentException("UUID cannot be null or empty.");
}
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " + uuid;
log.error(msg);
throw new NotFoundException(msg);
}
int appReleaseId = applicationReleaseDTO.getId();
List<CategorizedSubscriptionCountsDTO> subscriptionCounts = new ArrayList<>();
subscriptionCounts.add(new CategorizedSubscriptionCountsDTO(
"Device",
subscriptionDAO.getAllSubscriptionCount(appReleaseId, tenantId),
subscriptionDAO.getAllUnsubscriptionCount(appReleaseId, tenantId)));
subscriptionCounts.add(new CategorizedSubscriptionCountsDTO(
"Group",
subscriptionDAO.getGroupSubscriptionCount(appReleaseId, tenantId),
subscriptionDAO.getGroupUnsubscriptionCount(appReleaseId, tenantId)));
subscriptionCounts.add(new CategorizedSubscriptionCountsDTO(
"Role",
subscriptionDAO.getRoleSubscriptionCount(appReleaseId, tenantId),
subscriptionDAO.getRoleUnsubscriptionCount(appReleaseId, tenantId)));
subscriptionCounts.add(new CategorizedSubscriptionCountsDTO(
"User",
subscriptionDAO.getUserSubscriptionCount(appReleaseId, tenantId),
subscriptionDAO.getUserUnsubscriptionCount(appReleaseId, tenantId)));
return subscriptionCounts;
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while retrieving subscriptions counts for UUID: " + uuid;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while retrieving the database connection";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
}

@ -33,7 +33,9 @@ import io.entgra.device.mgt.core.application.mgt.core.impl.FileTransferServiceIm
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.application.mgt.core.task.ScheduledAppSubscriptionTaskManager;
import io.entgra.device.mgt.core.application.mgt.core.util.ApplicationManagementUtil;
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
@ -71,6 +73,12 @@ import java.util.List;
* policy="dynamic"
* bind="setTaskService"
* unbind="unsetTaskService"
* @scr.reference name="io.entgra.device.mgt.core.tenant.manager"
* interface="io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService"
* cardinality="0..1"
* policy="dynamic"
* bind="setTenantManagementAdminService"
* unbind="unsetTenantManagementAdminService"
*/
@SuppressWarnings("unused")
public class ApplicationManagementServiceComponent {
@ -196,4 +204,20 @@ public class ApplicationManagementServiceComponent {
}
DataHolder.getInstance().setTaskService(null);
}
@SuppressWarnings("unused")
protected void setTenantManagementAdminService(TenantManagerAdminService tenantManagerAdminService) {
if (log.isDebugEnabled()) {
log.debug("Setting Tenant management admin Service");
}
DataHolder.getInstance().setTenantManagerAdminService(tenantManagerAdminService);
}
@SuppressWarnings("unused")
protected void unsetTenantManagementAdminService(TenantManagerAdminService tenantManagerAdminService) {
if (log.isDebugEnabled()) {
log.debug("Un setting Tenant management admin service");
}
DataHolder.getInstance().setTenantManagerAdminService(null);
}
}

@ -27,6 +27,8 @@ import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionMan
import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager;
import io.entgra.device.mgt.core.application.mgt.core.lifecycle.LifecycleStateManager;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.tenant.mgt.common.spi.TenantManagerAdminService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.ntask.core.service.TaskService;
import org.wso2.carbon.user.core.service.RealmService;
@ -57,6 +59,7 @@ public class DataHolder {
private TaskService taskService;
private FileTransferService fileTransferService;
private TenantManagerAdminService tenantManagerAdminService;
private static final DataHolder applicationMgtDataHolder = new DataHolder();
@ -163,4 +166,12 @@ public class DataHolder {
public void setFileTransferService(FileTransferService fileTransferService) {
this.fileTransferService = fileTransferService;
}
public TenantManagerAdminService getTenantManagerAdminService() {
return tenantManagerAdminService;
}
public void setTenantManagerAdminService(TenantManagerAdminService tenantManagerAdminService) {
this.tenantManagerAdminService = tenantManagerAdminService;
}
}

@ -181,6 +181,7 @@ public class ApplicationManagementUtil {
fileDescriptor = FileDownloaderServiceProvider.getFileDownloaderService(artifactLinkUrl).download(artifactLinkUrl);
applicationArtifact.setInstallerName(fileDescriptor.getFullQualifiedName());
applicationArtifact.setInstallerStream(fileDescriptor.getFile());
applicationArtifact.setInstallerPath(fileDescriptor.getAbsolutePath());
}
if (iconLink != null) {
@ -188,6 +189,7 @@ public class ApplicationManagementUtil {
fileDescriptor = FileDownloaderServiceProvider.getFileDownloaderService(iconLinkUrl).download(iconLinkUrl);
applicationArtifact.setIconName(fileDescriptor.getFullQualifiedName());
applicationArtifact.setIconStream(fileDescriptor.getFile());
applicationArtifact.setIconPath(fileDescriptor.getAbsolutePath());
}
if (bannerLink != null) {
@ -195,10 +197,12 @@ public class ApplicationManagementUtil {
fileDescriptor = FileDownloaderServiceProvider.getFileDownloaderService(bannerLinkUrl).download(bannerLinkUrl);
applicationArtifact.setBannerName(fileDescriptor.getFullQualifiedName());
applicationArtifact.setBannerStream(fileDescriptor.getFile());
applicationArtifact.setBannerPath(fileDescriptor.getAbsolutePath());
}
if (screenshotLinks != null) {
Map<String, InputStream> screenshotData = new TreeMap<>();
Map<String, String> screenshotPaths = new TreeMap<>();
// This is to handle cases in which multiple screenshots have the same name
Map<String, Integer> screenshotNameCount = new HashMap<>();
URL screenshotLinkUrl;
@ -209,6 +213,7 @@ public class ApplicationManagementUtil {
screenshotNameCount.put(screenshotName, screenshotNameCount.getOrDefault(screenshotName, 0) + 1);
screenshotName = FileUtil.generateDuplicateFileName(screenshotName, screenshotNameCount.get(screenshotName));
screenshotData.put(screenshotName, fileDescriptor.getFile());
screenshotPaths.put(screenshotName, fileDescriptor.getAbsolutePath());
}
applicationArtifact.setScreenshots(screenshotData);
}

@ -74,6 +74,7 @@ public class Constants {
public static final String IS_USER_ABLE_TO_VIEW_ALL_ROLES = "isUserAbleToViewAllRoles";
public static final String GOOGLE_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=";
public static final String APPLE_STORE_URL = "https://itunes.apple.com/country/app/app-name/id";
public static final String MICROSOFT_STORE_URL = "https://apps.microsoft.com/detail/";
public static final String GOOGLE_PLAY_SYNCED_APP = "GooglePlaySyncedApp";
// Subscription task related constants

@ -383,7 +383,6 @@ public class DAOUtil {
activity.setAppType(rs.getString("TYPE"));
activity.setUsername(rs.getString("SUBSCRIBED_BY"));
activity.setPackageName(rs.getString("PACKAGE_NAME"));
activity.setStatus(rs.getString("STATUS"));
activity.setVersion(rs.getString("VERSION"));
activity.setTriggeredBy(rs.getString("ACTION_TRIGGERED_FROM"));
activities.add(activity);

@ -23,7 +23,9 @@ import com.google.gson.Gson;
import io.entgra.device.mgt.core.application.mgt.common.ChunkDescriptor;
import io.entgra.device.mgt.core.application.mgt.common.FileDescriptor;
import io.entgra.device.mgt.core.application.mgt.common.FileMetaEntry;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationStorageManagementException;
import io.entgra.device.mgt.core.application.mgt.core.exception.FileTransferServiceHelperUtilException;
import io.entgra.device.mgt.core.application.mgt.core.internal.DataHolder;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.NotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -175,6 +177,12 @@ public class FileTransferServiceHelperUtil {
}
String []urlPathSegments = downloadUrl.getPath().split("/");
FileDescriptor fileDescriptorResolvedFromRelease = resolve(urlPathSegments);
if (fileDescriptorResolvedFromRelease != null) {
return fileDescriptorResolvedFromRelease;
}
if (urlPathSegments.length < 2) {
if (log.isDebugEnabled()) {
log.debug("URL patch segments contain less than 2 segments");
@ -234,4 +242,54 @@ public class FileTransferServiceHelperUtil {
throw new FileTransferServiceHelperUtilException("Error encountered while creating artifact file", e);
}
}
private static FileDescriptor resolve(String []urlSegments) throws FileTransferServiceHelperUtilException {
// check the possibility of url is pointing to a file resides in the default storage path
if (urlSegments.length < 4) {
if (log.isDebugEnabled()) {
log.debug("URL path segments contain less than 4 segments");
}
return null;
}
int tenantId;
try {
tenantId = Integer.parseInt(urlSegments[urlSegments.length - 4]);
} catch (NumberFormatException e) {
if (log.isDebugEnabled()) {
log.debug("URL isn't pointing to a file resides in the default storage path");
}
return null;
}
String fileName = urlSegments[urlSegments.length - 1];
String folderName = urlSegments[urlSegments.length - 2];
String appHash = urlSegments[urlSegments.length - 3];
try {
InputStream fileStream = DataHolder.getInstance().
getApplicationStorageManager().getFileStream(appHash, folderName, fileName, tenantId);
if (fileStream == null) {
if (log.isDebugEnabled()) {
log.debug("Could not found the file " + fileName);
}
return null;
}
String []fileNameSegments = fileName.split("\\.(?=[^.]+$)");
if (fileNameSegments.length < 2) {
throw new FileTransferServiceHelperUtilException("Invalid full qualified name encountered :" + fileName);
}
FileDescriptor fileDescriptor = new FileDescriptor();
fileDescriptor.setFile(fileStream);
fileDescriptor.setFullQualifiedName(fileName);
fileDescriptor.setExtension(fileNameSegments[fileNameSegments.length - 1]);
fileDescriptor.setFileName(fileNameSegments[fileNameSegments.length - 2]);
fileDescriptor.setAbsolutePath(DataHolder.getInstance().
getApplicationStorageManager().getAbsolutePathOfFile(appHash, folderName, fileName, tenantId));
return fileDescriptor;
} catch (ApplicationStorageManagementException e) {
throw new FileTransferServiceHelperUtilException("Error encountered while getting file input stream", e);
}
}
}

@ -0,0 +1,207 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscription;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionFilterCriteria;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionData;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionMetadata;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionStatistics;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionStatisticDTO;
import io.entgra.device.mgt.core.application.mgt.core.util.HelperUtil;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class SubscriptionManagementHelperUtil {
/**
* Retrieves device subscription data based on the provided filters.
*
* @param deviceSubscriptionDTOS List of DeviceSubscriptionDTO objects.
* @param deviceSubscriptionFilterCriteria Filter criteria for device subscription.
* @param isUnsubscribed Boolean indicating whether to filter unsubscribed devices.
* @param deviceTypeId Device type ID.
* @param limit Limit for pagination.
* @param offset Offset for pagination.
* @return List of DeviceSubscription objects.
* @throws DeviceManagementException If an error occurs during device management.
*/
public static List<DeviceSubscription> getDeviceSubscriptionData(List<DeviceSubscriptionDTO> deviceSubscriptionDTOS,
DeviceSubscriptionFilterCriteria deviceSubscriptionFilterCriteria,
boolean isUnsubscribed, int deviceTypeId, int limit, int offset)
throws DeviceManagementException {
List<Integer> deviceIds = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId).collect(Collectors.toList());
PaginationRequest paginationRequest = new PaginationRequest(offset, limit);
paginationRequest.setDeviceName(deviceSubscriptionFilterCriteria.getName());
paginationRequest.setDeviceStatus(deviceSubscriptionFilterCriteria.getDeviceStatus());
paginationRequest.setOwner(deviceSubscriptionFilterCriteria.getOwner());
paginationRequest.setDeviceTypeId(deviceTypeId);
List<Device> devices = HelperUtil.getDeviceManagementProviderService().getDevicesByDeviceIds(paginationRequest, deviceIds);
return populateDeviceData(deviceSubscriptionDTOS, devices, isUnsubscribed);
}
/**
* Retrieves the total count of device subscriptions based on the provided filters.
*
* @param deviceSubscriptionDTOS List of DeviceSubscriptionDTO objects.
* @param deviceSubscriptionFilterCriteria Filter criteria for device subscription.
* @param deviceTypeId Device type ID.
* @return int Total count of device subscriptions.
* @throws DeviceManagementException If an error occurs during device management.
*/
public static int getTotalDeviceSubscriptionCount(List<DeviceSubscriptionDTO> deviceSubscriptionDTOS,
DeviceSubscriptionFilterCriteria deviceSubscriptionFilterCriteria, int deviceTypeId)
throws DeviceManagementException {
List<Integer> deviceIds = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId).collect(Collectors.toList());
PaginationRequest paginationRequest = new PaginationRequest(-1, -1);
paginationRequest.setDeviceName(deviceSubscriptionFilterCriteria.getName());
paginationRequest.setDeviceStatus(deviceSubscriptionFilterCriteria.getDeviceStatus());
paginationRequest.setOwner(deviceSubscriptionFilterCriteria.getOwner());
paginationRequest.setDeviceTypeId(deviceTypeId);
return HelperUtil.getDeviceManagementProviderService().getDeviceCountByDeviceIds(paginationRequest, deviceIds);
}
/**
* Populates device subscription data based on the provided devices and subscription DTOs.
*
* @param deviceSubscriptionDTOS List of DeviceSubscriptionDTO objects.
* @param devices List of Device objects.
* @param isUnsubscribed Boolean indicating whether to filter unsubscribed devices.
* @return List of DeviceSubscription objects.
*/
private static List<DeviceSubscription> populateDeviceData(List<DeviceSubscriptionDTO> deviceSubscriptionDTOS,
List<Device> devices, boolean isUnsubscribed) {
List<DeviceSubscription> deviceSubscriptions = new ArrayList<>();
for (Device device : devices) {
int idx = deviceSubscriptionDTOS.indexOf(new DeviceSubscriptionDTO(device.getId()));
if (idx >= 0) {
DeviceSubscriptionDTO deviceSubscriptionDTO = deviceSubscriptionDTOS.get(idx);
DeviceSubscription deviceSubscription = new DeviceSubscription();
deviceSubscription.setDeviceId(device.getId());
deviceSubscription.setDeviceIdentifier(device.getDeviceIdentifier());
deviceSubscription.setDeviceOwner(device.getEnrolmentInfo().getOwner());
deviceSubscription.setDeviceType(device.getType());
deviceSubscription.setDeviceName(device.getName());
deviceSubscription.setDeviceStatus(device.getEnrolmentInfo().getStatus().name());
deviceSubscription.setOwnershipType(device.getEnrolmentInfo().getOwnership().name());
deviceSubscription.setDateOfLastUpdate(new Timestamp(device.getEnrolmentInfo().getDateOfLastUpdate()));
SubscriptionData subscriptionData = getSubscriptionData(isUnsubscribed, deviceSubscriptionDTO);
deviceSubscription.setSubscriptionData(subscriptionData);
deviceSubscriptions.add(deviceSubscription);
}
}
return deviceSubscriptions;
}
/**
* Creates a SubscriptionData object based on the provided subscription DTO.
*
* @param isUnsubscribed Boolean indicating whether to filter unsubscribed devices.
* @param deviceSubscriptionDTO DeviceSubscriptionDTO object.
* @return SubscriptionData object.
*/
private static SubscriptionData getSubscriptionData(boolean isUnsubscribed, DeviceSubscriptionDTO deviceSubscriptionDTO) {
SubscriptionData subscriptionData = new SubscriptionData();
subscriptionData.setTriggeredBy(isUnsubscribed ? deviceSubscriptionDTO.getUnsubscribedBy() :
deviceSubscriptionDTO.getSubscribedBy());
subscriptionData.setTriggeredAt(deviceSubscriptionDTO.getSubscribedTimestamp());
subscriptionData.setDeviceSubscriptionStatus(deviceSubscriptionDTO.getStatus());
subscriptionData.setSubscriptionType(deviceSubscriptionDTO.getActionTriggeredFrom());
subscriptionData.setSubscriptionId(deviceSubscriptionDTO.getId());
return subscriptionData;
}
/**
* Retrieves the device subscription status based on the provided subscription info.
*
* @param subscriptionInfo SubscriptionInfo object.
* @return Device subscription status.
*/
public static String getDeviceSubscriptionStatus(SubscriptionInfo subscriptionInfo) {
return getDeviceSubscriptionStatus(subscriptionInfo.getDeviceSubscriptionFilterCriteria().
getFilteringDeviceSubscriptionStatus(), subscriptionInfo.getDeviceSubscriptionStatus());
}
/**
* Retrieves the device subscription status based on the provided filter and status.
*
* @param deviceSubscriptionStatusFilter Filtered device subscription status.
* @param deviceSubscriptionStatus Device subscription status.
* @return Device subscription status.
*/
public static String getDeviceSubscriptionStatus(String deviceSubscriptionStatusFilter, String deviceSubscriptionStatus) {
return (deviceSubscriptionStatusFilter != null && !deviceSubscriptionStatusFilter.isEmpty()) ?
deviceSubscriptionStatusFilter : deviceSubscriptionStatus;
}
/**
* Retrieves subscription statistics based on the provided subscription statistics DTO and device count.
*
* @param subscriptionStatisticDTO SubscriptionStatisticDTO object.
* @param allDeviceCount Total count of all devices.
* @return SubscriptionStatistics object.
*/
public static SubscriptionStatistics getSubscriptionStatistics(SubscriptionStatisticDTO subscriptionStatisticDTO, int allDeviceCount) {
SubscriptionStatistics subscriptionStatistics = new SubscriptionStatistics();
subscriptionStatistics.setCompletedPercentage(
getPercentage(subscriptionStatisticDTO.getCompletedDeviceCount(), allDeviceCount));
subscriptionStatistics.setPendingPercentage(
getPercentage(subscriptionStatisticDTO.getPendingDevicesCount(), allDeviceCount));
subscriptionStatistics.setFailedPercentage(
getPercentage(subscriptionStatisticDTO.getFailedDevicesCount(), allDeviceCount));
subscriptionStatistics.setNewDevicesPercentage(getPercentage((allDeviceCount -
subscriptionStatisticDTO.getCompletedDeviceCount() -
subscriptionStatisticDTO.getPendingDevicesCount() -
subscriptionStatisticDTO.getFailedDevicesCount()), allDeviceCount));
return subscriptionStatistics;
}
/**
* Calculates the percentages.
*
* @param numerator Numerator value.
* @param denominator Denominator value.
* @return Calculated percentage.
*/
public static float getPercentage(int numerator, int denominator) {
if (denominator <= 0) {
return 0.0f;
}
return ((float) numerator / (float) denominator) * 100;
}
/**
* Retrieves database subscription statuses based on the provided device subscription status.
*
* @param deviceSubscriptionStatus Device subscription status.
* @return List of database subscription statuses.
*/
public static List<String> getDBSubscriptionStatus(String deviceSubscriptionStatus) {
return SubscriptionMetadata.deviceSubscriptionStatusToDBSubscriptionStatusMap.get(deviceSubscriptionStatus);
}
}

@ -0,0 +1,71 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionMetadata;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.impl.DeviceBasedSubscriptionManagementHelperServiceImpl;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.impl.GroupBasedSubscriptionManagementHelperServiceImpl;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.impl.RoleBasedSubscriptionManagementHelperServiceImpl;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.impl.UserBasedSubscriptionManagementHelperServiceImpl;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.service.SubscriptionManagementHelperService;
import java.util.Objects;
public class SubscriptionManagementServiceProvider {
private SubscriptionManagementServiceProvider() {
}
public static SubscriptionManagementServiceProvider getInstance() {
return SubscriptionManagementProviderServiceHolder.INSTANCE;
}
/**
* Retrieves the appropriate SubscriptionManagementHelperService based on the provided SubscriptionInfo.
*
* @param subscriptionInfo SubscriptionInfo object containing the subscription type.
* @return SubscriptionManagementHelperService implementation based on the subscription type.
*/
public SubscriptionManagementHelperService getSubscriptionManagementHelperService(SubscriptionInfo subscriptionInfo) {
return getSubscriptionManagementHelperService(subscriptionInfo.getSubscriptionType());
}
/**
* Retrieves the appropriate SubscriptionManagementHelperService based on the subscription type.
*
* @param subscriptionType Type of the subscription.
* @return SubscriptionManagementHelperService implementation based on the subscription type.
*/
private SubscriptionManagementHelperService getSubscriptionManagementHelperService(String subscriptionType) {
if (Objects.equals(subscriptionType, SubscriptionMetadata.SubscriptionTypes.ROLE))
return RoleBasedSubscriptionManagementHelperServiceImpl.getInstance();
if (Objects.equals(subscriptionType, SubscriptionMetadata.SubscriptionTypes.GROUP))
return GroupBasedSubscriptionManagementHelperServiceImpl.getInstance();
if (Objects.equals(subscriptionType, SubscriptionMetadata.SubscriptionTypes.USER))
return UserBasedSubscriptionManagementHelperServiceImpl.getInstance();
if (Objects.equals(subscriptionType, SubscriptionMetadata.SubscriptionTypes.DEVICE))
return DeviceBasedSubscriptionManagementHelperServiceImpl.getInstance();
throw new UnsupportedOperationException("Subscription type: " + subscriptionType + " not supports");
}
private static class SubscriptionManagementProviderServiceHolder {
private static final SubscriptionManagementServiceProvider INSTANCE = new SubscriptionManagementServiceProvider();
}
}

@ -0,0 +1,143 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.impl;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscription;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionFilterCriteria;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionMetadata;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionResponse;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionStatistics;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.exception.NotFoundException;
import io.entgra.device.mgt.core.application.mgt.core.util.ConnectionManagerUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.HelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.SubscriptionManagementHelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.service.SubscriptionManagementHelperService;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class DeviceBasedSubscriptionManagementHelperServiceImpl implements SubscriptionManagementHelperService {
private static final Log log = LogFactory.getLog(DeviceBasedSubscriptionManagementHelperServiceImpl.class);
private DeviceBasedSubscriptionManagementHelperServiceImpl() {
}
public static DeviceBasedSubscriptionManagementHelperServiceImpl getInstance() {
return DeviceBasedSubscriptionManagementHelperServiceImpl.DeviceBasedSubscriptionManagementHelperServiceImplHolder.INSTANCE;
}
@Override
public SubscriptionResponse getStatusBaseSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS;
int deviceCount = 0;
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationDTO == null) {
String msg = "Application not found for the release UUID: " + subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
String deviceSubscriptionStatus = SubscriptionManagementHelperUtil.getDeviceSubscriptionStatus(subscriptionInfo);
DeviceSubscriptionFilterCriteria deviceSubscriptionFilterCriteria = subscriptionInfo.getDeviceSubscriptionFilterCriteria();
DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService();
List<String> dbSubscriptionStatus = SubscriptionManagementHelperUtil.getDBSubscriptionStatus(subscriptionInfo.getDeviceSubscriptionStatus());
if (Objects.equals(SubscriptionMetadata.DeviceSubscriptionStatus.NEW, deviceSubscriptionStatus)) {
deviceSubscriptionDTOS = subscriptionDAO.getAllSubscriptionsDetails(applicationReleaseDTO.
getId(), isUnsubscribe, tenantId, null, null,
deviceSubscriptionFilterCriteria.getTriggeredBy(), -1, -1);
List<Integer> deviceIdsOfSubscription = deviceSubscriptionDTOS.stream().
map(DeviceSubscriptionDTO::getDeviceId).collect(Collectors.toList());
List<Integer> newDeviceIds = deviceManagementProviderService.getDevicesNotInGivenIdList(deviceIdsOfSubscription);
deviceSubscriptionDTOS = newDeviceIds.stream().map(DeviceSubscriptionDTO::new).collect(Collectors.toList());
} else {
deviceSubscriptionDTOS = subscriptionDAO.getAllSubscriptionsDetails(applicationReleaseDTO.
getId(), isUnsubscribe, tenantId, dbSubscriptionStatus, null,
deviceSubscriptionFilterCriteria.getTriggeredBy(), -1, -1);
}
deviceCount = SubscriptionManagementHelperUtil.getTotalDeviceSubscriptionCount(deviceSubscriptionDTOS,
subscriptionInfo.getDeviceSubscriptionFilterCriteria(), applicationDTO.getDeviceTypeId());
List<DeviceSubscription> deviceSubscriptions = SubscriptionManagementHelperUtil.getDeviceSubscriptionData(deviceSubscriptionDTOS,
subscriptionInfo.getDeviceSubscriptionFilterCriteria(), isUnsubscribe, applicationDTO.getDeviceTypeId(), limit, offset);
return new SubscriptionResponse(subscriptionInfo.getApplicationUUID(), deviceCount, deviceSubscriptions);
} catch (DeviceManagementException e) {
String msg = "Error encountered while getting device details";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException | DBConnectionException e) {
String msg = "Error encountered while connecting to the database";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public SubscriptionResponse getSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
return new SubscriptionResponse(subscriptionInfo.getApplicationUUID(), Collections.emptyList());
}
@Override
public SubscriptionStatistics getSubscriptionStatistics(SubscriptionInfo subscriptionInfo)
throws ApplicationManagementException {
return null;
}
private static class DeviceBasedSubscriptionManagementHelperServiceImplHolder {
private static final DeviceBasedSubscriptionManagementHelperServiceImpl INSTANCE
= new DeviceBasedSubscriptionManagementHelperServiceImpl();
}
}

@ -0,0 +1,220 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.impl;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscription;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionFilterCriteria;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionEntity;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionMetadata;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionResponse;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionStatistics;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionStatisticDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.exception.NotFoundException;
import io.entgra.device.mgt.core.application.mgt.core.util.ConnectionManagerUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.HelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.SubscriptionManagementHelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.service.SubscriptionManagementHelperService;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException;
import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.core.service.GroupManagementProviderService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class GroupBasedSubscriptionManagementHelperServiceImpl implements SubscriptionManagementHelperService {
private static final Log log = LogFactory.getLog(GroupBasedSubscriptionManagementHelperServiceImpl.class);
private GroupBasedSubscriptionManagementHelperServiceImpl() {
}
public static GroupBasedSubscriptionManagementHelperServiceImpl getInstance() {
return GroupBasedSubscriptionManagementHelperServiceImplHolder.INSTANCE;
}
@Override
public SubscriptionResponse getStatusBaseSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS;
int deviceCount = 0;
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationDTO == null) {
String msg = "Application not found for the release UUID: " + subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
String deviceSubscriptionStatus = SubscriptionManagementHelperUtil.getDeviceSubscriptionStatus(subscriptionInfo);
DeviceSubscriptionFilterCriteria deviceSubscriptionFilterCriteria = subscriptionInfo.getDeviceSubscriptionFilterCriteria();
DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService();
GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService();
GroupDetailsDTO groupDetailsDTO;
List<String> dbSubscriptionStatus = SubscriptionManagementHelperUtil.getDBSubscriptionStatus(subscriptionInfo.getDeviceSubscriptionStatus());
if (Objects.equals(SubscriptionMetadata.DeviceSubscriptionStatus.NEW, deviceSubscriptionStatus)) {
List<Integer> allDeviceIdsOwnByGroup = groupManagementProviderService.getGroupDetailsWithDevices(subscriptionInfo.getIdentifier(),
applicationDTO.getDeviceTypeId(), deviceSubscriptionFilterCriteria.getOwner(), deviceSubscriptionFilterCriteria.getName(),
deviceSubscriptionFilterCriteria.getDeviceStatus(), -1, -1).getDeviceIds();
deviceSubscriptionDTOS = subscriptionDAO.getSubscriptionDetailsByDeviceIds(applicationReleaseDTO.getId(),
isUnsubscribe, tenantId, allDeviceIdsOwnByGroup, null,
null, deviceSubscriptionFilterCriteria.getTriggeredBy(), -1, -1);
List<Integer> deviceIdsOfSubscription = deviceSubscriptionDTOS.stream().
map(DeviceSubscriptionDTO::getDeviceId).collect(Collectors.toList());
for (Integer deviceId : deviceIdsOfSubscription) {
allDeviceIdsOwnByGroup.remove(deviceId);
}
List<Integer> newDeviceIds = deviceManagementProviderService.getDevicesInGivenIdList(allDeviceIdsOwnByGroup);
deviceSubscriptionDTOS = newDeviceIds.stream().map(DeviceSubscriptionDTO::new).collect(Collectors.toList());
} else {
groupDetailsDTO = groupManagementProviderService.getGroupDetailsWithDevices(subscriptionInfo.getIdentifier(),
applicationDTO.getDeviceTypeId(), deviceSubscriptionFilterCriteria.getOwner(), deviceSubscriptionFilterCriteria.getName(),
deviceSubscriptionFilterCriteria.getDeviceStatus(), offset, limit);
List<Integer> paginatedDeviceIdsOwnByGroup = groupDetailsDTO.getDeviceIds();
deviceSubscriptionDTOS = subscriptionDAO.getSubscriptionDetailsByDeviceIds(applicationReleaseDTO.getId(),
isUnsubscribe, tenantId, paginatedDeviceIdsOwnByGroup, dbSubscriptionStatus,
null, deviceSubscriptionFilterCriteria.getTriggeredBy(), -1, -1);
}
deviceCount = SubscriptionManagementHelperUtil.getTotalDeviceSubscriptionCount(deviceSubscriptionDTOS,
subscriptionInfo.getDeviceSubscriptionFilterCriteria(), applicationDTO.getDeviceTypeId());
List<DeviceSubscription> deviceSubscriptions = SubscriptionManagementHelperUtil.getDeviceSubscriptionData(deviceSubscriptionDTOS,
subscriptionInfo.getDeviceSubscriptionFilterCriteria(), isUnsubscribe, applicationDTO.getDeviceTypeId(), limit, offset);
return new SubscriptionResponse(subscriptionInfo.getApplicationUUID(), deviceCount, deviceSubscriptions);
} catch (GroupManagementException e) {
String msg = "Error encountered while retrieving group details for group: " + subscriptionInfo.getIdentifier();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException | DBConnectionException e) {
String msg = "Error encountered while connecting to the database";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DeviceManagementException e) {
throw new RuntimeException(e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public SubscriptionResponse getSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
final int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
List<SubscriptionEntity> subscriptionEntities = subscriptionDAO.
getGroupsSubscriptionDetailsByAppReleaseID(applicationReleaseDTO.getId(), isUnsubscribe, tenantId, offset, limit);
int subscriptionCount = isUnsubscribe ? subscriptionDAO.getGroupUnsubscriptionCount(applicationReleaseDTO.getId(), tenantId) :
subscriptionDAO.getGroupSubscriptionCount(applicationReleaseDTO.getId(), tenantId);
return new SubscriptionResponse(subscriptionInfo.getApplicationUUID(), subscriptionCount, subscriptionEntities);
} catch (DBConnectionException | ApplicationManagementDAOException e) {
String msg = "Error encountered while connecting to the database";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public SubscriptionStatistics getSubscriptionStatistics(SubscriptionInfo subscriptionInfo)
throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
List<Device> devices = HelperUtil.getGroupManagementProviderService().
getAllDevicesOfGroup(subscriptionInfo.getIdentifier(), false);
List<Integer> deviceIdsOwnByGroup = devices.stream().map(Device::getId).collect(Collectors.toList());
SubscriptionStatisticDTO subscriptionStatisticDTO = subscriptionDAO.
getSubscriptionStatistic(deviceIdsOwnByGroup, isUnsubscribe, tenantId, applicationReleaseDTO.getId());
int allDeviceCount = HelperUtil.getGroupManagementProviderService().getDeviceCount(subscriptionInfo.getIdentifier());
return SubscriptionManagementHelperUtil.getSubscriptionStatistics(subscriptionStatisticDTO, allDeviceCount);
} catch (ApplicationManagementDAOException e) {
String msg = "Error encountered while getting subscription statistics for group: " + subscriptionInfo.getIdentifier();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (GroupManagementException e) {
String msg = "Error encountered while getting device subscription for group: " + subscriptionInfo.getIdentifier();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
private static class GroupBasedSubscriptionManagementHelperServiceImplHolder {
private static final GroupBasedSubscriptionManagementHelperServiceImpl INSTANCE
= new GroupBasedSubscriptionManagementHelperServiceImpl();
}
}

@ -0,0 +1,227 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.impl;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscription;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionFilterCriteria;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionEntity;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionMetadata;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionResponse;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionStatistics;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionStatisticDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.exception.NotFoundException;
import io.entgra.device.mgt.core.application.mgt.core.internal.DataHolder;
import io.entgra.device.mgt.core.application.mgt.core.util.ConnectionManagerUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.HelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.SubscriptionManagementHelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.service.SubscriptionManagementHelperService;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class RoleBasedSubscriptionManagementHelperServiceImpl implements SubscriptionManagementHelperService {
private static final Log log = LogFactory.getLog(RoleBasedSubscriptionManagementHelperServiceImpl.class);
private RoleBasedSubscriptionManagementHelperServiceImpl() {
}
public static RoleBasedSubscriptionManagementHelperServiceImpl getInstance() {
return RoleBasedSubscriptionManagementHelperServiceImplHolder.INSTANCE;
}
@Override
public SubscriptionResponse getStatusBaseSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS;
int deviceCount = 0;
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
List<Integer> deviceIdsOwnByRole = getDeviceIdsOwnByRole(subscriptionInfo.getIdentifier(), tenantId);
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationDTO == null) {
String msg = "Application not found for the release UUID: " + subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
String deviceSubscriptionStatus = SubscriptionManagementHelperUtil.getDeviceSubscriptionStatus(subscriptionInfo);
DeviceSubscriptionFilterCriteria deviceSubscriptionFilterCriteria = subscriptionInfo.getDeviceSubscriptionFilterCriteria();
DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService();
List<String> dbSubscriptionStatus = SubscriptionManagementHelperUtil.getDBSubscriptionStatus(subscriptionInfo.getDeviceSubscriptionStatus());
if (Objects.equals(SubscriptionMetadata.DeviceSubscriptionStatus.NEW, deviceSubscriptionStatus)) {
deviceSubscriptionDTOS = subscriptionDAO.getSubscriptionDetailsByDeviceIds(applicationReleaseDTO.getId(),
isUnsubscribe, tenantId, deviceIdsOwnByRole, null,
null, deviceSubscriptionFilterCriteria.getTriggeredBy(), -1, -1);
List<Integer> deviceIdsOfSubscription = deviceSubscriptionDTOS.stream().
map(DeviceSubscriptionDTO::getDeviceId).collect(Collectors.toList());
for (Integer deviceId : deviceIdsOfSubscription) {
deviceIdsOwnByRole.remove(deviceId);
}
List<Integer> newDeviceIds = deviceManagementProviderService.getDevicesInGivenIdList(deviceIdsOwnByRole);
deviceSubscriptionDTOS = newDeviceIds.stream().map(DeviceSubscriptionDTO::new).collect(Collectors.toList());
} else {
deviceSubscriptionDTOS = subscriptionDAO.getSubscriptionDetailsByDeviceIds(applicationReleaseDTO.getId(),
isUnsubscribe, tenantId, deviceIdsOwnByRole, dbSubscriptionStatus,
subscriptionInfo.getSubscriptionType(), deviceSubscriptionFilterCriteria.getTriggeredBy(), -1, -1);
}
deviceCount = SubscriptionManagementHelperUtil.getTotalDeviceSubscriptionCount(deviceSubscriptionDTOS,
subscriptionInfo.getDeviceSubscriptionFilterCriteria(), applicationDTO.getDeviceTypeId());
List<DeviceSubscription> deviceSubscriptions = SubscriptionManagementHelperUtil.
getDeviceSubscriptionData(deviceSubscriptionDTOS,
subscriptionInfo.getDeviceSubscriptionFilterCriteria(), isUnsubscribe, applicationDTO.getDeviceTypeId(), limit, offset);
return new SubscriptionResponse(subscriptionInfo.getApplicationUUID(), deviceCount, deviceSubscriptions);
} catch (UserStoreException e) {
String msg = "Error encountered while getting the user management store for tenant id " + tenantId;
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DeviceManagementException e) {
String msg = "Error encountered while getting device details";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException | DBConnectionException e) {
String msg = "Error encountered while connecting to the database";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public SubscriptionResponse getSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
final int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
List<SubscriptionEntity> subscriptionEntities = subscriptionDAO.
getRoleSubscriptionsByAppReleaseID(applicationReleaseDTO.getId(), isUnsubscribe, tenantId, offset, limit);
int subscriptionCount = isUnsubscribe ? subscriptionDAO.getRoleUnsubscriptionCount(applicationReleaseDTO.getId(), tenantId) :
subscriptionDAO.getRoleSubscriptionCount(applicationReleaseDTO.getId(), tenantId);
return new SubscriptionResponse(subscriptionInfo.getApplicationUUID(), subscriptionCount, subscriptionEntities);
} catch (DBConnectionException | ApplicationManagementDAOException e) {
String msg = "Error encountered while connecting to the database";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public SubscriptionStatistics getSubscriptionStatistics(SubscriptionInfo subscriptionInfo) throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
List<Integer> deviceIdsOwnByRole = getDeviceIdsOwnByRole(subscriptionInfo.getIdentifier(), tenantId);
SubscriptionStatisticDTO subscriptionStatisticDTO = subscriptionDAO.
getSubscriptionStatistic(deviceIdsOwnByRole, isUnsubscribe, tenantId, applicationReleaseDTO.getId());
int allDeviceCount = deviceIdsOwnByRole.size();
return SubscriptionManagementHelperUtil.getSubscriptionStatistics(subscriptionStatisticDTO, allDeviceCount);
} catch (DeviceManagementException | ApplicationManagementDAOException | UserStoreException e) {
String msg = "Error encountered while getting subscription statistics for role: " + subscriptionInfo.getIdentifier();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@SuppressWarnings("unchecked")
private List<Integer> getDeviceIdsOwnByRole(String roleName, int tenantId) throws UserStoreException, DeviceManagementException {
UserStoreManager userStoreManager = DataHolder.getInstance().getRealmService().
getTenantUserRealm(tenantId).getUserStoreManager();
String[] usersWithRole =
userStoreManager.getUserListOfRole(roleName);
List<Device> deviceListOwnByRole = new ArrayList<>();
for (String user : usersWithRole) {
PaginationRequest paginationRequest = new PaginationRequest(-1, -1);
paginationRequest.setOwner(user);
paginationRequest.setStatusList(Arrays.asList("ACTIVE", "INACTIVE", "UNREACHABLE"));
PaginationResult ownDeviceIds = HelperUtil.getDeviceManagementProviderService().
getAllDevicesIdList(paginationRequest);
if (ownDeviceIds.getData() != null) {
deviceListOwnByRole.addAll((List<Device>) ownDeviceIds.getData());
}
}
return deviceListOwnByRole.stream().map(Device::getId).collect(Collectors.toList());
}
private static class RoleBasedSubscriptionManagementHelperServiceImplHolder {
private static final RoleBasedSubscriptionManagementHelperServiceImpl INSTANCE
= new RoleBasedSubscriptionManagementHelperServiceImpl();
}
}

@ -0,0 +1,212 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.impl;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscription;
import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionFilterCriteria;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionEntity;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionMetadata;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionResponse;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionStatistics;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO;
import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionStatisticDTO;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException;
import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException;
import io.entgra.device.mgt.core.application.mgt.core.exception.NotFoundException;
import io.entgra.device.mgt.core.application.mgt.core.util.ConnectionManagerUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.HelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.SubscriptionManagementHelperUtil;
import io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.service.SubscriptionManagementHelperService;
import io.entgra.device.mgt.core.device.mgt.common.Device;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.PaginationResult;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class UserBasedSubscriptionManagementHelperServiceImpl implements SubscriptionManagementHelperService {
private static final Log log = LogFactory.getLog(UserBasedSubscriptionManagementHelperServiceImpl.class);
private UserBasedSubscriptionManagementHelperServiceImpl() {
}
public static UserBasedSubscriptionManagementHelperServiceImpl getInstance() {
return UserBasedSubscriptionManagementHelperServiceImpl.UserBasedSubscriptionManagementHelperServiceImplHolder.INSTANCE;
}
@Override
public SubscriptionResponse getStatusBaseSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS;
int deviceCount = 0;
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
List<Integer> deviceIdsOwnByUser = getDeviceIdsOwnByUser(subscriptionInfo.getIdentifier());
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationDTO == null) {
String msg = "Application not found for the release UUID: " + subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
String deviceSubscriptionStatus = SubscriptionManagementHelperUtil.getDeviceSubscriptionStatus(subscriptionInfo);
DeviceSubscriptionFilterCriteria deviceSubscriptionFilterCriteria = subscriptionInfo.getDeviceSubscriptionFilterCriteria();
DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService();
List<String> dbSubscriptionStatus = SubscriptionManagementHelperUtil.getDBSubscriptionStatus(subscriptionInfo.getDeviceSubscriptionStatus());
if (Objects.equals(SubscriptionMetadata.DeviceSubscriptionStatus.NEW, deviceSubscriptionStatus)) {
deviceSubscriptionDTOS = subscriptionDAO.getSubscriptionDetailsByDeviceIds(applicationReleaseDTO.getId(),
isUnsubscribe, tenantId, deviceIdsOwnByUser, null,
null, deviceSubscriptionFilterCriteria.getTriggeredBy(), -1, -1);
List<Integer> deviceIdsOfSubscription = deviceSubscriptionDTOS.stream().
map(DeviceSubscriptionDTO::getDeviceId).collect(Collectors.toList());
for (Integer deviceId : deviceIdsOfSubscription) {
deviceIdsOwnByUser.remove(deviceId);
}
List<Integer> newDeviceIds = deviceManagementProviderService.getDevicesInGivenIdList(deviceIdsOwnByUser);
deviceSubscriptionDTOS = newDeviceIds.stream().map(DeviceSubscriptionDTO::new).collect(Collectors.toList());
} else {
deviceSubscriptionDTOS = subscriptionDAO.getSubscriptionDetailsByDeviceIds(applicationReleaseDTO.getId(),
isUnsubscribe, tenantId, deviceIdsOwnByUser, dbSubscriptionStatus,
null, deviceSubscriptionFilterCriteria.getTriggeredBy(), -1, -1);
}
deviceCount = SubscriptionManagementHelperUtil.getTotalDeviceSubscriptionCount(deviceSubscriptionDTOS,
subscriptionInfo.getDeviceSubscriptionFilterCriteria(), applicationDTO.getDeviceTypeId());
List<DeviceSubscription> deviceSubscriptions = SubscriptionManagementHelperUtil.getDeviceSubscriptionData(deviceSubscriptionDTOS,
subscriptionInfo.getDeviceSubscriptionFilterCriteria(), isUnsubscribe, applicationDTO.getDeviceTypeId(), limit, offset);
return new SubscriptionResponse(subscriptionInfo.getApplicationUUID(), deviceCount, deviceSubscriptions);
} catch (DeviceManagementException e) {
String msg = "Error encountered while getting device details";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException | DBConnectionException e) {
String msg = "Error encountered while connecting to the database";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public SubscriptionResponse getSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
final int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
List<SubscriptionEntity> subscriptionEntities = subscriptionDAO.
getUserSubscriptionsByAppReleaseID(applicationReleaseDTO.getId(), isUnsubscribe, tenantId, offset, limit);
int subscriptionCount = isUnsubscribe ? subscriptionDAO.getUserUnsubscriptionCount(applicationReleaseDTO.getId(), tenantId) :
subscriptionDAO.getUserSubscriptionCount(applicationReleaseDTO.getId(), tenantId);
return new SubscriptionResponse(subscriptionInfo.getApplicationUUID(), subscriptionCount, subscriptionEntities);
} catch (DBConnectionException | ApplicationManagementDAOException e) {
String msg = "Error encountered while connecting to the database";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public SubscriptionStatistics getSubscriptionStatistics(SubscriptionInfo subscriptionInfo) throws ApplicationManagementException {
final boolean isUnsubscribe = Objects.equals(SubscriptionMetadata.SUBSCRIPTION_STATUS_UNSUBSCRIBED, subscriptionInfo.getSubscriptionStatus());
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.
getReleaseByUUID(subscriptionInfo.getApplicationUUID(), tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find an application release for application release UUID: " +
subscriptionInfo.getApplicationUUID();
log.error(msg);
throw new NotFoundException(msg);
}
List<Integer> deviceIdsOwnByUser = getDeviceIdsOwnByUser(subscriptionInfo.getIdentifier());
SubscriptionStatisticDTO subscriptionStatisticDTO = subscriptionDAO.
getSubscriptionStatistic(deviceIdsOwnByUser, isUnsubscribe, tenantId, applicationReleaseDTO.getId());
int allDeviceCount = deviceIdsOwnByUser.size();
return SubscriptionManagementHelperUtil.getSubscriptionStatistics(subscriptionStatisticDTO, allDeviceCount);
} catch (DeviceManagementException | ApplicationManagementDAOException e) {
String msg = "Error encountered while getting subscription statistics for user: " + subscriptionInfo.getIdentifier();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@SuppressWarnings("unchecked")
private List<Integer> getDeviceIdsOwnByUser(String username) throws DeviceManagementException {
List<Device> deviceListOwnByUser = new ArrayList<>();
PaginationRequest paginationRequest = new PaginationRequest(-1, -1);
paginationRequest.setOwner(username);
paginationRequest.setStatusList(Arrays.asList("ACTIVE", "INACTIVE", "UNREACHABLE"));
PaginationResult ownDeviceIds = HelperUtil.getDeviceManagementProviderService().
getAllDevicesIdList(paginationRequest);
if (ownDeviceIds.getData() != null) {
deviceListOwnByUser.addAll((List<Device>) ownDeviceIds.getData());
}
return deviceListOwnByUser.stream().map(Device::getId).collect(Collectors.toList());
}
private static class UserBasedSubscriptionManagementHelperServiceImplHolder {
private static final UserBasedSubscriptionManagementHelperServiceImpl INSTANCE
= new UserBasedSubscriptionManagementHelperServiceImpl();
}
}

@ -0,0 +1,44 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package io.entgra.device.mgt.core.application.mgt.core.util.subscription.mgt.service;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionInfo;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionResponse;
import io.entgra.device.mgt.core.application.mgt.common.SubscriptionStatistics;
import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationReleaseDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.SubscriptionDAO;
import io.entgra.device.mgt.core.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
public interface SubscriptionManagementHelperService {
SubscriptionDAO subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO();
ApplicationDAO applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO();
ApplicationReleaseDAO applicationReleaseDAO = ApplicationManagementDAOFactory.getApplicationReleaseDAO();
SubscriptionResponse getStatusBaseSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException;
SubscriptionResponse getSubscriptions(SubscriptionInfo subscriptionInfo, int limit, int offset)
throws ApplicationManagementException;
SubscriptionStatistics getSubscriptionStatistics(SubscriptionInfo subscriptionInfo)
throws ApplicationManagementException;
}

@ -37,6 +37,7 @@ import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManag
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory;
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder;
import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOFactory;
import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory;
import org.wso2.carbon.registry.core.config.RegistryContext;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.internal.RegistryDataHolder;
@ -96,6 +97,7 @@ public abstract class BaseTestCase {
ConnectionManagerUtil.init(dataSource);
DeviceManagementDAOFactory.init(dataSource);
MetadataManagementDAOFactory.init(dataSource);
OperationManagementDAOFactory.init(dataSource);
// PolicyManagementDAOFactory.init(dataSource);
// OperationManagementDAOFactory.init(dataSource);
// GroupManagementDAOFactory.init(dataSource);

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>cea-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>cea-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>cea-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>cea-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>certificate-mgt</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>io.entgra.device.mgt.core</groupId>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -329,7 +329,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_POLICY_APPLIED
DEVICE_ID INT NOT NULL,
ENROLMENT_ID INT(11) NOT NULL,
POLICY_ID INT NOT NULL,
POLICY_CONTENT BLOB NULL,
POLICY_CONTENT TEXT NULL,
TENANT_ID INT NOT NULL,
APPLIED TINYINT(1) NULL,
CREATED_TIME TIMESTAMP NULL,

@ -336,7 +336,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_POLICY_APPLIED (
DEVICE_ID INT NOT NULL ,
ENROLMENT_ID INT(11) NOT NULL,
POLICY_ID INT NOT NULL ,
POLICY_CONTENT BLOB NULL ,
POLICY_CONTENT TEXT NULL ,
TENANT_ID INT NOT NULL,
APPLIED TINYINT(1) NULL ,
CREATED_TIME TIMESTAMP NULL ,

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -111,6 +111,50 @@
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.orbit.com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.orbit.com.google.auth-library-oauth2-http</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.orbit.io.opencensus</groupId>
<artifactId>opencensus</artifactId>
</dependency>
<dependency>
<groupId>io.opencensus</groupId>
<artifactId>opencensus-api</artifactId>
</dependency>
<dependency>
<groupId>io.opencensus</groupId>
<artifactId>opencensus-contrib-http-util</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.orbit.io.grpc</groupId>
<artifactId>grpc-context</artifactId>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>failureaccess</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
</dependencies>
<build>
@ -137,12 +181,27 @@
com.google.gson,
org.osgi.framework.*;version="${imp.package.version.osgi.framework}",
org.osgi.service.*;version="${imp.package.version.osgi.service}",
org.wso2.carbon.utils.*,
io.entgra.device.mgt.core.device.mgt.common.operation.mgt,
io.entgra.device.mgt.core.device.mgt.common.push.notification,
org.apache.commons.logging,
io.entgra.device.mgt.core.device.mgt.common.*,
io.entgra.device.mgt.core.device.mgt.core.service
io.entgra.device.mgt.core.device.mgt.core.service,
io.entgra.device.mgt.core.device.mgt.core.config.*,
io.entgra.device.mgt.core.device.mgt.core.config.push.notification.*,
io.entgra.device.mgt.core.device.mgt.extensions.logger.spi,
io.entgra.device.mgt.core.notification.logger.*,
com.google.auth.oauth2.*
</Import-Package>
<Embed-Dependency>
google-auth-library-oauth2-http;scope=compile|runtime,
google-http-client;scope=compile|runtime,
grpc-context;scope=compile|runtime,
guava;scope=compile|runtime,
opencensus;scope=compile|runtime,
failureaccess;scope=compile|runtime
</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>

@ -32,7 +32,9 @@ public class FCMBasedPushNotificationProvider implements PushNotificationProvide
@Override
public NotificationStrategy getNotificationStrategy(PushNotificationConfig config) {
return new FCMNotificationStrategy(config);
FCMNotificationStrategy fcmNotificationStrategy = new FCMNotificationStrategy(config);
fcmNotificationStrategy.init();
return fcmNotificationStrategy;
}
}

@ -17,9 +17,11 @@
*/
package io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.util.FCMUtil;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.Device;
@ -39,14 +41,13 @@ import java.util.List;
public class FCMNotificationStrategy implements NotificationStrategy {
private static final Log log = LogFactory.getLog(FCMNotificationStrategy.class);
private static final String NOTIFIER_TYPE_FCM = "FCM";
private static final String FCM_TOKEN = "FCM_TOKEN";
private static final String FCM_ENDPOINT = "https://fcm.googleapis.com/fcm/send";
private static final String FCM_API_KEY = "fcmAPIKey";
private static final int TIME_TO_LIVE = 2419199; // 1 second less that 28 days
private static final int TIME_TO_LIVE = 2419199; // 1 second less than 28 days
private static final int HTTP_STATUS_CODE_OK = 200;
private final PushNotificationConfig config;
private static final String FCM_ENDPOINT_KEY = "FCM_SERVER_ENDPOINT";
public FCMNotificationStrategy(PushNotificationConfig config) {
this.config = config;
@ -64,12 +65,14 @@ public class FCMNotificationStrategy implements NotificationStrategy {
Device device = FCMDataHolder.getInstance().getDeviceManagementProviderService()
.getDeviceWithTypeProperties(ctx.getDeviceId());
if(device.getProperties() != null && getFCMToken(device.getProperties()) != null) {
this.sendWakeUpCall(ctx.getOperation().getCode(), device);
FCMUtil.getInstance().getDefaultApplication().refresh();
sendWakeUpCall(FCMUtil.getInstance().getDefaultApplication().getAccessToken().getTokenValue(),
getFCMToken(device.getProperties()));
}
} else {
if (log.isDebugEnabled()) {
log.debug("Not using FCM notifier as notifier type is set to " + config.getType() +
" in Platform Configurations.");
" in Platform Configurations.");
}
}
} catch (DeviceManagementException e) {
@ -79,69 +82,66 @@ public class FCMNotificationStrategy implements NotificationStrategy {
}
}
@Override
public NotificationContext buildContext() {
return null;
}
@Override
public void undeploy() {
}
/**
* Send FCM message to the FCM server to initiate the push notification
* @param accessToken Access token to authenticate with the FCM server
* @param registrationId Registration ID of the device
* @throws IOException If an error occurs while sending the request
* @throws PushNotificationExecutionFailedException If an error occurs while sending the push notification
*/
private void sendWakeUpCall(String accessToken, String registrationId) throws IOException,
PushNotificationExecutionFailedException {
String fcmServerEndpoint = FCMUtil.getInstance().getContextMetadataProperties()
.getProperty(FCM_ENDPOINT_KEY);
if(fcmServerEndpoint == null) {
String msg = "Encountered configuration issue. " + FCM_ENDPOINT_KEY + " is not defined";
log.error(msg);
throw new PushNotificationExecutionFailedException(msg);
}
private void sendWakeUpCall(String message, Device device) throws IOException,
PushNotificationExecutionFailedException {
if (device.getProperties() != null) {
OutputStream os = null;
byte[] bytes = getFCMRequest(message, getFCMToken(device.getProperties())).getBytes();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(FCM_ENDPOINT).openConnection();
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key=" + config.getProperty(FCM_API_KEY));
conn.setRequestMethod("POST");
conn.setDoOutput(true);
os = conn.getOutputStream();
os.write(bytes);
} finally {
if (os != null) {
os.close();
}
if (conn != null) {
conn.disconnect();
}
}
int status = conn.getResponseCode();
RequestBody fcmRequest = getFCMRequest(registrationId);
Request request = new Request.Builder()
.url(fcmServerEndpoint)
.post(fcmRequest)
.addHeader("Authorization", "Bearer " + accessToken)
.build();
try (Response response = FCMUtil.getInstance().getHttpClient().newCall(request).execute()) {
if (log.isDebugEnabled()) {
log.debug("Result code: " + status + ", Message: " + conn.getResponseMessage());
log.debug("FCM message sent to the FCM server. Response code: " + response.code()
+ " Response message : " + response.message());
}
if (status != HTTP_STATUS_CODE_OK) {
throw new PushNotificationExecutionFailedException("Push notification sending failed with the HTTP " +
"error code '" + status + "'");
if(!response.isSuccessful()) {
String msg = "Response Status: " + response.code() + ", Response Message: " + response.message();
log.error(msg);
throw new IOException(msg);
}
}
}
private static String getFCMRequest(String message, String registrationId) {
/**
* Get the FCM request as a JSON string
* @param registrationId Registration ID of the device
* @return FCM request as a JSON string
*/
private static RequestBody getFCMRequest(String registrationId) {
JsonObject messageObject = new JsonObject();
messageObject.addProperty("token", registrationId);
JsonObject fcmRequest = new JsonObject();
fcmRequest.addProperty("delay_while_idle", false);
fcmRequest.addProperty("time_to_live", TIME_TO_LIVE);
fcmRequest.addProperty("priority", "high");
//Add message to FCM request
JsonObject data = new JsonObject();
if (message != null && !message.isEmpty()) {
data.addProperty("data", message);
fcmRequest.add("data", data);
}
fcmRequest.add("message", messageObject);
return RequestBody.create(fcmRequest.toString(), okhttp3.MediaType.parse("application/json"));
}
@Override
public NotificationContext buildContext() {
return null;
}
//Set device reg-id
JsonArray regIds = new JsonArray();
regIds.add(new JsonPrimitive(registrationId));
@Override
public void undeploy() {
fcmRequest.add("registration_ids", regIds);
return fcmRequest.toString();
}
private static String getFCMToken(List<Device.Property> properties) {
@ -159,5 +159,4 @@ public class FCMNotificationStrategy implements NotificationStrategy {
public PushNotificationConfig getConfig() {
return config;
}
}

@ -0,0 +1,130 @@
/*
* Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.util;
import com.google.auth.oauth2.GoogleCredentials;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager;
import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.ContextMetadata;
import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.PushNotificationConfiguration;
import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.FCMNotificationStrategy;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
public class FCMUtil {
private static final Log log = LogFactory.getLog(FCMUtil.class);
private static volatile FCMUtil instance;
private static GoogleCredentials defaultApplication;
private static final String FCM_SERVICE_ACCOUNT_PATH = CarbonUtils.getCarbonHome() + File.separator +
"repository" + File.separator + "resources" + File.separator + "service-account.json";
private static final String[] FCM_SCOPES = { "https://www.googleapis.com/auth/firebase.messaging" };
private Properties contextMetadataProperties;
private static ConnectionPool connectionPool;
private static OkHttpClient client;
private FCMUtil() {
initContextConfigs();
initDefaultOAuthApplication();
initPooledConnection();
}
/**
* Initialize the connection pool for the OkHttpClient instance.
*/
private void initPooledConnection() {
connectionPool = new ConnectionPool(25, 1, TimeUnit.MINUTES);
client = new OkHttpClient.Builder().connectionPool(connectionPool).build();
}
/**
* Get the Pooled OkHttpClient instance
* @return OkHttpClient instance
*/
public OkHttpClient getHttpClient() {
return client;
}
private void initDefaultOAuthApplication() {
if (defaultApplication == null) {
Path serviceAccountPath = Paths.get(FCM_SERVICE_ACCOUNT_PATH);
try {
defaultApplication = GoogleCredentials.
fromStream(Files.newInputStream(serviceAccountPath)).
createScoped(FCM_SCOPES);
} catch (IOException e) {
String msg = "Fail to initialize default OAuth application for FCM communication";
log.error(msg);
throw new IllegalStateException(msg, e);
}
}
}
/**
* Initialize the context metadata properties from the cdm-config.xml. This file includes the fcm server URL
* to be invoked when sending the wakeup call to the device.
*/
private void initContextConfigs() {
PushNotificationConfiguration pushNotificationConfiguration = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig().getPushNotificationConfiguration();
List<ContextMetadata> contextMetadata = pushNotificationConfiguration.getContextMetadata();
Properties properties = new Properties();
if (contextMetadata != null) {
for (ContextMetadata metadata : contextMetadata) {
properties.setProperty(metadata.getKey(), metadata.getValue());
}
}
contextMetadataProperties = properties;
}
/**
* Get the instance of FCMUtil. FCMUtil is a singleton class which should not be
* instantiating more than once. Instantiating the class requires to read the service account file from
* the filesystem and instantiation of the GoogleCredentials object which are costly operations.
* @return FCMUtil instance
*/
public static FCMUtil getInstance() {
if (instance == null) {
synchronized (FCMUtil.class) {
if (instance == null) {
instance = new FCMUtil();
}
}
}
return instance;
}
public GoogleCredentials getDefaultApplication() {
return defaultApplication;
}
public Properties getContextMetadataProperties() {
return contextMetadataProperties;
}
}

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>io.entgra.device.mgt.core.parent</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>io.entgra.device.mgt.core</groupId>
<version>5.0.42-SNAPSHOT</version>
<version>5.2.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save