Merge pull request #511 from ayyoob/release-3.0.x

IOTS-370 & IOTS-371 & removed scep capability from virtual firealarm
This commit is contained in:
Rasika Perera 2017-01-09 07:21:08 +05:30 committed by GitHub
commit ebca70639f
113 changed files with 1762 additions and 2166 deletions

View File

@ -21,10 +21,8 @@
<from eventAdapterType="oauth-mqtt">
<property name="topic">carbon.super/android_sense/+/data</property>
<property name="username">admin</property>
<property name="password">admin</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator</property>
<property name="contentTransformer">default</property>
<property name="dcrUrl">https://${iot.core.host}:${iot.core.https.port}/dynamic-client-web/register</property>
<property name="url">tcp://${mqtt.broker.host}:${mqtt.broker.port}</property>
<property name="cleanSession">true</property>
</from>
<mapping customMapping="disable" type="json"/>

View File

@ -156,6 +156,7 @@
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -18,14 +18,7 @@
-->
<eventReceiver name="arduino_receiver" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-http">
<property name="maximumHttpConnectionPerHost">2</property>
<property name="username">admin</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.http.util.HTTPContentValidator</property>
<property name="contentTransformer">default</property>
<property name="transports">all</property>
<property name="maximumTotalHttpConnection">100</property>
<property name="tokenValidationEndpointUrl">https://localhost:${dcr.endpoint.port}/services/OAuth2TokenValidationService</property>
<property name="password">admin</property>
</from>
<mapping customMapping="disable" type="json"/>
<to streamName="org.wso2.iot.arduino" version="1.0.0"/>

View File

@ -144,6 +144,7 @@
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -20,10 +20,8 @@
<from eventAdapterType="oauth-mqtt">
<property name="topic">carbon.super/raspberrypi/+/temperature</property>
<property name="username">admin</property>
<property name="password">admin</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator</property>
<property name="contentTransformer">default</property>
<property name="dcrUrl">https://${iot.core.host}:${iot.core.https.port}/dynamic-client-web/register</property>
<property name="url">tcp://${mqtt.broker.host}:${mqtt.broker.port}</property>
<property name="cleanSession">true</property>
</from>
<mapping customMapping="disable" type="json"/>

View File

