Merge pull request #301 from ayyoob/transport

Added support for push notification(xmpp, mqtt)
revert-70aa11f8
Ruwan 9 years ago committed by GitHub
commit 66f4c0607d

@ -115,6 +115,10 @@
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
<plugin> <plugin>
<groupId>org.apache.felix</groupId> <groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId> <artifactId>maven-bundle-plugin</artifactId>
@ -137,7 +141,9 @@
org.wso2.carbon.device.mgt.common.push.notification, org.wso2.carbon.device.mgt.common.push.notification,
org.wso2.carbon.device.mgt.core.service, org.wso2.carbon.device.mgt.core.service,
org.wso2.carbon.event.output.adapter.core, org.wso2.carbon.event.output.adapter.core,
org.wso2.carbon.event.output.adapter.core.exception org.wso2.carbon.event.output.adapter.core.exception,
org.osgi.framework,
org.wso2.carbon.core
</Import-Package> </Import-Package>
</instructions> </instructions>
</configuration> </configuration>

@ -18,5 +18,29 @@
*/ */
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt; package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt;
public class InvalidConfigurationException { /**
* This exception is thrown whether the mqtt configured with invalid configuration.
*/
public class InvalidConfigurationException extends RuntimeException {
public InvalidConfigurationException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public InvalidConfigurationException(String message, Throwable cause) {
super(message, cause);
}
public InvalidConfigurationException(String msg) {
super(msg);
}
public InvalidConfigurationException() {
super();
}
public InvalidConfigurationException(Throwable cause) {
super(cause);
}
} }

