added default UI for realtime,batch, device view and type view

4.x.x
ayyoob 8 years ago
parent 2a89a2fb23
commit 3df2912a6a

@ -22,7 +22,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.policy.mgt.Profile;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext; import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy; import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
@ -101,7 +100,7 @@ public class MQTTNotificationStrategy implements NotificationStrategy {
for (ProfileOperation profileOperation : profileOperations) { for (ProfileOperation profileOperation : profileOperations) {
Map<String, String> dynamicProperties = new HashMap<>(); Map<String, String> dynamicProperties = new HashMap<>();
String topic = tenantDomain + "/" String topic = tenantDomain + "/"
+ deviceType + "/" + deviceId + "/" + profileOperation.getType() + deviceType + "/" + deviceId + "/operation/" + profileOperation.getType()
.toString().toLowerCase() + "/" + profileOperation.getCode().toLowerCase(); .toString().toLowerCase() + "/" + profileOperation.getCode().toLowerCase();
dynamicProperties.put("topic", topic); dynamicProperties.put("topic", topic);
MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(mqttAdapterName, dynamicProperties, MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(mqttAdapterName, dynamicProperties,
@ -111,11 +110,11 @@ public class MQTTNotificationStrategy implements NotificationStrategy {
} else { } else {
Map<String, String> dynamicProperties = new HashMap<>(); Map<String, String> dynamicProperties = new HashMap<>();
String topic = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true) + "/" String topic = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true) + "/"
+ ctx.getDeviceId().getType() + "/" + ctx.getDeviceId().getId() + "/" + operation.getType() + ctx.getDeviceId().getType() + "/" + ctx.getDeviceId().getId() + "/operation/"
.toString().toLowerCase() + "/" + operation.getCode(); + operation.getType().toString().toLowerCase() + "/" + operation.getCode();
dynamicProperties.put("topic", topic); dynamicProperties.put("topic", topic);
if (operation.getPayLoad() == null) { if (operation.getPayLoad() == null) {
operation.setPayLoad(""); operation.setPayLoad(operation.getCode());
} }
MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(mqttAdapterName, dynamicProperties, MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(mqttAdapterName, dynamicProperties,
operation.getPayLoad()); operation.getPayLoad());

@ -42,7 +42,6 @@ public class EventRecords extends BasePaginatedResult {
public void setList(List<Record> records) { public void setList(List<Record> records) {
this.records = records; this.records = records;
setCount(records.size());
} }
@Override @Override

@ -41,7 +41,7 @@ import javax.ws.rs.core.Response;
extensions = { extensions = {
@Extension(properties = { @Extension(properties = {
@ExtensionProperty(name = "name", value = "DeviceEventManagement"), @ExtensionProperty(name = "name", value = "DeviceEventManagement"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/device-types/events"), @ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/events"),
}) })
} }
), ),
@ -65,7 +65,7 @@ import javax.ws.rs.core.Response;
) )
} }
) )
@Path("/device-types/events") @Path("/events")
@Api(value = "Device Event Management", description = "This API corresponds to all tasks related to device " + @Api(value = "Device Event Management", description = "This API corresponds to all tasks related to device " +
"event management") "event management")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)

