Merge branch 'master' of https://github.com/wso2/carbon-device-mgt into entgra-master

# Conflicts:
#	components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java
#	components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java
#	components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java
revert-70aa11f8
charitha 6 years ago
commit 2cac0053ab

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

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

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

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

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

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

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

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

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

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

@ -24,7 +24,7 @@
<parent> <parent>
<artifactId>certificate-mgt</artifactId> <artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

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

@ -24,7 +24,7 @@
<parent> <parent>
<artifactId>certificate-mgt</artifactId> <artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

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

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

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

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

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

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

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

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

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

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

@ -29,6 +29,7 @@ import org.wso2.carbon.analytics.dataservice.commons.SortType;
import org.wso2.carbon.analytics.datasource.commons.Record; import org.wso2.carbon.analytics.datasource.commons.Record;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.context.CarbonContext; 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.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices; import org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
@ -163,17 +164,20 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier(); DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId); identifier.setId(deviceId);
identifier.setType(deviceType); identifier.setType(deviceType);
Device device = DeviceMgtAPIUtils.getDeviceManagementService().getDevice(identifier, false);
if (device == null || device.getEnrolmentInfo() == null) {
if (log.isDebugEnabled()) {
log.debug("Device not found: " + identifier.toString());
}
return Response.status(Response.Status.NOT_FOUND.getStatusCode()).build();
}
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.createGeoAlert(alert, identifier, alertType); geoService.createGeoAlert(alert, identifier, alertType, device.getEnrolmentInfo().getOwner());
return Response.ok().build(); return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) { } catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) {
String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId; String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId;
@ -181,7 +185,12 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (AlertAlreadyExistException e) { } catch (AlertAlreadyExistException e) {
String error = "A geo alert with this name already exists."; String error = "A geo alert with this name already exists.";
log.error(error,e); log.error(error, e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
} catch (DeviceManagementException e) {
String error = "Error occurred while retrieving the device enrollment info of " +
deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
} }
} }
@ -202,7 +211,7 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (AlertAlreadyExistException e) { } catch (AlertAlreadyExistException e) {
String error = "A geo alert with this name already exists."; String error = "A geo alert with this name already exists.";
log.error(error,e); log.error(error, e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
} }
} }
@ -222,17 +231,20 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier(); DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId); identifier.setId(deviceId);
identifier.setType(deviceType); identifier.setType(deviceType);
Device device = DeviceMgtAPIUtils.getDeviceManagementService().getDevice(identifier, false);
if (device == null || device.getEnrolmentInfo() == null) {
if (log.isDebugEnabled()) {
log.debug("Device not found: " + identifier.toString());
}
return Response.status(Response.Status.NOT_FOUND.getStatusCode()).build();
}
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.updateGeoAlert(alert, identifier, alertType); geoService.updateGeoAlert(alert, identifier, alertType, device.getEnrolmentInfo().getOwner());
return Response.ok().build(); return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) { } catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) {
String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId; String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId;
@ -240,7 +252,12 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (AlertAlreadyExistException e) { } catch (AlertAlreadyExistException e) {
String error = "A geo alert with this name already exists."; String error = "A geo alert with this name already exists.";
log.error(error,e); log.error(error, e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
} catch (DeviceManagementException e) {
String error = "Error occurred while retrieving the device enrollment info of " +
deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
} }
} }
@ -260,7 +277,7 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (AlertAlreadyExistException e) { } catch (AlertAlreadyExistException e) {
String error = "A geo alert with this name already exists."; String error = "A geo alert with this name already exists.";
log.error(error,e); log.error(error, e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
} }
} }
@ -280,22 +297,30 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier(); DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId); identifier.setId(deviceId);
identifier.setType(deviceType); identifier.setType(deviceType);
Device device = DeviceMgtAPIUtils.getDeviceManagementService().getDevice(identifier, false);
if (device == null || device.getEnrolmentInfo() == null) {
if (log.isDebugEnabled()) {
log.debug("Device not found: " + identifier.toString());
}
return Response.status(Response.Status.NOT_FOUND.getStatusCode()).build();
}
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.removeGeoAlert(alertType, identifier, queryName); geoService.removeGeoAlert(alertType, identifier, queryName, device.getEnrolmentInfo().getOwner());
return Response.ok().build(); return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) { } catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) {
String error = "Error occurred while removing the geo alert for " + deviceType + " with id: " + deviceId; String error = "Error occurred while removing the geo alert for " + deviceType + " with id: " + deviceId;
log.error(error, e); log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (DeviceManagementException e) {
String error = "Error occurred while retrieving the device enrollment info of " +
deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
} }
} }
@ -329,34 +354,37 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier(); DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId); identifier.setId(deviceId);
identifier.setType(deviceType); identifier.setType(deviceType);
Device device = DeviceMgtAPIUtils.getDeviceManagementService().getDevice(identifier, false);
if (device == null || device.getEnrolmentInfo() == null) {
if (log.isDebugEnabled()) {
log.debug("Device not found: " + identifier.toString());
}
return Response.status(Response.Status.NOT_FOUND.getStatusCode()).build();
}
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) { if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) {
List<GeoFence> alerts = geoService.getWithinAlerts(identifier); List<GeoFence> alerts = geoService.getWithinAlerts(identifier, device.getEnrolmentInfo().getOwner());
return Response.ok().entity(alerts).build(); return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) {
List<GeoFence> alerts = geoService.getExitAlerts(identifier); List<GeoFence> alerts = geoService.getExitAlerts(identifier, device.getEnrolmentInfo().getOwner());
return Response.ok().entity(alerts).build(); return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) {
String result = geoService.getSpeedAlerts(identifier); String result = geoService.getSpeedAlerts(identifier, device.getEnrolmentInfo().getOwner());
return Response.ok().entity(result).build(); return Response.ok().entity(result).build();
} else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) {
String result = geoService.getProximityAlerts(identifier); String result = geoService.getProximityAlerts(identifier, device.getEnrolmentInfo().getOwner());
return Response.ok().entity(result).build(); return Response.ok().entity(result).build();
} else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) {
List<GeoFence> alerts = geoService.getStationaryAlerts(identifier); List<GeoFence> alerts = geoService.getStationaryAlerts(identifier, device.getEnrolmentInfo().getOwner());
return Response.ok().entity(alerts).build(); return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) {
List<GeoFence> alerts = geoService.getTrafficAlerts(identifier); List<GeoFence> alerts = geoService.getTrafficAlerts(identifier, device.getEnrolmentInfo().getOwner());
return Response.ok().entity(alerts).build(); return Response.ok().entity(alerts).build();
} }
return null; return null;
@ -364,6 +392,11 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
String error = "Error occurred while getting the geo alerts for " + deviceType + " with id: " + deviceId; String error = "Error occurred while getting the geo alerts for " + deviceType + " with id: " + deviceId;
log.error(error, e); log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (DeviceManagementException e) {
String error = "Error occurred while retrieving the device enrollment info of " +
deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
} }
} }

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

@ -105,7 +105,7 @@ public final class DeviceManagementConstants {
public static final String ALERT_TYPE_PROXIMITY = "Proximity"; public static final String ALERT_TYPE_PROXIMITY = "Proximity";
public static final String ALERT_TYPE_STATIONARY = "Stationery"; public static final String ALERT_TYPE_STATIONARY = "Stationery";
public static final String ALERT_TYPE_TRAFFIC = "Traffic"; public static final String ALERT_TYPE_TRAFFIC = "Traffic";
public static final String REGISTRY_PATH_FOR_ALERTS = "/_system/governance/geo/alerts/"; public static final String REGISTRY_PATH_FOR_ALERTS = "/geo/alerts/";
public static final String PROXIMITY_DISTANCE = "proximityDistance"; public static final String PROXIMITY_DISTANCE = "proximityDistance";
public static final String PROXIMITY_TIME = "proximityTime"; public static final String PROXIMITY_TIME = "proximityTime";
public static final String STATIONARY_NAME = "stationeryName"; public static final String STATIONARY_NAME = "stationeryName";
@ -113,6 +113,8 @@ public final class DeviceManagementConstants {
public static final String FLUCTUATION_RADIUS = "fluctuationRadius"; public static final String FLUCTUATION_RADIUS = "fluctuationRadius";
public static final String QUERY_NAME = "queryName"; public static final String QUERY_NAME = "queryName";
public static final String AREA_NAME = "areaName"; public static final String AREA_NAME = "areaName";
public static final String EXECUTION_PLAN_NAME = "executionPlanName";
public static final String DEVICE_OWNER = "owner";
public static final String GEO_FENCE_GEO_JSON = "geoFenceGeoJSON"; public static final String GEO_FENCE_GEO_JSON = "geoFenceGeoJSON";
public static final String SPEED_ALERT_VALUE = "speedAlertValue"; public static final String SPEED_ALERT_VALUE = "speedAlertValue";

@ -28,45 +28,45 @@ import java.util.List;
*/ */
public interface GeoLocationProviderService { public interface GeoLocationProviderService {
List<GeoFence> getWithinAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException; List<GeoFence> getWithinAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException;
List<GeoFence> getWithinAlerts() throws GeoLocationBasedServiceException; List<GeoFence> getWithinAlerts() throws GeoLocationBasedServiceException;
List<GeoFence> getExitAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException; List<GeoFence> getExitAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException;
List<GeoFence> getExitAlerts() throws GeoLocationBasedServiceException; List<GeoFence> getExitAlerts() throws GeoLocationBasedServiceException;
boolean createGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType) boolean createGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType, String owner)
throws GeoLocationBasedServiceException, AlertAlreadyExistException; throws GeoLocationBasedServiceException, AlertAlreadyExistException;
boolean createGeoAlert(Alert alert, String alertType) boolean createGeoAlert(Alert alert, String alertType)
throws GeoLocationBasedServiceException,AlertAlreadyExistException; throws GeoLocationBasedServiceException,AlertAlreadyExistException;
boolean updateGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType) boolean updateGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType, String owner)
throws GeoLocationBasedServiceException, AlertAlreadyExistException; throws GeoLocationBasedServiceException, AlertAlreadyExistException;
boolean updateGeoAlert(Alert alert, String alertType) boolean updateGeoAlert(Alert alert, String alertType)
throws GeoLocationBasedServiceException,AlertAlreadyExistException; throws GeoLocationBasedServiceException,AlertAlreadyExistException;
boolean removeGeoAlert(String alertType, DeviceIdentifier identifier, String queryName) boolean removeGeoAlert(String alertType, DeviceIdentifier identifier, String queryName, String owner)
throws GeoLocationBasedServiceException; throws GeoLocationBasedServiceException;
boolean removeGeoAlert(String alertType, String queryName) boolean removeGeoAlert(String alertType, String queryName)
throws GeoLocationBasedServiceException; throws GeoLocationBasedServiceException;
String getSpeedAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException; String getSpeedAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException;
String getSpeedAlerts() throws GeoLocationBasedServiceException; String getSpeedAlerts() throws GeoLocationBasedServiceException;
String getProximityAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException; String getProximityAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException;
String getProximityAlerts() throws GeoLocationBasedServiceException; String getProximityAlerts() throws GeoLocationBasedServiceException;
List<GeoFence> getStationaryAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException; List<GeoFence> getStationaryAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException;
List<GeoFence> getStationaryAlerts() throws GeoLocationBasedServiceException; List<GeoFence> getStationaryAlerts() throws GeoLocationBasedServiceException;
List<GeoFence> getTrafficAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException; List<GeoFence> getTrafficAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException;
List<GeoFence> getTrafficAlerts() throws GeoLocationBasedServiceException; List<GeoFence> getTrafficAlerts() throws GeoLocationBasedServiceException;
} }

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