@ -191,7 +191,10 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
@Override
public void run() {
int currentTemperature = agentManager.getTemperature();
String message = "PUBLISHER:" + AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
try {
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);

View File

@ -189,7 +189,10 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
try {
int currentTemperature = agentManager.getTemperature();
String message = AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
xmppMessage.setTo(xmppAdminJID);

View File

@ -58,7 +58,7 @@ public class AgentConstants {
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/temperature";
/* ---------------------------------------------------------------------------------------
XMPP Connection specific information
--------------------------------------------------------------------------------------- */

View File

@ -168,13 +168,13 @@ public class AgentManager {
}
}
try {
EnrollmentManager.getInstance().beginEnrollmentFlow();
} catch (AgentCoreOperationException e) {
log.error("Device Enrollment Failed:\n");
e.printStackTrace();
System.exit(0);
}
// try {
// EnrollmentManager.getInstance().beginEnrollmentFlow();
// } catch (AgentCoreOperationException e) {
// log.error("Device Enrollment Failed:\n");
// e.printStackTrace();
// System.exit(0);
// }
//Start agent communication
agentCommunicator.get(protocol).connect();

View File

@ -241,6 +241,7 @@ public class AgentUtilOperations {
public static String prepareSecurePayLoad(String message) throws AgentCoreOperationException {
if (EnrollmentManager.getInstance().isEnrolled()) {
PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey();
String encodedMessage = Base64.encodeBase64String(message.getBytes());
String signedPayload;
@ -259,10 +260,14 @@ public class AgentUtilOperations {
jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber());
return jsonPayload.toString();
} else {
return message;
}
}
public static String extractMessageFromPayload(String message) throws AgentCoreOperationException {
if (EnrollmentManager.getInstance().isEnrolled()) {
String actualMessage;
PublicKey serverPublicKey = EnrollmentManager.getInstance().getServerPublicKey();
@ -294,6 +299,9 @@ public class AgentUtilOperations {
throw new AgentCoreOperationException(errorMsg);
}
return actualMessage;
} else {
return message;
}
}
public static String formatMessage(String message) {

View File

@ -96,6 +96,7 @@ public class EnrollmentManager {
private PublicKey publicKey;
private PublicKey serverPublicKey;
private X509Certificate SCEPCertificate;
private boolean isEnrolled = false;
/**
@ -443,4 +444,13 @@ public class EnrollmentManager {
public PublicKey getServerPublicKey() {
return serverPublicKey;
}
/**
* Checks whether the device has already been enrolled with the SCEP Server.
*
* @return the enrollment status; 'TRUE' if already enrolled else 'FALSE'.
*/
public boolean isEnrolled() {
return isEnrolled;
}
}

View File

@ -208,7 +208,10 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
@Override
public void run() {
int currentTemperature = agentManager.getTemperature();
String message = "PUBLISHER:" + AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
try {
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);

View File

@ -189,8 +189,10 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
try {
int currentTemperature = agentManager.getTemperature();
String message = AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature;
String message = "{\"event\": {\"metaData\": {\"owner\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceOwner() + "\",\"deviceId\": \"" + AgentManager
.getInstance().getAgentConfigs().getDeviceId() + "\",\"time\": " +
"0},\"payloadData\": { \"temperature\": " + currentTemperature + "} }}";
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
xmppMessage.setTo(xmppAdminJID);

View File

@ -62,7 +62,7 @@ public class AgentConstants {
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/temperature";
/* ---------------------------------------------------------------------------------------
Device/Agent specific properties to be read from the 'deviceConfig.properties' file

View File

@ -153,15 +153,15 @@ public class AgentManager {
}
}
try {
if (!EnrollmentManager.getInstance().isEnrolled()) {
EnrollmentManager.getInstance().beginEnrollmentFlow();
}
} catch (AgentCoreOperationException e) {
log.error("Device Enrollment Failed:\n");
log.error(e);
System.exit(0);
}
// try {
// if (!EnrollmentManager.getInstance().isEnrolled()) {
// EnrollmentManager.getInstance().beginEnrollmentFlow();
// }
// } catch (AgentCoreOperationException e) {
// log.error("Device Enrollment Failed:\n");
// log.error(e);
// System.exit(0);
// }
//Start agent communication
agentCommunicator.get(protocol).connect();

View File

@ -250,6 +250,7 @@ public class AgentUtilOperations {
}
public static String prepareSecurePayLoad(String message) throws AgentCoreOperationException {
if (EnrollmentManager.getInstance().isEnrolled()) {
PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey();
String encodedMessage = Base64.encodeBase64String(message.getBytes());
String signedPayload;
@ -267,9 +268,13 @@ public class AgentUtilOperations {
//below statements are temporary fix.
jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber());
return jsonPayload.toString();
} else {
return message;
}
}
public static String extractMessageFromPayload(String message) throws AgentCoreOperationException {
if (EnrollmentManager.getInstance().isEnrolled()) {
String actualMessage;
PublicKey serverPublicKey = EnrollmentManager.getInstance().getServerPublicKey();
@ -301,6 +306,9 @@ public class AgentUtilOperations {
throw new AgentCoreOperationException(errorMsg);
}
return actualMessage;
} else {
return message;
}
}
public static String getAuthenticationMethod() {

View File

@ -111,7 +111,7 @@ public class EnrollmentManager {
*/
private EnrollmentManager() {
this.SCEPUrl = AgentManager.getInstance().getEnrollmentEP();
setEnrollmentStatus();
//setEnrollmentStatus();
}
/**

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project name="create-virtual-firealarm-capps" default="zip" basedir=".">
<property name="project-name" value="${ant.project.name}"/>
<property name="target-dir" value="target/carbonapps"/>
<property name="src-dir" value="src/main/resources/carbonapps"/>
<property name="Virtual_firealarm_dir" value="virtualfirealarm"/>
<target name="clean">
<delete dir="${target-dir}" />
</target>
<target name="zip" depends="clean">
<mkdir dir="${target-dir}"/>
<zip destfile="${target-dir}/${Virtual_firealarm_dir}.car">
<zipfileset dir="${src-dir}/${Virtual_firealarm_dir}"/>
</zip>
</target>
</project>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics</artifactId>
<name>WSO2 Carbon - IoT Server Virtual Firealarm Analytics capp</name>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<target>
<ant antfile="build.xml" target="zip" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<finalName>${project.artifactId}-${carbon.devicemgt.plugins.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/assembly/src.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>create-archive</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,36 @@
<!--
~ 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.
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>src</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>${basedir}/src</baseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/target/carbonapps</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<artifacts>
<artifact name="virtualfirealarm" version="1.0.0" type="carbon/application">
<dependency artifact="virtualfirealarm_stream" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="virtualfirealarm_receiver" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="virtualfirealarm_execution" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
</artifact>
</artifacts>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<artifact name="virtualfirealarm_execution" version="1.0.0" type="event/execution-plan" serverRole="DataAnalyticsServer">
<file>virtualfirealarm_execution.siddhiql</file>
</artifact>

View File

@ -0,0 +1,20 @@
/* Enter a unique ExecutionPlan */
@Plan:name('virtualfirealarm_execution')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('virtualfirealarm_execution')
/* define streams/tables and write queries here ... */
@Import('org.wso2.iot.virtualfirealarm:1.0.0')
define stream virtualfirealarm (meta_owner string, meta_deviceId string, meta_time long, temperature float);
@Export('org.wso2.iot.devices.temperature:1.0.0')
define stream temperature (meta_owner string, meta_deviceType string, meta_deviceId string, meta_time long, temperature float);
from virtualfirealarm
select meta_owner, 'virtual_firealarm' as meta_deviceType, meta_deviceId, time:timestampInMilliseconds() as meta_time, temperature
insert into temperature;

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<artifact name="virtualfirealarm_receiver" version="1.0.0" type="event/receiver" serverRole="DataAnalyticsServer">
<file>virtualfirealarm_receiver.xml</file>
</artifact>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<eventReceiver name="virtualfirealarm_receiver" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-mqtt">
<property name="topic">carbon.super/virtual_firealarm/+/temperature</property>
<property name="username">admin</property>
<property name="password">admin</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.input.adapter.mqtt.util.MQTTContentValidator</property>
<property name="cleanSession">true</property>
</from>
<mapping customMapping="disable" type="json"/>
<to streamName="org.wso2.iot.virtualfirealarm" version="1.0.0"/>
</eventReceiver>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<artifact name= "virtualfirealarm_stream" version="1.0.0" type="event/stream" serverRole="DataAnalyticsServer">
<file>org.wso2.iot.virtualfirealarm_1.0.0.json</file>
</artifact>

View File

@ -0,0 +1,16 @@
{
"name": "org.wso2.iot.virtualfirealarm",
"version": "1.0.0",
"nickName": "virtual_firealarm",
"description": "Temperature data received from the virtual_firealarm",
"metaData": [
{"name":"owner","type":"STRING"},
{"name":"deviceId","type":"STRING"},
{"name":"time","type":"LONG"}
],
"payloadData": [
{
"name": "temperature","type": "FLOAT"
}
]
}

View File

@ -235,14 +235,10 @@
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>

View File

@ -18,7 +18,6 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -35,18 +34,15 @@ import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
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.core.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.VirtualFirealarmSecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppAccount;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppServerClient;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.VirtualFirealarmXMPPException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppAccount;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppServerClient;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
@ -76,11 +72,8 @@ import java.util.UUID;
public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
private static final String XMPP_PROTOCOL = "XMPP";
private static final String MQTT_PROTOCOL = "MQTT";
private static final String KEY_TYPE = "PRODUCTION";
private static ApiApplicationKey apiApplicationKey;
private static final String DEVICE_MGT_SCOPE_IDENTIFIER = "device-mgt";
private static Log log = LogFactory.getLog(VirtualFireAlarmServiceImpl.class);
@POST
@ -103,10 +96,7 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
String resource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", "");
PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey();
String actualMessage = resource + ":" + switchToState;
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
serverPrivateKey);
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
@ -114,7 +104,7 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
commandOp.setCode("buzz");
commandOp.setType(Operation.Type.COMMAND);
commandOp.setEnabled(true);
commandOp.setPayLoad(encryptedMsg);
commandOp.setPayLoad(actualMessage);
Properties props = new Properties();
props.setProperty(VirtualFireAlarmConstants.MQTT_ADAPTER_TOPIC_PROPERTY_NAME, publishTopic);
@ -137,10 +127,6 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (VirtualFireAlarmException e) {
String errorMsg = "Preparing Secure payload failed for device - [" + deviceId + "]";
log.error(errorMsg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (OperationManagementException e) {
String msg = "Error occurred while executing command operation upon ringing the buzzer";
log.error(msg, e);
@ -162,37 +148,22 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
DeviceGroupConstants.Permissions.DEFAULT_MANAGE_POLICIES_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey();
String actualMessage = VirtualFireAlarmConstants.POLICY_CONTEXT + ":" + policy;
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
serverPrivateKey);
Map<String, String> dynamicProperties = new HashMap<>();
switch (protocolString) {
case XMPP_PROTOCOL:
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY,
deviceId + "@" + XmppConfig.getInstance().getServerName());
dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "POLICTY-REQUEST");
dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY,
VirtualFireAlarmConstants.CHAT_PROPERTY_KEY);
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME,
dynamicProperties, encryptedMsg);
break;
default:
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME,
dynamicProperties, encryptedMsg);
break;
}
dynamicProperties, actualMessage);
return Response.ok().build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (VirtualFireAlarmException e) {
log.error(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
@ -260,7 +231,7 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
} catch (UserStoreException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (VirtualFirealarmDeviceMgtPluginException ex) {
} catch (VirtualFirealarmXMPPException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
}
@ -294,7 +265,7 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
throws DeviceManagementException, APIManagerException, JWTClientException,
UserStoreException, VirtualFirealarmDeviceMgtPluginException {
UserStoreException, VirtualFirealarmXMPPException {
//create new device id
String deviceId = shortUUID();
boolean status = register(deviceId, deviceName);

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.service.impl.constants;
public class VirtualFireAlarmConstants {
public final static String DEVICE_TYPE = "virtual_firealarm";
public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME";
public final static String DEVICE_PLUGIN_DEVICE_ID = "VIRTUAL_FIREALARM_DEVICE_ID";
public final static String STATE_ON = "ON";
public final static String STATE_OFF = "OFF";
public static final String URL_PREFIX = "http://";
public static final String BULB_CONTEXT = "BULB";
public static final String POLICY_CONTEXT = "POLICY";
//sensor events sumerized table name for temperature
public static final String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY";
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
//mqtt tranport related constants
public static final String MQTT_ADAPTER_NAME = "virtual_firealarm_mqtt";
public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt";
public static final String ADAPTER_TOPIC_PROPERTY = "topic";
public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}";
public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}";
public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset";
public static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip";
public static final int CARBON_DEFAULT_PORT_OFFSET = 0;
public static final int DEFAULT_MQTT_PORT = 1886;
//xmpp transport related constants
public static final String XMPP_ADAPTER_NAME = "virtual_firealarm_xmpp";
public static final String XMPP_ADAPTER_TYPE = "xmpp";
public static final String PASSWORD_PROPERTY_KEY = "password";
public static final String JID_PROPERTY_KEY = "jid";
public static final String CLIENT_JID_PROPERTY_KEY = "xmpp.client.jid";
public static final String SUBJECT_PROPERTY_KEY = "xmpp.client.subject";
public static final String MESSAGE_TYPE_PROPERTY_KEY = "xmpp.client.messageType";
public static final String CHAT_PROPERTY_KEY = "chat";
public static final String USERNAME_PROPERTY_KEY = "username";
public static final String DCR_PROPERTY_KEY = "dcrUrl";
public static final String BROKER_URL_PROPERTY_KEY = "url";
public static final String SCOPES_PROPERTY_KEY = "scopes";
public static final String QOS_PROPERTY_KEY = "qos";
public static final String CLIENT_ID_PROPERTY_KEY = "qos";
public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession";
public static final String TOPIC = "topic";
public static final String SUBSCRIBED_TOPIC = "carbon.super/virtual_firealarm/+/publisher";
public static final String CONTENT_VALIDATION = "contentValidator";
public static final String CONTENT_TRANSFORMATION = "contentTransformer";
public static final String RESOURCE = "resource";
public static final String JSON_SERIAL_KEY = "SerialNumber";
public static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
public static final String JSON_MESSAGE_KEY = "Msg";
public static final String JSON_SIGNATURE_KEY = "Sig";
public static final String HOST_KEY = "host";
public static final String PORT_KEY = "port";
public static final String SERVER_NAME = "serverName";
public static final String MQTT_ADAPTER_TOPIC_PROPERTY_NAME = "mqtt.adapter.topic";
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
}

View File

@ -1,51 +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.iot.virtualfirealarm.service.impl.util;
import org.apache.commons.codec.binary.Base64;
import org.json.JSONObject;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.VirtualFirealarmSecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
import java.lang.*;
import java.security.PrivateKey;
/**
*
*/
public class VirtualFireAlarmServiceUtils {
private static final String JSON_MESSAGE_KEY = "Msg";
private static final String JSON_SIGNATURE_KEY = "Sig";
public static String prepareSecurePayLoad(String message, PrivateKey signatureKey) throws VirtualFireAlarmException {
try {
message = Base64.encodeBase64String(message.getBytes());
String signedPayload = VirtualFirealarmSecurityManager.signMessage(message, signatureKey);
JSONObject jsonPayload = new JSONObject();
jsonPayload.put(JSON_MESSAGE_KEY, message);
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
return jsonPayload.toString();
} catch (VirtualFirealarmDeviceMgtPluginException e) {
throw new VirtualFireAlarmException(e);
}
}
}

View File

@ -1,6 +1,5 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
public class VirtualFireAlarmUtilConstants {

View File

@ -30,7 +30,7 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.xmpp.XmppConfig;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.NetworkUtils;

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.service.impl.xmpp;
public class VirtualFirealarmXMPPException extends Exception{
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public VirtualFirealarmXMPPException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public VirtualFirealarmXMPPException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public VirtualFirealarmXMPPException(String msg) {
super(msg);
setErrorMessage(msg);
}
public VirtualFirealarmXMPPException() {
super();
}
public VirtualFirealarmXMPPException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.service.impl.xmpp;
/**
* holds the information related to account that needs to be created on xmpp server.
*/
public class XmppAccount {
private String username;
private String password;
private String accountName;
private String email;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.service.impl.xmpp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class XmppConfig {
private String host;
private int port;
private String username;
private String password;
private String serverName;
private boolean enabled;
private String jid;
private static XmppConfig xmppConfig = new XmppConfig();
private static final Log log = LogFactory.getLog(XmppConfig.class);
private static final String ENABLED = "enabled";
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static final String HOST = "host";
private static final String PORT = "port";
private static final String SERVERNAME = "serverName";
private static final String JID = "jid";
private XmppConfig() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("../xmpp.properties");
Properties properties = new Properties();
try {
properties.load(input);
enabled = Boolean.parseBoolean(properties.getProperty(ENABLED, "false"));
host = properties.getProperty(HOST);
port = Integer.parseInt(properties.getProperty(PORT));
username = properties.getProperty(USERNAME);
password = properties.getProperty(PASSWORD);
serverName = properties.getProperty(SERVERNAME);
jid = properties.getProperty(JID);
} catch (IOException e) {
log.error("Failed to load xmpp config properties.");
}
}
public static XmppConfig getInstance() {
return xmppConfig;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getJid() {
return jid;
}
public void setJid(String jid) {
this.jid = jid;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.service.impl.xmpp;
import org.jivesoftware.smack.AccountManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import java.util.HashMap;
import java.util.Map;
public class XmppServerClient {
public static boolean createAccount(XmppAccount xmppAccount) throws VirtualFirealarmXMPPException {
if (XmppConfig.getInstance().isEnabled()) {
if (xmppAccount != null) {
try {
ConnectionConfiguration config = new ConnectionConfiguration(XmppConfig.getInstance().getHost(),
XmppConfig.getInstance().getPort(),
"Accounts");
XMPPConnection xmppConnection = new XMPPConnection(config);
xmppConnection.connect();
xmppConnection.login(XmppConfig.getInstance().getUsername(), XmppConfig.getInstance().getPassword());
AccountManager accountManager = xmppConnection.getAccountManager();
Map<String, String> attributes = new HashMap<>();
attributes.put("username", xmppAccount.getUsername());
attributes.put("password", xmppAccount.getPassword());
attributes.put("email", xmppAccount.getEmail());
attributes.put("name", xmppAccount.getAccountName());
accountManager.createAccount(xmppAccount.getUsername(), xmppAccount.getPassword(), attributes);
xmppConnection.disconnect();
return true;
} catch (XMPPException e) {
if (e.getXMPPError().getCode() == 409) {
//AccountAlreadyExist
return true;
} else {
throw new VirtualFirealarmXMPPException(
"XMPP account creation failed. Error: " + e.getLocalizedMessage(), e);
}
}
} else {
throw new VirtualFirealarmXMPPException("Invalid XMPP attributes");
}
} else {
return true;
}
}
}

View File

@ -35,4 +35,6 @@
<param-value>true</param-value>
</context-param>
</web-app>

View File

@ -0,0 +1,25 @@
#
# Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
#
# Licensed 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.
#
#
#[XMPP-Configurations]
enabled=false
username=admin
password=admin
host=localhost
port=5222
serverName=localhost
jid=admin@localhost

View File

@ -1,65 +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.iot.virtualfirealarm.scep.service.impl;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.io.InputStream;
public interface VirtualFireAlarmScepServer {
/**
* This is an API called/used by the SCEP Client of the VirtualFirealarm device in its SCEP enrollment process.
* This acts as the endpoint exposed as part of the SCEP-Server for use by a SCEP Client. This is one of the two
* method-signatures that takes different parameters according to the SCEP-Operation executed by the SCEP-Client
* of the enrolling device. The API supports 2 SCEP Operations [GetCACert] and [GetCACaps].
* <p/>
* Operation [GetCACert] returns the CA cert of the SCEP-Server for the device to verify its authenticity.
* Operation [GetCACaps] returns the CA Capabilities of the SCEP-Server.
*
* @param operation the SCEP operation requested by the client. [GetCACert] or [GetCACaps]
* @param message any messages pertaining to the requested SCEP Operation.
* @return an HTTP Response object with either the CA-Cert or the CA-Capabilities according to the operation.
*/
@GET
@Path("scep")
Response scepRequest(@QueryParam("operation") String operation, @QueryParam("message") String message);
/**
* This is an API called/used by the SCEP Client of the VirtualFirealarm device in its SCEP enrollment process.
* This acts as the endpoint exposed as part of the SCEP-Server for use by a SCEP Client. This is one of the two
* method-signatures that takes different parameters according to the SCEP-Operation executed by the SCEP-Client
* of the enrolling device. This API supports the SCEP Operation [PKIOperation].
* <p/>
* Operation [PKIOperation] returns a certificate generated by the SCEP-Server for the enrolling device.
*
* @param operation the final SCEP operation executed in the enrollment process - which is [PKIOperation]
* @param inputStream an input stream consisting of the Certificate-Signing-Request (CSR) from the device.
* @return an HTTP Response object with the signed certificate for the device by the CA of the SCEP Server.
*/
@POST
@Path("scep")
Response scepRequestPost(@QueryParam("operation") String operation, InputStream inputStream);
}

View File

@ -1,136 +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.iot.virtualfirealarm.scep.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.core.dto.SCEPResponse;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.exception.VirtualFireAlarmException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.util.scep.ContentType;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.util.scep.SCEPOperation;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.util.VirtualFireAlarmServiceUtils;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
@SuppressWarnings("Non-Annoted WebService")
public class VirtualFireAlarmScepServerImpl implements VirtualFireAlarmScepServer {
private static Log log = LogFactory.getLog(VirtualFireAlarmScepServerImpl.class);
@GET
@Path("scep")
public Response scepRequest(@QueryParam("operation") String operation, @QueryParam("message") String message) {
if (log.isDebugEnabled()) {
log.debug("Invoking SCEP operation " + operation);
}
if (SCEPOperation.GET_CA_CERT.getValue().equals(operation)) {
if (log.isDebugEnabled()) {
log.debug("Invoking GetCACert");
}
try {
CertificateManagementService certificateManagementService =
VirtualFireAlarmServiceUtils.getCertificateManagementService();
SCEPResponse scepResponse = certificateManagementService.getCACertSCEP();
Response.ResponseBuilder responseBuilder;
switch (scepResponse.getResultCriteria()) {
case CA_CERT_FAILED:
log.error("CA cert failed");
responseBuilder = Response.serverError();
break;
case CA_CERT_RECEIVED:
if (log.isDebugEnabled()) {
log.debug("CA certificate received in GetCACert");
}
responseBuilder = Response.ok(scepResponse.getEncodedResponse(),
ContentType.X_X509_CA_CERT);
break;
case CA_RA_CERT_RECEIVED:
if (log.isDebugEnabled()) {
log.debug("CA and RA certificates received in GetCACert");
}
responseBuilder = Response.ok(scepResponse.getEncodedResponse(),
ContentType.X_X509_CA_RA_CERT);
break;
default:
log.error("Invalid SCEP request");
responseBuilder = Response.serverError();
break;
}
return responseBuilder.build();
} catch (VirtualFireAlarmException e) {
log.error("Error occurred while enrolling the VirtualFireAlarm device", e);
} catch (KeystoreException e) {
log.error("Keystore error occurred while enrolling the VirtualFireAlarm device", e);
}
} else if (SCEPOperation.GET_CA_CAPS.getValue().equals(operation)) {
if (log.isDebugEnabled()) {
log.debug("Invoking GetCACaps");
}
try {
CertificateManagementService certificateManagementService = VirtualFireAlarmServiceUtils.
getCertificateManagementService();
byte caCaps[] = certificateManagementService.getCACapsSCEP();
return Response.ok(caCaps, MediaType.TEXT_PLAIN).build();
} catch (VirtualFireAlarmException e) {
log.error("Error occurred while enrolling the device", e);
}
} else {
log.error("Invalid SCEP operation " + operation);
}
return Response.serverError().build();
}
@POST
@Path("scep")
public Response scepRequestPost(@QueryParam("operation") String operation, InputStream inputStream) {
if (log.isDebugEnabled()) {
log.debug("Invoking SCEP operation " + operation);
}
if (SCEPOperation.PKI_OPERATION.getValue().equals(operation)) {
if (log.isDebugEnabled()) {
log.debug("Invoking PKIOperation");
}
try {
CertificateManagementService certificateManagementService = VirtualFireAlarmServiceUtils.
getCertificateManagementService();
byte pkiMessage[] = certificateManagementService.getPKIMessageSCEP(inputStream);
return Response.ok(pkiMessage, ContentType.X_PKI_MESSAGE).build();
} catch (VirtualFireAlarmException e) {
log.error("Error occurred while enrolling the device", e);
} catch (KeystoreException e) {
log.error("Keystore error occurred while enrolling the device", e);
}
}
return Response.serverError().build();
}
}

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.scep.service.impl.exception;
public class VirtualFireAlarmException extends Exception {
private static final long serialVersionUID = 118512086957330189L;
public VirtualFireAlarmException(String errorMessage) {
super(errorMessage);
}
public VirtualFireAlarmException(String errorMessage, Throwable throwable) {
super(errorMessage, throwable);
}
}

View File

@ -1,103 +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.iot.virtualfirealarm.scep.service.impl.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.exception.VirtualFireAlarmException;
import java.lang.*;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
/**
*
*/
public class VirtualFireAlarmServiceUtils {
private static final Log log = LogFactory.getLog(VirtualFireAlarmServiceUtils.class);
/**
*
* @return
* @throws VirtualFireAlarmException
*/
public static CertificateManagementService getCertificateManagementService() throws VirtualFireAlarmException {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
CertificateManagementService certificateManagementService = (CertificateManagementService)
ctx.getOSGiService(CertificateManagementService.class, null);
if (certificateManagementService == null) {
String msg = "EnrollmentService is not initialized";
log.error(msg);
throw new VirtualFireAlarmException(msg);
}
return certificateManagementService;
}
/**
*
* @param deviceId
* @return
* @throws VirtualFireAlarmException
*/
public static PublicKey getDevicePublicKey(String deviceId) throws VirtualFireAlarmException {
PublicKey clientPublicKey;
String alias = "";
try {
alias += deviceId.hashCode();
CertificateManagementService certificateManagementService =
VirtualFireAlarmServiceUtils.getCertificateManagementService();
X509Certificate clientCertificate = (X509Certificate) certificateManagementService.getCertificateByAlias(
alias);
clientPublicKey = clientCertificate.getPublicKey();
} catch (VirtualFireAlarmException e) {
String errorMsg = "Could not retrieve CertificateManagementService from the runtime.";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
} catch (KeystoreException e) {
String errorMsg;
if (e.getMessage().contains("NULL_CERT")) {
errorMsg = "The Device-View page might have been accessed prior to the device being started.";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
} else {
errorMsg = "An error occurred whilst trying to retrieve certificate for deviceId [" + deviceId +
"] with alias: [" + alias + "]";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
}
}
return clientPublicKey;
}
}

View File

@ -1,26 +0,0 @@
/*
* Copyright (c) 2015, 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.iot.virtualfirealarm.scep.service.impl.util.scep;
public class ContentType {
public static final String X_PKI_MESSAGE = "application/x-pki-message";
public static final String X_X509_CA_CERT = "application/x-x509-ca-cert";
public static final String X_X509_CA_RA_CERT = "application/x-x509-ca-ra-cert";
}

View File

@ -1,39 +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.iot.virtualfirealarm.scep.service.impl.util.scep;
public enum SCEPOperation {
GET_CA_CERT("GetCACert"),
GET_CA_CAPS("GetCACaps"),
PKI_OPERATION("PKIOperation");
private String value;
private SCEPOperation(String value) {
this.setValue(value);
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright 2005-2013 WSO2, Inc. (http://wso2.com)
~
~ Licensed 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.
-->
<!--
This file defines class loading policy of the whole container. But this behaviour can be overridden by individual webapps by putting this file into the META-INF/ directory.
-->
<Classloading xmlns="http://wso2.org/projects/as/classloading">
<!-- Parent-first or child-first. Default behaviour is child-first.-->
<ParentFirst>false</ParentFirst>
<!--
Default environments that contains provides to all the webapps. This can be overridden by individual webapps by specifing required environments
Tomcat environment is the default and every webapps gets it even if they didn't specify it.
e.g. If a webapps requires CXF, they will get both Tomcat and CXF.
-->
<Environments>CXF,Carbon</Environments>
</Classloading>

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<jaxrs:server id="VirtualFireAlarmScepServer" address="/">
<jaxrs:serviceBeans>
<bean id="VirtualFireAlarmScepServerService"
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.service.impl.VirtualFireAlarmScepServerImpl">
</bean>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
</jaxrs:providers>
</jaxrs:server>
</beans>

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
metadata-complete="true">
<display-name>WSO2 IoT Server</display-name>
<description>WSO2 IoT Server</description>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>isAdminService</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>doAuthentication</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>isSharedWithAllTenants</param-name>
<param-value>true</param-value>
</context-param>
<!--publish to apim-->
<context-param>
<param-name>managed-api-enabled</param-name>
<param-value>false</param-value>
</context-param>
</web-app>

View File

@ -38,7 +38,7 @@
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl</module>
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl</module>
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.api</module>
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.scep.api</module>
<module>org.wso2.carbon.device.mgt.iot.virtualfirealarm.analytics</module>
</modules>
<build>

View File

@ -186,7 +186,7 @@ public final class HTTPEventAdapter implements InputEventAdapter {
"HttpService not available, Error in registering endpoint " + endpoint);
}
httpService.registerServlet(endpoint, new HTTPMessageServlet(eventAdaptorListener, tenantId,
eventAdapterConfiguration),
eventAdapterConfiguration, globalProperties),
new Hashtable(), httpService.createDefaultHttpContext());
} catch (ServletException | NamespaceException e) {
throw new InputEventAdapterRuntimeException("Error in registering endpoint " + endpoint, e);

View File

@ -66,7 +66,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
// Transport Exposed
Property exposedTransportsProperty = new Property(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS);
exposedTransportsProperty.setRequired(true);
exposedTransportsProperty.setRequired(false);
exposedTransportsProperty.setDisplayName(
resourceBundle.getString(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS));
exposedTransportsProperty.setOptions(
@ -75,45 +75,6 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
exposedTransportsProperty.setDefaultValue(HTTPEventAdapterConstants.ALL);
propertyList.add(exposedTransportsProperty);
// OAUTH validation endpoint admin service username
Property username = new Property(HTTPEventAdapterConstants.USERNAME);
username.setRequired(true);
username.setDisplayName(resourceBundle.getString(HTTPEventAdapterConstants.USERNAME));
username.setHint(resourceBundle.getString(HTTPEventAdapterConstants.USERNAME_HINT));
propertyList.add(username);
// OAUTH validation endpoint admin service password
Property password = new Property(HTTPEventAdapterConstants.PASSWORD);
password.setRequired(true);
password.setDisplayName(resourceBundle.getString(HTTPEventAdapterConstants.PASSWORD));
password.setHint(resourceBundle.getString(HTTPEventAdapterConstants.PASSWORD_HINT));
propertyList.add(password);
// OAUTH validation endpoint
Property tokenValidationEndpoint = new Property(HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL);
tokenValidationEndpoint.setRequired(true);
tokenValidationEndpoint.setDisplayName(resourceBundle.getString(HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL));
tokenValidationEndpoint.setHint(resourceBundle.getString(HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL_HINT));
propertyList.add(tokenValidationEndpoint);
Property maximumHttpConnectionPerHost = new Property(HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST);
maximumHttpConnectionPerHost.setRequired(true);
maximumHttpConnectionPerHost.setDisplayName(resourceBundle.getString(
HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST));
maximumHttpConnectionPerHost.setHint(resourceBundle.getString(
HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST_HINT));
maximumHttpConnectionPerHost.setDefaultValue(HTTPEventAdapterConstants.MAX_HTTP_CONNECTION);
propertyList.add(maximumHttpConnectionPerHost);
Property maxTotalHttpConnection = new Property(HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION);
maxTotalHttpConnection.setRequired(true);
maxTotalHttpConnection.setDisplayName(resourceBundle.getString(
HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION));
maxTotalHttpConnection.setHint(resourceBundle.getString(
HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION_HINT));
maxTotalHttpConnection.setDefaultValue(HTTPEventAdapterConstants.MAX_TOTAL_HTTP_CONNECTION);
propertyList.add(maxTotalHttpConnection);
//Content Validator details
Property contentValidator = new Property(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME);
contentValidator.setDisplayName(

View File

@ -60,7 +60,8 @@ public class HTTPMessageServlet extends HttpServlet {
private static OAuthAuthenticator oAuthAuthenticator;
public HTTPMessageServlet(InputEventAdapterListener eventAdaptorListener, int tenantId,
InputEventAdapterConfiguration eventAdapterConfiguration) {
InputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) {
this.eventAdaptorListener = eventAdaptorListener;
this.tenantId = tenantId;
this.exposedTransports = eventAdapterConfiguration.getProperties().get(
@ -107,7 +108,7 @@ public class HTTPMessageServlet extends HttpServlet {
}
jwtAuthenticator = new JWTAuthenticator();
oAuthAuthenticator = new OAuthAuthenticator(eventAdapterConfiguration);
oAuthAuthenticator = new OAuthAuthenticator(globalProperties);
}
@Override

View File

@ -36,6 +36,7 @@ import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import javax.servlet.http.HttpServletRequest;
import java.rmi.RemoteException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -51,8 +52,8 @@ public class OAuthAuthenticator {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static Log log = LogFactory.getLog(OAuthAuthenticator.class);
public OAuthAuthenticator(InputEventAdapterConfiguration eventAdapterConfiguration) {
this.stubs = new GenericObjectPool(new OAuthTokenValidaterStubFactory(eventAdapterConfiguration));
public OAuthAuthenticator(Map<String, String> globalProperties) {
this.stubs = new GenericObjectPool(new OAuthTokenValidaterStubFactory(globalProperties));
}
public AuthenticationInfo authenticate(HttpServletRequest req) {

View File

@ -34,7 +34,6 @@ import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.log4j.Logger;
import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.device.mgt.input.adapter.http.oauth.exception.OAuthTokenValidationException;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.device.mgt.input.adapter.http.util.HTTPEventAdapterConstants;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
@ -42,6 +41,7 @@ import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.Map;
/**
* This follows object pool pattern to manage the stub for oauth validation service.
@ -49,11 +49,11 @@ import java.security.GeneralSecurityException;
public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
private static final Logger log = Logger.getLogger(OAuthTokenValidaterStubFactory.class);
private HttpClient httpClient;
InputEventAdapterConfiguration eventAdapterConfiguration;
Map<String, String> globalProperties;
public OAuthTokenValidaterStubFactory(InputEventAdapterConfiguration eventAdapterConfiguration) {
this.eventAdapterConfiguration = eventAdapterConfiguration;
public OAuthTokenValidaterStubFactory(Map<String, String> globalProperties) {
this.globalProperties = globalProperties;
this.httpClient = createHttpClient();
}
@ -92,8 +92,9 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
private OAuth2TokenValidationServiceStub generateStub() throws OAuthTokenValidationException {
OAuth2TokenValidationServiceStub stub;
try {
URL hostURL = new URL(Utils.replaceSystemProperty(eventAdapterConfiguration.getProperties().get(
HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL)));
URL hostURL = new URL(Utils.replaceSystemProperty(globalProperties.get(
HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL)
+ HTTPEventAdapterConstants.TOKEN_VALIDATION_POST_FIX));
if (hostURL != null) {
stub = new OAuth2TokenValidationServiceStub(hostURL.toString());
if (stub != null) {
@ -104,10 +105,8 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
HttpTransportProperties.Authenticator auth =
new HttpTransportProperties.Authenticator();
auth.setPreemptiveAuthentication(true);
String username = eventAdapterConfiguration.getProperties().get(HTTPEventAdapterConstants
.USERNAME);
String password = eventAdapterConfiguration.getProperties().get(HTTPEventAdapterConstants
.PASSWORD);
String username = globalProperties.get(HTTPEventAdapterConstants.USERNAME);
String password = globalProperties.get(HTTPEventAdapterConstants.PASSWORD);
auth.setPassword(username);
auth.setUsername(password);
Options options = client.getOptions();
@ -151,8 +150,7 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
*/
private EasySSLProtocolSocketFactory createProtocolSocketFactory() throws OAuthTokenValidationException {
try {
EasySSLProtocolSocketFactory easySSLPSFactory = new EasySSLProtocolSocketFactory();
return easySSLPSFactory;
return new EasySSLProtocolSocketFactory();
} catch (IOException e) {
String errorMsg = "Failed to initiate EasySSLProtocolSocketFactory.";
throw new OAuthTokenValidationException(errorMsg, e);
@ -170,9 +168,9 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
*/
private HttpClient createHttpClient() {
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
params.setDefaultMaxConnectionsPerHost(Integer.parseInt(eventAdapterConfiguration.getProperties().get(
params.setDefaultMaxConnectionsPerHost(Integer.parseInt(globalProperties.get(
HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST)));
params.setMaxTotalConnections(Integer.parseInt(eventAdapterConfiguration.getProperties().get(
params.setMaxTotalConnections(Integer.parseInt(globalProperties.get(
HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION)));
HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.setParams(params);

View File

@ -51,8 +51,8 @@ public final class HTTPEventAdapterConstants {
public static final String MAXIMUM_TOTAL_HTTP_CONNECTION_HINT = "maximumTotalHttpConnection.hint";
public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST = "maximumHttpConnectionPerHost";
public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST_HINT = "maximumHttpConnectionPerHost.hint";
public static final String TOKEN_VALIDATION_ENDPOINT_URL = "tokenValidationEndpointUrl";
public static final String TOKEN_VALIDATION_ENDPOINT_URL_HINT = "tokenValidationEndpointUrl.hint";
public static final String TOKEN_VALIDATION_ENDPOINT_URL = "keymanagerUrl";
public static final String TOKEN_VALIDATION_POST_FIX = "/services/OAuth2TokenValidationService";
public static final String USERNAME = "username";
public static final String USERNAME_HINT = "username.hint";
public static final String PASSWORD = "password";

View File

@ -22,16 +22,6 @@ http.usage.tips_mid1=/endpoints/&lt;event_receiver_name&gt</i></br>&nbsp;&nbsp;<
http.usage.tips_mid2=/endpoints/&lt;event_receiver_name&gt;</i></br></br>For other tenants:</br>&nbsp;&nbsp;<i>http://localhost:
http.usage.tips_mid3=/endpoints/t/&lt;tenant_domain&gt;/&lt;event_receiver_name&gt;</i></br>&nbsp;&nbsp;<i>https://localhost:
http.usage.tips_postfix=/endpoints/t/&lt;tenant_domain&gt;/&lt;event_receiver_name&gt;</i>
tokenValidationEndpointUrl=tokenEndpointUrl
tokenValidationEndpointUrl.hint=OAUTH Token Validation Endpoint
username=username
username.hint=username of the user to connect to the admin services
password=password
password.hint=password of the user to connect to the admin services.
maximumTotalHttpConnection=maximumTotalHttpConnection
maximumTotalHttpConnection.hint=Maximum Total connection to be made with the endpoint
maximumHttpConnectionPerHost=maximumHttpConnectionPerHost
maximumHttpConnectionPerHost.hint=Maximum Http connection per host.
contentValidator=contentValidator
contentValidator.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required)
contentTransformer=contentTransformer

View File

@ -60,10 +60,6 @@
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
@ -128,7 +124,6 @@
org.apache.http.client.methods;version="${httpclient.version.range}",
org.apache.http.impl.client;version="${httpclient.version.range}",
org.json.simple.*,
org.wso2.carbon.identity.jwt.client.extension.*,
com.jayway.jsonpath.*
</Import-Package>
<DynamicImport-Package>*</DynamicImport-Package>

View File

@ -53,29 +53,13 @@ public class MQTTEventAdapter implements InputEventAdapter {
public void init(InputEventAdapterListener eventAdapterListener) throws InputEventAdapterException {
this.eventAdapterListener = eventAdapterListener;
try {
int keepAlive;
//If global properties are available those will be assigned else constant values will be assigned
if (globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_KEEP_ALIVE) != null) {
keepAlive = Integer.parseInt((globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_KEEP_ALIVE)));
} else {
keepAlive = MQTTEventAdapterConstants.ADAPTER_CONF_DEFAULT_KEEP_ALIVE;
}
mqttBrokerConnectionConfiguration = new MQTTBrokerConnectionConfiguration(
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_URL),
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME),
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES),
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL),
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION),
keepAlive,
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME),
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME)
);
mqttAdapterListener = new MQTTAdapterListener(mqttBrokerConnectionConfiguration,
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC),
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID),
eventAdapterListener, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
mqttBrokerConnectionConfiguration = new MQTTBrokerConnectionConfiguration(eventAdapterConfiguration
,globalProperties);
mqttAdapterListener = new MQTTAdapterListener(mqttBrokerConnectionConfiguration
,eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC)
,eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID)
,eventAdapterListener, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
} catch (Throwable t) {
throw new InputEventAdapterException(t.getMessage(), t);
}

View File

@ -59,16 +59,10 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
//Broker Url
Property brokerUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_URL);
brokerUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL));
brokerUrl.setRequired(true);
brokerUrl.setRequired(false);
brokerUrl.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL_HINT));
propertyList.add(brokerUrl);
//DCR endpoint details
Property dcrUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL);
dcrUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL));
dcrUrl.setRequired(false);
dcrUrl.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL_HINT));
propertyList.add(dcrUrl);
//Content Validator details
Property contentValidator = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME);
@ -84,10 +78,18 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
Property userName = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME);
userName.setDisplayName(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME));
userName.setRequired(false);
userName.setRequired(true);
userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT));
propertyList.add(userName);
//Broker Password
Property password = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD);
userName.setDisplayName(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD));
userName.setRequired(true);
userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD_HINT));
propertyList.add(password);
//Broker Required Scopes.
Property scopes = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES);
scopes.setDisplayName(

View File

@ -23,13 +23,9 @@ import org.osgi.service.component.ComponentContext;
import org.osgi.service.http.HttpService;
import org.wso2.carbon.device.mgt.input.adapter.mqtt.MQTTEventAdapterFactory;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory;
import org.wso2.carbon.user.core.service.RealmService;
/**
* @scr.component name="input.iot.mqtt.AdapterService.component" 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"
*/
public class InputAdapterServiceComponent {
@ -48,14 +44,6 @@ public class InputAdapterServiceComponent {
}
}
protected void setRealmService(RealmService realmService) {
InputAdapterServiceDataHolder.registerRealmService(realmService);
}
protected void unsetRealmService(RealmService realmService) {
InputAdapterServiceDataHolder.registerRealmService(null);
}
protected void setHttpService(HttpService httpService) {
InputAdapterServiceDataHolder.registerHTTPService(httpService);
}

View File

@ -15,28 +15,17 @@
package org.wso2.carbon.device.mgt.input.adapter.mqtt.internal;
import org.osgi.service.http.HttpService;
import org.wso2.carbon.user.core.service.RealmService;
/**
* common place to hold some OSGI service references.
*/
public final class InputAdapterServiceDataHolder {
private static RealmService realmService;
private static HttpService httpService;
private InputAdapterServiceDataHolder() {
}
public static void registerRealmService(
RealmService realmService) {
InputAdapterServiceDataHolder.realmService = realmService;
}
public static RealmService getRealmService() {
return realmService;
}
public static void registerHTTPService(
HttpService httpService) {
InputAdapterServiceDataHolder.httpService = httpService;

View File

@ -17,13 +17,18 @@
*/
package org.wso2.carbon.device.mgt.input.adapter.mqtt.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
import org.json.simple.JSONObject;
@ -39,9 +44,6 @@ import org.wso2.carbon.device.mgt.input.adapter.extension.DefaultContentValidato
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException;
import org.wso2.carbon.device.mgt.input.adapter.mqtt.exception.MQTTContentInitializationException;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import java.io.IOException;
import java.net.MalformedURLException;
@ -49,7 +51,9 @@ import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MQTTAdapterListener implements MqttCallback, Runnable {
@ -144,16 +148,14 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
}
public void startListener() throws MqttException {
if (this.mqttBrokerConnectionConfiguration.getBrokerUsername() != null &&
if (this.mqttBrokerConnectionConfiguration.getUsername() != null &&
this.mqttBrokerConnectionConfiguration.getDcrUrl() != null) {
String username = this.mqttBrokerConnectionConfiguration.getBrokerUsername();
String username = this.mqttBrokerConnectionConfiguration.getUsername();
String password = this.mqttBrokerConnectionConfiguration.getPassword();
String dcrUrlString = this.mqttBrokerConnectionConfiguration.getDcrUrl();
String scopes = this.mqttBrokerConnectionConfiguration.getBrokerScopes();
//getJWT Client Parameters.
if (dcrUrlString != null && !dcrUrlString.isEmpty()) {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username);
try {
URL dcrUrl = new URL(dcrUrlString);
HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol());
@ -163,11 +165,15 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE);
registrationProfile.setOwner(username);
registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE);
registrationProfile.setApplicationType(MQTTEventAdapterConstants.APPLICATION_TYPE);
registrationProfile.setClientName(username + "_" + tenantId);
registrationProfile.setClientName(MQTTEventAdapterConstants.APPLICATION_NAME_PREFIX
+ mqttBrokerConnectionConfiguration.getAdapterName() + "_" + tenantId);
String jsonString = registrationProfile.toJSON();
StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
postMethod.setEntity(requestEntity);
String basicAuth = getBase64Encode(username, password);
postMethod.setHeader(new BasicHeader(MQTTEventAdapterConstants.AUTHORIZATION_HEADER_NAME,
MQTTEventAdapterConstants.AUTHORIZATION_HEADER_VALUE_PREFIX +
basicAuth));
HttpResponse httpResponse = httpClient.execute(postMethod);
if (httpResponse != null) {
String response = MQTTUtil.getResponseString(httpResponse);
@ -177,16 +183,10 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
JSONObject jsonPayload = (JSONObject) jsonParser.parse(response);
String clientId = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_ID);
String clientSecret = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_SECRET);
JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService();
AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken(
clientId, clientSecret, username, scopes);
connectionOptions.setUserName(accessTokenInfo.getAccessToken());
connectionOptions.setUserName(getToken(clientId, clientSecret));
}
} catch (ParseException e) {
String msg = "error occurred while parsing client credential payload";
log.error(msg, e);
} catch (JWTClientException e) {
String msg = "error occurred while parsing the response from JWT Client";
String msg = "error occurred while parsing generating token for the adapter";
log.error(msg, e);
}
}
@ -194,8 +194,6 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
log.error("Invalid dcrUrl : " + dcrUrlString);
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) {
log.error("Failed to create an https connection.", e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
@ -287,4 +285,39 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
public boolean isConnectionInitialized() {
return connectionInitialized;
}
private String getToken(String clientId, String clientSecret)
throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, ParseException {
URL tokenEndpoint = new URL(mqttBrokerConnectionConfiguration.getTokenUrl());
HttpClient httpClient = MQTTUtil.getHttpClient(tokenEndpoint.getProtocol());
HttpPost postMethod = new HttpPost(tokenEndpoint.toString());
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.GRANT_TYPE_PARAM_NAME,
MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE));
nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_USERNAME,
mqttBrokerConnectionConfiguration.getUsername()));
nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_PASSWORD,
mqttBrokerConnectionConfiguration.getPassword()));
String scopes = mqttBrokerConnectionConfiguration.getBrokerScopes();
if (scopes != null && !scopes.isEmpty()) {
nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_SCOPES, scopes));
}
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
postMethod.addHeader("Authorization", "Basic " + getBase64Encode(clientId, clientSecret));
postMethod.addHeader("Content-Type", "application/x-www-form-urlencoded");
HttpResponse httpResponse = httpClient.execute(postMethod);
String response = MQTTUtil.getResponseString(httpResponse);
if (log.isDebugEnabled()) {
log.debug(response);
}
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(response);
return (String) jsonObject.get(MQTTEventAdapterConstants.ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME);
}
private String getBase64Encode(String key, String value) {
return new String(Base64.encodeBase64((key + ":" + value).getBytes()));
}
}

