diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml
new file mode 100644
index 000000000..3ba0ed3cf
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt-plugins
+ mb-extensions
+ 2.2.6-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+ bundle
+ WSO2 Carbon - Component - MQTT - Authorization Manager
+ MQTT authorization manager based on Carbon device manager
+ http://wso2.org
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+
+
+ org.wso2.andes.wso2
+ andes
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.api
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.core
+
+
+ commons-lang
+ commons-lang
+
+
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal
+
+
+ !org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal,
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.*
+
+
+ org.apache.log4j,
+ org.dna.mqtt.moquette.server,
+ org.wso2.andes.configuration.enums,
+ org.wso2.andes.mqtt,
+ org.wso2.carbon.context,
+ org.jaxen,
+ org.apache.axiom.*,
+ org.wso2.securevault,
+ org.apache.commons.*,
+ org.osgi.service.component,
+ org.wso2.carbon.user.core.service,
+ org.wso2.carbon.user.core.tenant,
+ org.wso2.carbon.user.api,
+ *;resolution:=optional
+
+ *
+
+
+
+
+
+
+
+
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java
new file mode 100644
index 000000000..effd878ab
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java
@@ -0,0 +1,125 @@
+/*
+ * 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.andes.extensions.device.mgt.mqtt.authorization;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dna.mqtt.moquette.server.IAuthorizer;
+import org.wso2.andes.configuration.enums.MQTTAuthoriztionPermissionLevel;
+import org.wso2.andes.mqtt.MQTTAuthorizationSubject;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal.AuthorizationDataHolder;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.user.api.UserRealm;
+import org.wso2.carbon.user.api.UserStoreException;
+
+import java.util.List;
+
+/**
+ * Authorize the connecting users against Carbon Permission Model. Intended usage is
+ * via providing fully qualified class name in broker.xml
+ *
+ * This is just a simple authorization model. For dynamic topics use an implementation based on IAuthorizer
+ */
+public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer {
+
+ private static final String SCOPE_IDENTIFIER = "scope";
+ private static final String UI_EXECUTE = "ui.execute";
+ private static Log logger = LogFactory.getLog(DeviceAccessBasedMQTTAuthorizer.class);
+ AuthorizationConfigurationManager MQTTAuthorizationConfiguration;
+
+ public DeviceAccessBasedMQTTAuthorizer() {
+ this.MQTTAuthorizationConfiguration = AuthorizationConfigurationManager.getInstance();
+ }
+
+ /**
+ * {@inheritDoc} Authorize the user against carbon device mgt model.
+ */
+ @Override
+ public boolean isAuthorizedForTopic(MQTTAuthorizationSubject authorizationSubject, String topic,
+ MQTTAuthoriztionPermissionLevel permissionLevel) {
+ if (isUserAuthorized(authorizationSubject, MQTTAuthorizationConfiguration.getAdminPermission(), UI_EXECUTE)) {
+ return true;
+ }
+ String topics[] = topic.split("/");
+ if (topics.length < 3) {
+ return false;
+ }
+ String tenantIdFromTopic = topics[0];
+ if (!tenantIdFromTopic.equals(authorizationSubject.getTenantDomain())) {
+ return false;
+ }
+ String deviceType = topics[1];
+ String deviceId = topics[2];
+ Object scopeObject = authorizationSubject.getProperties().get(SCOPE_IDENTIFIER);
+
+ if (!deviceId.isEmpty() && !deviceType.isEmpty() && scopeObject != null) {
+ List scopes = (List) scopeObject;
+ String permissionScope = MQTTAuthorizationConfiguration.getMQTTPublisherScopeIdentifier();
+ if (permissionLevel == MQTTAuthoriztionPermissionLevel.SUBSCRIBE) {
+ permissionScope = MQTTAuthorizationConfiguration.getMQTTSubscriberScopeIdentifier();
+ }
+ String requiredScope = MQTTAuthorizationConfiguration.getDevicemgtScopeIdentifier() + ":" + deviceType + ":"
+ + deviceId + ":" + permissionScope;
+ for (String scope : scopes) {
+ if (requiredScope.equals(scope)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc} Authorized the user against carbon device mgt model.
+ */
+ @Override
+ public boolean isAuthorizedToConnect(MQTTAuthorizationSubject authorizationSubject) {
+ return isUserAuthorized(authorizationSubject, MQTTAuthorizationConfiguration.getConnectionPermission()
+ , UI_EXECUTE);
+ }
+
+ /**
+ * Check whether the client is authorized with the given permission and action.
+ *
+ * @param authorizationSubject this contains the client information
+ * @param permission Carbon permission that requires for the use
+ * @param action Carbon permission action that requires for the given permission.
+ * @return boolean - true if user is authorized else return false.
+ */
+ private boolean isUserAuthorized(MQTTAuthorizationSubject authorizationSubject, String permission, String action) {
+ String username = authorizationSubject.getUsername();
+ try {
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
+ authorizationSubject.getTenantDomain(), true);
+ int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
+ UserRealm userRealm = AuthorizationDataHolder.getInstance().getRealmService()
+ .getTenantUserRealm(tenantId);
+ return userRealm != null && userRealm.getAuthorizationManager() != null &&
+ userRealm.getAuthorizationManager().isUserAuthorized(username, permission, action);
+ } catch (UserStoreException e) {
+ String errorMsg = String.format("Unable to authorize the user : %s", username);
+ logger.error(errorMsg, e);
+ return false;
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ }
+}
\ No newline at end of file
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfiguration.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfiguration.java
new file mode 100644
index 000000000..1a417a924
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfiguration.java
@@ -0,0 +1,246 @@
+/*
+ * 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.andes.extensions.device.mgt.mqtt.authorization.config;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.xpath.AXIOMXPath;
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jaxen.JaxenException;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.exception.AuthorizationException;
+import org.wso2.carbon.utils.ServerConstants;
+import org.wso2.securevault.SecretResolver;
+import org.wso2.securevault.SecretResolverFactory;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This class acts as a access point to retrieve config parameters used within the authorization.
+ * this configuration is read from broker.xml
+ */
+public class AuthorizationConfiguration {
+ /**
+ * Reserved Prefixes that activate different processing logic.
+ */
+ private static final String LIST_TYPE = "LIST_";
+ private static final QName SECURE_VAULT_QNAME = new QName("http://org.wso2.securevault/configuration"
+ , "secretAlias");
+ /**
+ * Common Error states
+ */
+ private static final String GENERIC_CONFIGURATION_PARSE_ERROR = "Error occurred when trying to parse " +
+ "configuration value {0}.";
+ private static final String NO_CHILD_FOR_KEY_IN_PROPERTY = "There was no child at the given key {0} for the " +
+ "parent property {1}.";
+ private static final String PROPERTY_NOT_A_LIST = "The input property {0} does not contain a list of child " +
+ "properties.";
+ /**
+ * location to broker.xml
+ */
+ private static final String ROOT_CONFIG_FILE_PATH = System.getProperty(ServerConstants.CARBON_HOME)
+ + "/repository/conf/";
+ /**
+ * File name of the main configuration file.
+ */
+ private static final String ROOT_CONFIG_FILE_NAME = "broker.xml";
+ private static Log log = LogFactory.getLog(AuthorizationConfigurationManager.class);
+ private static CompositeConfiguration compositeConfiguration;
+ /**
+ * This hashmap is used to maintain any properties that were read from broker.xml
+ */
+ private static ConcurrentHashMap propertyList;
+
+ public static void initialize() throws AuthorizationException {
+ String brokerConfigFilePath = ROOT_CONFIG_FILE_PATH + ROOT_CONFIG_FILE_NAME;
+ if (log.isDebugEnabled()) {
+ log.debug("Configuration located at : " + brokerConfigFilePath);
+ }
+ try {
+ compositeConfiguration = new CompositeConfiguration();
+ compositeConfiguration.setDelimiterParsingDisabled(true);
+ XMLConfiguration rootConfiguration = new XMLConfiguration();
+ rootConfiguration.setDelimiterParsingDisabled(true);
+ rootConfiguration.setFileName(brokerConfigFilePath);
+ rootConfiguration.setExpressionEngine(new XPathExpressionEngine());
+ rootConfiguration.load();
+ readConfigurationFromFile(brokerConfigFilePath);
+ compositeConfiguration.addConfiguration(rootConfiguration);
+ } catch (FileNotFoundException e) {
+ String error = "Error occurred when trying to read the configuration file : " + brokerConfigFilePath;
+ log.error(error, e);
+ throw new AuthorizationException(error, e);
+ } catch (JaxenException e) {
+ String error = "Error occurred when trying to process file : " + brokerConfigFilePath;
+ log.error(error, e);
+ throw new AuthorizationException(error, e);
+ } catch (XMLStreamException e) {
+ String error = "Error occurred when trying to process file : " + brokerConfigFilePath;
+ log.error(error, e);
+ throw new AuthorizationException(error, e);
+ } catch (ConfigurationException e) {
+ String error = "Error occurred when trying to process file :" + brokerConfigFilePath;
+ log.error(error, e);
+ throw new AuthorizationException(error, e);
+ }
+ }
+
+
+ private static void readConfigurationFromFile(String filePath) throws FileNotFoundException, JaxenException
+ , XMLStreamException {
+ propertyList = new ConcurrentHashMap();
+ StAXOMBuilder stAXOMBuilder = new StAXOMBuilder(new FileInputStream(new File(filePath)));
+ OMElement dom = stAXOMBuilder.getDocumentElement();
+ SecretResolver secretResolver = SecretResolverFactory.create(dom, false);
+ AXIOMXPath xpathExpression = new AXIOMXPath("//*[@*[local-name() = \'secretAlias\']]");
+ List nodeList = xpathExpression.selectNodes(dom);
+ String propertyKey;
+ String propertyValue;
+ for (Iterator i$ = nodeList.iterator(); i$.hasNext(); propertyList.put(propertyKey, propertyValue)) {
+ Object o = i$.next();
+ propertyKey = ((OMElement) o).getAttributeValue(SECURE_VAULT_QNAME);
+ propertyValue = "";
+ if (secretResolver != null && secretResolver.isInitialized()) {
+ if (secretResolver.isTokenProtected(propertyKey)) {
+ propertyValue = secretResolver.resolve(propertyKey);
+ }
+ } else {
+ log.warn("Error while reading properties form file");
+ }
+ }
+
+ }
+
+ /**
+ * Using this method, you can access a singular property of a child.
+ * example,
+ *
+ * /permission/admin/device-mgt/user
+ * /permission/admin/device-mgt/admin
+ * mqtt-subscriber
+ * mqtt-subscriber
+ * device-mgt
+ * scenario.
+ *
+ * @param configurationProperty relevant enum value (e.g.- above scenario -> org.wso2.carbon.andes.extensions
+ * .device.mgt.mqtt.authorization.config.TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES)
+ * @param key key of the child of whom you seek the value (e.g. above scenario -> "property list")
+ */
+ static T readValueOfChildByKey(MQTTConfiguration configurationProperty, String key) {
+
+ String constructedKey = configurationProperty.get().getKeyInFile().replace("{key}",
+ key);
+ try {
+ return (T) deriveValidConfigurationValue(constructedKey,
+ configurationProperty.get().getDataType(),
+ configurationProperty.get().getDefaultValue());
+ } catch (ConfigurationException e) {
+ log.error(MessageFormat.format(NO_CHILD_FOR_KEY_IN_PROPERTY, key, configurationProperty), e);
+ return null;
+ }
+ }
+
+
+ /**
+ * Use this method when you need to acquire a list of properties of same group.
+ *
+ * @param configurationProperty relevant enum value (e.g.- org.wso2.carbon.andes.extensions
+ * .device.mgt.mqtt.authorization.config.LIST_TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES)
+ * @return String list of required property values
+ */
+ static List readValueList(MQTTConfiguration configurationProperty) {
+
+ if (configurationProperty.toString().startsWith(LIST_TYPE)) {
+ return Arrays.asList(compositeConfiguration.getStringArray(configurationProperty.get().getKeyInFile()));
+ } else {
+ log.error(MessageFormat.format(PROPERTY_NOT_A_LIST, configurationProperty));
+ return new ArrayList<>();
+ }
+ }
+
+
+ /**
+ * Given the data type and the value read from a config, this returns the parsed value
+ * of the property.
+ *
+ * @param key The Key to the property being read (n xpath format as contained in file.)
+ * @param dataType Expected data type of the property
+ * @param defaultValue This parameter should NEVER be null since we assign a default value to
+ * every config property.
+ * @param Expected data type of the property
+ * @return Value of config in the expected data type.
+ * @throws ConfigurationException if there are any configuration issues
+ */
+ private static T deriveValidConfigurationValue(String key, Class dataType,
+ String defaultValue) throws ConfigurationException {
+ if (log.isDebugEnabled()) {
+ log.debug("Reading configuration value " + key);
+ }
+ String readValue = compositeConfiguration.getString(key);
+ String validValue = defaultValue;
+ if (StringUtils.isBlank(readValue)) {
+ log.warn("Error when trying to read property : " + key + ". Switching to " + "default value : " +
+ defaultValue);
+ } else {
+ validValue = overrideWithDecryptedValue(key, readValue);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Valid value read for andes configuration property " + key + " is : " + validValue);
+ }
+ try {
+ return dataType.getConstructor(String.class).newInstance(validValue);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
+ throw new ConfigurationException(MessageFormat.format(GENERIC_CONFIGURATION_PARSE_ERROR, key), e);
+ }
+ }
+
+ /**
+ * If the property is contained in the propertyList, replace the raw value with that value.
+ *
+ * @param keyInFile xpath expression used to extract the value from file.
+ * @param rawValue The value read from the file without any processing.
+ * @return the value with corresponding to actual value.
+ */
+ private static String overrideWithDecryptedValue(String keyInFile, String rawValue) {
+ if (!StringUtils.isBlank(keyInFile)) {
+ String key = keyInFile.replaceAll("/", ".");
+ if (propertyList.containsKey(key)) {
+ return propertyList.get(key);
+ }
+ }
+ return rawValue;
+ }
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfigurationManager.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfigurationManager.java
new file mode 100644
index 000000000..c477af77a
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfigurationManager.java
@@ -0,0 +1,140 @@
+/*
+ * 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.andes.extensions.device.mgt.mqtt.authorization.config;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.List;
+
+public class AuthorizationConfigurationManager {
+
+ private static final String CONNECTION_PERMISSION = "connectionPermission";
+ private static final String ADMIN_PERMISSION = "adminPermission";
+ private static final String MQTT_PUBLISHER_SCOPE_IDENTIFIER = "MQTTPublisherScopeIdentifier";
+ private static final String MQTT_SUBSCRIBER_SCOPE_IDENTIFIER = "MQTTSubscriberScopeIdentifier";
+ private static final String DEVICE_MGT_SCOPE_IDENTIFIER = "devicemgtScopeIdentifier";
+ private static final AuthorizationConfigurationManager oAuthConfigurationManager
+ = new AuthorizationConfigurationManager();
+ private static Log logger = LogFactory.getLog(AuthorizationConfigurationManager.class);
+ private String connectionPermission;
+ private String adminPermission;
+ private String MQTTPublisherScopeIdentifier;
+ private String MQTTSubscriberScopeIdentifier;
+ private String devicemgtScopeIdentifier;
+
+ private AuthorizationConfigurationManager() {
+
+ }
+
+ public static AuthorizationConfigurationManager getInstance() {
+ return oAuthConfigurationManager;
+ }
+
+ public String getConnectionPermission() {
+ return connectionPermission;
+ }
+
+ public void setConnectionPermission(String connectionPermission) {
+ if (connectionPermission != null) {
+ this.connectionPermission = connectionPermission;
+ } else {
+ logger.error("Connection permission can't be null ");
+ }
+ }
+
+ public String getAdminPermission() {
+ return adminPermission;
+ }
+
+ public void setAdminPermission(String adminPermission) {
+ if (adminPermission != null) {
+ this.adminPermission = adminPermission;
+ } else {
+ logger.error("admin permission can't be null ");
+ }
+ }
+
+ public String getMQTTPublisherScopeIdentifier() {
+ return MQTTPublisherScopeIdentifier;
+ }
+
+ public void setMQTTPublisherScopeIdentifier(String MQTTPublisherScopeIdentifier) {
+ if (MQTTPublisherScopeIdentifier != null) {
+ this.MQTTPublisherScopeIdentifier = MQTTPublisherScopeIdentifier;
+ } else {
+ logger.error("MQTT publisher scope identifier can't be null ");
+ }
+ }
+
+ public String getMQTTSubscriberScopeIdentifier() {
+ return MQTTSubscriberScopeIdentifier;
+ }
+
+ public void setMQTTSubscriberScopeIdentifier(String MQTTSubscriberScopeIdentifier) {
+ if (MQTTSubscriberScopeIdentifier != null) {
+ this.MQTTSubscriberScopeIdentifier = MQTTSubscriberScopeIdentifier;
+ } else {
+ logger.error("MQTT subscriber scope identifier can't be null ");
+ }
+ }
+
+ public String getDevicemgtScopeIdentifier() {
+ return devicemgtScopeIdentifier;
+ }
+
+ public void setDevicemgtScopeIdentifier(String devicemgtScopeIdentifier) {
+ if (devicemgtScopeIdentifier != null) {
+ this.devicemgtScopeIdentifier = devicemgtScopeIdentifier;
+ } else {
+ logger.error("Device management scope identifier can't be null ");
+ }
+ }
+
+ /**
+ * Initialize the configuration properties that required for MQTT Authorization
+ */
+ public synchronized void initConfig() {
+ List mqttTransportAuthorizationProperties = AuthorizationConfiguration.readValueList(MQTTConfiguration
+ .LIST_TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES);
+ for (String property : mqttTransportAuthorizationProperties) {
+ String propertyValue = AuthorizationConfiguration.readValueOfChildByKey(
+ MQTTConfiguration.TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES, property);
+ switch (property) {
+ case CONNECTION_PERMISSION:
+ setConnectionPermission(propertyValue);
+ break;
+ case ADMIN_PERMISSION:
+ setAdminPermission(propertyValue);
+ break;
+ case MQTT_PUBLISHER_SCOPE_IDENTIFIER:
+ setMQTTPublisherScopeIdentifier(propertyValue);
+ break;
+ case MQTT_SUBSCRIBER_SCOPE_IDENTIFIER:
+ setMQTTSubscriberScopeIdentifier(propertyValue);
+ break;
+ case DEVICE_MGT_SCOPE_IDENTIFIER:
+ setDevicemgtScopeIdentifier(propertyValue);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/MQTTConfiguration.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/MQTTConfiguration.java
new file mode 100644
index 000000000..9e56118da
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/MQTTConfiguration.java
@@ -0,0 +1,62 @@
+/*
+ * 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.andes.extensions.device.mgt.mqtt.authorization.config;
+
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.util.ImmutableMetaProperties;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.util.MetaProperties;
+
+import java.util.List;
+
+public enum MQTTConfiguration {
+
+ /**
+ * List of properties that can define how the server will authenticate the user with the authentication service.
+ */
+ LIST_TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES("transports/mqtt/security/authorizer/property/@name", "", List.class),
+
+ /**
+ * This can be used to access a property by giving its key. e.g. hosturl
+ */
+ TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES("transports/mqtt/security/authorizer/property[@name = '{key}']", ""
+ , String.class);
+
+ /**
+ * Meta data about configuration.
+ */
+ private final MetaProperties metaProperties;
+
+ /**
+ * Constructor to define a configuration in broker.
+ *
+ * @param keyInFile Xpath (or any key value) which can be used to identify the configuration in the file.
+ * @param defaultValue the default value
+ * @param dataType data type of the config ( e.g. boolean, string )
+ */
+ MQTTConfiguration(String keyInFile, String defaultValue, Class> dataType) {
+ // We need to pass the enum name as the identifier : therefore this.name()
+ this.metaProperties = new ImmutableMetaProperties(this.name(), keyInFile, defaultValue, dataType);
+ }
+
+ public MetaProperties get() {
+ return metaProperties;
+ }
+
+
+}
+
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/exception/AuthorizationException.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/exception/AuthorizationException.java
new file mode 100644
index 000000000..434388635
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/exception/AuthorizationException.java
@@ -0,0 +1,84 @@
+/*
+ * 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.andes.extensions.device.mgt.mqtt.authorization.exception;
+
+public class AuthorizationException extends Exception {
+ /**
+ * Default Serialization UID
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * error code for our custom exception type to identify specific scenarios and handle them properly.
+ */
+ private String errorCode = "";
+
+ public AuthorizationException() {
+ }
+
+ public AuthorizationException(String message) {
+ super(message);
+ }
+
+ /***
+ * Constructor
+ * @param message descriptive message
+ * @param errorCode one of the above defined constants that classifies the error.
+ */
+ public AuthorizationException(String message, String errorCode) {
+ super(message);
+ this.errorCode = errorCode;
+ }
+
+ /***
+ * Constructor
+ * @param message descriptive message
+ * @param cause reference to the exception for reference.
+ */
+ public AuthorizationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /***
+ * Constructor
+ * @param message descriptive message
+ * @param errorCode one of the above defined constants that classifies the error.
+ * @param cause reference to the exception for reference.
+ */
+ public AuthorizationException(String message, String errorCode, Throwable cause) {
+ super(message, cause);
+ this.errorCode = errorCode;
+ }
+
+ /***
+ * Constructor
+ * @param cause reference to the exception for reference.
+ */
+ public AuthorizationException(Throwable cause) {
+ super(cause);
+ }
+
+ /***
+ * One of the above defined constants that classifies the error. e.g.- MESSAGE_CONTENT_OBSOLETE
+ * @return
+ */
+ public String getErrorCode() {
+ return errorCode;
+ }
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationDataHolder.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationDataHolder.java
new file mode 100644
index 000000000..f36ac6d45
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationDataHolder.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal;
+
+import org.wso2.carbon.user.core.service.RealmService;
+import org.wso2.carbon.user.core.tenant.TenantManager;
+
+public class AuthorizationDataHolder {
+
+ private static AuthorizationDataHolder thisInstance = new AuthorizationDataHolder();
+ private RealmService realmService;
+ private TenantManager tenantManager;
+
+ private AuthorizationDataHolder() {
+ }
+
+ public static AuthorizationDataHolder getInstance() {
+ return thisInstance;
+ }
+
+ public RealmService getRealmService() {
+ return realmService;
+ }
+
+ public void setRealmService(RealmService realmService) {
+ this.realmService = realmService;
+ this.setTenantManager(realmService);
+ }
+
+ public TenantManager getTenantManager() {
+ return tenantManager;
+ }
+
+ private void setTenantManager(RealmService realmService) {
+ if (realmService == null) {
+ throw new IllegalStateException("Realm service is not initialized properly");
+ }
+ this.tenantManager = realmService.getTenantManager();
+ }
+
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationServiceComponent.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationServiceComponent.java
new file mode 100644
index 000000000..7a72d5969
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationServiceComponent.java
@@ -0,0 +1,81 @@
+/*
+ * 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.andes.extensions.device.mgt.mqtt.authorization.internal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.service.component.ComponentContext;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfiguration;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * @scr.component name="org.wso2.carbon.devicemgt.policy.manager" immediate="true"
+ * @scr.reference name="user.realmservice.default"
+ * interface="org.wso2.carbon.user.core.service.RealmService"
+ * cardinality="1..1"
+ * policy="dynamic"
+ * bind="setRealmService"
+ * unbind="unsetRealmService"
+ */
+@SuppressWarnings("unused")
+public class AuthorizationServiceComponent {
+
+ private static Log log = LogFactory.getLog(AuthorizationServiceComponent.class);
+
+ protected void activate(ComponentContext componentContext) {
+ try {
+ AuthorizationConfiguration.initialize();
+ AuthorizationConfigurationManager.getInstance().initConfig();
+ } catch (Throwable e) {
+ log.error("Failed to activate org.wso2.carbon.andes.authorization.internal." +
+ "AuthorizationServiceComponent : " + e);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ protected void deactivate(ComponentContext componentContext) {
+
+ }
+
+ /**
+ * Sets Realm Service
+ *
+ * @param realmService An instance of RealmService
+ */
+ protected void setRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting Realm Service");
+ }
+ AuthorizationDataHolder.getInstance().setRealmService(realmService);
+ }
+
+ /**
+ * Unsets Realm Service
+ *
+ * @param realmService An instance of RealmService
+ */
+ protected void unsetRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unsetting Realm Service");
+ }
+ AuthorizationDataHolder.getInstance().setRealmService(null);
+ }
+
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/ImmutableMetaProperties.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/ImmutableMetaProperties.java
new file mode 100644
index 000000000..5ff2b92da
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/ImmutableMetaProperties.java
@@ -0,0 +1,86 @@
+/*
+ * 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.andes.extensions.device.mgt.mqtt.authorization.util;
+
+/**
+ * This class contains the immutable meta attributes of a config property. These are
+ * immutable so that enums can contain them.
+ */
+public final class ImmutableMetaProperties implements MetaProperties {
+
+ private final String keyInFile;
+ private final String defaultValue;
+ private final Class> dataType;
+ private final String name;
+
+ /**
+ * constructor
+ *
+ * @param keyInFile xpath expression to the property in the config file
+ * @param defaultValue default value of property in case its not specified or found in config files.
+ * @param dataType expected data type of the property
+ */
+ public ImmutableMetaProperties(String name, String keyInFile, String defaultValue, Class> dataType) {
+ this.name = name;
+ this.keyInFile = keyInFile;
+ this.defaultValue = defaultValue;
+ this.dataType = dataType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getKeyInFile() {
+ return keyInFile;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class> getDataType() {
+ return dataType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "Property : " + keyInFile + " data-type : " + dataType.getName() + " default value" +
+ " : " + defaultValue;
+ }
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/MetaProperties.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/MetaProperties.java
new file mode 100644
index 000000000..003dcd12f
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/MetaProperties.java
@@ -0,0 +1,48 @@
+/*
+ * 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.andes.extensions.device.mgt.mqtt.authorization.util;
+
+/**
+ * Contains methods that should be implemented to access meta properties of a config
+ * property.
+ */
+public interface MetaProperties {
+
+ /**
+ * @return actual key with which the property is set in relevant config file.
+ */
+ String getKeyInFile();
+
+ /**
+ * @return Default value specified for the config property,
+ * in case it is not set in file.
+ */
+ String getDefaultValue();
+
+ /**
+ * @return Datatype of the property. (There could be numeric,date or boolean values.)
+ */
+ Class> getDataType();
+
+ /**
+ * @return Name of the property (e.g. TRANSPORTS_AMQP_DEFAULT_CONNECTION_PORT)
+ */
+ String getName();
+
+}
diff --git a/components/extensions/mb-extensions/pom.xml b/components/extensions/mb-extensions/pom.xml
new file mode 100644
index 000000000..eb13c0571
--- /dev/null
+++ b/components/extensions/mb-extensions/pom.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt-plugins
+ extensions
+ 2.2.6-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ mb-extensions
+ pom
+ WSO2 Carbon - MB Extension
+ http://wso2.org
+
+
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+
+
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+ 1.7.2
+
+
+ generate-scr-scrdescriptor
+
+ scr
+
+
+
+
+
+
+
+
diff --git a/components/extensions/pom.xml b/components/extensions/pom.xml
index b8d2076d7..1e3c2c3d4 100644
--- a/components/extensions/pom.xml
+++ b/components/extensions/pom.xml
@@ -35,6 +35,7 @@
appm-connector
cdmf-transport-adapters
+ mb-extensions
diff --git a/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/pom.xml b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/pom.xml
new file mode 100644
index 000000000..d3118d5f2
--- /dev/null
+++ b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt-plugins
+ extensions-feature
+ 2.2.6-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature
+ pom
+ WSO2 Carbon - MQTT Authorization Feature
+ http://wso2.org
+ This feature contains the bundles required for mqtt authorization
+
+
+
+ org.wso2.carbon.devicemgt-plugins
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ 4-p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+ ../../etc/feature.properties
+
+
+ org.wso2.carbon.p2.category.type:server
+ org.eclipse.equinox.p2.type.group:true
+
+
+
+
+ org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization:${carbon.devicemgt.plugins.version}
+
+
+
+ org.wso2.carbon.core.server:4.4.9
+
+
+
+
+
+
+
+
diff --git a/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/build.properties b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/build.properties
new file mode 100644
index 000000000..ddedd58dc
--- /dev/null
+++ b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/build.properties
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2005-2014, 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.
+#
+
+custom = true
diff --git a/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/p2.inf b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/p2.inf
new file mode 100644
index 000000000..7ab37b9d7
--- /dev/null
+++ b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/p2.inf
@@ -0,0 +1 @@
+instructions.configure = \
\ No newline at end of file
diff --git a/features/extensions-feature/pom.xml b/features/extensions-feature/pom.xml
index dd2de92bb..8b3e4aed4 100644
--- a/features/extensions-feature/pom.xml
+++ b/features/extensions-feature/pom.xml
@@ -36,6 +36,7 @@
org.wso2.carbon.appmgt.mdm.osgiconnector.feature
org.wso2.carbon.device.mgt.adapter.feature
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature
diff --git a/pom.xml b/pom.xml
index 248afa466..27724bdbb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1139,6 +1139,22 @@
org.wso2.carbon.apimgt.keymgt.client
${carbon.api.mgt.version}
+
+
+ org.wso2.andes.wso2
+ andes
+ ${carbon.messaging.version}
+
+
+ org.wso2.carbon.devicemgt-plugins
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+ ${carbon.devicemgt.plugins.version}
+
+
+ commons-lang
+ commons-lang
+ ${commons.lang.version}
+
@@ -1245,6 +1261,7 @@
1.0.8
1.8
0.9.1
+ 2.2
3.1.0.wso2v2
@@ -1297,6 +1314,9 @@
5.0.2.Final
[0.0.0,1.0.0)
+
+
+ 3.1.11