Implemented Pull Notification Support

4.x.x
ayyoob 8 years ago
parent 8a56161a43
commit a0d7518cbe

@ -157,7 +157,7 @@ public class MQTTNotificationStrategy implements NotificationStrategy {
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/" + ctx.getDeviceId().getType() + "/" + ctx.getDeviceId().getId() + "/operation/"
+ operation.getType().toString().toLowerCase() + "/" + operation.getCode(); + operation.getType().toString().toLowerCase() + "/" + operation.getCode() + "/" + operation.getId();
dynamicProperties.put("topic", topic); dynamicProperties.put("topic", topic);
Object payload; Object payload;
if ("command".equals(operation.getType().toString().toLowerCase())) { if ("command".equals(operation.getType().toString().toLowerCase())) {

@ -38,6 +38,7 @@
<module>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt</module> <module>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt</module>
<module>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp</module> <module>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp</module>
<module>org.wso2.carbon.device.mgt.extensions.device.type.deployer</module> <module>org.wso2.carbon.device.mgt.extensions.device.type.deployer</module>
<module>org.wso2.carbon.device.mgt.extensions.pull.notification</module>
</modules> </modules>
</project> </project>

@ -84,17 +84,23 @@ import javax.ws.rs.core.Response;
key = "perm:device:modify", key = "perm:device:modify",
permissions = {"/device-mgt/devices/owning-device/modify"} permissions = {"/device-mgt/devices/owning-device/modify"}
), ),
@Scope(
name = "Getting Device Operation Details",
description = "Getting Device Operation Details",
key = "perm:devices:operations",
permissions = {"/device-mgt/devices/owning-device/view"}
),
@Scope( @Scope(
name = "Disenroll Device", name = "Disenroll Device",
description = "Disenroll a device", description = "Disenroll a device",
key = "perm:device:disenroll", key = "perm:device:disenroll",
permissions = {"/device-mgt/devices/owning-device/remove"} permissions = {"/device-mgt/devices/owning-device/remove"}
),
@Scope(
name = "Publish Event",
description = "publish device event",
key = "perm:device:publish-event",
permissions = {"/device-mgt/devices/owning-device/event"}
),
@Scope(
name = "Getting Device Operation Details",
description = "Getting Device Operation Details",
key = "perm:device:operations",
permissions = {"/device-mgt/devices/owning-device/view"}
) )
} }
) )
@ -250,18 +256,14 @@ public interface DeviceAgentService {
tags = "Device Agent Management", tags = "Device Agent Management",
extensions = { extensions = {
@Extension(properties = { @Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device:enroll") @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:publish-event")
}) })
} }
) )
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(code = 201, message = "Created. \n Successfully published the event. Location header " + @ApiResponse(code = 200, message = "OK. \n Successfully published the event",
"contains URL of newly enrolled device",
responseHeaders = { responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The URL of the added policy."),
@ResponseHeader( @ResponseHeader(
name = "Content-Type", name = "Content-Type",
description = "The content type of the body"), description = "The content type of the body"),
@ -318,7 +320,7 @@ public interface DeviceAgentService {
tags = "Device Agent Management", tags = "Device Agent Management",
extensions = { extensions = {
@Extension(properties = { @Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations")
}) })
} }
) )
@ -375,7 +377,7 @@ public interface DeviceAgentService {
tags = "Device Agent Management", tags = "Device Agent Management",
extensions = { extensions = {
@Extension(properties = { @Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations")
}) })
} }
) )
@ -432,7 +434,7 @@ public interface DeviceAgentService {
tags = "Device Agent Management", tags = "Device Agent Management",
extensions = { extensions = {
@Extension(properties = { @Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations")
}) })
} }
) )
@ -490,7 +492,7 @@ public interface DeviceAgentService {
tags = "Device Agent Management", tags = "Device Agent Management",
extensions = { extensions = {
@Extension(properties = { @Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations")
}) })
} }
) )
@ -538,6 +540,4 @@ public interface DeviceAgentService {
@ApiParam(name = "status", value = "status of the operation.", required = true) @ApiParam(name = "status", value = "status of the operation.", required = true)
@QueryParam("status")Operation.Status status); @QueryParam("status")Operation.Status status);
} }