View File

@ -17,28 +17,38 @@
*/
package org.wso2.carbon.device.mgt.input.adapter.mqtt.util;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException;
import java.util.Map;
/**
* This holds the configurations related to MQTT Broker.
*/
public class MQTTBrokerConnectionConfiguration {
private String brokerUsername = null;
private String username = null;
private String password = null;
private String brokerScopes = null;
private boolean cleanSession = true;
private int keepAlive;
private String brokerUrl;
private String dcrUrl;
private String tokenUrl;
private String contentValidatorClassName;
private String contentTransformerClassName;
private String adapterName;
public String getBrokerScopes() {
return brokerScopes;
}
public String getBrokerUsername() {
return brokerUsername;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public boolean isCleanSession() {
@ -65,21 +75,44 @@ public class MQTTBrokerConnectionConfiguration {
return contentTransformerClassName;
}
public MQTTBrokerConnectionConfiguration(String brokerUrl, String brokerUsername, String brokerScopes,
String dcrUrl, String cleanSession, int keepAlive,
String contentValidatorClassName, String contentTransformerClassName) throws InputEventAdapterException {
this.brokerUsername = brokerUsername;
this.brokerScopes = brokerScopes;
public String getTokenUrl() {
return tokenUrl;
}
public String getAdapterName() {
return adapterName;
}
public MQTTBrokerConnectionConfiguration(InputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) throws InputEventAdapterException {
adapterName = eventAdapterConfiguration.getName();
this.username = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME);
this.password = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD);
this.brokerScopes = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES);
if (brokerScopes == null) {
this.brokerScopes = MQTTEventAdapterConstants.EMPTY_STRING;
}
this.brokerUrl = PropertyUtils.replaceMqttProperty(brokerUrl);
this.dcrUrl = PropertyUtils.replaceMqttProperty(dcrUrl);
this.contentValidatorClassName = contentValidatorClassName;
if (cleanSession != null) {
this.cleanSession = Boolean.parseBoolean(cleanSession);
String url = eventAdapterConfiguration .getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_URL);
if (url == null || url.isEmpty()) {
url = globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_URL);
}
this.keepAlive = keepAlive;
this.contentTransformerClassName = contentTransformerClassName;
this.brokerUrl = PropertyUtils.replaceMqttProperty(url);
this.dcrUrl = PropertyUtils
.replaceMqttProperty(globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL));
this.tokenUrl = PropertyUtils
.replaceMqttProperty(globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_TOKEN_URL));
this.contentValidatorClassName = eventAdapterConfiguration.getProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME);
this.cleanSession = Boolean.parseBoolean(eventAdapterConfiguration.getProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION));
//If global properties are available those will be assigned else constant values will be assigned
if (globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_KEEP_ALIVE) != null) {
keepAlive = Integer.parseInt((globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_KEEP_ALIVE)));
} else {
keepAlive = MQTTEventAdapterConstants.ADAPTER_CONF_DEFAULT_KEEP_ALIVE;
}
this.contentTransformerClassName = eventAdapterConfiguration.getProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME);
}
}