@ -2,6 +2,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.axis2.AxisFault; import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options; import org.apache.axis2.client.Options;
import org.apache.axis2.client.Stub;
import org.apache.axis2.transport.http.HTTPConstants; import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.Header;
@ -82,7 +83,7 @@ import java.util.UUID;
* This is used for simple analytics purpose, to create streams and receiver dynamically and a common endpoint * This is used for simple analytics purpose, to create streams and receiver dynamically and a common endpoint
* to retrieve data. * to retrieve data.
*/ */
@Path("/device-types/events") @Path("/events")
public class DeviceEventManagementServiceImpl implements DeviceEventManagementService { public class DeviceEventManagementServiceImpl implements DeviceEventManagementService {
private static final Log log = LogFactory.getLog(DeviceEventManagementServiceImpl.class); private static final Log log = LogFactory.getLog(DeviceEventManagementServiceImpl.class);
@ -138,6 +139,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
@Override @Override
public Response getDeviceTypeEventDefinition(@PathParam("type") String deviceType) { public Response getDeviceTypeEventDefinition(@PathParam("type") String deviceType) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
EventStreamAdminServiceStub eventStreamAdminServiceStub = null;
try { try {
if (deviceType == null || if (deviceType == null ||
!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) {
@ -146,11 +148,10 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
return Response.status(Response.Status.BAD_REQUEST).build(); return Response.status(Response.Status.BAD_REQUEST).build();
} }
String streamName = getStreamDefinition(deviceType, tenantDomain); String streamName = getStreamDefinition(deviceType, tenantDomain);
EventStreamAdminServiceStub eventStreamAdminServiceStub = getEventStreamAdminServiceStub(); eventStreamAdminServiceStub = getEventStreamAdminServiceStub();
EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto( EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto(
streamName + ":" + DEFAULT_STREAM_VERSION); streamName + ":" + DEFAULT_STREAM_VERSION);
if (eventStreamDefinitionDto == null) { if (eventStreamDefinitionDto == null) {
eventStreamAdminServiceStub.cleanup();
return Response.status(Response.Status.NO_CONTENT).build(); return Response.status(Response.Status.NO_CONTENT).build();
} }
EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData(); EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData();
@ -161,7 +162,6 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
, AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase()))); , AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase())));
} }
eventAttributeList.setList(attributes); eventAttributeList.setList(attributes);
eventStreamAdminServiceStub.cleanup();
return Response.ok().entity(eventAttributeList).build(); return Response.ok().entity(eventAttributeList).build();
} catch (AxisFault e) { } catch (AxisFault e) {
log.error("failed to retrieve event definitions for tenantDomain:" + tenantDomain, e); log.error("failed to retrieve event definitions for tenantDomain:" + tenantDomain, e);
@ -178,6 +178,8 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
} catch (DeviceManagementException e) { } catch (DeviceManagementException e) {
log.error("Failed to access device management service, tenantDomain: " + tenantDomain, e); log.error("Failed to access device management service, tenantDomain: " + tenantDomain, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} finally {
cleanup(eventStreamAdminServiceStub);
} }
} }
@ -250,6 +252,12 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
public Response deleteDeviceTypeEventDefinitions(@PathParam("type") String deviceType) { public Response deleteDeviceTypeEventDefinitions(@PathParam("type") String deviceType) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
boolean superTenantMode = false; boolean superTenantMode = false;
EventReceiverAdminServiceStub eventReceiverAdminServiceStub = null;
EventPublisherAdminServiceStub eventPublisherAdminServiceStub = null;
EventStreamAdminServiceStub eventStreamAdminServiceStub = null;
EventReceiverAdminServiceStub tenantBasedEventReceiverAdminServiceStub = null;
EventStreamAdminServiceStub tenantBasedEventStreamAdminServiceStub = null;
try { try {
if (deviceType == null || if (deviceType == null ||
!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) {
@ -260,43 +268,35 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
String eventReceiverName = getReceiverName(deviceType, tenantDomain); String eventReceiverName = getReceiverName(deviceType, tenantDomain);
String eventPublisherName = deviceType.trim().toLowerCase() + "_websocket_publisher"; String eventPublisherName = deviceType.trim().toLowerCase() + "_websocket_publisher";
String streamName = getStreamDefinition(deviceType, tenantDomain); String streamName = getStreamDefinition(deviceType, tenantDomain);
EventStreamAdminServiceStub eventStreamAdminServiceStub = getEventStreamAdminServiceStub(); eventStreamAdminServiceStub = getEventStreamAdminServiceStub();
if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamName + ":" + DEFAULT_STREAM_VERSION) == null) { if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamName + ":" + DEFAULT_STREAM_VERSION) == null) {
return Response.status(Response.Status.NO_CONTENT).build(); return Response.status(Response.Status.NO_CONTENT).build();
} }
eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, DEFAULT_STREAM_VERSION);
EventReceiverAdminServiceCallbackHandler eventReceiverAdminServiceCallbackHandler = EventReceiverAdminServiceCallbackHandler eventReceiverAdminServiceCallbackHandler =
new EventReceiverAdminServiceCallbackHandler() {}; new EventReceiverAdminServiceCallbackHandler() {};
EventPublisherAdminServiceCallbackHandler eventPublisherAdminServiceCallbackHandler = EventPublisherAdminServiceCallbackHandler eventPublisherAdminServiceCallbackHandler =
new EventPublisherAdminServiceCallbackHandler() {}; new EventPublisherAdminServiceCallbackHandler() {};
EventReceiverAdminServiceStub eventReceiverAdminServiceStub = getEventReceiverAdminServiceStub(); eventReceiverAdminServiceStub = getEventReceiverAdminServiceStub();
eventReceiverAdminServiceStub.startundeployActiveEventReceiverConfiguration(eventReceiverName eventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration(eventReceiverName
, eventReceiverAdminServiceCallbackHandler); , eventReceiverAdminServiceCallbackHandler);
eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, DEFAULT_STREAM_VERSION); eventPublisherAdminServiceStub = getEventPublisherAdminServiceStub();
eventPublisherAdminServiceStub.startundeployInactiveEventPublisherConfiguration(eventPublisherName
EventPublisherAdminServiceStub eventPublisherAdminServiceStub = getEventPublisherAdminServiceStub();
eventPublisherAdminServiceStub.startundeployActiveEventPublisherConfiguration(eventPublisherName
, eventPublisherAdminServiceCallbackHandler); , eventPublisherAdminServiceCallbackHandler);
eventStreamAdminServiceStub.cleanup();
eventPublisherAdminServiceStub.cleanup();
eventReceiverAdminServiceStub.cleanup();
superTenantMode = true; superTenantMode = true;
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
eventReceiverAdminServiceStub = getEventReceiverAdminServiceStub(); tenantBasedEventReceiverAdminServiceStub = getEventReceiverAdminServiceStub();
eventStreamAdminServiceStub = getEventStreamAdminServiceStub(); tenantBasedEventStreamAdminServiceStub = getEventStreamAdminServiceStub();
eventReceiverAdminServiceStub.startundeployActiveEventReceiverConfiguration(eventReceiverName
, eventReceiverAdminServiceCallbackHandler);
eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, DEFAULT_STREAM_VERSION); eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, DEFAULT_STREAM_VERSION);
eventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration(eventReceiverName
, eventReceiverAdminServiceCallbackHandler);
eventReceiverAdminServiceStub.cleanup();
eventStreamAdminServiceStub.cleanup();
} }
return Response.ok().build(); return Response.ok().build();
} catch (AxisFault e) { } catch (AxisFault e) {
@ -318,6 +318,11 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
if (superTenantMode) { if (superTenantMode) {
PrivilegedCarbonContext.endTenantFlow(); PrivilegedCarbonContext.endTenantFlow();
} }
cleanup(eventStreamAdminServiceStub);
cleanup(eventPublisherAdminServiceStub);
cleanup(eventReceiverAdminServiceStub);
cleanup(eventReceiverAdminServiceStub);
cleanup(eventStreamAdminServiceStub);
} }
} }
@ -367,6 +372,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
, String requestedTenantDomain, String deviceType) , String requestedTenantDomain, String deviceType)
throws RemoteException, UserStoreException, JWTClientException { throws RemoteException, UserStoreException, JWTClientException {
EventReceiverAdminServiceStub receiverAdminServiceStub = getEventReceiverAdminServiceStub(); EventReceiverAdminServiceStub receiverAdminServiceStub = getEventReceiverAdminServiceStub();
try {
String adapterType = "oauth-mqtt"; String adapterType = "oauth-mqtt";
BasicInputAdapterPropertyDto basicInputAdapterPropertyDtos[]; BasicInputAdapterPropertyDto basicInputAdapterPropertyDtos[];
if (transportType == TransportType.MQTT) { if (transportType == TransportType.MQTT) {
@ -385,18 +391,21 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
receiverAdminServiceStub.deployJsonEventReceiverConfiguration(eventRecieverName, streamNameWithVersion receiverAdminServiceStub.deployJsonEventReceiverConfiguration(eventRecieverName, streamNameWithVersion
, adapterType, null, basicInputAdapterPropertyDtos, false); , adapterType, null, basicInputAdapterPropertyDtos, false);
} }
receiverAdminServiceStub.cleanup(); } finally {
cleanup(receiverAdminServiceStub);
}
} }
private void publishStreamDefinitons(String streamName, String version, String deviceType private void publishStreamDefinitons(String streamName, String version, String deviceType
, EventAttributeList eventAttributes) , EventAttributeList eventAttributes)
throws RemoteException, UserStoreException, JWTClientException { throws RemoteException, UserStoreException, JWTClientException {
EventStreamAdminServiceStub eventStreamAdminServiceStub = getEventStreamAdminServiceStub(); EventStreamAdminServiceStub eventStreamAdminServiceStub = getEventStreamAdminServiceStub();
try {
EventStreamDefinitionDto eventStreamDefinitionDto = new EventStreamDefinitionDto(); EventStreamDefinitionDto eventStreamDefinitionDto = new EventStreamDefinitionDto();
eventStreamDefinitionDto.setName(streamName); eventStreamDefinitionDto.setName(streamName);
eventStreamDefinitionDto.setVersion(version); eventStreamDefinitionDto.setVersion(version);
EventStreamAttributeDto eventStreamAttributeDtos[] = EventStreamAttributeDto eventStreamAttributeDtos[] =
new EventStreamAttributeDto[eventAttributes.getList().size()]; new EventStreamAttributeDto[eventAttributes.getList().size() + 1];
int i = 0; int i = 0;
for (Attribute attribute : eventAttributes.getList()) { for (Attribute attribute : eventAttributes.getList()) {
EventStreamAttributeDto eventStreamAttributeDto = new EventStreamAttributeDto(); EventStreamAttributeDto eventStreamAttributeDto = new EventStreamAttributeDto();
@ -405,12 +414,11 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
eventStreamAttributeDtos[i] = eventStreamAttributeDto; eventStreamAttributeDtos[i] = eventStreamAttributeDto;
i++; i++;
} }
EventStreamAttributeDto metaData[] = new EventStreamAttributeDto[1];
EventStreamAttributeDto eventStreamAttributeDto = new EventStreamAttributeDto(); EventStreamAttributeDto eventStreamAttributeDto = new EventStreamAttributeDto();
eventStreamAttributeDto.setAttributeName("deviceId"); eventStreamAttributeDto.setAttributeName("deviceId");
eventStreamAttributeDto.setAttributeType(AttributeType.STRING.toString()); eventStreamAttributeDto.setAttributeType(AttributeType.STRING.toString());
metaData[0] = eventStreamAttributeDto; eventStreamAttributeDtos[i] = eventStreamAttributeDto;
eventStreamDefinitionDto.setMetaData(metaData);
eventStreamDefinitionDto.setPayloadData(eventStreamAttributeDtos); eventStreamDefinitionDto.setPayloadData(eventStreamAttributeDtos);
String streamId = streamName + ":" + version; String streamId = streamName + ":" + version;
if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamId) != null) { if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamId) != null) {
@ -418,14 +426,17 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
} else { } else {
eventStreamAdminServiceStub.addEventStreamDefinitionAsDto(eventStreamDefinitionDto); eventStreamAdminServiceStub.addEventStreamDefinitionAsDto(eventStreamDefinitionDto);
} }
eventStreamAdminServiceStub.cleanup(); } finally {
cleanup(eventStreamAdminServiceStub);
}
} }
private void publishEventStore(String streamName, String version, EventAttributeList eventAttributes) private void publishEventStore(String streamName, String version, EventAttributeList eventAttributes)
throws RemoteException, UserStoreException, JWTClientException, throws RemoteException, UserStoreException, JWTClientException,
EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException { EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException {
EventStreamPersistenceAdminServiceStub eventStreamAdminServiceStub = EventStreamPersistenceAdminServiceStub eventStreamPersistenceAdminServiceStub =
getEventStreamPersistenceAdminServiceStub(); getEventStreamPersistenceAdminServiceStub();
try {
AnalyticsTable analyticsTable = new AnalyticsTable(); AnalyticsTable analyticsTable = new AnalyticsTable();
analyticsTable.setRecordStoreName(DEFAULT_EVENT_STORE_NAME); analyticsTable.setRecordStoreName(DEFAULT_EVENT_STORE_NAME);
analyticsTable.setStreamVersion(version); analyticsTable.setStreamVersion(version);
@ -447,7 +458,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
i++; i++;
} }
AnalyticsTableRecord analyticsTableRecord = new AnalyticsTableRecord(); AnalyticsTableRecord analyticsTableRecord = new AnalyticsTableRecord();
analyticsTableRecord.setColumnName("meta_deviceId"); analyticsTableRecord.setColumnName("deviceId");
analyticsTableRecord.setColumnType(AttributeType.STRING.toString().toUpperCase()); analyticsTableRecord.setColumnType(AttributeType.STRING.toString().toUpperCase());
analyticsTableRecord.setFacet(false); analyticsTableRecord.setFacet(false);
analyticsTableRecord.setIndexed(true); analyticsTableRecord.setIndexed(true);
@ -456,20 +467,25 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
analyticsTableRecord.setScoreParam(false); analyticsTableRecord.setScoreParam(false);
analyticsTableRecords[i] = analyticsTableRecord; analyticsTableRecords[i] = analyticsTableRecord;
analyticsTable.setAnalyticsTableRecords(analyticsTableRecords); analyticsTable.setAnalyticsTableRecords(analyticsTableRecords);
eventStreamAdminServiceStub.addAnalyticsTable(analyticsTable); eventStreamPersistenceAdminServiceStub.addAnalyticsTable(analyticsTable);
eventStreamAdminServiceStub.cleanup(); } finally {
cleanup(eventStreamPersistenceAdminServiceStub);
}
} }
private void publishWebsocketPublisherDefinition(String streamNameWithVersion, String deviceType) private void publishWebsocketPublisherDefinition(String streamNameWithVersion, String deviceType)
throws RemoteException, UserStoreException, JWTClientException { throws RemoteException, UserStoreException, JWTClientException {
EventPublisherAdminServiceStub eventPublisherAdminServiceStub = getEventPublisherAdminServiceStub(); EventPublisherAdminServiceStub eventPublisherAdminServiceStub = getEventPublisherAdminServiceStub();
try {
String eventPublisherName = deviceType.trim().toLowerCase() + "_websocket_publisher"; String eventPublisherName = deviceType.trim().toLowerCase() + "_websocket_publisher";
if (eventPublisherAdminServiceStub.getActiveEventPublisherConfiguration(eventPublisherName) == null) { if (eventPublisherAdminServiceStub.getActiveEventPublisherConfiguration(eventPublisherName) == null) {
eventPublisherAdminServiceStub.deployJsonEventPublisherConfiguration(eventPublisherName eventPublisherAdminServiceStub.deployJsonEventPublisherConfiguration(eventPublisherName
, streamNameWithVersion, DEFAULT_WEBSOCKET_PUBLISHER_ADAPTER_TYPE, null, null , streamNameWithVersion, DEFAULT_WEBSOCKET_PUBLISHER_ADAPTER_TYPE, null, null
, null, false); , null, false);
} }
eventPublisherAdminServiceStub.cleanup(); } finally {
cleanup(eventPublisherAdminServiceStub);
}
} }
private EventStreamAdminServiceStub getEventStreamAdminServiceStub() private EventStreamAdminServiceStub getEventStreamAdminServiceStub()
@ -695,15 +711,16 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
, int offset, int limit) throws AnalyticsException { , int offset, int limit) throws AnalyticsException {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI(); AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI();
EventRecords eventRecords = new EventRecords();
int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query); int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query);
if (eventCount == 0) { if (eventCount == 0) {
return null; eventRecords.setCount(0);
} }
List<SearchResultEntry> resultEntries = analyticsDataAPI.search(tenantId, tableName, query, offset, limit, List<SearchResultEntry> resultEntries = analyticsDataAPI.search(tenantId, tableName, query, offset, limit,
sortByFields); sortByFields);
List<String> recordIds = getRecordIds(resultEntries); List<String> recordIds = getRecordIds(resultEntries);
AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds); AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
EventRecords eventRecords = new EventRecords(); eventRecords.setCount(eventCount);
eventRecords.setList(AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response)); eventRecords.setList(AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response));
return eventRecords; return eventRecords;
} }
@ -716,4 +733,14 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe
return ids; return ids;
} }
private void cleanup(Stub stub) {
if (stub != null) {
try {
stub.cleanup();
} catch (AxisFault axisFault) {
// do nothing
}
}
}
} }

