Merge branch 'application-mgt-new' into 'application-mgt-new'

Fix device-mgt operation log displaying issue

See merge request entgra/carbon-device-mgt!105
merge-requests/107/head^2
Inosh Perara 6 years ago
commit 06a8b3e1d8

@ -457,7 +457,7 @@ public interface DeviceManagementService {
String ifModifiedSince);
@PUT
@Path("/{type}/{id}/status")
@Path("/{type}/{id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",

@ -1,61 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.common.app.mgt;
public class DeviceApplicationMapping {
private String deviceIdentifier;
private String applicationUUID;
private String versionName;
private boolean installed;
public String getDeviceIdentifier() {
return deviceIdentifier;
}
public void setDeviceIdentifier(String deviceIdentifier) {
this.deviceIdentifier = deviceIdentifier;
}
public String getApplicationUUID() {
return applicationUUID;
}
public void setApplicationUUID(String applicationUUID) {
this.applicationUUID = applicationUUID;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public boolean isInstalled() {
return installed;
}
public void setInstalled(boolean installed) {
this.installed = installed;
}
}

@ -18,6 +18,7 @@
package org.wso2.carbon.device.mgt.core.app.mgt;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
@ -28,10 +29,10 @@ import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.app.mgt.DeviceApplicationMapping;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.app.mgt.config.AppManagementConfig;
import org.wso2.carbon.device.mgt.core.dao.ApplicationDAO;
import org.wso2.carbon.device.mgt.core.dao.ApplicationMappingDAO;
@ -193,96 +194,21 @@ public class ApplicationManagerProviderServiceImpl implements ApplicationManagem
}
}
private boolean contains(DeviceApplicationMapping deviceApp, List<Application> installedApps) {
boolean installed = false;
for (Application app : installedApps) {
if (app.getApplicationIdentifier().equals(deviceApp.getApplicationUUID()) && app.getVersion().equals(deviceApp.getVersionName())) {
installed = true;
break;
}
}
return installed;
}
@Override
public void updateApplicationListInstalledInDevice(
DeviceIdentifier deviceIdentifier,
List<Application> applications) throws ApplicationManagementException {
try {
DeviceManagementDAOFactory.beginTransaction();
List<DeviceApplicationMapping> installedDeviceApps = new ArrayList<>();
List<DeviceApplicationMapping> uninstalledDeviceApps = new ArrayList<>();
List<DeviceApplicationMapping> deviceApps = applicationMappingDAO.getApplicationsOfDevice(deviceIdentifier.getId(), false);
for (DeviceApplicationMapping deviceApp : deviceApps) {
if (contains(deviceApp, applications)) {
if (!deviceApp.isInstalled()) {
// device app mapping is recorded as not installed (i.e. install app operation has been sent to device)
// as the app list sent from the device contains this, app is now installed in the device
// so we can mark the device app mapping entry as installed.
deviceApp.setInstalled(true);
applicationMappingDAO.updateDeviceApplicationMapping(deviceApp);
}
} else {
if (deviceApp.isInstalled()) {
// we have a device-app mapping in the installed state in the db. but app is not installed in the device.
// which implies that a previously installed app has been uninstalled from the device. so we have to remove the device app mapping
applicationMappingDAO.removeApplicationMapping(deviceApp);
}
}
}
DeviceManagementDAOFactory.commitTransaction();
} catch (DeviceManagementDAOException | TransactionManagementException e) {
String msg = "Failed to update application list of the device " + deviceIdentifier;
throw new ApplicationManagementException(msg, e);
}
}
public void updateApplicationListInstalledInDeviceDep(
DeviceIdentifier deviceIdentifier,
List<Application> applications) throws ApplicationManagementException {
try {
DeviceManagementDAOFactory.beginTransaction();
List<DeviceApplicationMapping> installedDeviceApps = new ArrayList<>();
List<DeviceApplicationMapping> uninstalledDeviceApps = new ArrayList<>();
List<DeviceApplicationMapping> deviceApps = applicationMappingDAO.getApplicationsOfDevice(deviceIdentifier.getId(), false);
for (DeviceApplicationMapping deviceApp : deviceApps) {
if (contains(deviceApp, applications)) {
// if device app is pending mark device app as installed
if (!deviceApp.isInstalled()) {
deviceApp.setInstalled(true);
applicationMappingDAO.updateDeviceApplicationMapping(deviceApp);
}
} else {
if (deviceApp.isInstalled()) {
// this means we have a device-app mapping in the installed state in the db. but app is not installed in the device.
// which implies that a previously installed app has been uninstalled from the device. so we have to remove the device app mapping
applicationMappingDAO.removeApplicationMapping(deviceApp);
}
}
}
DeviceManagementDAOFactory.commitTransaction();
} catch (DeviceManagementDAOException | TransactionManagementException e) {
String msg = "Failed to update application list of the device " + deviceIdentifier;
throw new ApplicationManagementException(msg, e);
if (log.isDebugEnabled()) {
log.debug("Updating application list for device: " + deviceIdentifier.toString());
}
List<Application> installedAppList = getApplicationListForDevice(deviceIdentifier);
try {
Device device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider().getDevice(deviceIdentifier,
false);
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
if (log.isDebugEnabled()) {
log.debug("Device:" + device.getId() + ":identifier:" + deviceIdentifier.getId());
}
if (log.isDebugEnabled()) {
log.debug("num of apps installed:" + installedAppList.size());
log.debug("Number of apps installed:" + installedAppList.size());
}
List<Application> appsToAdd = new ArrayList<>();
List<Integer> appIdsToRemove = new ArrayList<>(installedAppList.size());
@ -303,6 +229,15 @@ public class ApplicationManagerProviderServiceImpl implements ApplicationManagem
List<Application> applicationsToMap = new ArrayList<>();
for (Application application : applications) {
// Adding N/A if application doesn't have a version. Also truncating the application version,
// if length of the version is greater than maximum allowed length.
if (application.getVersion() == null) {
application.setVersion("N/A");
} else if (application.getVersion().length() >
DeviceManagementConstants.OperationAttributes.APPLIST_VERSION_MAX_LENGTH) {
application.setVersion(StringUtils.abbreviate(application.getVersion(),
DeviceManagementConstants.OperationAttributes.APPLIST_VERSION_MAX_LENGTH));
}
if (!installedAppList.contains(application)) {
installedApp = applicationDAO.getApplication(application.getApplicationIdentifier(),
application.getVersion(), tenantId);
@ -335,24 +270,34 @@ public class ApplicationManagerProviderServiceImpl implements ApplicationManagem
if (log.isDebugEnabled()) {
log.debug("num of remove app Ids:" + appIdsToRemove.size());
}
DeviceManagementDAOFactory.commitTransaction();
} catch (DeviceManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();
throw new ApplicationManagementException("Error occurred saving application list to the device", e);
String msg = "Error occurred saving application list of the device " + deviceIdentifier.toString();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
throw new ApplicationManagementException("Error occurred while initializing transaction", e);
String msg = "Error occurred while initializing transaction for saving application list to the device "
+ deviceIdentifier.toString();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (DeviceManagementException e) {
throw new ApplicationManagementException("Error occurred obtaining the device object.", e);
String msg = "Error occurred obtaining the device object for device " + deviceIdentifier.toString();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (Exception e) {
String msg = "Exception occurred saving application list of the device " + deviceIdentifier.toString();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
@Override
public List<Application> getApplicationListForDevice(
DeviceIdentifier deviceId) throws ApplicationManagementException {
Device device = null;
public List<Application> getApplicationListForDevice(DeviceIdentifier deviceId)
throws ApplicationManagementException {
Device device;
try {
device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider().getDevice(deviceId,
false);
@ -363,18 +308,26 @@ public class ApplicationManagerProviderServiceImpl implements ApplicationManagem
if (device == null) {
if (log.isDebugEnabled()) {
log.debug("No device is found upon the device identifier '" + deviceId.getId() +
"' and type '" + deviceId.getType() + "'. Therefore returning null");
"' and type '" + deviceId.getType() + "'. Therefore returning empty app list");
}
return null;
return new ArrayList<>();
}
try {
DeviceManagementDAOFactory.openConnection();
return applicationDAO.getInstalledApplications(device.getId(), device.getEnrolmentInfo().getId());
} catch (DeviceManagementDAOException e) {
throw new ApplicationManagementException("Error occurred while fetching the Application List of '" +
deviceId.getType() + "' device carrying the identifier'" + deviceId.getId(), e);
String msg = "Error occurred while fetching the Application List of device " + deviceId.toString();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (SQLException e) {
throw new ApplicationManagementException("Error occurred while opening a connection to the data source", e);
String msg = "Error occurred while opening a connection to the data source to get application " +
"list of the device " + deviceId.toString();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (Exception e) {
String msg = "Exception occurred getting application list of the device " + deviceId.toString();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}

@ -19,7 +19,6 @@
package org.wso2.carbon.device.mgt.core.dao;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.app.mgt.DeviceApplicationMapping;
import java.util.List;
@ -35,12 +34,4 @@ public interface ApplicationMappingDAO {
void removeApplicationMapping(int deviceId, int enrolmentId, List<Integer> appIdList, int tenantId)
throws DeviceManagementDAOException;
int addDeviceApplicationMapping(DeviceApplicationMapping deviceApp) throws DeviceManagementDAOException;
void updateDeviceApplicationMapping(DeviceApplicationMapping deviceApp) throws DeviceManagementDAOException;
List<DeviceApplicationMapping> getApplicationsOfDevice(String deviceIdentifier, boolean installed) throws DeviceManagementDAOException;
void removeApplicationMapping(DeviceApplicationMapping deviceApp) throws DeviceManagementDAOException;
}

@ -21,23 +21,18 @@ package org.wso2.carbon.device.mgt.core.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.app.mgt.DeviceApplicationMapping;
import org.wso2.carbon.device.mgt.core.dao.ApplicationMappingDAO;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.ProfileOperation;
import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class ApplicationMappingDAOImpl implements ApplicationMappingDAO {
private static Log log = LogFactory.getLog(ApplicationMappingDAOImpl.class);
private static final Log log = LogFactory.getLog(ApplicationMappingDAOImpl.class);
@Override
public int addApplicationMapping(int deviceId, int applicationId,
@ -181,128 +176,6 @@ public class ApplicationMappingDAOImpl implements ApplicationMappingDAO {
}
}
@Override
public int addDeviceApplicationMapping(DeviceApplicationMapping deviceApp) throws
DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
int mappingId = -1;
try {
conn = getConnection();
String sql = "SELECT ID FROM DM_DEVICE_APPLICATION_MAPPING WHERE DEVICE_IDENTIFIER = ? AND " +
"APPLICATION_UUID = ? AND VERSION_NAME = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceApp.getDeviceIdentifier());
stmt.setString(2, deviceApp.getApplicationUUID());
stmt.setString(3, deviceApp.getVersionName());
rs = stmt.executeQuery();
if (!rs.next()) {
sql = "INSERT INTO DM_DEVICE_APPLICATION_MAPPING (DEVICE_IDENTIFIER, APPLICATION_UUID, VERSION_NAME," +
"INSTALLED) VALUES (?, ?, ?, ?)";
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt.setString(1, deviceApp.getDeviceIdentifier());
stmt.setString(2, deviceApp.getApplicationUUID());
stmt.setString(3, deviceApp.getVersionName());
stmt.setBoolean(4, deviceApp.isInstalled());
stmt.executeUpdate();
rs = stmt.getGeneratedKeys();
if (rs.next()) {
mappingId = rs.getInt(1);
}
return mappingId;
} else {
log.warn("Device[" + deviceApp.getDeviceIdentifier() + "] application[" + deviceApp.getApplicationUUID() + "] mapping already " +
"exists in the DB");
return -1;
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while adding device application mapping to DB", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
@Override
public void updateDeviceApplicationMapping(DeviceApplicationMapping deviceApp) throws
DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = getConnection();
String sql = "UPDATE DM_DEVICE_APPLICATION_MAPPING " +
"SET INSTALLED = ? " +
"WHERE DEVICE_IDENTIFIER = ? AND APPLICATION_UUID = ? AND VERSION_NAME = ?";
stmt = conn.prepareStatement(sql);
stmt.setBoolean(1, deviceApp.isInstalled());
stmt.setString(2, deviceApp.getDeviceIdentifier());
stmt.setString(3, deviceApp.getApplicationUUID());
stmt.setString(3, deviceApp.getVersionName());
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while adding device application mapping to DB", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
@Override
public List<DeviceApplicationMapping> getApplicationsOfDevice(String deviceIdentifier, boolean installed) throws
DeviceManagementDAOException {
List<DeviceApplicationMapping> applications = new ArrayList<>();
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
int mappingId = -1;
try {
conn = getConnection();
String sql = "SELECT APPLICATION_UUID, VERSION_NAME FROM DM_DEVICE_APPLICATION_MAPPING WHERE DEVICE_IDENTIFIER = ? AND INSTALLED = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier);
stmt.setBoolean(2, installed);
rs = stmt.executeQuery();
while (rs.next()) {
DeviceApplicationMapping deviceApp = new DeviceApplicationMapping();
deviceApp.setDeviceIdentifier(deviceIdentifier);
deviceApp.setApplicationUUID(rs.getString(1));
deviceApp.setVersionName(rs.getString(2));
deviceApp.setInstalled(true);
applications.add(deviceApp);
}
return applications;
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while adding device application mapping to DB", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
@Override
public void removeApplicationMapping(DeviceApplicationMapping deviceApp) throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
String sql = "DELETE FROM DM_DEVICE_APPLICATION_MAPPING WHERE DEVICE_IDENTIFIER = ? AND " +
"APPLICATION_UUID = ? AND VERSION_NAME = ?";
conn = this.getConnection();
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceApp.getDeviceIdentifier());
stmt.setString(2, deviceApp.getApplicationUUID());
stmt.setString(3, deviceApp.getVersionName());
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device application mapping", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, null);
}
}
private Connection getConnection() throws SQLException {
return DeviceManagementDAOFactory.getConnection();
}

@ -149,9 +149,6 @@ public class DeviceManagementServiceComponent {
@SuppressWarnings("unused")
protected void activate(ComponentContext componentContext) {
log.info("CALLING Crazy .............");
try {
if (log.isDebugEnabled()) {
log.debug("Initializing device management core bundle");

@ -37,11 +37,6 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.DeviceNotFoundException;
import org.wso2.carbon.device.mgt.common.app.mgt.DeviceApplicationMapping;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.core.dao.ApplicationMappingDAO;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceNotification;
import org.wso2.carbon.device.mgt.common.DevicePropertyNotification;
import org.wso2.carbon.device.mgt.common.DeviceTypeNotFoundException;
@ -74,6 +69,8 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
@ -92,6 +89,7 @@ import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsDAO;
import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsMgtDAOException;
import org.wso2.carbon.device.mgt.core.device.details.mgt.impl.DeviceInformationManagerImpl;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.core.geo.GeoCluster;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
@ -134,7 +132,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
private DeviceTypeDAO deviceTypeDAO;
private EnrollmentDAO enrollmentDAO;
private ApplicationDAO applicationDAO;
private ApplicationMappingDAO applicationMappingDAO;
private DeviceManagementPluginRepository pluginRepository;
public DeviceManagementProviderServiceImpl() {
@ -151,7 +148,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
this.applicationDAO = DeviceManagementDAOFactory.getApplicationDAO();
this.deviceTypeDAO = DeviceManagementDAOFactory.getDeviceTypeDAO();
this.enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO();
this.applicationMappingDAO = DeviceManagementDAOFactory.getApplicationMappingDAO();
}
@Override
@ -2582,20 +2578,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
pullNotificationSubscriber.execute(deviceIdentifier, operation);
}
public void addDeviceApplicationMapping(DeviceApplicationMapping deviceApp) throws DeviceManagementException {
try {
DeviceManagementDAOFactory.openConnection();
applicationMappingDAO.addDeviceApplicationMapping(deviceApp);
} catch (DeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while adding device application mapping for device "
+ deviceApp.getDeviceIdentifier() + " and application " + deviceApp.getApplicationUUID(), e);
} catch (SQLException e) {
throw new DeviceManagementException("Error occurred while opening a connection to the data source", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
/**
* Returns all the device-info including location of the given device.
*/

@ -24,10 +24,6 @@ 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;
from dataIn[id != "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information
insert into dataOut;
from withinStream[isWithin == true]
select id, owner, latitude, longitude,timeStamp, type, speed, heading, "NORMAL" as state, "" as information, false as notify
insert into dataOut;

@ -19,10 +19,6 @@ from dataIn[speed >= $speedAlertValue and id == "$deviceId" and owner == "$owner
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;
from dataIn[id != "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information
insert into dataOut;
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;

@ -468,7 +468,7 @@
-->
<FileUploadConfig>
<!--
The total file upllengthsize limit in MB
The total file upload size limit in MB
-->
<TotalFileSizeLimit>100</TotalFileSizeLimit>

@ -62,7 +62,7 @@ org.eclipse.osgi/defaultprofile/logfilename =
# requested.
org.eclipse.osgi/defaultprofile/logsynchronously = false
# Specify the length of the default profile implementation log buffer.
# Specify the size of the default profile implementation log buffer.
org.eclipse.osgi/defaultprofile/buffersize = 256
#### Monitoring settings

@ -47,7 +47,7 @@
<!-- fileEncoding Encoding to be used to read static resources -->
<!-- [platform default] -->
<!-- -->
<!-- input Input buflengthsize (in bytes) when reading -->
<!-- input Input buffer size (in bytes) when reading -->
<!-- resources to be served. [2048] -->
<!-- -->
<!-- listings Should directory listings be produced if there -->
@ -56,7 +56,7 @@
<!-- entries can be slow and may consume -->
<!-- significant proportions of server resources. -->
<!-- -->
<!-- output Output buflengthsize (in bytes) when writing -->
<!-- output Output buffer size (in bytes) when writing -->
<!-- resources to be served. [2048] -->
<!-- -->
<!-- readonly Is this context "read only", so HTTP -->
@ -67,7 +67,7 @@
<!-- contents. [null] -->
<!-- -->
<!-- sendfileSize If the connector used supports sendfile, this -->
<!-- represents the minimal flengthsize in KB for -->
<!-- represents the minimal file size in KB for -->
<!-- which sendfile will be used. Use a negative -->
<!-- value to always disable sendfile. [48] -->
<!-- -->

@ -45,18 +45,12 @@ if (!user) {
} else {
queryString = "?" + queryString;
}
<<<<<<< Updated upstream
var deviceType = request.getParameter("deviceType"); // need a better solution here
deviceTypeConfig = utility.getDeviceTypeConfig(deviceType);
if (deviceTypeConfig && deviceTypeConfig.deviceType.downloadAgentUri) {
=======
var type = request.getParameter("type"); // need a better solution here
deviceTypeConfig = utility.getDeviceTypeConfig(type);
if (deviceTypeConfig && deviceTypeConfig.type.downloadAgentUri) {
>>>>>>> Stashed changes
hearders = [{"name": constants["ACCEPT_IDENTIFIER"], "value": constants["APPLICATION_ZIP"]}];
sketchDownloadEndPoint = devicemgtProps["httpsURL"] + "/" + deviceTypeConfig.type.downloadAgentUri;
sketchDownloadEndPoint = devicemgtProps["httpsURL"] + "/" + deviceTypeConfig.deviceType.downloadAgentUri;
serviceInvokers.HttpClient.get(sketchDownloadEndPoint + queryString, function (responsePayload, responseHeaders) {
if (responseHeaders) {
for (var i = 0; i < responseHeaders.length; i++) {
@ -115,18 +109,18 @@ if (!user) {
} else if (uriMatcher.match("/{context}/api/devices/types")) {
result = deviceModule.listDeviceTypes();
} else if (uriMatcher.match("/{context}/api/devices/{type}/{deviceId}/remove")) {
} else if (uriMatcher.match("/{context}/api/devices/{deviceType}/{deviceId}/remove")) {
var elements = uriMatcher.elements();
var deviceId = elements.deviceId;
var type = elements.type;
result = deviceModule.removeDevice(type, deviceId);
var deviceType = elements.deviceType;
result = deviceModule.removeDevice(deviceType, deviceId);
} else if (uriMatcher.match("/{context}/api/devices/{type}/{deviceId}/update")) {
} else if (uriMatcher.match("/{context}/api/devices/{deviceType}/{deviceId}/update")) {
var elements = uriMatcher.elements();
var deviceId = elements.deviceId;
var type = elements.type;
var deviceType = elements.deviceType;
var deviceName = request.getParameter("name");
result = deviceModule.updateDevice(type, deviceId, deviceName);
result = deviceModule.updateDevice(deviceType, deviceId, deviceName);
} else if (uriMatcher.match("/{context}/api/devices")) {
var url = request.getParameter("url");
var draw = request.getParameter("draw");

@ -26,7 +26,7 @@ var serviceInvokers = require("/app/modules/oauth/token-protected-service-invoke
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
if (uriMatcher.match("/{context}/api/operation/paginate")) {
var type = request.getParameter("type");
var deviceType = request.getParameter("deviceType");
var deviceId = request.getParameter("deviceId");
var owner = request.getParameter("owner");
var index = request.getParameter("start");
@ -34,7 +34,7 @@ if (uriMatcher.match("/{context}/api/operation/paginate")) {
var search = request.getParameter("search[value]");
var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/devices/" + type + "/" + deviceId + "/operations?owner=" + owner + "&offset=" + index + "&limit=" + length;
"/devices/" + deviceType + "/" + deviceId + "/operations?owner=" + owner + "&offset=" + index + "&limit=" + length;
serviceInvokers.XMLHttp.get(
restAPIEndpoint,

@ -26,7 +26,7 @@ var serviceInvokers = require("/app/modules/oauth/token-protected-service-invoke
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
if (uriMatcher.match("/{context}/api/stats/paginate")) {
var type = request.getParameter("type");
var deviceType = request.getParameter("deviceType");
var deviceId = request.getParameter("deviceId");
var from = request.getParameter("from");
var to = request.getParameter("to");
@ -35,7 +35,7 @@ if (uriMatcher.match("/{context}/api/stats/paginate")) {
var keys = request.getParameter("attributes");
keys = JSON.parse(keys);
var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/events/"
+ type + "/" + deviceId + "?offset=" + index +"&limit=" + length + "&from="+ from + "&to=" + to;
+ deviceType + "/" + deviceId + "?offset=" + index +"&limit=" + length + "&from="+ from + "&to=" + to;
serviceInvokers.XMLHttp.get(
restAPIEndpoint,
function (restAPIResponse) {

@ -37,7 +37,7 @@
</a>
</li>
<li>
<a href="{{@app.context}}/device/{{type}}?id={{deviceId}}">
<a href="{{@app.context}}/device/{{deviceType}}?id={{deviceId}}">
{{deviceName}}
</a>
</li>

@ -39,7 +39,7 @@
</a>
</li>
<li>
<a href="{{@app.context}}/device/{{type}}/enroll">
<a href="{{@app.context}}/device/{{deviceType}}/enroll">
{{label}}
</a>
</li>
@ -50,7 +50,7 @@
<div class="wr-hidden-operations wr-advance-operations"></div>
<div class="col-md-12 wr-page-content">
<div>
{{! dynamically resolves device type-view unit according to type URI param }}
{{! dynamically resolves device type-view unit according to deviceType URI param }}
{{unit deviceTypeViewUnitName}}
</div>
</div>

@ -399,7 +399,7 @@
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<input id="edit-device-name" style="color:#3f3f3f;padding:5px" type="text"
value=""
placeholder="Type here" length="60">
placeholder="Type here" size="60">
</div>
<div class="modal-footer">
<div class="buttons">
@ -603,7 +603,7 @@
}
.select2-selection__choice {
font-length: medium;
font-size: medium;
}
</style>
{{/zone}}

@ -422,7 +422,7 @@
}
.select2-selection__choice {
font-length: medium;
font-size: medium;
}
</style>
{{/zone}}

@ -182,7 +182,7 @@
{{#each policyListToView}}
<tr data-type="selectable" data-id="{{id}}" data-status="{{status}}">
<td class="remove-padding icon-only content-fill viewEnabledIcon"
data-url="{{@app.context}}/policy/view?id={{id}}&type={{platform}}" data-id="{{id}}">
data-url="{{@app.context}}/policy/view?id={{id}}&deviceType={{platform}}" data-id="{{id}}">
<div class="thumbnail icon">
<img src="{{icon}}">
</div>
@ -239,7 +239,7 @@
</td>
<td class="text-right content-fill text-left-on-grid-view no-wrap tooltip-overflow-fix">
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/edit?id={{id}}&type={{platform}}"
<a href="{{@app.context}}/policy/edit?id={{id}}&deviceType={{platform}}"
data-id="{{id}}"
data-toggle="tooltip"
data-original-title="Edit"

@ -1,11 +1,11 @@
<div class="col-lg-12 margin-top-double">
<h1 class="grey ">{{type}}</h1>
<h1 class="grey ">{{deviceType}}</h1>
<hr>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-3 padding-top add-margin-bottom-5x">
<img src="{{@unit.publicUri}}/images/type.png" class="img-responsive">
<img src="{{@unit.publicUri}}/images/deviceType.png" class="img-responsive">
</div>
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 padding-top">
@ -127,7 +127,7 @@
<li class="padding-top-double"><span><h4 class="uppercase">Create Device</h4></span>
<code>curl -X POST {{httpsGateway}}/api/device-mgt/v1.0/device/agent/enroll -H 'accept: application/json'
-H 'authorization: Bearer %accessToken%'
-H 'content-type: application/json' -d '{ "name": "devicename", "type": "{{type}}",
-H 'content-type: application/json' -d '{ "name": "devicename", "type": "{{deviceType}}",
"description": "descritption", "deviceIdentifier": "1234", "enrolmentInfo":
{"ownership": "BYOD", "status": "ACTIVE"}
,"properties": [{"name": "propertyName","value": "propertyValue"}]}'</code>
@ -149,7 +149,7 @@
<i class="icon fw fw-error"></i><span></span>
</div>
<input aria-describedby="basic-addon1" type="text" id="deviceTypeName" style="display: none;"
data-error-msg="invalid device type name" class="form-control" value="{{type}}"/>
data-error-msg="invalid device type name" class="form-control" value="{{deviceType}}"/>
<br>
<label class="wr-input-label">Name</label>
<input aria-describedby="basic-addon1" type="text" id="deviceName"

@ -18,7 +18,7 @@
{{#defineZone "contentTitle"}}
<div class="row wr-device-board">
<div class="col-lg-12 wr-secondary-bar">
<span class="page-sub-title">{{@uriParams.type}} Agent Download</span>
<span class="page-sub-title">{{@uriParams.deviceType}} Agent Download</span>
</div>
</div>
{{/defineZone}}
@ -63,22 +63,22 @@
<div class="container">
<div class="col-lg-12 margin-top-double">
<h1 class="grey ">{{type.displayName}}</h1>
<h1 class="grey ">{{deviceType.displayName}}</h1>
<hr>
<p class="margin-bottom-double light-grey ">{{#defineZone "deviceTypeHeading"}}Connect your {{type.displayName}} device
<p class="margin-bottom-double light-grey ">{{#defineZone "deviceTypeHeading"}}Connect your {{deviceType.displayName}} device
to the WSO2 device cloud. {{/defineZone}}</p>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 padding-top">
<img src="{{@app.context}}{{type.image}}" class="img-responsive">
<img src="{{@app.context}}{{deviceType.image}}" class="img-responsive">
</div>
<div class="col-xs-12 col-sm-6 col-md-8 col-lg-8 padding-top">
{{#if type.ingredients}}
{{#if deviceType.ingredients}}
<h3 class="uppercase">Ingredients</h3>
<hr>
<p class="grey margin-top">Hardware Requirements </p>
<br>
<ul>
{{#itr type.ingredients}}
{{#itr deviceType.ingredients}}
<span class="fw-stack fw-lg margin-right">
<i class="fw fw-circle-outline fw-stack-2x"> </i>
<i class="fw fw-right-arrow fw-stack-1x"></i>
@ -89,22 +89,22 @@
<br>
{{/if}}
{{#if type.downloadBtnText}}
<a href="#" class="download-link btn-operations" data-devicetype="{{@uriParams.type}}" data-sketchtype="{{@uriParams.type}}"><i class="fw fw-download"></i> {{{type.downloadBtnText}}}</a>
{{#if deviceType.downloadBtnText}}
<a href="#" class="download-link btn-operations" data-devicetype="{{@uriParams.deviceType}}" data-sketchtype="{{@uriParams.deviceType}}"><i class="fw fw-download"></i> {{{deviceType.downloadBtnText}}}</a>
{{else}}
<a href="#" class="download-link btn-operations" data-devicetype="{{@uriParams.type}}" data-sketchtype="{{@uriParams.type}}"><i class="fw fw-download"></i> Download</a>
<a href="#" class="download-link btn-operations" data-devicetype="{{@uriParams.deviceType}}" data-sketchtype="{{@uriParams.deviceType}}"><i class="fw fw-download"></i> Download</a>
{{/if}}
<br/><br/>
</div>
{{#if type.prepareSteps}}
{{#if deviceType.prepareSteps}}
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-12 padding-double grey-bg ">
<h3 class="uppercase">Prepare</h3><hr>
<p class="grey margin-top">Get your device ready</p>
<br/>
<ul>
{{#itr type.prepareSteps}}
{{#itr deviceType.prepareSteps}}
<p class="padding-top-double"><span class="circle">0{{key}}</span> {{{value}}}</p>
{{/itr}}
</ul>
@ -112,26 +112,26 @@
</div>
{{/if}}
{{#if type.schematicDiagram}}
{{#if deviceType.schematicDiagram}}
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-12 padding-double">
<h3 class="uppercase">Schematic Diagram</h3><hr>
<p class="grey margin-top">Click on the image to zoom</p>
<center>
<a href="{{@app.context}}{{type.schematicDiagram}}" target="_blank">
<img src="{{@app.context}}{{type.schematicDiagram}}" class="img-responsive" style="max-width: 500px; max-height: 500px">
<a href="{{@app.context}}{{deviceType.schematicDiagram}}" target="_blank">
<img src="{{@app.context}}{{deviceType.schematicDiagram}}" class="img-responsive" style="max-width: 500px; max-height: 500px">
</a>
</center>
<br/>
</div>
{{/if}}
{{#if type.quickStartup}}
{{#if deviceType.quickStartup}}
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-12 padding-double">
<h3 class="uppercase">Connect (Quick Start)</h3><hr>
<p class="grey margin-top">Internet of Things Foundation Quickstart connection</p>
<br/>
<ul>
{{#itr type.quickStartup}}
{{#itr deviceType.quickStartup}}
<p class="padding-top-double"><span class="circle">0{{key}}</span> {{{value}}}</p>
{{/itr}}
</ul>
@ -139,17 +139,17 @@
</div>
{{/if}}
{{#if type.additionalHtml}}
{{{type.additionalHtml}}}
{{#if deviceType.additionalHtml}}
{{{deviceType.additionalHtml}}}
{{/if}}
</div>
{{#if type.showQRCode}}
{{#if deviceType.showQRCode}}
<div id="qr-code-modal" data-enrollment-url="{{type.enrollmentURL}}" class="hidden">
<div id="qr-code-modal" data-enrollment-url="{{deviceType.enrollmentURL}}" class="hidden">
<div class="content">
<div class="row">

@ -7,7 +7,7 @@
</span>
<span class="wr-list-desc">
<h3 class="wr-list-name">{{policy.policyName}}</h3>
<span class="wr-list-username">{{type}}</span>
<span class="wr-list-username">{{deviceType}}</span>
</span>
</div>
<div class="col-lg-6">
@ -37,7 +37,7 @@
</div>
<div class="col-lg-3">
<span class="list-group-item-actions">
<a href="{{appContext}}/policy/effective-policy?type={{type}}&id={{deviceId}}"
<a href="{{appContext}}/policy/effective-policy?type={{deviceType}}&id={{deviceId}}"
class="cu-btn-inner policy-view-link" data-id="{{id}}">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>

@ -23,7 +23,7 @@
@footer-height: 40px;
@footer-background: #000000;
@footer-color: #FFFFFF;
@footer-font-length: 12px;
@footer-font-size: 12px;
@footer-letter-spacing: 1px;
@footer-font-weight: 500;

@ -83,7 +83,7 @@
&:after {
content: " ";
display: block;
font-length: 0;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
@ -613,7 +613,7 @@ header .brand {
display: inline-block;
line-height: 1;
font-weight: 500;
font-length: 17px;
font-size: 17px;
margin: 0 0 0 5px;
color: @base-light-color;
padding: 6px 0 0 0;
@ -699,7 +699,7 @@ header .dropdown[aria-expanded=true], header .dropdown:hover {
height: @navbar-height;
padding: 0 8px;
line-height: @navbar-height;
font-length: 18px;
font-size: 18px;
background: @optional-color;
color: @base-light-color;
@ -737,7 +737,7 @@ header .dropdown[aria-expanded=true], header .dropdown:hover {
.navbar > .container .navbar-brand a,
.navbar > .container-fluid .navbar-brand a {
color: @base-light-color;
font-length: 16px;
font-size: 16px;
}
.navbar-default .navbar-collapse, .navbar-default .navbar-form {
@ -798,7 +798,7 @@ header .dropdown[aria-expanded=true], header .dropdown:hover {
}
.navbar-collapse.tiles ul.nav li a i {
font-length: 46px;
font-size: 46px;
display: block;
margin-bottom: 10px;
}
@ -913,7 +913,7 @@ ul.sidebar-messages > li {
.sidebar-nav > .sidebar-brand {
height: 65px;
font-length: 18px;
font-size: 18px;
line-height: 60px;
}
@ -999,7 +999,7 @@ footer > .container-fluid p {
}
footer .icon {
font-length: 21px;
font-size: 21px;
vertical-align: middle;
color: @footer-color;
}
@ -1054,7 +1054,7 @@ footer a {
width: 50px;
line-height: 1;
padding: 0 10px;
font-length: 12px;
font-size: 12px;
background: @base-dark-color;
color: @base-light-color;
}
@ -1221,7 +1221,7 @@ footer a {
.dropdown-menu.tiles li a .icon {
display: block;
font-length: 35px;
font-size: 35px;
margin: 3px 0 7px;
height: 35px;
}
@ -1229,7 +1229,7 @@ footer a {
.dropdown-menu.tiles li a .name {
display: block;
line-height: 14px;
font-length: 12px;
font-size: 12px;
height: 28px;
overflow: hidden;
}
@ -1395,7 +1395,7 @@ footer a {
.loading .loading-animation p {
color: @loading-color;
text-align: center;
font-length: 11px;
font-size: 11px;
margin-top: 4px;
text-transform: uppercase;
}
@ -1418,7 +1418,7 @@ footer a {
}
.input-group-btn .control-label {
font-length: 14px;
font-size: 14px;
padding-top: 0;
margin: 0 5px;
}
@ -1880,7 +1880,7 @@ table.dataTable thead .sorting_desc:after {
.dataTables_wrapper ul.sort-list li a.sorting_desc:before {
font-family: @font-icons;
margin-right: 10px;
font-length: 11px;
font-size: 11px;
.opacity(1);
}
@ -2097,7 +2097,7 @@ table.dataTable.dtr-inline.collapsed > tbody > tr {
.panel-default > .panel-heading {
background: transparent;
font-length: 24px;
font-size: 24px;
font-weight: 500;
border-bottom: 1px solid #e4e4e4;
padding-bottom: 10px;
@ -2184,7 +2184,7 @@ ul.tiles li a {
ul.tiles .icon {
display: block;
font-length: 15px;
font-size: 15px;
margin: 0 auto 5px;
}
@ -2286,7 +2286,7 @@ a.list-group-item:hover {
width: 20px;
text-align: center;
line-height: 20px;
font-length: 10px;
font-size: 10px;
display: inline-block;
margin-right: 10px;
}
@ -2363,11 +2363,11 @@ a.list-group-item:hover {
}
.asset-desc .asset-name {
font-length: 24px;
font-size: 24px;
margin-bottom: 0;
}
.asset-desc .asset-publisher {
font-length: 14px;
font-size: 14px;
margin-bottom: 20px;
}

@ -468,7 +468,7 @@
-->
<FileUploadConfig>
<!--
The total file upllengthsize limit in MB
The total file upload size limit in MB
-->
<TotalFileSizeLimit>100</TotalFileSizeLimit>

@ -1,19 +0,0 @@
mvn clean install -Dmaven.test.skip=true -f components/application-mgt/org.wso2.carbon.device.application.mgt.common/pom.xml
mvn clean install -Dmaven.test.skip=true -f components/application-mgt/org.wso2.carbon.device.application.mgt.core/pom.xml
mvn clean install -Dmaven.test.skip=true -f components/application-mgt/org.wso2.carbon.device.application.mgt.api/pom.xml
rm ~/projects/wso2/iot/testing/appm/310appm/wso2iot-3.1.0-SNAPSHOT/patches/patch0101/ -r
mkdir ~/projects/wso2/iot/testing/appm/310appm/wso2iot-3.1.0-SNAPSHOT/patches/patch0101
cp components/application-mgt/org.wso2.carbon.device.application.mgt.common/target/org.wso2.carbon.device.application.mgt.common-*.jar ~/projects/wso2/iot/testing/appm/310appm/wso2iot-3.1.0-SNAPSHOT/patches/patch0101/
cp components/application-mgt/org.wso2.carbon.device.application.mgt.core/target/org.wso2.carbon.device.application.mgt.core-*.jar ~/projects/wso2/iot/testing/appm/310appm/wso2iot-3.1.0-SNAPSHOT/patches/patch0101/
rm ~/projects/wso2/iot/testing/appm/310appm/wso2iot-3.1.0-SNAPSHOT/repository/deployment/server/webapps/api#application-mgt#v1.0.war
rm ~/projects/wso2/iot/testing/appm/310appm/wso2iot-3.1.0-SNAPSHOT/repository/deployment/server/webapps/api#application-mgt#v1.0/ -r
cp components/application-mgt/org.wso2.carbon.device.application.mgt.api/target/api#application-mgt#v1.0.war ~/projects/wso2/iot/testing/appm/310appm/wso2iot-3.1.0-SNAPSHOT/repository/deployment/server/webapps/

@ -24,6 +24,6 @@
</JndiLookupDefinition>
</DataSourceConfiguration>
</ManagementRepository>
<!-- Default plengthsize of GET certificates API -->
<!-- Default page size of GET certificates API -->
<DefaultPageSize>10</DefaultPageSize>
</CertificateConfigurations>

@ -556,20 +556,6 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_DETAIL (
)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `APPM_DEVICE_APPLICATION_MAPPING`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `DM_DEVICE_APPLICATION_MAPPING` (
`ID` INT AUTO_INCREMENT NOT NULL,
`DEVICE_IDENTIFIER` VARCHAR(255) NOT NULL,
`APPLICATION_UUID` VARCHAR(100) NOT NULL,
`VERSION_NAME` VARCHAR(100) NOT NULL,
`INSTALLED` BOOLEAN NOT NULL,
`SENT_AT` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (ID),
UNIQUE KEY `device_app_mapping` (`DEVICE_IDENTIFIER`, `APPLICATION_UUID`)
) ENGINE = InnoDB;
-- DASHBOARD RELATED VIEWS --
CREATE VIEW DEVICE_INFO_VIEW AS

@ -24,7 +24,7 @@
<title>Entgra IoT Server</title>
</head>
<body style="color: #666666; background-color:#cdcdcd; padding: 0px; margin: 0px;">
<div style="background-color:#cdcdcd; font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; padding: 20px 0px; margin: 0px;">
<div style="background-color:#cdcdcd; font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; padding: 20px 0px; margin: 0px;">
<div style="width: 86%; max-width: 650px; padding: 2%; background-color: #ffffff; margin: auto; border-radius: 14px;">
<div style="background-color: #49c8f5; line-height: 0px; border-top-left-radius: 10px; border-top-right-radius: 10px; padding: 0px 10px 0px 0px;">
<div style="display: inline-block; line-height: 0px;">
@ -33,23 +33,23 @@
</div>
</div>
<div style="background-color: #ffffff; line-height: 170%; color: #666666; padding: 20px 25px;">
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px 20px;">
<p style="font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px 20px;">
Hi $first-name,
</p>
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
<p style="font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
You have been invited to enrol devices with WSO2 IoT Server.
Click <a href="$base-url-https/devicemgt/device/enroll">here</a> to enrol the WSO2 IoT Server devices to begin.</p>
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
<p style="font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
Should you need assistance, please contact your administrator.
</p>
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 20px 0px 5px;">
<p style="font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 20px 0px 5px;">
Regards,
</p>
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
<p style="font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
WSO2 IoT Server Administrator
</p>
</div>

@ -1,355 +0,0 @@
2017-09-11 11:17:06,019 INFO o.a.j.u.JMeterUtils: Setting Locale to en_US
2017-09-11 11:17:06,029 INFO o.a.j.JMeter: Loading user properties from: /home/wso2/programs/jmeter/apache-jmeter-3.2/bin/user.properties
2017-09-11 11:17:06,030 INFO o.a.j.JMeter: Loading system properties from: /home/wso2/programs/jmeter/apache-jmeter-3.2/bin/system.properties
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: Copyright (c) 1998-2017 The Apache Software Foundation
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: Version 3.2 r1790748
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: java.version=1.8.0_131
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: java.vm.name=Java HotSpot(TM) 64-Bit Server VM
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: os.name=Linux
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: os.arch=amd64
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: os.version=4.10.0-33-generic
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: file.encoding=UTF-8
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: Max memory =536870912
2017-09-11 11:17:06,036 INFO o.a.j.JMeter: Available Processors =4
2017-09-11 11:17:06,040 INFO o.a.j.JMeter: Default Locale=English (United States)
2017-09-11 11:17:06,041 INFO o.a.j.JMeter: JMeter Locale=English (United States)
2017-09-11 11:17:06,041 INFO o.a.j.JMeter: JMeterHome=/home/wso2/programs/jmeter/apache-jmeter-3.2
2017-09-11 11:17:06,041 INFO o.a.j.JMeter: user.dir =/home/wso2/projects/wso2/iot/chathura/device-mgt/carbon-device-mgt
2017-09-11 11:17:06,041 INFO o.a.j.JMeter: PWD =/home/wso2/projects/wso2/iot/chathura/device-mgt/carbon-device-mgt
2017-09-11 11:17:06,041 INFO o.a.j.JMeter: IP: 127.0.1.1 Name: laptop1 FullName: laptop1
2017-09-11 11:17:06,302 INFO o.a.j.g.a.LookAndFeelCommand: Using look and feel: javax.swing.plaf.metal.MetalLookAndFeel [Metal, CrossPlatform]
2017-09-11 11:17:06,305 INFO o.a.j.JMeter: Loaded icon properties from org/apache/jmeter/images/icon.properties
2017-09-11 11:17:06,714 INFO o.a.j.e.u.CompoundVariable: Note: Function class names must contain the string: '.functions.'
2017-09-11 11:17:06,714 INFO o.a.j.e.u.CompoundVariable: Note: Function class names must not contain the string: '.gui.'
2017-09-11 11:17:07,644 INFO o.a.j.g.u.MenuFactory: Skipping org.apache.jmeter.assertions.BSFAssertion
2017-09-11 11:17:08,197 INFO o.a.j.g.u.MenuFactory: Skipping org.apache.jmeter.extractor.BSFPostProcessor
2017-09-11 11:17:08,237 INFO o.a.j.g.u.MenuFactory: Skipping org.apache.jmeter.modifiers.BSFPreProcessor
2017-09-11 11:17:08,271 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/html is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2017-09-11 11:17:08,271 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for application/xhtml+xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2017-09-11 11:17:08,271 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for application/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2017-09-11 11:17:08,272 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2017-09-11 11:17:08,272 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/vnd.wap.wml is org.apache.jmeter.protocol.http.parser.RegexpHTMLParser
2017-09-11 11:17:08,272 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/css is org.apache.jmeter.protocol.http.parser.CssParser
2017-09-11 11:17:08,616 INFO o.a.j.e.KeyToolUtils: keytool found at 'keytool'
2017-09-11 11:17:08,617 INFO o.a.j.p.h.p.ProxyControl: HTTP(S) Test Script Recorder SSL Proxy will use keys that support embedded 3rd party resources in file /home/wso2/programs/jmeter/apache-jmeter-3.2/bin/proxyserver.jks
2017-09-11 11:17:08,755 INFO o.a.j.g.u.MenuFactory: Skipping org.apache.jmeter.protocol.java.sampler.BSFSampler
2017-09-11 11:17:08,797 INFO o.a.j.s.FileServer: Default base='/home/wso2/projects/wso2/iot/chathura/device-mgt/carbon-device-mgt'
2017-09-11 11:17:08,876 INFO o.a.j.g.u.MenuFactory: Skipping org.apache.jmeter.protocol.mongodb.config.MongoSourceElement
2017-09-11 11:17:08,876 INFO o.a.j.g.u.MenuFactory: Skipping org.apache.jmeter.protocol.mongodb.sampler.MongoScriptSampler
2017-09-11 11:17:08,989 INFO o.a.j.g.u.MenuFactory: Skipping org.apache.jmeter.timers.BSFTimer
2017-09-11 11:17:09,023 INFO o.a.j.g.u.MenuFactory: Skipping org.apache.jmeter.visualizers.BSFListener
2017-09-11 11:17:09,177 INFO o.a.j.s.SampleResult: Note: Sample TimeStamps are START times
2017-09-11 11:17:09,178 INFO o.a.j.s.SampleResult: sampleresult.default.encoding is set to ISO-8859-1
2017-09-11 11:17:09,178 INFO o.a.j.s.SampleResult: sampleresult.useNanoTime=true
2017-09-11 11:17:09,178 INFO o.a.j.s.SampleResult: sampleresult.nanoThreadSleep=5000
2017-09-11 11:17:16,343 INFO o.a.j.g.a.Load: Loading file: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/ApplicationManagementAPI.jmx
2017-09-11 11:17:16,344 INFO o.a.j.s.FileServer: Set new base='/home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts'
2017-09-11 11:17:16,441 INFO o.a.j.s.SaveService: Testplan (JMX) version: 2.2. Testlog (JTL) version: 2.2
2017-09-11 11:17:16,456 INFO o.a.j.s.SaveService: Using SaveService properties file encoding UTF-8
2017-09-11 11:17:16,458 INFO o.a.j.s.SaveService: Using SaveService properties version 3.2
2017-09-11 11:17:16,461 INFO o.a.j.s.SaveService: Loading file: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/ApplicationManagementAPI.jmx
2017-09-11 11:17:16,491 INFO o.a.j.p.h.c.CookieManager: Settings: Delete null: true Check: true Allow variable: true Save: false Prefix: COOKIE_
2017-09-11 11:17:16,491 INFO o.a.j.u.NameUpdater: Upgrading class org.apache.jmeter.protocol.http.sampler.SoapSampler to org.apache.jmeter.config.ConfigTestElement
2017-09-11 11:17:16,491 INFO o.a.j.u.NameUpdater: Upgrading class org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui to org.apache.jmeter.config.gui.ObsoleteGui
2017-09-11 11:17:16,492 INFO o.a.j.u.NameUpdater: Upgrading class org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui to org.apache.jmeter.config.gui.ObsoleteGui
2017-09-11 11:17:16,503 INFO o.a.j.u.NameUpdater: Upgrading class org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui to org.apache.jmeter.config.gui.ObsoleteGui
2017-09-11 11:17:16,504 INFO o.a.j.u.NameUpdater: Upgrading class org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui to org.apache.jmeter.config.gui.ObsoleteGui
2017-09-11 11:17:17,087 INFO o.a.j.s.FileServer: Set new base='/home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts'
2017-09-11 11:18:36,250 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 11:18:36,251 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 11:18:36,251 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 11:18:36,266 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 11:18:36,378 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 11:18:36,378 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 11:18:36,378 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 11:18:36,378 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 11:18:36,418 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 11:18:36,418 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 11:18:36,424 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 11:18:36,464 INFO o.a.j.p.h.s.HTTPHCAbstractImpl: Local host = laptop1
2017-09-11 11:18:36,467 INFO o.a.j.p.h.s.HTTPHC4Impl: HTTP request retry count = 0
2017-09-11 11:18:36,521 INFO o.a.j.p.h.s.LazySchemeSocketFactory: Setting up HTTPS TrustAll Socket Factory
2017-09-11 11:18:36,525 INFO o.a.j.u.JsseSSLManager: Using default SSL protocol: TLS
2017-09-11 11:18:36,525 INFO o.a.j.u.JsseSSLManager: SSL session context: per-thread
2017-09-11 11:18:36,705 INFO o.a.j.u.SSLManager: JmeterKeyStore Location: type JKS
2017-09-11 11:18:36,705 INFO o.a.j.u.SSLManager: KeyStore created OK
2017-09-11 11:18:36,705 WARN o.a.j.u.SSLManager: Keystore file not found, loading empty keystore
2017-09-11 11:18:40,414 INFO o.a.j.s.FileServer: Stored: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/image.png
2017-09-11 11:18:40,915 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 11:18:40,916 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 11:18:40,916 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 11:18:40,917 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 11:41:19,241 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 11:41:19,242 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 11:41:19,247 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 11:41:19,371 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 11:41:19,371 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 11:41:19,371 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 11:41:19,372 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 11:41:19,403 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 11:41:19,403 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 11:41:19,408 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 11:41:25,273 INFO o.a.j.s.FileServer: Stored: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/image.png
2017-09-11 11:41:26,162 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 11:41:26,163 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 11:41:26,163 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 11:41:26,163 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 11:46:37,551 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 11:46:37,551 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 11:46:37,555 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 11:46:37,677 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 11:46:37,677 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 11:46:37,677 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 11:46:37,678 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 11:46:37,703 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 11:46:37,703 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 11:46:37,704 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 11:46:40,303 INFO o.a.j.s.FileServer: Stored: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/image.png
2017-09-11 11:46:41,107 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 11:46:41,107 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 11:46:41,108 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 11:46:41,108 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 11:49:20,026 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 11:49:20,026 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 11:49:20,029 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 11:49:20,136 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 11:49:20,136 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 11:49:20,137 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 11:49:20,137 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 11:49:20,165 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 11:49:20,166 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 11:49:20,167 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 11:51:01,448 INFO o.a.j.s.FileServer: Stored: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/image.png
2017-09-11 11:53:08,769 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 11:53:08,769 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 11:53:08,770 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 11:53:08,771 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 11:57:09,607 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 11:57:09,609 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 11:57:09,613 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 11:57:09,736 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 11:57:09,736 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 11:57:09,736 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 11:57:09,736 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 11:57:09,761 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 11:57:09,761 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 11:57:09,762 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 11:57:19,936 INFO o.a.j.s.FileServer: Stored: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/image.png
2017-09-11 11:57:20,432 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 11:57:20,432 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 11:57:20,433 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 11:57:20,433 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 11:59:08,030 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 11:59:08,031 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 11:59:08,031 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 11:59:08,164 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 11:59:08,164 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 11:59:08,164 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 11:59:08,164 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 11:59:08,178 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 11:59:08,178 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 11:59:08,179 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 11:59:10,634 INFO o.a.j.s.FileServer: Stored: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/image.png
2017-09-11 11:59:10,712 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 11:59:10,712 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 11:59:10,713 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 11:59:10,713 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 12:01:02,024 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 12:01:02,024 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 12:01:02,026 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 12:01:02,140 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 12:01:02,140 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 12:01:02,140 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 12:01:02,140 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 12:01:02,156 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 12:01:02,156 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 12:01:02,156 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 12:01:04,482 INFO o.a.j.s.FileServer: Stored: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/image.png
2017-09-11 12:01:04,525 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 12:01:04,525 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 12:01:04,526 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 12:01:04,526 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 12:03:39,895 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 12:03:39,896 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 12:03:39,897 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 12:03:40,008 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 12:03:40,008 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 12:03:40,008 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 12:03:40,008 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 12:03:40,018 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 12:03:40,018 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 12:03:40,020 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 12:03:42,312 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 12:03:42,312 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 12:03:42,312 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 12:03:42,312 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 12:07:13,180 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 12:07:13,180 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 12:07:13,181 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 12:07:13,321 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 12:07:13,321 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 12:07:13,321 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 12:07:13,321 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 12:07:13,332 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 12:07:13,332 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 12:07:13,332 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 12:07:15,869 INFO o.a.j.s.FileServer: Stored: /home/wso2/projects/wso2/iot/chathura/product-iots/product-iots/modules/integration/tests-integration/src/test/resources/jmeter-scripts/image.png
2017-09-11 12:07:15,910 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 12:07:15,910 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 12:07:15,910 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 12:07:15,911 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 14:23:30,019 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 14:23:30,024 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 14:23:30,032 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 14:23:30,562 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 14:23:30,562 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 14:23:30,562 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 14:23:30,562 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 14:23:30,589 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 14:23:30,589 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 14:23:30,590 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 14:23:33,752 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 14:23:33,753 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 14:23:33,753 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 14:23:33,754 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 14:24:35,246 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 14:24:35,246 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 14:24:35,247 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 14:24:35,361 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 14:24:35,361 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 14:24:35,362 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 14:24:35,362 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 14:24:35,380 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 14:24:35,380 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 14:24:35,381 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 14:24:37,901 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 14:24:37,901 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 14:24:37,901 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 14:24:37,901 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 14:26:47,180 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 14:26:47,180 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 14:26:47,182 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 14:26:47,302 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 14:26:47,302 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 14:26:47,302 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 14:26:47,303 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 14:26:47,316 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 14:26:47,316 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 14:26:47,317 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 14:26:49,859 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 14:26:49,859 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 14:26:49,859 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 14:26:49,859 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 14:30:37,092 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 14:30:37,092 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 14:30:37,093 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 14:30:37,207 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Application Management - Super Tenant
2017-09-11 14:30:37,207 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Application Management - Super Tenant.
2017-09-11 14:30:37,207 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 14:30:37,207 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 14:30:37,220 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 14:30:37,220 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 14:30:37,221 INFO o.a.j.t.JMeterThread: Thread started: Application Management - Super Tenant 1-1
2017-09-11 14:30:39,716 INFO o.a.j.t.JMeterThread: Thread is done: Application Management - Super Tenant 1-1
2017-09-11 14:30:39,716 INFO o.a.j.t.JMeterThread: Thread finished: Application Management - Super Tenant 1-1
2017-09-11 14:30:39,717 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 14:30:39,717 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 14:43:17,010 INFO o.a.j.s.FileServer: Set new base='/home/wso2/projects/wso2/iot/testing/appm/scripts'
2017-09-11 14:51:18,349 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 14:51:18,351 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 14:51:18,352 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 14:51:18,479 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : TokenGen
2017-09-11 14:51:18,479 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group TokenGen.
2017-09-11 14:51:18,479 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 14:51:18,480 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 14:51:18,485 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 14:51:18,485 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 14:51:18,485 INFO o.a.j.t.JMeterThread: Thread started: TokenGen 1-1
2017-09-11 14:51:20,803 INFO o.a.j.t.JMeterThread: Thread is done: TokenGen 1-1
2017-09-11 14:51:20,803 INFO o.a.j.t.JMeterThread: Thread finished: TokenGen 1-1
2017-09-11 14:51:20,804 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 14:51:20,804 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 14:53:40,651 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 14:53:40,652 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 14:53:40,654 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 14:53:40,790 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : UnitTests
2017-09-11 14:53:40,790 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group UnitTests.
2017-09-11 14:53:40,790 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 14:53:40,791 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 14:53:40,791 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 14:53:40,791 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 14:53:40,791 INFO o.a.j.t.JMeterThread: Thread started: UnitTests 1-1
2017-09-11 14:53:41,079 INFO o.a.j.t.JMeterThread: Thread is done: UnitTests 1-1
2017-09-11 14:53:41,079 INFO o.a.j.t.JMeterThread: Thread finished: UnitTests 1-1
2017-09-11 14:53:41,081 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 14:53:41,081 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 14:54:28,012 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 14:54:28,012 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 14:54:28,013 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 14:54:28,123 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : UnitTests
2017-09-11 14:54:28,123 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group UnitTests.
2017-09-11 14:54:28,124 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 14:54:28,124 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 14:54:28,128 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 14:54:28,128 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 14:54:28,128 INFO o.a.j.t.JMeterThread: Thread started: UnitTests 1-1
2017-09-11 14:54:28,385 INFO o.a.j.t.JMeterThread: Thread is done: UnitTests 1-1
2017-09-11 14:54:28,385 INFO o.a.j.t.JMeterThread: Thread finished: UnitTests 1-1
2017-09-11 14:54:28,385 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 14:54:28,385 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 14:56:06,132 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 14:56:06,132 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 14:56:06,133 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 14:56:06,249 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : UnitTests
2017-09-11 14:56:06,249 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group UnitTests.
2017-09-11 14:56:06,249 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 14:56:06,249 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 14:56:06,254 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 14:56:06,254 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 14:56:06,254 INFO o.a.j.t.JMeterThread: Thread started: UnitTests 1-1
2017-09-11 14:56:06,349 INFO o.a.j.t.JMeterThread: Thread is done: UnitTests 1-1
2017-09-11 14:56:06,349 INFO o.a.j.t.JMeterThread: Thread finished: UnitTests 1-1
2017-09-11 14:56:06,350 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 14:56:06,350 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 15:05:21,190 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 15:05:21,191 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 15:05:21,192 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 15:05:21,335 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : UnitTests
2017-09-11 15:05:21,335 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group UnitTests.
2017-09-11 15:05:21,336 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 15:05:21,336 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 15:05:21,336 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 15:05:21,336 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 15:05:21,337 INFO o.a.j.t.JMeterThread: Thread started: UnitTests 1-1
2017-09-11 15:05:21,454 INFO o.a.j.t.JMeterThread: Thread is done: UnitTests 1-1
2017-09-11 15:05:21,454 INFO o.a.j.t.JMeterThread: Thread finished: UnitTests 1-1
2017-09-11 15:05:21,454 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 15:05:21,454 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 15:06:50,344 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 15:06:50,345 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 15:06:50,346 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 15:06:50,484 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : UnitTests
2017-09-11 15:06:50,485 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group UnitTests.
2017-09-11 15:06:50,485 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 15:06:50,485 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 15:06:50,485 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 15:06:50,485 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 15:06:50,486 INFO o.a.j.t.JMeterThread: Thread started: UnitTests 1-1
2017-09-11 15:06:50,581 INFO o.a.j.t.JMeterThread: Thread is done: UnitTests 1-1
2017-09-11 15:06:50,581 INFO o.a.j.t.JMeterThread: Thread finished: UnitTests 1-1
2017-09-11 15:06:50,581 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 15:06:50,581 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
2017-09-11 15:07:27,565 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-09-11 15:07:27,567 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-09-11 15:07:27,567 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, *local*)
2017-09-11 15:07:27,681 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : UnitTests
2017-09-11 15:07:27,681 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group UnitTests.
2017-09-11 15:07:27,681 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-09-11 15:07:27,681 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 perThread=1000.0 delayedStart=false
2017-09-11 15:07:27,681 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-09-11 15:07:27,681 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-09-11 15:07:27,684 INFO o.a.j.t.JMeterThread: Thread started: UnitTests 1-1
2017-09-11 15:07:27,759 INFO o.a.j.t.JMeterThread: Thread is done: UnitTests 1-1
2017-09-11 15:07:27,759 INFO o.a.j.t.JMeterThread: Thread finished: UnitTests 1-1
2017-09-11 15:07:27,760 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-09-11 15:07:27,760 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, *local*)
Loading…
Cancel
Save