resolved merging conflicts

revert-70aa11f8
lasantha 7 years ago
commit 7ec652a910

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Annotations</name>
<description>WSO2 Carbon - API Management Custom Annotation Module</description>

@ -21,12 +21,12 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - API Application Management API</name>

@ -22,12 +22,12 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Application Management</name>

@ -21,13 +21,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.handlers</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Security Handler Component</name>
<description>WSO2 Carbon - API Management Security Handler Module</description>

@ -13,13 +13,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.client</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Integration Client</name>
<description>WSO2 Carbon - API Management Integration Client</description>

@ -13,13 +13,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.generated.client</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Integration Generated Client</name>
<description>WSO2 Carbon - API Management Integration Client</description>

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.webapp.publisher</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Webapp Publisher</name>
<description>WSO2 Carbon - API Management Webapp Publisher</description>

@ -22,13 +22,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apimgt-extensions</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - API Management Extensions Component</name>
<url>http://wso2.org</url>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,13 +21,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Certificate Management Core</name>
<description>WSO2 Carbon - Certificate Management Core</description>

@ -22,14 +22,14 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - Certificate Management Component</name>
<url>http://wso2.org</url>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>carbon-devicemgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -0,0 +1,52 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import java.util.List;
@ApiModel(value = "RemoteSessionInfo", description = "Template of the remote session")
public class RemoteSessionInfo {
@ApiModelProperty(name = "Server Url", value = "Url of the remote session server.", required = true)
private String serverUrl;
@ApiModelProperty(name = "isEnabled", value = "Is remote session functionality enabled", required = true)
private Boolean isEnabled;
public String getServerUrl() {
return serverUrl;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
public Boolean getEnabled() {
return isEnabled;
}
public void setEnabled(Boolean enabled) {
isEnabled = enabled;
}
}

@ -81,7 +81,7 @@ import javax.ws.rs.core.Response;
)
@Path("/geo-services")
@Api(value = "Geo Service",
description = "This carries all the resources related to the geo service functionalities.")
description = "This carries all the resources related to the geo service functionalities.")
public interface GeoLocationBasedService {
/**
* Retrieve Analytics for the device type
@ -152,6 +152,79 @@ public interface GeoLocationBasedService {
required = true)
@QueryParam("to") long to);
/**
* Get data to show device locations in a map
*/
@GET
@Path("stats/deviceLocations")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve locations of devices",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics-view")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid parameters found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response getGeoDeviceLocations(
@ApiParam(
name = "minLat",
value = "minimum latitude",
required = true)
@QueryParam("minLat") double minLat,
@ApiParam(
name = "maxLat",
value = "maxmimum latitude",
required = true)
@QueryParam("maxLat") double maxLat,
@ApiParam(
name = "minLong",
value = "minimum longitude",
required = true)
@QueryParam("minLong") double minLong,
@ApiParam(
name = "maxLong",
value = "maximum longitudeude",
required = true)
@QueryParam("maxLong") double maxLong,
@ApiParam(
name = "zoom",
value = "zoom level",
required = true)
@QueryParam("zoom") int zoom);
/**
* Create Geo alerts
*/

@ -0,0 +1,130 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.jaxrs.service.api;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.constraints.Size;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "remote_session_services"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/remote-session-services"),
})
}
),
tags = {
@Tag(name = "device_management", description = "")
}
)
@Scopes(
scopes = {
@Scope(
name = "Remote Session Connection",
description = "",
key = "perm:remote-session-service:connect",
permissions = {"/device-mgt/devices/owning-device/remote-session"}
)
}
)
@Path("/remote-session-services")
@Api(value = "Remote Session Service",
description = "This carries all the resources related to the remote session service functionality.")
public interface RemoteSessionService {
/**
* Retrieve Analytics for the device type
*/
@GET
@Path("connection/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve Connection Information for the device type",
notes = "",
response = Response.class,
tags = "Remote Session Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:remote-session-service:connect")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response getRemoteSessionDeviceConnect(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "device-type",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("deviceType")
@Size(max = 45)
String deviceType);
}

@ -33,12 +33,13 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.geo.service.Alert;
import org.wso2.carbon.device.mgt.common.geo.service.Event;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFence;
import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationBasedServiceException;
import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService;
import org.wso2.carbon.device.mgt.common.geo.service.*;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.core.geo.GeoCluster;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
import org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy.GeoHashLengthStrategy;
import org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy.ZoomGeoHashLengthStrategy;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import org.wso2.carbon.device.mgt.jaxrs.service.api.GeoLocationBasedService;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
@ -47,15 +48,7 @@ import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtUtil;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.HashMap;
@ -110,11 +103,11 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain);
AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI();
List<SearchResultEntry> searchResults = analyticsDataAPI.search(tenantId, tableName, query,
0,
100,
sortByFields);
0,
100,
sortByFields);
List<Event> events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList<String>(),
searchResults);
searchResults);
return Response.ok().entity(events).build();
} catch (AnalyticsException | UserStoreException e) {
log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e);
@ -127,6 +120,34 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
}
}
@Path("stats/deviceLocations")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoDeviceLocations(
@QueryParam("minLat") double minLat,
@QueryParam("maxLat") double maxLat,
@QueryParam("minLong") double minLong,
@QueryParam("maxLong") double maxLong,
@QueryParam("zoom") int zoom) {
GeoHashLengthStrategy geoHashLengthStrategy = new ZoomGeoHashLengthStrategy();
GeoCoordinate southWest = new GeoCoordinate(minLat, minLong);
GeoCoordinate northEast = new GeoCoordinate(maxLat, maxLong);
int geohashLength = geoHashLengthStrategy.getGeohashLength(southWest, northEast, zoom);
DeviceManagementProviderService deviceManagementService = DeviceMgtAPIUtils.getDeviceManagementService();
List<GeoCluster> geoClusters;
try {
geoClusters = deviceManagementService.findGeoClusters(southWest, northEast, geohashLength);
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving geo clusters ";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
}
return Response.ok().entity(geoClusters).build();
}
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@POST
@Consumes("application/json")
@ -312,11 +333,11 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain);
AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI();
List<SearchResultEntry> searchResults = analyticsDataAPI.search(tenantId, tableName, query,
0,
100,
sortByFields);
0,
100,
sortByFields);
List<Event> events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList<String>(),
searchResults);
searchResults);
return Response.ok().entity(events).build();
} catch (AnalyticsException | UserStoreException e) {
log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e);

@ -0,0 +1,68 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
import org.wso2.carbon.device.mgt.core.config.remote.session.RemoteSessionConfiguration;
import org.wso2.carbon.device.mgt.jaxrs.beans.RemoteSessionInfo;
import org.wso2.carbon.device.mgt.jaxrs.service.api.RemoteSessionService;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
/**
* The api for
*/
public class RemoteSessionServiceImpl implements RemoteSessionService {
private static Log log = LogFactory.getLog(RemoteSessionServiceImpl.class);
@Path("connect/{deviceType}/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getRemoteSessionDeviceConnect(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType) {
//First, check whether the remote session is enabled.
RemoteSessionInfo sessionInfo = new RemoteSessionInfo();
sessionInfo.setEnabled(false);
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance()
.getDeviceManagementConfig();
if (deviceManagementConfig != null) {
RemoteSessionConfiguration remoteSessionConfiguration = deviceManagementConfig.getRemoteSessionConfiguration();
if (remoteSessionConfiguration != null) {
boolean isEnabled = remoteSessionConfiguration.isEnabled();
sessionInfo.setEnabled(isEnabled);
if (isEnabled) {
sessionInfo.setServerUrl(remoteSessionConfiguration.getRemoteSessionServerUrl());
}
return Response.ok().entity(sessionInfo).build();
}
}
return Response.ok().entity(sessionInfo).build();
}
}

@ -38,6 +38,7 @@
<ref bean="userManagementAdminService"/>
<ref bean="groupManagementService"/>
<ref bean="geoService"/>
<ref bean="remoteSessionService"/>
<ref bean="groupManagementAdminService"/>
<ref bean="applicationManagementAdminService"/>
<ref bean="deviceTypeManagementAdminService"/>
@ -81,6 +82,7 @@
<bean id="userManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.UserManagementServiceImpl"/>
<bean id="groupManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.GroupManagementServiceImpl"/>
<bean id="geoService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.GeoLocationBasedServiceImpl"/>
<bean id="remoteSessionService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.RemoteSessionServiceImpl"/>
<bean id="deviceManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceManagementAdminServiceImpl"/>
<bean id="applicationManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.ApplicationManagementAdminServiceImpl"/>
<bean id="groupManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.GroupManagementAdminServiceImpl"/>
@ -99,4 +101,4 @@
</cxf:inInterceptors>
</cxf:bus>
</beans>
</beans>