@ -22,7 +22,9 @@ package org.wso2.carbon.device.mgt.core.archival;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.TransactionManagementException; import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.core.archival.beans.*;
import org.wso2.carbon.device.mgt.core.archival.dao.*; import org.wso2.carbon.device.mgt.core.archival.dao.*;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
@ -36,7 +38,13 @@ public class ArchivalServiceImpl implements ArchivalService {
private ArchivalDAO archivalDAO; private ArchivalDAO archivalDAO;
private DataDeletionDAO dataDeletionDAO; private DataDeletionDAO dataDeletionDAO;
private static int ITERATION_COUNT = 10000; private static final int EXECUTION_BATCH_SIZE =
DeviceConfigurationManager.getInstance().getDeviceManagementConfig().getArchivalConfiguration()
.getArchivalTaskConfiguration().getBatchSize();
private static final boolean ARCHIVE_PENDING_OPERATIONS =
DeviceConfigurationManager.getInstance().getDeviceManagementConfig().getArchivalConfiguration()
.getArchivalTaskConfiguration().isArchivePendingOperations();
private String[] NOT_IN_PROGRESS_OPS = new String[]{"COMPLETED", "ERROR", "REPEATED"}; 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_OPS = new String[]{"COMPLETED", "ERROR", "REPEATED", "IN_PROGRESS"};
@ -49,95 +57,188 @@ public class ArchivalServiceImpl implements ArchivalService {
@Override @Override
public void archiveTransactionalRecords() throws ArchivalException { public void archiveTransactionalRecords() throws ArchivalException {
List<Integer> allOperations;
try { try {
ArchivalSourceDAOFactory.openConnection(); ArchivalSourceDAOFactory.openConnection();
ArchivalDestinationDAOFactory.openConnection(); ArchivalDestinationDAOFactory.openConnection();
List<Integer> allOperations = archivalDAO.getAllOperations(); if (log.isDebugEnabled()) {
List<Integer> pendingAndIPOperations = archivalDAO.getPendingAndInProgressOperations(); log.debug("Fetching All Operations");
}
allOperations = archivalDAO.getAllOperations();
if (log.isDebugEnabled()) {
log.debug("Fetching All Pending Operations");
}
} catch (ArchivalDAOException e) {
// rollbackTransactions();
String msg = "Rollback the get all operations and get all pending operations";
log.error(msg, e);
throw new ArchivalException(msg, e);
} catch (SQLException e) {
String msg = "An error occurred while connecting to the archival database";
log.error(msg, e);
throw new ArchivalException(msg, e);
} finally {
ArchivalSourceDAOFactory.closeConnection();
ArchivalDestinationDAOFactory.closeConnection();
}
log.info(allOperations.size() + " All Operations. " + pendingAndIPOperations.size() + List<Integer> candidates = allOperations;
" P&IP Operations"); log.info(allOperations.size() + " All Operations.");
//Get the diff of operations
Set<Integer> setA = new HashSet<>(allOperations); if (!ARCHIVE_PENDING_OPERATIONS) {
Set<Integer> setB = new HashSet<>(pendingAndIPOperations); try {
setA.removeAll(setB); ArchivalSourceDAOFactory.openConnection();
ArchivalDestinationDAOFactory.openConnection();
List<Integer> pendingAndIPOperations = archivalDAO.getPendingAndInProgressOperations();
log.info(pendingAndIPOperations.size() +" P&IP Operations");
// Get the diff of operations
candidates.removeAll(pendingAndIPOperations);
} catch (ArchivalDAOException e) {
String msg = "Error occurred while retrieving the pending operations";
log.error(msg, e);
throw new ArchivalException(msg, e);
} catch (SQLException e) {
String msg = "An error occurred while connecting to the archival database";
log.error(msg, e);
throw new ArchivalException(msg, e);
} finally {
ArchivalSourceDAOFactory.closeConnection();
ArchivalDestinationDAOFactory.closeConnection();
}
}
List<Integer> candidates = new ArrayList<>(); int total = candidates.size();
candidates.addAll(setA); int batches = calculateNumberOfBatches(total);
log.info(total + " Operations ready for archiving. " + batches + " iterations to be done.");
int batchSize = EXECUTION_BATCH_SIZE;
if (log.isDebugEnabled()) {
log.debug(total + " Operations ready for archiving. " + batches + " iterations to be done.");
log.debug(batchSize + " is the batch size");
}
int total = candidates.size(); for (int i = 1; i <= batches; i++) {
int batches = calculateNumberOfBatches(total); int startIdx = batchSize * (i - 1);
int batchSize = ITERATION_COUNT; int endIdx = batchSize * i;
if (i == batches) {
endIdx = startIdx + (total % batchSize);
}
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(total + " Operations ready for archiving. " + batches + " iterations to be done."); log.debug("\n\n############ Iterating over batch " + i + "[" +
startIdx + "," + endIdx + "] #######");
} }
List<Integer> subList = candidates.subList(startIdx, endIdx);
beginTransactions(); if (log.isDebugEnabled()) {
for (int i = 1; i <= batches; i++) { log.debug("SubList size is: " + subList.size());
int startIdx = batchSize * (i - 1); if (subList.size() > 0) {
int endIdx = batchSize * i; log.debug("First Element is: " + subList.get(0));
if (i == batches) { log.debug("Last Element is: " + subList.get(subList.size() - 1));
endIdx = startIdx + (total % batchSize);
} }
if(log.isDebugEnabled()) { }
log.debug("\n\n############ Iterating over batch " + i + "[" +
startIdx + "," + endIdx + "] #######"); if (log.isDebugEnabled()) {
for (Integer val : subList) {
if (log.isDebugEnabled()) {
log.debug("Sub List Element: " + val);
}
} }
List<Integer> subList = candidates.subList(startIdx, endIdx); }
try {
beginTransactions();
prepareTempTable(subList); prepareTempTable(subList);
commitTransactions();
} catch (Exception e) {
rollbackTransactions();
String msg = "Error occurred while preparing the operations.";
log.error(msg, e);
throw new ArchivalException(msg, e);
} finally {
ArchivalSourceDAOFactory.closeConnection();
ArchivalDestinationDAOFactory.closeConnection();
}
List<ArchiveOperationResponse> operationResponses = null;
List<ArchiveNotification> notification = null;
List<ArchiveCommandOperation> commandOperations = null;
List<ArchiveProfileOperation> profileOperations = null;
List<ArchiveEnrolmentOperationMap> enrollmentMapping = null;
List<ArchiveOperation> operations = null;
try {
openConnection();
operationResponses = archivalDAO.selectOperationResponses();
notification = archivalDAO.selectNotifications();
commandOperations = archivalDAO.selectCommandOperations();
profileOperations = archivalDAO.selectProfileOperations();
enrollmentMapping = archivalDAO.selectEnrolmentMappings();
operations = archivalDAO.selectOperations();
} catch (Exception e) {
String msg = "Error occurred while retrieving data.";
log.error(msg, e);
throw new ArchivalException(msg, e);
} finally {
closeConnection();
}
try {
beginTransactions();
//Purge the largest table, DM_DEVICE_OPERATION_RESPONSE //Purge the largest table, DM_DEVICE_OPERATION_RESPONSE
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("## Purging operation responses"); log.debug("## Archiving operation responses");
} }
archivalDAO.moveOperationResponses(); archivalDAO.moveOperationResponses(operationResponses);
//Purge the notifications table, DM_NOTIFICATION //Purge the notifications table, DM_NOTIFICATION
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("## Purging notifications"); log.debug("## Archiving notifications");
} }
archivalDAO.moveNotifications(); archivalDAO.moveNotifications(notification);
//Purge the command operations table, DM_COMMAND_OPERATION //Purge the command operations table, DM_COMMAND_OPERATION
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("## Purging command operations"); log.debug("## Archiving command operations");
} }
archivalDAO.moveCommandOperations(); archivalDAO.moveCommandOperations(commandOperations);
//Purge the profile operation table, DM_PROFILE_OPERATION //Purge the profile operation table, DM_PROFILE_OPERATION
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("## Purging profile operations"); log.debug("## Archiving profile operations");
} }
archivalDAO.moveProfileOperations(); archivalDAO.moveProfileOperations(profileOperations);
//Purge the config operation table, DM_CONFIG_OPERATION
if (log.isDebugEnabled()) {
log.debug("## Purging config operations");
}
archivalDAO.moveConfigOperations();
//Purge the enrolment mappings table, DM_ENROLMENT_OP_MAPPING //Purge the enrolment mappings table, DM_ENROLMENT_OP_MAPPING
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("## Purging enrolment mappings"); log.debug("## Archiving enrolment mappings");
} }
archivalDAO.moveEnrolmentMappings(); archivalDAO.moveEnrolmentMappings(enrollmentMapping);
//Finally, purge the operations table, DM_OPERATION //Finally, purge the operations table, DM_OPERATION
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("## Purging operations"); log.debug("## Archiving operations");
}
archivalDAO.moveOperations(operations);
commitTransactions();
if (log.isDebugEnabled()) {
log.debug("End of Iteration : " + i);
} }
archivalDAO.moveOperations(); } catch (ArchivalDAOException e) {
rollbackTransactions();
String msg = "Error occurred while trying to archive data to the six tables";
log.error(msg, e);
throw new ArchivalException(msg, e);
} finally {
ArchivalSourceDAOFactory.closeConnection();
ArchivalDestinationDAOFactory.closeConnection();
} }
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();
} }
} }
@ -147,6 +248,9 @@ public class ArchivalServiceImpl implements ArchivalService {
log.debug("## Truncating the temporary table"); log.debug("## Truncating the temporary table");
} }
archivalDAO.truncateOperationIDsForArchival(); archivalDAO.truncateOperationIDsForArchival();
if (log.isDebugEnabled()) {
log.debug("## Inserting into the temporary table");
}
archivalDAO.copyOperationIDsForArchival(subList); archivalDAO.copyOperationIDsForArchival(subList);
} }
@ -160,6 +264,28 @@ public class ArchivalServiceImpl implements ArchivalService {
} }
} }
private void openConnection() throws ArchivalException {
try {
ArchivalSourceDAOFactory.openConnection();
} catch (SQLException e) {
String msg = "An error occurred during opening connection";
log.error(msg, e);
throw new ArchivalException(msg, e);
}
}
private void closeConnection() throws ArchivalException {
try {
ArchivalSourceDAOFactory.closeConnection();
} catch (Exception e) {
String msg = "An error occurred during opening connection";
log.error(msg, e);
throw new ArchivalException(msg, e);
}
}
private void commitTransactions() { private void commitTransactions() {
ArchivalSourceDAOFactory.commitTransaction(); ArchivalSourceDAOFactory.commitTransaction();
ArchivalDestinationDAOFactory.commitTransaction(); ArchivalDestinationDAOFactory.commitTransaction();
@ -172,7 +298,7 @@ public class ArchivalServiceImpl implements ArchivalService {
private int calculateNumberOfBatches(int total) { private int calculateNumberOfBatches(int total) {
int batches = 0; int batches = 0;
int batchSize = ITERATION_COUNT; int batchSize = EXECUTION_BATCH_SIZE;
if ((total % batchSize) > 0) { if ((total % batchSize) > 0) {
batches = (total / batchSize) + 1; batches = (total / batchSize) + 1;
} else { } else {

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

@ -0,0 +1,80 @@
/*
* Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.beans;
public class ArchiveEnrolmentOperationMap {
private int id;
private int enrolmentId;
private int operationId;
private String status;
private int createdTimestamp;
private int updatedTimestamp;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getEnrolmentId() {
return enrolmentId;
}
public void setEnrolmentId(int enrolmentId) {
this.enrolmentId = enrolmentId;
}
public int getOperationId() {
return operationId;
}
public void setOperationId(int operationId) {
this.operationId = operationId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public int getCreatedTimestamp() {
return createdTimestamp;
}
public void setCreatedTimestamp(int createdTimestamp) {
this.createdTimestamp = createdTimestamp;
}
public int getUpdatedTimestamp() {
return updatedTimestamp;
}
public void setUpdatedTimestamp(int updatedTimestamp) {
this.updatedTimestamp = updatedTimestamp;
}
}

@ -0,0 +1,80 @@
/*
* Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.beans;
public class ArchiveNotification {
private int notificationId;
private int deviceId;
private int operationId;
private int tenantId;
private String status;
private String description;
public int getNotificationId() {
return notificationId;
}
public void setNotificationId(int notificationId) {
this.notificationId = notificationId;
}
public int getDeviceId() {
return deviceId;
}
public void setDeviceId(int deviceId) {
this.deviceId = deviceId;
}
public int getOperationId() {
return operationId;
}
public void setOperationId(int operationId) {
this.operationId = operationId;
}
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

@ -0,0 +1,72 @@
/*
* Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.beans;
import java.sql.Timestamp;
public class ArchiveOperation {
private int id;
private String type;
private Timestamp createdTimeStamp;
private Timestamp recievedTimeStamp;
private String operationCode;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Timestamp getCreatedTimeStamp() {
return createdTimeStamp;
}
public void setCreatedTimeStamp(Timestamp createdTimeStamp) {
this.createdTimeStamp = createdTimeStamp;
}
public Timestamp getRecievedTimeStamp() {
return recievedTimeStamp;
}
public void setRecievedTimeStamp(Timestamp recievedTimeStamp) {
this.recievedTimeStamp = recievedTimeStamp;
}
public String getOperationCode() {
return operationCode;
}
public void setOperationCode(String operationCode) {
this.operationCode = operationCode;
}
}

@ -0,0 +1,83 @@
/*
* Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.beans;
import java.sql.Timestamp;
public class ArchiveOperationResponse {
private int id;
private int enrolmentId;
private int operationId;
private int enOpMapId;
private Object operationResponse;
private Timestamp receivedTimeStamp;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getEnrolmentId() {
return enrolmentId;
}
public void setEnrolmentId(int enrolmentId) {
this.enrolmentId = enrolmentId;
}
public int getOperationId() {
return operationId;
}
public void setOperationId(int operationId) {
this.operationId = operationId;
}
public int getEnOpMapId() {
return enOpMapId;
}
public void setEnOpMapId(int enOpMapId) {
this.enOpMapId = enOpMapId;
}
public Object getOperationResponse() {
return operationResponse;
}
public void setOperationResponse(Object operationResponse) {
this.operationResponse = operationResponse;
}
public Timestamp getReceivedTimeStamp() {
return receivedTimeStamp;
}
public void setReceivedTimeStamp(Timestamp receivedTimeStamp) {
this.receivedTimeStamp = receivedTimeStamp;
}
}

@ -0,0 +1,53 @@
/*
* Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.archival.beans;
public class ArchiveProfileOperation {
private int operationId;
private int enabled;
private Object operationDetails;
public int getOperationId() {
return operationId;
}
public void setOperationId(int operationId) {
this.operationId = operationId;
}
public int getEnabled() {
return enabled;
}
public void setEnabled(int enabled) {
this.enabled = enabled;
}
public Object getOperationDetails() {
return operationDetails;
}
public void setOperationDetails(Object operationDetails) {
this.operationDetails = operationDetails;
}
}

@ -18,6 +18,9 @@
package org.wso2.carbon.device.mgt.core.archival.dao; package org.wso2.carbon.device.mgt.core.archival.dao;
import org.wso2.carbon.device.mgt.core.archival.beans.*;
import java.sql.ResultSet;
import java.util.List; import java.util.List;
/** /**
@ -33,19 +36,29 @@ public interface ArchivalDAO {
void copyOperationIDsForArchival(List<Integer> operationIds) throws ArchivalDAOException; void copyOperationIDsForArchival(List<Integer> operationIds) throws ArchivalDAOException;
void moveOperationResponses() throws ArchivalDAOException; List<ArchiveOperationResponse> selectOperationResponses() throws ArchivalDAOException;
void moveOperationResponses(List<ArchiveOperationResponse> rs) throws ArchivalDAOException;
List<ArchiveNotification> selectNotifications() throws ArchivalDAOException;
void moveNotifications(List<ArchiveNotification> rs) throws ArchivalDAOException;
List<ArchiveCommandOperation> selectCommandOperations() throws ArchivalDAOException;
void moveCommandOperations(List<ArchiveCommandOperation> rs) throws ArchivalDAOException;
void moveNotifications() throws ArchivalDAOException; List<ArchiveProfileOperation> selectProfileOperations() throws ArchivalDAOException;
void moveCommandOperations() throws ArchivalDAOException; void moveProfileOperations(List<ArchiveProfileOperation> rs) throws ArchivalDAOException;
void moveProfileOperations() throws ArchivalDAOException; List<ArchiveEnrolmentOperationMap> selectEnrolmentMappings() throws ArchivalDAOException;
void moveConfigOperations() throws ArchivalDAOException; void moveEnrolmentMappings(List<ArchiveEnrolmentOperationMap> rs) throws ArchivalDAOException;
void moveEnrolmentMappings() throws ArchivalDAOException; List<ArchiveOperation> selectOperations() throws ArchivalDAOException;
void moveOperations() throws ArchivalDAOException; void moveOperations(List<ArchiveOperation> rs) throws ArchivalDAOException;
void truncateOperationIDsForArchival() throws ArchivalDAOException; void truncateOperationIDsForArchival() throws ArchivalDAOException;

@ -57,4 +57,14 @@ public class ArchivalDAOUtil {
} }
} }
public static void cleanupResultSet(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
log.warn("Error occurred while closing the result set", e);
}
}
}
} }

@ -20,11 +20,11 @@ package org.wso2.carbon.device.mgt.core.archival.dao.impl;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.core.archival.beans.*;
import org.wso2.carbon.device.mgt.core.archival.dao.*; import org.wso2.carbon.device.mgt.core.archival.dao.*;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.util.*;
import java.util.List;
public class ArchivalDAOImpl implements ArchivalDAO { public class ArchivalDAOImpl implements ArchivalDAO {
@ -55,21 +55,26 @@ public class ArchivalDAOImpl implements ArchivalDAO {
ResultSet rs = null; ResultSet rs = null;
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT DISTINCT OPERATION_ID FROM DM_ENROLMENT_OP_MAPPING " + String sql = "SELECT ID FROM DM_OPERATION WHERE CREATED_TIMESTAMP < (DATE_SUB(NOW(), INTERVAL "
"WHERE CREATED_TIMESTAMP BETWEEN DATE(TIMESTAMPADD(DAY, " + + this.retentionPeriod + " DAY))";
this.retentionPeriod + ", NOW())) AND NOW()";
stmt = this.createMemoryEfficientStatement(conn); stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql); rs = stmt.executeQuery(sql);
if (log.isDebugEnabled()) {
log.debug("Selected Operation Ids from Enrolment OP Mapping");
}
while (rs.next()) { while (rs.next()) {
operationIds.add(rs.getInt("OPERATION_ID")); operationIds.add(rs.getInt("ID"));
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("An error occurred while getting a list operation Ids to archive", e); String msg = "An error occurred while getting a list operation Ids to archive";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs); ArchivalDAOUtil.cleanupResources(stmt, rs);
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(operationIds.size() + " operations found for the archival"); log.debug(operationIds.size() + " operations found for the archival");
log.debug(operationIds.size() + "[" + operationIds.get(0) + "," + operationIds.get(batchSize - 1) + "]");
} }
return operationIds; return operationIds;
} }
@ -81,22 +86,41 @@ public class ArchivalDAOImpl implements ArchivalDAO {
ResultSet rs = null; ResultSet rs = null;
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT DISTINCT OPERATION_ID " + String sql = "(SELECT DISTINCT\n" +
" FROM DM_ENROLMENT_OP_MAPPING WHERE STATUS IN('PENDING', 'IN_PROGRESS') " + " OPERATION_ID\n" +
" AND CREATED_TIMESTAMP BETWEEN DATE(TIMESTAMPADD(DAY, " + this.retentionPeriod +", NOW())) " + " FROM\n" +
"AND NOW()"; " DM_ENROLMENT_OP_MAPPING\n" +
" WHERE\n" +
" STATUS = 'PENDING'\n" +
" AND CREATED_TIMESTAMP < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL "
+ this.retentionPeriod + " DAY))) \n" +
" UNION ALL \n" +
"\t(SELECT DISTINCT\n" +
" OPERATION_ID\n" +
" FROM\n" +
" DM_ENROLMENT_OP_MAPPING\n" +
" WHERE\n" +
" STATUS = 'IN_PROGRESS'\n" +
" AND CREATED_TIMESTAMP < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL " +
"" + this.retentionPeriod + " DAY)))";
stmt = this.createMemoryEfficientStatement(conn); stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql); rs = stmt.executeQuery(sql);
if (log.isDebugEnabled()) {
log.debug("Selected Pending or In Progress Operation IDs");
}
while (rs.next()) { while (rs.next()) {
operationIds.add(rs.getInt("OPERATION_ID")); operationIds.add(rs.getInt("OPERATION_ID"));
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("An error occurred while getting a list operation Ids to archive", e); String msg = "An error occurred while getting a list pending or in progress operation Ids to archive";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs); ArchivalDAOUtil.cleanupResources(stmt, rs);
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(operationIds.size() + " PENDING and IN_PROFRESS operations found for the archival"); log.debug(operationIds.size() + " operations found for the archival");
log.debug(operationIds.size() + "[" + operationIds.get(0) + "," + operationIds.get(batchSize - 1) + "]");
} }
return operationIds; return operationIds;
} }
@ -123,44 +147,88 @@ public class ArchivalDAOImpl implements ArchivalDAO {
log.debug(count + " Records copied to the temporary table."); log.debug(count + " Records copied to the temporary table.");
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error while copying operation Ids for archival", e); String msg = "Error while copying operation Ids for archival";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt); ArchivalDAOUtil.cleanupResources(stmt);
} }
} }
@Override @Override
public void moveOperationResponses() throws ArchivalDAOException { public List<ArchiveOperationResponse> selectOperationResponses() throws ArchivalDAOException {
Statement stmt = null; Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null; ResultSet rs = null;
List<ArchiveOperationResponse> operationResponses = new ArrayList<>();
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_DEVICE_OPERATION_RESPONSE WHERE OPERATION_ID IN " + String sql = "SELECT \n" +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " o.ID,\n" +
" o.ENROLMENT_ID,\n" +
" o.OPERATION_ID,\n" +
" o.EN_OP_MAP_ID,\n" +
" o.OPERATION_RESPONSE,\n" +
" o.RECEIVED_TIMESTAMP\n" +
"FROM\n" +
" DM_DEVICE_OPERATION_RESPONSE o\n" +
" INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID;";
stmt = this.createMemoryEfficientStatement(conn); stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql); rs = stmt.executeQuery(sql);
while (rs.next()) {
ArchiveOperationResponse rep = new ArchiveOperationResponse();
rep.setId(rs.getInt("ID"));
rep.setEnrolmentId(rs.getInt("ENROLMENT_ID"));
rep.setOperationId(rs.getInt("OPERATION_ID"));
rep.setOperationResponse(rs.getBytes("OPERATION_RESPONSE"));
rep.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP"));
operationResponses.add(rep);
}
if (log.isDebugEnabled()) {
log.debug("Selecting done for the Operation Response");
}
} catch (SQLException e) {
String msg = "Error occurred while archiving the operation responses";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
}
return operationResponses;
}
@Override
public void moveOperationResponses(List<ArchiveOperationResponse> archiveOperationResponse) throws ArchivalDAOException {
PreparedStatement stmt2 = null;
Statement stmt3 = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
Connection conn2 = ArchivalDestinationDAOFactory.getConnection(); Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_DEVICE_OPERATION_RESPONSE_ARCH VALUES(?, ?, ?, ?, ?,?,?)"; String sql = "INSERT INTO DM_DEVICE_OPERATION_RESPONSE_ARCH VALUES(?, ?, ?, ?, ?,?)";
stmt2 = conn2.prepareStatement(sql); stmt2 = conn2.prepareStatement(sql);
int count = 0; int count = 0;
while (rs.next()) { for (ArchiveOperationResponse rs : archiveOperationResponse) {
stmt2.setInt(1, rs.getInt("ID")); stmt2.setInt(1, rs.getId());
stmt2.setInt(2, rs.getInt("ENROLMENT_ID")); stmt2.setInt(2, rs.getEnrolmentId());
stmt2.setInt(3, rs.getInt("OPERATION_ID")); stmt2.setInt(3, rs.getOperationId());
stmt2.setInt(4, rs.getInt("EN_OP_MAP_ID")); stmt2.setBytes(4, (byte[]) rs.getOperationResponse());
stmt2.setBytes(5, rs.getBytes("OPERATION_RESPONSE")); stmt2.setTimestamp(5, rs.getReceivedTimeStamp());
stmt2.setTimestamp(6, rs.getTimestamp("RECEIVED_TIMESTAMP")); stmt2.setTimestamp(6, this.currentTimestamp);
stmt2.setTimestamp(7, this.currentTimestamp);
stmt2.addBatch(); stmt2.addBatch();
if (++count % batchSize == 0) { if (++count % batchSize == 0) {
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Executing batch " + count); log.debug("Executing Operation Responses batch " + count);
} }
} }
} }
@ -169,259 +237,382 @@ public class ArchivalDAOImpl implements ArchivalDAO {
log.debug(count + " [OPERATION_RESPONSES] Records copied to the archival table. Starting deletion"); log.debug(count + " [OPERATION_RESPONSES] Records copied to the archival table. Starting deletion");
} }
//try the deletion now //try the deletion now
sql = "DELETE FROM DM_DEVICE_OPERATION_RESPONSE WHERE OPERATION_ID IN (" + sql = "DELETE o.* FROM DM_DEVICE_OPERATION_RESPONSE o\n" +
" SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID \n" +
"WHERE\n" +
" o.OPERATION_ID = da.ID;";
stmt3 = conn.createStatement(); stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql); int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted"); log.debug(affected + " Rows deleted");
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving operations ", e); String msg = "Error occurred while archiving the operation responses";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2); ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3); ArchivalDAOUtil.cleanupResources(stmt3);
} }
} }
@Override @Override
public void moveNotifications() throws ArchivalDAOException { public List<ArchiveNotification> selectNotifications() throws ArchivalDAOException {
Statement stmt = null; Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null; ResultSet rs = null;
List<ArchiveNotification> notifications = new ArrayList<>();
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_NOTIFICATION WHERE OPERATION_ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; String sql = "SELECT \n" +
" o.NOTIFICATION_ID,\n" +
" o.DEVICE_ID,\n" +
" o.OPERATION_ID,\n" +
" o.TENANT_ID,\n" +
" o.STATUS,\n" +
" o.DESCRIPTION\n" +
"FROM\n" +
" DM_NOTIFICATION o\n" +
" INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID;";
stmt = this.createMemoryEfficientStatement(conn); stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql); rs = stmt.executeQuery(sql);
// ArchivalDestinationDAOFactory.beginTransaction(); while (rs.next()) {
ArchiveNotification note = new ArchiveNotification();
note.setNotificationId(rs.getInt("NOTIFICATION_ID"));
note.setDeviceId(rs.getInt("DEVICE_ID"));
note.setOperationId(rs.getInt("OPERATION_ID"));
note.setTenantId(rs.getInt("TENANT_ID"));
note.setStatus(rs.getString("STATUS"));
note.setDescription(rs.getString("DESCRIPTION"));
notifications.add(note);
}
if (log.isDebugEnabled()) {
log.debug("Selecting done for the Notification");
}
} catch (SQLException e) {
String msg = "Error occurred while archiving the notifications";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
}
return notifications;
}
@Override
public void moveNotifications(List<ArchiveNotification> archiveNotifications) throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
Connection conn2 = ArchivalDestinationDAOFactory.getConnection(); Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_NOTIFICATION_ARCH VALUES(?, ?, ?, ?, ?, ?, ?)"; String sql = "INSERT INTO DM_NOTIFICATION_ARCH VALUES(?, ?, ?, ?, ?, ?, ?)";
stmt2 = conn2.prepareStatement(sql); stmt2 = conn2.prepareStatement(sql);
int count = 0; int count = 0;
while (rs.next()) { // while (rs.next()) {
stmt2.setInt(1, rs.getInt("NOTIFICATION_ID")); for (ArchiveNotification rs : archiveNotifications) {
stmt2.setInt(2, rs.getInt("DEVICE_ID")); stmt2.setInt(1, rs.getNotificationId());
stmt2.setInt(3, rs.getInt("OPERATION_ID")); stmt2.setInt(2, rs.getDeviceId());
stmt2.setInt(4, rs.getInt("TENANT_ID")); stmt2.setInt(3, rs.getOperationId());
stmt2.setString(5, rs.getString("STATUS")); stmt2.setInt(4, rs.getTenantId());
stmt2.setString(6, rs.getString("DESCRIPTION")); stmt2.setString(5, rs.getStatus());
stmt2.setString(6, rs.getDescription());
stmt2.setTimestamp(7, this.currentTimestamp); stmt2.setTimestamp(7, this.currentTimestamp);
stmt2.addBatch(); stmt2.addBatch();
if (++count % batchSize == 0) { if (++count % batchSize == 0) {
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug("Executing Notifications batch " + count);
}
} }
} }
stmt2.executeBatch(); stmt2.executeBatch();
// ArchivalDestinationDAOFactory.commitTransaction();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(count + " [NOTIFICATIONS] Records copied to the archival table. Starting deletion"); log.debug(count + " [NOTIFICATIONS] Records copied to the archival table. Starting deletion");
} }
sql = "DELETE FROM DM_NOTIFICATION" + sql = "DELETE o.* FROM DM_NOTIFICATION o\n" +
" WHERE OPERATION_ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID \n" +
"WHERE\n" +
" o.OPERATION_ID = da.ID;";
stmt3 = conn.createStatement(); stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql); int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted"); log.debug(affected + " Rows deleted");
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving notifications ", e); String msg = "Error occurred while archiving the notifications";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2); ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3); ArchivalDAOUtil.cleanupResources(stmt3);
} }
} }
@Override @Override
public void moveCommandOperations() throws ArchivalDAOException { public List<ArchiveCommandOperation> selectCommandOperations() throws ArchivalDAOException {
Statement stmt = null; Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null; ResultSet rs = null;
List<ArchiveCommandOperation> commandOperations = new ArrayList<>();
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_COMMAND_OPERATION WHERE OPERATION_ID IN " + String sql = "SELECT \n" +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " *\n" +
"FROM\n" +
" DM_COMMAND_OPERATION o\n" +
" INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID;";
stmt = this.createMemoryEfficientStatement(conn); stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql); rs = stmt.executeQuery(sql);
while (rs.next()) {
ArchiveCommandOperation op = new ArchiveCommandOperation();
op.setOperationId(rs.getInt("OPERATION_ID"));
op.setEnabled(rs.getInt("ENABLED"));
commandOperations.add(op);
}
if (log.isDebugEnabled()) {
log.debug("Selecting done for the Command Operation");
}
} catch (SQLException e) {
String msg = "Error occurred while archiving the command operation";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
}
return commandOperations;
}
@Override
public void moveCommandOperations(List<ArchiveCommandOperation> commandOperations) throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
Connection conn2 = ArchivalDestinationDAOFactory.getConnection(); Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_COMMAND_OPERATION_ARCH VALUES(?,?,?)"; String sql = "INSERT INTO DM_COMMAND_OPERATION_ARCH VALUES(?,?,?)";
stmt2 = conn2.prepareStatement(sql); stmt2 = conn2.prepareStatement(sql);
int count = 0; int count = 0;
while (rs.next()) { for (ArchiveCommandOperation rs : commandOperations) {
stmt2.setInt(1, rs.getInt("OPERATION_ID")); stmt2.setInt(1, rs.getOperationId());
stmt2.setInt(2, rs.getInt("ENABLED")); stmt2.setInt(2, rs.getEnabled());
stmt2.setTimestamp(3, this.currentTimestamp); stmt2.setTimestamp(3, this.currentTimestamp);
stmt2.addBatch(); stmt2.addBatch();
if (++count % batchSize == 0) { if (++count % batchSize == 0) {
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug("Executing Command Operations batch " + count);
}
} }
} }
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(count + " [COMMAND_OPERATION] Records copied to the archival table. Starting deletion"); log.debug(count + " [COMMAND_OPERATION] Records copied to the archival table. Starting deletion");
} }
sql = "DELETE FROM DM_COMMAND_OPERATION" + sql = "DELETE o.* FROM DM_COMMAND_OPERATION o\n" +
" WHERE OPERATION_ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID \n" +
"WHERE\n" +
" o.OPERATION_ID = da.ID;";
stmt3 = conn.createStatement(); stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql); int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted"); log.debug(affected + " Rows deleted");
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving command operations", e); String msg = "Error occurred while archiving the command operation";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2); ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3); ArchivalDAOUtil.cleanupResources(stmt3);
} }
} }
@Override @Override
public void moveProfileOperations() throws ArchivalDAOException { public List<ArchiveProfileOperation> selectProfileOperations() throws ArchivalDAOException {
Statement stmt = null; Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null; ResultSet rs = null;
List<ArchiveProfileOperation> profileOperations = new ArrayList<>();
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_PROFILE_OPERATION WHERE OPERATION_ID IN " + String sql = "SELECT \n" +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " *\n" +
"FROM\n" +
" DM_PROFILE_OPERATION o\n" +
" INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID;";
stmt = this.createMemoryEfficientStatement(conn); stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql); 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()) { while (rs.next()) {
stmt2.setInt(1, rs.getInt("OPERATION_ID")); ArchiveProfileOperation op = new ArchiveProfileOperation();
stmt2.setInt(2, rs.getInt("ENABLED"));
stmt2.setBytes(3, rs.getBytes("OPERATION_DETAILS")); op.setOperationId(rs.getInt("OPERATION_ID"));
stmt2.setTimestamp(4,this.currentTimestamp ); op.setEnabled(rs.getInt("ENABLED"));
stmt2.addBatch(); op.setOperationDetails(rs.getBytes("OPERATION_DETAILS"));
profileOperations.add(op);
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()) { if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted"); log.debug("Selecting done for the Profile Operation");
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving profile operations", e); String msg = "Error occurred while archiving the profile operation";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs); ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3);
} }
return profileOperations;
} }
@Override @Override
public void moveConfigOperations() throws ArchivalDAOException { public void moveProfileOperations(List<ArchiveProfileOperation> profileOperations) throws ArchivalDAOException {
Statement stmt = null; Statement stmt = null;
PreparedStatement stmt2 = null; PreparedStatement stmt2 = null;
Statement stmt3 = null; Statement stmt3 = null;
ResultSet rs = null;
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_CONFIG_OPERATION WHERE OPERATION_ID IN " +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)";
stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql);
Connection conn2 = ArchivalDestinationDAOFactory.getConnection(); Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_CONFIG_OPERATION_ARCH VALUES(?, ?, ?, ?)"; String sql = "INSERT INTO DM_PROFILE_OPERATION_ARCH VALUES(?, ?, ?, ?)";
stmt2 = conn2.prepareStatement(sql); stmt2 = conn2.prepareStatement(sql);
int count = 0; int count = 0;
while (rs.next()) { for (ArchiveProfileOperation rs : profileOperations) {
stmt2.setInt(1, rs.getInt("OPERATION_ID")); stmt2.setInt(1, rs.getOperationId());
stmt2.setBytes(2, rs.getBytes("OPERATION_CONFIG")); stmt2.setInt(2, rs.getEnabled());
stmt2.setInt(3, rs.getInt("ENABLED")); stmt2.setBytes(3, (byte[]) rs.getOperationDetails());
stmt2.setTimestamp(4,this.currentTimestamp ); stmt2.setTimestamp(4, this.currentTimestamp);
stmt2.addBatch(); stmt2.addBatch();
if (++count % batchSize == 0) { if (++count % batchSize == 0) {
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug("Executing Profile Operations batch " + count);
}
} }
} }
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(count + " [CONFIG_OPERATION] Records copied to the archival table. Starting deletion"); log.debug(count + " [PROFILE_OPERATION] Records copied to the archival table. Starting deletion");
} }
sql = "DELETE FROM DM_CONFIG_OPERATION" + sql = "DELETE o.* FROM DM_PROFILE_OPERATION o\n" +
" WHERE OPERATION_ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID \n" +
"WHERE\n" +
" o.OPERATION_ID = da.ID;";
stmt3 = conn.createStatement(); stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql); int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted"); log.debug(affected + " Rows deleted");
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving config operations", e); String msg = "Error occurred while archiving the profile operation";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2); ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3); ArchivalDAOUtil.cleanupResources(stmt3);
} }
} }
@Override @Override
public void moveEnrolmentMappings() throws ArchivalDAOException { public List<ArchiveEnrolmentOperationMap> selectEnrolmentMappings() throws ArchivalDAOException {
Statement stmt = null; Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null; ResultSet rs = null;
List<ArchiveEnrolmentOperationMap> operationMaps = new ArrayList<>();
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_ENROLMENT_OP_MAPPING WHERE OPERATION_ID IN " + String sql = "SELECT \n" +
"(SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " o.ID,\n" +
" o.ENROLMENT_ID,\n" +
" o.OPERATION_ID,\n" +
" o.STATUS,\n" +
" o.CREATED_TIMESTAMP,\n" +
" o.UPDATED_TIMESTAMP\n" +
"FROM\n" +
" DM_ENROLMENT_OP_MAPPING o\n" +
" INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID;";
stmt = this.createMemoryEfficientStatement(conn); stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql); rs = stmt.executeQuery(sql);
while (rs.next()) {
ArchiveEnrolmentOperationMap eom = new ArchiveEnrolmentOperationMap();
eom.setId(rs.getInt("ID"));
eom.setEnrolmentId(rs.getInt("ENROLMENT_ID"));
eom.setOperationId(rs.getInt("OPERATION_ID"));
eom.setStatus(rs.getString("STATUS"));
eom.setCreatedTimestamp(rs.getInt("CREATED_TIMESTAMP"));
eom.setUpdatedTimestamp(rs.getInt("UPDATED_TIMESTAMP"));
operationMaps.add(eom);
}
if (log.isDebugEnabled()) {
log.debug("Selecting done for the Enrolment OP Mapping");
}
} catch (SQLException e) {
String msg = "Error occurred while archiving the enrolment op mappings";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
}
return operationMaps;
}
@Override
public void moveEnrolmentMappings(List<ArchiveEnrolmentOperationMap> operationMaps) throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
Connection conn2 = ArchivalDestinationDAOFactory.getConnection(); Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_ENROLMENT_OP_MAPPING_ARCH VALUES(?, ?, ?, ?, ?, ?, ?,?)"; String sql = "INSERT INTO DM_ENROLMENT_OP_MAPPING_ARCH VALUES(?, ?, ?, ?, ?, ?, ?)";
stmt2 = conn2.prepareStatement(sql); stmt2 = conn2.prepareStatement(sql);
int count = 0; int count = 0;
while (rs.next()) { for (ArchiveEnrolmentOperationMap rs : operationMaps) {
stmt2.setInt(1, rs.getInt("ID")); stmt2.setInt(1, rs.getId());
stmt2.setInt(2, rs.getInt("ENROLMENT_ID")); stmt2.setInt(2, rs.getEnrolmentId());
stmt2.setInt(3, rs.getInt("OPERATION_ID")); stmt2.setInt(3, rs.getOperationId());
stmt2.setString(4, rs.getString("STATUS")); stmt2.setString(4, rs.getStatus());
stmt2.setString(5, rs.getString("PUSH_NOTIFICATION_STATUS")); stmt2.setInt(5, rs.getCreatedTimestamp());
stmt2.setInt(6, rs.getInt("CREATED_TIMESTAMP")); stmt2.setInt(6, rs.getUpdatedTimestamp());
stmt2.setInt(7, rs.getInt("UPDATED_TIMESTAMP")); stmt2.setTimestamp(7, this.currentTimestamp);
stmt2.setTimestamp(8, this.currentTimestamp);
stmt2.addBatch(); stmt2.addBatch();
if (++count % batchSize == 0) { if (++count % batchSize == 0) {
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Executing batch " + count); log.debug("Executing Enrolment Mappings batch " + count);
} }
} }
} }
@ -429,67 +620,119 @@ public class ArchivalDAOImpl implements ArchivalDAO {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(count + " [ENROLMENT_OP_MAPPING] Records copied to the archival table. Starting deletion"); 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 (" + sql = "DELETE o.* FROM DM_ENROLMENT_OP_MAPPING o\n" +
"SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.OPERATION_ID = da.ID \n" +
"WHERE\n" +
" o.OPERATION_ID = da.ID;";
stmt3 = conn.createStatement(); stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql); int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted"); log.debug(affected + " Rows deleted");
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving enrolment mappings", e); String msg = "Error occurred while archiving the enrolment op mappings";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2); ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3); ArchivalDAOUtil.cleanupResources(stmt3);
} }
} }
@Override @Override
public void moveOperations() throws ArchivalDAOException { public List<ArchiveOperation> selectOperations() throws ArchivalDAOException {
Statement stmt = null; Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
ResultSet rs = null; ResultSet rs = null;
List<ArchiveOperation> operations = new ArrayList<>();
try { try {
Connection conn = ArchivalSourceDAOFactory.getConnection(); Connection conn = ArchivalSourceDAOFactory.getConnection();
String sql = "SELECT * FROM DM_OPERATION WHERE ID IN (SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; String sql = "SELECT \n" +
" o.ID,\n" +
" o.TYPE,\n" +
" o.CREATED_TIMESTAMP,\n" +
" o.RECEIVED_TIMESTAMP,\n" +
" o.OPERATION_CODE\n" +
"FROM\n" +
" DM_OPERATION o\n" +
" INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.ID = da.ID;";
stmt = this.createMemoryEfficientStatement(conn); stmt = this.createMemoryEfficientStatement(conn);
rs = stmt.executeQuery(sql); rs = stmt.executeQuery(sql);
while (rs.next()) {
ArchiveOperation op = new ArchiveOperation();
op.setId(rs.getInt("ID"));
op.setType(rs.getString("TYPE"));
op.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP"));
op.setRecievedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP"));
op.setOperationCode(rs.getString("OPERATION_CODE"));
operations.add(op);
}
if (log.isDebugEnabled()) {
log.debug("Selecting done for the Operation");
}
} catch (SQLException e) {
String msg = "Error occurred while archiving the operations";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
}
return operations;
}
@Override
public void moveOperations(List<ArchiveOperation> operations) throws ArchivalDAOException {
Statement stmt = null;
PreparedStatement stmt2 = null;
Statement stmt3 = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
Connection conn2 = ArchivalDestinationDAOFactory.getConnection(); Connection conn2 = ArchivalDestinationDAOFactory.getConnection();
sql = "INSERT INTO DM_OPERATION_ARCH VALUES(?, ?, ?, ?, ?, ?)"; String sql = "INSERT INTO DM_OPERATION_ARCH VALUES(?, ?, ?, ?, ?, ?)";
stmt2 = conn2.prepareStatement(sql); stmt2 = conn2.prepareStatement(sql);
int count = 0; int count = 0;
while (rs.next()) { for (ArchiveOperation rs : operations) {
stmt2.setInt(1, rs.getInt("ID")); stmt2.setInt(1, rs.getId());
stmt2.setString(2, rs.getString("TYPE")); stmt2.setString(2, rs.getType());
stmt2.setTimestamp(3, rs.getTimestamp("CREATED_TIMESTAMP")); stmt2.setTimestamp(3, rs.getCreatedTimeStamp());
stmt2.setTimestamp(4, rs.getTimestamp("RECEIVED_TIMESTAMP")); stmt2.setTimestamp(4, rs.getRecievedTimeStamp());
stmt2.setString(5, rs.getString("OPERATION_CODE")); stmt2.setString(5, rs.getOperationCode());
stmt2.setTimestamp(6, this.currentTimestamp); stmt2.setTimestamp(6, this.currentTimestamp);
stmt2.addBatch(); stmt2.addBatch();
if (++count % batchSize == 0) { if (++count % batchSize == 0) {
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) {
log.debug("Final Execution of Operations batch " + count);
}
} }
} }
stmt2.executeBatch(); stmt2.executeBatch();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(count + " [OPERATIONS] Records copied to the archival table. Starting deletion"); log.debug(count + " [OPERATIONS] Records copied to the archival table. Starting deletion");
} }
sql = "DELETE FROM DM_OPERATION WHERE ID IN (" + sql = "DELETE o.* FROM DM_OPERATION o\n" +
"SELECT ID FROM DM_ARCHIVED_OPERATIONS)"; " INNER JOIN\n" +
" DM_ARCHIVED_OPERATIONS da ON o.ID = da.ID \n" +
"WHERE\n" +
" o.ID = da.ID;";
stmt3 = conn.createStatement(); stmt3 = conn.createStatement();
int affected = stmt3.executeUpdate(sql); int affected = stmt3.executeUpdate(sql);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(affected + " Rows deleted"); log.debug(affected + " Rows deleted");
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while moving operations", e); String msg = "Error occurred while archiving the operations";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt, rs);
ArchivalDAOUtil.cleanupResources(stmt2); ArchivalDAOUtil.cleanupResources(stmt2);
ArchivalDAOUtil.cleanupResources(stmt3); ArchivalDAOUtil.cleanupResources(stmt3);
} }
@ -503,11 +746,13 @@ public class ArchivalDAOImpl implements ArchivalDAO {
conn.setAutoCommit(false); conn.setAutoCommit(false);
String sql = "TRUNCATE DM_ARCHIVED_OPERATIONS"; String sql = "TRUNCATE DM_ARCHIVED_OPERATIONS";
stmt = conn.prepareStatement(sql); stmt = conn.prepareStatement(sql);
stmt.addBatch(); stmt.executeUpdate();
stmt.executeBatch();
conn.commit(); conn.commit();
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while truncating operation Ids", e); String msg = "Error occurred while truncating operation Ids";
log.error(msg, e);
throw new ArchivalDAOException(msg, e);
} finally { } finally {
ArchivalDAOUtil.cleanupResources(stmt); ArchivalDAOUtil.cleanupResources(stmt);
} }
@ -519,4 +764,59 @@ public class ArchivalDAOImpl implements ArchivalDAO {
return stmt; return stmt;
} }
} private String buildWhereClause(String[] statuses) {
StringBuilder whereClause = new StringBuilder("WHERE ");
for (int i = 0; i < statuses.length; i++) {
whereClause.append("STATUS ='");
whereClause.append(statuses[i]);
whereClause.append("' ");
if (i != (statuses.length - 1))
whereClause.append(" OR ");
}
return whereClause.toString();
}
private void copyOperationIDsForArchival() throws ArchivalDAOException {
PreparedStatement stmt = null;
Statement createStmt = null;
try {
Connection conn = ArchivalSourceDAOFactory.getConnection();
// conn.setAutoCommit(false);
// String sql = "INSERT INTO DM_ARCHIVED_OPERATIONS(ID,CREATED_TIMESTAMP)" +
// " SELECT DISTINCT op.ID as OPERATION_ID, NOW()" +
// " FROM DM_ENROLMENT_OP_MAPPING AS opm" +
// " LEFT JOIN DM_OPERATION AS op ON opm.OPERATION_ID = op.ID" +
// " WHERE opm.STATUS='ERROR' OR opm.STATUS='COMPLETED'" +
// " AND op.RECEIVED_TIMESTAMP < DATE_SUB(NOW(), INTERVAL ? DAY);";
// stmt = conn.prepareStatement(sql);
// stmt.setInt(1, this.retentionPeriod);
// stmt.addBatch();
// stmt.executeBatch();
// conn.commit();
//Create the temporary table first
// String sql = "CREATE TEMPORARY TABLE DM_ARCHIVED_OPERATIONS (ID INTEGER NOT NULL," +
// " CREATED_TIMESTAMP TIMESTAMP NOT NULL, PRIMARY KEY (ID))" ;
// createStmt = conn.createStatement();
// createStmt.execute(sql);
// if(log.isDebugEnabled()) {
// log.debug("Temporary table DM_ARCHIVED_OPERATIONS has been created ");
// }
//Copy eligible operations into DM_ARCHIVED_OPERATIONS
String sql = "INSERT INTO DM_ARCHIVED_OPERATIONS(ID,CREATED_TIMESTAMP)" +
" SELECT DISTINCT OPERATION_ID, NOW()" +
" FROM DM_ENROLMENT_OP_MAPPING" +
" WHERE STATUS='ERROR' OR STATUS='COMPLETED' OR STATUS='REPEATED'" +
" AND CREATED_TIMESTAMP < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod);
int affected = stmt.executeUpdate();
log.info(affected + " Eligible operations found for archival");
} catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while copying operation Ids for archival", e);
} finally {
ArchivalDAOUtil.cleanupResources(stmt);
ArchivalDAOUtil.cleanupResources(createStmt);
}
}
}

@ -21,10 +21,11 @@ package org.wso2.carbon.device.mgt.core.archival.dao.impl;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.core.archival.dao.DataDeletionDAO;
import org.wso2.carbon.device.mgt.core.archival.dao.ArchivalDAOException; 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.ArchivalDAOUtil;
import org.wso2.carbon.device.mgt.core.archival.dao.ArchivalDestinationDAOFactory; import org.wso2.carbon.device.mgt.core.archival.dao.ArchivalDestinationDAOFactory;
import org.wso2.carbon.device.mgt.core.archival.dao.DataDeletionDAO; import org.wso2.carbon.device.mgt.core.task.impl.ArchivedDataDeletionTask;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -52,8 +53,7 @@ public class DataDeletionDAOImpl implements DataDeletionDAO {
"WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)"; "WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql); stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod); stmt.setInt(1, this.retentionPeriod);
stmt.addBatch(); stmt.executeUpdate();
stmt.executeBatch();
conn.commit(); conn.commit();
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting operation responses", e); throw new ArchivalDAOException("Error occurred while deleting operation responses", e);
@ -72,8 +72,7 @@ public class DataDeletionDAOImpl implements DataDeletionDAO {
" WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)"; " WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql); stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod); stmt.setInt(1, this.retentionPeriod);
stmt.addBatch(); stmt.executeUpdate();
stmt.executeBatch();
conn.commit(); conn.commit();
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting notifications", e); throw new ArchivalDAOException("Error occurred while deleting notifications", e);
@ -92,8 +91,7 @@ public class DataDeletionDAOImpl implements DataDeletionDAO {
" WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)"; " WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql); stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod); stmt.setInt(1, this.retentionPeriod);
stmt.addBatch(); stmt.executeUpdate();
stmt.executeBatch();
conn.commit(); conn.commit();
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting command operations", e); throw new ArchivalDAOException("Error occurred while deleting command operations", e);
@ -112,8 +110,7 @@ public class DataDeletionDAOImpl implements DataDeletionDAO {
" WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)"; " WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql); stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod); stmt.setInt(1, this.retentionPeriod);
stmt.addBatch(); stmt.executeUpdate();
stmt.executeBatch();
conn.commit(); conn.commit();
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting profile operations", e); throw new ArchivalDAOException("Error occurred while deleting profile operations", e);
@ -131,8 +128,7 @@ public class DataDeletionDAOImpl implements DataDeletionDAO {
String sql = "DELETE FROM DM_ENROLMENT_OP_MAPPING_ARCH WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)"; String sql = "DELETE FROM DM_ENROLMENT_OP_MAPPING_ARCH WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql); stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod); stmt.setInt(1, this.retentionPeriod);
stmt.addBatch(); stmt.executeUpdate();
stmt.executeBatch();
conn.commit(); conn.commit();
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting enrolment mappings", e); throw new ArchivalDAOException("Error occurred while deleting enrolment mappings", e);
@ -150,8 +146,7 @@ public class DataDeletionDAOImpl implements DataDeletionDAO {
String sql = "DELETE FROM DM_OPERATION_ARCH WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)"; String sql = "DELETE FROM DM_OPERATION_ARCH WHERE ARCHIVED_AT < DATE_SUB(NOW(), INTERVAL ? DAY)";
stmt = conn.prepareStatement(sql); stmt = conn.prepareStatement(sql);
stmt.setInt(1, this.retentionPeriod); stmt.setInt(1, this.retentionPeriod);
stmt.addBatch(); stmt.executeUpdate();
stmt.executeBatch();
conn.commit(); conn.commit();
} catch (SQLException e) { } catch (SQLException e) {
throw new ArchivalDAOException("Error occurred while deleting operations", e); throw new ArchivalDAOException("Error occurred while deleting operations", e);

@ -29,7 +29,7 @@ public class ArchivalTaskConfiguration {
private int retentionPeriod; private int retentionPeriod;
private int batchSize; private int batchSize;
private PurgingTaskConfiguration purgingTaskConfiguration; private PurgingTaskConfiguration purgingTaskConfiguration;
private final int MULTIPLIER = -1; private boolean archivePendingOperations;
@XmlElement(name = "Enabled", required = true) @XmlElement(name = "Enabled", required = true)
public boolean isEnabled() { public boolean isEnabled() {
@ -60,8 +60,7 @@ public class ArchivalTaskConfiguration {
@XmlElement(name = "RetentionPeriod", required = true) @XmlElement(name = "RetentionPeriod", required = true)
public int getRetentionPeriod() { public int getRetentionPeriod() {
// multiply by -1 to get the diff return retentionPeriod;
return retentionPeriod * MULTIPLIER;
} }
public void setRetentionPeriod(int retentionPeriod) { public void setRetentionPeriod(int retentionPeriod) {
@ -85,4 +84,13 @@ public class ArchivalTaskConfiguration {
public void setBatchSize(int batchSize) { public void setBatchSize(int batchSize) {
this.batchSize = batchSize; this.batchSize = batchSize;
} }
@XmlElement(name ="ArchivePendingOperations")
public boolean isArchivePendingOperations() {
return archivePendingOperations;
}
public void setArchivePendingOperations(boolean archivePendingOperations) {
this.archivePendingOperations = archivePendingOperations;
}
} }

@ -198,9 +198,8 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager {
deviceDAO.updateDevice(device, CarbonContext.getThreadLocalCarbonContext().getTenantId()); deviceDAO.updateDevice(device, CarbonContext.getThreadLocalCarbonContext().getTenantId());
deviceDetailsDAO.deleteDeviceLocation(deviceLocation.getDeviceId(), device.getEnrolmentInfo().getId()); deviceDetailsDAO.deleteDeviceLocation(deviceLocation.getDeviceId(), device.getEnrolmentInfo().getId());
deviceDetailsDAO.addDeviceLocation(deviceLocation, device.getEnrolmentInfo().getId()); deviceDetailsDAO.addDeviceLocation(deviceLocation, device.getEnrolmentInfo().getId());
//TODO: This has to be fixed with enrollment id or username should include in the stream def.
if (DeviceManagerUtil.isPublishLocationResponseEnabled()) { if (DeviceManagerUtil.isPublishLocationResponseEnabled()) {
Object[] metaData = {device.getDeviceIdentifier(), device.getType()}; Object[] metaData = {device.getDeviceIdentifier(), device.getEnrolmentInfo().getOwner(), device.getType()};
Object[] payload = new Object[]{ Object[] payload = new Object[]{
deviceLocation.getUpdatedTime().getTime(), deviceLocation.getUpdatedTime().getTime(),
deviceLocation.getLatitude(), deviceLocation.getLatitude(),

@ -55,7 +55,6 @@ import org.wso2.carbon.registry.api.Resource;
import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
import javax.persistence.EntityExistsException;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -114,16 +113,16 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
private static final String SSLV3 = "SSLv3"; private static final String SSLV3 = "SSLv3";
@Override @Override
public List<GeoFence> getWithinAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException { public List<GeoFence> getWithinAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException {
Registry registry = getGovernanceRegistry(); Registry registry = getGovernanceRegistry();
String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS + String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_WITHIN + "/" + identifier.getId() + "/"; GeoServices.ALERT_TYPE_WITHIN + "/" + owner + "/" + identifier.getId() + "/";
Resource resource; Resource resource;
try { try {
resource = registry.get(registryPath); resource = registry.get(registryPath);
} catch (RegistryException e) { } catch (RegistryException e) {
log.error("Error while reading the registry path: " + registryPath); log.error("Error while reading the registry path: " + registryPath + ". Error: " + e.getMessage());
return null; return null;
} }
@ -171,7 +170,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
try { try {
resource = registry.get(registryPath); resource = registry.get(registryPath);
} catch (RegistryException e) { } catch (RegistryException e) {
log.error("Error while reading the registry path: " + registryPath); log.error("Error while reading the registry path: " + registryPath + ". Error: " + e.getMessage());
return Collections.emptyList(); return Collections.emptyList();
} }
@ -209,16 +208,16 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
@Override @Override
public List<GeoFence> getExitAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException { public List<GeoFence> getExitAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException {
Registry registry = getGovernanceRegistry(); Registry registry = getGovernanceRegistry();
String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS + String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_EXIT + "/" + identifier.getId() + "/"; GeoServices.ALERT_TYPE_EXIT + "/" + owner + "/" + identifier.getId() + "/";
Resource resource; Resource resource;
try { try {
resource = registry.get(registryPath); resource = registry.get(registryPath);
} catch (RegistryException e) { } catch (RegistryException e) {
log.error("Error while reading the registry path: " + registryPath); log.error("Error while reading the registry path: " + registryPath + ". Error: " + e.getMessage());
return null; return null;
} }
@ -266,7 +265,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
try { try {
resource = registry.get(registryPath); resource = registry.get(registryPath);
} catch (RegistryException e) { } catch (RegistryException e) {
log.error("Error while reading the registry path: " + registryPath); log.error("Error while reading the registry path: " + registryPath + ". Error: " + e.getMessage());
return Collections.emptyList(); return Collections.emptyList();
} }
@ -304,9 +303,9 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
@Override @Override
public boolean createGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType) public boolean createGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType, String owner)
throws GeoLocationBasedServiceException, AlertAlreadyExistException { throws GeoLocationBasedServiceException, AlertAlreadyExistException {
return saveGeoAlert(alert, identifier, alertType, false); return saveGeoAlert(alert, identifier, alertType, false, owner);
} }
@Override @Override
@ -316,9 +315,9 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
@Override @Override
public boolean updateGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType) public boolean updateGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType, String owner)
throws GeoLocationBasedServiceException, AlertAlreadyExistException { throws GeoLocationBasedServiceException, AlertAlreadyExistException {
return saveGeoAlert(alert, identifier, alertType, true); return saveGeoAlert(alert, identifier, alertType, true, owner);
} }
@Override @Override
@ -327,7 +326,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
return saveGeoAlert(alert, alertType, true); return saveGeoAlert(alert, alertType, true);
} }
public boolean saveGeoAlert(Alert alert, String alertType, boolean isUpdate) private boolean saveGeoAlert(Alert alert, String alertType, boolean isUpdate)
throws GeoLocationBasedServiceException,AlertAlreadyExistException { throws GeoLocationBasedServiceException,AlertAlreadyExistException {
Type type = new TypeToken<Map<String, String>>() { Type type = new TypeToken<Map<String, String>>() {
@ -377,6 +376,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
ExecutionPlanConfigurationDto[] allActiveExecutionPlanConfigs = null; ExecutionPlanConfigurationDto[] allActiveExecutionPlanConfigs = null;
String activeExecutionPlan = null; String activeExecutionPlan = null;
String executionPlanName = getExecutionPlanName(alertType, alert.getQueryName()); String executionPlanName = getExecutionPlanName(alertType, alert.getQueryName());
parseMap.put(GeoServices.EXECUTION_PLAN_NAME, executionPlanName);
eventprocessorStub = getEventProcessorAdminServiceStub(); eventprocessorStub = getEventProcessorAdminServiceStub();
String parsedTemplate = parseTemplateForGeoClusters(alertType, parseMap); String parsedTemplate = parseTemplateForGeoClusters(alertType, parseMap);
String validationResponse = eventprocessorStub.validateExecutionPlan(parsedTemplate); String validationResponse = eventprocessorStub.validateExecutionPlan(parsedTemplate);
@ -434,7 +434,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
public boolean saveGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType, boolean isUpdate) private boolean saveGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType, boolean isUpdate, String owner)
throws GeoLocationBasedServiceException, AlertAlreadyExistException { throws GeoLocationBasedServiceException, AlertAlreadyExistException {
Type type = new TypeToken<Map<String, String>>() { Type type = new TypeToken<Map<String, String>>() {
@ -483,8 +483,9 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
try { try {
ExecutionPlanConfigurationDto[] allActiveExecutionPlanConfigs = null; ExecutionPlanConfigurationDto[] allActiveExecutionPlanConfigs = null;
String activeExecutionPlan = null; String activeExecutionPlan = null;
String executionPlanName = getExecutionPlanName(alertType, alert.getQueryName(), String executionPlanName = getExecutionPlanName(alertType, alert.getQueryName(), identifier.getId(), owner);
identifier.getId()); parseMap.put(GeoServices.EXECUTION_PLAN_NAME, executionPlanName);
parseMap.put(GeoServices.DEVICE_OWNER, owner);
eventprocessorStub = getEventProcessorAdminServiceStub(); eventprocessorStub = getEventProcessorAdminServiceStub();
String parsedTemplate = parseTemplate(alertType, parseMap); String parsedTemplate = parseTemplate(alertType, parseMap);
String validationResponse = eventprocessorStub.validateExecutionPlan(parsedTemplate); String validationResponse = eventprocessorStub.validateExecutionPlan(parsedTemplate);
@ -507,7 +508,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
+ executionPlanName); + executionPlanName);
} }
} }
updateRegistry(getRegistryPath(alertType, identifier, alert.getQueryName()), identifier, content, updateRegistry(getRegistryPath(alertType, identifier, alert.getQueryName(), owner), identifier, content,
options); options);
eventprocessorStub.deployExecutionPlan(parsedTemplate); eventprocessorStub.deployExecutionPlan(parsedTemplate);
} }
@ -545,27 +546,27 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
} }
private String getRegistryPath(String alertType, DeviceIdentifier identifier, String queryName) private String getRegistryPath(String alertType, DeviceIdentifier identifier, String queryName, String owner)
throws GeoLocationBasedServiceException { throws GeoLocationBasedServiceException {
String path = ""; String path = "";
if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) { if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_WITHIN + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_WITHIN +
"/" + identifier.getId() + "/" + queryName; "/" + owner + "/" + identifier.getId() + "/" + queryName;
} else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_EXIT + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_EXIT +
"/" + identifier.getId() + "/" + queryName; "/" + owner + "/" + identifier.getId() + "/" + queryName;
} else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_SPEED + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_SPEED +
"/" + identifier.getId(); "/" + owner + "/" + identifier.getId();
} else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_PROXIMITY + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_PROXIMITY +
"/" + identifier.getId() + "/" + queryName; "/" + owner + "/" + identifier.getId() + "/" + queryName;
} else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_STATIONARY + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_STATIONARY +
"/" + identifier.getId() + "/" + queryName; "/" + owner + "/" + identifier.getId() + "/" + queryName;
} else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) { } else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_TRAFFIC + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_TRAFFIC +
"/" + identifier.getId() + "/" + queryName; "/" + owner + "/" + identifier.getId() + "/" + queryName;
} else { } else {
throw new GeoLocationBasedServiceException( throw new GeoLocationBasedServiceException(
"Unrecognized execution plan type: " + alertType); "Unrecognized execution plan type: " + alertType);
@ -601,11 +602,13 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
return path; return path;
} }
private String getExecutionPlanName(String alertType, String queryName, String deviceId) { private String getExecutionPlanName(String alertType, String queryName, String deviceId, String owner) {
if ("Traffic".equals(alertType)) { if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) {
return "Geo-ExecutionPlan-Traffic_" + queryName + "_alert"; return "Geo-ExecutionPlan-Traffic_" + queryName + "_alert";
} else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) {
return "Geo-ExecutionPlan-" + alertType + "---_" + owner + "_" + deviceId + "_alert";
} else { } else {
return "Geo-ExecutionPlan-" + alertType + "_" + queryName + "---_" + deviceId + "_alert"; return "Geo-ExecutionPlan-" + alertType + "_" + queryName + "---_" + owner + "_" + deviceId + "_alert";
} }
} }
@ -621,10 +624,10 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
@Override @Override
public boolean removeGeoAlert(String alertType, DeviceIdentifier identifier, String queryName) public boolean removeGeoAlert(String alertType, DeviceIdentifier identifier, String queryName, String owner)
throws GeoLocationBasedServiceException { throws GeoLocationBasedServiceException {
removeFromRegistry(alertType, identifier, queryName); removeFromRegistry(alertType, identifier, queryName, owner);
String executionPlanName = getExecutionPlanName(alertType, queryName, identifier.getId()); String executionPlanName = getExecutionPlanName(alertType, queryName, identifier.getId(), owner);
EventProcessorAdminServiceStub eventprocessorStub = null; EventProcessorAdminServiceStub eventprocessorStub = null;
try { try {
eventprocessorStub = getEventProcessorAdminServiceStub(); eventprocessorStub = getEventProcessorAdminServiceStub();
@ -674,11 +677,11 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
} }
private void removeFromRegistry(String alertType, DeviceIdentifier identifier, String queryName) private void removeFromRegistry(String alertType, DeviceIdentifier identifier, String queryName, String owner)
throws GeoLocationBasedServiceException { throws GeoLocationBasedServiceException {
String path = "unknown"; String path = "unknown";
try { try {
path = getRegistryPath(alertType, identifier, queryName); path = getRegistryPath(alertType, identifier, queryName, owner);
getGovernanceRegistry().delete(path); getGovernanceRegistry().delete(path);
} catch (RegistryException e) { } catch (RegistryException e) {
throw new GeoLocationBasedServiceException( throw new GeoLocationBasedServiceException(
@ -746,11 +749,11 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
@Override @Override
public String getSpeedAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException { public String getSpeedAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException {
try { try {
Registry registry = getGovernanceRegistry(); Registry registry = getGovernanceRegistry();
Resource resource = registry.get(GeoServices.REGISTRY_PATH_FOR_ALERTS + Resource resource = registry.get(GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_SPEED + "/" + identifier.getId()); GeoServices.ALERT_TYPE_SPEED + "/" + owner + "/" + identifier.getId());
if (resource == null) { if (resource == null) {
return "{'content': false}"; return "{'content': false}";
} }
@ -782,12 +785,11 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
@Override @Override
public String getProximityAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException { public String getProximityAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException {
try { try {
Registry registry = getGovernanceRegistry(); Registry registry = getGovernanceRegistry();
Resource resource = registry.get(GeoServices.REGISTRY_PATH_FOR_ALERTS + Resource resource = registry.get(GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_PROXIMITY +
GeoServices.ALERT_TYPE_PROXIMITY "/" + owner + "/" + identifier.getId());
+ "/" + identifier.getId());
if (resource != null) { if (resource != null) {
Properties props = resource.getProperties(); Properties props = resource.getProperties();
@ -830,11 +832,11 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
@Override @Override
public List<GeoFence> getStationaryAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException { public List<GeoFence> getStationaryAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException {
Registry registry = getGovernanceRegistry(); Registry registry = getGovernanceRegistry();
String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS + String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_STATIONARY + "/" + identifier.getId() + "/"; GeoServices.ALERT_TYPE_STATIONARY + "/" + owner + "/" + identifier.getId() + "/";
Resource resource; Resource resource;
try { try {
resource = registry.get(registryPath); resource = registry.get(registryPath);
@ -933,10 +935,10 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
@Override @Override
public List<GeoFence> getTrafficAlerts(DeviceIdentifier identifier) throws GeoLocationBasedServiceException { public List<GeoFence> getTrafficAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException {
Registry registry = getGovernanceRegistry(); Registry registry = getGovernanceRegistry();
String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS + String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_STATIONARY + "/" + identifier.getId() + "/"; GeoServices.ALERT_TYPE_STATIONARY + "/" + owner + "/" + identifier.getId() + "/";
Resource resource; Resource resource;
try { try {
resource = registry.get(registryPath); resource = registry.get(registryPath);

@ -116,7 +116,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
this.pluginRepository = new DeviceManagementPluginRepository(); this.pluginRepository = new DeviceManagementPluginRepository();
initDataAccessObjects(); initDataAccessObjects();
/* Registering a listener to retrieve events when some device management service plugin is installed after /* Registering a listener to retrieve events when some device management service plugin is installed after
* the component is done getting initialized */ * the component is done getting initialized */
DeviceManagementServiceComponent.registerPluginInitializationListener(this); DeviceManagementServiceComponent.registerPluginInitializationListener(this);
} }
@ -1457,7 +1457,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
if (DeviceManagerUtil.isPublishOperationResponseEnabled()) { if (DeviceManagerUtil.isPublishOperationResponseEnabled()) {
List<String> permittedOperations = DeviceManagerUtil.getEnabledOperationsForResponsePublish(); List<String> permittedOperations = DeviceManagerUtil.getEnabledOperationsForResponsePublish();
if (permittedOperations.contains(operation.getCode()) if (permittedOperations.contains(operation.getCode())
|| permittedOperations.contains("*")) { || permittedOperations.contains("*")) {
Object[] metaData = {deviceId.getId(), deviceId.getType()}; Object[] metaData = {deviceId.getId(), deviceId.getType()};
Object[] payload = new Object[]{ Object[] payload = new Object[]{
Calendar.getInstance().getTimeInMillis(), Calendar.getInstance().getTimeInMillis(),
@ -1531,7 +1531,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
} }
@Override @Override
public List<Activity> getOperationByActivityIds(List<String> idList) throws OperationManagementException{ public List<Activity> getOperationByActivityIds(List<String> idList) throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getOperationByActivityIds(idList); return DeviceManagementDataHolder.getInstance().getOperationManager().getOperationByActivityIds(idList);
} }
@ -2511,11 +2511,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
/** /**
* Returns all the installed apps of the given device. * Returns all the installed apps of the given device.
*/ */
private List<Application> getInstalledApplications(Device device) throws DeviceManagementException { private List<Application> getInstalledApplications(Device device) throws DeviceManagementException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Get installed applications of device: " + device.getId() + " of type '" + device.getType() + "'"); log.debug("Get installed applications of device: " + device.getId() + " of type '" + device.getType() + "'");
} }
List<Application> applications = new ArrayList<>(); List<Application> applications;
try { try {
DeviceManagementDAOFactory.openConnection(); DeviceManagementDAOFactory.openConnection();
applications = applicationDAO.getInstalledApplications(device.getId(), device.getEnrolmentInfo().getId()); applications = applicationDAO.getInstalledApplications(device.getId(), device.getEnrolmentInfo().getId());
@ -2671,8 +2671,10 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
deviceInformationManager.addDeviceLocation(deviceLocation); deviceInformationManager.addDeviceLocation(deviceLocation);
} catch (Exception e) { } catch (Exception e) {
//We are not failing the execution since this is not critical for the functionality. But logging as //We are not failing the execution since this is not critical for the functionality. But logging as
// an error for reference. // a warning for reference.
log.error("Exception occurred while trying to add device location.", e); log.warn("Error occurred while trying to add '" + device.getType() + "' device '" +
device.getDeviceIdentifier() + "' (id:'" + device.getId() + "') location (lat:" + latitude +
", lon:" + longitude + ") due to:" + e.getMessage());
} }
} }
} }

@ -55,7 +55,7 @@ public class ArchivedDataDeletionTask implements Task {
log.error("An error occurred while executing DataDeletionTask", e); log.error("An error occurred while executing DataDeletionTask", e);
} }
long endTime = System.nanoTime(); long endTime = System.nanoTime();
long difference = (endTime - startTime) / 1000000 * 1000; long difference = (endTime - startTime) / (1000000 * 1000);
log.info("DataDeletionTask completed. Total execution time: " + difference + " seconds"); log.info("DataDeletionTask completed. Total execution time: " + difference + " seconds");
} }
} }