@ -736,6 +736,13 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
log.error(errorMessage); log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build(); return Response.status(Response.Status.BAD_REQUEST).build();
} }
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device identifier list is empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
Operation.Type operationType = operationRequest.getOperation().getType();
if (operationType == Operation.Type.COMMAND || operationType == Operation.Type.CONFIG) {
DeviceIdentifier deviceIdentifier; DeviceIdentifier deviceIdentifier;
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>(); List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
for (String deviceId : operationRequest.getDeviceIdentifiers()) { for (String deviceId : operationRequest.getDeviceIdentifiers()) {
@ -747,6 +754,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
Activity activity = DeviceMgtAPIUtils.getDeviceManagementService().addOperation(type Activity activity = DeviceMgtAPIUtils.getDeviceManagementService().addOperation(type
, operationRequest.getOperation(), deviceIdentifiers); , operationRequest.getOperation(), deviceIdentifiers);
return Response.status(Response.Status.CREATED).entity(activity).build(); return Response.status(Response.Status.CREATED).entity(activity).build();
} else {
String message = "Only Command and Config operation is supported through this api";
return Response.status(Response.Status.NOT_ACCEPTABLE).entity(message).build();
}
} catch (InvalidDeviceException e) { } catch (InvalidDeviceException e) {
String errorMessage = "Invalid Device Identifiers found."; String errorMessage = "Invalid Device Identifiers found.";
log.error(errorMessage, e); log.error(errorMessage, e);
@ -757,6 +769,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
log.error(errorMessage, e); log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} }
} }
@ -764,6 +781,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@Path("/{type}/{id}/pending/operations") @Path("/{type}/{id}/pending/operations")
public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) { public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) {
try { try {
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device identifier list is empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
List<? extends Operation> operations = DeviceMgtAPIUtils.getDeviceManagementService().getPendingOperations( List<? extends Operation> operations = DeviceMgtAPIUtils.getDeviceManagementService().getPendingOperations(
new DeviceIdentifier(deviceId, type)); new DeviceIdentifier(deviceId, type));
OperationList operationsList = new OperationList(); OperationList operationsList = new OperationList();
@ -775,6 +797,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
log.error(errorMessage, e); log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} }
} }
@ -782,6 +809,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@Path("/{type}/{id}/last-pending/operation") @Path("/{type}/{id}/last-pending/operation")
public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) { public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) {
try { try {
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device identifier list is empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
Operation operation = DeviceMgtAPIUtils.getDeviceManagementService().getNextPendingOperation( Operation operation = DeviceMgtAPIUtils.getDeviceManagementService().getNextPendingOperation(
new DeviceIdentifier(deviceId, type)); new DeviceIdentifier(deviceId, type));
return Response.status(Response.Status.OK).entity(operation).build(); return Response.status(Response.Status.OK).entity(operation).build();
@ -790,6 +822,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
log.error(errorMessage, e); log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} }
} }
@ -797,6 +834,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@Path("/{type}/{id}/operations") @Path("/{type}/{id}/operations")
public Response updateOperation(@PathParam("type") String type, @PathParam("id") String deviceId, @Valid Operation operation) { public Response updateOperation(@PathParam("type") String type, @PathParam("id") String deviceId, @Valid Operation operation) {
try { try {
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device identifier list is empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
if (operation == null) { if (operation == null) {
String errorMessage = "Device identifier list is empty"; String errorMessage = "Device identifier list is empty";
log.error(errorMessage); log.error(errorMessage);
@ -810,6 +852,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
log.error(errorMessage, e); log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} catch (DeviceManagementException e) {
String errorMessage = "Issue in retrieving deivce management service instance";
log.error(errorMessage, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
} }
} }
@ -824,6 +871,11 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
} }
try { try {
if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) {
String errorMessage = "Device identifier list is empty";
log.error(errorMessage);
return Response.status(Response.Status.BAD_REQUEST).build();
}
List<? extends Operation> operations = DeviceMgtAPIUtils.getDeviceManagementService() List<? extends Operation> operations = DeviceMgtAPIUtils.getDeviceManagementService()
.getOperationsByDeviceAndStatus(new DeviceIdentifier(deviceId, type), status); .getOperationsByDeviceAndStatus(new DeviceIdentifier(deviceId, type), status);
OperationList operationsList = new OperationList(); OperationList operationsList = new OperationList();

@ -0,0 +1,77 @@
<%
/*
* Copyright (c) 2015, 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.
*/
var uri = request.getRequestURI();
var uriMatcher = new URIMatcher(String(uri));
var log = new Log("api/stats-api.jag");
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
if (uriMatcher.match("/{context}/api/stats/paginate")) {
var deviceType = request.getParameter("deviceType");
var deviceId = request.getParameter("deviceId");
var from = request.getParameter("from");
var to = request.getParameter("to");
var index = request.getParameter("start");
var length = request.getParameter("length");
var keys = request.getParameter("attributes");
keys = JSON.parse(keys);
var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/events/"
+ deviceType + "/" + deviceId + "?offset=" + index +"&limit=" + length + "&from="+ from + "&to=" + to;
serviceInvokers.XMLHttp.get(
restAPIEndpoint,
function (restAPIResponse) {
if (restAPIResponse["status"] == 200 && restAPIResponse["responseText"]) {
var responsePayload = parse(restAPIResponse["responseText"]);
var paginatedResult = {};
paginatedResult["recordsTotal"] = responsePayload["count"];
paginatedResult["recordsFiltered"] = responsePayload["count"];
var records = responsePayload["records"];
var dataSet = [];
for (var i = 0; i < records.length; i++){
var record = records[i];
var timestamp = record["timestamp"];
var dataRow = [];
dataRow.push(timestamp);
for (var j = 0; j < keys.length; j++) {
var key = keys[j];
dataRow.push(record.values[key]);
}
//dataSet.push(dataRow);
dataSet.push(dataRow);
}
paginatedResult["data"] = dataSet;
response["status"] = restAPIResponse["status"];
response["content"] = paginatedResult;
} else {
response["status"] = 204;
var paginatedResult = {};
var dataSet = [];
paginatedResult["recordsTotal"] = 0;
paginatedResult["recordsFiltered"] = 0;
paginatedResult["data"] = dataSet;
response["content"] = paginatedResult;
}
}
);
}
%>

@ -176,7 +176,9 @@
"perm:ios:get-restrictions", "perm:ios:get-restrictions",
"perm:ios:wipe-data", "perm:ios:wipe-data",
"perm:admin", "perm:admin",
"perm:devicetype:deployment" "perm:devicetype:deployment",
"perm:device-types:events",
"perm:device-types:events:view"
], ],
"isOAuthEnabled": true, "isOAuthEnabled": true,
"backendRestEndpoints": { "backendRestEndpoints": {

@ -21,8 +21,12 @@ function onRequest(context) {
var deviceType = context.uriParams.deviceType; var deviceType = context.uriParams.deviceType;
var deviceName = request.getParameter("deviceName"); var deviceName = request.getParameter("deviceName");
var deviceId = request.getParameter("deviceId"); var deviceId = request.getParameter("deviceId");
var unitName = utility.getTenantedDeviceUnitName(deviceType, "analytics-view");
if (!unitName) {
unitName = "cdmf.unit.default.device.type.analytics-view";
}
return { return {
"deviceAnalyticsViewUnitName": utility.getTenantedDeviceUnitName(deviceType, "analytics-view"), "deviceAnalyticsViewUnitName": unitName,
"deviceType": deviceType, "deviceType": deviceType,
"deviceName": deviceName, "deviceName": deviceName,
"deviceId": deviceId "deviceId": deviceId

@ -103,7 +103,14 @@ function setDateTime(from, to) {
// Implement drawGraph_<device type name> method in your UI unit for analytics. // Implement drawGraph_<device type name> method in your UI unit for analytics.
var deviceTypes = $("#device-type-details").data("devicetypes"); var deviceTypes = $("#device-type-details").data("devicetypes");
for (var i = 0; i < deviceTypes.length; i++){ for (var i = 0; i < deviceTypes.length; i++){
try{
window["drawGraph_" + deviceTypes](parseInt(from / 1000), parseInt(to / 1000)); window["drawGraph_" + deviceTypes](parseInt(from / 1000), parseInt(to / 1000));
}catch(e){
}
try{
window["drawTable"](parseInt(from / 1000), parseInt(to / 1000));
}catch(e){
}
} }
} }

@ -0,0 +1,114 @@
{{!
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.
}}
<span id="operation-details" data-endpoint="{{operationEndpoint}}" data-deviceid="{{device.deviceIdentifier}}">
{{#if control_operations}}
<div class="wr-operations" style="height: 87px; display: block;">
<style>
::-webkit-input-placeholder {
color: #B8B8B8;
}
::-moz-placeholder {
color: #B8B8B8;
}
:-ms-input-placeholder {
color: #B8B8B8;
}
input:-moz-placeholder {
color: #B8B8B8;
}
</style>
{{#each control_operations}}
<a href="javascript:operationSelect('{{operation}}')">
<i class="fw fw-service"></i>
<span>{{name}}</span>
</a>
<div class="operation" data-operation-code="{{operation}}">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-service fw-stack-1x"></i>
</span>
{{name}}
<br>
</h3>
<h4>
{{description}}
<br>
</h4>
<form id="form-{{operation}}" style="padding-bottom: 20px;"-->
<select id="operation-type" class="form-control" onChange="operationTypeChage(this)">
<option value="CONFIG">Config</option>
<option value="COMMAND">Command</option>
</select>
<br />
<input type="hidden" id="operation-code" value="{{operation}}" />
<textarea id="operation-payload" placeholder="payload" class="form-control" rows="10" cols="70"></textarea>
<br />
<button id="btnSend" type="button" onclick="submitForm('form-{{operation}}')" class="btn btn-default">&nbsp;&nbsp;&nbsp;&nbsp;Send
to Device&nbsp;&nbsp;&nbsp;&nbsp;</button>
<label id="lblSending" class="wr-input-label hidden"><i
class="fw fw-lifecycle fw-spin fw-2x"></i> Sending..</label>
<label id="lblSent" class="wr-input-label hidden"><i
class="fw fw-check fw-2x"></i> Sent</label>
</form>
</div>
</div>
</div>
</div>
{{/each}}
</div>
{{else}}
<div align="center">
<h4 style="color: #D8000C"><i class="icon fw fw-error" style="color: #D8000C"></i>
Operations Loading Failed!</h4>
</div>
{{/if}}
<div id="operation-response-template" style="display: none">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i id="status-icon" class="fw fw-error fw-stack-1x"></i>
</span>
<br>
</h3>
<h4>
<span id="title"></span>
<br>
</h4>
<span id="description"></span>
</div>
</div>
</div>
</div>
{{#zone "bottomJs"}}
{{js "js/operation-bar.js"}}
{{/zone}}

@ -0,0 +1,29 @@
/*
* 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.
*/
function onRequest(context) {
var log = new Log("operation.js");
var deviceType = context.uriParams.deviceType;
var operationModule = require("/app/modules/business-controllers/operation.js")["operationModule"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var restAPIEndpoint = devicemgtProps["backendRestEndpoints"]["deviceMgt"]
+ "/devices/" + deviceType + "/operations";
var device = context.unit.params.device;
var features = context.unit.params.features;
return {"control_operations": features, "device": device, "operationEndpoint": restAPIEndpoint};
}

@ -0,0 +1,116 @@
/*
* 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.
*/
/*
* On operation click function.
* @param selection: Selected operation
*/
function operationSelect(selection) {
$(modalPopupContent).addClass("operation-data");
$(modalPopupContent).html($(" .operation[data-operation-code=" + selection + "]").html());
$(modalPopupContent).data("operation-code", selection);
showPopup();
}
function submitForm(formId) {
var form = $("#" + formId);
var operationDetails = $("#operation-details");
var deviceId = operationDetails.data("deviceid");
var operationEndpoint = operationDetails.data("endpoint");
console.log(deviceId);
console.log(operationEndpoint);
var contentType = "application/json";
var payload = {};
var devices=[];
devices.push(deviceId);
payload["deviceIdentifiers"] = devices;
var operation = {};
operation["code"] = form.find("#operation-code").val();
operation["type"]= form.find("#operation-type").val();
operation["status"] = "IN_PROGRESS";
operation["control"] = "REPEAT";
operation["payLoad"] = form.find("#operation-payload").val();
operation["enabled"] = true;
payload["operation"] = operation;
//setting responses callbacks
var defaultStatusClasses = "fw fw-stack-1x";
var content = $("#operation-response-template").find(".content");
var title = content.find("#title");
var statusIcon = content.find("#status-icon");
var description = content.find("#description");
var successCallBack = function (response) {
var res = response;
try {
res = JSON.parse(response).messageFromServer;
} catch (err) {
//do nothing
}
title.html("Operation Triggered!");
statusIcon.attr("class", defaultStatusClasses + " fw-check");
description.html(res);
$(modalPopupContent).html(content.html());
};
var errorCallBack = function (response) {
console.log(response);
title.html("An Error Occurred!");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
var reason = (response.responseText == "null")?response.statusText:response.responseText;
description.html(reason);
$(modalPopupContent).html(content.html());
};
invokerUtil.post(operationEndpoint, payload, successCallBack, errorCallBack, contentType);
}
$(document).on('submit', 'form', function (e) {
e.preventDefault();
var postOperationRequest = $.ajax({
url: $(this).attr("action") + '&' + $(this).serialize(),
method: "post"
});
var btnSubmit = $('#btnSend', this);
btnSubmit.addClass('hidden');
var lblSending = $('#lblSending', this);
lblSending.removeClass('hidden');
var lblSent = $('#lblSent', this);
postOperationRequest.done(function (data) {
lblSending.addClass('hidden');
lblSent.removeClass('hidden');
setTimeout(function () {
hidePopup();
}, 3000);
});
postOperationRequest.fail(function (jqXHR, textStatus) {
lblSending.addClass('hidden');
lblSent.addClass('hidden');
});
});
function operationTypeChage(selectElement) {
if (selectElement.value == "COMMAND") {
$("#operation-payload").hide();
} else {
$("#operation-payload").show();
}
}

@ -0,0 +1,65 @@
{{!
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.
}}
<table class="table table-responsive table-striped" id="members">
<tbody>
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px;">Model</td>
<td style="padding:10px 15px;">TODO</td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Status</td>
<td style="padding:10px 15px;">
{{#if permissions.CHANGE_DEVICE_STATUS}}
{{#equal device.status "ACTIVE"}}<span><i id="statusIcon"
class="fw fw-success icon-success"></i>
<a href="#" id="status" data-type="select" data-pk="1"
data-title="Select status"
selectedValue="Active"></a>
</span>{{/equal}}
{{#equal device.status "INACTIVE"}}<span><i id="statusIcon"
class="fw fw-warning icon-warning"></i>
<a href="#" id="status" data-type="select" data-pk="1"
data-title="Select status"
selectedValue="Inactive"></a>
</span>{{/equal}}
{{#equal device.status "BLOCKED"}}<span><i id="statusIcon"
class="fw fw-remove icon-danger"></i>
<a href="#" id="status" data-type="select" data-pk="1"
data-title="Select status"
selectedValue="Blocked"></a>
</span>{{/equal}}
{{#equal device.status "REMOVED"}}<span><i id="statusIcon"
class="fw fw-delete icon-danger"></i>
<a href="#" id="status" data-type="select" data-pk="1"
data-title="Select status"
selectedValue="Removed"></a>
</span>{{/equal}}
{{else}}
{{#equal device.status "ACTIVE"}}<span><i
class="fw fw-success icon-success"></i> Active</span>{{/equal}}
{{#equal device.status "INACTIVE"}}<span><i
class="fw fw-warning icon-warning"></i> Inactive</span>{{/equal}}
{{#equal device.status "BLOCKED"}}<span><i
class="fw fw-remove icon-danger"></i> Blocked</span>{{/equal}}
{{#equal device.status "REMOVED"}}<span><i
class="fw fw-delete icon-danger"></i> Removed</span>{{/equal}}
{{/if}}
</td>
</tr>
</tbody>
</table>

@ -0,0 +1,23 @@
/*
* 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.
*/
function onRequest (context) {
var log = new Log("overview-section.js");
var device = context.unit.params.device;
return {"device" : device};
}

@ -0,0 +1,47 @@
{{!
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
}}
{{unit "cdmf.unit.data-tables-extended"}}
<span id="device-details" data-devices="{{devices}}" data-devicename="{{device.name}}"
data-deviceid="{{device.deviceIdentifier}}"
data-devicetype="{{device.type}}"
data-appcontext="{{@app.context}}" data-attributes="{{attributes}}"></span>
<div id="device-div-chart" data-backend-api-url= {{backendApiUri}}>
{{#if attributes}}
<table class="table table-striped table-hover table-bordered display data-table"
id="stats-table">
<thead>
<tr id="header-rows">
<td>Timestamp</td>
{{#each attributes}}
<td>{{this}}</td>
{{/each}}
</tr>
</thead>
<tbody>
</tbody>
</table>
{{else}}
<div id="warn-config"><h1>Analytics Not Configured</h1> </div>
{{/if}}
</div>
{{#zone "bottomJs"}}
{{js "js/device.js"}}
{{/zone}}

@ -0,0 +1,71 @@
/*
* 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.
*/
function onRequest(context) {
var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("deviceId");
var keys = [];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
+ "/events/" + deviceType;
serviceInvokers.XMLHttp.get(
restAPIEndpoint,
function (restAPIResponse) {
if (restAPIResponse["status"] == 200 && restAPIResponse["responseText"]) {
var eventAttributes = parse(restAPIResponse["responseText"]);
if (eventAttributes.attributes.length > 0) {
for (var i = 0; i < eventAttributes.attributes.length; i++) {
var attribute = eventAttributes.attributes[i];
if (attribute['name'] == "deviceId") {
continue;
}
keys.push(attribute['name']);
}
}
}
}
);
if (device && device.status != "error") {
if (keys.length === 0 || keys.length === undefined) {
return {
"device": device.content,
"backendApiUri": "/api/device-mgt/v1.0/events/" + deviceType
};
} else {
return {
"device": device.content,
"backendApiUri": "/api/device-mgt/v1.0/events/" + deviceType,
"attributes": keys
};
}
} else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");
exit();
}
}
}

@ -0,0 +1,74 @@
/*
* 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.
*/
var InitiateViewOption = null;
var deviceId = null;
var deviceType = null;
var fromTime = null;
var toTime = null;
var keys = null;
function drawTable(from, to) {
var device = $("#device-details");
deviceId = device.data("deviceid");
deviceType = device.data("devicetype");
keys = device.data("attributes").split(",");
fromTime = from * 1000;
toTime = to * 1000;
if ( $.fn.dataTable.isDataTable( '#stats-table' ) ) {
var table = $('#stats-table').DataTable();
table.clear().draw();
table.ajax.reload();
}
else {
$("#stats-table").datatables_extended({
serverSide: true,
processing: false,
searching: false,
ordering: false,
pageLength: 100,
order: [],
ajax: {
url: "/devicemgt/api/stats/paginate",
data: buildAjaxData
}
});
}
}
function buildAjaxData (){
var settings = $("#stats-table").dataTable().fnSettings();
var obj = {
//default params
"draw" : settings.iDraw,
"start" : settings._iDisplayStart,
"length" : settings._iDisplayLength,
"columns" : "",
"order": "",
"deviceType" : deviceType,
"deviceId" : deviceId,
"from": fromTime,
"to" : toTime,
"attributes" : JSON.stringify(keys)
};
return obj;
}

@ -23,34 +23,50 @@
</style> </style>
{{/zone}} {{/zone}}
{{#zone "overview-section"}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Device Overview - {{label}}</div>
{{unit "cdmf.unit.default.device.overview-section" device=device}}
{{/zone}}
{{#zone "device-thumbnail"}} {{#zone "device-thumbnail"}}
<img src="{{@unit.publicUri}}/images/deviceType.png"/> <img src="{{@unit.publicUri}}/images/deviceType.png"/>
{{/zone}} {{/zone}}
{{#zone "device-opetations"}} {{#zone "device-opetations"}}
{{#if features}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px"> <div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Operations Operations
</div> </div>
<div class="add-margin-top-4x"> <div class="add-margin-top-4x">
operation comes here {{unit "cdmf.unit.default.device.operation-bar" device=device features=features}}
</div> </div>
{{/if}}
{{/zone}} {{/zone}}
{{#zone "device-view-tabs"}} {{#zone "device-view-tabs"}}
{{#if attributes}}
<li class="active"><a class="list-group-item" href="#device_statistics" role="tab" <li class="active"><a class="list-group-item" href="#device_statistics" role="tab"
data-toggle="tab" aria-controls="device_statistics">Device data-toggle="tab" aria-controls="device_statistics">Device
Statistics</a> Statistics</a>
</li> </li>
{{/if}}
{{#if features}}
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab" <li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li> aria-controls="event_log">Operations Log</a></li>
{{/if}}
{{/zone}} {{/zone}}
{{#zone "device-view-tab-contents"}} {{#zone "device-view-tab-contents"}}
{{#if attributes}}
<div class="panel panel-default tab-pane active" <div class="panel panel-default tab-pane active"
id="device_statistics" role="tabpanel" aria-labelledby="device_statistics"> id="device_statistics" role="tabpanel" aria-labelledby="device_statistics">
<div class="panel-heading">Device Statistics</div> <div class="panel-heading">Realtime Statistics</div>
unit "cdmf.unit.device.type.senseme.realtime.analytics-view" device=device {{unit "cdmf.unit.default.device.type.realtime.analytics-view" device=device attributes=attributes}}
</div> </div>
{{/if}}
{{#if features}}
<div class="panel panel-default tab-pane" id="event_log" role="tabpanel" <div class="panel panel-default tab-pane" id="event_log" role="tabpanel"
aria-labelledby="event_log"> aria-labelledby="event_log">
<div class="panel-heading">Operations Log <span><a href="#" <div class="panel-heading">Operations Log <span><a href="#"
@ -74,4 +90,5 @@
</div> </div>
</div> </div>
</div> </div>
{{/if}}
{{/zone}} {{/zone}}

@ -15,11 +15,53 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
function onRequest(context) { function onRequest(context) {
var log = new Log("device-view.js"); var log = new Log("device-view.js");
var deviceType = context.uriParams.deviceType; var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("id"); var deviceId = request.getParameter("id");
var attributes = [];
var featureList = [];
log.error(featureList);
var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
+ "/events/" + deviceType;
serviceInvokers.XMLHttp.get(
restAPIEndpoint,
function (restAPIResponse) {
if (restAPIResponse["status"] == 200 && restAPIResponse["responseText"]) {
var eventAttributes = parse(restAPIResponse["responseText"]);
if (eventAttributes.attributes.length > 0) {
for (var i = 0; i < eventAttributes.attributes.length; i++) {
var attribute = eventAttributes.attributes[i];
if (attribute['name'] == "deviceId") {
continue;
}
attributes.push(attribute['name']);
}
}
}
}
);
var featureEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"]
+ "/device-types/" + deviceType + "/features";
var featuresList = serviceInvokers.XMLHttp.get(featureEndpoint, function (responsePayload) {
var features = JSON.parse(responsePayload.responseText);
var feature;
for (var i = 0; i < features.length; i++) {
feature = {};
feature["operation"] = features[i].code;
feature["name"] = features[i].name;
feature["description"] = features[i].description;
}
featureList.push(feature);
}, function (responsePayload) {
featureList = null;
}
);
var autoCompleteParams = [ var autoCompleteParams = [
{"name" : "deviceId", "value" : deviceId} {"name" : "deviceId", "value" : deviceId}
]; ];
@ -28,7 +70,13 @@ function onRequest(context) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"]; var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId); var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") { if (device && device.status != "error") {
return {"device": device.content, "autoCompleteParams" : autoCompleteParams, "encodedFeaturePayloads": ""}; if (attributes.length === 0 || attributes.length === undefined) {
return {"device": device.content, "autoCompleteParams" : autoCompleteParams
, "encodedFeaturePayloads": "", "features":featureList};
} else {
return {"device": device.content, "autoCompleteParams" : autoCompleteParams
, "encodedFeaturePayloads": "", "attributes": attributes, "features":featureList};
}
} else { } else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!"); response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");
exit(); exit();

@ -0,0 +1,44 @@
{{!
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
}}
{{unit "cdmf.unit.lib.rickshaw-graph"}}
<div id="div-chart" data-websocketurl="{{websocketEndpoint}}" data-attributes="{{attributes}}">
<table class="table table-responsive table-striped" id="members">
<tbody>
{{#each attributes}}
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px;">{{this}}</td>
<td id="{{this}}-value" style="padding:10px 15px;">-</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<a class="padding-left"
href="{{@app.context}}/device/{{device.type}}/analytics?deviceId={{device.deviceIdentifier}}&deviceName={{device.name}}">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-statistics fw-stack-1x"></i>
</span> View Device Analytics
</a>
<!-- /statistics -->
{{#zone "bottomJs"}}
{{js "js/moment.min.js"}}
{{js "js/socket.io.min.js"}}
{{js "js/device-stats.js"}}
{{/zone}}

@ -0,0 +1,54 @@
/*
* 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.
*/
function onRequest(context) {
var log = new Log("stats.js");
var carbonServer = require("carbon").server;
var device = context.unit.params.device;
var attributes = context.unit.params.attributes;
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var constants = require("/app/modules/constants.js");
var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
var jwtService = carbonServer.osgiService(
'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
var jwtClient = jwtService.getJWTClient();
var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"]);
var token = "";
var user = userModule.getCarbonUser();
var tenantDomain = user.domain;
if (encodedClientKeys) {
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
var resp = tokenUtil.decode(encodedClientKeys).split(":");
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {});
if (tokenPair) {
token = tokenPair.accessToken;
}
if (tenantDomain == "carbon.super") {
websocketEndpoint = websocketEndpoint + "/secured-websocket/" + tenantDomain + "." + device.type + "/1.0.0?"
+ "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token;
} else {
websocketEndpoint = websocketEndpoint + "/t/" + tenantDomain + "/secured-websocket/" + tenantDomain
+ "." + device.type + "/1.0.0?" + "deviceId=" + device.deviceIdentifier + "&deviceType="
+ device.type + "&websocketToken=" + token;
}
}
return {"device": device, "websocketEndpoint": websocketEndpoint, "attributes": attributes};
}

@ -0,0 +1,57 @@
/*
* 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.
*/
var ws;
var attributes = null;
$(window).load(function () {
var div = $("#div-chart");
var websocketUrl = div.data("websocketurl");
attributes = div.data("attributes").split(",");
connect(websocketUrl)
});
$(window).unload(function () {
disconnect();
});
//websocket connection
function connect(target) {
if ('WebSocket' in window) {
ws = new WebSocket(target);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket(target);
} else {
console.log('WebSocket is not supported by this browser.');
}
if (ws) {
ws.onmessage = function (webSocketData) {
var data = JSON.parse(webSocketData.data);
var payloadData = data["event"]["payloadData"];
for (var i = 0; i < attributes.length; i++){
$("#" + attributes[i] +"-value").text(payloadData[attributes[i]]);
}
};
}
}
function disconnect() {
if (ws != null) {
ws.close();
ws = null;
}
}

@ -134,6 +134,32 @@
<br> <br>
</div> </div>
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 padding-double grey-bg">
<h3 class="uppercase">Topic to publish data for analytics : {{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/events</h3>
<h3 class="uppercase">Topic to publish data to an external system : {{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/proxy</h3>
<h3 class="uppercase">Topic to listen for operation: {{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/#</h3>
<hr>
<ul class="list-unstyled">
<li class="padding-top-double">
{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/command/&lt;feature_code&gt;
</li>
<li class="padding-top-double">
{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/config/&lt;feature_code&gt;
</li>
<li class="padding-top-double">
{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/profile/&lt;feature_code&gt;
</li>
<li class="padding-top-double">
{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/policy/policy_bundle
</li>
<li class="padding-top-double">
{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/policy/policy_revoke
</li>
</ul>
<br>
<br>
</div>
{{#zone "topCss"}} {{#zone "topCss"}}
{{css "css/styles.css"}} {{css "css/styles.css"}}
{{/zone}} {{/zone}}

@ -18,7 +18,11 @@
function onRequest(context) { function onRequest(context) {
var deviceType = context.uriParams.deviceType; var deviceType = context.uriParams.deviceType;
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var user = userModule.getCarbonUser();
var tenantDomain = user.domain;
return { return {
"deviceType": deviceType "deviceType": deviceType,
"tenantDomain": tenantDomain
}; };
} }

@ -54,6 +54,10 @@
{ {
"url": "/api/operation/*", "url": "/api/operation/*",
"path": "/api/operation-api.jag" "path": "/api/operation-api.jag"
},
{
"url": "/api/stats/*",
"path": "/api/stats-api.jag"
} }
], ],
"errorPages": { "errorPages": {

Loading…
Cancel
Save