@ -30,6 +30,7 @@ import org.testng.IObjectFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.caching.impl.CacheImpl;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
@ -93,7 +94,6 @@ public class DeviceAgentServiceTest {
private static final String TEST_DEVICE_TYPE = "TEST-DEVICE-TYPE";
private static final String TEST_DEVICE_IDENTIFIER = "11222334455";
private static final String AUTHENTICATED_USER = "admin";
private static final String TENANT_DOMAIN = "carbon.super";
private static final String MONITOR_OPERATION = "POLICY_MONITOR";
private static Device demoDevice;
@ -119,35 +119,32 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test device Enrollment when the device is null")
public void testEnrollDeviceWithDeviceIsNULL() {
public void testEnrollDeviceWithNullDevice() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceAgentService.enrollDevice(null);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The response status should be 400");
}
@Test(description = "Test device enrollment when device type is null.")
public void testEnrollDeviceWithDeviceTypeNull() {
public void testEnrollDeviceWithNullDeviceType() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Device device = DeviceMgtAPITestHelper.generateDummyDevice(null, TEST_DEVICE_IDENTIFIER);
Response response = this.deviceAgentService.enrollDevice(device);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The response status should be 400");
}
@Test(description = "Test device enrollment of a device with null device identifier.")
public void testEnrollNewDeviceWithDeviceIdentifierIsNull() {
public void testEnrollNewDeviceWithNullDeviceIdentifier() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Device device = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, null);
Response response = this.deviceAgentService.enrollDevice(device);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The response status should be 400");
@ -173,12 +170,10 @@ public class DeviceAgentServiceTest {
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser"))
.toReturn(AUTHENTICATED_USER);
EnrolmentInfo enrolmentInfo = demoDevice.getEnrolmentInfo();
enrolmentInfo.setStatus(EnrolmentInfo.Status.INACTIVE);
demoDevice.setEnrolmentInfo(enrolmentInfo);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(demoDevice);
Response response = this.deviceAgentService.enrollDevice(demoDevice);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
@ -187,12 +182,11 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test the device enrollment with device management exception.")
public void testEnrollDeviceWithException() throws DeviceManagementException {
public void testEnrollDeviceWithDeviceManagementException() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser"))
.toReturn(AUTHENTICATED_USER);
Device device = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo();
enrolmentInfo.setStatus(EnrolmentInfo.Status.INACTIVE);
@ -200,7 +194,6 @@ public class DeviceAgentServiceTest {
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(device);
Mockito.when(this.deviceManagementProviderService.enrollDevice(Mockito.any()))
.thenThrow(new DeviceManagementException());
Response response = this.deviceAgentService.enrollDevice(device);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
@ -221,7 +214,7 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test dis-enrolling non existing device.")
public void testDisEnrollNonExistingDevice() throws DeviceManagementException {
public void testDisEnrollWithNonExistingDevice() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = deviceAgentService.disEnrollDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
@ -230,8 +223,8 @@ public class DeviceAgentServiceTest {
"The response status should be 204");
}
@Test(description = "Test dis-enrolling device error")
public void testDisEnrollingDeviceError() throws DeviceManagementException {
@Test(description = "Test dis-enrolling device where device management exception is thrown.")
public void testDisEnrollingDeviceWithDeviceManagementException() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any())).thenThrow(new
@ -244,14 +237,13 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test device update scenario with device management exception.")
public void testUpdateDeviceDMException() throws DeviceManagementException {
public void testUpdateDeviceWithDeviceManagementException() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenThrow(new
DeviceManagementException());
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
@ -263,20 +255,18 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, null);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The response status should be 400");
}
@Test(description = "Test the update device scenario when there is no enrolled device.")
public void testUpdatingNonExistingDevice() throws DeviceManagementException {
public void testUpdateDeviceWithNonExistingDevice() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(null);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
"The response status should be 404");
@ -284,14 +274,13 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test update device with device access authorization exception.")
public void testEnrollDeviceWithDeviceAccessAuthException() throws DeviceManagementException,
public void testEnrollDeviceWithDeviceAccessAuthorizationException() throws DeviceManagementException,
DeviceAccessAuthorizationException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenThrow(new DeviceAccessAuthorizationException());
@ -311,7 +300,6 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(false);
@ -324,16 +312,15 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test update device when device modification is unsuccessful.")
public void testUpdateDeviceNOTModify() throws DeviceManagementException, DeviceAccessAuthorizationException {
public void testUpdateDeviceWithUnsuccessfulDeviceModification() throws DeviceManagementException,
DeviceAccessAuthorizationException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getAuthenticatedUser")).toReturn(AUTHENTICATED_USER);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(true);
@ -347,20 +334,20 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test updating device when modify enrollment throws exception")
public void testUpdateDeviceWithModifyEnrollmentFailure() throws DeviceManagementException, DeviceAccessAuthorizationException {
public void testUpdateDeviceWithModifyEnrollmentFailure() throws DeviceManagementException,
DeviceAccessAuthorizationException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getAuthenticatedUser")).toReturn(AUTHENTICATED_USER);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(true);
Mockito.when(this.deviceManagementProviderService.modifyEnrollment(Mockito.any())).thenThrow(new DeviceManagementException());
Mockito.when(this.deviceManagementProviderService.modifyEnrollment(Mockito.any()))
.thenThrow(new DeviceManagementException());
Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
@ -377,9 +364,7 @@ public class DeviceAgentServiceTest {
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getAuthenticatedUser")).toReturn(AUTHENTICATED_USER);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(true);
@ -396,14 +381,13 @@ public class DeviceAgentServiceTest {
public void testPublishEventsWithNullPayload() {
PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(this.privilegedCarbonContext);
Mockito.when(this.privilegedCarbonContext.getTenantDomain()).thenReturn(TENANT_DOMAIN);
Mockito.when(this.privilegedCarbonContext.getTenantDomain())
.thenReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
Map<String, Object> payload = null;
Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The response status should be 400");
List<Object> payloadList = null;
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
@ -413,47 +397,47 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test publish events with no device access authorization.")
public void testPublishEventsWithOutAuthorization() throws DeviceAccessAuthorizationException {
public void testPublishEventsWithoutAuthorization() throws DeviceAccessAuthorizationException {
PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(this.privilegedCarbonContext);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(false);
Mockito.when(this.privilegedCarbonContext.getTenantDomain()).thenReturn(TENANT_DOMAIN);
Mockito.when(this.privilegedCarbonContext.getTenantDomain())
.thenReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
Map<String, Object> payload = new HashMap<>();
Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
"The response status should be 401");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(),
"The response status should be 401");
Mockito.reset(this.deviceAccessAuthorizationService);
}
@Test
public void testPublishEventsWithDeviceAccessAuthException() throws DeviceAccessAuthorizationException {
@Test(description = "Test publish events when device access authorization exception is thrown.")
public void testPublishEventsWithDeviceAccessAuthorizationException() throws DeviceAccessAuthorizationException {
PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(this.privilegedCarbonContext);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService"))
.toReturn(this.deviceAccessAuthorizationService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenThrow(new DeviceAccessAuthorizationException());
Mockito.when(this.privilegedCarbonContext.getTenantDomain()).thenReturn(TENANT_DOMAIN);
Mockito.when(this.privilegedCarbonContext.getTenantDomain())
.thenReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
Map<String, Object> payload = new HashMap<>();
Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
@ -461,30 +445,28 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test event publishing when the event stream dao is null.")
public void testEventPublishWithNullEventAttributesAndNullEventStreamDefDAO() throws DeviceAccessAuthorizationException, RemoteException {
public void testEventPublishWithNullEventAttributesAndNullEventStreamDefDAO()
throws DeviceAccessAuthorizationException, RemoteException {
PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(this.privilegedCarbonContext);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService"))
.toReturn(this.deviceAccessAuthorizationService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(true);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub"))
.toReturn(this.eventStreamAdminServiceStub);
Mockito.when(this.eventStreamAdminServiceStub.getStreamDefinitionDto(Mockito.anyString())).thenReturn(null);
Map<String, Object> payload = new HashMap<>();
CacheImpl cache = Mockito.mock(CacheImpl.class);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache"))
.toReturn(cache);
Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The response status should be 400");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The response status should be 400");
@ -511,22 +493,19 @@ public class DeviceAgentServiceTest {
Mockito.when(eventStreamDefinitionDto.getPayloadData()).thenReturn(new EventStreamAttributeDto[]{});
EventsPublisherService eventPublisherService = Mockito.mock(EventsPublisherServiceImpl.class,
Mockito.RETURNS_MOCKS);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventPublisherService")).toReturn
(eventPublisherService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventPublisherService"))
.toReturn(eventPublisherService);
Map<String, Object> payload = new HashMap<>();
CacheImpl cache = Mockito.mock(CacheImpl.class);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache"))
.toReturn(cache);
Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
@ -552,31 +531,29 @@ public class DeviceAgentServiceTest {
Mockito.when(eventStreamDefinitionDto.getPayloadData()).thenReturn(new EventStreamAttributeDto[]{});
EventsPublisherService eventPublisherService = Mockito.mock(EventsPublisherServiceImpl.class,
Mockito.RETURNS_MOCKS);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventPublisherService")).toReturn
(eventPublisherService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventPublisherService"))
.toReturn(eventPublisherService);
Mockito.when(eventPublisherService.publishEvent(Mockito.anyString(), Mockito.anyString(), Mockito.any(),
Mockito.any(), Mockito.any())).thenReturn(true);
Map<String, Object> payload = new HashMap<>();
CacheImpl cache = Mockito.mock(CacheImpl.class);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache"))
.toReturn(cache);
Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The response status should be 200");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList,
TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.OK.getStatusCode(),
"The response status should be 200");
}
@Test(description = "Test event publishing when PublishEvents throws DataPublisherConfigurationException.")
public void testPublishEventsDataPublisherConfig() throws DeviceAccessAuthorizationException, RemoteException, DataPublisherConfigurationException {
public void testPublishEventsDataPublisherConfigurationException() throws DeviceAccessAuthorizationException,
RemoteException, DataPublisherConfigurationException {
PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(this.privilegedCarbonContext);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
@ -599,24 +576,20 @@ public class DeviceAgentServiceTest {
Mockito.when(eventPublisherService.publishEvent(Mockito.anyString(), Mockito.anyString(), Mockito.any(),
Mockito.any(), Mockito.any())).thenThrow(
new DataPublisherConfigurationException("meta data[0] should have the device Id field"));
Map<String, Object> payload = new HashMap<>();
CacheImpl cache = Mockito.mock(CacheImpl.class);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache"))
.toReturn(cache);
Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
}
@Test(description = "Test Publish events with Axis Fault.")
@ -631,17 +604,15 @@ public class DeviceAgentServiceTest {
.toThrow(new AxisFault(""));
Map<String, Object> payload = new HashMap<>();
CacheImpl cache = Mockito.mock(CacheImpl.class);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache"))
.toReturn(cache);
Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
@ -659,7 +630,6 @@ public class DeviceAgentServiceTest {
.toThrow(new RemoteException());
Map<String, Object> payload = new HashMap<>();
CacheImpl cache = Mockito.mock(CacheImpl.class);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache"))
.toReturn(cache);
@ -669,7 +639,8 @@ public class DeviceAgentServiceTest {
"The response status should be 500");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
@ -687,7 +658,6 @@ public class DeviceAgentServiceTest {
.toThrow(new JWTClientException());
Map<String, Object> payload = new HashMap<>();
CacheImpl cache = Mockito.mock(CacheImpl.class);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache"))
.toReturn(cache);
@ -697,7 +667,8 @@ public class DeviceAgentServiceTest {
"The response status should be 500");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
@ -715,7 +686,6 @@ public class DeviceAgentServiceTest {
.toThrow(new UserStoreException());
Map<String, Object> payload = new HashMap<>();
CacheImpl cache = Mockito.mock(CacheImpl.class);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache"))
.toReturn(cache);
@ -725,7 +695,8 @@ public class DeviceAgentServiceTest {
"The response status should be 500");
List<Object> payloadList = new ArrayList<>();
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response2, "Response should not be null");
Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
@ -753,9 +724,7 @@ public class DeviceAgentServiceTest {
.toReturn(false);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode(),
@ -771,9 +740,7 @@ public class DeviceAgentServiceTest {
.toReturn(true);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertNotNull(response.getEntity(), "Response entity should not be null.");
@ -783,16 +750,15 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test the scenario when get pending operations throw OperationManagementException.")
public void testGetPendingOperationsWithOperationManagementException() throws DeviceManagementException, OperationManagementException {
public void testGetPendingOperationsWithOperationManagementException() throws DeviceManagementException,
OperationManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier"))
.toReturn(true);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getPendingOperations(Mockito.any())).thenThrow(new
OperationManagementException());
Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
@ -811,7 +777,6 @@ public class DeviceAgentServiceTest {
.toReturn(true);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenThrow(new DeviceManagementException());
Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertNotNull(response.getEntity(), "Response entity should not be null.");
@ -825,8 +790,7 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(new ArrayList<String>() {
});
.thenReturn(new ArrayList<String>() {});
Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
@ -842,9 +806,7 @@ public class DeviceAgentServiceTest {
.toReturn(false);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
@ -860,9 +822,7 @@ public class DeviceAgentServiceTest {
.toReturn(true);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertNotNull(response.getEntity(), "Response entity should not be null.");
@ -872,18 +832,17 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test get next pending operation with operation management exception.")
public void getNextPendingOperationWithOperationManagementException() throws DeviceManagementException, OperationManagementException {
public void getNextPendingOperationWithOperationManagementException() throws DeviceManagementException,
OperationManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier"))
.toReturn(true);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getNextPendingOperation(Mockito.any())).thenThrow(new
OperationManagementException());
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getNextPendingOperation(Mockito.any())).thenThrow(
new OperationManagementException());
Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertNotNull(response.getEntity(), "Response entity should not be null.");
@ -900,7 +859,6 @@ public class DeviceAgentServiceTest {
.toReturn(true);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenThrow(new DeviceManagementException());
Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertNotNull(response.getEntity(), "Response entity should not be null.");
@ -914,10 +872,8 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(new ArrayList<String>() {
});
.thenReturn(new ArrayList<String>() {});
Operation operation = new Operation();
Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
operation);
Assert.assertNotNull(response, "The response should not be null");
@ -930,11 +886,9 @@ public class DeviceAgentServiceTest {
public void testUpdateOperationWithNullOperation() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
null);
Assert.assertNotNull(response, "The response should not be null");
@ -949,13 +903,10 @@ public class DeviceAgentServiceTest {
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier"))
.toReturn(false);
Operation operation = new Operation();
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
operation);
Assert.assertNotNull(response, "The response should not be null");
@ -970,13 +921,10 @@ public class DeviceAgentServiceTest {
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier"))
.toReturn(true);
Operation operation = new Operation();
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
operation);
Assert.assertNotNull(response, "The response should not be null");
@ -986,7 +934,8 @@ public class DeviceAgentServiceTest {
}
@Test(description = "Test the update Operation method with Policy Monitoring Operation.")
public void testUpdateOperationSuccessWithPolicyMonitorOperation() throws DeviceManagementException, PolicyComplianceException {
public void testUpdateOperationSuccessWithPolicyMonitorOperation() throws DeviceManagementException,
PolicyComplianceException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier"))
@ -1003,9 +952,7 @@ public class DeviceAgentServiceTest {
operation.setPayLoad(null);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
operation);
Assert.assertNotNull(response, "The response should not be null");
@ -1024,12 +971,9 @@ public class DeviceAgentServiceTest {
Operation operation = new Operation();
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Mockito.doThrow(new OperationManagementException()).when(this.deviceManagementProviderService)
.updateOperation(Mockito.any(), Mockito.any());
Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
operation);
Assert.assertNotNull(response, "The response should not be null");
@ -1050,7 +994,6 @@ public class DeviceAgentServiceTest {
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenThrow(new DeviceManagementException());
Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
operation);
Assert.assertNotNull(response, "The response should not be null");
@ -1079,9 +1022,7 @@ public class DeviceAgentServiceTest {
operation.setPayLoad(null);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
operation);
Assert.assertNotNull(response, "The response should not be null");
@ -1104,9 +1045,8 @@ public class DeviceAgentServiceTest {
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(new ArrayList<String>() {});
Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
Operation.Status.COMPLETED);
Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER, Operation.Status.COMPLETED);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The response status should be 400");
@ -1116,14 +1056,11 @@ public class DeviceAgentServiceTest {
public void testGetOperationSuccess() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
Operation.Status.COMPLETED);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER, Operation.Status.COMPLETED);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The response status should be 200");
@ -1134,16 +1071,13 @@ public class DeviceAgentServiceTest {
OperationManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getOperationsByDeviceAndStatus(Mockito.any(), Mockito.any()
)).thenThrow(new OperationManagementException());
Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
Operation.Status.COMPLETED);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes);
Mockito.when(this.deviceManagementProviderService.getOperationsByDeviceAndStatus(Mockito.any(), Mockito.any()))
.thenThrow(new OperationManagementException());
Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER, Operation.Status.COMPLETED);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");
@ -1154,13 +1088,12 @@ public class DeviceAgentServiceTest {
public void testGetOperationsWithDeviceManagementException() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
List<String> deviceTypes = new ArrayList<>();
deviceTypes.add(TEST_DEVICE_TYPE);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes())
.thenThrow(new DeviceManagementException());
Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER,
Operation.Status.COMPLETED);
Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE,
TEST_DEVICE_IDENTIFIER, Operation.Status.COMPLETED);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500");

@ -31,8 +31,10 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
@ -553,4 +555,51 @@ public class DeviceManagementServiceImplTest {
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Expects to return HTTP 500 when an exception occurred while getting effective policy of the device");
}
@Test(description = "Testing changing device status")
public void testChangeDeviceStatus() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceManagementService
.changeDeviceStatus(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), EnrolmentInfo.Status.INACTIVE);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
}
@Test(description = "Testing changing device status when device does not exist")
public void testChangeDeviceStatusWhenDeviceNotExists() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService
.getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())).thenReturn(null);
Response response = this.deviceManagementService
.changeDeviceStatus(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), EnrolmentInfo.Status.INACTIVE);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
Mockito.reset(this.deviceManagementProviderService);
}
@Test(description = "Testing changing device status when device cannot be retrieved")
public void testChangeDeviceStatusException() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService
.getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean()))
.thenThrow(new DeviceManagementException());
Response response = this.deviceManagementService
.changeDeviceStatus(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), EnrolmentInfo.Status.ACTIVE);
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
Mockito.reset(this.deviceManagementProviderService);
}
@Test(description = "Testing changing device status when unable to change device status")
public void testChangeDeviceStatusWhenUnableToChangeStatus() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService
.changeDeviceStatus(Mockito.any(DeviceIdentifier.class), Mockito.any()))
.thenThrow(new DeviceManagementException());
Response response = this.deviceManagementService
.changeDeviceStatus(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), EnrolmentInfo.Status.ACTIVE);
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
Mockito.reset(this.deviceManagementProviderService);
}
}

@ -83,24 +83,18 @@ public class DeviceTypeManagementAdminServiceTest {
public void testGetDeviceTypes() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceTypeManagementAdminService.getDeviceTypes();
log.info(response.getEntity());
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "The Response status code " +
"should be 200.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The Response status code should be 200.");
}
@Test(description = "Test the error scenario of getting all the device types.")
public void testGetDeviceTypesError() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(deviceManagementProviderService.getDeviceTypes()).thenThrow(new DeviceManagementException());
Response response = this.deviceTypeManagementAdminService.getDeviceTypes();
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The expected status code is 500.");
@ -111,12 +105,8 @@ public class DeviceTypeManagementAdminServiceTest {
public void testAddDeviceTypeWithExistingName() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE_1, TEST_DEVICE_TYPE_ID_1);
Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType);
log.info(response.getEntity());
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.CONFLICT.getStatusCode(),
"The Response Status code should be 409.");
@ -126,14 +116,9 @@ public class DeviceTypeManagementAdminServiceTest {
public void testAddDeviceTypeWithUnqualifiedName() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null);
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE_2, TEST_DEVICE_TYPE_ID_2);
Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType);
log.info(response.getEntity());
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The Response Status code should be 400.");
@ -146,12 +131,9 @@ public class DeviceTypeManagementAdminServiceTest {
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceTypeGeneratorService"))
.toReturn(this.deviceTypeGeneratorService);
Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null);
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The Response Status code should be 200.");
@ -162,11 +144,7 @@ public class DeviceTypeManagementAdminServiceTest {
public void testAddDeviceTypeWithNoDeviceType() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceTypeManagementAdminService.addDeviceType(null);
log.info(response.getEntity());
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The Response Status code should be 409.");
@ -178,10 +156,8 @@ public class DeviceTypeManagementAdminServiceTest {
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenThrow(new
DeviceManagementException());
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The Response Status code should be 500.");
@ -194,10 +170,8 @@ public class DeviceTypeManagementAdminServiceTest {
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceTypeGeneratorService"))
.toReturn(this.deviceTypeGeneratorService);
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The Response Status code should be 200.");
@ -210,10 +184,8 @@ public class DeviceTypeManagementAdminServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceTypeGeneratorService"))
.toReturn(this.deviceTypeGeneratorService);
Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null);
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The Response Status code should be 400.");
@ -224,9 +196,7 @@ public class DeviceTypeManagementAdminServiceTest {
public void testUpdateDeviceTypeWithNullDeviceType() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(null);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The Response Status code should be 400.");
@ -237,13 +207,10 @@ public class DeviceTypeManagementAdminServiceTest {
public void testUpdateDeviceTypeWithException() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString()))
.thenThrow(new DeviceManagementException());
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The Response Status code should be 500.");

@ -89,7 +89,6 @@ public class DeviceTypeManagementServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenThrow(new DeviceManagementException());
Response response = this.deviceTypeManagementService.getDeviceTypes();
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
@ -103,7 +102,6 @@ public class DeviceTypeManagementServiceTest {
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenThrow(new
DeviceManagementException());
Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
@ -163,10 +161,8 @@ public class DeviceTypeManagementServiceTest {
public void testGetDeviceTypesWithDeviceTypes() throws Exception {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
List<DeviceType> deviceTypes = DeviceMgtAPITestHelper.getDummyDeviceTypeList(5);
Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceTypeManagementService.getDeviceTypes();
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
@ -189,7 +185,6 @@ public class DeviceTypeManagementServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null);
Response response = this.deviceTypeManagementService.getDeviceTypeByName(TEST_DEVICE_TYPE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode(),
@ -203,7 +198,6 @@ public class DeviceTypeManagementServiceTest {
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString()))
.thenThrow(new DeviceManagementException());
Response response = this.deviceTypeManagementService.getDeviceTypeByName(TEST_DEVICE_TYPE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
@ -227,10 +221,8 @@ public class DeviceTypeManagementServiceTest {
Method clearMetaEntryInfo = DeviceTypeManagementServiceImpl.class.getDeclaredMethod("clearMetaEntryInfo",
DeviceType.class);
clearMetaEntryInfo.setAccessible(true);
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
DeviceType returned = (DeviceType) clearMetaEntryInfo.invoke(this.deviceTypeManagementService, deviceType);
Assert.assertNotNull(returned.getDeviceTypeMetaDefinition(), "The response object is null.");
}
}

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -0,0 +1,49 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival;
public class ArchivalException extends Exception {
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public ArchivalException(String message) {
super(message);
setErrorMessage(message);
}
public ArchivalException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
protected ArchivalException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
setErrorMessage(message);
}
}

@ -0,0 +1,26 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival;
public interface ArchivalService {
void archiveTransactionalRecords() throws ArchivalException;
void deleteArchivedRecords() throws ArchivalException;
}

@ -0,0 +1,220 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.core.archival.dao.*;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ArchivalServiceImpl implements ArchivalService {
private static Log log = LogFactory.getLog(ArchivalServiceImpl.class);
private ArchivalDAO archivalDAO;
private DataDeletionDAO dataDeletionDAO;
private static int ITERATION_COUNT = 10000;
private String[] NOT_IN_PROGRESS_OPS = new String[]{"COMPLETED", "ERROR", "REPEATED"};
private String[] NOT_PENDING_OPS = new String[]{"COMPLETED", "ERROR", "REPEATED", "IN_PROGRESS"};
private String[] NOT_PENDING_IN_PROGRESS_OPS = new String[]{"COMPLETED", "ERROR", "REPEATED"};
public ArchivalServiceImpl() {
this.archivalDAO = ArchivalSourceDAOFactory.getDataPurgingDAO();
this.dataDeletionDAO = ArchivalDestinationDAOFactory.getDataDeletionDAO();
}
@Override
public void archiveTransactionalRecords() throws ArchivalException {
try {
ArchivalSourceDAOFactory.openConnection();
ArchivalDestinationDAOFactory.openConnection();
List<Integer> allOperations = archivalDAO.getAllOperations();
List<Integer> pendingAndIPOperations = archivalDAO.getPendingAndInProgressOperations();
log.info(allOperations.size() + " All Operations. " + pendingAndIPOperations.size() +
" P&IP Operations");
//Get the diff of operations
Set<Integer> setA = new HashSet<>(allOperations);
Set<Integer> setB = new HashSet<>(pendingAndIPOperations);
setA.removeAll(setB);
List<Integer> candidates = new ArrayList<>();
candidates.addAll(setA);
int total = candidates.size();
int batches = calculateNumberOfBatches(total);
int batchSize = ITERATION_COUNT;
if (log.isDebugEnabled()) {
log.debug(total + " Operations ready for archiving. " + batches + " iterations to be done.");
}
beginTransactions();
for (int i = 1; i <= batches; i++) {
int startIdx = batchSize * (i - 1);
int endIdx = batchSize * i;
if (i == batches) {
endIdx = startIdx + (total % batchSize);
}
if(log.isDebugEnabled()) {
log.debug("\n\n############ Iterating over batch " + i + "[" +
startIdx + "," + endIdx + "] #######");
}
List<Integer> subList = candidates.subList(startIdx, endIdx);
prepareTempTable(subList);
//Purge the largest table, DM_DEVICE_OPERATION_RESPONSE
if (log.isDebugEnabled()) {
log.debug("## Purging operation responses");
}
archivalDAO.moveOperationResponses();
//Purge the notifications table, DM_NOTIFICATION
if (log.isDebugEnabled()) {
log.debug("## Purging notifications");
}
archivalDAO.moveNotifications();
//Purge the command operations table, DM_COMMAND_OPERATION
if (log.isDebugEnabled()) {
log.debug("## Purging command operations");
}
archivalDAO.moveCommandOperations();
//Purge the profile operation table, DM_PROFILE_OPERATION
if (log.isDebugEnabled()) {
log.debug("## Purging profile operations");
}
archivalDAO.moveProfileOperations();
//Purge the enrolment mappings table, DM_ENROLMENT_OP_MAPPING
if (log.isDebugEnabled()) {
log.debug("## Purging enrolment mappings");
}
archivalDAO.moveEnrolmentMappings();
//Finally, purge the operations table, DM_OPERATION
if (log.isDebugEnabled()) {
log.debug("## Purging operations");
}
archivalDAO.moveOperations();
}
commitTransactions();
} catch (ArchivalDAOException e) {
rollbackTransactions();
throw new ArchivalException("An error occurred while data archival", e);
} catch (SQLException e) {
throw new ArchivalException("An error occurred while connecting to the archival database.", e);
} finally {
ArchivalSourceDAOFactory.closeConnection();
ArchivalDestinationDAOFactory.closeConnection();
}
}
private void prepareTempTable(List<Integer> subList) throws ArchivalDAOException {
//Clean up the DM_ARCHIVED_OPERATIONS table
if (log.isDebugEnabled()) {
log.debug("## Truncating the temporary table");
}
archivalDAO.truncateOperationIDsForArchival();
archivalDAO.copyOperationIDsForArchival(subList);
}
private void beginTransactions() throws ArchivalException {
try {
ArchivalSourceDAOFactory.beginTransaction();
ArchivalDestinationDAOFactory.beginTransaction();
} catch (TransactionManagementException e) {
log.error("An error occurred during starting transactions", e);
throw new ArchivalException("An error occurred during starting transactions", e);
}
}
private void commitTransactions() {
ArchivalSourceDAOFactory.commitTransaction();
ArchivalDestinationDAOFactory.commitTransaction();
}
private void rollbackTransactions() {
ArchivalSourceDAOFactory.rollbackTransaction();
ArchivalDestinationDAOFactory.rollbackTransaction();
}
private int calculateNumberOfBatches(int total) {
int batches = 0;
int batchSize = ITERATION_COUNT;
if ((total % batchSize) > 0) {
batches = (total / batchSize) + 1;
} else {
batches = total / batchSize;
}
return batches;
}
@Override
public void deleteArchivedRecords() throws ArchivalException {
try {
ArchivalDestinationDAOFactory.openConnection();
if (log.isDebugEnabled()) {
log.debug("## Deleting operation responses");
}
dataDeletionDAO.deleteOperationResponses();
if (log.isDebugEnabled()) {
log.debug("## Deleting notifications ");
}
dataDeletionDAO.deleteNotifications();
if (log.isDebugEnabled()) {
log.debug("## Deleting command operations");
}
dataDeletionDAO.deleteCommandOperations();
if (log.isDebugEnabled()) {
log.debug("## Deleting profile operations ");
}
dataDeletionDAO.deleteProfileOperations();
if (log.isDebugEnabled()) {
log.debug("## Deleting enrolment mappings ");
}
dataDeletionDAO.deleteEnrolmentMappings();
if (log.isDebugEnabled()) {
log.debug("## Deleting operations ");
}
dataDeletionDAO.deleteOperations();
} catch (SQLException e) {
throw new ArchivalException("An error occurred while initialising data source for archival", e);
} catch (ArchivalDAOException e) {
log.error("An error occurred while executing DataDeletionTask");
} finally {
ArchivalDestinationDAOFactory.closeConnection();
}
}
}

@ -0,0 +1,50 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.dao;
import java.util.List;
/**
* Operations to move data from DM database to archival database
*/
public interface ArchivalDAO {
int DEFAULT_BATCH_SIZE = 1000;
List<Integer> getAllOperations() throws ArchivalDAOException;
List<Integer> getPendingAndInProgressOperations() throws ArchivalDAOException;
void copyOperationIDsForArchival(List<Integer> operationIds) throws ArchivalDAOException;
void moveOperationResponses() throws ArchivalDAOException;
void moveNotifications() throws ArchivalDAOException;
void moveCommandOperations() throws ArchivalDAOException;
void moveProfileOperations() throws ArchivalDAOException;
void moveEnrolmentMappings() throws ArchivalDAOException;
void moveOperations() throws ArchivalDAOException;
void truncateOperationIDsForArchival() throws ArchivalDAOException;
}

@ -0,0 +1,50 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.core.archival.dao;
public class ArchivalDAOException extends Exception {
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public ArchivalDAOException(String message) {
super(message);
setErrorMessage(message);
}
public ArchivalDAOException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
protected ArchivalDAOException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
setErrorMessage(message);
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.core.archival.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ArchivalDAOUtil {
private static final Log log = LogFactory.getLog(ArchivalDAOUtil.class);
public static void cleanupResources(Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
log.warn("Error occurred while closing the result set", e);
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
log.warn("Error occurred while closing the statement", e);
}
}
}
public static void cleanupResources(Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
log.warn("Error occurred while closing the statement", e);
}
}
}
}