@ -7,17 +7,31 @@
/* define streams/tables and write queries here ... */ /* define streams/tables and write queries here ... */
@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') @Import('org.wso2.geo.StandardSpatialEvents:1.0.0')
define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string); define stream dataIn (id string, owner string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string);
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') @Export('iot.per.device.stream.geo.FusedSpatialEvent:1.0.0')
define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string); define stream dataOut (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, state string, information string, notify bool);
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==false and id == "$deviceId"]#geodashboard:subscribe() @Export('iot.per.device.stream.geo.AlertNotifications:1.0.0')
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(type," device "),id), " is outside $areaName area!!!") as information define stream alertsOut (id string, owner string, state string, information string, timeStamp long, latitude double, longitude double, type string);
insert into dataOut;
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=false and id == "$deviceId"] /* Check if the device is within the geo fence. */
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information from dataIn[id == "$deviceId" and owner == "$owner"]
select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId, geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin
insert into withinStream;
from withinStream[isWithin == false]
select id, owner, latitude, longitude,timeStamp, type, speed, heading, "ALERTED" as state, str:concat("The ", type, " device `", id, "` of $owner is outside $areaName area!") as information, true as notify
insert into dataOut; insert into dataOut;
from dataIn[id != "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information from withinStream[isWithin == true]
select id, owner, latitude, longitude,timeStamp, type, speed, heading, "NORMAL" as state, "" as information, false as notify
insert into dataOut; insert into dataOut;
from every fs1=withinStream, fs2=withinStream[fs1.isWithin != isWithin]
select fs2.id, fs2.owner, fs2.latitude, fs2.longitude, fs2.timeStamp, fs2.type, fs2.speed, fs2.heading, fs2.eventId, fs2.isWithin
insert into crossedStream;
from crossedStream[isWithin == false]
select id, owner, "ALERTED" as state, str:concat("The ", type, " device `", id, "` of $owner is outside $areaName area!") as information, timeStamp, latitude, longitude, type
insert into alertsOut;

@ -12,7 +12,7 @@ define stream dataIn (id string, latitude double, longitude double, timeStamp lo
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') @Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0')
define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string); define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string);
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==false]#geodashboard:subscribe() from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==false]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(type," device "),id), " is outside $areaName area!!!") as information select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(type," device "),id), " is outside $areaName area!!!") as information
insert into dataOut; insert into dataOut;
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=false] from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=false]

