Add multiple push notification support and transport config for features

revert-70aa11f8
warunalakshitha 8 years ago
parent e23ef52e61
commit ad9ec1f994

@ -30,7 +30,6 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceTypeManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import javax.validation.constraints.Size;
@ -38,9 +37,9 @@ import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@Path("/device-types")
@ -79,7 +78,7 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
if (fm == null) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("No feature manager is " +
"registered with the given type '" + type + "'").build()).build();
"registered with the given type '" + type + "'").build()).build();
}
features = fm.getFeatures();
} catch (DeviceManagementException e) {
@ -133,6 +132,7 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
/**
* This cleans up the configs that should not be exposed to iot users.
*
* @param deviceType
* @return
*/
@ -140,9 +140,13 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
DeviceTypeMetaDefinition metaDefinition = deviceType.getDeviceTypeMetaDefinition();
if (metaDefinition != null) {
metaDefinition.setInitialOperationConfig(null);
if (metaDefinition.getPushNotificationConfig() != null) {
metaDefinition.setPushNotificationConfig(new PushNotificationConfig(metaDefinition.
getPushNotificationConfig().getType(), false, null));
if (metaDefinition.getPushNotificationConfigs() != null) {
List<PushNotificationConfig> pushNotificationConfigs = new LinkedList<>();
for (PushNotificationConfig pushNotificationConfig : metaDefinition.getPushNotificationConfigs()) {
pushNotificationConfigs.add(new PushNotificationConfig(pushNotificationConfig.getType(), false,
false, null));
}
metaDefinition.setPushNotificationConfigs(pushNotificationConfigs);
}
deviceType.setDeviceTypeMetaDefinition(metaDefinition);
}

@ -40,6 +40,10 @@ public class Feature implements Serializable {
"such as android, iOS or windows..", required = true )
private String deviceType;
@ApiModelProperty(name = "pushNotificationProviderType", value = "Provides push notification provider for the " +
"feature. If not set default push notification strategy will be used.")
private String pushNotificationType;
@ApiModelProperty(name = "metadataEntries", value = "Properties related to features.", required = true )
private List<MetadataEntry> metadataEntries;
@ -87,6 +91,15 @@ public class Feature implements Serializable {
this.deviceType = deviceType;
}
@XmlElement
public String getPushNotificationType() {
return pushNotificationType;
}
public void setPushNotificationType(String pushNotificationType) {
this.pushNotificationType = pushNotificationType;
}
@XmlElement
public String getDescription() {
return description;

@ -25,6 +25,7 @@ import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import java.util.List;
import java.util.Map;
/**
* This represents the Device Operation management functionality which should be implemented by
@ -107,12 +108,23 @@ public interface OperationManager {
* Operation manger implementation can have a push notification stratergy
* @param notificationStrategy eg: mqtt/xmpp
*/
void setNotificationStrategy(NotificationStrategy notificationStrategy);
void setDefaultNotificationStrategy(NotificationStrategy notificationStrategy);
/**
* retrive the push notification strategy.
* @return NotificationStrategy
*/
NotificationStrategy getNotificationStrategy();
NotificationStrategy getDefaultNotificationStrategy();
/**
* Set notification strategy map which contains feature code to notification strategy map
* @param notificationStrategyMap
*/
public void setNotificationStrategyMap(Map<String, NotificationStrategy> notificationStrategyMap);
/**
* Provides notification strategy Map
* @return Map which contains mapping for feature code to notification strategy
*/
public Map<String, NotificationStrategy> getNotificationStrategyMap();
}

@ -27,12 +27,15 @@ public class PushNotificationConfig {
private String type;
private boolean isScheduled;
private boolean isDefault;
Map<String, String> properties;
public PushNotificationConfig(String type, boolean isScheduled, Map<String, String> properties) {
public PushNotificationConfig(String type, boolean isScheduled, boolean isDefault, Map<String, String>
properties) {
this.type = type;
this.properties = properties;
this.isScheduled = isScheduled;
this.isDefault = isDefault;
}
@XmlElement(name = "Type", required = true)
@ -45,6 +48,11 @@ public class PushNotificationConfig {
return isScheduled;
}
@XmlElement(name = "Default")
public boolean isDefault() {
return isDefault;
}
public Map<String, String> getProperties() {
return properties;
}

@ -24,6 +24,8 @@ 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 java.util.List;
/**
* Composite interface that acts as the SPI exposing all device management as well as application management
* functionalities.
@ -42,7 +44,7 @@ public interface DeviceManagementService {
ProvisioningConfig getProvisioningConfig();
PushNotificationConfig getPushNotificationConfig();
List<PushNotificationConfig> getPushNotificationConfigs();
PolicyMonitoringManager getPolicyMonitoringManager();

@ -2,7 +2,6 @@ package org.wso2.carbon.device.mgt.common.type.mgt;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
@ -13,7 +12,7 @@ public class DeviceTypeMetaDefinition {
private List<String> properties;
private List<Feature> features;
private boolean claimable;
private PushNotificationConfig pushNotificationConfig;
private List<PushNotificationConfig> pushNotificationConfigs;
private boolean policyMonitoringEnabled;
private InitialOperationConfig initialOperationConfig;
private License license;
@ -51,13 +50,13 @@ public class DeviceTypeMetaDefinition {
this.claimable = isClaimable;
}
public PushNotificationConfig getPushNotificationConfig() {
return pushNotificationConfig;
public List<PushNotificationConfig> getPushNotificationConfigs() {
return pushNotificationConfigs;
}
public void setPushNotificationConfig(
PushNotificationConfig pushNotificationConfig) {
this.pushNotificationConfig = pushNotificationConfig;
public void setPushNotificationConfigs(
List<PushNotificationConfig> pushNotificationConfigs) {
this.pushNotificationConfigs = pushNotificationConfigs;
}
public boolean isPolicyMonitoringEnabled() {

@ -22,13 +22,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
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.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationProvider;
@ -37,7 +35,9 @@ import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeDefinitionProvider;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
import org.wso2.carbon.device.mgt.core.dto.DeviceManagementServiceHolder;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagerStartupListener;
@ -51,9 +51,12 @@ import org.wso2.carbon.device.mgt.core.task.DeviceMgtTaskException;
import org.wso2.carbon.device.mgt.core.task.DeviceTaskManagerService;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DeviceManagementPluginRepository implements DeviceManagerStartupListener {
@ -155,8 +158,9 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
OperationManager operationManager = operationManagerRepository.getOperationManager(
deviceTypeIdentifier);
if (operationManager != null) {
NotificationStrategy notificationStrategy = operationManager.getNotificationStrategy();
if (notificationStrategy != null) {
Collection<NotificationStrategy> notificationStrategies = operationManager.getNotificationStrategyMap()
.values();
for (NotificationStrategy notificationStrategy : notificationStrategies) {
notificationStrategy.undeploy();
}
operationManagerRepository.removeOperationManager(deviceTypeIdentifier);
@ -204,7 +208,7 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
long updatedTimestamp = provider.getTimestamp();
if (System.currentTimeMillis() - updatedTimestamp > DEFAULT_UPDATE_TIMESTAMP) {
try {
DeviceType deviceType = DeviceManagerUtil.getDeviceType(type,tenantId);
DeviceType deviceType = DeviceManagerUtil.getDeviceType(type, tenantId);
DeviceTypeMetaDefinition deviceTypeMetaDefinition = deviceType.getDeviceTypeMetaDefinition();
if (deviceTypeMetaDefinition != null) {
Gson gson = new Gson();
@ -213,8 +217,9 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
provider.getDeviceManagementService()).getDeviceTypeMetaDefinition();
String cachedDefinition = gson.toJson(deviceTypeMetaDefinition);
if (!cachedDefinition.equals(dbStoredDefinition)) {
DeviceManagementService deviceTypeManagerService = DeviceManagementDataHolder.getInstance()
.getDeviceTypeGeneratorService().populateDeviceManagementService(type, deviceTypeMetaDefinition);
DeviceManagementService deviceTypeManagerService = DeviceManagementDataHolder
.getInstance().getDeviceTypeGeneratorService()
.populateDeviceManagementService(type, deviceTypeMetaDefinition);
if (deviceTypeManagerService == null) {
log.error("Failing to retrieve the device type service for " + type);
return null;
@ -248,7 +253,7 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
private void registerPushNotificationStrategy(DeviceManagementService deviceManagementService)
throws DeviceManagementException {
PushNotificationConfig pushNoteConfig = deviceManagementService.getPushNotificationConfig();
List<PushNotificationConfig> pushNoteConfigs = deviceManagementService.getPushNotificationConfigs();
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
deviceManagementService.getProvisioningConfig().getProviderTenantDomain(), true);
@ -262,17 +267,40 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
deviceTypeIdentifier = new DeviceTypeServiceIdentifier(deviceManagementService.getType(), tenantId);
}
if (pushNoteConfig != null) {
PushNotificationProvider provider = DeviceManagementDataHolder.getInstance()
.getPushNotificationProviderRepository().getProvider(pushNoteConfig.getType());
if (provider == null) {
if (pushNoteConfigs != null) {
Map<String, NotificationStrategy> notificationStrategyMap = new ConcurrentHashMap<>();
NotificationStrategy defaultNotificationStrategy = null;
for (PushNotificationConfig pushNoteConfig : pushNoteConfigs) {
PushNotificationProvider provider = DeviceManagementDataHolder.getInstance()
.getPushNotificationProviderRepository().getProvider(pushNoteConfig.getType());
if (provider == null) {
throw new DeviceManagementException(
"No registered push notification provider found for the type: '" +
pushNoteConfig.getType() + "'.");
}
NotificationStrategy notificationStrategy = provider.getNotificationStrategy(pushNoteConfig);
if (pushNoteConfig.isDefault()) {
if (defaultNotificationStrategy == null) {
defaultNotificationStrategy = notificationStrategy;
} else {
throw new DeviceManagementException(
"Multiple push notification strategies are set as default. Only one strategy can " +
"be set as default for the device type: '" + deviceTypeIdentifier
.getDeviceType() + "'.");
}
}
notificationStrategyMap.put(pushNoteConfig.getType(), notificationStrategy);
}
if (defaultNotificationStrategy != null) {
operationManagerRepository.addOperationManager(deviceTypeIdentifier,
new OperationManagerImpl(deviceTypeIdentifier.getDeviceType(),
defaultNotificationStrategy, notificationStrategyMap));
} else {
throw new DeviceManagementException(
"No registered push notification provider found for the type: '" +
pushNoteConfig.getType() + "'.");
"No registered default push notification provider found for the device type: '" + deviceTypeIdentifier
.getDeviceType() + "'.");
}
NotificationStrategy notificationStrategy = provider.getNotificationStrategy(pushNoteConfig);
operationManagerRepository.addOperationManager(deviceTypeIdentifier,
new OperationManagerImpl(deviceTypeIdentifier.getDeviceType(), notificationStrategy));
} else {
operationManagerRepository.addOperationManager(deviceTypeIdentifier,
new OperationManagerImpl(deviceTypeIdentifier.getDeviceType()));
@ -377,7 +405,7 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
String deviceTypeName;
synchronized (providers) {
for (DeviceManagementServiceHolder deviceManagementServiceHolder : providers.values()) {
DeviceManagementService provider= deviceManagementServiceHolder.getDeviceManagementService();
DeviceManagementService provider = deviceManagementServiceHolder.getDeviceManagementService();
try {
provider.init();
deviceTypeName = provider.getType();

@ -25,6 +25,8 @@ import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.MonitoringOperation;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
@ -64,6 +66,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* This class implements all the functionality exposed as part of the OperationManager. Any transaction initiated
@ -82,8 +85,10 @@ public class OperationManagerImpl implements OperationManager {
private OperationDAO operationDAO;
private DeviceDAO deviceDAO;
private EnrollmentDAO enrollmentDAO;
private NotificationStrategy notificationStrategy;
private Map<String, NotificationStrategy> notificationStrategyMap;
private NotificationStrategy defaultNotificationStrategy;
private String deviceType;
private FeatureManager featureManager;
public OperationManagerImpl() {
commandOperationDAO = OperationManagementDAOFactory.getCommandOperationDAO();
@ -96,22 +101,35 @@ public class OperationManagerImpl implements OperationManager {
enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO();
}
public OperationManagerImpl(String deviceType) {
public OperationManagerImpl(String deviceType) throws DeviceManagementException {
this();
this.deviceType = deviceType;
featureManager = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider()
.getFeatureManager(deviceType);
}
public NotificationStrategy getNotificationStrategy() {
return notificationStrategy;
public NotificationStrategy getDefaultNotificationStrategy() {
return defaultNotificationStrategy;
}
public void setNotificationStrategy(NotificationStrategy notificationStrategy) {
this.notificationStrategy = notificationStrategy;
public void setDefaultNotificationStrategy(NotificationStrategy defaultNotificationStrategy) {
this.defaultNotificationStrategy = defaultNotificationStrategy;
}
public OperationManagerImpl(String deviceType, NotificationStrategy notificationStrategy) {
public Map<String, NotificationStrategy> getNotificationStrategyMap() {
return notificationStrategyMap;
}
public void setNotificationStrategyMap(Map<String, NotificationStrategy> notificationStrategyMap) {
this.notificationStrategyMap = notificationStrategyMap;
}
public OperationManagerImpl(String deviceType, NotificationStrategy defaultNotificationStrategy, Map<String,
NotificationStrategy> notificationStrategyMap) throws
DeviceManagementException {
this(deviceType);
this.notificationStrategy = notificationStrategy;
this.defaultNotificationStrategy = defaultNotificationStrategy;
this.notificationStrategyMap = notificationStrategyMap;
}
@Override
@ -149,8 +167,17 @@ public class OperationManagerImpl implements OperationManager {
boolean isNotRepeated = false;
boolean isScheduled = false;
// check whether device list is greater than batch size notification strategy has enable to send push
// notification using scheduler task
NotificationStrategy notificationStrategy = null;
Feature feature = featureManager.getFeature(operation.getCode());
if (feature != null && feature.getPushNotificationType() != null) {
notificationStrategy = notificationStrategyMap.get(feature.getPushNotificationType());
}
if (notificationStrategy == null) {
notificationStrategy = defaultNotificationStrategy;
}
if (DeviceConfigurationManager.getInstance().getDeviceManagementConfig().
getPushNotificationConfiguration().getSchedulerBatchSize() <= authorizedDeviceList.size() &&
notificationStrategy != null) {
@ -197,13 +224,15 @@ public class OperationManagerImpl implements OperationManager {
operation.setId(operationId);
operation.setActivityId(DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId);
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) {
log.error("Error occurred while sending push notifications to " +
deviceId.getType() + " device carrying id '" +
deviceId + "'", e);
// Reschedule if push notification failed.
operationMappingDAO.updateOperationMapping(operationId, enrolmentId, org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.PushNotificationStatus.SCHEDULED);
operationMappingDAO.updateOperationMapping(operationId, enrolmentId, org.wso2.carbon
.device.mgt.core.dto.operation.mgt.Operation.PushNotificationStatus.SCHEDULED);
}
}
}
@ -230,6 +259,9 @@ public class OperationManagerImpl implements OperationManager {
throw new OperationManagementException("Error occurred while adding operation", e);
} catch (TransactionManagementException e) {
throw new OperationManagementException("Error occurred while initiating the transaction", e);
} catch (DeviceManagementException e) {
throw new OperationManagementException("Error occurred while getting feature for given operation code :"
+ operation.getCode(), e);
} finally {
OperationManagementDAOFactory.closeConnection();
}
@ -242,7 +274,7 @@ public class OperationManagerImpl implements OperationManager {
//Add the invalid DeviceIds
for (String id : deviceIdValidationResult.getErrorDeviceIdList()) {
activityStatus = new ActivityStatus();
activityStatus.setDeviceIdentifier(new DeviceIdentifier(id,deviceType));
activityStatus.setDeviceIdentifier(new DeviceIdentifier(id, deviceType));
activityStatus.setStatus(ActivityStatus.Status.INVALID);
activityStatuses.add(activityStatus);
}

@ -28,6 +28,7 @@ import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationExecutionFailedException;
import java.util.List;
import java.util.Map;
public class PushNotificationBasedOperationManager implements OperationManager {
@ -142,13 +143,24 @@ public class PushNotificationBasedOperationManager implements OperationManager {
}
@Override
public void setNotificationStrategy(NotificationStrategy notificationStrategy) {
public void setDefaultNotificationStrategy(NotificationStrategy notificationStrategy) {
}
@Override
public NotificationStrategy getNotificationStrategy() {
return notificationProvider;
public NotificationStrategy getDefaultNotificationStrategy() {
return null;
}
@Override
public void setNotificationStrategyMap(Map<String, NotificationStrategy> notificationStrategyMap) {
}
@Override
public Map<String, NotificationStrategy> getNotificationStrategyMap() {
return null;
}
}

@ -21,6 +21,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
@ -83,12 +85,24 @@ public class PushNotificationSchedulerTask implements Runnable {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(operationMapping.getTenantId(), true);
// Get notification strategy for given device type
NotificationStrategy notificationStrategy = provider.getNotificationStrategyByDeviceType
(operationMapping.getDeviceIdentifier().getType());
NotificationStrategy notificationStrategy = null;
org.wso2.carbon.device.mgt.common.operation.mgt.Operation operation = provider.getOperation(operationMapping.getDeviceIdentifier().getType(), operationMapping
.getOperationId());
FeatureManager featureManager = provider.getFeatureManager(operationMapping.getDeviceIdentifier().getType());
Feature feature = featureManager.getFeature(operation.getCode());
if (feature != null) {
Map<String, NotificationStrategy> notificationStrategyListByDeviceType = provider.getNotificationStrategyListByDeviceType(operationMapping.getDeviceIdentifier().getType());
if (notificationStrategyListByDeviceType != null && feature.getPushNotificationType() != null) {
notificationStrategy = notificationStrategyListByDeviceType.get(feature.getPushNotificationType());
}
}
if (notificationStrategy == null) {
notificationStrategy = provider.getDefaultNotificationStrategyByDeviceType(operationMapping.getDeviceIdentifier()
.getType());
}
// Send the push notification on given strategy
notificationStrategy.execute(new NotificationContext(operationMapping.getDeviceIdentifier(),
provider.getOperation(operationMapping.getDeviceIdentifier().getType(), operationMapping
.getOperationId())));
operation));
operationMapping.setPushNotificationStatus(Operation.PushNotificationStatus.COMPLETED);
operationsCompletedList.add(operationMapping);
} catch (DeviceManagementException e) {

@ -39,7 +39,9 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Proxy class for all Device Management related operations that take the corresponding plugin type in
@ -471,7 +473,10 @@ public interface DeviceManagementProviderService {
* @return Notification Strategy for device type
* @throws DeviceManagementException
*/
NotificationStrategy getNotificationStrategyByDeviceType(String deviceType) throws DeviceManagementException;
NotificationStrategy getDefaultNotificationStrategyByDeviceType(String deviceType) throws DeviceManagementException;
Map<String, NotificationStrategy> getNotificationStrategyListByDeviceType(String deviceType) throws
DeviceManagementException;
License getLicense(String deviceType, String languageCode) throws DeviceManagementException;

@ -28,9 +28,6 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.DeviceNotFoundException;
import org.wso2.carbon.device.mgt.common.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.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
@ -55,6 +52,8 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
@ -69,6 +68,7 @@ import org.wso2.carbon.device.mgt.core.dao.EnrollmentDAO;
import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsDAO;
import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsMgtDAOException;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.internal.PluginInitializationListener;
@ -1428,11 +1428,24 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
@Override
public NotificationStrategy getNotificationStrategyByDeviceType(String deviceType) throws DeviceManagementException {
public NotificationStrategy getDefaultNotificationStrategyByDeviceType(String deviceType) throws
DeviceManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
OperationManager operationManager = pluginRepository.getOperationManager(deviceType, tenantId);
if (operationManager != null) {
return operationManager.getDefaultNotificationStrategy();
} else {
throw new DeviceManagementException("Cannot find operation manager for given device type :" + deviceType);
}
}
@Override
public Map<String, NotificationStrategy> getNotificationStrategyListByDeviceType(String deviceType) throws
DeviceManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
OperationManager operationManager = pluginRepository.getOperationManager(deviceType, tenantId);
if (operationManager != null) {
return operationManager.getNotificationStrategy();
return operationManager.getNotificationStrategyMap();
} else {
throw new DeviceManagementException("Cannot find operation manager for given device type :" + deviceType);
}
@ -1662,8 +1675,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
DeviceManagementService dms =
pluginRepository.getDeviceManagementService(deviceIdentifier.getType(), this.getTenantId());
if (dms == null) {
String message = "Device type '" + deviceIdentifier.getType() + "' does not have an associated device management " +
"plugin registered within the framework";
String message = "Device type '" + deviceIdentifier.getType() + "' does not have an associated device " +
"management " + "plugin registered within the framework";
if (log.isDebugEnabled()) {
log.debug(message);
}

@ -24,6 +24,8 @@ import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubsc
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import java.util.List;
public class TestDeviceManagementService implements DeviceManagementService {
private String providerType;
@ -63,8 +65,7 @@ public class TestDeviceManagementService implements DeviceManagementService {
return new ProvisioningConfig(tenantDomain, false);
}
@Override
public PushNotificationConfig getPushNotificationConfig() {
public List<PushNotificationConfig> getPushNotificationConfigs() {
return null;
}

@ -22,10 +22,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
import org.wso2.carbon.device.mgt.common.MonitoringOperation;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
@ -42,12 +42,14 @@ import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PolicyM
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Property;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PullNotificationSubscriberConfig;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PushNotificationProvider;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PushNotificationProviders;
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.pull.notification.PullNotificationSubscriberLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -60,7 +62,7 @@ public class DeviceTypeManagerService implements DeviceManagementService {
private static final Log log = LogFactory.getLog(DeviceTypeManagerService.class);
private DeviceManager deviceManager;
private PushNotificationConfig pushNotificationConfig;
private List<PushNotificationConfig> pushNotificationConfigs;
private ProvisioningConfig provisioningConfig;
private String type;
private OperationMonitoringTaskConfig operationMonitoringConfigs;
@ -75,7 +77,7 @@ public class DeviceTypeManagerService implements DeviceManagementService {
this.setProvisioningConfig(deviceTypeConfigIdentifier.getTenantDomain(), deviceTypeConfiguration);
this.deviceManager = new DeviceTypeManager(deviceTypeConfigIdentifier, deviceTypeConfiguration);
this.setType(deviceTypeConfiguration.getName());
this.populatePushNotificationConfig(deviceTypeConfiguration.getPushNotificationProvider());
this.populatePushNotificationConfig(deviceTypeConfiguration.getPushNotificationProviders());
this.operationMonitoringConfigs = new OperationMonitoringTaskConfig();
this.setOperationMonitoringConfig(deviceTypeConfiguration);
this.initialOperationConfig = new InitialOperationConfig();
@ -92,7 +94,7 @@ public class DeviceTypeManagerService implements DeviceManagementService {
}
@Override
public OperationMonitoringTaskConfig getOperationMonitoringConfig(){
public OperationMonitoringTaskConfig getOperationMonitoringConfig() {
return operationMonitoringConfigs;
}
@ -120,35 +122,42 @@ public class DeviceTypeManagerService implements DeviceManagementService {
public void init() throws DeviceManagementException {
}
private void populatePushNotificationConfig(PushNotificationProvider pushNotificationProvider) {
if (pushNotificationProvider != null) {
if (pushNotificationProvider.isFileBasedProperties()) {
Map<String, String> staticProps = new HashMap<>();
ConfigProperties configProperties = pushNotificationProvider.getConfigProperties();
if (configProperties != null) {
List<Property> properties = configProperties.getProperty();
if (properties != null && properties.size() > 0) {
for (Property property : properties) {
staticProps.put(property.getName(), property.getValue());
private void populatePushNotificationConfig(PushNotificationProviders pushNotificationProviders) {
if (pushNotificationProviders != null) {
pushNotificationConfigs = new LinkedList<>();
List<PushNotificationProvider> notificationProviders = pushNotificationProviders.getPushNotificationProviders();
for (PushNotificationProvider pushNotificationProvider : notificationProviders) {
if (pushNotificationProvider != null) {
if (pushNotificationProvider.isFileBasedProperties()) {
Map<String, String> staticProps = new HashMap<>();
ConfigProperties configProperties = pushNotificationProvider.getConfigProperties();
if (configProperties != null) {
List<Property> properties = configProperties.getProperty();
if (properties != null && properties.size() > 0) {
for (Property property : properties) {
staticProps.put(property.getName(), property.getValue());
}
}
}
}
}
pushNotificationConfig = new PushNotificationConfig(pushNotificationProvider.getType(),
pushNotificationProvider.isScheduled(), staticProps);
} else {
try {
PlatformConfiguration deviceTypeConfig = deviceManager.getConfiguration();
if (deviceTypeConfig != null) {
List<ConfigurationEntry> configuration = deviceTypeConfig.getConfiguration();
if (configuration.size() > 0) {
Map<String, String> properties = this.getConfigProperty(configuration);
pushNotificationConfig = new PushNotificationConfig(
pushNotificationProvider.getType(), pushNotificationProvider.isScheduled(),
properties);
pushNotificationConfigs.add(new PushNotificationConfig(pushNotificationProvider.getType(),
pushNotificationProvider.isScheduled(), pushNotificationProvider.isDefault(), staticProps));
} else {
try {
PlatformConfiguration deviceTypeConfig = deviceManager.getConfiguration();
if (deviceTypeConfig != null) {
List<ConfigurationEntry> configuration = deviceTypeConfig.getConfiguration();
if (configuration.size() > 0) {
Map<String, String> properties = this.getConfigProperty(configuration);
pushNotificationConfigs.add(new PushNotificationConfig(
pushNotificationProvider.getType(), pushNotificationProvider.isScheduled(),
pushNotificationProvider.isDefault(),
properties));
}
}
} catch (DeviceManagementException e) {
log.error("Unable to get the " + type + " platform configuration from registry.");
}
}
} catch (DeviceManagementException e) {
log.error("Unable to get the " + type + " platform configuration from registry.");
}
}
}
@ -169,9 +178,8 @@ public class DeviceTypeManagerService implements DeviceManagementService {
return provisioningConfig;
}
@Override
public PushNotificationConfig getPushNotificationConfig() {
return pushNotificationConfig;
public List<PushNotificationConfig> getPushNotificationConfigs() {
return pushNotificationConfigs;
}
@Override

@ -29,15 +29,16 @@ import org.wso2.carbon.device.mgt.extensions.device.type.template.config.ConfigP
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceDetails;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Features;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.License;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PolicyMonitoring;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Properties;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Property;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.ProvisioningConfig;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PullNotificationSubscriberConfig;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PushNotificationProvider;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.PushNotificationProviders;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -84,6 +85,7 @@ public class HTTPDeviceTypeManagerService extends DeviceTypeManagerService imple
configFeature.setCode(feature.getCode());
configFeature.setDescription(feature.getDescription());
configFeature.setName(feature.getName());
configFeature.setPushNotificationType(feature.getPushNotificationType());
if (feature.getMetadataEntries() != null && feature.getMetadataEntries().size() > 0) {
List<String> metaValues = new ArrayList<>();
for (Feature.MetadataEntry metadataEntry : feature.getMetadataEntries()) {
@ -115,29 +117,37 @@ public class HTTPDeviceTypeManagerService extends DeviceTypeManagerService imple
provisioningConfig.setSharedWithAllTenants(false);
deviceTypeConfiguration.setProvisioningConfig(provisioningConfig);
PushNotificationConfig pushNotificationConfig = deviceTypeMetaDefinition.getPushNotificationConfig();
if (pushNotificationConfig != null) {
PushNotificationProvider pushNotificationProvider = new PushNotificationProvider();
pushNotificationProvider.setType(pushNotificationConfig.getType());
//default schedule value will be true.
pushNotificationProvider.setScheduled(true);
if (pushNotificationConfig.getProperties() != null &&
pushNotificationConfig.getProperties().size() > 0) {
ConfigProperties configProperties = new ConfigProperties();
List<Property> properties = new ArrayList<>();
for (Map.Entry<String, String> entry : pushNotificationConfig.getProperties().entrySet()) {
Property property = new Property();
property.setName(entry.getKey());
property.setValue(entry.getValue());
properties.add(property);
List<PushNotificationConfig> pushNotificationConfigs = deviceTypeMetaDefinition
.getPushNotificationConfigs();
if (pushNotificationConfigs != null) {
List<PushNotificationProvider> pushNotificationProviderList = new LinkedList<>();
PushNotificationProviders pushNotificationProviders = new PushNotificationProviders();
for (PushNotificationConfig pushNotificationConfig : pushNotificationConfigs) {
PushNotificationProvider pushNotificationProvider = new PushNotificationProvider();
pushNotificationProvider.setType(pushNotificationConfig.getType());
//default schedule value will be true.
pushNotificationProvider.setScheduled(true);
if (pushNotificationConfig.getProperties() != null &&
pushNotificationConfig.getProperties().size() > 0) {
ConfigProperties configProperties = new ConfigProperties();
List<Property> properties = new ArrayList<>();
for (Map.Entry<String, String> entry : pushNotificationConfig.getProperties().entrySet()) {
Property property = new Property();
property.setName(entry.getKey());
property.setValue(entry.getValue());
properties.add(property);
}
configProperties.addProperties(properties);
pushNotificationProvider.setConfigProperties(configProperties);
}
configProperties.addProperties(properties);
pushNotificationProvider.setConfigProperties(configProperties);
pushNotificationProvider.setFileBasedProperties(true);
pushNotificationProviderList.add(pushNotificationProvider);
}
pushNotificationProvider.setFileBasedProperties(true);
deviceTypeConfiguration.setPushNotificationProvider(pushNotificationProvider);
pushNotificationProviders.addPushNotificationProviders(pushNotificationProviderList);
deviceTypeConfiguration.setPushNotificationProviders(pushNotificationProviders);
}
// This is commented until the task registration handling issue is solved
// OperationMonitoringTaskConfig operationMonitoringTaskConfig = deviceTypeMetaDefinition.getTaskConfig();
// if (operationMonitoringTaskConfig != null) {

@ -41,6 +41,7 @@ import java.util.List;
* &lt;element name="Features" type="{}Features"/>
* &lt;element name="ProvisioningConfig" type="{}ProvisioningConfig"/>
* &lt;element name="PushNotificationProviderConfig" type="{}PushNotificationProviderConfig"/>
* &lt;element name="PullNotificationSubscriberConfig" type="{}PullNotificationSubscriberConfig"/>
* &lt;element name="License" type="{}License"/>
* &lt;element name="DataSource" type="{}DataSource"/>
* &lt;element name="PolicyMonitoring" type="{}PolicyMonitoring"/>
@ -65,8 +66,8 @@ public class DeviceTypeConfiguration {
protected Features features;
@XmlElement(name = "ProvisioningConfig", required = true)
protected ProvisioningConfig provisioningConfig;
@XmlElement(name = "PushNotificationProviderConfig", required = true)
protected PushNotificationProvider pushNotificationProvider;
@XmlElement(name = "PushNotificationProviderConfigs", required = true)
protected PushNotificationProviders pushNotificationProviders;
@XmlElement(name = "PullNotificationSubscriberConfig", required = true)
protected PullNotificationSubscriberConfig pullNotificationSubscriberConfig;
@XmlElement(name = "License", required = true)
@ -245,23 +246,23 @@ public class DeviceTypeConfiguration {
}
/**
* Gets the value of the pushNotificationProvider property.
* Gets the value of the pushNotificationProviders property.
*
* @return possible object is
* {@link PushNotificationProvider }
*/
public PushNotificationProvider getPushNotificationProvider() {
return pushNotificationProvider;
public PushNotificationProviders getPushNotificationProviders() {
return pushNotificationProviders;
}
/**
* Sets the value of the pushNotificationProvider property.
* Sets the value of the pushNotificationProviders property.
*
* @param value allowed object is
* {@link PushNotificationProvider }
*/
public void setPushNotificationProvider(PushNotificationProvider value) {
this.pushNotificationProvider = value;
public void setPushNotificationProviders(PushNotificationProviders value) {
this.pushNotificationProviders = value;
}
/**

@ -42,6 +42,7 @@ import java.util.List;
* &lt;element name="Operation" type="{}Operation"/>
* &lt;/sequence>
* &lt;attribute name="code" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="pushNotificationType" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
@ -68,6 +69,8 @@ public class Feature {
@XmlElementWrapper(name = "MetaData")
@XmlElement(name = "Property", required = true)
protected List<String> metaData;
@XmlAttribute(name = "pushNotificationType")
protected String pushNotificationType;
/**
* Gets the value of the name property.
@ -172,4 +175,28 @@ public class Feature {
public void setMetaData(List<String> metaData) {
this.metaData = metaData;
}
/**
* Gets the value of the pushNotificationType property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPushNotificationType() {
return pushNotificationType;
}
/**
* Sets the value of the pushNotificationType property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPushNotificationType(String value) {
this.pushNotificationType = value;
}
}

@ -39,6 +39,8 @@ import javax.xml.bind.annotation.XmlType;
* &lt;element name="ConfigProperties" type="{}ConfigProperties"/>
* &lt;/sequence>
* &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="isScheduled" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="default" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
@ -61,6 +63,8 @@ public class PushNotificationProvider {
protected String type;
@XmlAttribute(name = "isScheduled")
protected boolean isScheduled;
@XmlAttribute(name = "default")
protected boolean isDefault;
/**
* Gets the value of the fileBasedProperties property.
@ -152,4 +156,30 @@ public class PushNotificationProvider {
public void setScheduled(boolean scheduled) {
isScheduled = scheduled;
}
/**
* Gets the value of the isDefault property.
* This property will be used to determine whether the given push notification will be used as Default for
* features which do not have push notification provider config
*
* @return
* possible object is
* {@link Boolean }
*
*/
public boolean isDefault() {
return isDefault;
}
/**
* Sets the value of the isDefault property.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public void setDefault(boolean isDefault) {
isScheduled = isDefault;
}
}

@ -0,0 +1,74 @@
/*
* 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.XmlElement;
import javax.xml.bind.annotation.XmlType;
import java.util.ArrayList;
import java.util.List;
/**
* <p>Java class for PushNotificationProviders complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="PushNotificationProviders">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="PushNotificationProvider" type="{}PushNotificationProvider"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PushNotificationProviders", propOrder = {
"pushNotificationProviders"
})
public class PushNotificationProviders {
@XmlElement(name = "PushNotificationProviderConfig")
protected List<PushNotificationProvider> pushNotificationProviders;
/**
* Gets the value of the pushNotificationProviders property.
*
* @return
* possible object is
* {@link PushNotificationProvider }
*
*/
public List<PushNotificationProvider> getPushNotificationProviders() {
if (pushNotificationProviders == null) {
pushNotificationProviders = new ArrayList<PushNotificationProvider>();
}
return this.pushNotificationProviders;
}
public void addPushNotificationProviders(List<PushNotificationProvider> pushNotificationProviders) {
this.pushNotificationProviders = pushNotificationProviders;
}
}

@ -50,6 +50,7 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
deviceFeature.setCode(feature.getCode());
deviceFeature.setName(feature.getName());
deviceFeature.setDescription(feature.getDescription());
deviceFeature.setPushNotificationType(feature.getPushNotificationType());
Operation operation = feature.getOperation();
List<Feature.MetadataEntry> metadataEntries = null;
if (feature.getMetaData() != null) {

Loading…
Cancel
Save