@ -0,0 +1,167 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.IllegalTransactionStateException;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.core.archival.dao.impl.DataDeletionDAOImpl;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig;
import org.wso2.carbon.device.mgt.core.config.datasource.JNDILookupDefinition;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.List;
public class ArchivalDestinationDAOFactory {
private static final Log log = LogFactory.getLog(OperationManagementDAOFactory.class);
private static DataSource dataSource;
private static String databaseEngine;
private static int retentionPeriod;
private static ThreadLocal<Connection> currentConnection = new ThreadLocal<Connection>();
public static DataDeletionDAO getDataDeletionDAO() {
return new DataDeletionDAOImpl(DeviceConfigurationManager.getInstance().getDeviceManagementConfig()
.getArchivalConfiguration().getArchivalTaskConfiguration()
.getPurgingTaskConfiguration().getRetentionPeriod());
}
public static void init(DataSource dtSource) {
dataSource = dtSource;
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
}
public static void init(DataSourceConfig config) {
dataSource = resolveDataSource(config);
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
}
public static void beginTransaction() throws TransactionManagementException {
try {
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
currentConnection.set(conn);
} catch (SQLException e) {
throw new TransactionManagementException(
"Error occurred while retrieving config.datasource connection", e);
}
}
public static void openConnection() throws SQLException {
currentConnection.set(dataSource.getConnection());
}
public static Connection getConnection() throws SQLException {
if (currentConnection.get() == null) {
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
"This might have ideally caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
}
return currentConnection.get();
}
public static void closeConnection() {
Connection con = currentConnection.get();
if (con != null) {
try {
con.close();
} catch (SQLException e) {
log.error("Error occurred while close the connection");
}
currentConnection.remove();
}
}
public static void commitTransaction() {
try {
Connection conn = currentConnection.get();
if (conn != null) {
conn.commit();
} else {
if (log.isDebugEnabled()) {
log.debug("Datasource connection associated with the current thread is null, hence commit " +
"has not been attempted");
}
}
} catch (SQLException e) {
log.error("Error occurred while committing the transaction", e);
}
}
public static void rollbackTransaction() {
try {
Connection conn = currentConnection.get();
if (conn != null) {
conn.rollback();
} else {
if (log.isDebugEnabled()) {
log.debug("Datasource connection associated with the current thread is null, hence rollback " +
"has not been attempted");
}
}
} catch (SQLException e) {
log.error("Error occurred while roll-backing the transaction", e);
}
}
/**
* Resolve data source from the data source definition
*
* @param config data source configuration
* @return data source resolved from the data source definition
*/
private static DataSource resolveDataSource(DataSourceConfig config) {
DataSource dataSource = null;
if (config == null) {
throw new RuntimeException("Device Management Repository data source configuration is null and " +
"thus, is not initialized");
}
JNDILookupDefinition jndiConfig = config.getJndiLookupDefinition();
if (jndiConfig != null) {
if (log.isDebugEnabled()) {
log.debug("Initializing Device Management Repository data source using the JNDI Lookup Definition");
}
List<JNDILookupDefinition.JNDIProperty> jndiPropertyList = jndiConfig.getJndiProperties();
if (jndiPropertyList != null) {
Hashtable<Object, Object> jndiProperties = new Hashtable<Object, Object>();
for (JNDILookupDefinition.JNDIProperty prop : jndiPropertyList) {
jndiProperties.put(prop.getName(), prop.getValue());
}
dataSource = DeviceManagementDAOUtil.lookupDataSource(jndiConfig.getJndiName(), jndiProperties);
} else {
dataSource = DeviceManagementDAOUtil.lookupDataSource(jndiConfig.getJndiName(), null);
}
}
return dataSource;
}
}

@ -0,0 +1,170 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.IllegalTransactionStateException;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.core.archival.dao.impl.ArchivalDAOImpl;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.archival.ArchivalTaskConfiguration;
import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig;
import org.wso2.carbon.device.mgt.core.config.datasource.JNDILookupDefinition;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.List;
public class ArchivalSourceDAOFactory {
private static final Log log = LogFactory.getLog(OperationManagementDAOFactory.class);
private static DataSource dataSource;
private static String databaseEngine;
private static ThreadLocal<Connection> currentConnection = new ThreadLocal<Connection>();
public static ArchivalDAO getDataPurgingDAO() {
ArchivalTaskConfiguration configuration = DeviceConfigurationManager.getInstance()
.getDeviceManagementConfig()
.getArchivalConfiguration()
.getArchivalTaskConfiguration();
return new ArchivalDAOImpl(configuration.getRetentionPeriod(), configuration.getBatchSize());
}
public static void init(DataSource dtSource) {
dataSource = dtSource;
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
}
public static void init(DataSourceConfig config) {
dataSource = resolveDataSource(config);
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
}
public static void beginTransaction() throws TransactionManagementException {
try {
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
currentConnection.set(conn);
} catch (SQLException e) {
throw new TransactionManagementException(
"Error occurred while retrieving config.datasource connection", e);
}
}
public static void openConnection() throws SQLException {
currentConnection.set(dataSource.getConnection());
}
public static Connection getConnection() throws SQLException {
if (currentConnection.get() == null) {
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
"This might have ideally caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
}
return currentConnection.get();
}
public static void closeConnection() {
Connection con = currentConnection.get();
if (con != null) {
try {
con.close();
} catch (SQLException e) {
log.error("Error occurred while close the connection");
}
currentConnection.remove();
}
}
public static void commitTransaction() {
try {
Connection conn = currentConnection.get();
if (conn != null) {
conn.commit();
} else {
if (log.isDebugEnabled()) {
log.debug("Datasource connection associated with the current thread is null, hence commit " +
"has not been attempted");
}
}
} catch (SQLException e) {
log.error("Error occurred while committing the transaction", e);
}
}
public static void rollbackTransaction() {
try {
Connection conn = currentConnection.get();
if (conn != null) {
conn.rollback();
} else {
if (log.isDebugEnabled()) {
log.debug("Datasource connection associated with the current thread is null, hence rollback " +
"has not been attempted");
}
}
} catch (SQLException e) {
log.error("Error occurred while roll-backing the transaction", e);
}
}
/**
* Resolve data source from the data source definition
*
* @param config data source configuration
* @return data source resolved from the data source definition
*/
private static DataSource resolveDataSource(DataSourceConfig config) {
DataSource dataSource = null;
if (config == null) {
throw new RuntimeException("Device Management Repository data source configuration is null and " +
"thus, is not initialized");
}
JNDILookupDefinition jndiConfig = config.getJndiLookupDefinition();
if (jndiConfig != null) {
if (log.isDebugEnabled()) {
log.debug("Initializing Device Management Repository data source using the JNDI Lookup Definition");
}
List<JNDILookupDefinition.JNDIProperty> jndiPropertyList = jndiConfig.getJndiProperties();
if (jndiPropertyList != null) {
Hashtable<Object, Object> jndiProperties = new Hashtable<Object, Object>();
for (JNDILookupDefinition.JNDIProperty prop : jndiPropertyList) {
jndiProperties.put(prop.getName(), prop.getValue());
}
dataSource = DeviceManagementDAOUtil.lookupDataSource(jndiConfig.getJndiName(), jndiProperties);
} else {
dataSource = DeviceManagementDAOUtil.lookupDataSource(jndiConfig.getJndiName(), null);
}
}
return dataSource;
}
}

@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.dao;
/**
* Operations to permanently delete data from archived database tables
*/
public interface DataDeletionDAO {
int DEFAULT_RETENTION_PERIOD = 364;
void deleteOperationResponses() throws ArchivalDAOException;
void deleteNotifications() throws ArchivalDAOException;
void deleteCommandOperations() throws ArchivalDAOException;
void deleteProfileOperations() throws ArchivalDAOException;
void deleteEnrolmentMappings() throws ArchivalDAOException;
void deleteOperations() throws ArchivalDAOException;
}