@ -1,5 +1,5 @@
/* Enter a unique ExecutionPlan */ /* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-Proximity_alert') @Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */ /* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan') -- @Plan:description('ExecutionPlan')
@ -7,10 +7,10 @@
/* define streams/tables and write queries here ... */ /* define streams/tables and write queries here ... */
@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') @Import('org.wso2.geo.StandardSpatialEvents:1.0.0')
define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string ); define stream dataIn (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string );
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') @Export('iot.per.device.stream.geo.FusedSpatialEvent:1.0.0')
define stream dataOut ( id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string, state string, information string ); define stream dataOut (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, state string, information string, notify bool);
@IndexBy('id') @IndexBy('id')
define table ProximityTable(id string, timeStamp long); define table ProximityTable(id string, timeStamp long);
@ -18,12 +18,12 @@ define table ProximityTable(id string, timeStamp long);
@IndexBy('id') @IndexBy('id')
define table AlertsTable(id string , proximityWith string, eventId string); define table AlertsTable(id string , proximityWith string, eventId string);
from dataIn#geodashboard:subscribe() from dataIn
select id, latitude, longitude, timeStamp, type, speed, heading, eventId select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId
insert into initialStream; insert into initialStream;
from initialStream[type == 'STOP'] from initialStream[type == 'STOP']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream; insert into dataOutStream;
from initialStream[type != 'STOP'] from initialStream[type != 'STOP']
@ -31,51 +31,51 @@ select *
insert into objectInitialStream; insert into objectInitialStream;
from objectInitialStream#geo:proximity(id,longitude,latitude, $proximityDistance) from objectInitialStream#geo:proximity(id,longitude,latitude, $proximityDistance)
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith
insert into proxymityStream; insert into proxymityStream;
from proxymityStream[AlertsTable.id == proxymityStream.id in AlertsTable] from proxymityStream[AlertsTable.id == proxymityStream.id in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable
insert into innerStreamOne; insert into innerStreamOne;
from proxymityStream[not(AlertsTable.id == proxymityStream.id in AlertsTable)] from proxymityStream[not(AlertsTable.id == proxymityStream.id in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable
insert into innerStreamOne; insert into innerStreamOne;
from proxymityStream[AlertsTable.id == proxymityStream.proximityWith in AlertsTable] from proxymityStream[AlertsTable.id == proxymityStream.proximityWith in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId, inCloseProximity, proximityWith, true as inAlertTable
insert into innerStreamSeven; insert into innerStreamSeven;
from proxymityStream[not(AlertsTable.id == proxymityStream.proximityWith in AlertsTable)] from proxymityStream[not(AlertsTable.id == proxymityStream.proximityWith in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable
insert into innerStreamSeven; insert into innerStreamSeven;
from innerStreamOne[inCloseProximity == true AND not(inAlertTable)] from innerStreamOne[inCloseProximity == true AND not(inAlertTable)]
select id,str:concat(",",proximityWith) as proximityWith , eventId select id, owner, str:concat(",",proximityWith) as proximityWith , eventId
insert into AlertsTable; insert into AlertsTable;
from innerStreamSeven[inCloseProximity == true AND not(inAlertTable)] from innerStreamSeven[inCloseProximity == true AND not(inAlertTable)]
select proximityWith as id,str:concat(",",id) as proximityWith , eventId select proximityWith as id, owner, str:concat(",",id) as proximityWith , eventId
insert into AlertsTable; insert into AlertsTable;
from innerStreamOne[innerStreamOne.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable from innerStreamOne[innerStreamOne.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamOne.id == AlertsTable.id on innerStreamOne.id == AlertsTable.id
select innerStreamOne.id as id, str:concat(",", innerStreamOne.proximityWith, AlertsTable.proximityWith) as proximityWith, innerStreamOne.eventId as eventId select innerStreamOne.id as id, innerStreamOne.owner as owner, str:concat(",", innerStreamOne.proximityWith, AlertsTable.proximityWith) as proximityWith, innerStreamOne.eventId as eventId
insert into updateStream; insert into updateStream;
from innerStreamSeven[innerStreamSeven.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable from innerStreamSeven[innerStreamSeven.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamSeven.proximityWith == AlertsTable.id on innerStreamSeven.proximityWith == AlertsTable.id
select innerStreamSeven.proximityWith as id, str:concat(",", innerStreamSeven.id, AlertsTable.proximityWith) as proximityWith, innerStreamSeven.eventId as eventId select innerStreamSeven.proximityWith as id, innerStreamSeven.owner as owner, str:concat(",", innerStreamSeven.id, AlertsTable.proximityWith) as proximityWith, innerStreamSeven.eventId as eventId
insert into updateStream; insert into updateStream;
from innerStreamOne[innerStreamOne.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable from innerStreamOne[innerStreamOne.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamOne.id == AlertsTable.id on innerStreamOne.id == AlertsTable.id
select innerStreamOne.id as id, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamOne.proximityWith), "") as proximityWith, innerStreamOne.eventId as eventId select innerStreamOne.id as id, innerStreamOne.owner as owner, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamOne.proximityWith), "") as proximityWith, innerStreamOne.eventId as eventId
insert into updateStream; insert into updateStream;
from innerStreamSeven[innerStreamSeven.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable from innerStreamSeven[innerStreamSeven.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamSeven.proximityWith == AlertsTable.id on innerStreamSeven.proximityWith == AlertsTable.id
select innerStreamSeven.proximityWith as id, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamSeven.id), "") as proximityWith, innerStreamSeven.eventId as eventId select innerStreamSeven.proximityWith as id, innerStreamSeven.owner as owner, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamSeven.id), "") as proximityWith, innerStreamSeven.eventId as eventId
insert into updateStream; insert into updateStream;
from updateStream from updateStream
@ -88,23 +88,23 @@ delete AlertsTable
on id== AlertsTable.id; on id== AlertsTable.id;
from objectInitialStream[AlertsTable.id == objectInitialStream.id in AlertsTable] from objectInitialStream[AlertsTable.id == objectInitialStream.id in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId, true as inAlertTable select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId, true as inAlertTable
insert into publishStream; insert into publishStream;
from objectInitialStream[not(AlertsTable.id == objectInitialStream.id in AlertsTable)] from objectInitialStream[not(AlertsTable.id == objectInitialStream.id in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId, false as inAlertTable select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId, false as inAlertTable
insert into publishStream; insert into publishStream;
from publishStream[inAlertTable == true]#window.length(0) join AlertsTable from publishStream[inAlertTable == true]#window.length(0) join AlertsTable
on publishStream.id== AlertsTable.id on publishStream.id== AlertsTable.id
select publishStream.id as id, publishStream.latitude as latitude, publishStream.longitude as longitude, publishStream.timeStamp as timeStamp, publishStream.type as type, publishStream.speed as speed, publishStream.heading as heading, publishStream.eventId as eventId, AlertsTable.proximityWith as proximityInfo select publishStream.id as id, publishStream.owner as owner, publishStream.latitude as latitude, publishStream.longitude as longitude, publishStream.timeStamp as timeStamp, publishStream.type as type, publishStream.speed as speed, publishStream.heading as heading, publishStream.eventId as eventId, AlertsTable.proximityWith as proximityInfo
insert into innerStreamTwo; insert into innerStreamTwo;
from publishStream[inAlertTable == false] from publishStream[inAlertTable == false]
delete ProximityTable on ProximityTable.id==id; delete ProximityTable on ProximityTable.id==id;
from publishStream[inAlertTable == false] from publishStream[inAlertTable == false]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream; insert into dataOutStream;
from innerStreamTwo[ProximityTable.id == innerStreamTwo.id in ProximityTable] from innerStreamTwo[ProximityTable.id == innerStreamTwo.id in ProximityTable]
@ -112,29 +112,29 @@ insert into innerStreamThree;
from innerStreamThree#window.length(0) join ProximityTable from innerStreamThree#window.length(0) join ProximityTable
on innerStreamThree.id == ProximityTable.id on innerStreamThree.id == ProximityTable.id
select innerStreamThree.id , innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId, ProximityTable.timeStamp as storedTime, innerStreamThree.proximityInfo as proximityInfo select innerStreamThree.id, innerStreamThree.owner, innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId, ProximityTable.timeStamp as storedTime, innerStreamThree.proximityInfo as proximityInfo
insert into innerStreamFour; insert into innerStreamFour;
from innerStreamFour[(timeStamp - storedTime) >= $proximityTime] from innerStreamFour[(timeStamp - storedTime) >= $proximityTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,proximityInfo,"true" as isProximity select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId ,proximityInfo, "true" as isProximity
insert into dataOutStream; insert into dataOutStream;
from innerStreamFour[(timeStamp - storedTime) < $proximityTime] from innerStreamFour[(timeStamp - storedTime) < $proximityTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , proximityInfo ,"false" as isProximity select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId, proximityInfo, "false" as isProximity
insert into dataOutStream; insert into dataOutStream;
from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)] from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)]
select innerStreamTwo.id, innerStreamTwo.timeStamp select innerStreamTwo.id, innerStreamTwo.owner, innerStreamTwo.timeStamp
insert into ProximityTable; insert into ProximityTable;
from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)] from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream; insert into dataOutStream;
from dataOutStream[isProximity == 'true'] from dataOutStream[isProximity == 'true']
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,"WARNING" as state,str:concat("Proximity with "," ",proximityInfo) as information select id, owner, latitude, longitude, timeStamp, type, speed, heading, "WARNING" as state,str:concat("Proximity with "," ",proximityInfo) as information, true as notify
insert into dataOut; insert into dataOut;
from dataOutStream[isProximity == 'false'] from dataOutStream[isProximity == 'false']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"NORMAL" as state,"" as information select id, owner, latitude, longitude,timeStamp, type, speed, heading, "NORMAL" as state,"" as information, false as notify
insert into dataOut; insert into dataOut;

@ -1,5 +1,5 @@
/* Enter a unique ExecutionPlan */ /* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-Proximity_alert') @Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */ /* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan') -- @Plan:description('ExecutionPlan')
@ -18,7 +18,7 @@ define table ProximityTable(id string, timeStamp long);
@IndexBy('id') @IndexBy('id')
define table AlertsTable(id string , proximityWith string, eventId string); define table AlertsTable(id string , proximityWith string, eventId string);
from dataIn#geodashboard:subscribe() from dataIn
select id, latitude, longitude, timeStamp, type, speed, heading, eventId select id, latitude, longitude, timeStamp, type, speed, heading, eventId
insert into initialStream; insert into initialStream;

@ -1,5 +1,5 @@
/* Enter a unique ExecutionPlan */ /* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-Speed---$deviceId_alert') @Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */ /* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan') -- @Plan:description('ExecutionPlan')
@ -7,17 +7,22 @@
/* define streams/tables and write queries here ... */ /* define streams/tables and write queries here ... */
@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') @Import('org.wso2.geo.StandardSpatialEvents:1.0.0')
define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string); define stream dataIn (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string);
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') @Export('iot.per.device.stream.geo.FusedSpatialEvent:1.0.0')
define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string, state string, information string); define stream dataOut (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, state string, information string, notify bool );
from dataIn[speed >= $speedAlertValue and id == "$deviceId"]#geodashboard:subscribe() @Export('iot.per.device.stream.geo.AlertNotifications:1.0.0')
select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(str:concat("Movement of ",type), " device "), id), " is not normal!!") as information define stream alertsOut (id string, owner string, state string, information string, timeStamp long, latitude double, longitude double, type string);
insert into dataOut;
from dataIn[speed < $speedAlertValue and id == "$deviceId"] from dataIn[speed >= $speedAlertValue and id == "$deviceId" and owner == "$owner"]
select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "NORMAL" as state, str:concat(str:concat(str:concat(str:concat("Movement of ",type), " device "), id), " is normal") as information select id, owner, latitude, longitude, timeStamp, type, speed, heading, "ALERTED" as state, str:concat("The ", type, " device `", id, "` of $owner is traveling at ", math:round(speed), "km/h and is exceeding the $speedAlertValuekm/h speed limit") as information, true as notify
insert into dataOut; insert into dataOut;
from dataIn[id != "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information from dataIn[speed < $speedAlertValue and id == "$deviceId" and owner == "$owner"]
select id, owner, latitude, longitude, timeStamp, type, speed, heading, "NORMAL" as state, str:concat("The ", type, " device `", id, "` of $owner is travailing at normal speed.") as information, false as notify
insert into dataOut; insert into dataOut;
from dataOut[notify == true]
select id, owner, state, information, timeStamp, latitude, longitude, type
insert into alertsOut;

@ -1,5 +1,5 @@
/* Enter a unique ExecutionPlan */ /* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-Speed---_alert') @Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */ /* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan') -- @Plan:description('ExecutionPlan')
@ -12,7 +12,7 @@ define stream dataIn (id string, latitude double, longitude double, timeStamp lo
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') @Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0')
define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string, state string, information string); define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string, state string, information string);
from dataIn[speed >= $speedAlertValue]#geodashboard:subscribe() from dataIn[speed >= $speedAlertValue]
select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(str:concat("Movement of ",type), " device "), id), " is not normal!!") as information select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(str:concat("Movement of ",type), " device "), id), " is not normal!!") as information
insert into dataOut; insert into dataOut;
from dataIn[speed < $speedAlertValue] from dataIn[speed < $speedAlertValue]

@ -7,11 +7,13 @@
/* define streams/tables and write queries here ... */ /* define streams/tables and write queries here ... */
@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') @Import('org.wso2.geo.StandardSpatialEvents:1.0.0')
define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string); define stream dataIn (id string, owner string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string);
@Export('iot.per.device.stream.geo.FusedSpatialEvent:1.0.0')
define stream dataOut (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, state string, information string, notify bool );
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') @Export('iot.per.device.stream.geo.AlertNotifications:1.0.0')
define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string); define stream alertsOut (id string, owner string, state string, information string, timeStamp long, latitude double, longitude double, type string);
@IndexBy('id') @IndexBy('id')
define table StationeryTable(id string, timeStamp long); define table StationeryTable(id string, timeStamp long);
@ -19,19 +21,19 @@ define table StationeryTable(id string, timeStamp long);
@IndexBy('id') @IndexBy('id')
define table AlertsTable(id string, stationary bool); define table AlertsTable(id string, stationary bool);
from dataIn#geodashboard:subscribe() from dataIn
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId,geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin
insert into innerStreamOne; insert into innerStreamOne;
from innerStreamOne[isWithin == false] from innerStreamOne[isWithin == false]
delete StationeryTable on StationeryTable.id==id; delete StationeryTable on StationeryTable.id==id;
from innerStreamOne[isWithin == false] from innerStreamOne[isWithin == false]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream; insert into dataOutStream;
from innerStreamOne[isWithin == true]#geo:stationary(id,longitude,latitude, $fluctuationRadius) from innerStreamOne[isWithin == true]#geo:stationary(id,longitude,latitude, $fluctuationRadius)
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,stationary select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId,stationary
insert into innerStreamTwo; insert into innerStreamTwo;
from innerStreamTwo[innerStreamTwo.stationary == true] from innerStreamTwo[innerStreamTwo.stationary == true]
@ -45,7 +47,7 @@ from innerStreamTwo[innerStreamTwo.stationary == false]
delete StationeryTable on StationeryTable.id==id; delete StationeryTable on StationeryTable.id==id;
from innerStreamOne[isWithin == true AND not(AlertsTable.id == innerStreamOne.id in AlertsTable)] from innerStreamOne[isWithin == true AND not(AlertsTable.id == innerStreamOne.id in AlertsTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream; insert into dataOutStream;
from innerStreamOne[isWithin == true AND AlertsTable.id == innerStreamOne.id in AlertsTable] from innerStreamOne[isWithin == true AND AlertsTable.id == innerStreamOne.id in AlertsTable]
@ -53,7 +55,7 @@ insert into innerStreamThree;
from innerStreamThree#window.length(0) join AlertsTable from innerStreamThree#window.length(0) join AlertsTable
on innerStreamThree.id == AlertsTable.id on innerStreamThree.id == AlertsTable.id
select innerStreamThree.id , innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId select innerStreamThree.id, innerStreamThree.owner, innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId
insert into innerStreamFour; insert into innerStreamFour;
from innerStreamFour[not(StationeryTable.id == innerStreamFour.id in StationeryTable)] from innerStreamFour[not(StationeryTable.id == innerStreamFour.id in StationeryTable)]
@ -61,7 +63,7 @@ select innerStreamFour.id, innerStreamFour.timeStamp
insert into StationeryTable; insert into StationeryTable;
from innerStreamOne[isWithin == true AND not(StationeryTable.id == innerStreamOne.id in StationeryTable)] from innerStreamOne[isWithin == true AND not(StationeryTable.id == innerStreamOne.id in StationeryTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream; insert into dataOutStream;
from innerStreamOne[isWithin == true AND StationeryTable.id == innerStreamOne.id in StationeryTable] from innerStreamOne[isWithin == true AND StationeryTable.id == innerStreamOne.id in StationeryTable]
@ -69,21 +71,25 @@ insert into innerStreamFive;
from innerStreamFive#window.length(0) join StationeryTable from innerStreamFive#window.length(0) join StationeryTable
on innerStreamFive.id == StationeryTable.id on innerStreamFive.id == StationeryTable.id
select innerStreamFive.id , innerStreamFive.latitude, innerStreamFive.longitude,innerStreamFive.timeStamp, innerStreamFive.type, innerStreamFive.speed, innerStreamFive.heading ,innerStreamFive.eventId, StationeryTable.timeStamp as storedTime select innerStreamFive.id, innerStreamFive.owner, innerStreamFive.latitude, innerStreamFive.longitude,innerStreamFive.timeStamp, innerStreamFive.type, innerStreamFive.speed, innerStreamFive.heading ,innerStreamFive.eventId, StationeryTable.timeStamp as storedTime
insert into innerStreamSix; insert into innerStreamSix;
from innerStreamSix[(timeStamp - storedTime) >= $stationeryTime] from innerStreamSix[(timeStamp - storedTime) >= $stationeryTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"true" as isStationary select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId ,"true" as isStationary
insert into dataOutStream; insert into dataOutStream;
from innerStreamSix[(timeStamp - storedTime) < $stationeryTime] from innerStreamSix[(timeStamp - storedTime) < $stationeryTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"false" as isStationary select id, owner, latitude, longitude,timeStamp, type, speed, heading ,eventId ,"false" as isStationary
insert into dataOutStream; insert into dataOutStream;
from dataOutStream[isStationary == 'true'] from dataOutStream[isStationary == 'true']
select id ,latitude, longitude,timeStamp, type, speed, heading ,eventId ,"ALERTED" as state, str:concat(str:concat(str:concat(type," device "),id),"is in $stationeryName area!!!") as information select id, owner, latitude, longitude,timeStamp, type, speed, heading, "ALERTED" as state, str:concat("The ", type, " device `", id, "` of $owner is in $stationeryName area!") as information, true as notify
insert into dataOut; insert into dataOut;
from dataOutStream[isStationary == 'false'] from dataOutStream[isStationary == 'false']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"NORMAL" as state,"" as information select id, owner, latitude, longitude,timeStamp, type, speed, heading, "NORMAL" as state,"" as information, false as notify
insert into dataOut; insert into dataOut;
from dataOut[notify == true]
select id, owner, state, information, timeStamp, latitude, longitude, type
insert into alertsOut;

@ -19,7 +19,7 @@ define table StationeryTable(id string, timeStamp long);
@IndexBy('id') @IndexBy('id')
define table AlertsTable(id string, stationary bool); define table AlertsTable(id string, stationary bool);
from dataIn#geodashboard:subscribe() from dataIn
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin select id, latitude, longitude, timeStamp, type, speed, heading, eventId,geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin
insert into innerStreamOne; insert into innerStreamOne;

@ -7,11 +7,11 @@
/* define streams/tables and write queries here ... */ /* define streams/tables and write queries here ... */
@Import('rawGeoStream:1.0.0') @Import('rawGeoStream:1.0.0')
define stream dataIn (id string, timeStamp long, geometry string, state string, information string); define stream dataIn (id string, owner string, timeStamp long, geometry string, state string, information string);
@Export('AlertsNotifications:1.0.0') @Export('AlertsNotifications:1.0.0')
define stream dataOut (id string, state string, information string, timeStamp long, latitude double, longitude double); define stream dataOut (id string, owner string, state string, information string, timeStamp long, latitude double, longitude double);
from dataIn[geo:intersects(geometry, "$geoFenceGeoJSON")==true and geodashboard:needToNotify(id, str:concat(information, state), "sendFirst") == true and id == $deviceId] from dataIn[geo:intersects(geometry, "$geoFenceGeoJSON")==true and geodashboard:needToNotify(id, str:concat(information, state), "sendFirst") == true and id == "$deviceId" and owner == "$owner"]
select id, state, str:concat("Traffic alert in $areaName. State: ", state, " ", information) as information, timeStamp, 0.0 as latitude, 0.0 as longitude select id, owner, state, str:concat("Traffic alert in $areaName. State: ", state, " ", information) as information, timeStamp, 0.0 as latitude, 0.0 as longitude
insert into dataOut insert into dataOut

@ -7,17 +7,31 @@
/* define streams/tables and write queries here ... */ /* define streams/tables and write queries here ... */
@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') @Import('org.wso2.geo.StandardSpatialEvents:1.0.0')
define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string); define stream dataIn (id string, owner string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string);
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') @Export('iot.per.device.stream.geo.FusedSpatialEvent:1.0.0')
define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string); define stream dataOut (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, state string, information string, notify bool );
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==true and id == "$deviceId"]#geodashboard:subscribe() @Export('iot.per.device.stream.geo.AlertNotifications:1.0.0')
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(type," device "), id), " is in $areaName restricted area!!!") as information define stream alertsOut (id string, owner string, state string, information string, timeStamp long, latitude double, longitude double, type string);
insert into dataOut;
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=true and id == "$deviceId"] /* Check if the device is within the geo fence. */
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information from dataIn[id == "$deviceId" and owner == "$owner"]
select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId, geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin
insert into withinStream;
from withinStream[isWithin == true]
select id, owner, latitude, longitude,timeStamp, type, speed, heading, "ALERTED" as state, str:concat("The ", type, " device `", id, "` of $owner is inside $areaName area!") as information, true as notify
insert into dataOut; insert into dataOut;
from dataIn[id != "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information from withinStream[isWithin == false]
select id, owner, latitude, longitude,timeStamp, type, speed, heading, "NORMAL" as state, "" as information, false as notify
insert into dataOut; insert into dataOut;
from every fs1=withinStream, fs2=withinStream[fs1.isWithin != isWithin]
select fs2.id, fs2.owner, fs2.latitude, fs2.longitude, fs2.timeStamp, fs2.type, fs2.speed, fs2.heading, fs2.eventId, fs2.isWithin
insert into crossedStream;
from crossedStream[isWithin == true]
select id, owner, "ALERTED" as state, str:concat("The ", type, " device `", id, "` of $owner is inside $areaName area!") as information, timeStamp, latitude, longitude, type
insert into alertsOut;

@ -12,7 +12,7 @@ define stream dataIn (id string, latitude double, longitude double, timeStamp lo
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') @Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0')
define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string); define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string);
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==true]#geodashboard:subscribe() from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==true]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(type," device "), id), " is in $areaName restricted area!!!") as information select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, str:concat(str:concat(str:concat(type," device "), id), " is in $areaName restricted area!!!") as information
insert into dataOut; insert into dataOut;
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=true] from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=true]