@ -19,17 +19,9 @@
package org.wso2.carbon.device.mgt.jaxrs.service.impl; 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.java.security.SSLProtocolSocketFactory;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
@ -52,12 +44,9 @@ import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub;
import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto; import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto;
import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto; import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
import javax.cache.Cache;
import javax.cache.Caching;
import javax.validation.Valid; import javax.validation.Valid;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.GET; import javax.ws.rs.GET;

@ -0,0 +1,49 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.common.pull.notification;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
public class NotificationContext {
private DeviceIdentifier deviceId;
private NotificationPayload notificationPayload;
public NotificationContext(DeviceIdentifier deviceId) {
this.deviceId = deviceId;
}
public NotificationContext(DeviceIdentifier deviceId, NotificationPayload notificationPayload) {
this.deviceId = deviceId;
this.notificationPayload = notificationPayload;
}
public DeviceIdentifier getDeviceId() {
return deviceId;
}
public NotificationPayload getNotificationPayload() {
return notificationPayload;
}
public void setNotificationPayload(NotificationPayload notificationPayload) {
this.notificationPayload = notificationPayload;
}
}

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

@ -0,0 +1,45 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.common.pull.notification;
public class PullNotificationExecutionFailedException extends Exception {
private static final long serialVersionUID = -3151279311923070297L;
public PullNotificationExecutionFailedException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public PullNotificationExecutionFailedException(String message, Throwable cause) {
super(message, cause);
}
public PullNotificationExecutionFailedException(String msg) {
super(msg);
}
public PullNotificationExecutionFailedException() {
super();
}
public PullNotificationExecutionFailedException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,34 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.common.pull.notification;
import java.util.Map;
/**
* This will handle the execution flow when a device sends a payload to IoT Server.
*/
public interface PullNotificationSubscriber {
void init(Map<String, String> properties);
void execute(NotificationContext ctx) throws PullNotificationExecutionFailedException;
void clean();
}

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.common.spi;
import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
/** /**
@ -47,6 +48,6 @@ public interface DeviceManagementService {
InitialOperationConfig getInitialOperationConfig(); InitialOperationConfig getInitialOperationConfig();
PullNotificationSubscriber getPullNotificationSubscriber();
} }

@ -22,6 +22,7 @@ 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.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.core.dto.DeviceManagementServiceHolder; import org.wso2.carbon.device.mgt.core.dto.DeviceManagementServiceHolder;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
@ -126,12 +127,15 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
ProvisioningConfig provisioningConfig = provider.getProvisioningConfig(); ProvisioningConfig provisioningConfig = provider.getProvisioningConfig();
if (provisioningConfig.isSharedWithAllTenants()) { if (provisioningConfig.isSharedWithAllTenants()) {
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceTypeName); deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceTypeName);
providers.remove(deviceTypeIdentifier);
} else { } else {
int providerTenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain()); int providerTenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain());
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceTypeName, providerTenantId); deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceTypeName, providerTenantId);
providers.remove(deviceTypeIdentifier);
} }
PullNotificationSubscriber pullNotificationSubscriber = provider.getPullNotificationSubscriber();
if (pullNotificationSubscriber != null) {
pullNotificationSubscriber.clean();
}
providers.remove(deviceTypeIdentifier);
unregisterPushNotificationStrategy(deviceTypeIdentifier); unregisterPushNotificationStrategy(deviceTypeIdentifier);
unregisterMonitoringTask(provider); unregisterMonitoringTask(provider);
} }

@ -20,13 +20,12 @@ package org.wso2.carbon.device.mgt.core.config;
import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations; import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations;
import org.wso2.carbon.device.mgt.core.config.pagination.PaginationConfiguration; import org.wso2.carbon.device.mgt.core.config.pagination.PaginationConfiguration;
import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration; import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration;
import org.wso2.carbon.device.mgt.core.config.pull.notification.PullNotificationConfiguration;
import org.wso2.carbon.device.mgt.core.config.push.notification.PushNotificationConfiguration; import org.wso2.carbon.device.mgt.core.config.push.notification.PushNotificationConfiguration;
import org.wso2.carbon.device.mgt.core.config.task.TaskConfiguration; import org.wso2.carbon.device.mgt.core.config.task.TaskConfiguration;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
/** /**
* Represents Device Mgt configuration. * Represents Device Mgt configuration.
@ -41,6 +40,7 @@ public final class DeviceManagementConfig {
private PolicyConfiguration policyConfiguration; private PolicyConfiguration policyConfiguration;
private PaginationConfiguration paginationConfiguration; private PaginationConfiguration paginationConfiguration;
private PushNotificationConfiguration pushNotificationConfiguration; private PushNotificationConfiguration pushNotificationConfiguration;
private PullNotificationConfiguration pullNotificationConfiguration;
@XmlElement(name = "ManagementRepository", required = true) @XmlElement(name = "ManagementRepository", required = true)
@ -97,5 +97,14 @@ public final class DeviceManagementConfig {
public void setPushNotificationConfiguration(PushNotificationConfiguration pushNotificationConfiguration) { public void setPushNotificationConfiguration(PushNotificationConfiguration pushNotificationConfiguration) {
this.pushNotificationConfiguration = pushNotificationConfiguration; this.pushNotificationConfiguration = pushNotificationConfiguration;
} }
@XmlElement(name = "PullNotificationConfiguration", required = true)
public PullNotificationConfiguration getPullNotificationConfiguration() {
return pullNotificationConfiguration;
}
public void setPullNotificationConfiguration(PullNotificationConfiguration pullNotificationConfiguration) {
this.pullNotificationConfiguration = pullNotificationConfiguration;
}
} }

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.config.pull.notification;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This class is for Pull notification related Configurations
*/
@XmlRootElement(name = "PullNotificationConfiguration")
public class PullNotificationConfiguration {
private boolean enabled;
@XmlElement(name = "Enabled", required = true)
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

@ -193,6 +193,8 @@ public class OperationManagerImpl implements OperationManager {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Sending push notification to " + deviceId + " from add operation method."); log.debug("Sending push notification to " + deviceId + " from add operation method.");
} }
operation.setId(operationId);
operation.setActivityId(DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId);
notificationStrategy.execute(new NotificationContext(deviceId, operation)); notificationStrategy.execute(new NotificationContext(deviceId, operation));
operationMappingDAO.updateOperationMapping(operationId, enrolmentId, org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.PushNotificationStatus.COMPLETED); operationMappingDAO.updateOperationMapping(operationId, enrolmentId, org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.PushNotificationStatus.COMPLETED);
} catch (PushNotificationExecutionFailedException e) { } catch (PushNotificationExecutionFailedException e) {
@ -554,7 +556,7 @@ public class OperationManagerImpl implements OperationManager {
Operation.Status.valueOf(operation.getStatus(). Operation.Status.valueOf(operation.getStatus().
toString())); toString()));
} }
if (isUpdated && operation.getOperationResponse() != null) { if (operation.getOperationResponse() != null) {
operationDAO.addOperationResponse(enrolmentId, operationId, operation.getOperationResponse()); operationDAO.addOperationResponse(enrolmentId, operationId, operation.getOperationResponse());
} }
OperationManagementDAOFactory.commitTransaction(); OperationManagementDAOFactory.commitTransaction();