@ -0,0 +1,471 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.core.archival.dao.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class ArchivalDAOImpl implements ArchivalDAO {
private static final Log log = LogFactory.getLog(ArchivalDAOImpl.class);
private int retentionPeriod;
private int batchSize = ArchivalDAO.DEFAULT_BATCH_SIZE;
private Timestamp currentTimestamp;
public ArchivalDAOImpl(int retentionPeriod) {
this.retentionPeriod = retentionPeriod;
}
public ArchivalDAOImpl(int retentionPeriod, int batchSize) {
this.retentionPeriod = retentionPeriod;
this.batchSize = batchSize;
this.currentTimestamp = new Timestamp(new java.util.Date().getTime());
if (log.isDebugEnabled()) {
log.debug("Using batch size of " + this.batchSize + " with retention period " + this.retentionPeriod);
}
}
@Override
public List<Integer> getAllOperations() throws ArchivalDAOException {
List<Integer> operationIds = new ArrayList<>();
Statement stmt = null;
ResultSet rs = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT DISTINCT OPERATION_ID FROM DM_ENROLMENT_OP_MAPPING " +
"WHERE CREATED_TIMESTAMP BETWEEN DATE_SUB(NOW(), INTERVAL " +
this.retentionPeriod + " DAY) AND NOW()";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
while (rs.next()) {
operationIds.add(rs.getInt("OPERATION_ID"));
}
} catch (SQLException e) {
throw new ArchivalDAOException("An error occurred while getting a list operation Ids to archive", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
}
if (log.isDebugEnabled()) {
log.debug(operationIds.size() + " operations found for the archival");
}
return operationIds;
}
@Override
public List<Integer> getPendingAndInProgressOperations() throws ArchivalDAOException {
List<Integer> operationIds = new ArrayList<>();
Statement stmt = null;
ResultSet rs = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT DISTINCT OPERATION_ID " +
" FROM DM_ENROLMENT_OP_MAPPING WHERE STATUS IN('PENDING', 'IN_PROGRESS') " +
" AND CREATED_TIMESTAMP BETWEEN DATE_SUB(NOW(), INTERVAL " + this.retentionPeriod +" DAY) AND NOW()";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
while (rs.next()) {
operationIds.add(rs.getInt("OPERATION_ID"));
}
} catch (SQLException e) {
throw new ArchivalDAOException("An error occurred while getting a list operation Ids to archive", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
}
if (log.isDebugEnabled()) {
log.debug(operationIds.size() + " PENDING and IN_PROFRESS operations found for the archival");
}
return operationIds;
}
@Override
public void copyOperationIDsForArchival(List<Integer> operationIds) throws ArchivalDAOException {
PreparedStatement stmt = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "INSERT INTO DM_ARCHIVED_OPERATIONS(ID,CREATED_TIMESTAMP) VALUES (?,NOW())";
stmt = conn.prepareStatement(sql);
int count = 0;
for (int i = 0; i < operationIds.size(); i++) {
stmt.setInt(1, operationIds.get(i));
stmt.addBatch();
if (++count % this.batchSize == 0) {
stmt.executeBatch();
}
}
stmt.executeBatch();
if (log.isDebugEnabled()) {
log.debug(count + " Records copied to the temporary table.");
}
} catch (SQLException e) {
throw new ArchivalDAOException("Error while copying operation Ids for archival", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
}
}
@Override
public void moveOperationResponses() throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_DEVICE_OPERATION_RESPONSE WHERE OPERATION_ID IN " +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_DEVICE_OPERATION_RESPONSE_ARCH VALUES(?, ?, ?, ?, ?,?,?)";
stmt2 = conn2.prepareStatement(sql);
int count = 0;
while (rs.next()) {
stmt2.setInt(1, rs.getInt("ID"));
stmt2.setInt(2, rs.getInt("ENROLMENT_ID"));
stmt2.setInt(3, rs.getInt("OPERATION_ID"));
stmt2.setInt(4, rs.getInt("EN_OP_MAP_ID"));
stmt2.setBytes(5, rs.getBytes("OPERATION_RESPONSE"));
stmt2.setTimestamp(6, rs.getTimestamp("RECEIVED_TIMESTAMP"));
stmt2.setTimestamp(7, this.currentTimestamp);
stmt2.addBatch();
if (++count % batchSize == 0) {
stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug("Executing batch " + count);
}
}
}
stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug(count + " [OPERATION_RESPONSES] Records copied to the archival table. Starting deletion");
}
//try the deletion now
sql = "DELETE FROM DM_DEVICE_OPERATION_RESPONSE WHERE OPERATION_ID IN (" +
" SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted");
}
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving operations ", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3);
}
}
@Override
public void moveNotifications() throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_NOTIFICATION WHERE OPERATION_ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
// ArchivalDestinationDAOFactory.beginTransaction();
Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_NOTIFICATION_ARCH VALUES(?, ?, ?, ?, ?, ?, ?)";
stmt2 = conn2.prepareStatement(sql);
int count = 0;
while (rs.next()) {
stmt2.setInt(1, rs.getInt("NOTIFICATION_ID"));
stmt2.setInt(2, rs.getInt("DEVICE_ID"));
stmt2.setInt(3, rs.getInt("OPERATION_ID"));
stmt2.setInt(4, rs.getInt("TENANT_ID"));
stmt2.setString(5, rs.getString("STATUS"));
stmt2.setString(6, rs.getString("DESCRIPTION"));
stmt2.setTimestamp(7, this.currentTimestamp);
stmt2.addBatch();
if (++count % batchSize == 0) {
stmt2.executeBatch();
}
}
stmt2.executeBatch();
// ArchivalDestinationDAOFactory.commitTransaction();
if (log.isDebugEnabled()) {
log.debug(count + " [NOTIFICATIONS] Records copied to the archival table. Starting deletion");
}
sql = "DELETE FROM DM_NOTIFICATION" +
" WHERE OPERATION_ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted");
}
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving notifications ", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3);
}
}
@Override
public void moveCommandOperations() throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_COMMAND_OPERATION WHERE OPERATION_ID IN " +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_COMMAND_OPERATION_ARCH VALUES(?,?,?)";
stmt2 = conn2.prepareStatement(sql);
int count = 0;
while (rs.next()) {
stmt2.setInt(1, rs.getInt("OPERATION_ID"));
stmt2.setInt(2, rs.getInt("ENABLED"));
stmt2.setTimestamp(3, this.currentTimestamp);
stmt2.addBatch();
if (++count % batchSize == 0) {
stmt2.executeBatch();
}
}
stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug(count + " [COMMAND_OPERATION] Records copied to the archival table. Starting deletion");
}
sql = "DELETE FROM DM_COMMAND_OPERATION" +
" WHERE OPERATION_ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted");
}
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving command operations", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3);
}
}
@Override
public void moveProfileOperations() throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_PROFILE_OPERATION WHERE OPERATION_ID IN " +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_PROFILE_OPERATION_ARCH VALUES(?, ?, ?, ?)";
stmt2 = conn2.prepareStatement(sql);
int count = 0;
while (rs.next()) {
stmt2.setInt(1, rs.getInt("OPERATION_ID"));
stmt2.setInt(2, rs.getInt("ENABLED"));
stmt2.setBytes(3, rs.getBytes("OPERATION_DETAILS"));
stmt2.setTimestamp(4,this.currentTimestamp );
stmt2.addBatch();
if (++count % batchSize == 0) {
stmt2.executeBatch();
}
}
stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug(count + " [PROFILE_OPERATION] Records copied to the archival table. Starting deletion");
}
sql = "DELETE FROM DM_PROFILE_OPERATION" +
" WHERE OPERATION_ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted");
}
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving profile operations", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3);
}
}
@Override
public void moveEnrolmentMappings() throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_ENROLMENT_OP_MAPPING WHERE OPERATION_ID IN " +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_ENROLMENT_OP_MAPPING_ARCH VALUES(?, ?, ?, ?, ?, ?, ?,?)";
stmt2 = conn2.prepareStatement(sql);
int count = 0;
while (rs.next()) {
stmt2.setInt(1, rs.getInt("ID"));
stmt2.setInt(2, rs.getInt("ENROLMENT_ID"));
stmt2.setInt(3, rs.getInt("OPERATION_ID"));
stmt2.setString(4, rs.getString("STATUS"));
stmt2.setString(5, rs.getString("PUSH_NOTIFICATION_STATUS"));
stmt2.setInt(6, rs.getInt("CREATED_TIMESTAMP"));
stmt2.setInt(7, rs.getInt("UPDATED_TIMESTAMP"));
stmt2.setTimestamp(8, this.currentTimestamp);
stmt2.addBatch();
if (++count % batchSize == 0) {
stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug("Executing batch " + count);
}
}
}
stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug(count + " [ENROLMENT_OP_MAPPING] Records copied to the archival table. Starting deletion");
}
sql = "DELETE FROM DM_ENROLMENT_OP_MAPPING WHERE OPERATION_ID IN (" +
"SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted");
}
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving enrolment mappings", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3);
}
}
@Override
public void moveOperations() throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_OPERATION WHERE ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_OPERATION_ARCH VALUES(?, ?, ?, ?, ?, ?)";
stmt2 = conn2.prepareStatement(sql);
int count = 0;
while (rs.next()) {
stmt2.setInt(1, rs.getInt("ID"));
stmt2.setString(2, rs.getString("TYPE"));
stmt2.setTimestamp(3, rs.getTimestamp("CREATED_TIMESTAMP"));
stmt2.setTimestamp(4, rs.getTimestamp("RECEIVED_TIMESTAMP"));
stmt2.setString(5, rs.getString("OPERATION_CODE"));
stmt2.setTimestamp(6, this.currentTimestamp);
stmt2.addBatch();
if (++count % batchSize == 0) {
stmt2.executeBatch();
}
}
stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug(count + " [OPERATIONS] Records copied to the archival table. Starting deletion");
}
sql = "DELETE FROM DM_OPERATION WHERE ID IN (" +
"SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted");
}
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving operations", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3);
}
}
@Override
public void truncateOperationIDsForArchival() throws ArchivalDAOException {
PreparedStatement stmt = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
conn.setAutoCommit(false);
String sql = "TRUNCATE DM_ARCHIVED_OPERATIONS";
stmt = conn.prepareStatement(sql);
stmt.addBatch();
stmt.executeBatch();
conn.commit();
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while truncating operation Ids", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
}
}
private Statement createMemoryEfficientStatement(Connection conn) throws ArchivalDAOException, SQLException {
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
return stmt;
}
}

@ -0,0 +1,163 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.core.archival.dao.ArchivalDAOException;
import org.wso2.carbon.device.mgt.core.archival.dao.ArchivalDAOUtil;
import org.wso2.carbon.device.mgt.core.archival.dao.ArchivalDestinationDAOFactory;
import org.wso2.carbon.device.mgt.core.archival.dao.DataDeletionDAO;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DataDeletionDAOImpl implements DataDeletionDAO {
private static Log log = LogFactory.getLog(DataDeletionDAOImpl.class);
private int retentionPeriod = DataDeletionDAO.DEFAULT_RETENTION_PERIOD;
public DataDeletionDAOImpl(int retentionPeriod) {
this.retentionPeriod = retentionPeriod;
if (log.isDebugEnabled()) {
log.debug("Using retention period as " + retentionPeriod);
}
}
@Override
public void deleteOperationResponses() throws ArchivalDAOException {
PreparedStatement stmt = null;
try {
Connection conn = ArchivalDestinationDAOFactory.getConnection();
conn.setAutoCommit(false);
String sql = "DELETE FROM DM_DEVICE_OPERATION_RESPONSE_ARCH " +
"WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod);
stmt.addBatch();
stmt.executeBatch();
conn.commit();
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting operation responses", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
}
}
@Override
public void deleteNotifications() throws ArchivalDAOException {
PreparedStatement stmt = null;
try {
Connection conn = ArchivalDestinationDAOFactory.getConnection();
conn.setAutoCommit(false);
String sql = "DELETE FROM DM_NOTIFICATION_ARCH" +
" WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod);
stmt.addBatch();
stmt.executeBatch();
conn.commit();
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting notifications", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
}
}
@Override
public void deleteCommandOperations() throws ArchivalDAOException {
PreparedStatement stmt = null;
try {
Connection conn = ArchivalDestinationDAOFactory.getConnection();
conn.setAutoCommit(false);
String sql = "DELETE FROM DM_COMMAND_OPERATION_ARCH" +
" WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod);
stmt.addBatch();
stmt.executeBatch();
conn.commit();
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting command operations", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
}
}
@Override
public void deleteProfileOperations() throws ArchivalDAOException {
PreparedStatement stmt = null;
try {
Connection conn = ArchivalDestinationDAOFactory.getConnection();
conn.setAutoCommit(false);
String sql = "DELETE FROM DM_PROFILE_OPERATION_ARCH" +
" WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod);
stmt.addBatch();
stmt.executeBatch();
conn.commit();
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting profile operations", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
}
}
@Override
public void deleteEnrolmentMappings() throws ArchivalDAOException {
PreparedStatement stmt = null;
try {
Connection conn = ArchivalDestinationDAOFactory.getConnection();
conn.setAutoCommit(false);
String sql = "DELETE FROM DM_ENROLMENT_OP_MAPPING_ARCH WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod);
stmt.addBatch();
stmt.executeBatch();
conn.commit();
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting enrolment mappings", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
}
}
@Override
public void deleteOperations() throws ArchivalDAOException {
PreparedStatement stmt = null;
try {
Connection conn = ArchivalDestinationDAOFactory.getConnection();
conn.setAutoCommit(false);
String sql = "DELETE FROM DM_OPERATION_ARCH WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod);
stmt.addBatch();
stmt.executeBatch();
conn.commit();
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting operations", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
}
}
}