@ -19,21 +19,17 @@
package org.wso2.carbon.device.mgt.core.geo.service; package org.wso2.carbon.device.mgt.core.geo.service;
import org.apache.axis2.AxisFault;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.geo.service.Alert; import org.wso2.carbon.device.mgt.common.geo.service.Alert;
import org.wso2.carbon.device.mgt.common.geo.service.AlertAlreadyExistException; import org.wso2.carbon.device.mgt.common.geo.service.AlertAlreadyExistException;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFence; 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.GeoLocationBasedServiceException;
import org.wso2.carbon.device.mgt.common.geo.service.AlertAlreadyExistException;
import org.wso2.carbon.device.mgt.core.TestDeviceManagementService; import org.wso2.carbon.device.mgt.core.TestDeviceManagementService;
import org.wso2.carbon.device.mgt.core.common.TestDataHolder; import org.wso2.carbon.device.mgt.core.common.TestDataHolder;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
@ -59,70 +55,76 @@ public class GeoLocationProviderServiceTest {
private static final String SAMPLE_STATIONARY_TIME = "1500"; private static final String SAMPLE_STATIONARY_TIME = "1500";
private static final String SAMPLE_FLUCTUATION_RADIUS = "2000"; private static final String SAMPLE_FLUCTUATION_RADIUS = "2000";
private EventProcessorAdminServiceStub mockEventProcessorAdminServiceStub;
private GeoLocationProviderServiceImpl geoLocationProviderServiceImpl; private GeoLocationProviderServiceImpl geoLocationProviderServiceImpl;
private ExecutionPlanConfigurationDto[] mockExecutionPlanConfigurationDto = new ExecutionPlanConfigurationDto[1]; private ExecutionPlanConfigurationDto[] mockExecutionPlanConfigurationDto = new ExecutionPlanConfigurationDto[1];
private Device device;
@BeforeClass @BeforeClass
public void init() throws Exception { public void init() throws Exception {
initMocks(); initMocks();
enrollDevice(); device = enrollDevice();
} }
@Test (description = "Create a sample geo exit-alert with relevant details.") @Test(description = "Create a sample geo exit-alert with relevant details.")
public void createGeoExitAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException { public void createGeoExitAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException {
Boolean result = geoLocationProviderServiceImpl. Boolean result = geoLocationProviderServiceImpl.
createGeoAlert(getExitAlert(), getDeviceIdentifier(), DeviceManagementConstants.GeoServices.ALERT_TYPE_EXIT); createGeoAlert(getExitAlert(), getDeviceIdentifier(),
DeviceManagementConstants.GeoServices.ALERT_TYPE_EXIT, device.getEnrolmentInfo().getOwner());
Assert.assertEquals(result, Boolean.TRUE); Assert.assertEquals(result, Boolean.TRUE);
} }
@Test (description = "Create a sample geo within-alert with relevant details.") @Test(description = "Create a sample geo within-alert with relevant details.")
public void createGeoWithinAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException { public void createGeoWithinAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException {
Boolean result = geoLocationProviderServiceImpl. Boolean result = geoLocationProviderServiceImpl.
createGeoAlert(getWithinAlert(), getDeviceIdentifier(), DeviceManagementConstants.GeoServices.ALERT_TYPE_WITHIN); createGeoAlert(getWithinAlert(), getDeviceIdentifier(),
DeviceManagementConstants.GeoServices.ALERT_TYPE_WITHIN, device.getEnrolmentInfo().getOwner());
Assert.assertEquals(result, Boolean.TRUE); Assert.assertEquals(result, Boolean.TRUE);
} }
@Test (description = "Create a sample geo proximity-alert with relevant details.") @Test(description = "Create a sample geo proximity-alert with relevant details.")
public void createGeoProximityAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException { public void createGeoProximityAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException {
Boolean result = geoLocationProviderServiceImpl. Boolean result = geoLocationProviderServiceImpl.
createGeoAlert(getProximityAlert(), getDeviceIdentifier(), DeviceManagementConstants.GeoServices.ALERT_TYPE_PROXIMITY); createGeoAlert(getProximityAlert(), getDeviceIdentifier(),
DeviceManagementConstants.GeoServices.ALERT_TYPE_PROXIMITY, device.getEnrolmentInfo().getOwner());
Assert.assertEquals(result, Boolean.TRUE); Assert.assertEquals(result, Boolean.TRUE);
} }
@Test (description = "Create a sample geo speed-alert with relevant details.") @Test(description = "Create a sample geo speed-alert with relevant details.")
public void createGeoSpeedAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException { public void createGeoSpeedAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException {
Boolean result = geoLocationProviderServiceImpl. Boolean result = geoLocationProviderServiceImpl.
createGeoAlert(getSpeedAlert(), getDeviceIdentifier(), DeviceManagementConstants.GeoServices.ALERT_TYPE_SPEED); createGeoAlert(getSpeedAlert(), getDeviceIdentifier(),
DeviceManagementConstants.GeoServices.ALERT_TYPE_SPEED, device.getEnrolmentInfo().getOwner());
Assert.assertEquals(result, Boolean.TRUE); Assert.assertEquals(result, Boolean.TRUE);
} }
@Test (description = "Create a sample geo stationary-alert with relevant details.") @Test(description = "Create a sample geo stationary-alert with relevant details.")
public void createGeoStationaryAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException { public void createGeoStationaryAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException {
Boolean result = geoLocationProviderServiceImpl. Boolean result = geoLocationProviderServiceImpl.
createGeoAlert(getStationaryAlert(), getDeviceIdentifier(), DeviceManagementConstants.GeoServices.ALERT_TYPE_STATIONARY); createGeoAlert(getStationaryAlert(), getDeviceIdentifier(),
DeviceManagementConstants.GeoServices.ALERT_TYPE_STATIONARY, device.getEnrolmentInfo().getOwner());
Assert.assertEquals(result, Boolean.TRUE); Assert.assertEquals(result, Boolean.TRUE);
} }
@Test (description = "Create a sample geo traffic-alert with relevant details.") @Test(description = "Create a sample geo traffic-alert with relevant details.")
public void createGeoTrafficAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException { public void createGeoTrafficAlert() throws GeoLocationBasedServiceException, AlertAlreadyExistException {
Boolean result = geoLocationProviderServiceImpl. Boolean result = geoLocationProviderServiceImpl.
createGeoAlert(getTrafficAlert(), getDeviceIdentifier(), DeviceManagementConstants.GeoServices.ALERT_TYPE_TRAFFIC); createGeoAlert(getTrafficAlert(), getDeviceIdentifier(),
DeviceManagementConstants.GeoServices.ALERT_TYPE_TRAFFIC, device.getEnrolmentInfo().getOwner());
Assert.assertEquals(result, Boolean.TRUE); Assert.assertEquals(result, Boolean.TRUE);
} }
@Test(dependsOnMethods = "createGeoSpeedAlert", description = "retrieve saved geo speed-alert.") @Test(dependsOnMethods = "createGeoSpeedAlert", description = "retrieve saved geo speed-alert.")
public void getGeoSpeedAlerts() throws GeoLocationBasedServiceException { public void getGeoSpeedAlerts() throws GeoLocationBasedServiceException {
String result; String result;
result = geoLocationProviderServiceImpl.getSpeedAlerts(getDeviceIdentifier()); result = geoLocationProviderServiceImpl.getSpeedAlerts(getDeviceIdentifier(), device.getEnrolmentInfo().getOwner());
Assert.assertNotNull(result); Assert.assertNotNull(result);
Assert.assertEquals(result, "{'speedLimit':" + SAMPLE_SPEED_ALERT_VALUE + "}"); Assert.assertEquals(result, "{'speedLimit':" + SAMPLE_SPEED_ALERT_VALUE + "}");
} }
@Test(dependsOnMethods = "createGeoTrafficAlert" , description = "retrieve saved geo exit-alert.") @Test(dependsOnMethods = "createGeoTrafficAlert", description = "retrieve saved geo exit-alert.")
public void getGeoTrafficAlerts() throws GeoLocationBasedServiceException { public void getGeoTrafficAlerts() throws GeoLocationBasedServiceException {
List<GeoFence> geoFences; List<GeoFence> geoFences;
geoFences = geoLocationProviderServiceImpl.getTrafficAlerts(getDeviceIdentifier()); geoFences = geoLocationProviderServiceImpl.getTrafficAlerts(getDeviceIdentifier(), device.getEnrolmentInfo().getOwner());
Assert.assertNotNull(geoFences); Assert.assertNotNull(geoFences);
GeoFence geoFenceNode = geoFences.get(0); GeoFence geoFenceNode = geoFences.get(0);
Assert.assertEquals(geoFenceNode.getGeoJson(), "{\n" + Assert.assertEquals(geoFenceNode.getGeoJson(), "{\n" +
@ -133,7 +135,7 @@ public class GeoLocationProviderServiceTest {
@Test(dependsOnMethods = "createGeoStationaryAlert", description = "retrieve saved geo stationary-alert.") @Test(dependsOnMethods = "createGeoStationaryAlert", description = "retrieve saved geo stationary-alert.")
public void getGeoStationaryAlerts() throws GeoLocationBasedServiceException { public void getGeoStationaryAlerts() throws GeoLocationBasedServiceException {
List<GeoFence> geoFences; List<GeoFence> geoFences;
geoFences = geoLocationProviderServiceImpl.getStationaryAlerts(getDeviceIdentifier()); geoFences = geoLocationProviderServiceImpl.getStationaryAlerts(getDeviceIdentifier(), device.getEnrolmentInfo().getOwner());
Assert.assertNotNull(geoFences); Assert.assertNotNull(geoFences);
GeoFence geoFenceNode = geoFences.get(0); GeoFence geoFenceNode = geoFences.get(0);
Assert.assertEquals(geoFenceNode.getAreaName(), SAMPLE_AREA_NAME); Assert.assertEquals(geoFenceNode.getAreaName(), SAMPLE_AREA_NAME);
@ -142,7 +144,7 @@ public class GeoLocationProviderServiceTest {
} }
private void initMocks() throws JWTClientException, RemoteException { private void initMocks() throws JWTClientException, RemoteException {
mockEventProcessorAdminServiceStub = Mockito.mock(EventProcessorAdminServiceStub.class); EventProcessorAdminServiceStub mockEventProcessorAdminServiceStub = Mockito.mock(EventProcessorAdminServiceStub.class);
geoLocationProviderServiceImpl = Mockito.mock(GeoLocationProviderServiceImpl.class, Mockito.CALLS_REAL_METHODS); geoLocationProviderServiceImpl = Mockito.mock(GeoLocationProviderServiceImpl.class, Mockito.CALLS_REAL_METHODS);
mockExecutionPlanConfigurationDto[0] = Mockito.mock(ExecutionPlanConfigurationDto.class); mockExecutionPlanConfigurationDto[0] = Mockito.mock(ExecutionPlanConfigurationDto.class);
Mockito.doReturn(mockEventProcessorAdminServiceStub). Mockito.doReturn(mockEventProcessorAdminServiceStub).
@ -156,8 +158,8 @@ public class GeoLocationProviderServiceTest {
private DeviceIdentifier getDeviceIdentifier() { private DeviceIdentifier getDeviceIdentifier() {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId("1234"); deviceIdentifier.setId(device.getDeviceIdentifier());
deviceIdentifier.setType("TEST"); deviceIdentifier.setType(device.getType());
return deviceIdentifier; return deviceIdentifier;
} }
@ -200,7 +202,7 @@ public class GeoLocationProviderServiceTest {
} }
private Alert getSpeedAlert() { private Alert getSpeedAlert() {
Alert alert = new Alert(); Alert alert = new Alert();
alert.setDeviceId(DEVICE_ID); alert.setDeviceId(DEVICE_ID);
alert.setParseData("{\n" + alert.setParseData("{\n" +
" \"" + DeviceManagementConstants.GeoServices.GEO_FENCE_GEO_JSON + "\": \"" + SAMPLE_GEO_JSON + "\",\n" + " \"" + DeviceManagementConstants.GeoServices.GEO_FENCE_GEO_JSON + "\": \"" + SAMPLE_GEO_JSON + "\",\n" +
@ -226,7 +228,7 @@ public class GeoLocationProviderServiceTest {
Alert alert = new Alert(); Alert alert = new Alert();
alert.setDeviceId(DEVICE_ID); alert.setDeviceId(DEVICE_ID);
alert.setParseData("{\n" + alert.setParseData("{\n" +
" \"" + DeviceManagementConstants.GeoServices.GEO_FENCE_GEO_JSON +"\": \"" + SAMPLE_GEO_JSON + "\"\n" + " \"" + DeviceManagementConstants.GeoServices.GEO_FENCE_GEO_JSON + "\": \"" + SAMPLE_GEO_JSON + "\"\n" +
"}"); "}");
alert.setCustomName(SAMPLE_AREA_NAME); alert.setCustomName(SAMPLE_AREA_NAME);
alert.setExecutionPlan("EXECUTION_PLAN"); alert.setExecutionPlan("EXECUTION_PLAN");
@ -234,7 +236,7 @@ public class GeoLocationProviderServiceTest {
return alert; return alert;
} }
private void enrollDevice() throws Exception { private Device enrollDevice() throws Exception {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(DEVICE_ID, DEVICE_TYPE); DeviceIdentifier deviceIdentifier = new DeviceIdentifier(DEVICE_ID, DEVICE_TYPE);
Device device = TestDataHolder.generateDummyDeviceData(deviceIdentifier); Device device = TestDataHolder.generateDummyDeviceData(deviceIdentifier);
DeviceManagementProviderService deviceMgtService = DeviceManagementDataHolder.getInstance(). DeviceManagementProviderService deviceMgtService = DeviceManagementDataHolder.getInstance().
@ -245,9 +247,11 @@ public class GeoLocationProviderServiceTest {
Device returnedDevice = deviceMgtService.getDevice(deviceIdentifier); Device returnedDevice = deviceMgtService.getDevice(deviceIdentifier);
if (!returnedDevice.getDeviceIdentifier().equals(deviceIdentifier.getId())) { if (!returnedDevice.getDeviceIdentifier().equals(deviceIdentifier.getId())) {
throw new Exception("Incorrect device with ID - " + device.getDeviceIdentifier() + " returned!"); throw new Exception("Incorrect device with ID - " + device.getDeviceIdentifier() + " returned!");
}
} }
return returnedDevice;
}
} }

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

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

@ -521,10 +521,10 @@
<p id="information" class="bg-primary" style="margin: 0px;padding: 0px;"></p> <p id="information" class="bg-primary" style="margin: 0px;padding: 0px;"></p>
{{#if geoServicesEnabled}} {{#if geoServicesEnabled}}
<h6>Speed<span class="label label-primary pull-right"><span id="speed"></span> km/h</span></h6> <h6>Speed<span class="label label-primary pull-right"><span id="speed"></span> km/h</span></h6>
<h6>Heading<span id="heading" class="label label-primary pull-right"></span></h6> <!--<h6>Heading<span id="heading" class="label label-primary pull-right"></span></h6>-->
<button type="button" class="btn btn-info btn-xs" onClick="toggleSpeedGraph();return false;">Speed Graph</button> <!--<button type="button" class="btn btn-info btn-xs" onClick="toggleSpeedGraph();return false;">Speed Graph</button>-->
<button type="button" class="btn btn-info btn-xs" onClick="focusOnRecentHistorySpatialObject();return false;">Recent History</button> <!--<button type="button" class="btn btn-info btn-xs" onClick="focusOnRecentHistorySpatialObject();return false;">Recent History</button>-->
<button type="button" class="btn btn-info btn-xs" onClick="popupDateRange();">Full History</button> <!--<button type="button" class="btn btn-info btn-xs" onClick="popupDateRange();">Full History</button>-->
{{/if}} {{/if}}
</div> </div>
</div> </div>

@ -122,10 +122,10 @@ function processAfterInitializationMap(geoFencingEnabled) {
}; };
map.addControl(L.control.fullscreen({position: 'bottomright'})); map.addControl(L.control.fullscreen({position: 'bottomright'}));
geoAlertsBar = L.control.geoAlerts({position: 'topright'}); // geoAlertsBar = L.control.geoAlerts({position: 'topright'});
if (geoFencingEnabled) { // if (geoFencingEnabled) {
map.addControl(geoAlertsBar); // map.addControl(geoAlertsBar);
} // }
groupedOverlays = { groupedOverlays = {
"Web Map Service layers": {} "Web Map Service layers": {}
@ -256,7 +256,7 @@ function focusOnSpatialObject(objectId) {
// TODO: check the map._layersMaxZoom and set the zoom level accordingly // TODO: check the map._layersMaxZoom and set the zoom level accordingly
spatialObject.marker.openPopup(); spatialObject.marker.openPopup();
getAlertsHistory(deviceType, deviceId, new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime()); // getAlertsHistory(deviceType, deviceId, new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime());
spatialObject.drawPath(); spatialObject.drawPath();
if (speedGraphControl) { if (speedGraphControl) {
setTimeout(function () { setTimeout(function () {
@ -435,11 +435,11 @@ function drawSpatialObject() {
return true; return true;
} }
if (geoFencingEnabled) { // if (geoFencingEnabled) {
var alertsFromDate = new Date(); // var alertsFromDate = new Date();
alertsFromDate.setHours(alertsFromDate.getHours() - 24); //last 24 hours // alertsFromDate.setHours(alertsFromDate.getHours() - 24); //last 24 hours
getAlertsHistory(deviceType, deviceId, alertsFromDate.valueOf(), toDate.valueOf()); // getAlertsHistory(deviceType, deviceId, alertsFromDate.valueOf(), toDate.valueOf());
} // }
setTimeout(function () { setTimeout(function () {
map.invalidateSize(); map.invalidateSize();
@ -513,7 +513,7 @@ function focusOnHistorySpatialObject(objectId, timeFrom, timeTo) {
// TODO: check the map._layersMaxZoom and set the zoom level accordingly // TODO: check the map._layersMaxZoom and set the zoom level accordingly
spatialObject.marker.openPopup(); spatialObject.marker.openPopup();
getAlertsHistory(deviceType, deviceId, new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime()); // getAlertsHistory(deviceType, deviceId, new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime());
spatialObject.drawPath(); spatialObject.drawPath();
if (speedGraphControl) { if (speedGraphControl) {
setTimeout(function () { setTimeout(function () {

@ -248,7 +248,6 @@ function setWithinAlert(leafletId) {
var data = { var data = {
'parseData': JSON.stringify({ 'parseData': JSON.stringify({
'geoFenceGeoJSON': selectedAreaGeoJson, 'geoFenceGeoJSON': selectedAreaGeoJson,
'executionPlanName': createExecutionPlanName(queryName, "WithIn", deviceId),
'areaName': areaName, 'areaName': areaName,
'deviceId': deviceId 'deviceId': deviceId
}), }),
@ -307,7 +306,6 @@ function setExitAlert(leafletId) {
var data = { var data = {
'parseData': JSON.stringify({ 'parseData': JSON.stringify({
'geoFenceGeoJSON': selectedAreaGeoJson, 'geoFenceGeoJSON': selectedAreaGeoJson,
'executionPlanName': createExecutionPlanName(queryName, "Exit", deviceId),
'areaName': areaName, 'areaName': areaName,
'deviceId': deviceId 'deviceId': deviceId
}), }),
@ -379,7 +377,6 @@ function setStationeryAlert(leafletId) {
var data = { var data = {
'parseData': JSON.stringify({ 'parseData': JSON.stringify({
'geoFenceGeoJSON': selectedProcessedAreaGeoJson, 'geoFenceGeoJSON': selectedProcessedAreaGeoJson,
'executionPlanName': createExecutionPlanName(queryName, "Stationery", deviceId),
'stationeryName': stationeryName, 'stationeryName': stationeryName,
'stationeryTime': time, 'stationeryTime': time,
'fluctuationRadius': fluctuationRadius 'fluctuationRadius': fluctuationRadius
@ -492,7 +489,6 @@ function setTrafficAlert(leafletId) {
var data = { var data = {
'parseData': JSON.stringify({ 'parseData': JSON.stringify({
'geoFenceGeoJSON': selectedProcessedAreaGeoJson, 'geoFenceGeoJSON': selectedProcessedAreaGeoJson,
'executionPlanName': createExecutionPlanName(queryName, "Traffic", deviceId),
'areaName': areaName 'areaName': areaName
}), }),
'executionPlan': 'Traffic', 'executionPlan': 'Traffic',
@ -634,21 +630,6 @@ function setProximityAlert() {
} }
} }
// TODO:this is not a remote call , move this to application.js
function createExecutionPlanName(queryName, id, deviceId) {
if (id == "WithIn") {
return 'Geo-ExecutionPlan-Within' + (queryName ? '_' + queryName : '') + "---" + (deviceId ? '_' + deviceId : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String)
} else if (id == "Exit") {
return 'Geo-ExecutionPlan-Exit' + (queryName ? '_' + queryName : '') + "---" + (deviceId ? '_' + deviceId : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String)
} else if (id == "Stationery") {
return 'Geo-ExecutionPlan-Stationery' + (queryName ? '_' + queryName : '') + "---" + (deviceId ? '_' + deviceId : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String)
} else if (id == "Traffic") {
return 'Geo-ExecutionPlan-Traffic' + (queryName ? '_' + queryName : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String)
}
}
// TODO:this is not a remote call , move this to application.js // TODO:this is not a remote call , move this to application.js
function closeAll() { function closeAll() {
$('.modal').modal('hide'); $('.modal').modal('hide');

@ -78,7 +78,7 @@ function initializeGeoLocation(geoFencingEnabled) {
geoPublicUri = geoCharts.data("geo-public-uri"); geoPublicUri = geoCharts.data("geo-public-uri");
webSocketURL = wsEndPoint + "iot.per.device.stream.geo.FusedSpatialEvent/1.0.0?" webSocketURL = wsEndPoint + "iot.per.device.stream.geo.FusedSpatialEvent/1.0.0?"
+ "deviceId=" + deviceId + "&deviceType=" + deviceType + "&websocketToken=" + wsToken; + "deviceId=" + deviceId + "&deviceType=" + deviceType + "&websocketToken=" + wsToken;
alertWebSocketURL = wsEndPoint + "iot.per.device.stream.geo.AlertsNotifications/1.0.0?" alertWebSocketURL = wsEndPoint + "iot.per.device.stream.geo.AlertNotifications/1.0.0?"
+ "deviceId=" + deviceId + "&deviceType=" + deviceType + "&websocketToken=" + wsToken; + "deviceId=" + deviceId + "&deviceType=" + deviceType + "&websocketToken=" + wsToken;
$("#proximity_alert").hide(); $("#proximity_alert").hide();
@ -214,7 +214,7 @@ SpatialObject.prototype.update = function (geoJSON) {
this.popupTemplate.find('#information').html(this.information); this.popupTemplate.find('#information').html(this.information);
this.popupTemplate.find('#speed').html(Math.round(this.speed * 10) / 10); this.popupTemplate.find('#speed').html(Math.round(this.speed * 10) / 10);
this.popupTemplate.find('#heading').html(angleToHeading(this.heading)); // this.popupTemplate.find('#heading').html(angleToHeading(this.heading));
this.marker.setPopupContent(this.popupTemplate.html()) this.marker.setPopupContent(this.popupTemplate.html())
}; };

@ -31,28 +31,14 @@
<div class="action-btn-container" id="location-action-bar"> <div class="action-btn-container" id="location-action-bar">
</div> </div>
</div> </div>
{{#if geoServicesEnabled}}
<br>
<br>
<br>
{{/if}}
<span id="geo-charts" data-ws-endpoint="{{wsEndpoint}}" data-ws-token="{{wsToken}}" data-geo-public-uri="{{@unit.publicUri}}" <span id="geo-charts" data-ws-endpoint="{{wsEndpoint}}" data-ws-token="{{wsToken}}" data-geo-public-uri="{{@unit.publicUri}}"
data-device-location="{{lastLocation}}"></span> data-device-location="{{lastLocation}}"></span>
<div class="map-wrapper"> <div class="map-wrapper">
{{#if geoServicesEnabled}} <div id="" style="height: 80vh;">
<div id="" style="height: 75vh;"> <div id="map"></div>
<div id="map"></div> </div>
<div id="ws-alerts">
<i id="ws-alert-stream" class="fw fw-circle text-muted"></i> Alerts Stream&nbsp;
<i id="ws-spatial-stream" class="fw fw-circle text-muted"></i> Spatial Stream
</div>
</div>
{{else}}
<div id="" style="height: 80vh;">
<div id="map"></div>
</div>
{{/if}}
<div id="predictionResults" style="background: darkgray;display: none;border-radius: 13px;height: 94%;padding: 0" <div id="predictionResults" style="background: darkgray;display: none;border-radius: 13px;height: 94%;padding: 0"
class="col-md-2 pull-right"> class="col-md-2 pull-right">
@ -693,13 +679,6 @@
<div class="popover-content"> <div class="popover-content">
<h6>Information</h6> <h6>Information</h6>
<p id="information" class="bg-primary" style="margin: 0px;padding: 0px;"></p> <p id="information" class="bg-primary" style="margin: 0px;padding: 0px;"></p>
{{#if geoServicesEnabled}}
<h6>Speed<span class="label label-primary pull-right"><span id="speed"></span> km/h</span></h6>
<h6>Heading<span id="heading" class="label label-primary pull-right"></span></h6>
<button type="button" class="btn btn-info btn-xs" onClick="toggleSpeedGraph();return false;">Speed Graph</button>
<button type="button" class="btn btn-info btn-xs" onClick="showRecentAlertsHistory();return false;">Recent History</button>
<button type="button" class="btn btn-info btn-xs" onClick="popupDateRange();">Full History</button>
{{/if}}
</div> </div>
</div> </div>
@ -891,10 +870,6 @@
{{js "js/typeahead.bundle.min.js" }} {{js "js/typeahead.bundle.min.js" }}
{{js "js/geo_remote.js" }} {{js "js/geo_remote.js" }}
{{js "js/app.js" }} {{js "js/app.js" }}
{{js "js/geo_exit_fence.js" }}
{{js "js/geo_within.js" }}
{{js "js/geo_stationary.js" }}
{{js "js/geo_speed.js" }}
{{!js "js/jquery/jquery-ui.min.js" }} {{!js "js/jquery/jquery-ui.min.js" }}
<!-- Leaflet plugins libries --> <!-- Leaflet plugins libries -->
@ -913,46 +888,12 @@
{{js "js/geo_fencing.js" }} {{js "js/geo_fencing.js" }}
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {
initializeGeoLocation({{geoServicesEnabled}}); initializeGeoLocation(false);
geoPublicUri = $("#geo-charts").data("geo-public-uri"); geoPublicUri = $("#geo-charts").data("geo-public-uri");
{{#if geoServicesEnabled}}
var geoToolsMenu = $('#location-action-bar');
var refreshMap = createGeoToolListItem('javascript:void(0);', 'Refresh', 'fw fw-refresh', geoToolsMenu, true);
refreshMap.addClass("geo-tools");
refreshMap.on("click", function(){enableRealTime({{geoServicesEnabled}});});
var viewAll = createGeoToolListItem('javascript:void(0);', 'View All', 'glyphicon glyphicon-th-list', geoToolsMenu, true);
viewAll.addClass("geo-tools");
viewAll.on("click", function(){viewAllFences();});
var realTime = createGeoToolListItem('javascript:void(0);', 'Return to Real Time View', 'fw fw-undo', geoToolsMenu, true);
realTime.addClass("geo-tools");
realTime.on("click", function(){enableRealTime({{geoServicesEnabled}});});
realTime.css("display", "none");
realTime.attr("id", "realTimeShow");
var exitAlert = createGeoToolListItem('#', 'Add Geofence Exit Alert', 'glyphicon glyphicon-log-out', geoToolsMenu,'Exit');
exitAlert.addClass("geo-alert");
exitAlert.on("click", function(){initializeExit();});
var withinAlert = createGeoToolListItem('#', 'Add Geofence Enter Alert', 'glyphicon glyphicon-log-in', geoToolsMenu,'Within');
withinAlert.addClass("geo-alert");
withinAlert.on("click", function(){initializeWithin();});
var stationaryAlert = createGeoToolListItem('#', 'Add Stationary Alert', 'glyphicon glyphicon-link', geoToolsMenu,'Stationery');
stationaryAlert.addClass("geo-alert");
stationaryAlert.on("click", function(){initStationaryAlert();});
var speedAlert = createGeoToolListItem('#', 'Set Speed Alert', 'glyphicon glyphicon-dashboard', geoToolsMenu,'Speed');
speedAlert.addClass("geo-alert");
speedAlert.on("click", function(){initializeSpeed();});
{{/if}}
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
$('#dateRangePopup.ui-dialog-content').dialog('close'); $('#dateRangePopup.ui-dialog-content').dialog('close');
}); });
}); });
</script> </script>
{{/zone}} {{/zone}}

@ -165,7 +165,9 @@ function setSpeedAlert() {
noty({text: message, type: 'error'}); noty({text: message, type: 'error'});
} else { } else {
data = { data = {
'parseData': JSON.stringify({'speedAlertValue': speedAlertValue, 'deviceId': deviceId}), // parseKey : parseValue pair , this key pair is replace with the key in the template file 'parseData': JSON.stringify({
'speedAlertValue': speedAlertValue,
'deviceId': deviceId}), // parseKey : parseValue pair , this key pair is replace with the key in the template file
'executionPlan': 'Speed', 'executionPlan': 'Speed',
'customName': null, 'customName': null,
'cepAction': 'edit', 'cepAction': 'edit',
@ -221,7 +223,6 @@ function setWithinAlert(leafletId) {
var data = { var data = {
'parseData': JSON.stringify({ 'parseData': JSON.stringify({
'geoFenceGeoJSON': selectedAreaGeoJson, 'geoFenceGeoJSON': selectedAreaGeoJson,
'executionPlanName': createExecutionPlanName(queryName, "WithIn", deviceId),
'areaName': areaName, 'areaName': areaName,
'deviceId': deviceId 'deviceId': deviceId
}), }),
@ -280,7 +281,6 @@ function setExitAlert(leafletId) {
var data = { var data = {
'parseData': JSON.stringify({ 'parseData': JSON.stringify({
'geoFenceGeoJSON': selectedAreaGeoJson, 'geoFenceGeoJSON': selectedAreaGeoJson,
'executionPlanName': createExecutionPlanName(queryName, "Exit", deviceId),
'areaName': areaName, 'areaName': areaName,
'deviceId': deviceId 'deviceId': deviceId
}), }),
@ -352,7 +352,6 @@ function setStationeryAlert(leafletId) {
var data = { var data = {
'parseData': JSON.stringify({ 'parseData': JSON.stringify({
'geoFenceGeoJSON': selectedProcessedAreaGeoJson, 'geoFenceGeoJSON': selectedProcessedAreaGeoJson,
'executionPlanName': createExecutionPlanName(queryName, "Stationery", deviceId),
'stationeryName': stationeryName, 'stationeryName': stationeryName,
'stationeryTime': time, 'stationeryTime': time,
'fluctuationRadius': fluctuationRadius 'fluctuationRadius': fluctuationRadius
@ -427,7 +426,6 @@ function setTrafficAlert(leafletId) {
var data = { var data = {
'parseData': JSON.stringify({ 'parseData': JSON.stringify({
'geoFenceGeoJSON': selectedProcessedAreaGeoJson, 'geoFenceGeoJSON': selectedProcessedAreaGeoJson,
'executionPlanName': createExecutionPlanName(queryName, "Traffic", deviceId),
'areaName': areaName 'areaName': areaName
}), }),
'executionPlan': 'Traffic', 'executionPlan': 'Traffic',
@ -569,21 +567,6 @@ function setProximityAlert() {
} }
} }
// TODO:this is not a remote call , move this to application.js
function createExecutionPlanName(queryName, id) {
if (id == "WithIn") {
return 'Geo-ExecutionPlan-Within' + (queryName ? '_' + queryName : '') + "---" + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String)
} else if (id == "Exit") {
return 'Geo-ExecutionPlan-Exit' + (queryName ? '_' + queryName : '') + "---" + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String)
} else if (id == "Stationery") {
return 'Geo-ExecutionPlan-Stationery' + (queryName ? '_' + queryName : '') + "---" + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String)
} else if (id == "Traffic") {
return 'Geo-ExecutionPlan-Traffic' + (queryName ? '_' + queryName : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String)
}
}
// TODO:this is not a remote call , move this to application.js // TODO:this is not a remote call , move this to application.js
function closeAll() { function closeAll() {
$('.modal').modal('hide'); $('.modal').modal('hide');

@ -68,25 +68,21 @@ function initializeOnAlertWebSocket() {
} }
function initializeGeoLocation(geoFencingEnabled) { function initializeGeoLocation(geoFencingEnabled) {
if (true) { var geoCharts = $("#geo-charts");
var geoCharts = $("#geo-charts"); var wsEndPoint = geoCharts.data("ws-endpoint");
var wsEndPoint = geoCharts.data("ws-endpoint"); wsToken = geoCharts.data("ws-token");
wsToken = geoCharts.data("ws-token"); geoPublicUri = geoCharts.data("geo-public-uri");
geoPublicUri = geoCharts.data("geo-public-uri"); geoPublicUri = geoCharts.data("geo-public-uri");
geoPublicUri = geoCharts.data("geo-public-uri"); webSocketURL = wsEndPoint + "iot.per.device.stream.geo.FusedSpatialEvent/1.0.0?" + "&websocketToken=" + wsToken;
webSocketURL = wsEndPoint + "iot.per.device.stream.geo.FusedSpatialEvent/1.0.0?" + "&websocketToken=" + wsToken; alertWebSocketURL = wsEndPoint + "iot.per.device.stream.geo.AlertNotifications/1.0.0?" + "&websocketToken=" + wsToken;
alertWebSocketURL = wsEndPoint + "iot.per.device.stream.geo.AlertsNotifications/1.0.0?" + "&websocketToken=" + wsToken; $("#proximity_alert").hide();
$("#proximity_alert").hide();
if (geoFencingEnabled) {
if (geoFencingEnabled) { disconnect();
disconnect(); initializeSpatialStreamWebSocket();
initializeSpatialStreamWebSocket(); initializeOnAlertWebSocket();
initializeOnAlertWebSocket();
}
initialLoad(geoFencingEnabled);
} else {
noty({text: 'Invalid Access! No device information provided to track!', type: 'error'});
} }
initialLoad(geoFencingEnabled);
} }
function disconnect(){ function disconnect(){

@ -23,7 +23,7 @@
<parent> <parent>
<artifactId>device-mgt</artifactId> <artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

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

@ -1,550 +0,0 @@
/*
* 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.common.geo.service.Alert;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.Valid;
import javax.validation.constraints.Size;
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.core.Response;
@SwaggerDefinition(
info = @Info(
version = "0.9.0",
title = "",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "geo_services"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/geo-services"),
})
}
),
tags = {
@Tag(name = "device_management", description = "")
}
)
@Scopes(
scopes = {
@Scope(
name = "View Analytics",
description = "",
key = "perm:geo-service:analytics-view",
permissions = {"/device-mgt/devices/owning-device/view-analytics"}
),
@Scope(
name = "Manage Alerts",
description = "",
key = "perm:geo-service:alerts-manage",
permissions = {"/device-mgt/devices/owning-device/manage-alerts"}
)
}
)
@Path("/geo-services")
@Api(value = "Geo Service",
description = "This carries all the resources related to the geo service functionalities.")
public interface GeoLocationBasedService {
/**
* Retrieve Analytics for the device type
*/
@GET
@Path("stats/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve Analytics for the device type",
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 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 getGeoDeviceStats(
@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,
@ApiParam(
name = "from",
value = "Get stats from what time",
required = true)
@QueryParam("from") long from,
@ApiParam(
name = "to",
value = "Get stats up to what time",
required = true)
@QueryParam("to") long to);
/**
* Get data to show device locations in a map
*/
@GET
@Path("stats/device-locations")
@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
*/
@POST
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Create Geo alerts for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@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 createGeoAlerts(
@ApiParam(
name = "alert",
value = "The alert object",
required = true)
@Valid Alert alert,
@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,
@ApiParam(
name = "alertType",
value = "The alert type, such as Within, Speed, Stationary",
required = true)
@PathParam("alertType") String alertType);
/**
* Update Geo alerts
*/
@PUT
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Update Geo alerts for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@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 updateGeoAlerts(
@ApiParam(
name = "alert",
value = "The alert object",
required = true)
@Valid Alert alert,
@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,
@ApiParam(
name = "alertType",
value = "The alert type, such as Within, Speed, Stationary",
required = true)
@PathParam("alertType") String alertType);
/**
* Retrieve Geo alerts
*/
@GET
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve Geo alerts for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage")
})
}
)
@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 getGeoAlerts(
@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,
@ApiParam(
name = "alertType",
value = "The alert type, such as Within, Speed, Stationary",
required = true)
@PathParam("alertType") String alertType);
/**
* Retrieve Geo alerts history
*/
@GET
@Path("alerts/history/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve Geo alerts history for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage")
})
}
)
@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 getGeoAlertsHistory(
@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,
@ApiParam(
name = "from",
value = "Get stats from what time",
required = true)
@QueryParam("from") long from,
@ApiParam(
name = "to",
value = "Get stats up to what time",
required = true)
@QueryParam("to") long to);
@DELETE
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "DELETE",
value = "Deletes Geo alerts for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@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 removeGeoAlerts(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "deviceType",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("deviceType") String deviceType,
@ApiParam(
name = "alertType",
value = "The alert type, such as Within, Speed, Stationary",
required = true)
@PathParam("alertType") String alertType,
@ApiParam(
name = "queryName",
value = "The query name.",
required = true)
@QueryParam("queryName") String queryName);
}

@ -1,565 +0,0 @@
/*
* 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.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.analytics.api.AnalyticsDataAPIUtil;
import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.dataservice.commons.SortType;
import org.wso2.carbon.analytics.datasource.commons.Record;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.context.CarbonContext;
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.*;
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;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
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.*;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The api for
*/
public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
private static Log log = LogFactory.getLog(GeoLocationBasedServiceImpl.class);
@Path("stats/{deviceType}/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoDeviceStats(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@QueryParam("from") long from, @QueryParam("to") long to) {
try {
if (!DeviceManagerUtil.isPublishLocationResponseEnabled()) {
return Response.status(Response.Status.BAD_REQUEST.getStatusCode())
.entity("Unable to retrive Geo Device stats. Geo Data publishing does not enabled.").build();
}
} catch (DeviceManagementException e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(e.getMessage()).build();
}
String tableName = "IOT_PER_DEVICE_STREAM_GEO_FUSEDSPATIALEVENT";
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = "id:" + deviceId + " AND type:" + deviceType;
if (from != 0 || to != 0) {
query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]";
}
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("timeStamp", SortType.ASC);
sortByFields.add(sortByField);
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername());
try {
String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser);
int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain);
AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI();
List<SearchResultEntry> searchResults = analyticsDataAPI.search(tenantId, tableName, query,
0,
100,
sortByFields);
List<Event> events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList<String>(),
searchResults);
return Response.ok().entity(events).build();
} catch (AnalyticsException | UserStoreException e) {
log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e);
throw DeviceMgtUtil.buildBadRequestException(
Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT);
}
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
}
}
@Path("stats/device-locations")
@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(null, 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")
@Produces("application/json")
public Response createGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@PathParam("alertType") String alertType) {
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId);
identifier.setType(deviceType);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.createGeoAlert(alert, identifier, alertType);
return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) {
String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (AlertAlreadyExistException e) {
String error = "A geo alert with this name already exists.";
log.error(error,e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
}
@Path("alerts/{alertType}")
@POST
@Consumes("application/json")
@Produces("application/json")
public Response createGeoAlertsForGeoClusters(Alert alert, @PathParam("alertType") String alertType) {
try {
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.createGeoAlert(alert, alertType);
return Response.ok().build();
} catch (GeoLocationBasedServiceException e) {
String error = "Error occurred while creating " + alertType + " alert";
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (AlertAlreadyExistException e) {
String error = "A geo alert with this name already exists.";
log.error(error,e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
}
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@PUT
@Consumes("application/json")
@Produces("application/json")
public Response updateGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@PathParam("alertType") String alertType) {
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId);
identifier.setType(deviceType);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.updateGeoAlert(alert, identifier, alertType);
return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) {
String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (AlertAlreadyExistException e) {
String error = "A geo alert with this name already exists.";
log.error(error,e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
}
@Path("alerts/{alertType}")
@PUT
@Consumes("application/json")
@Produces("application/json")
public Response updateGeoAlertsForGeoClusters(Alert alert, @PathParam("alertType") String alertType) {
try {
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.updateGeoAlert(alert, alertType);
return Response.ok().build();
} catch (GeoLocationBasedServiceException e) {
String error = "Error occurred while updating the geo alert for geo clusters";
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
} catch (AlertAlreadyExistException e) {
String error = "A geo alert with this name already exists.";
log.error(error,e);
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
}
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@DELETE
@Consumes("application/json")
@Produces("application/json")
public Response removeGeoAlerts(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@PathParam("alertType") String alertType,
@QueryParam("queryName") String queryName) {
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId);
identifier.setType(deviceType);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.removeGeoAlert(alertType, identifier, queryName);
return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) {
String error = "Error occurred while removing the geo alert for " + deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Path("alerts/{alertType}")
@DELETE
@Consumes("application/json")
@Produces("application/json")
public Response removeGeoAlertsForGeoClusters(@PathParam("alertType") String alertType, @QueryParam("queryName") String queryName) {
try {
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.removeGeoAlert(alertType, queryName);
return Response.ok().build();
} catch (GeoLocationBasedServiceException e) {
String error = "Error occurred while removing the geo alert for geo clusters";
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoAlerts(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@PathParam("alertType") String alertType) {
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId);
identifier.setType(deviceType);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) {
List<GeoFence> alerts = geoService.getWithinAlerts(identifier);
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) {
List<GeoFence> alerts = geoService.getExitAlerts(identifier);
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) {
String result = geoService.getSpeedAlerts(identifier);
return Response.ok().entity(result).build();
} else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) {
String result = geoService.getProximityAlerts(identifier);
return Response.ok().entity(result).build();
} else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) {
List<GeoFence> alerts = geoService.getStationaryAlerts(identifier);
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) {
List<GeoFence> alerts = geoService.getTrafficAlerts(identifier);
return Response.ok().entity(alerts).build();
}
return null;
} catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) {
String error = "Error occurred while getting the geo alerts for " + deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Path("alerts/{alertType}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoAlertsForGeoClusters(@PathParam("alertType") String alertType) {
try {
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) {
List<GeoFence> alerts = geoService.getWithinAlerts();
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) {
List<GeoFence> alerts = geoService.getExitAlerts();
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) {
String result = geoService.getSpeedAlerts();
return Response.ok().entity(result).build();
} else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) {
String result = geoService.getProximityAlerts();
return Response.ok().entity(result).build();
} else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) {
List<GeoFence> alerts = geoService.getStationaryAlerts();
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) {
List<GeoFence> alerts = geoService.getTrafficAlerts();
return Response.ok().entity(alerts).build();
}
return null;
} catch (GeoLocationBasedServiceException e) {
String error = "Error occurred while getting the geo alerts for " + alertType + " alert";
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Path("alerts/history/{deviceType}/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoAlertsHistory(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@QueryParam("from") long from, @QueryParam("to") long to) {
String tableName = "IOT_PER_DEVICE_STREAM_GEO_ALERTNOTIFICATIONS";
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = "id:" + deviceId + " AND type:" + deviceType;
if (from != 0 || to != 0) {
query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]";
}
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("timeStamp", SortType.ASC);
sortByFields.add(sortByField);
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername());
try {
String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser);
int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain);
AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI();
List<SearchResultEntry> searchResults = analyticsDataAPI.search(tenantId, tableName, query,
0,
100,
sortByFields);
List<Event> events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList<String>(),
searchResults);
return Response.ok().entity(events).build();
} catch (AnalyticsException | UserStoreException e) {
log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e);
throw DeviceMgtUtil.buildBadRequestException(
Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT);
}
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
}
}
@Path("alerts/history")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoAlertsHistoryForGeoClusters(@QueryParam("from") long from, @QueryParam("to") long to) {
String tableName = "IOT_PER_DEVICE_STREAM_GEO_ALERTNOTIFICATIONS";
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = "";
if (from != 0 || to != 0) {
query = "timeStamp : [" + fromDate + " TO " + toDate + "]";
}
try {
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("timeStamp", SortType.ASC);
sortByFields.add(sortByField);
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername());
try {
String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser);
int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain);
AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI();
List<SearchResultEntry> searchResults = analyticsDataAPI.search(tenantId, tableName, query,
0,
100,
sortByFields);
List<Event> events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList<String>(),
searchResults);
return Response.ok().entity(events).build();
} catch (AnalyticsException | UserStoreException e) {
log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e);
throw DeviceMgtUtil.buildBadRequestException(
Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT);
}
} catch (Exception e) {
log.error(e.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
}
}
private List<Event> getEventBeans(AnalyticsDataAPI analyticsDataAPI, int tenantId, String tableName,
List<String> columns,
List<SearchResultEntry> searchResults) throws AnalyticsException {
List<String> ids = getIds(searchResults);
List<String> requiredColumns = (columns == null || columns.isEmpty()) ? null : columns;
AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, requiredColumns, ids);
List<Record> records = AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response);
Map<String, Event> eventBeanMap = getEventBeanKeyedWithIds(records);
return getSortedEventBeans(eventBeanMap, searchResults);
}
private List<Event> getSortedEventBeans(Map<String, Event> eventBeanMap,
List<SearchResultEntry> searchResults) {
List<Event> sortedRecords = new ArrayList<>();
for (SearchResultEntry entry : searchResults) {
sortedRecords.add(eventBeanMap.get(entry.getId()));
}
return sortedRecords;
}
private Map<String, Event> getEventBeanKeyedWithIds(List<Record> records) {
Map<String, Event> eventBeanMap = new HashMap<>();
for (Record record : records) {
Event event = getEventBean(record);
eventBeanMap.put(event.getId(), event);
}
return eventBeanMap;
}
private List<String> getIds(List<SearchResultEntry> searchResults) {
List<String> ids = new ArrayList<>();
if (searchResults != null) {
for (SearchResultEntry resultEntry : searchResults) {
ids.add(resultEntry.getId());
}
}
return ids;
}
private static Event getEventBean(Record record) {
Event eventBean = new Event();
eventBean.setId(record.getId());
eventBean.setTableName(record.getTableName());
eventBean.setTimestamp(record.getTimestamp());
eventBean.setValues(record.getValues());
return eventBean;
}
}

@ -37,7 +37,6 @@
<ref bean="userManagementService"/> <ref bean="userManagementService"/>
<ref bean="userManagementAdminService"/> <ref bean="userManagementAdminService"/>
<ref bean="groupManagementService"/> <ref bean="groupManagementService"/>
<ref bean="geoService"/>
<ref bean="remoteSessionService"/> <ref bean="remoteSessionService"/>
<ref bean="groupManagementAdminService"/> <ref bean="groupManagementAdminService"/>
<ref bean="applicationManagementAdminService"/> <ref bean="applicationManagementAdminService"/>
@ -81,7 +80,6 @@
<bean id="roleManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.RoleManagementServiceImpl"/> <bean id="roleManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.RoleManagementServiceImpl"/>
<bean id="userManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.UserManagementServiceImpl"/> <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="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="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="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="applicationManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.ApplicationManagementAdminServiceImpl"/>

@ -1,78 +0,0 @@
/*
* 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.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
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.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.service.api.GeoLocationBasedService;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
public class GeoLocationBasedServiceImplTest {
private DeviceManagementProviderService deviceManagementProviderService;
private PrivilegedCarbonContext context;
private GeoLocationBasedService geoLocationBasedService;
@BeforeClass
public void init() {
deviceManagementProviderService = Mockito.mock(DeviceManagementProviderService.class);
geoLocationBasedService = new GeoLocationBasedServiceImpl();
context = Mockito.mock(PrivilegedCarbonContext.class);
Mockito.doReturn("admin").when(context).getUsername();
}
@Test(description = "This method tests the behaviour of getGeoDeviceLocations when there are no devices" +
"in the given map boundaries")
public void testGetGeoDeviceLocations1() throws DeviceManagementException {
Mockito.doReturn(new ArrayList<GeoCluster>()).when(deviceManagementProviderService)
.findGeoClusters(null, Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt());
Response response = geoLocationBasedService.getGeoDeviceLocations(0.4, 15, 75.6,
90.1, 6);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"getGeoDeviceLocations request failed with valid parameters");
}
@Test(description = "This method tests the behaviour of getGeoDeviceLocations when there are devices" +
"in the given map boundaries")
public void testGetGeoDeviceLocations2() throws DeviceManagementException {
List<GeoCluster> geoClusters = new ArrayList<>();
geoClusters.add(new GeoCluster(new GeoCoordinate(1.5, 80.7),
new GeoCoordinate(1.1, 79.5), new GeoCoordinate(1.9, 82.1), 3,
"tb32", "aegtew234", "android", "1234"));
geoClusters.add(new GeoCluster(new GeoCoordinate(10.2, 86.1),
new GeoCoordinate(9.8, 84.7), new GeoCoordinate(11.1, 88.1), 4,
"t1gd", "swerty12s", "android", "1234"));
Mockito.doReturn(geoClusters).when(deviceManagementProviderService)
.findGeoClusters(null,Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt());
Response response = geoLocationBasedService.getGeoDeviceLocations(0.4, 15, 75.6,
90.1, 6);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"getGeoDeviceLocations request failed with valid parameters");
}
}

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

@ -22,7 +22,7 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>email-sender</artifactId> <artifactId>email-sender</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

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

@ -22,13 +22,13 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>identity-extensions</artifactId> <artifactId>identity-extensions</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.oauth.extensions</artifactId> <artifactId>org.wso2.carbon.device.mgt.oauth.extensions</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - OAuth Extensions</name> <name>WSO2 Carbon - OAuth Extensions</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>

@ -21,7 +21,7 @@
<parent> <parent>
<artifactId>identity-extensions</artifactId> <artifactId>identity-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -22,7 +22,7 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>identity-extensions</artifactId> <artifactId>identity-extensions</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

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

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>policy-mgt</artifactId> <artifactId>policy-mgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.complex.policy.decision.point</artifactId> <artifactId>org.wso2.carbon.complex.policy.decision.point</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Policy Decision Point</name> <name>WSO2 Carbon - Policy Decision Point</name>
<description>WSO2 Carbon - Policy Decision Point</description> <description>WSO2 Carbon - Policy Decision Point</description>

@ -3,14 +3,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>policy-mgt</artifactId> <artifactId>policy-mgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.policy.decision.point</artifactId> <artifactId>org.wso2.carbon.policy.decision.point</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Policy Decision Point</name> <name>WSO2 Carbon - Policy Decision Point</name>
<description>WSO2 Carbon - Policy Decision Point</description> <description>WSO2 Carbon - Policy Decision Point</description>

@ -3,7 +3,7 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>policy-mgt</artifactId> <artifactId>policy-mgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
@ -11,7 +11,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.policy.information.point</artifactId> <artifactId>org.wso2.carbon.policy.information.point</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Policy Information Point</name> <name>WSO2 Carbon - Policy Information Point</name>
<description>WSO2 Carbon - Policy Information Point</description> <description>WSO2 Carbon - Policy Information Point</description>

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>policy-mgt</artifactId> <artifactId>policy-mgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.policy.mgt.common</artifactId> <artifactId>org.wso2.carbon.policy.mgt.common</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Policy Management Common</name> <name>WSO2 Carbon - Policy Management Common</name>
<description>WSO2 Carbon - Policy Management Common</description> <description>WSO2 Carbon - Policy Management Common</description>

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>policy-mgt</artifactId> <artifactId>policy-mgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.policy.mgt.core</artifactId> <artifactId>org.wso2.carbon.policy.mgt.core</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Policy Management Core</name> <name>WSO2 Carbon - Policy Management Core</name>
<description>WSO2 Carbon - Policy Management Core</description> <description>WSO2 Carbon - Policy Management Core</description>

@ -23,13 +23,13 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId> <artifactId>carbon-devicemgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>policy-mgt</artifactId> <artifactId>policy-mgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>WSO2 Carbon - Policy Management Component</name> <name>WSO2 Carbon - Policy Management Component</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>

@ -21,7 +21,7 @@
<parent> <parent>
<artifactId>carbon-devicemgt</artifactId> <artifactId>carbon-devicemgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -21,14 +21,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>webapp-authenticator-framework</artifactId> <artifactId>webapp-authenticator-framework</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.webapp.authenticator.framework</artifactId> <artifactId>org.wso2.carbon.webapp.authenticator.framework</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Web Application Authenticator Framework Bundle</name> <name>WSO2 Carbon - Web Application Authenticator Framework Bundle</name>
<description>WSO2 Carbon - Web Application Authenticator Framework Bundle</description> <description>WSO2 Carbon - Web Application Authenticator Framework Bundle</description>

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId> <artifactId>carbon-devicemgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>webapp-authenticator-framework</artifactId> <artifactId>webapp-authenticator-framework</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>WSO2 Carbon - Webapp Authenticator Framework</name> <name>WSO2 Carbon - Webapp Authenticator Framework</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>

@ -21,14 +21,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>apimgt-extensions-feature</artifactId> <artifactId>apimgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.application.extension.feature</artifactId> <artifactId>org.wso2.carbon.apimgt.application.extension.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<name>WSO2 Carbon - API Management Application Extension Feature</name> <name>WSO2 Carbon - API Management Application Extension Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>This feature contains an implementation of a api application registration, which takes care of subscription <description>This feature contains an implementation of a api application registration, which takes care of subscription

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>apimgt-extensions-feature</artifactId> <artifactId>apimgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.handler.server.feature</artifactId> <artifactId>org.wso2.carbon.apimgt.handler.server.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<name>WSO2 Carbon - Device Management - APIM handler Server Feature</name> <name>WSO2 Carbon - Device Management - APIM handler Server Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>This feature contains the handler for the api authentications <description>This feature contains the handler for the api authentications

@ -21,13 +21,13 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>apimgt-extensions-feature</artifactId> <artifactId>apimgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.client.feature</artifactId> <artifactId>org.wso2.carbon.apimgt.integration.client.feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>WSO2 Carbon - APIM Integration Client Feature</name> <name>WSO2 Carbon - APIM Integration Client Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>

@ -21,14 +21,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>apimgt-extensions-feature</artifactId> <artifactId>apimgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.webapp.publisher.feature</artifactId> <artifactId>org.wso2.carbon.apimgt.webapp.publisher.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<name>WSO2 Carbon - API Management Webapp Publisher Feature</name> <name>WSO2 Carbon - API Management Webapp Publisher Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>This feature contains an implementation of a Tomcat lifecycle listener, which takes care of publishing <description>This feature contains an implementation of a Tomcat lifecycle listener, which takes care of publishing

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId> <artifactId>carbon-devicemgt</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>apimgt-extensions-feature</artifactId> <artifactId>apimgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>WSO2 Carbon - API Management Extensions Feature</name> <name>WSO2 Carbon - API Management Extensions Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>

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

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

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt-feature</artifactId> <artifactId>certificate-mgt-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.server.feature</artifactId> <artifactId>org.wso2.carbon.certificate.mgt.server.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<name>WSO2 Carbon - Certificate Management Server Feature</name> <name>WSO2 Carbon - Certificate Management Server Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>This feature contains the core bundles required for back-end Certificate Management functionality <description>This feature contains the core bundles required for back-end Certificate Management functionality

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

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt-extensions-feature</artifactId> <artifactId>device-mgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.extensions.device.type.deployer.feature</artifactId> <artifactId>org.wso2.carbon.device.mgt.extensions.device.type.deployer.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<name>WSO2 Carbon - Device Type Deployer Feature</name> <name>WSO2 Carbon - Device Type Deployer Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>WSO2 Carbon - Device Type Deployer Feature</description> <description>WSO2 Carbon - Device Type Deployer Feature</description>

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt-extensions-feature</artifactId> <artifactId>device-mgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.fcm.feature</artifactId> <artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.fcm.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<name>WSO2 Carbon - FCM Based Push Notification Provider Feature</name> <name>WSO2 Carbon - FCM Based Push Notification Provider Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>WSO2 Carbon - MQTT Based Push Notification Provider Feature</description> <description>WSO2 Carbon - MQTT Based Push Notification Provider Feature</description>

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt-extensions-feature</artifactId> <artifactId>device-mgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.feature</artifactId> <artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<name>WSO2 Carbon - MQTT Based Push Notification Provider Feature</name> <name>WSO2 Carbon - MQTT Based Push Notification Provider Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>WSO2 Carbon - MQTT Based Push Notification Provider Feature</description> <description>WSO2 Carbon - MQTT Based Push Notification Provider Feature</description>

@ -22,14 +22,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt-extensions-feature</artifactId> <artifactId>device-mgt-extensions-feature</artifactId>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.feature</artifactId> <artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>3.1.31-SNAPSHOT</version> <version>3.1.33-SNAPSHOT</version>
<name>WSO2 Carbon - MQTT Based Push Notification Provider Feature</name> <name>WSO2 Carbon - MQTT Based Push Notification Provider Feature</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>WSO2 Carbon - MQTT Based Push Notification Provider Feature</description> <description>WSO2 Carbon - MQTT Based Push Notification Provider Feature</description>

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

Loading…
Cancel
Save