View File

@ -27,10 +27,13 @@ public class MQTTEventAdapterConstants {
public static final String ADAPTER_CONF_URL = "url";
public static final String ADAPTER_CONF_USERNAME = "username";
public static final String ADAPTER_CONF_USERNAME_HINT = "username.hint";
public static final String ADAPTER_CONF_PASSWORD = "password";
public static final String ADAPTER_CONF_PASSWORD_HINT = "password.hint";
public static final String ADAPTER_CONF_SCOPES = "scopes";
public static final String ADAPTER_CONF_SCOPES_HINT = "scopes.hint";
public static final String ADAPTER_CONF_URL_HINT = "url.hint";
public static final String ADAPTER_CONF_DCR_URL = "dcrUrl";
public static final String ADAPTER_CONF_TOKEN_URL = "tokenUrl";
public static final String ADAPTER_CONF_DCR_URL_HINT = "dcrUrl.hint";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME = "contentValidator";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT = "contentValidator.hint";
@ -49,11 +52,12 @@ public class MQTTEventAdapterConstants {
public static final int RECONNECTION_PROGRESS_FACTOR = 2;
public static final String EMPTY_STRING = "";
public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer refresh_token";
public static final String GRANT_TYPE_PARAM_NAME = "grant_type";
public static final String GRANT_TYPE = "password refresh_token";
public static final String TOKEN_SCOPE = "production";
public static final String APPLICATION_TYPE = "device";
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String APPLICATION_NAME_PREFIX = "InputAdapter_";
public static final String CLIENT_ID = "clientId";
public static final String CLIENT_SECRET = "clientSecret";
public static final String CLIENT_NAME = "client_name";
public static final String DEFAULT = "default";
public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS = "";
@ -62,4 +66,12 @@ public class MQTTEventAdapterConstants {
public static final String DEVICE_ID_JSON_PATH = "event.metaData.deviceId";
public static final String DEVICE_TYPE_JSON_PATH = "event.metaData.deviceId";
public static final int DEVICE_ID_TOPIC_HIERARCHY_INDEX = 2;
public static final String AUTHORIZATION_HEADER_NAME = "Authorization";
public static final String AUTHORIZATION_HEADER_VALUE_PREFIX = "Basic ";
public static final String PASSWORD_GRANT_TYPE = "password";
public static final String PASSWORD_GRANT_TYPE_USERNAME = "username";
public static final String PASSWORD_GRANT_TYPE_PASSWORD = "password";
public static final String PASSWORD_GRANT_TYPE_SCOPES = "scopes";
public static final String ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME = "access_token";
}

View File

@ -27,8 +27,6 @@ import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import java.io.BufferedReader;
import java.io.IOException;
@ -84,16 +82,4 @@ public class MQTTUtil {
}
}
}
public static JWTClientManagerService getJWTClientManagerService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
JWTClientManagerService jwtClientManagerService =
(JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
if (jwtClientManagerService == null) {
String msg = "JWT management service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return jwtClientManagerService;
}
}

View File

@ -20,9 +20,11 @@ topic=Topic
topic.hint=Topic subscribed
clientId=Client Id
clientId.hint=client identifier is used by the server to identify a client when it reconnects, It used for durable subscriptions or reliable delivery of messages is required.
url=Broker Url
url=Broker Url (Not required), If it is not provided then it will connect to the default broker.
username=Username
username.hint=Username of the broker (if required)
password=Password
password.hint=Password of the user for the broker (if required)
scopes=Scopes
scopes.hint=Scopes required to connect to broker (if required)
dcrUrl=dcrUrl

View File

@ -61,10 +61,6 @@
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
@ -122,7 +118,10 @@
org.osgi.framework,
org.osgi.service.component,
org.wso2.carbon.context,
org.wso2.carbon.identity.jwt.client.extension.*
org.apache.commons.codec.binary,
org.apache.http.client.entity,
org.apache.http.message,
org.apache.commons.ssl
</Import-Package>
</instructions>
</configuration>

View File

@ -118,19 +118,7 @@ public class MQTTEventAdapter implements OutputEventAdapter {
@Override
public void connect() {
MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration =
new MQTTBrokerConnectionConfiguration(eventAdapterConfiguration.getStaticProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_URL),
eventAdapterConfiguration.getStaticProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME),
eventAdapterConfiguration.getStaticProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL),
eventAdapterConfiguration.getStaticProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES),
connectionKeepAliveInterval,
eventAdapterConfiguration.getStaticProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION)
);
new MQTTBrokerConnectionConfiguration(eventAdapterConfiguration, globalProperties);
String clientId = eventAdapterConfiguration.getStaticProperties().get(
MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID);
qos = eventAdapterConfiguration.getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_QOS);

View File

