diff --git a/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.pull.notification/pom.xml b/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.pull.notification/pom.xml index 69df3be212..47d5fc0dcb 100644 --- a/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.pull.notification/pom.xml +++ b/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.pull.notification/pom.xml @@ -22,7 +22,7 @@ device-mgt-extensions org.wso2.carbon.devicemgt - 2.0.74-SNAPSHOT + 2.0.75-SNAPSHOT ../pom.xml diff --git a/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.http/pom.xml b/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.http/pom.xml index de9fbb36db..181cab05fa 100644 --- a/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.http/pom.xml +++ b/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.http/pom.xml @@ -22,7 +22,7 @@ device-mgt-extensions org.wso2.carbon.devicemgt - 2.0.74-SNAPSHOT + 2.0.75-SNAPSHOT ../pom.xml diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java index a490197960..ce442701e1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java @@ -49,6 +49,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.List; import java.util.Map; @SwaggerDefinition( @@ -309,6 +310,70 @@ public interface DeviceAgentService { value = "deviceId of the device") @PathParam("deviceId") String deviceId); + @POST + @Path("/events/publish/data/{type}/{deviceId}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Publishing Events data only", + notes = "Publish events received by the device client to the WSO2 Data Analytics Server (DAS) using this API.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:publish-event") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 200, message = "OK. \n Successfully published the event", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + }), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while publishing events.") + }) + Response publishEvents( + @ApiParam( + name = "payloadData", + value = "Information of the agent event to be published on DAS.") + @Valid + List payloadData, + @ApiParam( + name = "type", + value = "name of the device type") + @PathParam("type") String type, + @ApiParam( + name = "deviceId", + value = "deviceId of the device") + @PathParam("deviceId") String deviceId); + @GET @Path("/pending/operations/{type}/{id}") @ApiOperation( @@ -367,7 +432,7 @@ public interface DeviceAgentService { @PathParam("id") String deviceId); @GET - @Path("/last-pending/operation/{type}/{id}") + @Path("/next-pending/operation/{type}/{id}") @ApiOperation( produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java index 1926a3ef87..e1f9c765aa 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java @@ -306,6 +306,106 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { } } + @POST + @Path("/events/publish/data/{type}/{deviceId}") + @Override + public Response publishEvents(@Valid List payload, @PathParam("type") String type + , @PathParam("deviceId") String deviceId) { + + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + try { + if (payload == null) { + String msg = "invalid payload structure"; + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } else { + boolean authorized = DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized + (new DeviceIdentifier(type, deviceId)); + if (!authorized) { + String msg = "does not have permission to access the device."; + return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build(); + } + } + Object metaData[] = new Object[1]; + metaData[0] = deviceId; + EventAttributeList eventAttributeList = DeviceMgtAPIUtils.getDynamicEventCache().get(type); + if (eventAttributeList == null) { + String streamName = DeviceMgtAPIUtils.getStreamDefinition(type, tenantDomain); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto( + streamName + ":" + Constants.DEFAULT_STREAM_VERSION); + if (eventStreamDefinitionDto == null) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } else { + EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData(); + List attributes = new ArrayList<>(); + for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) { + attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName() + , AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase()))); + + } + if (payload.size() != attributes.size()) { + String msg = "payload does not match with the stream definition"; + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + eventAttributeList = new EventAttributeList(); + eventAttributeList.setList(attributes); + DeviceMgtAPIUtils.getDynamicEventCache().put(type, eventAttributeList); + } + } + int i = 0; + Object[] payloadData = new Object[eventAttributeList.getList().size()]; + for (Attribute attribute : eventAttributeList.getList()) { + if (attribute.getType() == AttributeType.INT) { + payloadData[i] = ((Double) payload.get(i)).intValue(); + } else if (attribute.getType() == AttributeType.LONG) { + payloadData[i] = ((Double) payload.get(i)).longValue(); + } else { + payloadData[i] = payload.get(i); + } + i++; + } + + if (DeviceMgtAPIUtils.getEventPublisherService().publishEvent(DeviceMgtAPIUtils.getStreamDefinition(type + , PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()) + , Constants.DEFAULT_STREAM_VERSION, metaData + , null, payloadData)) { + return Response.status(Response.Status.OK).build(); + } else { + String msg = "Error occurred while publishing the event."; + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (DataPublisherConfigurationException e) { + String msg = "Error occurred while publishing the event."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred when checking for authorization"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (AxisFault e) { + log.error("failed to retrieve event definitions for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RemoteException e) { + log.error("Failed to connect with the remote services:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (JWTClientException e) { + log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (UserStoreException e) { + log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } finally { + if (eventStreamAdminServiceStub != null) { + try { + eventStreamAdminServiceStub.cleanup(); + } catch (AxisFault axisFault) { + log.warn("Failed to clean eventStreamAdminServiceStub"); + } + } + } + } + @GET @Path("/pending/operations/{type}/{id}") public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) { @@ -339,7 +439,7 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { } @GET - @Path("/last-pending/operation/{type}/{id}") + @Path("/next-pending/operation/{type}/{id}") public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) { try { if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java index 1f7dc7f9ff..c596735b4c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java @@ -37,6 +37,8 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Path("/admin/device-types") @Produces(MediaType.APPLICATION_JSON) @@ -44,6 +46,8 @@ import java.util.List; public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagementAdminService { private static final Log log = LogFactory.getLog(DeviceTypeManagementAdminServiceImpl.class); + private static final String DEVICETYPE_REGEX_PATTERN = "^[^ /]+$"; + private static final Pattern patternMatcher = Pattern.compile(DEVICETYPE_REGEX_PATTERN); @GET @Override @@ -68,10 +72,18 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen String msg = "Device type already available, " + deviceType.getName(); return Response.status(Response.Status.CONFLICT).entity(msg).build(); } - DeviceManagementService httpDeviceTypeManagerService = DeviceMgtAPIUtils.getDeviceTypeGeneratorService() - .populateDeviceManagementService(deviceType.getName(), deviceType.getDeviceTypeMetaDefinition()); - DeviceMgtAPIUtils.getDeviceManagementService().registerDeviceType(httpDeviceTypeManagerService); - return Response.status(Response.Status.OK).build(); + Matcher matcher = patternMatcher.matcher(deviceType.getName()); + if(matcher.find()) { + DeviceManagementService httpDeviceTypeManagerService = + DeviceMgtAPIUtils.getDeviceTypeGeneratorService() + .populateDeviceManagementService(deviceType.getName(), + deviceType.getDeviceTypeMetaDefinition()); + DeviceMgtAPIUtils.getDeviceManagementService().registerDeviceType(httpDeviceTypeManagerService); + return Response.status(Response.Status.OK).build(); + } else { + return Response.status(Response.Status.BAD_REQUEST).entity("device type name does not match the pattern " + + DEVICETYPE_REGEX_PATTERN).build(); + } } catch (DeviceManagementException e) { String msg = "Error occurred at server side while adding a device type."; log.error(msg, e); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/ConfigOperationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/ConfigOperationDAOImpl.java index c847c7652c..3020096972 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/ConfigOperationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/ConfigOperationDAOImpl.java @@ -178,6 +178,7 @@ public class ConfigOperationDAOImpl extends GenericOperationDAOImpl { ois = new ObjectInputStream(bais); configOperation = (ConfigOperation) ois.readObject(); configOperation.setStatus(status); + configOperation.setId(rs.getInt("OPERATION_ID")); operations.add(configOperation); } } catch (IOException e) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.create/public/js/bottomJs.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.create/public/js/bottomJs.js index 941729dc0e..0e9db49c5c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.create/public/js/bottomJs.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.create/public/js/bottomJs.js @@ -229,6 +229,10 @@ $(document).ready(function () { $(errorMsg).text("Unexpected error."); $(errorMsgWrapper).removeClass("hidden"); } + if (jqXHR.status == 400) { + $(errorMsg).text("Device type name should not contain whitespaces."); + $(errorMsgWrapper).removeClass("hidden"); + } if (jqXHR.status == 409) { $(errorMsg).text("Device type already exists"); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.hbs index f100540ebf..e4403ff3c4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.hbs @@ -271,11 +271,10 @@ curl -k -X GET {{httpsGateway}}/api/device-mgt/v1.0/device/agent/pending/operations/{{deviceType}}/deviceId -H 'authorization: Bearer %accessToken%' -H 'content-type: application/json'
- Retrieve last pending operation: - curl -k -X GET {{httpsGateway}}/api/device-mgt/v1.0/device/agent/last-pending/operation/{{deviceType}}/deviceId + Retrieve next pending operation: + curl -k -X GET {{httpsGateway}}/api/device-mgt/v1.0/device/agent/next-pending/operations/{{deviceType}}/deviceId -H 'authorization: Bearer %accessToken%' -H 'content-type: application/json'
- Update operation: curl -k -X PUT {{httpsGateway}}/api/device-mgt/v1.0/device/agent/operations/{{deviceType}}/deviceId -H 'authorization: Bearer %accessToken%' -H 'content-type: application/json' -d '{"id": 1,"status": "COMPLETED", "payload": "this is my response"}' diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/AccessTokenGrantHandler.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/AccessTokenGrantHandler.java index 40d87a17ec..af4eae0629 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/AccessTokenGrantHandler.java +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/AccessTokenGrantHandler.java @@ -52,7 +52,7 @@ public class AccessTokenGrantHandler extends AbstractAuthorizationGrantHandler { public AccessTokenGrantHandler() { try { - tokenValidator = OAuthValidatorFactory.getValidator(); + // tokenValidator = OAuthValidatorFactory.getValidator(); } catch (IllegalArgumentException e) { log.error("Failed to initialise Authenticator", e); } diff --git a/components/identity-extensions/org.wso2.carbon.identity.authenticator.backend.oauth/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorServiceComponent.java b/components/identity-extensions/org.wso2.carbon.identity.authenticator.backend.oauth/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorServiceComponent.java index cdcc9a2396..0da3fa41ef 100755 --- a/components/identity-extensions/org.wso2.carbon.identity.authenticator.backend.oauth/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorServiceComponent.java +++ b/components/identity-extensions/org.wso2.carbon.identity.authenticator.backend.oauth/src/main/java/org/wso2/carbon/identity/authenticator/backend/oauth/internal/OAuthAuthenticatorServiceComponent.java @@ -44,14 +44,6 @@ public class OAuthAuthenticatorServiceComponent { if (log.isDebugEnabled()) { log.debug("Starting Backend OAuthAuthenticator Framework Bundle"); } - try { - /* Registering BackendOAuthAuthenticator Service */ - BundleContext bundleContext = componentContext.getBundleContext(); - OauthAuthenticator oAuthAuthenticator = new OauthAuthenticator(); - bundleContext.registerService(CarbonServerAuthenticator.class.getName(), oAuthAuthenticator, null); - } catch (Throwable e) { - log.error("Error occurred while initializing the bundle", e); - } } @SuppressWarnings("unused") diff --git a/features/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.feature/pom.xml b/features/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.feature/pom.xml index c3c42301b7..cad6715e4b 100644 --- a/features/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.feature/pom.xml +++ b/features/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.feature/pom.xml @@ -22,14 +22,14 @@ org.wso2.carbon.devicemgt device-mgt-extensions-feature - 2.0.74-SNAPSHOT + 2.0.75-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.device.mgt.extensions.push.notification.provider.http.feature pom - 2.0.74-SNAPSHOT + 2.0.75-SNAPSHOT WSO2 Carbon - MQTT Based Push Notification Provider Feature http://wso2.org WSO2 Carbon - MQTT Based Push Notification Provider Feature diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/dbscripts/cdm/h2.sql index 39ea23a9d2..1422715967 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -74,6 +74,7 @@ CREATE TABLE IF NOT EXISTS DM_OPERATION ( CREATE TABLE IF NOT EXISTS DM_CONFIG_OPERATION ( OPERATION_ID INTEGER NOT NULL, OPERATION_CONFIG BLOB DEFAULT NULL, + ENABLED BOOLEAN NOT NULL DEFAULT FALSE, PRIMARY KEY (OPERATION_ID), CONSTRAINT fk_dm_operation_config FOREIGN KEY (OPERATION_ID) REFERENCES DM_OPERATION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION diff --git a/features/oauth-extensions/org.wso2.carbon.device.mgt.oauth.extensions.feature/pom.xml b/features/oauth-extensions/org.wso2.carbon.device.mgt.oauth.extensions.feature/pom.xml index 65ec7a34b4..829f57b353 100644 --- a/features/oauth-extensions/org.wso2.carbon.device.mgt.oauth.extensions.feature/pom.xml +++ b/features/oauth-extensions/org.wso2.carbon.device.mgt.oauth.extensions.feature/pom.xml @@ -80,6 +80,9 @@ org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.oauth.extensions:${carbon.device.mgt.version} + + org.wso2.carbon.devicemgt:org.wso2.carbon.identity.authenticator.backend.oauth:${carbon.device.mgt.version} + org.wso2.carbon.core.server:${carbon.kernel.version}