@ -17,14 +17,17 @@
*/
package org.wso2.carbon.device.mgt.core.config;
import org.wso2.carbon.device.mgt.core.config.archival.ArchivalConfiguration;
import org.wso2.carbon.device.mgt.core.config.cache.CertificateCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.geo.location.OperationAnalyticsConfiguration;
import org.wso2.carbon.device.mgt.core.config.cache.DeviceCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations;
import org.wso2.carbon.device.mgt.core.config.keymanager.KeyManagerConfigurations;
import org.wso2.carbon.device.mgt.core.config.pagination.PaginationConfiguration;
import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration;
import org.wso2.carbon.device.mgt.core.config.pull.notification.PullNotificationConfiguration;
import org.wso2.carbon.device.mgt.core.config.push.notification.PushNotificationConfiguration;
import org.wso2.carbon.device.mgt.core.config.remote.session.RemoteSessionConfiguration;
import org.wso2.carbon.device.mgt.core.config.status.task.DeviceStatusTaskConfig;
import org.wso2.carbon.device.mgt.core.config.task.TaskConfiguration;
@ -41,6 +44,7 @@ public final class DeviceManagementConfig {
private DeviceManagementConfigRepository deviceManagementConfigRepository;
private TaskConfiguration taskConfiguration;
private IdentityConfigurations identityConfigurations;
private KeyManagerConfigurations keyManagerConfigurations;
private PolicyConfiguration policyConfiguration;
private PaginationConfiguration paginationConfiguration;
private PushNotificationConfiguration pushNotificationConfiguration;
@ -50,6 +54,9 @@ public final class DeviceManagementConfig {
private CertificateCacheConfiguration certificateCacheConfiguration;
private OperationAnalyticsConfiguration operationAnalyticsConfiguration;
private String defaultGroupsConfiguration;
private RemoteSessionConfiguration remoteSessionConfiguration;
private ArchivalConfiguration archivalConfiguration;
@XmlElement(name = "ManagementRepository", required = true)
public DeviceManagementConfigRepository getDeviceManagementConfigRepository() {
@ -70,6 +77,15 @@ public final class DeviceManagementConfig {
this.identityConfigurations = identityConfigurations;
}
@XmlElement(name = "KeyManagerConfiguration", required = true)
public KeyManagerConfigurations getKeyManagerConfigurations() {
return keyManagerConfigurations;
}
public void setKeyManagerConfigurations(KeyManagerConfigurations keyManagerConfigurations) {
this.keyManagerConfigurations = keyManagerConfigurations;
}
@XmlElement(name = "PolicyConfiguration", required = true)
public PolicyConfiguration getPolicyConfiguration() {
return policyConfiguration;
@ -159,5 +175,22 @@ public final class DeviceManagementConfig {
public void setDefaultGroupsConfiguration(String defaultGroupsConfiguration) {
this.defaultGroupsConfiguration = defaultGroupsConfiguration;
}
@XmlElement(name = "ArchivalConfiguration", required = true)
public ArchivalConfiguration getArchivalConfiguration() {
return archivalConfiguration;
}
public void setArchivalConfiguration(ArchivalConfiguration archivalConfiguration) {
this.archivalConfiguration = archivalConfiguration;
}
@XmlElement(name = "RemoteSessionConfiguration", required = true)
public RemoteSessionConfiguration getRemoteSessionConfiguration() {
return remoteSessionConfiguration;
}
public void setRemoteSessionConfiguration(RemoteSessionConfiguration remoteSessionConfiguration) {
this.remoteSessionConfiguration = remoteSessionConfiguration;
}
}

@ -0,0 +1,53 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.config.archival;
import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This class represents the information related to data archival configurations.
*/
@XmlRootElement(name = "ArchivalConfiguration")
public class ArchivalConfiguration {
private DataSourceConfig dataSourceConfig;
private ArchivalTaskConfiguration archivalTaskConfiguration;
@XmlElement(name = "DataSourceConfiguration", required = true)
public DataSourceConfig getDataSourceConfig() {
return dataSourceConfig;
}
public void setDataSourceConfig(DataSourceConfig dataSourceConfig) {
this.dataSourceConfig = dataSourceConfig;
}
@XmlElement(name = "ArchivalTask", required = true)
public ArchivalTaskConfiguration getArchivalTaskConfiguration() {
return archivalTaskConfiguration;
}
public void setArchivalTaskConfiguration(ArchivalTaskConfiguration archivalTaskConfiguration) {
this.archivalTaskConfiguration = archivalTaskConfiguration;
}
}

@ -0,0 +1,86 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.config.archival;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "ArchivalTask")
public class ArchivalTaskConfiguration {
private boolean enabled;
private String cronExpression;
private String taskClazz;
private int retentionPeriod;
private int batchSize;
private PurgingTaskConfiguration purgingTaskConfiguration;
@XmlElement(name = "Enabled", required = true)
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@XmlElement(name = "CronExpression", required = true)
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
@XmlElement(name = "TaskClass", required = true)
public String getTaskClazz() {
return taskClazz;
}
public void setTaskClazz(String taskClazz) {
this.taskClazz = taskClazz;
}
@XmlElement(name = "RetentionPeriod", required = true)
public int getRetentionPeriod() {
return retentionPeriod;
}
public void setRetentionPeriod(int retentionPeriod) {
this.retentionPeriod = retentionPeriod;
}
@XmlElement(name = "PurgingTask", required = true)
public PurgingTaskConfiguration getPurgingTaskConfiguration() {
return purgingTaskConfiguration;
}
public void setPurgingTaskConfiguration(PurgingTaskConfiguration purgingTaskConfiguration) {
this.purgingTaskConfiguration = purgingTaskConfiguration;
}
@XmlElement(name ="ExecutionBatchSize", required = true)
public int getBatchSize() {
return batchSize;
}
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
}

@ -0,0 +1,66 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.config.archival;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "PurgingTask")
public class PurgingTaskConfiguration {
private boolean enabled;
private String cronExpression;
private String taskClazz;
private int retentionPeriod;
@XmlElement(name = "Enabled", required = true)
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@XmlElement(name = "CronExpression", required = true)
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
@XmlElement(name = "TaskClass", required = true)
public String getTaskClazz() {
return taskClazz;
}
public void setTaskClazz(String taskClazz) {
this.taskClazz = taskClazz;
}
@XmlElement(name = "RetentionPeriod", required = true)
public int getRetentionPeriod() {
return retentionPeriod;
}
public void setRetentionPeriod(int retentionPeriod) {
this.retentionPeriod = retentionPeriod;
}
}

@ -0,0 +1,59 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.config.keymanager;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Configurations related to key management.
*/
@XmlRootElement(name = "KeyManagerConfiguration")
public class KeyManagerConfigurations {
private String serverUrl;
private String adminUsername;
private String adminPassword;
@XmlElement(name = "AdminUsername", required = true)
public String getAdminUsername() {
return adminUsername;
}
public void setAdminUsername(String adminUsername) {
this.adminUsername = adminUsername;
}
@XmlElement(name = "AdminPassword", required = true)
public String getAdminPassword() {
return adminPassword;
}
public void setAdminPassword(String adminPassword) {
this.adminPassword = adminPassword;
}
@XmlElement(name = "ServerUrl", required = true)
public String getServerUrl() {
return serverUrl;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
}

@ -0,0 +1,129 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.config.remote.session;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This class represents the information related to Remote Session configuration.
*/
@XmlRootElement(name = "RemoteSessionConfiguration")
public class RemoteSessionConfiguration {
private String remoteSessionServerUrl;
private boolean enabled;
private int maxHTTPConnectionPerHost;
private int maxTotalHTTPConnections;
private int maxMessagesPerSecond;
private int sessionIdleTimeOut;
private int maxMessageBufferSize;
public void setRemoteSessionServerUrl(String remoteSessionServerUrl) {
this.remoteSessionServerUrl = remoteSessionServerUrl;
}
/**
* Remote session server url
* @return
*/
@XmlElement(name = "RemoteSessionServerUrl", required = true)
public String getRemoteSessionServerUrl() {
return remoteSessionServerUrl;
}
/**
* Remote session enabled
* @return
*/
@XmlElement(name = "Enabled", required = true)
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* Maximum connections per host for external http invocations
* @return
*/
@XmlElement(name = "MaximumHTTPConnectionPerHost", required = true, defaultValue = "2")
public int getMaxHTTPConnectionPerHost() {
return maxHTTPConnectionPerHost;
}
public void setMaxHTTPConnectionPerHost(int maxHTTPConnectionPerHost) {
this.maxHTTPConnectionPerHost = maxHTTPConnectionPerHost;
}
/**
* Maximum total connections for external http invocation
*/
@XmlElement(name = "MaximumTotalHTTPConnections", required = true, defaultValue = "100")
public int getMaxTotalHTTPConnections() {
return maxTotalHTTPConnections;
}
public void setMaxTotalHTTPConnections(int maxTotalHTTPConnections) {
this.maxTotalHTTPConnections = maxTotalHTTPConnections;
}
/**
* This is for protect device from message spamming. Throttling limit in term of messages for device
* @return
*/
@XmlElement(name = "MaximumMessagesPerSecond", required = true, defaultValue = "10")
public int getMaxMessagesPerSession() {
return maxMessagesPerSecond;
}
public void setMaxMessagesPerSession(int maxMessagesPerSession) {
this.maxMessagesPerSecond = maxMessagesPerSession;
}
/**
* Maximum idle timeout in minutes
* @return
*/
@XmlElement(name = "SessionIdleTimeOut", required = true, defaultValue = "5")
public int getSessionIdleTimeOut() {
return sessionIdleTimeOut;
}
public void setSessionIdleTimeOut(int sessionIdleTimeOut) {
this.sessionIdleTimeOut = sessionIdleTimeOut;
}
/**
* Maximum session buffer size in kilo bytes
* @return
*/
@XmlElement(name = "MaximumMessageBufferSize", required = true, defaultValue = "640")
public int getMaxMessageBufferSize() {
return maxMessageBufferSize;
}
public void setMaxMessageBufferSize(int MaxMessageBufferSize) {
this.maxMessageBufferSize = MaxMessageBufferSize;
}
}

@ -24,6 +24,8 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.geo.GeoCluster;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
import java.util.Date;
import java.util.HashMap;
@ -395,5 +397,16 @@ public interface DeviceDAO {
List<Integer> getDeviceEnrolledTenants() throws DeviceManagementDAOException;
/**
* This method is used to retrieve the details of geoclusters formed relatively to the zoom level and map
* boundaries.
*
* @param southWest the coordinates of southWest corner of the map.
* @param northEast the coordinates of northEast corner of the map.
* @param tenantId tenant id.
* @return returns a list of enrolment info objects.
*/
List<GeoCluster> findGeoClusters(GeoCoordinate southWest, GeoCoordinate northEast, int geohashLength,int tenantId) throws DeviceManagementDAOException;
}

@ -28,6 +28,8 @@ import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.geo.GeoCluster;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ -1060,4 +1062,56 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
return tenants;
}
public List<GeoCluster> findGeoClusters(GeoCoordinate southWest, GeoCoordinate northEast,
int geohashLength, int tenantId) throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
List<GeoCluster> geoClusters = new ArrayList<>();
try {
conn = this.getConnection();
String sql ="SELECT AVG(DEVICE_LOCATION.LATITUDE) AS LATITUDE,AVG(DEVICE_LOCATION.LONGITUDE) AS LONGITUDE," +
" MIN(DEVICE_LOCATION.LATITUDE) AS MIN_LATITUDE, MAX(DEVICE_LOCATION.LATITUDE) AS MAX_LATITUDE," +
" MIN(DEVICE_LOCATION.LONGITUDE) AS MIN_LONGITUDE," +
" MAX(DEVICE_LOCATION.LONGITUDE) AS MAX_LONGITUDE, " +
"SUBSTRING (DEVICE_LOCATION.GEO_HASH,1,?) AS GEOHASH_PREFIX, COUNT(*) AS COUNT, " +
"MIN(DEVICE.DEVICE_IDENTIFICATION) AS DEVICE_IDENTIFICATION, " +
"MIN(DEVICE_TYPE.NAME) AS TYPE " +
"FROM DM_DEVICE_LOCATION AS DEVICE_LOCATION,DM_DEVICE AS DEVICE, DM_DEVICE_TYPE AS DEVICE_TYPE " +
"WHERE DEVICE_LOCATION.LATITUDE BETWEEN ? AND ? AND " +
"DEVICE_LOCATION.LONGITUDE BETWEEN ? AND ? AND " +
"DEVICE.TENANT_ID=? AND " +
"DEVICE.ID=DEVICE_LOCATION.DEVICE_ID AND DEVICE.DEVICE_TYPE_ID=DEVICE_TYPE.ID" +
" GROUP BY GEOHASH_PREFIX";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, geohashLength);
stmt.setDouble(2, southWest.getLatitude());
stmt.setDouble(3, northEast.getLatitude());
stmt.setDouble(4, southWest.getLongitude());
stmt.setDouble(5, northEast.getLongitude());
stmt.setDouble(6,tenantId);
rs = stmt.executeQuery();
while (rs.next()) {
double latitude = rs.getDouble("LATITUDE");
double longitude = rs.getDouble("LONGITUDE");
double min_latitude = rs.getDouble("MIN_LATITUDE");
double max_latitude = rs.getDouble("MAX_LATITUDE");
double min_longitude = rs.getDouble("MIN_LONGITUDE");
double max_longitude = rs.getDouble("MAX_LONGITUDE");
String device_identification = rs.getString("DEVICE_IDENTIFICATION");
String device_type=rs.getString("TYPE");
long count = rs.getLong("COUNT");
String geohashPrefix = rs.getString("GEOHASH_PREFIX");
geoClusters.add(new GeoCluster(new GeoCoordinate(latitude, longitude),
new GeoCoordinate(min_latitude,min_longitude), new GeoCoordinate(max_latitude,max_longitude),
count, geohashPrefix,device_identification,device_type));
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while retrieving information of " +
"Geo Clusters", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return geoClusters;
}
}

@ -45,7 +45,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID) VALUES (?, ?, ?, ?)";
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt = conn.prepareStatement(sql, new String[]{"ID"});
stmt.setString(1, deviceGroup.getDescription());
stmt.setString(2, deviceGroup.getName());
stmt.setString(3, deviceGroup.getOwner());