@ -50,7 +50,7 @@ public class MQTTEventAdapterFactory extends OutputEventAdapterFactory {
//Broker Url
Property brokerUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_URL);
brokerUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL));
brokerUrl.setRequired(true);
brokerUrl.setRequired(false);
brokerUrl.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL_HINT));
//Broker Username
@ -59,11 +59,11 @@ public class MQTTEventAdapterFactory extends OutputEventAdapterFactory {
userName.setRequired(true);
userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT));
//Broker dcr URL
Property dcrUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL);
dcrUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL));
dcrUrl.setRequired(true);
dcrUrl.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL_HINT));
//Broker Password
Property password = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD);
password.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD));
password.setRequired(true);
password.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD_HINT));
//Broker Connection Scopes
Property scopes = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES);
@ -95,10 +95,10 @@ public class MQTTEventAdapterFactory extends OutputEventAdapterFactory {
staticPropertyList.add(brokerUrl);
staticPropertyList.add(userName);
staticPropertyList.add(dcrUrl);
staticPropertyList.add(scopes);
staticPropertyList.add(clearSession);
staticPropertyList.add(qos);
staticPropertyList.add(password);
return staticPropertyList;
}

View File

@ -19,11 +19,16 @@ package org.wso2.carbon.device.mgt.output.adapter.mqtt.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.ssl.Base64;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
@ -36,9 +41,6 @@ import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.event.output.adapter.core.exception.ConnectionUnavailableException;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterRuntimeException;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import java.io.IOException;
import java.net.MalformedURLException;
@ -46,6 +48,8 @@ import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
/**
* MQTT publisher related configuration initialization and publishing capabilties are implemented here.
@ -77,10 +81,8 @@ public class MQTTAdapterPublisher {
MqttConnectOptions connectionOptions = new MqttConnectOptions();
connectionOptions.setCleanSession(cleanSession);
connectionOptions.setKeepAliveInterval(keepAlive);
if (mqttBrokerConnectionConfiguration.getBrokerUsername() != null) {
connectionOptions.setUserName(getToken(mqttBrokerConnectionConfiguration.getBrokerUsername(),
mqttBrokerConnectionConfiguration.getDcrUrl(),
mqttBrokerConnectionConfiguration.getScopes()));
if (mqttBrokerConnectionConfiguration.getUsername() != null) {
connectionOptions.setUserName(getToken());
connectionOptions.setPassword(MQTTEventAdapterConstants.DEFAULT_PASSWORD.toCharArray());
}
// Construct an MQTT blocking mode client
@ -139,7 +141,11 @@ public class MQTTAdapterPublisher {
}
}
private String getToken(String username, String dcrUrlString, String scopes) {
private String getToken() {
String username = this.mqttBrokerConnectionConfiguration.getUsername();
String password = this.mqttBrokerConnectionConfiguration.getPassword();
String dcrUrlString = this.mqttBrokerConnectionConfiguration.getDcrUrl();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (dcrUrlString != null && !dcrUrlString.isEmpty()) {
try {
@ -147,32 +153,34 @@ public class MQTTAdapterPublisher {
HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol());
HttpPost postMethod = new HttpPost(dcrUrlString);
RegistrationProfile registrationProfile = new RegistrationProfile();
registrationProfile.setCallbackUrl(MQTTEventAdapterConstants.DEFAULT_CALLBACK);
registrationProfile.setCallbackUrl(MQTTEventAdapterConstants.EMPTY_STRING);
registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE);
registrationProfile.setOwner(username);
registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE);
registrationProfile.setApplicationType(MQTTEventAdapterConstants.APPLICATION_TYPE);
registrationProfile.setClientName(username + "_" + tenantId);
registrationProfile.setClientName(MQTTEventAdapterConstants.APPLICATION_NAME_PREFIX
+ mqttBrokerConnectionConfiguration.getAdapterName() + "_" + tenantId);
String jsonString = registrationProfile.toJSON();
StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
postMethod.setEntity(requestEntity);
String basicAuth = getBase64Encode(username, password);
postMethod.setHeader(new BasicHeader(MQTTEventAdapterConstants.AUTHORIZATION_HEADER_NAME,
MQTTEventAdapterConstants.AUTHORIZATION_HEADER_VALUE_PREFIX +
basicAuth));
HttpResponse httpResponse = httpClient.execute(postMethod);
if (httpResponse != null) {
String response = MQTTUtil.getResponseString(httpResponse);
try {
if (response != null) {
JSONParser jsonParser = new JSONParser();
JSONObject jsonPayload = (JSONObject) jsonParser.parse(response);
String clientId = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_ID);
String clientSecret = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_SECRET);
JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService();
AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken(
clientId, clientSecret, username, scopes);
return accessTokenInfo.getAccessToken();
return getToken(clientId, clientSecret);
}
} catch (ParseException e) {
String msg = "error occurred while parsing client credential payload";
throw new OutputEventAdapterRuntimeException(msg, e);
} catch (JWTClientException e) {
String msg = "error occurred while parsing the response from JWT Client";
throw new OutputEventAdapterRuntimeException(msg, e);
String msg = "error occurred while parsing generating token for the adapter";
log.error(msg, e);
}
}
} catch (MalformedURLException e) {
throw new OutputEventAdapterRuntimeException("Invalid dcrUrl : " + dcrUrlString);
@ -183,4 +191,39 @@ public class MQTTAdapterPublisher {
throw new OutputEventAdapterRuntimeException("Invalid configuration for mqtt publisher");
}
private String getToken(String clientId, String clientSecret)
throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, ParseException {
URL tokenEndpoint = new URL(mqttBrokerConnectionConfiguration.getTokenUrl());
HttpClient httpClient = MQTTUtil.getHttpClient(tokenEndpoint.getProtocol());
HttpPost postMethod = new HttpPost(tokenEndpoint.toString());
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.GRANT_TYPE_PARAM_NAME,
MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE));
nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_USERNAME,
mqttBrokerConnectionConfiguration.getUsername()));
nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_PASSWORD,
mqttBrokerConnectionConfiguration.getPassword()));
String scopes = mqttBrokerConnectionConfiguration.getScopes();
if (scopes != null && !scopes.isEmpty()) {
nameValuePairs.add(new BasicNameValuePair(MQTTEventAdapterConstants.PASSWORD_GRANT_TYPE_SCOPES, scopes));
}
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
postMethod.addHeader("Authorization", "Basic " + getBase64Encode(clientId, clientSecret));
postMethod.addHeader("Content-Type", "application/x-www-form-urlencoded");
HttpResponse httpResponse = httpClient.execute(postMethod);
String response = MQTTUtil.getResponseString(httpResponse);
if (log.isDebugEnabled()) {
log.debug(response);
}
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(response);
return (String) jsonObject.get(MQTTEventAdapterConstants.ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME);
}
private String getBase64Encode(String key, String value) {
return new String(Base64.encodeBase64((key + ":" + value).getBytes()));
}
}

View File

@ -17,14 +17,25 @@
*/
package org.wso2.carbon.device.mgt.output.adapter.mqtt.util;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import java.util.Map;
public class MQTTBrokerConnectionConfiguration {
private String brokerUsername;
private String adapterName;
private String username;
private String password;
private String dcrUrl;
private String scopes;
private String brokerUrl;
private String tokenUrl;
private boolean cleanSession = true;
private int keepAlive;
public String getTokenUrl() {
return tokenUrl;
}
public String getDcrUrl() {
return dcrUrl;
@ -34,8 +45,12 @@ public class MQTTBrokerConnectionConfiguration {
return scopes;
}
public String getBrokerUsername() {
return brokerUsername;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public boolean isCleanSession() {
@ -50,15 +65,35 @@ public class MQTTBrokerConnectionConfiguration {
return keepAlive;
}
public MQTTBrokerConnectionConfiguration(String brokerUrl, String brokerUsername,
String dcrUrl, String scopes, int keepAlive, String cleanSession) {
this.brokerUsername = brokerUsername;
this.dcrUrl = dcrUrl;
this.scopes = scopes;
this.brokerUrl = brokerUrl;
this.keepAlive = keepAlive;
if (cleanSession != null) {
this.cleanSession = Boolean.parseBoolean(cleanSession);
public String getAdapterName() {
return adapterName;
}
public MQTTBrokerConnectionConfiguration(OutputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) {
adapterName = eventAdapterConfiguration.getName();
this.username = eventAdapterConfiguration.getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME);
this.password = eventAdapterConfiguration.getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_PASSWORD);
String url = eventAdapterConfiguration .getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_URL);
if (url == null || url.isEmpty()) {
url = globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_URL);
}
this.brokerUrl = PropertyUtils.replaceMqttProperty(url);
this.dcrUrl = PropertyUtils
.replaceMqttProperty(globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL));
this.tokenUrl = PropertyUtils
.replaceMqttProperty(globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_TOKEN_URL));
this.scopes = eventAdapterConfiguration.getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES);
if (scopes == null) {
this.scopes = MQTTEventAdapterConstants.EMPTY_STRING;
}
this.cleanSession = Boolean.parseBoolean(eventAdapterConfiguration.getStaticProperties()
.get(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION));
//If global properties are available those will be assigned else constant values will be assigned
if (globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_KEEP_ALIVE) != null) {
keepAlive = Integer.parseInt((globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_KEEP_ALIVE)));
} else {
keepAlive = MQTTEventAdapterConstants.ADAPTER_CONF_DEFAULT_KEEP_ALIVE;
}
}

View File