@ -18,6 +18,8 @@
*/ */
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt; package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext; import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy; import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
@ -33,15 +35,16 @@ import java.util.Map;
public class MQTTNotificationStrategy implements NotificationStrategy { public class MQTTNotificationStrategy implements NotificationStrategy {
private static final String MQTT_ADAPTER_PROPERTY_NAME = "mqtt.adapter.name";
private static final String MQTT_ADAPTER_TOPIC = "mqtt.adapter.topic"; private static final String MQTT_ADAPTER_TOPIC = "mqtt.adapter.topic";
private static final String MQTT_ADAPTER_NAME = "mqtt.push.notification.publisher"; private String mqttAdapterName;
private static final Log log = LogFactory.getLog(MQTTNotificationStrategy.class);
public MQTTNotificationStrategy(PushNotificationConfig config) { public MQTTNotificationStrategy(PushNotificationConfig config) {
OutputEventAdapterConfiguration adapterConfig = new OutputEventAdapterConfiguration(); OutputEventAdapterConfiguration adapterConfig = new OutputEventAdapterConfiguration();
adapterConfig.setType(MQTTAdapterConstants.MQTT_ADAPTER_TYPE); adapterConfig.setType(MQTTAdapterConstants.MQTT_ADAPTER_TYPE);
adapterConfig.setName(MQTT_ADAPTER_NAME); mqttAdapterName = config.getProperty(MQTTAdapterConstants.MQTT_ADAPTER_PROPERTY_NAME);
adapterConfig.setMessageFormat(MessageType.JSON); adapterConfig.setName(mqttAdapterName);
adapterConfig.setMessageFormat(MessageType.TEXT);
Map<String, String> configProperties = new HashMap<String, String>(); Map<String, String> configProperties = new HashMap<String, String>();
configProperties.put(MQTTAdapterConstants.MQTT_ADAPTER_PROPERTY_BROKER_URL, configProperties.put(MQTTAdapterConstants.MQTT_ADAPTER_PROPERTY_BROKER_URL,
@ -60,7 +63,7 @@ public class MQTTNotificationStrategy implements NotificationStrategy {
try { try {
MQTTDataHolder.getInstance().getOutputEventAdapterService().create(adapterConfig); MQTTDataHolder.getInstance().getOutputEventAdapterService().create(adapterConfig);
} catch (OutputEventAdapterException e) { } catch (OutputEventAdapterException e) {
throw new RuntimeException("Error occurred while initializing MQTT output event adapter", e); throw new InvalidConfigurationException("Error occurred while initializing MQTT output event adapter", e);
} }
} }
@ -71,10 +74,10 @@ public class MQTTNotificationStrategy implements NotificationStrategy {
@Override @Override
public void execute(NotificationContext ctx) throws PushNotificationExecutionFailedException { public void execute(NotificationContext ctx) throws PushNotificationExecutionFailedException {
Map<String, String> dynamicProperties = ctx.getProperties(); Map<String, String> dynamicProperties = new HashMap<>();
dynamicProperties.put("topic", (String) ctx.getOperation().getProperties().get(MQTT_ADAPTER_TOPIC)); dynamicProperties.put("topic", (String) ctx.getOperation().getProperties().get(MQTT_ADAPTER_TOPIC));
MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(MQTT_ADAPTER_NAME, dynamicProperties, MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(mqttAdapterName, dynamicProperties,
ctx.getOperation().getPayLoad()); ctx.getOperation().getPayLoad());
} }
@Override @Override

@ -1,46 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
public class MQTTPushNotificationStrategyUtil {
private static final Log log = LogFactory.getLog(MQTTPushNotificationStrategyUtil.class);
public static String getAuthenticatedUser() {
CarbonContext carbonContext = CarbonContext.getThreadLocalCarbonContext();
String username = carbonContext.getUsername();
String tenantDomain = carbonContext.getTenantDomain();
if (username.endsWith(tenantDomain)) {
return username.substring(0, username.lastIndexOf("@"));
}
return username;
}
public static String getAuthenticatedUserTenantDomain() {
return CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
}
}

@ -19,8 +19,12 @@
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.internal; package org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.internal;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
import java.util.List;
import java.util.Stack;
public class MQTTDataHolder { public class MQTTDataHolder {
private OutputEventAdapterService outputEventAdapterService; private OutputEventAdapterService outputEventAdapterService;

@ -25,7 +25,7 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
/** /**
* @scr.component name="org.wso2.carbon.device.mgt.extensions.push.notification.provider.gcm.internal.MQTTPushNotificationServiceComponent" immediate="true" * @scr.component name="org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.internal.MQTTPushNotificationServiceComponent" immediate="true"
* @scr.reference name="carbon.device.mgt.provider" * @scr.reference name="carbon.device.mgt.provider"
* interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService" * interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService"
* cardinality="1..1" * cardinality="1..1"
@ -34,7 +34,9 @@ import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
* unbind="unsetDeviceManagementProviderService" * unbind="unsetDeviceManagementProviderService"
* @scr.reference name="event.output.adapter.service" * @scr.reference name="event.output.adapter.service"
* interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService" * interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService"
* cardinality="1..1" policy="dynamic" bind="setOutputEventAdapterService" * cardinality="1..1"
* policy="dynamic"
* bind="setOutputEventAdapterService"
* unbind="unsetOutputEventAdapterService" * unbind="unsetOutputEventAdapterService"
*/ */
public class MQTTPushNotificationServiceComponent { public class MQTTPushNotificationServiceComponent {

@ -29,9 +29,8 @@ public final class MQTTAdapterConstants {
public static final String MQTT_ADAPTER_PROPERTY_USERNAME = "username"; public static final String MQTT_ADAPTER_PROPERTY_USERNAME = "username";
public static final String MQTT_ADAPTER_PROPERTY_DCR_URL = "dcrUrl"; public static final String MQTT_ADAPTER_PROPERTY_DCR_URL = "dcrUrl";
public static final String MQTT_ADAPTER_PROPERTY_SCOPES = "scopes"; public static final String MQTT_ADAPTER_PROPERTY_SCOPES = "scopes";
public static final String MQTT_ADAPTER_PROPERTY_PASSWORD = "password";
public static final String MQTT_ADAPTER_PROPERTY_CLIENT_ID = "clientId";
public static final String MQTT_ADAPTER_PROPERTY_CLEAR_SESSION = "cleanSession"; public static final String MQTT_ADAPTER_PROPERTY_CLEAR_SESSION = "cleanSession";
public static final String MQTT_ADAPTER_PROPERTY_MESSAGE_QOS = "qos"; public static final String MQTT_ADAPTER_PROPERTY_MESSAGE_QOS = "qos";
public static final String MQTT_ADAPTER_PROPERTY_NAME = "mqtt.adapter.name";
} }

@ -115,6 +115,10 @@
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
<plugin> <plugin>
<groupId>org.apache.felix</groupId> <groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId> <artifactId>maven-bundle-plugin</artifactId>
@ -132,8 +136,14 @@
<Import-Package> <Import-Package>
org.apache.commons.logging, org.apache.commons.logging,
org.osgi.service.component, org.osgi.service.component,
org.wso2.carbon.context,
org.wso2.carbon.device.mgt.common.operation.mgt,
org.wso2.carbon.device.mgt.common.push.notification, org.wso2.carbon.device.mgt.common.push.notification,
org.wso2.carbon.device.mgt.core.service org.wso2.carbon.device.mgt.core.service,
org.wso2.carbon.event.output.adapter.core,
org.wso2.carbon.event.output.adapter.core.exception,
org.osgi.framework,
org.wso2.carbon.core
</Import-Package> </Import-Package>
</instructions> </instructions>
</configuration> </configuration>

@ -0,0 +1,46 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp;
/**
* This exception is thrown whether the xmpp configured with invalid configuration.
*/
public class InvalidConfigurationException extends RuntimeException {
public InvalidConfigurationException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public InvalidConfigurationException(String message, Throwable cause) {
super(message, cause);
}
public InvalidConfigurationException(String msg) {
super(msg);
}
public InvalidConfigurationException() {
super();
}
public InvalidConfigurationException(Throwable cause) {
super(cause);
}
}

@ -31,7 +31,7 @@ public class XMPPBasedPushNotificationProvider implements PushNotificationProvid
@Override @Override
public NotificationStrategy getNotificationStrategy(PushNotificationConfig pushNotificationConfig) { public NotificationStrategy getNotificationStrategy(PushNotificationConfig pushNotificationConfig) {
return null; return new XMPPNotificationStrategy(pushNotificationConfig);
} }
} }

@ -18,12 +18,56 @@
*/ */
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp; package org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext; import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy; import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationExecutionFailedException; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.internal.XMPPDataHolder;
import org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.internal.util.XMPPAdapterConstants;
import org.wso2.carbon.event.output.adapter.core.MessageType;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class XMPPNotificationStrategy implements NotificationStrategy { public class XMPPNotificationStrategy implements NotificationStrategy {
private static final String XMPP_CLIENT_JID = "xmpp.client.jid";
private static final String XMPP_CLIENT_SUBJECT = "xmpp.client.subject";
public static final String XMPP_CLIENT_MESSAGE_TYPE = "xmpp.client.messageType";
private String xmppAdapterName;
private static final Log log = LogFactory.getLog(XMPPNotificationStrategy.class);
public XMPPNotificationStrategy(PushNotificationConfig config) {
OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration();
xmppAdapterName = config.getProperty(XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_NAME);
outputEventAdapterConfiguration.setName(xmppAdapterName);
outputEventAdapterConfiguration.setType(XMPPAdapterConstants.XMPP_ADAPTER_TYPE);
outputEventAdapterConfiguration.setMessageFormat(MessageType.TEXT);
Map<String, String> xmppAdapterProperties = new HashMap<>();
xmppAdapterProperties.put(XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_HOST, config.getProperty(
XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_HOST));
xmppAdapterProperties.put(XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_PORT, config.getProperty(
XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_PORT));
xmppAdapterProperties.put(XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_USERNAME, config.getProperty(
XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_USERNAME));
xmppAdapterProperties.put(XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_PASSWORD, config.getProperty(
XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_PASSWORD));
xmppAdapterProperties.put(XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_JID, config.getProperty(
XMPPAdapterConstants.XMPP_ADAPTER_PROPERTY_JID));
outputEventAdapterConfiguration.setStaticProperties(xmppAdapterProperties);
try {
XMPPDataHolder.getInstance().getOutputEventAdapterService().create(outputEventAdapterConfiguration);
} catch (OutputEventAdapterException e) {
throw new InvalidConfigurationException("Error occurred while initializing MQTT output event adapter", e);
}
}
@Override @Override
public void init() { public void init() {
@ -31,7 +75,13 @@ public class XMPPNotificationStrategy implements NotificationStrategy {
@Override @Override
public void execute(NotificationContext ctx) throws PushNotificationExecutionFailedException { public void execute(NotificationContext ctx) throws PushNotificationExecutionFailedException {
Map<String, String> dynamicProperties = new HashMap<>();
Properties properties = ctx.getOperation().getProperties();
dynamicProperties.put("jid", properties.getProperty(XMPP_CLIENT_JID));
dynamicProperties.put("subject", properties.getProperty(XMPP_CLIENT_SUBJECT));
dynamicProperties.put("messageType", properties.getProperty(XMPP_CLIENT_MESSAGE_TYPE));
XMPPDataHolder.getInstance().getOutputEventAdapterService().publish(xmppAdapterName, dynamicProperties,
ctx.getOperation().getPayLoad());
} }
@Override @Override

@ -19,11 +19,13 @@
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.internal; package org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.internal;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
public class XMPPDataHolder { public class XMPPDataHolder {
private DeviceManagementProviderService deviceManagementProviderService; private DeviceManagementProviderService deviceManagementProviderService;
private static XMPPDataHolder thisInstance = new XMPPDataHolder(); private static XMPPDataHolder thisInstance = new XMPPDataHolder();
private OutputEventAdapterService outputEventAdapterService;
public static XMPPDataHolder getInstance() { public static XMPPDataHolder getInstance() {
return thisInstance; return thisInstance;
@ -37,4 +39,12 @@ public class XMPPDataHolder {
this.deviceManagementProviderService = deviceManagementProviderService; this.deviceManagementProviderService = deviceManagementProviderService;
} }
public void setOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) {
this.outputEventAdapterService = outputEventAdapterService;
}
public OutputEventAdapterService getOutputEventAdapterService() {
return outputEventAdapterService;
}
} }

@ -22,6 +22,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
/** /**
* @scr.component name="org.wso2.carbon.device.mgt.extensions.push.notification.provider.gcm.internal.XMPPPushNotificationServiceComponent" immediate="true" * @scr.component name="org.wso2.carbon.device.mgt.extensions.push.notification.provider.gcm.internal.XMPPPushNotificationServiceComponent" immediate="true"
@ -31,6 +32,12 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
* policy="dynamic" * policy="dynamic"
* bind="setDeviceManagementProviderService" * bind="setDeviceManagementProviderService"
* unbind="unsetDeviceManagementProviderService" * unbind="unsetDeviceManagementProviderService"
* @scr.reference name="event.output.adapter.service"
* interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService"
* cardinality="1..1"
* policy="dynamic"
* bind="setOutputEventAdapterService"
* unbind="unsetOutputEventAdapterService"
*/ */
public class XMPPPushNotificationServiceComponent { public class XMPPPushNotificationServiceComponent {
@ -67,4 +74,11 @@ public class XMPPPushNotificationServiceComponent {
XMPPDataHolder.getInstance().setDeviceManagementProviderService(deviceManagementProviderService); XMPPDataHolder.getInstance().setDeviceManagementProviderService(deviceManagementProviderService);
} }
protected void setOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService){
XMPPDataHolder.getInstance().setOutputEventAdapterService(outputEventAdapterService);
}
protected void unsetOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService){
XMPPDataHolder.getInstance().setOutputEventAdapterService(null);
}
} }

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.internal.util;
public final class XMPPAdapterConstants {
private XMPPAdapterConstants() {
throw new AssertionError();
}
public static final String XMPP_ADAPTER_TYPE = "xmpp";
public static final String XMPP_ADAPTER_PROPERTY_PASSWORD = "password";
public static final String XMPP_ADAPTER_PROPERTY_JID = "jid";
public static final String SUBJECT_PROPERTY_KEY = "subject";
public static final String MESSAGE_TYPE_PROPERTY_KEY = "messageType";
public static final String CHAT_PROPERTY_KEY = "chat";
public static final String XMPP_ADAPTER_PROPERTY_HOST = "host";
public static final String XMPP_ADAPTER_PROPERTY_PORT = "port";
public static final String XMPP_ADAPTER_PROPERTY_USERNAME = "username";
public static final String XMPP_ADAPTER_PROPERTY_NAME = "xmpp.adapter.name";
}

@ -184,7 +184,7 @@ public interface Device {
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse(code = 200, message = "List of devices based on the type"), @ApiResponse(code = 200, message = "List of devices based on the type"),
@ApiResponse(code = 500, message = "Error occurred while fetching the list of device types") }) @ApiResponse(code = 500, message = "Error occurred while fetching the list of device types") })
@Permission(scope = "device-list", permissions = {"/permission/admin/device-mgt/admin/devices/list"}) @Permission(scope = "device-list", permissions = {"/permission/admin/device-mgt/user/devices/list"})
Response getDeviceTypes(); Response getDeviceTypes();
/** /**

@ -19,13 +19,19 @@ package org.wso2.carbon.device.mgt.core;
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.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceTypeIdentifier; import org.wso2.carbon.device.mgt.common.DeviceTypeIdentifier;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig; import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
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.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; 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.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagerStartupListener; import org.wso2.carbon.device.mgt.core.internal.DeviceManagerStartupListener;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerImpl;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerRepository;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import java.util.Collections; import java.util.Collections;
@ -37,8 +43,10 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
private Map<DeviceTypeIdentifier, DeviceManagementService> providers; private Map<DeviceTypeIdentifier, DeviceManagementService> providers;
private boolean isInited; private boolean isInited;
private static final Log log = LogFactory.getLog(DeviceManagementPluginRepository.class); private static final Log log = LogFactory.getLog(DeviceManagementPluginRepository.class);
private OperationManagerRepository operationManagerRepository;
public DeviceManagementPluginRepository() { public DeviceManagementPluginRepository() {
this.operationManagerRepository = new OperationManagerRepository();
providers = Collections.synchronizedMap(new HashMap<DeviceTypeIdentifier, DeviceManagementService>()); providers = Collections.synchronizedMap(new HashMap<DeviceTypeIdentifier, DeviceManagementService>());
DeviceManagementServiceComponent.registerStartupListener(this); DeviceManagementServiceComponent.registerStartupListener(this);
} }
@ -60,8 +68,9 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
provider.init(); provider.init();
DeviceManagerUtil.registerDeviceType(deviceType, tenantId, isSharedWithAllTenants); DeviceManagerUtil.registerDeviceType(deviceType, tenantId, isSharedWithAllTenants);
DeviceManagementDataHolder.getInstance().setRequireDeviceAuthorization(deviceType, DeviceManagementDataHolder.getInstance().setRequireDeviceAuthorization(deviceType,
provider.getDeviceManager().requireDeviceAuthorization()); provider.getDeviceManager()
.requireDeviceAuthorization());
registerPushNotificationStrategy(provider);
} }
} catch (DeviceManagementException e) { } catch (DeviceManagementException e) {
throw new DeviceManagementException("Error occurred while adding device management provider '" + throw new DeviceManagementException("Error occurred while adding device management provider '" +
@ -79,16 +88,17 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
public void removeDeviceManagementProvider(DeviceManagementService provider) throws DeviceManagementException { public void removeDeviceManagementProvider(DeviceManagementService provider) throws DeviceManagementException {
String deviceTypeName = provider.getType(); String deviceTypeName = provider.getType();
DeviceTypeIdentifier deviceTypeIdentifier;
ProvisioningConfig provisioningConfig = provider.getProvisioningConfig(); ProvisioningConfig provisioningConfig = provider.getProvisioningConfig();
if (provisioningConfig.isSharedWithAllTenants()) { if (provisioningConfig.isSharedWithAllTenants()) {
DeviceTypeIdentifier deviceTypeIdentifier = new DeviceTypeIdentifier(deviceTypeName); deviceTypeIdentifier = new DeviceTypeIdentifier(deviceTypeName);
providers.remove(deviceTypeIdentifier); providers.remove(deviceTypeIdentifier);
} else { } else {
int providerTenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain()); int providerTenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain());
DeviceTypeIdentifier deviceTypeIdentifier = new DeviceTypeIdentifier(deviceTypeName, providerTenantId); deviceTypeIdentifier = new DeviceTypeIdentifier(deviceTypeName, providerTenantId);
providers.remove(deviceTypeIdentifier); providers.remove(deviceTypeIdentifier);
} }
operationManagerRepository.removeOperationManager(deviceTypeIdentifier);
} }
public DeviceManagementService getDeviceManagementService(String type, int tenantId) { public DeviceManagementService getDeviceManagementService(String type, int tenantId) {
@ -112,6 +122,46 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
return tenantProviders; return tenantProviders;
} }
private void registerPushNotificationStrategy(DeviceManagementService deviceManagementService)
throws DeviceManagementException {
PushNotificationConfig pushNoteConfig = deviceManagementService.getPushNotificationConfig();
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
deviceManagementService.getProvisioningConfig().getProviderTenantDomain(), true);
try {
boolean isSharedWithAllTenants = deviceManagementService.getProvisioningConfig().isSharedWithAllTenants();
DeviceTypeIdentifier deviceTypeIdentifier;
if (isSharedWithAllTenants) {
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceManagementService.getType());
} else {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceManagementService.getType(), tenantId);
}
if (pushNoteConfig != null) {
NotificationStrategy notificationStrategy =
DeviceManagementDataHolder.getInstance().getPushNotificationProviderRepository().getProvider(
pushNoteConfig.getType()).getNotificationStrategy(pushNoteConfig);
operationManagerRepository.addOperationManager(deviceTypeIdentifier, new OperationManagerImpl(
notificationStrategy));
} else {
operationManagerRepository.addOperationManager(deviceTypeIdentifier, new OperationManagerImpl());
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
public OperationManager getOperationManager(String deviceType, int tenantId) {
//Priority need to be given to the tenant before public.
DeviceTypeIdentifier deviceTypeIdentifier = new DeviceTypeIdentifier(deviceType, tenantId);
OperationManager operationManager = operationManagerRepository.getOperationManager(deviceTypeIdentifier);
if (operationManager == null) {
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceType);
operationManager = operationManagerRepository.getOperationManager(deviceTypeIdentifier);
}
return operationManager;
}
@Override @Override
public void notifyObserver() { public void notifyObserver() {
synchronized (providers) { synchronized (providers) {
@ -122,6 +172,7 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
ProvisioningConfig provisioningConfig = provider.getProvisioningConfig(); ProvisioningConfig provisioningConfig = provider.getProvisioningConfig();
int tenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain()); int tenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain());
DeviceManagerUtil.registerDeviceType(provider.getType(), tenantId, provisioningConfig.isSharedWithAllTenants()); DeviceManagerUtil.registerDeviceType(provider.getType(), tenantId, provisioningConfig.isSharedWithAllTenants());
registerPushNotificationStrategy(provider);
//TODO: //TODO:
//This is a temporory fix. //This is a temporory fix.
//windows and IOS cannot resolve user info by extracting certs //windows and IOS cannot resolve user info by extracting certs

@ -101,31 +101,28 @@ public class OperationManagerImpl implements OperationManager {
return null; return null;
} }
List<EnrolmentInfo> enrolments = this.getEnrollmentsByStatus(deviceIds);
try { try {
OperationManagementDAOFactory.beginTransaction(); OperationManagementDAOFactory.beginTransaction();
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation operationDto = org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation operationDto =
OperationDAOUtil.convertOperation(operation); OperationDAOUtil.convertOperation(operation);
int operationId = this.lookupOperationDAO(operation).addOperation(operationDto); int operationId = this.lookupOperationDAO(operation).addOperation(operationDto);
for (EnrolmentInfo enrolmentInfo : enrolments) { //TODO have to create a sql to load device details from deviceDAO using single query.
for (DeviceIdentifier deviceId : deviceIds) {
Device device = getDevice(deviceId);
if (operationDto.getControl() == if (operationDto.getControl() ==
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Control.NO_REPEAT) { org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Control.NO_REPEAT) {
operationDAO.updateEnrollmentOperationsStatus(enrolmentInfo.getId(), operationDto.getCode(), operationDAO.updateEnrollmentOperationsStatus(device.getEnrolmentInfo().getId(), operationDto.getCode(),
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Status.PENDING, org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Status.PENDING,
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Status.REPEATED); org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Status.REPEATED);
} }
operationMappingDAO.addOperationMapping(operationId, enrolmentInfo.getId()); operationMappingDAO.addOperationMapping(operationId, device.getId());
if (notificationStrategy != null) { if (notificationStrategy != null) {
try { try {
notificationStrategy.execute(new NotificationContext(deviceId, operation));
notificationStrategy.execute(new NotificationContext(
new DeviceIdentifier(enrolmentInfo.getDevice().getDeviceIdentifier(),
enrolmentInfo.getDevice().getType())));
} catch (PushNotificationExecutionFailedException e) { } catch (PushNotificationExecutionFailedException e) {
log.error("Error occurred while sending push notifications to " + log.error("Error occurred while sending push notifications to " +
enrolmentInfo.getDevice().getType() + " device carrying id '" + deviceId.getType() + " device carrying id '" +
enrolmentInfo.getDevice().getDeviceIdentifier() + "'", e); deviceId + "'", e);
} }
} }
} }
@ -184,6 +181,23 @@ public class OperationManagerImpl implements OperationManager {
return enrolments; return enrolments;
} }
private Device getDevice(DeviceIdentifier deviceId) throws OperationManagementException {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
DeviceManagementDAOFactory.openConnection();
return deviceDAO.getDevice(deviceId, tenantId);
} catch (SQLException e) {
throw new OperationManagementException("Error occurred while opening a connection the data " +
"source", e);
} catch (DeviceManagementDAOException e) {
OperationManagementDAOFactory.rollbackTransaction();
throw new OperationManagementException(
"Error occurred while retrieving device info", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
@Override @Override
public List<? extends Operation> getOperations(DeviceIdentifier deviceId) throws OperationManagementException { public List<? extends Operation> getOperations(DeviceIdentifier deviceId) throws OperationManagementException {
int enrolmentId; int enrolmentId;

@ -18,6 +18,7 @@
*/ */
package org.wso2.carbon.device.mgt.core.operation.mgt; package org.wso2.carbon.device.mgt.core.operation.mgt;
import org.wso2.carbon.device.mgt.common.DeviceTypeIdentifier;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import java.util.Map; import java.util.Map;
@ -25,21 +26,21 @@ import java.util.concurrent.ConcurrentHashMap;
public class OperationManagerRepository { public class OperationManagerRepository {
private Map<String, OperationManager> operationManagers; private Map<DeviceTypeIdentifier, OperationManager> operationManagers;
public OperationManagerRepository() { public OperationManagerRepository() {
operationManagers = new ConcurrentHashMap<>(); operationManagers = new ConcurrentHashMap<>();
} }
public void addOperationManager(String type, OperationManager operationManager) { public void addOperationManager(DeviceTypeIdentifier type, OperationManager operationManager) {
operationManagers.put(type, operationManager); operationManagers.put(type, operationManager);
} }
public OperationManager getOperationManager(String type) { public OperationManager getOperationManager(DeviceTypeIdentifier type) {
return operationManagers.get(type); return operationManagers.get(type);
} }
public void removeOperationManager(String type) { public void removeOperationManager(DeviceTypeIdentifier type) {
operationManagers.remove(type); operationManagers.remove(type);
} }

@ -178,6 +178,17 @@ public interface DeviceManagementProviderService {
*/ */
PaginationResult getDevicesByStatus(PaginationRequest request) throws DeviceManagementException; PaginationResult getDevicesByStatus(PaginationRequest request) throws DeviceManagementException;
/**
* This method is used to check whether the device is enrolled with the give user.
*
* @param deviceId identifier of the device that needs to be checked against the user.
* @param user username of the device owner.
*
* @return true if the user owns the device else will return false.
* @throws DeviceManagementException If some unusual behaviour is observed while fetching the device.
*/
public boolean isEnrolled(DeviceIdentifier deviceId, String user) throws DeviceManagementException;
License getLicense(String deviceType, String languageCode) throws DeviceManagementException; License getLicense(String deviceType, String languageCode) throws DeviceManagementException;
void addLicense(String deviceType, License license) throws DeviceManagementException; void addLicense(String deviceType, License license) throws DeviceManagementException;

@ -36,8 +36,6 @@ import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; 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.push.notification.NotificationStrategy;
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.core.DeviceManagementPluginRepository; import org.wso2.carbon.device.mgt.core.DeviceManagementPluginRepository;
import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceDAO;
@ -49,8 +47,6 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; 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.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.internal.PluginInitializationListener; import org.wso2.carbon.device.mgt.core.internal.PluginInitializationListener;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerImpl;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerRepository;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import org.wso2.carbon.email.sender.core.ContentProviderInfo; import org.wso2.carbon.email.sender.core.ContentProviderInfo;
import org.wso2.carbon.email.sender.core.EmailContext; import org.wso2.carbon.email.sender.core.EmailContext;
@ -75,11 +71,9 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
private DeviceTypeDAO deviceTypeDAO; private DeviceTypeDAO deviceTypeDAO;
private EnrollmentDAO enrollmentDAO; private EnrollmentDAO enrollmentDAO;
private DeviceManagementPluginRepository pluginRepository; private DeviceManagementPluginRepository pluginRepository;
private OperationManagerRepository operationManagerRepository;
public DeviceManagementProviderServiceImpl() { public DeviceManagementProviderServiceImpl() {
this.pluginRepository = new DeviceManagementPluginRepository(); this.pluginRepository = new DeviceManagementPluginRepository();
this.operationManagerRepository = new OperationManagerRepository();
initDataAccessObjects(); initDataAccessObjects();
/* Registering a listener to retrieve events when some device management service plugin is installed after /* Registering a listener to retrieve events when some device management service plugin is installed after
* the component is done getting initialized */ * the component is done getting initialized */
@ -819,59 +813,63 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
@Override @Override
public Activity addOperation(String type, Operation operation, public Activity addOperation(String type, Operation operation,
List<DeviceIdentifier> devices) throws OperationManagementException { List<DeviceIdentifier> devices) throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().addOperation(operation, devices); return pluginRepository.getOperationManager(type, this.getTenantId()).addOperation(operation, devices);
} }
@Override @Override
public List<? extends Operation> getOperations(DeviceIdentifier deviceId) throws OperationManagementException { public List<? extends Operation> getOperations(DeviceIdentifier deviceId) throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getOperations(deviceId); return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId()).getOperations(deviceId);
} }
@Override @Override
public PaginationResult getOperations(DeviceIdentifier deviceId, PaginationRequest request) public PaginationResult getOperations(DeviceIdentifier deviceId, PaginationRequest request)
throws OperationManagementException { throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getOperations(deviceId, request); return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId())
.getOperations(deviceId, request);
} }
@Override @Override
public List<? extends Operation> getPendingOperations(DeviceIdentifier deviceId) public List<? extends Operation> getPendingOperations(DeviceIdentifier deviceId)
throws OperationManagementException { throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getPendingOperations(deviceId); return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId())
.getPendingOperations(deviceId);
} }
@Override @Override
public Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException { public Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getNextPendingOperation(deviceId); return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId())
.getNextPendingOperation(deviceId);
} }
@Override @Override
public void updateOperation(DeviceIdentifier deviceId, Operation operation) throws OperationManagementException { public void updateOperation(DeviceIdentifier deviceId, Operation operation) throws OperationManagementException {
DeviceManagementDataHolder.getInstance().getOperationManager().updateOperation(deviceId, operation); pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId())
.updateOperation(deviceId, operation);
} }
@Override @Override
public void deleteOperation(String type, int operationId) throws OperationManagementException { public void deleteOperation(String type, int operationId) throws OperationManagementException {
DeviceManagementDataHolder.getInstance().getOperationManager().deleteOperation(operationId); pluginRepository.getOperationManager(type, this.getTenantId()).deleteOperation(operationId);
} }
@Override @Override
public Operation getOperationByDeviceAndOperationId(DeviceIdentifier deviceId, public Operation getOperationByDeviceAndOperationId(DeviceIdentifier deviceId,
int operationId) throws OperationManagementException { int operationId) throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getOperationByDeviceAndOperationId( return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId())
deviceId, operationId); .getOperationByDeviceAndOperationId(deviceId, operationId);
} }
@Override @Override
public List<? extends Operation> getOperationsByDeviceAndStatus( public List<? extends Operation> getOperationsByDeviceAndStatus(
DeviceIdentifier deviceId, DeviceIdentifier deviceId,
Operation.Status status) throws OperationManagementException, DeviceManagementException { Operation.Status status) throws OperationManagementException, DeviceManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getOperationsByDeviceAndStatus( return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId())
deviceId, status); .getOperationsByDeviceAndStatus(deviceId, status);
} }
@Override @Override
public Operation getOperation(String type, int operationId) throws OperationManagementException { public Operation getOperation(String type, int operationId) throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getOperation(operationId); return pluginRepository.getOperationManager(type, this.getTenantId()).getOperation(operationId);
} }
@Override @Override
@ -1155,17 +1153,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
public void registerDeviceManagementService(DeviceManagementService deviceManagementService) { public void registerDeviceManagementService(DeviceManagementService deviceManagementService) {
try { try {
pluginRepository.addDeviceManagementProvider(deviceManagementService); pluginRepository.addDeviceManagementProvider(deviceManagementService);
PushNotificationConfig pushNoteConfig = deviceManagementService.getPushNotificationConfig();
if (pushNoteConfig != null) {
NotificationStrategy notificationStrategy =
DeviceManagementDataHolder.getInstance().getPushNotificationProviderRepository().getProvider(
pushNoteConfig.getType()).getNotificationStrategy(pushNoteConfig);
operationManagerRepository.addOperationManager(
deviceManagementService.getType(), new OperationManagerImpl(notificationStrategy));
} else {
operationManagerRepository.addOperationManager(
deviceManagementService.getType(), new OperationManagerImpl());
}
} catch (DeviceManagementException e) { } catch (DeviceManagementException e) {
log.error("Error occurred while registering device management plugin '" + log.error("Error occurred while registering device management plugin '" +
deviceManagementService.getType() + "'", e); deviceManagementService.getType() + "'", e);
@ -1176,7 +1163,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
public void unregisterDeviceManagementService(DeviceManagementService deviceManagementService) { public void unregisterDeviceManagementService(DeviceManagementService deviceManagementService) {
try { try {
pluginRepository.removeDeviceManagementProvider(deviceManagementService); pluginRepository.removeDeviceManagementProvider(deviceManagementService);
operationManagerRepository.removeOperationManager(deviceManagementService.getType());
} catch (DeviceManagementException e) { } catch (DeviceManagementException e) {
log.error("Error occurred while un-registering device management plugin '" + log.error("Error occurred while un-registering device management plugin '" +
deviceManagementService.getType() + "'", e); deviceManagementService.getType() + "'", e);
@ -1244,6 +1230,25 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return result; return result;
} }
@Override
public boolean isEnrolled(DeviceIdentifier deviceId, String user) throws DeviceManagementException {
try {
DeviceManagementDAOFactory.openConnection();
Device device = deviceDAO.getDevice(deviceId, this.getTenantId());
if (device != null && device.getEnrolmentInfo().getOwner().equals(user)) {
return true;
}
} catch (DeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while obtaining the enrollment information device for" +
"id '" + deviceId.getId() + "' and user : " + user, e);
} catch (SQLException e) {
throw new DeviceManagementException("Error occurred while opening a connection to the data source", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
return false;
}
private int getTenantId() { private int getTenantId() {
return CarbonContext.getThreadLocalCarbonContext().getTenantId(); return CarbonContext.getThreadLocalCarbonContext().getTenantId();
} }

@ -54,6 +54,14 @@
<groupId>com.googlecode.json-simple.wso2</groupId> <groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId> <artifactId>json-simple</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.oauth2.grant.jwt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -118,7 +126,9 @@
org.wso2.carbon.identity.oauth.config, org.wso2.carbon.identity.oauth.config,
org.wso2.carbon.identity.oauth2.dao, org.wso2.carbon.identity.oauth2.dao,
org.wso2.carbon.utils.multitenancy, org.wso2.carbon.utils.multitenancy,
org.wso2.carbon.base org.wso2.carbon.base,
org.wso2.carbon.identity.oauth2.grant.jwt.*,
org.wso2.carbon.device.mgt.core.*
</Import-Package> </Import-Package>
</instructions> </instructions>
</configuration> </configuration>

@ -24,6 +24,9 @@ import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO; import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO;
import org.wso2.carbon.apimgt.impl.utils.APIUtil; import org.wso2.carbon.apimgt.impl.utils.APIUtil;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder; import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
@ -48,7 +51,7 @@ public class OAuthExtUtils {
private static final String UI_EXECUTE = "ui.execute"; private static final String UI_EXECUTE = "ui.execute";
private static final String REST_API_SCOPE_CACHE = "REST_API_SCOPE_CACHE"; private static final String REST_API_SCOPE_CACHE = "REST_API_SCOPE_CACHE";
private static final int START_INDEX = 0; private static final int START_INDEX = 0;
private static final String CDMF_SCOPE_SEPERATOR = "/";
/** /**
* This method is used to get the tenant id when given tenant domain. * This method is used to get the tenant id when given tenant domain.
* *
@ -59,7 +62,8 @@ public class OAuthExtUtils {
int tenantId = 0; int tenantId = 0;
if (tenantDomain != null) { if (tenantDomain != null) {
try { try {
TenantManager tenantManager = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantManager(); TenantManager tenantManager =
OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantManager();
tenantId = tenantManager.getTenantId(tenantDomain); tenantId = tenantManager.getTenantId(tenantDomain);
} catch (UserStoreException e) { } catch (UserStoreException e) {
String errorMsg = "Error when getting the tenant id from the tenant domain : " + String errorMsg = "Error when getting the tenant id from the tenant domain : " +
@ -121,7 +125,7 @@ public class OAuthExtUtils {
if (appScopes.isEmpty()) { if (appScopes.isEmpty()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("No scopes defined for the Application " + log.debug("No scopes defined for the Application " +
tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId()); tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId());
} }
String[] allowedScopes = getAllowedScopes(reqScopeList); String[] allowedScopes = getAllowedScopes(reqScopeList);
@ -162,6 +166,20 @@ public class OAuthExtUtils {
return false; return false;
} }
/**
* Determines if the scope is specified with CDMF device scope prefix.
*
* @param scope - The scope key to check
* @return - 'true' if the scope has the prefix. 'false' if not.
*/
private static boolean isCDMFDeviceSpecificScope(String scope) {
// load white listed scopes
if (scope.startsWith(OAuthExtensionsDataHolder.getInstance().getDeviceScope())) {
return true;
}
return false;
}
/** /**
* Get the set of default scopes. If a requested scope is matches with the patterns specified in the white list, * Get the set of default scopes. If a requested scope is matches with the patterns specified in the white list,
* then such scopes will be issued without further validation. If the scope list is empty, * then such scopes will be issued without further validation. If the scope list is empty,
@ -191,7 +209,7 @@ public class OAuthExtUtils {
* *
* @param tokReqMsgCtx OAuth token request message context. * @param tokReqMsgCtx OAuth token request message context.
* @param reqScopeList Requested scope list. * @param reqScopeList Requested scope list.
* @param appScopes App scopes. * @param appScopes App scopes.
* @return Returns a list of scopes. * @return Returns a list of scopes.
*/ */
private static List<String> getAuthorizedScopes(OAuthTokenReqMessageContext tokReqMsgCtx, List<String> reqScopeList, private static List<String> getAuthorizedScopes(OAuthTokenReqMessageContext tokReqMsgCtx, List<String> reqScopeList,
@ -213,7 +231,8 @@ public class OAuthExtUtils {
tenantId = IdentityTenantUtil.getTenantIdOfUser(username); tenantId = IdentityTenantUtil.getTenantIdOfUser(username);
} }
UserRealm userRealm = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); UserRealm userRealm = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantUserRealm(
tenantId);
//Iterate the requested scopes list. //Iterate the requested scopes list.
for (String scope : reqScopeList) { for (String scope : reqScopeList) {
@ -222,9 +241,11 @@ public class OAuthExtUtils {
//Get the set of roles associated with the requested scope. //Get the set of roles associated with the requested scope.
String appPermissions = appScopes.get(scope); String appPermissions = appScopes.get(scope);
//If the scope has been defined in the context of the App and if permissions have been defined for the scope //If the scope has been defined in the context of the App and if permissions have been defined for
// the scope
if (appPermissions != null && appPermissions.length() != 0) { if (appPermissions != null && appPermissions.length() != 0) {
List<String> permissions = new ArrayList<>(Arrays.asList(appPermissions.replaceAll(" ", "").split(","))); List<String> permissions = new ArrayList<>(Arrays.asList(appPermissions.replaceAll(" ", "").split(
",")));
//Check if user has at least one of the permission associated with the scope //Check if user has at least one of the permission associated with the scope
if (!permissions.isEmpty()) { if (!permissions.isEmpty()) {
@ -254,6 +275,27 @@ public class OAuthExtUtils {
else if (appScopes.containsKey(scope) || isWhiteListedScope(scope)) { else if (appScopes.containsKey(scope) || isWhiteListedScope(scope)) {
authorizedScopes.add(scope); authorizedScopes.add(scope);
} }
//check whether is device specific scope (CDMF)
else if (isCDMFDeviceSpecificScope(scope)) {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
try {
String deviceId[] = scope.split(CDMF_SCOPE_SEPERATOR);
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId[2], deviceId[1]);
boolean enrolled = OAuthExtensionsDataHolder.getInstance().getDeviceManagementService().isEnrolled(
deviceIdentifier, tokReqMsgCtx.getAuthorizedUser().getUserName());
if (enrolled) {
authorizedScopes.add(scope);
}
} catch (DeviceManagementException e) {
log.error("Error occurred while checking device scope with CDMF", e);
} catch (ArrayIndexOutOfBoundsException e) {
log.error("Invalid scope format, have to adhere [prefix/devicetype/deviceId]", e);
}finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
} }
} catch (UserStoreException e) { } catch (UserStoreException e) {
log.error("Error occurred while initializing user store.", e); log.error("Error occurred while initializing user store.", e);

@ -0,0 +1,14 @@
package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant;
import org.wso2.carbon.device.mgt.oauth.extensions.OAuthExtUtils;
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
public class ExtendedJWTBearerGrantHandler extends JWTBearerGrantHandler {
@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception {
return OAuthExtUtils.setScopes(tokReqMsgCtx);
}
}

@ -25,6 +25,7 @@ import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
@ -53,6 +54,12 @@ import java.util.List;
* policy="dynamic" * policy="dynamic"
* bind="setPermissionManagerService" * bind="setPermissionManagerService"
* unbind="unsetPermissionManagerService" * unbind="unsetPermissionManagerService"
* @scr.reference name="org.wso2.carbon.device.manager"
* interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService"
* cardinality="1..1"
* policy="dynamic"
* bind="setDeviceManagementService"
* unbind="unsetDeviceManagementService"
*/ */
public class OAuthExtensionServiceComponent { public class OAuthExtensionServiceComponent {
@ -60,6 +67,8 @@ public class OAuthExtensionServiceComponent {
private static final String REPOSITORY = "repository"; private static final String REPOSITORY = "repository";
private static final String CONFIGURATION = "conf"; private static final String CONFIGURATION = "conf";
private static final String APIM_CONF_FILE = "api-manager.xml"; private static final String APIM_CONF_FILE = "api-manager.xml";
private static final String API_KEY_MANGER_DEVICE_SCOPE = "APIKeyValidator.DeviceScope";
private static final String CDMF_DEVICE_SCOPE_PREFIX = "cdmf_";
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -94,6 +103,15 @@ public class OAuthExtensionServiceComponent {
OAuthExtensionsDataHolder.getInstance().setWhitelistedScopes(whiteList); OAuthExtensionsDataHolder.getInstance().setWhitelistedScopes(whiteList);
// Read device scope(Specific to CDMF) from Configuration.
String deviceScope = configuration.getFirstProperty(API_KEY_MANGER_DEVICE_SCOPE);
if (deviceScope == null) {
deviceScope = CDMF_DEVICE_SCOPE_PREFIX;
}
OAuthExtensionsDataHolder.getInstance().setDeviceScope(deviceScope);
} catch (APIManagementException e) { } catch (APIManagementException e) {
log.error("Error occurred while loading APIM configurations", e); log.error("Error occurred while loading APIM configurations", e);
} }
@ -178,4 +196,26 @@ public class OAuthExtensionServiceComponent {
OAuthExtensionsDataHolder.getInstance().setPermissionManagerService(null); OAuthExtensionsDataHolder.getInstance().setPermissionManagerService(null);
} }
/**
* Set DeviceManagementProviderService
* @param deviceManagerService An instance of PermissionManagerService
*/
protected void setDeviceManagementService(DeviceManagementProviderService deviceManagerService) {
if (log.isDebugEnabled()) {
log.debug("Setting Device Management Service");
}
OAuthExtensionsDataHolder.getInstance().setDeviceManagementService(deviceManagerService);
}
/**
* unset DeviceManagementProviderService
* @param deviceManagementService An instance of PermissionManagerService
*/
protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementService) {
if (log.isDebugEnabled()) {
log.debug("Removing Device Management Service");
}
OAuthExtensionsDataHolder.getInstance().setDeviceManagementService(null);
}
} }

@ -19,6 +19,7 @@
package org.wso2.carbon.device.mgt.oauth.extensions.internal; package org.wso2.carbon.device.mgt.oauth.extensions.internal;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
@ -33,6 +34,8 @@ public class OAuthExtensionsDataHolder {
private OAuth2TokenValidationService oAuth2TokenValidationService; private OAuth2TokenValidationService oAuth2TokenValidationService;
private PermissionManagerService permissionManagerService; private PermissionManagerService permissionManagerService;
private List<String> whitelistedScopes; private List<String> whitelistedScopes;
private String deviceScope;
private DeviceManagementProviderService deviceManagementService;
private static OAuthExtensionsDataHolder thisInstance = new OAuthExtensionsDataHolder(); private static OAuthExtensionsDataHolder thisInstance = new OAuthExtensionsDataHolder();
@ -83,4 +86,20 @@ public class OAuthExtensionsDataHolder {
public void setWhitelistedScopes(List<String> whitelistedScopes) { public void setWhitelistedScopes(List<String> whitelistedScopes) {
this.whitelistedScopes = whitelistedScopes; this.whitelistedScopes = whitelistedScopes;
} }
public void setDeviceScope(String deviceScope) {
this.deviceScope = deviceScope;
}
public String getDeviceScope() {
return deviceScope;
}
public DeviceManagementProviderService getDeviceManagementService() {
return deviceManagementService;
}
public void setDeviceManagementService(DeviceManagementProviderService deviceManagementService) {
this.deviceManagementService = deviceManagementService;
}
} }

@ -28,6 +28,7 @@
<PushNotificationProviders> <PushNotificationProviders>
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.gcm.GCMBasedPushNotificationProvider</Provider> <Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.gcm.GCMBasedPushNotificationProvider</Provider>
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider</Provider> <Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider</Provider>
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider</Provider>
</PushNotificationProviders> </PushNotificationProviders>
<IdentityConfiguration> <IdentityConfiguration>
<ServerUrl>https://localhost:9443</ServerUrl> <ServerUrl>https://localhost:9443</ServerUrl>

@ -1054,6 +1054,11 @@
<artifactId>org.wso2.carbon.identity.application.common</artifactId> <artifactId>org.wso2.carbon.identity.application.common</artifactId>
<version>${carbon.identity.version}</version> <version>${carbon.identity.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.oauth2.grant.jwt</artifactId>
<version>${identity.jwt.extension.version}</version>
</dependency>
<!-- End of Carbon Identity dependencies --> <!-- End of Carbon Identity dependencies -->
<!-- CXF dependencies --> <!-- CXF dependencies -->
@ -1865,6 +1870,9 @@
<javax.ws.rs.version>2.0.1</javax.ws.rs.version> <javax.ws.rs.version>2.0.1</javax.ws.rs.version>
<swagger.version>1.5.8</swagger.version> <swagger.version>1.5.8</swagger.version>
<servlet-api.version>2.5</servlet-api.version> <servlet-api.version>2.5</servlet-api.version>
<!--JWT grant type extension feature-->
<identity.jwt.extension.version>1.0.2</identity.jwt.extension.version>
</properties> </properties>
</project> </project>

Loading…
Cancel
Save