@ -32,6 +32,8 @@ 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.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.NotificationContext;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy; import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
@ -349,4 +351,11 @@ public interface DeviceManagementProviderService {
* @throws DeviceManagementException * @throws DeviceManagementException
*/ */
List<DeviceType> getDeviceTypes() throws DeviceManagementException; List<DeviceType> getDeviceTypes() throws DeviceManagementException;
/**
* This retrieves the device pull notification payload and passes to device type executor.
* @throws PullNotificationExecutionFailedException
*/
void executePullNotification(String deviceType, NotificationContext notificationContext)
throws PullNotificationExecutionFailedException;
} }

@ -28,6 +28,9 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager; import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.DeviceNotFoundException; import org.wso2.carbon.device.mgt.common.DeviceNotFoundException;
import org.wso2.carbon.device.mgt.common.pull.notification.NotificationContext;
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.dto.DeviceTypeServiceIdentifier; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.FeatureManager; import org.wso2.carbon.device.mgt.common.FeatureManager;
@ -2202,4 +2205,25 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
DeviceManagementDAOFactory.closeConnection(); DeviceManagementDAOFactory.closeConnection();
} }
} }
@Override
public void executePullNotification(String deviceType, NotificationContext notificationContext)
throws PullNotificationExecutionFailedException {
DeviceManagementService dms =
pluginRepository.getDeviceManagementService(deviceType, this.getTenantId());
if (dms == null) {
String message = "Device type '" + deviceType + "' does not have an associated device management " +
"plugin registered within the framework";
if (log.isDebugEnabled()) {
log.debug(message);
}
throw new PullNotificationExecutionFailedException(message);
}
PullNotificationSubscriber pullNotificationSubscriber = dms.getPullNotificationSubscriber();
if (pullNotificationSubscriber == null) {
throw new PullNotificationExecutionFailedException("Pull Notification Subscriber is not configured " +
"for device type" + deviceType);
}
pullNotificationSubscriber.execute(notificationContext);
}
} }

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.core;
import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
@ -77,4 +78,9 @@ public class TestDeviceManagementService implements DeviceManagementService {
return null; return null;
} }
@Override
public PullNotificationSubscriber getPullNotificationSubscriber() {
return null;
}
} }