@ -26,8 +26,16 @@ import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import java.io.*;
import java.sql.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@ -84,14 +92,14 @@ public class ApplicationDAOImpl implements ApplicationDAO {
try {
bao.close();
} catch (IOException e) {
log.warn("Error occurred while closing ByteArrayOutputStream", e);
log.error("Error occurred while closing ByteArrayOutputStream", e);
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
log.warn("Error occurred while closing ObjectOutputStream", e);
log.error("Error occurred while closing ObjectOutputStream", e);
}
}
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
@ -150,14 +158,14 @@ public class ApplicationDAOImpl implements ApplicationDAO {
try {
bao.close();
} catch (IOException e) {
log.warn("Error occurred while closing ByteArrayOutputStream", e);
log.error("Error occurred while closing ByteArrayOutputStream", e);
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
log.warn("Error occurred while closing ObjectOutputStream", e);
log.error("Error occurred while closing ObjectOutputStream", e);
}
}
DeviceManagementDAOUtil.cleanupResources(stmt, null);
@ -193,7 +201,7 @@ public class ApplicationDAOImpl implements ApplicationDAO {
conn.rollback();
}
} catch (SQLException e1) {
log.warn("Error occurred while roll-backing the transaction", e);
log.error("Error occurred while roll-backing the transaction", e);
}
throw new DeviceManagementDAOException("Error occurred while removing bulk application list", e);
} finally {

@ -27,6 +27,7 @@ import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsDAO;
import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsMgtDAOException;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoHashGenerator;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ -228,7 +229,7 @@ public class DeviceDetailsDAOImpl implements DeviceDetailsDAO {
try {
conn = this.getConnection();
stmt = conn.prepareStatement("INSERT INTO DM_DEVICE_LOCATION (DEVICE_ID, LATITUDE, LONGITUDE, STREET1, " +
"STREET2, CITY, ZIP, STATE, COUNTRY, UPDATE_TIMESTAMP) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
"STREET2, CITY, ZIP, STATE, COUNTRY, GEO_HASH, UPDATE_TIMESTAMP) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,?,?)");
stmt.setInt(1, deviceLocation.getDeviceId());
stmt.setDouble(2, deviceLocation.getLatitude());
stmt.setDouble(3, deviceLocation.getLongitude());
@ -238,7 +239,8 @@ public class DeviceDetailsDAOImpl implements DeviceDetailsDAO {
stmt.setString(7, deviceLocation.getZip());
stmt.setString(8, deviceLocation.getState());
stmt.setString(9, deviceLocation.getCountry());
stmt.setLong(10, System.currentTimeMillis());
stmt.setString(10, GeoHashGenerator.encodeGeohash(deviceLocation));
stmt.setLong(11, System.currentTimeMillis());
stmt.execute();
} catch (SQLException e) {
throw new DeviceDetailsMgtDAOException("Error occurred while adding the device location to database.", e);

@ -0,0 +1,54 @@
package org.wso2.carbon.device.mgt.core.geo;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
public class GeoCluster {
private GeoCoordinate coordinates;
private GeoCoordinate southWestBound;
private GeoCoordinate northEastBound;
private long count;
private String geohashPrefix;
private String deviceIdentification;
private String deviceType;
public GeoCluster(GeoCoordinate coordinates, GeoCoordinate southWestBound, GeoCoordinate northEastBound, long count,
String geohashPrefix, String deviceIdentification, String deviceType){
this.coordinates=coordinates;
this.southWestBound=southWestBound;
this.northEastBound=northEastBound;
this.count=count;
this.geohashPrefix=geohashPrefix;
this.deviceIdentification=deviceIdentification;
this.deviceType=deviceType;
}
public String getGeohashPrefix() {
return geohashPrefix;
}
public long getCount() {
return count;
}
public GeoCoordinate getCoordinates() {
return coordinates;
}
public GeoCoordinate getSouthWestBound() {
return southWestBound;
}
public GeoCoordinate getNorthEastBound() {
return northEastBound;
}
public String getDeviceIdentification() {
return deviceIdentification;
}
public String getDeviceType() { return deviceType;
}
}

@ -0,0 +1,21 @@
package org.wso2.carbon.device.mgt.core.geo.geoHash;
public class GeoCoordinate {
private double latitude;
private double longitude;
public GeoCoordinate(double latitude, double longitude){
this.latitude=latitude;
this.longitude=longitude;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
}

@ -0,0 +1,92 @@
package org.wso2.carbon.device.mgt.core.geo.geoHash;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation;
import java.util.HashMap;
import java.util.Map;
public class GeoHashGenerator {
private static final String BASE_32 = "0123456789bcdefghjkmnpqrstuvwxyz";
private static final int GEOHASH_LENGTH = 16;
private GeoHashGenerator(){};
private static int divideRangeByValue(double value, double[] range) {
double mid = middle(range);
if (value >= mid) {
range[0] = mid;
return 1;
} else {
range[1] = mid;
return 0;
}
}
private static void divideRangeByBit(int bit, double[] range) {
double mid = middle(range);
if (bit > 0) {
range[0] = mid;
} else {
range[1] = mid;
}
}
private static double middle(double[] range) {
return (range[0] + range[1]) / 2;
}
public static String encodeGeohash(double latitude, double longitude) {
int geohashLength=GEOHASH_LENGTH;
double[] latRange = new double[]{-90.0, 90.0};
double[] lonRange = new double[]{-180.0, 180.0};
boolean isEven = true;
int bit = 0;
int base32CharIndex = 0;
StringBuilder geohash = new StringBuilder();
while (geohash.length() < geohashLength) {
if (isEven) {
base32CharIndex = (base32CharIndex << 1) | divideRangeByValue(longitude, lonRange);
} else {
base32CharIndex = (base32CharIndex << 1) | divideRangeByValue(latitude, latRange);
}
isEven = !isEven;
if (bit < 4) {
bit++;
} else {
geohash.append(BASE_32.charAt(base32CharIndex));
bit = 0;
base32CharIndex = 0;
}
}
return geohash.toString();
}
public static String encodeGeohash(DeviceLocation deviceLocation) {
return encodeGeohash(deviceLocation.getLatitude(), deviceLocation.getLongitude());
}
public static GeoCoordinate decodeGeohash(String geohash) {
double[] latRange = new double[]{-90.0, 90.0};
double[] lonRange = new double[]{-180.0, 180.0};
boolean isEvenBit = true;
for (int i = 0; i < geohash.length(); i++) {
int base32CharIndex = BASE_32.indexOf(geohash.charAt(i));
for (int j = 4; j >= 0; j--) {
if (isEvenBit) {
divideRangeByBit((base32CharIndex >> j) & 1, lonRange);
} else {
divideRangeByBit((base32CharIndex >> j) & 1, latRange);
}
isEvenBit = !isEvenBit;
}
}
GeoCoordinate coordinates = new GeoCoordinate(middle(latRange),middle(lonRange));
return coordinates;
}
}

@ -0,0 +1,11 @@
package org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
/**
* This interface is to decide a length for the geohash prefix
* which will be used to group the clusters based on geohash
*/
public interface GeoHashLengthStrategy {
int getGeohashLength(GeoCoordinate southWest, GeoCoordinate northEast, int zoom);
}

@ -0,0 +1,53 @@
package org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
/**A class that will decide the geoHashLength based on the zoom level and
* the boundaries of the map**/
public class ZoomGeoHashLengthStrategy implements GeoHashLengthStrategy{
private int minGeohashLength = 1;
private int maxGeohashLength = 16;
private int minZoom = 1;
private int maxZoom = 17;
@Override
public int getGeohashLength(GeoCoordinate southWest, GeoCoordinate northEast, int zoom) {
double a = minGeohashLength / Math.exp(minZoom / (maxZoom - minZoom) * Math.log(maxGeohashLength / minGeohashLength));
double b = Math.log(maxGeohashLength / minGeohashLength) / (maxZoom - minZoom);
return (int) Math.max(minGeohashLength, Math.min(a * Math.exp(b * zoom), maxGeohashLength));
}
public void setMinGeohashLength(int minGeohashLength) {
this.minGeohashLength = minGeohashLength;
}
public void setMaxGeohashLength(int maxGeohashLength) {
this.maxGeohashLength = maxGeohashLength;
}
public void setMinZoom(int minZoom) {
this.minZoom = minZoom;
}
public void setMaxZoom(int maxZoom) {
this.maxZoom = maxZoom;
}
public int getMinGeohashLength() {
return minGeohashLength;
}
public int getMaxGeohashLength() {
return maxGeohashLength;
}
public int getMinZoom() {
return minZoom;
}
public int getMaxZoom() {
return maxZoom;
}
}

@ -0,0 +1,129 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.device.mgt.core.archival.dao.ArchivalDestinationDAOFactory;
import org.wso2.carbon.device.mgt.core.archival.dao.ArchivalSourceDAOFactory;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.task.ArchivalTaskManager;
import org.wso2.carbon.device.mgt.core.task.impl.ArchivalTaskManagerImpl;
import org.wso2.carbon.ntask.core.service.TaskService;
/**
* @scr.component name="org.wso2.carbon.activity.data.archival" immediate="true"
* @scr.reference name="device.ntask.component"
* interface="org.wso2.carbon.ntask.core.service.TaskService"
* cardinality="1..1"
* policy="dynamic"
* bind="setTaskService"
* unbind="unsetTaskService"
* @scr.reference name="org.wso2.carbon.device.manager"
* interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService"
* cardinality="1..1"
* policy="dynamic"
* bind="setDeviceManagementService"
* unbind="unsetDeviceManagementService"
*/
public class ActivityDataPurgingServiceComponent {
private static Log log = LogFactory.getLog(ActivityDataPurgingServiceComponent.class);
protected void activate(ComponentContext componentContext) {
try {
if (log.isDebugEnabled()) {
log.debug("Initializing activity data archival task manager bundle.");
}
/* Initialising data archival configurations */
DeviceManagementConfig config =
DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
boolean archivalTaskEnabled = false;
boolean purgingTaskEnabled = false;
if (config.getArchivalConfiguration() != null
&& config.getArchivalConfiguration().getArchivalTaskConfiguration() != null){
archivalTaskEnabled = config.getArchivalConfiguration().getArchivalTaskConfiguration().isEnabled();
purgingTaskEnabled = config.getArchivalConfiguration().getArchivalTaskConfiguration()
.getPurgingTaskConfiguration() != null
&& config.getArchivalConfiguration()
.getArchivalTaskConfiguration().getPurgingTaskConfiguration().isEnabled();
}
if (archivalTaskEnabled || purgingTaskEnabled) {
DataSourceConfig dsConfig = config.getDeviceManagementConfigRepository().getDataSourceConfig();
ArchivalSourceDAOFactory.init(dsConfig);
DataSourceConfig purgingDSConfig = config.getArchivalConfiguration().getDataSourceConfig();
ArchivalDestinationDAOFactory.init(purgingDSConfig);
}
ArchivalTaskManager archivalTaskManager = new ArchivalTaskManagerImpl();
// This will start the data archival task
if (archivalTaskEnabled) {
archivalTaskManager.scheduleArchivalTask();
log.info("Data archival task has been scheduled.");
} else {
log.warn("Data archival task has been disabled. It is recommended to enable archival task to " +
"prune the transactional databases tables time to time if you are using MySQL.");
}
// This will start the data deletion task.
if (purgingTaskEnabled) {
archivalTaskManager.scheduleDeletionTask();
log.info("Data purging task has been scheduled for archived data.");
}
} catch (Throwable e) {
log.error("Error occurred while initializing activity data archival task manager service.", e);
}
}
protected void setTaskService(TaskService taskService) {
if (log.isDebugEnabled()) {
log.debug("Setting the task service.");
}
DeviceManagementDataHolder.getInstance().setTaskService(taskService);
}
protected void unsetTaskService(TaskService taskService) {
if (log.isDebugEnabled()) {
log.debug("Removing the task service.");
}
DeviceManagementDataHolder.getInstance().setTaskService(null);
}
protected void setDeviceManagementService(DeviceManagementProviderService deviceManagementService){
}
protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementService){
}
@SuppressWarnings("unused")
protected void deactivate(ComponentContext componentContext) {
}
}

@ -32,6 +32,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
@ -45,6 +46,7 @@ public class ConfigOperationDAOImpl extends GenericOperationDAOImpl {
PreparedStatement stmt = null;
try {
operationId = super.addOperation(operation);
operation.setCreatedTimeStamp(new Timestamp(new java.util.Date().getTime()).toString());
Connection conn = OperationManagementDAOFactory.getConnection();
stmt = conn.prepareStatement("INSERT INTO DM_CONFIG_OPERATION(OPERATION_ID, OPERATION_CONFIG) VALUES(?, ?)");
stmt.setInt(1, operationId);

@ -22,7 +22,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationResponse;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.*;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.ConfigOperation;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.PolicyOperation;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.ProfileOperation;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -32,6 +36,7 @@ import java.sql.SQLException;
public class OperationDAOUtil {
private static final Log log = LogFactory.getLog(OperationDAOUtil.class);
public static Operation convertOperation(org.wso2.carbon.device.mgt.common.operation.mgt.Operation operation) {
Operation dtoOperation = null;
@ -40,28 +45,28 @@ public class OperationDAOUtil {
dtoOperation = new CommandOperation();
} else if (operation.getType().equals(org.wso2.carbon.device.mgt.common.operation.mgt.Operation.Type.PROFILE)) {
dtoOperation = new ProfileOperation();
}else if(operation.getType().equals(org.wso2.carbon.device.mgt.common.operation.mgt.Operation.Type.POLICY)){
} else if (operation.getType().equals(org.wso2.carbon.device.mgt.common.operation.mgt.Operation.Type.POLICY)) {
dtoOperation = new PolicyOperation();
}else if(operation.getType().equals(org.wso2.carbon.device.mgt.common.operation.mgt.Operation.Type.CONFIG)) {
} else if (operation.getType().equals(org.wso2.carbon.device.mgt.common.operation.mgt.Operation.Type.CONFIG)) {
dtoOperation = new ConfigOperation();
}else{
} else {
dtoOperation = new Operation();
}
dtoOperation.setEnabled(operation.isEnabled());
dtoOperation.setCode(operation.getCode());
if (operation.getType() != null){
if (operation.getType() != null) {
dtoOperation.setType(Operation.Type.valueOf(operation.getType().toString()));
}else{
} else {
dtoOperation.setType(null);
}
dtoOperation.setCreatedTimeStamp(operation.getCreatedTimeStamp());
if (operation.getStatus() != null){
if (operation.getStatus() != null) {
dtoOperation.setStatus(Operation.Status.valueOf(operation.getStatus().toString()));
}else{
} else {
dtoOperation.setStatus(null);
}
@ -70,31 +75,35 @@ public class OperationDAOUtil {
dtoOperation.setReceivedTimeStamp(operation.getReceivedTimeStamp());
dtoOperation.setProperties(operation.getProperties());
if (operation.getControl() != null) {
dtoOperation.setControl(Operation.Control.valueOf(operation.getControl().toString()));
}
return dtoOperation;
}
public static org.wso2.carbon.device.mgt.common.operation.mgt.Operation convertOperation(Operation dtoOperation){
public static org.wso2.carbon.device.mgt.common.operation.mgt.Operation convertOperation(Operation dtoOperation) {
org.wso2.carbon.device.mgt.common.operation.mgt.Operation operation = null;
if (dtoOperation.getType().equals(Operation.Type.COMMAND)){
if (dtoOperation.getType().equals(Operation.Type.COMMAND)) {
operation = new org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation();
}else if(dtoOperation.getType().equals(Operation.Type.PROFILE)){
} else if (dtoOperation.getType().equals(Operation.Type.PROFILE)) {
operation = new org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation();
}else{
} else {
operation = new org.wso2.carbon.device.mgt.common.operation.mgt.Operation();
}
operation.setEnabled(dtoOperation.isEnabled());
operation.setCode(dtoOperation.getCode());
if(dtoOperation.getType() != null) {
if (dtoOperation.getType() != null) {
operation.setType(org.wso2.carbon.device.mgt.common.operation.mgt.Operation.Type.valueOf(dtoOperation
.getType().toString()));
}
operation.setCreatedTimeStamp(dtoOperation.getCreatedTimeStamp());
if(dtoOperation.getStatus() != null) {
if (dtoOperation.getStatus() != null) {
operation.setStatus(org.wso2.carbon.device.mgt.common.operation.mgt.Operation.Status.valueOf(dtoOperation
.getStatus().toString()));
}

@ -36,7 +36,10 @@ import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.geo.GeoCluster;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
import java.util.Date;
import java.util.HashMap;
@ -612,4 +615,7 @@ public interface DeviceManagementProviderService {
throws PullNotificationExecutionFailedException;
List<Integer> getDeviceEnrolledTenants() throws DeviceManagementException;
List<GeoCluster> findGeoClusters(GeoCoordinate southWest, GeoCoordinate northEast,
int geohashLength) throws DeviceManagementException;
}

@ -70,6 +70,8 @@ import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsDAO;
import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsMgtDAOException;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.core.geo.GeoCluster;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.internal.PluginInitializationListener;
@ -2517,4 +2519,29 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
private void removeDeviceFromCache(DeviceIdentifier deviceIdentifier) {
DeviceCacheManagerImpl.getInstance().removeDeviceFromCache(deviceIdentifier, this.getTenantId());
}
@Override
public List<GeoCluster> findGeoClusters(GeoCoordinate southWest, GeoCoordinate northEast, int geohashLength) throws DeviceManagementException {
if (log.isDebugEnabled()) {
log.debug("get information about geo clusters");
}
try {
DeviceManagementDAOFactory.openConnection();
return deviceDAO.findGeoClusters(southWest,northEast,geohashLength,this.getTenantId());
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving the geo clusters.";
log.error(msg, e);
throw new DeviceManagementException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while opening a connection to the data source";
log.error(msg, e);
throw new DeviceManagementException(msg, e);
} catch (Exception e) {
String msg = "Error occurred in findGeoClusters";
log.error(msg, e);
throw new DeviceManagementException(msg, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
}

@ -0,0 +1,47 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.task;
public class ArchivalTaskException extends Exception {
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public ArchivalTaskException(String message) {
super(message);
setErrorMessage(message);
}
public ArchivalTaskException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public ArchivalTaskException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace, String errorMessage) {
super(message, cause, enableSuppression, writableStackTrace);
setErrorMessage(message);
}
}

@ -0,0 +1,27 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.task;
public interface ArchivalTaskManager {
void scheduleArchivalTask() throws ArchivalTaskException;
void scheduleDeletionTask() throws ArchivalTaskException;
}

@ -0,0 +1,87 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.task.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.core.archival.ArchivalException;
import org.wso2.carbon.device.mgt.core.archival.ArchivalService;
import org.wso2.carbon.device.mgt.core.archival.ArchivalServiceImpl;
import org.wso2.carbon.ntask.core.Task;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class ArchivalTask implements Task {
private static Log log = LogFactory.getLog(ArchivalTask.class);
private ArchivalService archivalService;
@Override
public void setProperties(Map<String, String> map) {
}
@Override
public void init() {
this.archivalService = new ArchivalServiceImpl();
}
@Override
public void execute() {
log.info("Executing ArchivalTask at " + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()));
long startTime = System.currentTimeMillis();
try {
archivalService.archiveTransactionalRecords();
} catch (ArchivalException e) {
log.error("An error occurred while running ArchivalTask", e);
}
long endTime = System.currentTimeMillis();
long difference = endTime - startTime;
log.info("ArchivalTask completed. Total execution time: " + getDurationBreakdown(difference));
}
private String getDurationBreakdown(long millis) {
if (millis < 0) {
throw new IllegalArgumentException("Duration must be greater than zero!");
}
long days = TimeUnit.MILLISECONDS.toDays(millis);
millis -= TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
StringBuilder sb = new StringBuilder(64);
sb.append(days);
sb.append(" Days ");
sb.append(hours);
sb.append(" Hours ");
sb.append(minutes);
sb.append(" Minutes ");
sb.append(seconds);
sb.append(" Seconds");
return (sb.toString());
}
}

@ -0,0 +1,128 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.task.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.task.ArchivalTaskException;
import org.wso2.carbon.device.mgt.core.task.ArchivalTaskManager;
import org.wso2.carbon.ntask.common.TaskException;
import org.wso2.carbon.ntask.core.TaskInfo;
import org.wso2.carbon.ntask.core.TaskManager;
import org.wso2.carbon.ntask.core.service.TaskService;
import java.util.HashMap;
import java.util.Map;
public class ArchivalTaskManagerImpl implements ArchivalTaskManager {
private static final String TASK_TYPE_ARCHIVAL = "DATA_ARCHIVAL";
private static final String TASK_TYPE_DELETION = "DATA_DELETION";
private static final String TASK_NAME_ARCHIVAL = "DATA_ARCHIVAL_TASK";
private static final String TASK_NAME_DELETION = "DATA_DELETION_TASK";
private static final String TENANT_ID = "TENANT_ID";
private static Log log = LogFactory.getLog(ArchivalTaskManagerImpl.class);
public void scheduleArchivalTask() throws ArchivalTaskException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
taskService.registerTaskType(TASK_TYPE_ARCHIVAL);
if (log.isDebugEnabled()) {
log.debug("Data archival task is started for the tenant id " + tenantId);
}
String taskClazz = DeviceConfigurationManager.getInstance().getDeviceManagementConfig()
.getArchivalConfiguration().getArchivalTaskConfiguration().getTaskClazz();
String cronExpression = DeviceConfigurationManager.getInstance().getDeviceManagementConfig()
.getArchivalConfiguration().getArchivalTaskConfiguration().getCronExpression();
TaskManager taskManager = taskService.getTaskManager(TASK_TYPE_ARCHIVAL);
TaskInfo.TriggerInfo triggerInfo = new TaskInfo.TriggerInfo();
triggerInfo.setCronExpression(cronExpression);
triggerInfo.setRepeatCount(-1);
triggerInfo.setDisallowConcurrentExecution(true);
Map<String, String> properties = new HashMap<>();
properties.put(TENANT_ID, String.valueOf(tenantId));
if (!taskManager.isTaskScheduled(TASK_NAME_ARCHIVAL)) {
TaskInfo taskInfo = new TaskInfo(TASK_NAME_ARCHIVAL, taskClazz, properties, triggerInfo);
taskManager.registerTask(taskInfo);
taskManager.rescheduleTask(taskInfo.getName());
} else {
throw new ArchivalTaskException("Data archival task is already started for this tenant " +
tenantId);
}
} catch (TaskException e) {
throw new ArchivalTaskException("Error occurred while creating the task for tenant " + tenantId, e);
}
}
public void scheduleDeletionTask() throws ArchivalTaskException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
taskService.registerTaskType(TASK_TYPE_DELETION);
String taskClazz = DeviceConfigurationManager.getInstance().getDeviceManagementConfig()
.getArchivalConfiguration().getArchivalTaskConfiguration()
.getPurgingTaskConfiguration().getTaskClazz();
String cronExpression = DeviceConfigurationManager.getInstance().getDeviceManagementConfig()
.getArchivalConfiguration().getArchivalTaskConfiguration()
.getPurgingTaskConfiguration().getCronExpression();
if (log.isDebugEnabled()) {
log.debug("Data deletion task is started for the tenant id " + tenantId);
}
TaskManager taskManager = taskService.getTaskManager(TASK_TYPE_DELETION);
TaskInfo.TriggerInfo triggerInfo = new TaskInfo.TriggerInfo();
triggerInfo.setCronExpression(cronExpression);
triggerInfo.setRepeatCount(-1);
triggerInfo.setDisallowConcurrentExecution(true);
Map<String, String> properties = new HashMap<>();
properties.put(TENANT_ID, String.valueOf(tenantId));
if (!taskManager.isTaskScheduled(TASK_NAME_DELETION)) {
TaskInfo taskInfo = new TaskInfo(TASK_NAME_DELETION, taskClazz, properties, triggerInfo);
taskManager.registerTask(taskInfo);
taskManager.rescheduleTask(taskInfo.getName());
} else {
throw new ArchivalTaskException("Data deletion task is already started for this tenant " +
tenantId);
}
} catch (TaskException e) {
throw new ArchivalTaskException("Error occurred while creating the task for tenant " + tenantId, e);
}
}
}

@ -0,0 +1,61 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.task.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.core.archival.ArchivalException;
import org.wso2.carbon.device.mgt.core.archival.ArchivalService;
import org.wso2.carbon.device.mgt.core.archival.ArchivalServiceImpl;
import org.wso2.carbon.ntask.core.Task;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
public class ArchivedDataDeletionTask implements Task {
private static Log log = LogFactory.getLog(ArchivedDataDeletionTask.class);
private ArchivalService archivalService;
@Override
public void setProperties(Map<String, String> map) {
}
@Override
public void init() {
this.archivalService = new ArchivalServiceImpl();
}
@Override
public void execute() {
log.info("Executing DataDeletionTask at " + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()));
long startTime = System.nanoTime();
try {
archivalService.deleteArchivedRecords();
} catch (ArchivalException e) {
log.error("An error occurred while executing DataDeletionTask", e);
}
long endTime = System.nanoTime();
long difference = (endTime - startTime) / 1000000 * 1000;
log.info("DataDeletionTask completed. Total execution time: " + difference + " seconds");
}
}

@ -35,6 +35,9 @@ import java.util.Properties;
import static org.mockito.MockitoAnnotations.initMocks;
/**
* This contains unit tests for PermissionManagerService class.
*/
@PrepareForTest(PermissionUtils.class)
public class PermissionManagerServiceTest {
@ -47,7 +50,6 @@ public class PermissionManagerServiceTest {
//For create properties to retrieve permission.
private static final String HTTP_METHOD = "HTTP_METHOD";
private static final String URL = "URL";
private Permission permission;
private PermissionManagerService permissionManagerService;
@ -72,7 +74,6 @@ public class PermissionManagerServiceTest {
try {
PowerMockito.mockStatic(PermissionUtils.class);
PowerMockito.when(PermissionUtils.putPermission(permission)).thenReturn(true);
Assert.assertTrue(permissionManagerService.addPermission(permission));
} catch (PermissionManagementException e) {
log.error("Error creating permission " + e.getErrorMessage());
@ -83,7 +84,6 @@ public class PermissionManagerServiceTest {
"from the permission tree.")
public void testGetPermission() throws PermissionManagementException {
Permission permission = permissionManagerService.getPermission(createProperties());
Assert.assertEquals(permission.getMethod(), PERMISSION_METHOD);
Assert.assertEquals(permission.getName(), PERMISSION_NAME);
Assert.assertEquals(permission.getPath(), PERMISSION_PATH);

@ -19,7 +19,6 @@ package org.wso2.carbon.device.mgt.core.search;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.powermock.api.mockito.PowerMockito;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -31,7 +30,6 @@ import org.wso2.carbon.device.mgt.common.search.SearchContext;
import org.wso2.carbon.device.mgt.core.TestDeviceManagementService;
import org.wso2.carbon.device.mgt.core.common.BaseDeviceManagementTest;
import org.wso2.carbon.device.mgt.core.common.TestDataHolder;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.search.mgt.InvalidOperatorException;
@ -43,19 +41,14 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* This class holds unit test cases for org.wso2.carbon.device.mgt.core.search.mgt.impl.ProcessorImpl
* */
public class ProcessorImplTest extends BaseDeviceManagementTest{
*/
public class ProcessorImplTest extends BaseDeviceManagementTest {
private DeviceAccessAuthorizationService deviceAccessAuthorizationService;
private static final Log log = LogFactory.getLog(SearchManagementServiceTest.class);
@ -67,7 +60,6 @@ public class ProcessorImplTest extends BaseDeviceManagementTest{
public void init() throws Exception {
deviceAccessAuthorizationService = DeviceManagementDataHolder.getInstance()
.getDeviceAccessAuthorizationService();
for (int i = 0; i < 5; i++) {
deviceIdentifiers.add(new DeviceIdentifier(DEVICE_ID_PREFIX + i, DEVICE_TYPE));
}
@ -76,7 +68,6 @@ public class ProcessorImplTest extends BaseDeviceManagementTest{
DeviceManagementDataHolder.getInstance().setDeviceManagementProvider(deviceMgtService);
deviceMgtService.registerDeviceType(new TestDeviceManagementService(DEVICE_TYPE,
MultitenantConstants.SUPER_TENANT_DOMAIN_NAME));
List<Device> devices = TestDataHolder.generateDummyDeviceData(deviceIdentifiers);
for (Device device : devices) {
device.setDeviceInfo(Utils.getDeviceInfo());
@ -91,27 +82,23 @@ public class ProcessorImplTest extends BaseDeviceManagementTest{
}
@Test(description = "Test the Search Processor")
public void testWithNoDeviceAccessAuthorization() throws Exception {
public void testWithNoDeviceAccessAuthorization() throws NoSuchFieldException, IllegalAccessException,
SearchMgtException {
SearchContext context = new SearchContext();
List<Condition> conditions = new ArrayList<>();
Condition cond = new Condition();
cond.setKey("batteryLevel");
cond.setOperator("=");
cond.setValue("40");
cond.setState(Condition.State.AND);
conditions.add(cond);
context.setConditions(conditions);
ProcessorImpl processor = new ProcessorImpl();
Field deviceAccessAuthorizationServiceField = ProcessorImpl.class.getDeclaredField
("deviceAccessAuthorizationService");
deviceAccessAuthorizationServiceField.setAccessible(true);
deviceAccessAuthorizationServiceField.set(processor, null);
List<Device> searchedDevices = processor.execute(context);
Assert.assertEquals(0, searchedDevices.size());
}
@ -120,9 +107,7 @@ public class ProcessorImplTest extends BaseDeviceManagementTest{
public void testInvalidState() throws SearchMgtException {
SearchContext context = new SearchContext();
List<Condition> conditions = new ArrayList<>();
ChangeEnumValues.addEnum(Condition.State.class, "BLA");
Condition.State state = Condition.State.valueOf("BLA");
Condition cond = new Condition();
@ -147,7 +132,6 @@ public class ProcessorImplTest extends BaseDeviceManagementTest{
conditions.add(cond3);
context.setConditions(conditions);
ProcessorImpl processor = new ProcessorImpl();
try {
processor.execute(context);
@ -161,13 +145,11 @@ public class ProcessorImplTest extends BaseDeviceManagementTest{
@Test(description = "Test when Device Access Authorization is null", expectedExceptions = {IllegalStateException
.class}, dependsOnMethods = {"testWithNoDeviceAccessAuthorization", "testInvalidState"})
public void testProcessorInitializationError() throws ClassNotFoundException, NoSuchMethodException,
NoSuchFieldException,
IllegalAccessException, SearchMgtException {
NoSuchFieldException, IllegalAccessException, SearchMgtException {
DeviceManagementDataHolder deviceManagementDataHolder = DeviceManagementDataHolder.getInstance();
Field field = DeviceManagementDataHolder.class.getDeclaredField("deviceAccessAuthorizationService");
field.setAccessible(true);
field.set(deviceManagementDataHolder, null);
ProcessorImpl processor = new ProcessorImpl();
processor.execute(null);
}

@ -72,8 +72,8 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
deviceMgtService.registerDeviceType(new TestDeviceManagementService(DEVICE_TYPE,
MultitenantConstants.SUPER_TENANT_DOMAIN_NAME));
DeviceInformationManager deviceInformationManager = new DeviceInformationManagerImpl();
List<Device> devices = TestDataHolder.generateDummyDeviceData(deviceIdentifiers);
for (Device device : devices) {
deviceMgtService.enrollDevice(device);
}
@ -90,6 +90,7 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
}
List<Device> returnedDevices = deviceMgtService.getAllDevices(DEVICE_TYPE, true);
for (Device device : returnedDevices) {
if (!device.getDeviceIdentifier().startsWith(DEVICE_ID_PREFIX)) {
throw new Exception("Incorrect device with ID - " + device.getDeviceIdentifier() + " returned!");
@ -108,9 +109,7 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
cond.setValue("40");
cond.setState(Condition.State.OR);
conditions.add(cond);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
List<Device> devices = service.search(context);
Assert.assertTrue(devices != null);
@ -127,9 +126,7 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
cond.setValue("Karandeniya");
cond.setState(Condition.State.AND);
conditions.add(cond);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
List<Device> devices = service.search(context);
Assert.assertTrue(devices != null);
@ -146,9 +143,7 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
cond.setValue("Colombo");
cond.setState(Condition.State.AND);
conditions.add(cond);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
List<Device> devices = service.search(context);
Assert.assertTrue(devices.size() == 0);
@ -165,12 +160,9 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
cond.setValue("SM-T520");
cond.setState(Condition.State.AND);
conditions.add(cond);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
List<Device> devices = service.search(context);
Assert.assertTrue(devices != null);
}
@ -185,12 +177,9 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
cond.setValue("3.56");
cond.setState(Condition.State.AND);
conditions.add(cond);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
List<Device> devices = service.search(context);
Assert.assertTrue(devices != null);
}
@ -205,12 +194,9 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
cond.setValue("SM-T520");
cond.setState(Condition.State.OR);
conditions.add(cond);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
List<Device> devices = service.search(context);
Assert.assertTrue(devices != null);
}
@ -232,9 +218,7 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
cond.setValue("bbb");
cond.setState(Condition.State.OR);
conditions.add(cond);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
try {
service.search(context);
@ -293,7 +277,6 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
conditions.add(cond6);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
List<Device> devices = service.search(context);
Assert.assertTrue(devices != null);
@ -333,7 +316,6 @@ public class SearchManagementServiceTest extends BaseDeviceManagementTest {
conditions.add(condition4);
context.setConditions(conditions);
SearchManagerService service = new SearchManagerServiceImpl();
List<Device> devices = service.search(context);
Assert.assertTrue(devices != null);

@ -66,7 +66,6 @@ public class SearchMgtUtilTest {
public void testConvertStringToList() {
List<String> stringList = Utils.convertStringToList("some string");
List<String> expected = this.getStringList();
Assert.assertEquals(stringList, expected);
}

@ -41,16 +41,12 @@ public class ChangeEnumValues {
private static void setFailSafeFieldValue(Field field, Object target, Object value) throws NoSuchFieldException,
IllegalAccessException {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
FieldAccessor fa = reflectionFactory.newFieldAccessor(field, false);
fa.set(target, value);
}
@ -115,15 +111,10 @@ public class ChangeEnumValues {
try {
T[] previousValues = (T[]) valuesField.get(enumType);
List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
T newValue = (T) makeEnum(enumType, enumName, values.size(), new Class<?>[]{}, new Object[]{});
values.add(newValue);
setFailSafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
cleanEnumCache(enumType);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}

@ -51,7 +51,6 @@ public class Utils {
deviceInfo.setLocation(getSampleDeviceLocation());
Map<String, String> propertyMap = new HashMap<>();
propertyMap.put("BATTERY_VOLTAGE", "40");
propertyMap.put("BATTERY_HEALTH", "Good");
propertyMap.put("BATTERY_STATUS", "SWElLED");
@ -61,14 +60,11 @@ public class Utils {
propertyMap.put("CPU_IRQ", "1");
propertyMap.put("IMEI", "e6f236ac82537a8e");
propertyMap.put("IMSI", "432659632123654845");
deviceInfo.setDeviceDetailsMap(propertyMap);
return deviceInfo;
}
private static DeviceLocation getSampleDeviceLocation(){
public static DeviceLocation getSampleDeviceLocation(){
DeviceLocation deviceLocation = new DeviceLocation();
deviceLocation.setDeviceIdentifier(Utils.getDeviceIdentifier());
deviceLocation.setLatitude(76.2422);
@ -80,7 +76,6 @@ public class Utils {
deviceLocation.setZip("80360");
deviceLocation.setCountry("Sri Lanka");
deviceLocation.setDeviceId(1);
return deviceLocation;
}
@ -88,11 +83,6 @@ public class Utils {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setType(TestDataHolder.TEST_DEVICE_TYPE);
deviceIdentifier.setId("12345");
return deviceIdentifier;
}
}

@ -417,6 +417,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_LOCATION (
ZIP VARCHAR(10) NULL,
STATE VARCHAR(45) NULL,
COUNTRY VARCHAR(45) NULL,
GEO_HASH VARCHAR(45) NULL,
UPDATE_TIMESTAMP BIGINT(15) NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT DM_DEVICE_LOCATION_DEVICE
@ -426,6 +427,8 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_LOCATION (
ON UPDATE NO ACTION
);
CREATE INDEX DM_DEVICE_LOCATION_GEO_hashx ON DM_DEVICE_LOCATION(GEO_HASH ASC);
CREATE TABLE IF NOT EXISTS DM_DEVICE_DETAIL (
ID INT NOT NULL AUTO_INCREMENT,
DEVICE_ID INT NOT NULL,

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -417,6 +417,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_LOCATION (
ZIP VARCHAR(10) NULL,
STATE VARCHAR(45) NULL,
COUNTRY VARCHAR(45) NULL,
GEO_HASH VARCHAR(45) NULL,
UPDATE_TIMESTAMP BIGINT(15) NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT DM_DEVICE_LOCATION_DEVICE

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.173-SNAPSHOT</version>
<version>3.0.183-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -6,6 +6,7 @@
"httpsURL": "https://%iot.gateway.host%:%iot.gateway.https.port%",
"httpURL": "http://%iot.gateway.host%:%iot.gateway.http.port%",
"wssURL": "https://%iot.analytics.host%:%iot.analytics.https.port%",
"remoteSessionWSURL": "https://%iot.core.host%:%iot.core.https.port%",
"portalURL": "https://%iot.analytics.host%:%iot.analytics.https.port%",
"dashboardServerURL": "%https.ip%",
"androidEnrollmentDir": "/android-web-agent/enrollment",

@ -0,0 +1,35 @@
{{!
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
}}
{{unit "cdmf.unit.ui.title" pageTitle="Device Location"}}
{{#zone "breadcrumbs"}}
<li>
<a href="{{@app.context}}/">
<i class="icon fw fw-home"></i>
</a>
</li>
<li>
<a href="{{@app.context}}/device-locations">
Device Locations
</a>
</li>
{{/zone}}
{{#zone "content"}}
{{unit "cdmf.unit.geo-devices"}}
{{/zone}}

@ -141,7 +141,7 @@
margin: 0px;
}
.tab-actions {
margin: 0px;
margin: 0px;
margin-bottom: 10px;
}
.tab-actions .action-prop{

@ -59,7 +59,7 @@ function getLogStatusIcon(entry) {
case 'ERROR':
return 'fw-error';
default:
return 'fw-info'
return 'fw-info';
}
}
@ -203,7 +203,7 @@ function loadOperationsLog(update) {
case 'ERROR':
return 'fw-error';
default:
return 'fw-info'
return 'fw-info';
}
}
}
@ -306,7 +306,6 @@ function loadApplicationsList() {
data[i]["name"] = decodeURIComponent(data[i]["name"]);
data[i]["platform"] = deviceType;
}
var viewModel = {};
viewModel["applications"] = data;
viewModel["deviceType"] = deviceType;

@ -105,7 +105,6 @@ function updateAttribution(e) {
}
});
}
var attributionControl;
var geoAlertsBar;
var groupedOverlays;

@ -40,33 +40,32 @@ function loadGeoFencing() {
function openTools(id) {
lastId = id;
if(drawControl){
if (drawControl) {
try{
map.removeControl(drawControl);
}catch(e){
} catch(e) {
console.log("error: " + e.message);
}
console.log("removed drawControl");
}
if(removeAllControl){
try{
if (removeAllControl) {
try {
map.removeControl(removeAllControl);
}catch(e){
} catch(e) {
console.log("error: " + e.message);
}
console.log("removed removeAllControl");
}
if(drawnItems){
if (drawnItems) {
try{
map.removeLayer(drawnItems);
console.log("removing layer");
}catch(e){
} catch(e) {
console.log("error: " + e.message);
}
console.log("removed drawnItems");
}
closeAll();
noty({text: "Please draw the required area on the map", type: "information"});
@ -107,12 +106,11 @@ function openTools(id) {
removeAllControl = new L.Control.RemoveAll();
map.addControl(removeAllControl);
// Initialise the FeatureGroup to store editable layers
drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
if(id=="WithIn"){
if (id=="WithIn") {
// Initialise the draw control and pass it the FeatureGroup of editable layers
drawControl = new L.Control.Draw({
draw: {
@ -139,7 +137,7 @@ function openTools(id) {
featureGroup: drawnItems
}
});
} else if(id=="Exit"){
} else if (id=="Exit") {
// Initialise the draw control and pass it the FeatureGroup of editable layers
drawControl = new L.Control.Draw({
draw: {
@ -168,7 +166,6 @@ function openTools(id) {
});
} else if(id=="Stationery"){
// Initialise the draw control and pass it the FeatureGroup of editable layers
drawControl = new L.Control.Draw({
draw: {
polygon: {
@ -198,7 +195,7 @@ function openTools(id) {
featureGroup: drawnItems
}
});
} else if(id=="Traffic"){
} else if (id=="Traffic") {
// Initialise the draw control and pass it the FeatureGroup of editable layers
drawControl = new L.Control.Draw({
draw: {
@ -233,7 +230,7 @@ function openTools(id) {
featureGroup: drawnItems
}
});
} else if(id =="Prediction"){
} else if (id =="Prediction") {
drawControl = new L.Control.Draw({
draw: {
polygon: false,
@ -252,28 +249,24 @@ function openTools(id) {
});
console.log("prediction tool opened");
}
map.addControl(drawControl);
}
function createPopup(layer,id) {
if(id=="WithIn"){
if (id=="WithIn") {
var popupTemplate = $('#setWithinAlert');
popupTemplate.find('#addWithinAlert').attr('leaflet_id', layer._leaflet_id);
} else if(id=="Exit"){
} else if (id=="Exit") {
var popupTemplate = $('#setExitAlert');
popupTemplate.find('#addExitAlert').attr('leaflet_id', layer._leaflet_id);
} else if(id=="Stationery"){
} else if (id=="Stationery") {
var popupTemplate = $('#setStationeryAlert');
popupTemplate.find('#addStationeryAlert').attr('leaflet_id', layer._leaflet_id);
} else if(id=="Traffic"){
} else if (id=="Traffic") {
var popupTemplate = $('#setTrafficAlert');
popupTemplate.find('#addTrafficAlert').attr('leaflet_id', layer._leaflet_id);
//console.log(">>got here " + id + " " + popupTemplate.find('#addTrafficAlert') + " " + layer._leaflet_id);
} else if(id=="Prediction"){
} else if (id=="Prediction") {
getPrediction(layer._leaflet_id);
return;
}
@ -364,7 +357,7 @@ function viewFence(geoFenceElement,id) {
var areaName = $(geoFenceElement).attr('data-areaName');
var geometryShape;
if(geoJson.type=="Point"){
if (geoJson.type=="Point") {
var circleOptions = {
color: '#ff0043'
@ -373,7 +366,7 @@ function viewFence(geoFenceElement,id) {
// var marker=new L.marker([geoJson.coordinates[1],geoJson.coordinates[0]]);
map.addLayer(geometryShape);
// map.addLayer(marker);
} else if(geoJson.type=="Polygon"){
} else if (geoJson.type=="Polygon") {
geoJson.coordinates[0].pop(); // popout the last coordinate set(lat,lng pair) due to circular chain
var leafletLatLngs = [];
$.each(geoJson.coordinates[0], function (idx, pItem) {
@ -385,7 +378,7 @@ function viewFence(geoFenceElement,id) {
var geoPublicUri = $("#geo-charts").data("geo-public-uri");
if(id=="Stationery"){
if (id=="Stationery") {
var stationeryTime=$(geoFenceElement).attr('data-stationeryTime');
$('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewStationeryAlert", function () {
@ -401,7 +394,7 @@ function viewFence(geoFenceElement,id) {
$(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)");
});
} else if(id=="WithIn"){
} else if (id=="WithIn") {
$('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewWithinAlert", function () {
var popupTemplate = $('#templateLoader').find('#viewWithinAlert');
@ -414,7 +407,7 @@ function viewFence(geoFenceElement,id) {
// transparent the layer .leaflet-popup-content-wrapper
$(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)");
});
} else if(id=="Exit"){
} else if (id=="Exit") {
$('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewExitAlert", function () {
var popupTemplate = $('#templateLoader').find('#viewExitAlert');
@ -427,7 +420,6 @@ function viewFence(geoFenceElement,id) {
// transparent the layer .leaflet-popup-content-wrapper
$(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)");
});
} else if(id=="Traffic"){
}
closeAll();
}
@ -440,7 +432,7 @@ function viewFenceByData(geoJson, queryName, areaName, stationeryTime, id) {
geoJson = JSON.parse(geoJson.replace(/'/g, '"'));
var geometryShape;
if(geoJson.type=="Point"){
if (geoJson.type=="Point") {
var circleOptions = {
color: '#ff0043'
@ -449,7 +441,7 @@ function viewFenceByData(geoJson, queryName, areaName, stationeryTime, id) {
// var marker=new L.marker([geoJson.coordinates[1],geoJson.coordinates[0]]);
map.addLayer(geometryShape);
// map.addLayer(marker);
} else if(geoJson.type=="Polygon"){
} else if (geoJson.type=="Polygon") {
geoJson.coordinates[0].pop(); // popout the last coordinate set(lat,lng pair) due to circular chain
var leafletLatLngs = [];
$.each(geoJson.coordinates[0], function (idx, pItem) {
@ -461,7 +453,7 @@ function viewFenceByData(geoJson, queryName, areaName, stationeryTime, id) {
var geoPublicUri = $("#geo-charts").data("geo-public-uri");
if(id=="Stationery"){
if (id=="Stationery") {
$('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewStationeryAlert", function () {
var popupTemplate = $('#templateLoader').find('#viewStationeryAlert');
@ -473,7 +465,7 @@ function viewFenceByData(geoJson, queryName, areaName, stationeryTime, id) {
$(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)");
});
} else if(id=="WithIn"){
} else if (id=="WithIn") {
$('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewWithinAlert", function () {
var popupTemplate = $('#templateLoader').find('#viewWithinAlert');
@ -486,7 +478,7 @@ function viewFenceByData(geoJson, queryName, areaName, stationeryTime, id) {
// transparent the layer .leaflet-popup-content-wrapper
$(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)");
});
} else if(id=="Exit"){
} else if (id=="Exit") {
$('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewExitAlert", function () {
var popupTemplate = $('#templateLoader').find('#viewExitAlert');
@ -499,7 +491,6 @@ function viewFenceByData(geoJson, queryName, areaName, stationeryTime, id) {
// transparent the layer .leaflet-popup-content-wrapper
$(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)");
});
} else if(id=="Traffic"){
}
closeAll();
}

@ -0,0 +1,55 @@
{{!
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
}}
{{#zone "topCss"}}
{{css "css/app.css" combine=false}}
{{css "css/map.css" combine=false}}
{{css "css/leaflet.css" combine=false}}
{{css "css/L.Control.Locate.css" combine=false}}
{{css "css/MarkerCluster.Default.css" combine=false}}
{{css "css/leaflet_fullscreen/leaflet.fullscreen.css" combine=false}}
{{css "css/leaflet/leaflet.draw.css" combine=false}}
{{css "css/leaflet.awesome-markers.css" combine=false}}
{{/zone}}
<div class="map-wrapper">
<div id="" style="height: 80vh;">
<div id="map"></div>
</div>
</div>
{{#zone "bottomJs" }}
{{js "js/leaflet/leaflet.js" }}
{{js "js/leaflet/leaflet.markercluster.js" }}
{{js "js/leaflet/L.Control.Locate.js" }}
{{js "js/leaflet/L.Control.Focus.js" }}
{{js "js/leaflet/leaflet.groupedlayercontrol.js" }}
{{js "js/leaflet/Leaflet.fullscreen.min.js" }}
{{js "js/leaflet/Marker.Rotate.js" }}
{{js "js/leaflet/leaflet.draw.js" }}
{{js "js/leaflet.awesome-markers.js"}}
{{js "js/typeahead.bundle.min.js" }}
{{js "js/geo_remote.js" }}
{{js "js/app.js" }}
<script type="text/javascript">
$(document).ready(function () {
initialLoad(false);
});
</script>
{{/zone}}

@ -0,0 +1,31 @@
/* Compatible with Leaflet 0.7 */
@import url('font/locate-fa.woff');
@import url('css/locate-fa.css');
@import url('css/animation.css');
.leaflet-touch .leaflet-bar-part-single {
-webkit-border-radius: 7px 7px 7px 7px;
border-radius: 7px 7px 7px 7px;
border-bottom: none;
}
.leaflet-control-locate a {
font-size: 1.4em;
margin-left: 1px;
color: #444;
}
.leaflet-control-locate.active a {
color: #2074B6;
}
.leaflet-control-locate.active.following a {
color: #FC8428;
}
.leaflet-touch .leaflet-control-locate {
box-shadow: none;
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}

@ -0,0 +1,14 @@
/* Conditional stylesheet for IE. */
@import url('css/locate-fa-ie7.css');
.leaflet-control-locate {
border: 3px solid #999;
}
.leaflet-control-locate a {
background-color: #eee;
}
.leaflet-control-locate a:hover {
background-color: #fff;
}

@ -0,0 +1,60 @@
.marker-cluster-small {
background-color: rgba(181, 226, 140, 0.6);
}
.marker-cluster-small div {
background-color: rgba(110, 204, 57, 0.6);
}
.marker-cluster-medium {
background-color: rgba(241, 211, 87, 0.6);
}
.marker-cluster-medium div {
background-color: rgba(240, 194, 12, 0.6);
}
.marker-cluster-large {
background-color: rgba(253, 156, 115, 0.6);
}
.marker-cluster-large div {
background-color: rgba(241, 128, 23, 0.6);
}
/* IE 6-8 fallback colors */
.leaflet-oldie .marker-cluster-small {
background-color: rgb(181, 226, 140);
}
.leaflet-oldie .marker-cluster-small div {
background-color: rgb(110, 204, 57);
}
.leaflet-oldie .marker-cluster-medium {
background-color: rgb(241, 211, 87);
}
.leaflet-oldie .marker-cluster-medium div {
background-color: rgb(240, 194, 12);
}
.leaflet-oldie .marker-cluster-large {
background-color: rgb(253, 156, 115);
}
.leaflet-oldie .marker-cluster-large div {
background-color: rgb(241, 128, 23);
}
.marker-cluster {
background-clip: padding-box;
border-radius: 20px;
}
.marker-cluster div {
width: 30px;
height: 30px;
margin-left: 5px;
margin-top: 5px;
text-align: center;
border-radius: 15px;
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
}
.marker-cluster span {
line-height: 30px;
}

@ -0,0 +1,6 @@
.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
-webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in;
-moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in;
-o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in;
transition: transform 0.3s ease-out, opacity 0.3s ease-in;
}

@ -0,0 +1,151 @@
input[type="radio"], input[type="checkbox"] {
margin: 0;
}
.map-wrapper{
background: #37474f;
}
#left_side_pannel> .nav > li > a{
color: #fff;
}
.typeahead {
background-color: #FFFFFF;
}
#map {
width: auto;
height: 100%;
}
#loading {
position: absolute;
width: 220px;
height: 19px;
top: 50%;
left: 50%;
margin: -10px 0 0 -110px;
z-index: 20001;
}
/*.sidebar-wrapper {
width: 100%;
height: 100%;
position: relative;
}
.sidebar-table {
position: absolute;
width: 100%;
top: 124px;
bottom: 0px;
overflow: auto;
}*/
.leaflet-control-layers label {
font-weight: normal;
margin-bottom: 0px;
}
.leaflet-control-layers-group-name {
font-weight: bold;
margin-bottom: .2em;
display: block;
}
.leaflet-control-layers-group {
margin-bottom: .5em;
}
.leaflet-control-layers-group label {
padding-left: .5em;
}
.table {
margin-bottom: 0px;
}
.tt-dropdown-menu {
background-color: #FFFFFF;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 4px 4px 4px 4px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
margin-top: 4px;
padding: 4px 0;
width: 100%;
max-height: 300px;
overflow: auto;
}
.tt-suggestion {
font-size: 14px;
line-height: 20px;
padding: 3px 10px;
}
.tt-suggestion.tt-cursor {
background-color: #0097CF;
color: #FFFFFF;
cursor: pointer;
}
.tt-suggestion p {
margin: 0;
}
.tt-suggestion + .tt-suggestion {
border-top: 1px solid #ccc;
}
.typeahead-header {
margin: 0 5px 5px 5px;
padding: 3px 0;
border-bottom: 2px solid #333;
}
.has-feedback .form-control-feedback {
position: absolute;
top: 0;
right: 0;
display: block;
width: 34px;
height: 34px;
line-height: 34px;
text-align: center;
}
@media (max-width: 992px) {
/*.navbar .navbar-brand {
font-size: 18px;
}*/
}
@media (max-width: 767px){
.url-break {
word-break: break-all;
word-break: break-word;
-webkit-hyphens: auto;
hyphens: auto;
}
#sidebar {
display: none;
}
}
.leaflet-geo-alerts{
border-radius: 4px;
border: none;
background-color: white;
padding: 5px;
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
width: 200px;
font-size: 11px;
}
.leaflet-geo-alerts a{
padding: 5px 10px;
}
/*
!* Print Handling *!
@media print {
.navbar {
display: none !important;
}
.leaflet-control-container {
display: none !important;
}
}
.nav > li > a {
padding: 25px 15px !important;
}
.nav > li > a:hover, .nav > li > a:focus {
background-color: transparent !important;
}
*/

@ -0,0 +1,19 @@
Copyright (C) 2013 Panopta, Andrew Moffat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,182 @@
/* WIZARD GENERAL */
.wizard {
display:none;
}
.wizard-dialog {}
.wizard-content {}
.wizard-body {
padding: 0;
margin: 0;
}
/* WIZARD HEADER */
.wizard-header {
padding: 9px 15px;
border-bottom: 0;
}
.wizard-header h3 {
margin: 0;
line-height: 35px;
display: inline;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-family: inherit;
font-weight: bold;
text-rendering: optimizelegibility;
color: rgb(51, 51, 51);
}
.wizard-subtitle {
font-weight:bold;
color:#AFAFAF;
padding-left:20px;
}
/* WIZARD NAVIGATION */
.wizard-steps {
width: 28%;
background-color: #f5f5f5;
border-bottom-left-radius: 6px;
position: relative;
}
.wizard-nav-container {
padding-bottom: 30px;
}
.wizard-nav-list {
margin-bottom: 0;
}
.wizard-nav-link .glyphicon-chevron-right {
float:right;
margin-top:12px;
margin-right:-6px;
opacity:.25;
}
li.wizard-nav-item.active .glyphicon-chevron-right {
opacity:1;
}
li.wizard-nav-item {
line-height:40px;
}
.wizard-nav-list > li > a {
background-color:#f5f5f5;
padding:3px 15px 3px 20px;
cursor:default;
color:#B4B4B4;
}
.wizard-nav-list > li > a:hover {
background-color: transparent;
}
.wizard-nav-list > li.already-visited > a.wizard-nav-link {
color:#08C;
cursor:pointer;
}
.wizard-nav-list > li.active > a.wizard-nav-link {
color:white;
}
.wizard-nav-item .already-visited .active {
background-color:#08C;
}
.wizard-nav-list li.active > a {
background-color:#08C;
}
/* WIZARD CONTENT */
.wizard-body form {
padding: 0;
margin: 0;
}
/* WIZARD PROGRESS BAR */
.wizard-progress-container {
margin-top: 20px;
padding: 15px;
width: 100%;
position: absolute;
bottom: 0;
}
.wizard-card-container {
margin-left: 28%;
}
/* WIZARD CARDS */
.wizard-error,
.wizard-failure,
.wizard-success,
.wizard-loading,
.wizard-card {
border-top: 1px solid #EEE;
display:none;
padding:35px;
padding-top:20px;
overflow-y:auto;
/*
position:relative;
height:300px;
margin-right: 5px;
*/
}
.wizard-card-overlay {
overflow-y: initial;
}
.wizard-card > h3 {
margin-top:0;
margin-bottom:20px;
font-size:21px;
line-height:40px;
font-weight:normal;
}
/* WIZARD FOOTER */
.wizard-footer {
padding:0;
}
.wizard-buttons-container {
padding:20px;
}
.wizard-cancel {
margin-left: 12px;
}
/* Inner Card */
.wizard-input-section {
margin-bottom:20px;
}
.wizard-dialog .popover.error-popover {
background-color:#F2DEDE;
color:#B94A48;
border-color:#953B39;
}
.wizard-dialog .popover.error-popover .arrow::after {
border-right-color:#F2DEDE;
}
.wizard-dialog .popover.error-popover .popover-title {
display:none;
}
.wizard-dialog .popover.error-popover .arrow {
border-right-color:#953B39;
}

@ -0,0 +1,85 @@
/*
Animation example, for spinners
*/
.animate-spin:before {
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
-webkit-animation: spin 2s infinite linear;
animation: spin 2s infinite linear;
display: inline-block;
}
@-moz-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-webkit-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-o-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-ms-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}

@ -0,0 +1,4 @@
.icon-location:before { content: '\e802'; } /* '' */
.icon-direction:before { content: '\e800'; } /* '' */
.icon-spinner:before { content: '\e801'; } /* '' */

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

Loading…
Cancel
Save