@ -27,8 +27,10 @@ public final class MQTTEventAdapterConstants {
public static final String ADAPTER_CONF_URL = "url";
public static final String ADAPTER_CONF_USERNAME = "username";
public static final String ADAPTER_CONF_USERNAME_HINT = "username.hint";
public static final String ADAPTER_CONF_PASSWORD = "password";
public static final String ADAPTER_CONF_PASSWORD_HINT = "password.hint";
public static final String ADAPTER_CONF_DCR_URL = "dcrUrl";
public static final String ADAPTER_CONF_DCR_URL_HINT = "dcrUrl.hint";
public static final String ADAPTER_CONF_TOKEN_URL = "tokenUrl";
public static final String ADAPTER_CONF_SCOPES = "scopes";
public static final String ADAPTER_CONF_SCOPES_HINT = "scopes.hint";
public static final String ADAPTER_CONF_URL_HINT = "url.hint";
@ -41,6 +43,9 @@ public final class MQTTEventAdapterConstants {
public static final String ADAPTER_TEMP_DIRECTORY_NAME = "java.io.tmpdir";
public static final String ADAPTER_CONF_CLIENTID = "clientId";
public static final String ADAPTER_CONF_CLIENTID_HINT = "clientId.hint";
public static final String EMPTY_STRING = "";
public static final String ADAPTER_CONF_KEEP_ALIVE = "keepAlive";
public static final int ADAPTER_CONF_DEFAULT_KEEP_ALIVE = 60000;
public static final int DEFAULT_MIN_THREAD_POOL_SIZE = 8;
public static final int DEFAULT_MAX_THREAD_POOL_SIZE = 100;
@ -53,9 +58,19 @@ public final class MQTTEventAdapterConstants {
public static final String DEFAULT_CALLBACK = "";
public static final String DEFAULT_PASSWORD = "";
public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer refresh_token";
public static final String GRANT_TYPE = "password";
public static final String TOKEN_SCOPE = "production";
public static final String APPLICATION_TYPE = "device";
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String APPLICATION_NAME_PREFIX = "OutputAdapter_";
public static final String CLIENT_ID = "clientId";
public static final String CLIENT_SECRET = "clientSecret";
public static final String AUTHORIZATION_HEADER_NAME = "Authorization";
public static final String AUTHORIZATION_HEADER_VALUE_PREFIX = "Basic ";
public static final String PASSWORD_GRANT_TYPE = "password";
public static final String PASSWORD_GRANT_TYPE_USERNAME = "username";
public static final String PASSWORD_GRANT_TYPE_PASSWORD = "password";
public static final String PASSWORD_GRANT_TYPE_SCOPES = "scopes";
public static final String ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME = "access_token";
public static final String GRANT_TYPE_PARAM_NAME = "grant_type";
}

View File

@ -28,7 +28,6 @@ import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import java.io.BufferedReader;
import java.io.IOException;
@ -85,15 +84,4 @@ public class MQTTUtil {
}
}
public static JWTClientManagerService getJWTClientManagerService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
JWTClientManagerService jwtClientManagerService =
(JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
if (jwtClientManagerService == null) {
String msg = "JWT management service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return jwtClientManagerService;
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.output.adapter.mqtt.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class PropertyUtils {
//This method is only used if the mb features are within DAS.
static String replaceMqttProperty(String urlWithPlaceholders) {
String regex = "\\$\\{(.*?)\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matchPattern = pattern.matcher(urlWithPlaceholders);
while (matchPattern.find()) {
String sysPropertyName = matchPattern.group(1);
String sysPropertyValue = System.getProperty(sysPropertyName);
if (sysPropertyValue != null && !sysPropertyName.isEmpty()) {
urlWithPlaceholders = urlWithPlaceholders.replaceAll("\\$\\{(" + sysPropertyName + ")\\}", sysPropertyValue);
}
}
return urlWithPlaceholders;
}
}

View File

@ -18,13 +18,13 @@
topic=Topic
url=Broker Url
url.hint=MQTT broker url
username=Username
username.hint=Username of the broker
dcrUrl=dcrUrl
dcrUrl.hint=Dynamic Client Registration Url
password=Password
password.hint=Password to connect to the server.
scopes=scopes
scopes.hint=Scopes that required to connect with the broker.
url.hint=MQTT broker url
cleanSession=Clean Session
cleanSession.hint=Persist topic subscriptions and ack positions across client sessions
keepAlive=Keep Alive (In seconds)

View File

@ -52,7 +52,7 @@ public class SubscriptionEndpoint {
() +
", for request URI - " + session.getRequestURI());
}
ServiceHolder.getInstance().getUiOutputCallbackControllerService().unsubscribeWebsocket(streamName, version,
ServiceHolder.getInstance().getWebsocketOutputCallbackControllerService().unsubscribeWebsocket(streamName, version,
session);
}
@ -68,7 +68,7 @@ public class SubscriptionEndpoint {
log.error(
"Error occurred in session ID: " + session.getId() + ", for request URI - " + session.getRequestURI() +
", " + throwable.getMessage(), throwable);
ServiceHolder.getInstance().getUiOutputCallbackControllerService().unsubscribeWebsocket(streamName, version,
ServiceHolder.getInstance().getWebsocketOutputCallbackControllerService().unsubscribeWebsocket(streamName, version,
session);
}
}

View File

@ -75,7 +75,7 @@ public class SuperTenantSubscriptionEndpoint extends SubscriptionEndpoint {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(
MultitenantConstants.SUPER_TENANT_ID);
ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName,
ServiceHolder.getInstance().getWebsocketOutputCallbackControllerService().subscribeWebsocket(streamName,
version,
session);
} finally {

View File

@ -74,7 +74,7 @@ public class TenantSubscriptionEndpoint extends SubscriptionEndpoint {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tdomain, true);
ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName
ServiceHolder.getInstance().getWebsocketOutputCallbackControllerService().subscribeWebsocket(streamName
, version, session);
} finally {
PrivilegedCarbonContext.endTenantFlow();

View File

@ -21,18 +21,18 @@ package org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.output.adapter.websocket.UIOutputCallbackControllerService;
import org.wso2.carbon.device.mgt.output.adapter.websocket.WebsocketOutputCallbackControllerService;
import org.wso2.carbon.device.mgt.output.adapter.websocket.service.WebsocketValidationService;
public class ServiceHolder {
private static ServiceHolder instance;
private UIOutputCallbackControllerService uiOutputCallbackControllerService;
private WebsocketOutputCallbackControllerService websocketOutputCallbackControllerService;
private static final Log log = LogFactory.getLog(ServiceHolder.class);
private ServiceHolder(){
uiOutputCallbackControllerService = (UIOutputCallbackControllerService) PrivilegedCarbonContext
.getThreadLocalCarbonContext().getOSGiService(UIOutputCallbackControllerService.class, null);
websocketOutputCallbackControllerService = (WebsocketOutputCallbackControllerService) PrivilegedCarbonContext
.getThreadLocalCarbonContext().getOSGiService(WebsocketOutputCallbackControllerService.class, null);
}
public synchronized static ServiceHolder getInstance() {
@ -42,8 +42,8 @@ public class ServiceHolder {
return instance;
}
public UIOutputCallbackControllerService getUiOutputCallbackControllerService() {
return uiOutputCallbackControllerService;
public WebsocketOutputCallbackControllerService getWebsocketOutputCallbackControllerService() {
return websocketOutputCallbackControllerService;
}
public static WebsocketValidationService getWebsocketValidationService() {

View File

@ -1,80 +0,0 @@
/*
* Copyright (c) 2015, 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.output.adapter.websocket;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.UIEventAdapterConstants;
import org.wso2.carbon.event.output.adapter.core.MessageType;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory;
import org.wso2.carbon.event.output.adapter.core.Property;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
/**
* The UI event adapter factory class to create a UI output adapter
*/
public class UIEventAdapterFactory extends OutputEventAdapterFactory {
private ResourceBundle resourceBundle = ResourceBundle.getBundle("org.wso2.carbon.device.mgt.output.adapter.websocket.i18n" +
".Resources", Locale.getDefault());
public UIEventAdapterFactory() {
}
@Override
public String getType() {
return UIEventAdapterConstants.ADAPTER_TYPE_UI;
}
@Override
public List<String> getSupportedMessageFormats() {
List<String> supportedMessageFormats = new ArrayList<String>();
supportedMessageFormats.add(MessageType.WSO2EVENT);
supportedMessageFormats.add(MessageType.JSON);
return supportedMessageFormats;
}
@Override
public List<Property> getStaticPropertyList() {
return null;
}
@Override
public List<Property> getDynamicPropertyList() {
return null;
}
@Override
public String getUsageTips() {
return resourceBundle.getString(UIEventAdapterConstants.ADAPTER_USAGE_TIPS_PREFIX) + " "
+ resourceBundle.getString(UIEventAdapterConstants.ADAPTER_USAGE_TIPS_POSTFIX);
}
@Override
public OutputEventAdapter createEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) {
return new UIEventAdapter(eventAdapterConfiguration, globalProperties);
}
}

View File

@ -28,8 +28,8 @@ import org.wso2.carbon.databridge.commons.Attribute;
import org.wso2.carbon.databridge.commons.Event;
import org.wso2.carbon.databridge.commons.StreamDefinition;
import org.wso2.carbon.device.mgt.output.adapter.websocket.constants.WebsocketConstants;
import org.wso2.carbon.device.mgt.output.adapter.websocket.internal.UIEventAdaptorServiceDataHolder;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.UIEventAdapterConstants;
import org.wso2.carbon.device.mgt.output.adapter.websocket.internal.WebsocketEventAdaptorServiceDataHolder;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebsocketEventAdapterConstants;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebSocketSessionRequest;
import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter;
@ -56,9 +56,9 @@ import java.util.concurrent.TimeUnit;
* Contains the life cycle of executions regarding the UI Adapter
*/
public class UIEventAdapter implements OutputEventAdapter {
public class WebsocketEventAdapter implements OutputEventAdapter {
private static final Log log = LogFactory.getLog(UIEventAdapter.class);
private static final Log log = LogFactory.getLog(WebsocketEventAdapter.class);
private OutputEventAdapterConfiguration eventAdapterConfiguration;
private Map<String, String> globalProperties;
private int queueSize;
@ -72,7 +72,7 @@ public class UIEventAdapter implements OutputEventAdapter {
private List<Attribute> streamCorrelationAttributes;
private List<Attribute> streamPayloadAttributes;
public UIEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration, Map<String,
public WebsocketEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration, Map<String,
String> globalProperties) {
this.eventAdapterConfiguration = eventAdapterConfiguration;
this.globalProperties = globalProperties;
@ -91,32 +91,32 @@ public class UIEventAdapter implements OutputEventAdapter {
int jobQueSize;
//If global properties are available those will be assigned else constant values will be assigned
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME) != null) {
if (globalProperties.get(WebsocketEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME) != null) {
minThread = Integer.parseInt(globalProperties.get(
UIEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME));
WebsocketEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME));
} else {
minThread = UIEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE;
minThread = WebsocketEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE;
}
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME) != null) {
if (globalProperties.get(WebsocketEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME) != null) {
maxThread = Integer.parseInt(globalProperties.get(
UIEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME));
WebsocketEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME));
} else {
maxThread = UIEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE;
maxThread = WebsocketEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE;
}
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME) != null) {
if (globalProperties.get(WebsocketEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME) != null) {
defaultKeepAliveTime = Integer.parseInt(globalProperties.get(
UIEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME));
WebsocketEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME));
} else {
defaultKeepAliveTime = UIEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_IN_MILLIS;
defaultKeepAliveTime = WebsocketEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_IN_MILLIS;
}
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME) != null) {
if (globalProperties.get(WebsocketEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME) != null) {
jobQueSize = Integer.parseInt(globalProperties.get(
UIEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME));
WebsocketEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME));
} else {
jobQueSize = UIEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE;
jobQueSize = WebsocketEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE;
}
executorService = new ThreadPoolExecutor(minThread, maxThread, defaultKeepAliveTime, TimeUnit.MILLISECONDS,
@ -137,7 +137,7 @@ public class UIEventAdapter implements OutputEventAdapter {
streamPayloadAttributes = streamDefinition.getPayloadData();
ConcurrentHashMap<Integer, ConcurrentHashMap<String, String>> tenantSpecifcEventOutputAdapterMap =
UIEventAdaptorServiceDataHolder.getTenantSpecificOutputEventStreamAdapterMap();
WebsocketEventAdaptorServiceDataHolder.getTenantSpecificOutputEventStreamAdapterMap();
ConcurrentHashMap<String, String> streamSpecifAdapterMap = tenantSpecifcEventOutputAdapterMap.get(tenantId);
@ -157,7 +157,7 @@ public class UIEventAdapter implements OutputEventAdapter {
streamSpecifAdapterMap.put(streamId, eventAdapterConfiguration.getName());
ConcurrentHashMap<Integer, ConcurrentHashMap<String, LinkedBlockingDeque<Object>>> tenantSpecificStreamMap =
UIEventAdaptorServiceDataHolder.getTenantSpecificStreamEventMap();
WebsocketEventAdaptorServiceDataHolder.getTenantSpecificStreamEventMap();
ConcurrentHashMap<String, LinkedBlockingDeque<Object>> streamSpecificEventsMap =
tenantSpecificStreamMap.get(tenantId);
if (streamSpecificEventsMap == null) {
@ -175,16 +175,16 @@ public class UIEventAdapter implements OutputEventAdapter {
}
}
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_EVENT_QUEUE_SIZE_NAME) != null) {
if (globalProperties.get(WebsocketEventAdapterConstants.ADAPTER_EVENT_QUEUE_SIZE_NAME) != null) {
try {
queueSize = Integer.parseInt(
globalProperties.get(UIEventAdapterConstants.ADAPTER_EVENT_QUEUE_SIZE_NAME));
globalProperties.get(WebsocketEventAdapterConstants.ADAPTER_EVENT_QUEUE_SIZE_NAME));
} catch (NumberFormatException e) {
log.error("String does not have the appropriate format for conversion." + e.getMessage());
queueSize = UIEventAdapterConstants.EVENTS_QUEUE_SIZE;
queueSize = WebsocketEventAdapterConstants.EVENTS_QUEUE_SIZE;
}
} else {
queueSize = UIEventAdapterConstants.EVENTS_QUEUE_SIZE;
queueSize = WebsocketEventAdapterConstants.EVENTS_QUEUE_SIZE;
}
}
@ -256,9 +256,9 @@ public class UIEventAdapter implements OutputEventAdapter {
eventString = message.toString();
}
Object[] eventValues = new Object[UIEventAdapterConstants.INDEX_TWO];
eventValues[UIEventAdapterConstants.INDEX_ZERO] = eventString;
eventValues[UIEventAdapterConstants.INDEX_ONE] = System.currentTimeMillis();
Object[] eventValues = new Object[WebsocketEventAdapterConstants.INDEX_TWO];
eventValues[WebsocketEventAdapterConstants.INDEX_ZERO] = eventString;
eventValues[WebsocketEventAdapterConstants.INDEX_ONE] = System.currentTimeMillis();
streamSpecificEvents.add(eventValues);
// fetch all valid sessions checked against any queryParameters provided when subscribing.
@ -282,14 +282,14 @@ public class UIEventAdapter implements OutputEventAdapter {
public void destroy() {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
ConcurrentHashMap<String, String> tenantSpecificAdapterMap = UIEventAdaptorServiceDataHolder
ConcurrentHashMap<String, String> tenantSpecificAdapterMap = WebsocketEventAdaptorServiceDataHolder
.getTenantSpecificOutputEventStreamAdapterMap().get(tenantId);
if (tenantSpecificAdapterMap != null && streamId != null) {
tenantSpecificAdapterMap.remove(streamId); //Removing outputadapter and streamId
}
ConcurrentHashMap<String, LinkedBlockingDeque<Object>> tenantSpecificStreamEventMap =
UIEventAdaptorServiceDataHolder.getTenantSpecificStreamEventMap().get(tenantId);
WebsocketEventAdaptorServiceDataHolder.getTenantSpecificStreamEventMap().get(tenantId);
if (tenantSpecificStreamEventMap != null && streamId != null) {
//Removing the streamId and events registered for the output adapter
tenantSpecificStreamEventMap.remove(streamId);
@ -310,7 +310,7 @@ public class UIEventAdapter implements OutputEventAdapter {
* the matching Steam-Definition for the given StreamId cannot be retrieved.
*/
private StreamDefinition getStreamDefinition(String streamId) throws OutputEventAdapterException {
EventStreamService eventStreamService = UIEventAdaptorServiceDataHolder.getEventStreamService();
EventStreamService eventStreamService = WebsocketEventAdaptorServiceDataHolder.getEventStreamService();
if (eventStreamService != null) {
try {
return eventStreamService.getStreamDefinition(streamId);
@ -337,11 +337,11 @@ public class UIEventAdapter implements OutputEventAdapter {
*/
private CopyOnWriteArrayList<WebSocketSessionRequest> getValidSessions(Object event) {
CopyOnWriteArrayList<WebSocketSessionRequest> validSessions = new CopyOnWriteArrayList<>();
UIOutputCallbackControllerServiceImpl uiOutputCallbackControllerServiceImpl =
UIEventAdaptorServiceDataHolder.getUIOutputCallbackRegisterServiceImpl();
WebsocketOutputCallbackControllerServiceImpl websocketOutputCallbackControllerServiceImpl =
WebsocketEventAdaptorServiceDataHolder.getUIOutputCallbackRegisterServiceImpl();
// get all subscribed web-socket sessions.
CopyOnWriteArrayList<WebSocketSessionRequest> webSocketSessionUtils =
uiOutputCallbackControllerServiceImpl.getSessions(tenantId, streamId);
websocketOutputCallbackControllerServiceImpl.getSessions(tenantId, streamId);
if (webSocketSessionUtils != null) {
for (WebSocketSessionRequest webSocketSessionUtil : webSocketSessionUtils) {
boolean isValidSession;

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2015, 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.output.adapter.websocket;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.Authenticator;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.Authorizer;
import org.wso2.carbon.device.mgt.output.adapter.websocket.service.WebsocketValidationService;
import org.wso2.carbon.device.mgt.output.adapter.websocket.service.WebsocketValidationServiceImpl;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebsocketEventAdapterConstants;
import org.wso2.carbon.event.output.adapter.core.MessageType;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory;
import org.wso2.carbon.event.output.adapter.core.Property;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
/**
* The UI event adapter factory class to create a UI output adapter
*/
public class WebsocketEventAdapterFactory extends OutputEventAdapterFactory {
private ResourceBundle resourceBundle = ResourceBundle.getBundle("org.wso2.carbon.device.mgt.output.adapter.websocket.i18n" +
".Resources", Locale.getDefault());
private BundleContext bundleContext;
private boolean isAuthInitialized = false;
private static final Log log = LogFactory.getLog(WebsocketEventAdapter.class);
public WebsocketEventAdapterFactory() {
}
@Override
public String getType() {
return WebsocketEventAdapterConstants.ADAPTER_TYPE_UI;
}
@Override
public List<String> getSupportedMessageFormats() {
List<String> supportedMessageFormats = new ArrayList<String>();
supportedMessageFormats.add(MessageType.WSO2EVENT);
supportedMessageFormats.add(MessageType.JSON);
return supportedMessageFormats;
}
@Override
public List<Property> getStaticPropertyList() {
return null;
}
@Override
public List<Property> getDynamicPropertyList() {
return null;
}
@Override
public String getUsageTips() {
return resourceBundle.getString(WebsocketEventAdapterConstants.ADAPTER_USAGE_TIPS_PREFIX) + " "
+ resourceBundle.getString(WebsocketEventAdapterConstants.ADAPTER_USAGE_TIPS_POSTFIX);
}
@Override
public OutputEventAdapter createEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) {
if (!isAuthInitialized) {
initializeAuthenticatorAndAuthorizor(globalProperties);
}
return new WebsocketEventAdapter(eventAdapterConfiguration, globalProperties);
}
public BundleContext getBundleContext() {
return bundleContext;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
private void initializeAuthenticatorAndAuthorizor (Map<String, String> globalProperties) {
if (!isAuthInitialized) {
synchronized (WebsocketEventAdapterFactory.class) {
if (!isAuthInitialized) {
try {
WebsocketValidationServiceImpl websocketValidationService =
new WebsocketValidationServiceImpl();
String authenticatorClassName = globalProperties.get(
WebsocketEventAdapterConstants.AUTHENTICATOR_CLASS);
String authorizerClassName = globalProperties.get(WebsocketEventAdapterConstants.AUTHORIZER_CLASS);
if (authenticatorClassName != null && !authenticatorClassName.isEmpty()) {
Class<? extends Authenticator> authenticatorClass = Class.forName(authenticatorClassName)
.asSubclass(Authenticator.class);
Authenticator authenticator = authenticatorClass.newInstance();
authenticator.init(globalProperties);
websocketValidationService.setAuthenticator(authenticator);
}
if (authorizerClassName != null && !authorizerClassName.isEmpty()) {
Class<? extends Authorizer> authorizerClass = Class.forName(authorizerClassName)
.asSubclass(Authorizer.class);
Authorizer authorizer = authorizerClass.newInstance();
authorizer.init(globalProperties);
websocketValidationService.setAuthorizer(authorizer);
}
bundleContext.registerService(
WebsocketValidationService.class.getName(), websocketValidationService, null);
isAuthInitialized = true;
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
log.error("Failed to initialize the class authentication and authorization given " +
"in the websocket validation configuration.", e);
}
}
}
}
}
}

View File

@ -24,7 +24,7 @@ import javax.websocket.Session;
/**
* This interface is exposed as an OSGI service, which will be invoked by the local websocket endpoint to inform new subscriptions; and do un-subscriptions..
*/
public interface UIOutputCallbackControllerService {
public interface WebsocketOutputCallbackControllerService {
/**
* Used to subscribe the session id and stream id for later web socket connectivity

View File

@ -19,9 +19,9 @@
package org.wso2.carbon.device.mgt.output.adapter.websocket;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.output.adapter.websocket.internal.UIEventAdaptorServiceDataHolder;
import org.wso2.carbon.device.mgt.output.adapter.websocket.internal.WebsocketEventAdaptorServiceDataHolder;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebSocketSessionRequest;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.UIEventAdapterConstants;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebsocketEventAdapterConstants;
import javax.websocket.Session;
import java.util.Iterator;
@ -32,12 +32,12 @@ import java.util.concurrent.LinkedBlockingDeque;
/**
* Service implementation class which exposes to front end
*/
public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackControllerService {
public class WebsocketOutputCallbackControllerServiceImpl implements WebsocketOutputCallbackControllerService {
private ConcurrentHashMap<Integer, ConcurrentHashMap<String, CopyOnWriteArrayList<WebSocketSessionRequest>>>
outputEventAdaptorSessionMap;
public UIOutputCallbackControllerServiceImpl() {
public WebsocketOutputCallbackControllerServiceImpl() {
outputEventAdaptorSessionMap = new ConcurrentHashMap<>();
}
@ -53,9 +53,9 @@ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackCo
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
if (version == null || " ".equals(version)) {
version = UIEventAdapterConstants.ADAPTER_UI_DEFAULT_OUTPUT_STREAM_VERSION;
version = WebsocketEventAdapterConstants.ADAPTER_UI_DEFAULT_OUTPUT_STREAM_VERSION;
}
String streamId = streamName + UIEventAdapterConstants.ADAPTER_UI_COLON + version;
String streamId = streamName + WebsocketEventAdapterConstants.ADAPTER_UI_COLON + version;
ConcurrentHashMap<String, CopyOnWriteArrayList<WebSocketSessionRequest>> tenantSpecificAdaptorMap =
outputEventAdaptorSessionMap.get(tenantId);
if (tenantSpecificAdaptorMap == null) {
@ -102,9 +102,9 @@ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackCo
*/
public LinkedBlockingDeque<Object> getEvents(int tenanId, String streamName, String version) {
ConcurrentHashMap<String, LinkedBlockingDeque<Object>> tenantSpecificStreamMap =
UIEventAdaptorServiceDataHolder.getTenantSpecificStreamEventMap().get(tenanId);
WebsocketEventAdaptorServiceDataHolder.getTenantSpecificStreamEventMap().get(tenanId);
if (tenantSpecificStreamMap != null) {
String streamId = streamName + UIEventAdapterConstants.ADAPTER_UI_COLON + version;
String streamId = streamName + WebsocketEventAdapterConstants.ADAPTER_UI_COLON + version;
return tenantSpecificStreamMap.get(streamId);
}
return null;
@ -120,9 +120,9 @@ public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackCo
public void unsubscribeWebsocket(String streamName, String version, Session session) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
if (version == null || " ".equals(version)) {
version = UIEventAdapterConstants.ADAPTER_UI_DEFAULT_OUTPUT_STREAM_VERSION;
version = WebsocketEventAdapterConstants.ADAPTER_UI_DEFAULT_OUTPUT_STREAM_VERSION;
}
String id = streamName + UIEventAdapterConstants.ADAPTER_UI_COLON + version;
String id = streamName + WebsocketEventAdapterConstants.ADAPTER_UI_COLON + version;
ConcurrentHashMap<String, CopyOnWriteArrayList<WebSocketSessionRequest>> tenantSpecificAdaptorMap
= outputEventAdaptorSessionMap.get(tenantId);
if (tenantSpecificAdaptorMap != null) {

View File

@ -22,9 +22,14 @@ import java.util.Map;
*/
public interface Authenticator {
/**
* This is used to initialize the authenticator
* @param globalProperties related to the output adapter
*/
void init(Map<String, String> globalProperties);
/**
* Check whether the client is authenticated to connect.
* @param session user object.
* @return AuthenticationInfo which contains authentication client information.
*/
AuthenticationInfo isAuthenticated(Map<String, List<String>> webSocketConnectionProperties);

View File

@ -20,8 +20,13 @@ import java.util.List;
import java.util.Map;
public class OAuthAuthenticator implements Authenticator {
OAuthTokenValdiator oAuthTokenValdiator;
@Override
public void init(Map<String, String> globalProperties) {
oAuthTokenValdiator = new OAuthTokenValdiator(globalProperties);
}
public AuthenticationInfo isAuthenticated(Map<String, List<String>> webSocketConnectionProperties) {
return OAuthTokenValdiator.getInstance().validateToken(webSocketConnectionProperties);
return oAuthTokenValdiator.validateToken(webSocketConnectionProperties);
}
}

View File

@ -20,24 +20,18 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.AuthenticationInfo;
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Property;
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.WebsocketConfig;
import org.wso2.carbon.device.mgt.output.adapter.websocket.constants.WebsocketConstants;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO;
import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO_OAuth2AccessToken;
import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationResponseDTO;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.io.File;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* This acts as a contract point for OAuth token validation.
@ -47,8 +41,6 @@ public class OAuthTokenValdiator {
private static String cookie;
private GenericObjectPool stubs;
private static Log log = LogFactory.getLog(OAuthTokenValdiator.class);
private static final String WEBSOCKET_CONFIG_LOCATION =
CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "websocket-validation.properties";
private static final String COOKIE_KEY_VALUE_SEPERATOR = "=";
private static final String COOKIE_KEYPAIR_SEPERATOR = ";";
private static final String COOKIE = "cookie";
@ -56,25 +48,9 @@ public class OAuthTokenValdiator {
private static final String TOKEN_IDENTIFIER = "websocket-token";
private static OAuthTokenValdiator oAuthTokenValdiator;
public static OAuthTokenValdiator getInstance() {
if (oAuthTokenValdiator == null) {
synchronized (OAuthTokenValdiator.class) {
if (oAuthTokenValdiator == null) {
oAuthTokenValdiator = new OAuthTokenValdiator();
}
}
}
return oAuthTokenValdiator;
}
private OAuthTokenValdiator() {
try {
Properties properties = getWebSocketConfig();
this.stubs = new GenericObjectPool(new OAuthTokenValidaterStubFactory(properties));
} catch (IOException e) {
log.error("Failed to parse the web socket org.wso2.carbon.device.mgt.output.adapter.websocket.config file " +
WEBSOCKET_CONFIG_LOCATION, e);
}
public OAuthTokenValdiator(Map<String, String> globalProperties) {
this.stubs = new GenericObjectPool(new OAuthTokenValidaterStubFactory(globalProperties));
}
/**
@ -174,19 +150,6 @@ public class OAuthTokenValdiator {
return authenticationInfo;
}
/**
* Retrieve JWT configs from registry.
*/
private Properties getWebSocketConfig() throws IOException {
Properties properties = new Properties();
List<Property> propertyList = WebsocketConfig.getInstance().getWebsocketValidationConfigs().getAuthenticator()
.getProperties().getProperty();
for (Property property : propertyList) {
properties.put(property.getName(), property.getValue());
}
return properties;
}
/**
* Retrieving the token from the http header
* @param webSocketConnectionProperties WebSocket connection information including http headers

View File

@ -35,13 +35,15 @@ import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.oauth.exception.OAuthTokenValidationException;
import org.wso2.carbon.device.mgt.output.adapter.websocket.constants.WebsocketConstants;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.PropertyUtils;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.Properties;
import java.util.Map;
/**
* This follows object pool pattern to manage the stub for oauth validation service.
@ -49,11 +51,11 @@ import java.util.Properties;
public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
private static final Log log = LogFactory.getLog(OAuthTokenValidaterStubFactory.class);
private HttpClient httpClient;
Properties tokenValidationProperties;
Map<String, String> tokenValidationProperties;
public OAuthTokenValidaterStubFactory(Properties tokenValidationProperties) {
this.tokenValidationProperties = tokenValidationProperties;
public OAuthTokenValidaterStubFactory(Map<String, String> globalProperties) {
this.tokenValidationProperties = globalProperties;
this.httpClient = createHttpClient();
}
@ -92,10 +94,10 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
private OAuth2TokenValidationServiceStub generateStub() throws OAuthTokenValidationException {
OAuth2TokenValidationServiceStub stub;
try {
URL hostURL = new URL(tokenValidationProperties.getProperty((WebsocketConstants.TOKEN_VALIDATION_ENDPOINT_URL)));
if (hostURL != null) {
URL hostURL = new URL(PropertyUtils.replaceProperty(tokenValidationProperties.get(
(WebsocketConstants.TOKEN_VALIDATION_ENDPOINT_URL)))
+ WebsocketConstants.TOKEN_VALIDATION_CONTEX);
stub = new OAuth2TokenValidationServiceStub(hostURL.toString());
if (stub != null) {
ServiceClient client = stub._getServiceClient();
client.getServiceContext().getConfigurationContext().setProperty(
HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
@ -103,8 +105,8 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
HttpTransportProperties.Authenticator auth =
new HttpTransportProperties.Authenticator();
auth.setPreemptiveAuthentication(true);
String username = tokenValidationProperties.getProperty(WebsocketConstants.USERNAME);
String password = tokenValidationProperties.getProperty(WebsocketConstants.PASSWORD);
String username = tokenValidationProperties.get(WebsocketConstants.USERNAME);
String password = tokenValidationProperties.get(WebsocketConstants.PASSWORD);
auth.setPassword(username);
auth.setUsername(password);
Options options = client.getOptions();
@ -119,20 +121,15 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
Protocol.registerProtocol(hostURL.getProtocol(), authhttps);
options.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER, authhttps);
}
} else {
String errorMsg = "OAuth Validation instanization failed.";
throw new OAuthTokenValidationException(errorMsg);
}
} else {
String errorMsg = "host url is invalid";
throw new OAuthTokenValidationException(errorMsg);
}
} catch (AxisFault axisFault) {
throw new OAuthTokenValidationException(
"Error occurred while creating the OAuth2TokenValidationServiceStub.", axisFault);
} catch (MalformedURLException e) {
throw new OAuthTokenValidationException(
"Error occurred while parsing token endpoint URL", e);
} catch (OutputEventAdapterException e) {
throw new OAuthTokenValidationException("Invalid token endpoint url", e);
}
return stub;
@ -165,9 +162,9 @@ public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
*/
private HttpClient createHttpClient() {
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
params.setDefaultMaxConnectionsPerHost(Integer.parseInt(tokenValidationProperties.getProperty(
params.setDefaultMaxConnectionsPerHost(Integer.parseInt(tokenValidationProperties.get(
WebsocketConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST)));
params.setMaxTotalConnections(Integer.parseInt(tokenValidationProperties.getProperty(
params.setMaxTotalConnections(Integer.parseInt(tokenValidationProperties.get(
WebsocketConstants.MAXIMUM_TOTAL_HTTP_CONNECTION)));
HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.setParams(params);

View File

@ -21,12 +21,19 @@ package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.AuthenticationInfo;
import javax.websocket.Session;
import java.util.Map;
/**
* Check whether the client is authorized to connect.
*/
public interface Authorizer {
/**
* This is used to initialize the authenticator
* @param globalProperties related to the output adapter
*/
void init(Map<String, String> globalProperties);
/**
* Check whether the client is authorized to connect with the stream.
* @param authenticationInfo authenticated client information.

View File

@ -31,13 +31,13 @@ import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.
.DeviceAccessAuthorizationAdminService;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.DeviceAuthorizationResult;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.DeviceIdentifier;
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Properties;
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Property;
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.WebsocketConfig;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.PropertyUtils;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebSocketSessionRequest;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import javax.websocket.Session;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -50,26 +50,34 @@ public class DeviceAuthorizer implements Authorizer {
private static final String CDMF_SERVER_BASE_CONTEXT = "/api/device-mgt/v1.0";
private static final String DEVICE_MGT_SERVER_URL = "deviceMgtServerUrl";
private static final String STAT_PERMISSION = "statsPermission";
private static final String DEVICE_ID = "deviceId";
private static final String DEVICE_TYPE = "deviceType";
private static Log logger = LogFactory.getLog(DeviceAuthorizer.class);
private static List<String> statPermissions;
public DeviceAuthorizer() {
Properties properties =
WebsocketConfig.getInstance().getWebsocketValidationConfigs().getAuthorizer().getProperties();
statPermissions = getPermissions(properties);
}
@Override
public void init(Map<String, String> globalProperties) {
statPermissions = getPermissions(globalProperties);
try {
deviceAccessAuthorizationAdminService = Feign.builder()
.requestInterceptor(new OAuthRequestInterceptor())
.requestInterceptor(new OAuthRequestInterceptor(globalProperties))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(properties)
.target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(globalProperties)
+ CDMF_SERVER_BASE_CONTEXT);
} catch (OutputEventAdapterException e) {
logger.error("Invalid value for deviceMgtServerUrl in globalProperties.");
}
}
@Override
public boolean isAuthorized(AuthenticationInfo authenticationInfo, Session session, String stream) {
WebSocketSessionRequest webSocketSessionRequest = new WebSocketSessionRequest(session);
Map<String, String> queryParams = webSocketSessionRequest.getQueryParamValuePairs();
String deviceId = queryParams.get("deviceId");
String deviceType = queryParams.get("deviceType");
String deviceId = queryParams.get(DEVICE_ID);
String deviceType = queryParams.get(DEVICE_TYPE);
if (deviceId != null && !deviceId.isEmpty() && deviceType != null && !deviceType.isEmpty()) {
@ -102,27 +110,19 @@ public class DeviceAuthorizer implements Authorizer {
return false;
}
private String getDeviceMgtServerUrl(Properties properties) {
String deviceMgtServerUrl = null;
for (Property property : properties.getProperty()) {
if (property.getName().equals(DEVICE_MGT_SERVER_URL)) {
deviceMgtServerUrl = property.getValue();
break;
}
}
private String getDeviceMgtServerUrl(Map<String, String> properties) throws OutputEventAdapterException {
String deviceMgtServerUrl = PropertyUtils.replaceProperty(properties.get(DEVICE_MGT_SERVER_URL));
if (deviceMgtServerUrl == null || deviceMgtServerUrl.isEmpty()) {
logger.error("deviceMgtServerUrl can't be empty ");
}
return deviceMgtServerUrl;
}
private List<String> getPermissions(Properties properties) {
List<String> permission = new ArrayList<>();
for (Property property : properties.getProperty()) {
if (property.getName().equals(STAT_PERMISSION)) {
permission.add(property.getValue());
}
}
return permission;
private List<String> getPermissions(Map<String, String> properties) {
String stats = properties.get(STAT_PERMISSION);
if (stats != null && !stats.isEmpty()) {
return Arrays.asList(stats.replace("\n", "").split(" "));
}
return null;
}
}

View File

@ -28,9 +28,10 @@ import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.ApiApplicationRegistrationService;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.ApiRegistrationProfile;
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.TokenIssuerService;
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Properties;
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Property;
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.WebsocketConfig;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.PropertyUtils;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import java.util.Map;
/**
* This is a request interceptor to add oauth token header.
@ -51,30 +52,40 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
private static final String CONNECTION_USERNAME = "username";
private static final String CONNECTION_PASSWORD = "password";
private static final String TOKEN_ENDPOINT = "tokenEndpoint";
private static final String TOKEN_ENDPOINT = "tokenUrl";
private static final String TOKEN_REFRESH_TIME_OFFSET = "tokenRefreshTimeOffset";
private static final String TOKEN_SCOPES = "scopes";
private static final String DEVICE_MGT_SERVER_URL = "deviceMgtServerUrl";
private static final String TOKEN_ENDPOINT_CONTEXT = "tokenUrl";
private static String username;
private static String password;
private static String tokenEndpoint;
private static String deviceMgtServerUrl;
private static String scopes;
private static Map<String, String> globalProperties;
/**
* Creates an interceptor that authenticates all requests.
*/
public OAuthRequestInterceptor() {
Properties properties =
WebsocketConfig.getInstance().getWebsocketValidationConfigs().getAuthorizer().getProperties();
deviceMgtServerUrl = getDeviceMgtServerUrl(properties);
refreshTimeOffset = getRefreshTimeOffset(properties);
username = getUsername(properties);
password = getPassword(properties);
tokenEndpoint = getTokenEndpoint(properties);
public OAuthRequestInterceptor(Map<String, String> globalProperties) {
this.globalProperties = globalProperties;
try {
deviceMgtServerUrl = getDeviceMgtServerUrl(globalProperties);
refreshTimeOffset = getRefreshTimeOffset(globalProperties);
username = getUsername(globalProperties);
password = getPassword(globalProperties);
tokenEndpoint = getTokenEndpoint(globalProperties);
scopes = getScopes(globalProperties);
apiApplicationRegistrationService = Feign.builder().requestInterceptor(
new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(ApiApplicationRegistrationService.class,
deviceMgtServerUrl + API_APPLICATION_REGISTRATION_CONTEXT);
} catch (OutputEventAdapterException e) {
logger.error("Invalid url: deviceMgtServerUrl" + deviceMgtServerUrl + " or tokenEndpoint:" + tokenEndpoint,
e);
}
}
@Override
@ -93,7 +104,11 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(TokenIssuerService.class, tokenEndpoint);
if (scopes == null || scopes.isEmpty()) {
tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password);
} else {
tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password, scopes);
}
tokenInfo.setExpires_in(System.currentTimeMillis() + tokenInfo.getExpires_in());
}
synchronized(this) {
@ -106,76 +121,51 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
template.header("Authorization", headerValue);
}
private String getUsername(Properties properties) {
String username = null;
for (Property property : properties.getProperty()) {
if (property.getName().equals(CONNECTION_USERNAME)) {
username = property.getValue();
break;
}
}
private String getUsername(Map<String, String> globalProperties) {
String username = globalProperties.get(CONNECTION_USERNAME);
if (username == null || username.isEmpty()) {
logger.error("username can't be empty ");
}
return username;
}
private String getPassword(Properties properties) {
String password = null;
for (Property property : properties.getProperty()) {
if (property.getName().equals(CONNECTION_PASSWORD)) {
password = property.getValue();
break;
}
}
private String getPassword(Map<String, String> globalProperties) {
String password = globalProperties.get(CONNECTION_PASSWORD);;
if (password == null || password.isEmpty()) {
logger.error("password can't be empty ");
}
return password;
}
private String getDeviceMgtServerUrl(Properties properties) {
String deviceMgtServerUrl = null;
for (Property property : properties.getProperty()) {
if (property.getName().equals(DEVICE_MGT_SERVER_URL)) {
deviceMgtServerUrl = property.getValue();
break;
}
}
private String getDeviceMgtServerUrl(Map<String, String> globalProperties) throws OutputEventAdapterException {
String deviceMgtServerUrl = globalProperties.get(DEVICE_MGT_SERVER_URL);
if (deviceMgtServerUrl == null || deviceMgtServerUrl.isEmpty()) {
logger.error("deviceMgtServerUrl can't be empty ");
}
return deviceMgtServerUrl;
return PropertyUtils.replaceProperty(deviceMgtServerUrl);
}
private String getTokenEndpoint(Properties properties) {
String tokenEndpoint = null;
for (Property property : properties.getProperty()) {
if (property.getName().equals(TOKEN_ENDPOINT)) {
tokenEndpoint = property.getValue();
break;
}
}
if (tokenEndpoint == null || tokenEndpoint.isEmpty()) {
private String getTokenEndpoint(Map<String, String> globalProperties) throws OutputEventAdapterException {
String tokenEndpoint = globalProperties.get(TOKEN_ENDPOINT_CONTEXT);
if ( tokenEndpoint.isEmpty()) {
logger.error("tokenEndpoint can't be empty ");
}
return tokenEndpoint;
return PropertyUtils.replaceProperty(tokenEndpoint);
}
private long getRefreshTimeOffset(Properties properties) {
long refreshTimeOffset = 0;
private long getRefreshTimeOffset(Map<String, String> globalProperties) {
long refreshTimeOffset = 100;
try {
for (Property property : properties.getProperty()) {
if (property.getName().equals(TOKEN_REFRESH_TIME_OFFSET)) {
refreshTimeOffset = Long.parseLong(property.getValue());
break;
}
}
refreshTimeOffset = Long.parseLong(globalProperties.get(TOKEN_REFRESH_TIME_OFFSET));
} catch (NumberFormatException e) {
logger.error("refreshTimeOffset should be a number", e);
}
return refreshTimeOffset;
}
private String getScopes(Map<String, String> globalProperties) {
return globalProperties.get(TOKEN_SCOPES);
}
}

View File

@ -36,7 +36,6 @@ import javax.ws.rs.core.MediaType;
/**
* This hold the api defintion that is used as a contract with netflix feign.
*/
@Path("/token")
public interface TokenIssuerService {
@POST
@ -45,6 +44,12 @@ public interface TokenIssuerService {
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
@QueryParam("password") String password);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
@QueryParam("password") String password, @QueryParam("scopes") String scopes);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)

View File

@ -1,107 +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.output.adapter.websocket.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for Authenticator complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="Authenticator">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Properties" type="{}Properties"/>
* &lt;/sequence>
* &lt;attribute name="class" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Authenticator", propOrder = {
"properties"
})
public class Authenticator {
@XmlElement(name = "Properties", required = false)
protected Properties properties;
@XmlAttribute(name = "class")
protected String clazz;
/**
* Gets the value of the properties property.
*
* @return
* possible object is
* {@link Properties }
*
*/
public Properties getProperties() {
return properties;
}
/**
* Sets the value of the properties property.
*
* @param value
* allowed object is
* {@link Properties }
*
*/
public void setProperties(Properties value) {
this.properties = value;
}
/**
* Gets the value of the clazz property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getClazz() {
return clazz;
}
/**
* Sets the value of the clazz property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setClazz(String value) {
this.clazz = value;
}
}

View File

@ -1,107 +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.output.adapter.websocket.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for Authorizer complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="Authorizer">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Properties" type="{}Properties"/>
* &lt;/sequence>
* &lt;attribute name="class" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Authorizer", propOrder = {
"properties"
})
public class Authorizer {
@XmlElement(name = "Properties", required = false)
protected Properties properties;
@XmlAttribute(name = "class")
protected String clazz;
/**
* Gets the value of the properties property.
*
* @return
* possible object is
* {@link Properties }
*
*/
public Properties getProperties() {
return properties;
}
/**
* Sets the value of the properties property.
*
* @param value
* allowed object is
* {@link Properties }
*
*/
public void setProperties(Properties value) {
this.properties = value;
}
/**
* Gets the value of the clazz property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getClazz() {
return clazz;
}
/**
* Sets the value of the clazz property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setClazz(String value) {
this.clazz = value;
}
}

View File

@ -1,86 +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.output.adapter.websocket.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import java.util.ArrayList;
import java.util.List;
/**
* <p>Java class for Properties complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="Properties">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Property" type="{}Property" maxOccurs="unbounded" minOccurs="0"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Properties", propOrder = {
"property"
})
public class Properties {
@XmlElement(name = "Property")
protected List<Property> property;
/**
* Gets the value of the property property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the property property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getProperty().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link Property }
*
*
*/
public List<Property> getProperty() {
if (property == null) {
property = new ArrayList<Property>();
}
return this.property;
}
}

View File

@ -1,104 +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.output.adapter.websocket.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
/**
* <p>Java class for Property complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="Property">
* &lt;simpleContent>
* &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
* &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/extension>
* &lt;/simpleContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Property", propOrder = {
"value"
})
public class Property {
@XmlValue
protected String value;
@XmlAttribute(name = "name")
protected String name;
/**
* Gets the value of the value property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getValue() {
return value;
}
/**
* Sets the value of the value property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setValue(String value) {
this.value = value;
}
/**
* Gets the value of the name property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setName(String value) {
this.name = value;
}
}

View File

@ -1,82 +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.output.adapter.websocket.config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebsocketUtils;
import org.wso2.carbon.utils.CarbonUtils;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
/**
* This class represents the configuration that are needed for scopes to permission map.
*/
public class WebsocketConfig {
private static WebsocketConfig config = new WebsocketConfig();
private WebsocketValidationConfigs websocketValidationConfigs;
private static final Log log = LogFactory.getLog(WebsocketConfig.class);
private static final String WEBSOCKET_VALIDATION_CONFIG_PATH =
CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "websocket-validation.xml";
private WebsocketConfig() {
}
public static WebsocketConfig getInstance() {
return config;
}
public void init() throws WebsocketValidationConfigurationFailedException {
try {
File deviceMgtConfig = new File(WEBSOCKET_VALIDATION_CONFIG_PATH);
Document doc = WebsocketUtils.convertToDocument(deviceMgtConfig);
/* Un-marshaling DeviceMGtScope configuration */
JAXBContext ctx = JAXBContext.newInstance(WebsocketValidationConfigs.class);
Unmarshaller unmarshaller = ctx.createUnmarshaller();
//unmarshaller.setSchema(getSchema());
websocketValidationConfigs = (WebsocketValidationConfigs) unmarshaller.unmarshal(doc);
} catch (JAXBException e) {
throw new WebsocketValidationConfigurationFailedException("Error occurred while un-marshalling Websocket" +
" Config", e);
}
}
public WebsocketValidationConfigs getWebsocketValidationConfigs() {
if (websocketValidationConfigs == null) {
try {
init();
} catch (WebsocketValidationConfigurationFailedException e) {
log.error("failed to initialize the config", e);
}
}
return websocketValidationConfigs;
}
public void setWebsocketValidationConfigs(WebsocketValidationConfigs websocketValidationConfigsTemp) {
websocketValidationConfigs = websocketValidationConfigsTemp;
}
}

View File

@ -1,105 +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.output.adapter.websocket.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* <p>Java class for WebsocketValidationConfigs complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="WebsocketValidationConfigs">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Authenticator" type="{}Authenticator"/>
* &lt;element name="Authorizer" type="{}Authorizer"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlRootElement(name = "WebsocketValidationConfigs")
@XmlAccessorType(XmlAccessType.FIELD)
public class WebsocketValidationConfigs {
@XmlElement(name = "Authenticator", required = true)
protected Authenticator authenticator;
@XmlElement(name = "Authorizer", required = true)
protected Authorizer authorizer;
/**
* Gets the value of the authenticator property.
*
* @return
* possible object is
* {@link Authenticator }
*
*/
public Authenticator getAuthenticator() {
return authenticator;
}
/**
* Sets the value of the authenticator property.
*
* @param value
* allowed object is
* {@link Authenticator }
*
*/
public void setAuthenticator(Authenticator value) {
this.authenticator = value;
}
/**
* Gets the value of the authorizer property.
*
* @return
* possible object is
* {@link Authorizer }
*
*/
public Authorizer getAuthorizer() {
return authorizer;
}
/**
* Sets the value of the authorizer property.
*
* @param value
* allowed object is
* {@link Authorizer }
*
*/
public void setAuthorizer(Authorizer value) {
this.authorizer = value;
}
}

View File

@ -1,44 +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.output.adapter.websocket.config;
public class WebsocketValidationConfigurationFailedException extends Exception {
private static final long serialVersionUID = -3151279329290703928L;
public WebsocketValidationConfigurationFailedException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public WebsocketValidationConfigurationFailedException(String message, Throwable cause) {
super(message, cause);
}
public WebsocketValidationConfigurationFailedException(String msg) {
super(msg);
}
public WebsocketValidationConfigurationFailedException() {
super();
}
public WebsocketValidationConfigurationFailedException(Throwable cause) {
super(cause);
}
}

View File

@ -29,7 +29,8 @@ public class WebsocketConstants {
public static final String SCOPE_IDENTIFIER = "scopes";
public static final String MAXIMUM_TOTAL_HTTP_CONNECTION = "maximumTotalHttpConnection";
public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST = "maximumHttpConnectionPerHost";
public static final String TOKEN_VALIDATION_ENDPOINT_URL = "tokenValidationEndpoint";
public static final String TOKEN_VALIDATION_ENDPOINT_URL = "keymanagerUrl";
public static final String TOKEN_VALIDATION_CONTEX = "/services/OAuth2TokenValidationService";
public static final String USERNAME = "username";
public static final String PASSWORD = "password";
public static final String TOKEN_PARAM = "token";

Some files were not shown because too many files have changed in this diff Show More