@ -109,8 +109,9 @@
org.wso2.carbon.ndatasource.core, org.wso2.carbon.ndatasource.core,
org.wso2.carbon.registry.core.service, org.wso2.carbon.registry.core.service,
org.wso2.carbon.utils.dbcreator, org.wso2.carbon.utils.dbcreator,
org.wso2.carbon.utils.multitenancy org.wso2.carbon.utils.multitenancy,
</Import-Package> </Import-Package>
<DynamicImport-Package>org.wso2.carbon.device.mgt.extensions.pull.notification.*</DynamicImport-Package>
</instructions> </instructions>
</configuration> </configuration>
</plugin> </plugin>

@ -30,6 +30,7 @@ import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.ConfigProperties; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.ConfigProperties;
@ -39,6 +40,7 @@ import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Propert
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PushNotificationProvider; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PushNotificationProvider;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.TaskConfiguration; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.TaskConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.template.policy.mgt.DefaultPolicyMonitoringManager; import org.wso2.carbon.device.mgt.extensions.device.type.template.policy.mgt.DefaultPolicyMonitoringManager;
import org.wso2.carbon.device.mgt.extensions.device.type.template.pull.notification.PullNotificationSubscriberLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -61,6 +63,7 @@ public class DeviceTypeManagerService implements DeviceManagementService {
private List<MonitoringOperation> monitoringOperations; private List<MonitoringOperation> monitoringOperations;
private PolicyMonitoringManager policyMonitoringManager; private PolicyMonitoringManager policyMonitoringManager;
private InitialOperationConfig initialOperationConfig; private InitialOperationConfig initialOperationConfig;
private PullNotificationSubscriber pullNotificationSubscriber;
public DeviceTypeManagerService(DeviceTypeConfigIdentifier deviceTypeConfigIdentifier, public DeviceTypeManagerService(DeviceTypeConfigIdentifier deviceTypeConfigIdentifier,
DeviceTypeConfiguration deviceTypeConfiguration) { DeviceTypeConfiguration deviceTypeConfiguration) {
@ -76,6 +79,15 @@ public class DeviceTypeManagerService implements DeviceManagementService {
&& deviceTypeConfiguration.getPolicyMonitoring().isEnabled()) { && deviceTypeConfiguration.getPolicyMonitoring().isEnabled()) {
this.policyMonitoringManager = new DefaultPolicyMonitoringManager(); this.policyMonitoringManager = new DefaultPolicyMonitoringManager();
} }
if (deviceTypeConfiguration.getPullNotificationExecutor() != null) {
String className = deviceTypeConfiguration.getPullNotificationExecutor().getClassName();
if (className != null && !className.isEmpty()) {
PullNotificationSubscriberLoader pullNotificationExecutorImpl = new PullNotificationSubscriberLoader(className
, deviceTypeConfiguration.getPullNotificationExecutor().getConfigProperties());
this.pullNotificationSubscriber = pullNotificationExecutorImpl.getPullNotificationSubscriber();
}
}
} }
@Override @Override
@ -176,6 +188,11 @@ public class DeviceTypeManagerService implements DeviceManagementService {
return initialOperationConfig; return initialOperationConfig;
} }
@Override
public PullNotificationSubscriber getPullNotificationSubscriber() {
return pullNotificationSubscriber;
}
private void setProvisioningConfig(String tenantDomain, DeviceTypeConfiguration deviceTypeConfiguration) { private void setProvisioningConfig(String tenantDomain, DeviceTypeConfiguration deviceTypeConfiguration) {
if (deviceTypeConfiguration.getProvisioningConfig() != null) { if (deviceTypeConfiguration.getProvisioningConfig() != null) {
boolean sharedWithAllTenants = deviceTypeConfiguration.getProvisioningConfig().isSharedWithAllTenants(); boolean sharedWithAllTenants = deviceTypeConfiguration.getProvisioningConfig().isSharedWithAllTenants();

@ -61,6 +61,8 @@ public class DeviceTypeConfiguration {
protected ProvisioningConfig provisioningConfig; protected ProvisioningConfig provisioningConfig;
@XmlElement(name = "PushNotificationProvider", required = true) @XmlElement(name = "PushNotificationProvider", required = true)
protected PushNotificationProvider pushNotificationProvider; protected PushNotificationProvider pushNotificationProvider;
@XmlElement(name = "PullNotificationSubscriber", required = true)
protected PullNotificationSubscriber pullNotificationSubscriber;
@XmlElement(name = "License", required = true) @XmlElement(name = "License", required = true)
protected License license; protected License license;
@XmlElement(name = "DataSource", required = true) @XmlElement(name = "DataSource", required = true)
@ -230,6 +232,26 @@ public class DeviceTypeConfiguration {
this.pushNotificationProvider = value; this.pushNotificationProvider = value;
} }
/**
* Gets the value of the pullNotificationSubscriber property.
*
* @return possible object is
* {@link PullNotificationSubscriber }
*/
public PullNotificationSubscriber getPullNotificationExecutor() {
return pullNotificationSubscriber;
}
/**
* Sets the value of the pullNotificationSubscriber property.
*
* @param value allowed object is
* {@link PullNotificationSubscriber }
*/
public void setPullNotificationExecutor(PullNotificationSubscriber value) {
this.pullNotificationSubscriber = value;
}
/** /**
* Gets the value of the license property. * Gets the value of the license property.
* *

@ -0,0 +1,106 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for PullNotificationSubscriber complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="PullNotificationSubscriber">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="ConfigProperties" type="{}ConfigProperties"/>
* &lt;/sequence>
* &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PullNotificationSubscriber", propOrder = {
"configProperties"
})
public class PullNotificationSubscriber {
@XmlElement(name = "ConfigProperties", required = true)
protected ConfigProperties configProperties;
@XmlAttribute(name = "className")
protected String className;
/**
* Gets the value of the configProperties property.
*
* @return
* possible object is
* {@link ConfigProperties }
*
*/
public ConfigProperties getConfigProperties() {
return configProperties;
}
/**
* Sets the value of the configProperties property.
*
* @param value
* allowed object is
* {@link ConfigProperties }
*
*/
public void setConfigProperties(ConfigProperties value) {
this.configProperties = value;
}
/**
* Gets the value of the type property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getClassName() {
return className;
}
/**
* Sets the value of the type property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setClassName(String value) {
this.className = className;
}
}

@ -0,0 +1,43 @@
package org.wso2.carbon.device.mgt.extensions.device.type.template.pull.notification;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.ConfigProperties;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Property;
import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeDeployerPayloadException;
import java.util.HashMap;
import java.util.Map;
/**
* This creates an instance of the pull notification executor strategy with the given class name.
* makes sure the class name starts with the package prefix org.wso2.carbon.device.mgt.pull.notification.*
*/
public class PullNotificationSubscriberLoader {
private PullNotificationSubscriber pullNotificationSubscriber;
public PullNotificationSubscriberLoader(String className, ConfigProperties configProperties) {
try {
Class<? extends PullNotificationSubscriber> pullNotificationExecutorClass
= Class.forName(className).asSubclass(PullNotificationSubscriber.class);
Map<String, String> properties = new HashMap<>();
if (configProperties != null) {
for (Property property : configProperties.getProperty()) {
properties.put(property.getName(), property.getValue());
}
}
pullNotificationSubscriber = pullNotificationExecutorClass.newInstance();
pullNotificationSubscriber.init(properties);
} catch (ClassNotFoundException e) {
throw new DeviceTypeDeployerPayloadException("Unable to find the class pull notification executor: " + className, e);
} catch (InstantiationException e) {
throw new DeviceTypeDeployerPayloadException("Unable to create an instance of :" + className, e);
} catch (IllegalAccessException e) {
throw new DeviceTypeDeployerPayloadException("Access of the instance in not allowed.", e);
}
}
public PullNotificationSubscriber getPullNotificationSubscriber() {
return pullNotificationSubscriber;
}
}

@ -92,6 +92,13 @@
</ConfigProperties> </ConfigProperties>
</PushNotificationProvider> </PushNotificationProvider>
<PullNotificationExecutor className="org.wso2.carbon.device.mgt.pull.notification.proxy.http.HTTPNotificationPublisher">
<ConfigProperties>
<Property Name="url">sample.mqtt.adapter</Property>
<Property Name="authorization">admin</Property>
</ConfigProperties>
</PullNotificationExecutor>
<PolicyMonitoring enabled="true"/> <PolicyMonitoring enabled="true"/>
<License> <License>

@ -387,7 +387,7 @@ deviceModule = function () {
var jwtClient = JWTClientManagerService.getJWTClient(); var jwtClient = JWTClientManagerService.getJWTClient();
// returning access token by JWT grant type // returning access token by JWT grant type
var deviceScope = "device_" + type.replace(" ", "") + "_" + deviceId + " perm:device:enroll " + var deviceScope = "device_" + type.replace(" ", "") + "_" + deviceId + " perm:device:enroll " +
"perm:device:disenroll perm:device:modify perm:devices:operations"; "perm:device:disenroll perm:device:modify perm:device:operations perm:device:publish-event";
var tokenInfo = jwtClient.getAccessToken(config.clientId, config.clientSecret, var tokenInfo = jwtClient.getAccessToken(config.clientId, config.clientSecret,
userName, deviceScope); userName, deviceScope);
config.accessToken = tokenInfo.getAccessToken(); config.accessToken = tokenInfo.getAccessToken();

@ -117,7 +117,7 @@
-d '{ "applicationName":"testme", "isAllowedToAllDomains":false, "tags":["device_agent"]}'</code> -d '{ "applicationName":"testme", "isAllowedToAllDomains":false, "tags":["device_agent"]}'</code>
</li> </li>
<li class="padding-top-double"><span><h3 class="uppercase">Generate Token</h3></span> <li class="padding-top-double"><span><h3 class="uppercase">Generate Token</h3></span>
<code>curl -k -d "grant_type=password&username=%username%&password=%password%&scope=perm:device:enroll perm:device:disenroll perm:device:modify perm:devices:operations" <code>curl -k -d "grant_type=password&username=%username%&password=%password%&scope=perm:device:enroll perm:device:disenroll perm:device:modify perm:device:operations perm:device:publish-event"
-H "Authorization: Basic Base64(client_id:client_secret)" -H "Authorization: Basic Base64(client_id:client_secret)"
-H "Content-Type: application/x-www-form-urlencoded" {{httpsGateway}}/token</code> -H "Content-Type: application/x-www-form-urlencoded" {{httpsGateway}}/token</code>
</li> </li>
@ -242,16 +242,21 @@
MQTT - {{mqttGateway}} MQTT - {{mqttGateway}}
MQTT Topic : <code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/#</code> MQTT Topic : <code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/#</code>
<br/> <br/>
Operation Response:
<code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/update/operation</code>
<br/>
Payload : <code>{operationId:1, payload:"example"}</code>
<br/>
Topic Structure: Topic Structure:
<ul class="list-unstyled"> <ul class="list-unstyled">
<li class="padding-top-double"> <li class="padding-top-double">
<code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/command/&lt;feature_code&gt;</code> <code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/command/&lt;feature_code&gt;&lt;operation_id&gt;</code>
</li> </li>
<li class="padding-top-double"> <li class="padding-top-double">
<code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/config/&lt;feature_code&gt;</code> <code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/config/&lt;feature_code&gt;&lt;operation_id&gt;</code>
</li> </li>
<li class="padding-top-double"> <li class="padding-top-double">
<code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/profile/&lt;feature_code&gt;</code> <code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/profile/&lt;feature_code&gt;&lt;operation_id&gt;</code>
</li> </li>
<li class="padding-top-double"> <li class="padding-top-double">
<code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/policy/policy_bundle</code> <code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/policy/policy_bundle</code>

@ -57,6 +57,10 @@
<groupId>org.wso2.orbit.org.apache.pdfbox</groupId> <groupId>org.wso2.orbit.org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId> <artifactId>pdfbox</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.extensions.pull.notification</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.wso2.carbon.registry</groupId> <groupId>org.wso2.carbon.registry</groupId>
<artifactId>org.wso2.carbon.registry.indexing</artifactId> <artifactId>org.wso2.carbon.registry.indexing</artifactId>
@ -141,6 +145,9 @@
<bundleDef> <bundleDef>
org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.url.printer:${carbon.device.mgt.version} org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.url.printer:${carbon.device.mgt.version}
</bundleDef> </bundleDef>
<bundleDef>
org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.extensions.pull.notification:${carbon.device.mgt.version}
</bundleDef>
<!--<bundleDef>--> <!--<bundleDef>-->
<!--org.wso2.carbon.commons:org.wso2.carbon.email.verification--> <!--org.wso2.carbon.commons:org.wso2.carbon.email.verification-->
<!--</bundleDef>--> <!--</bundleDef>-->

@ -37,6 +37,9 @@
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider</Provider> <Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider</Provider>
</PushNotificationProviders> </PushNotificationProviders>
</PushNotificationConfiguration> </PushNotificationConfiguration>
<PullNotificationConfiguration>
<Enabled>true</Enabled>
</PullNotificationConfiguration>
<IdentityConfiguration> <IdentityConfiguration>
<ServerUrl>https://localhost:9443</ServerUrl> <ServerUrl>https://localhost:9443</ServerUrl>
<AdminUsername>admin</AdminUsername> <AdminUsername>admin</AdminUsername>

@ -1451,6 +1451,11 @@
<artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp</artifactId> <artifactId>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp</artifactId>
<version>${carbon.device.mgt.version}</version> <version>${carbon.device.mgt.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.extensions.pull.notification</artifactId>
<version>${carbon.device.mgt.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId> <groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId> <artifactId>jackson-annotations</artifactId>

Loading…
Cancel
Save