Merge pull request #117 from ayyoob/das-ext

Added DAS extensions features and upgraded analytics versions
application-manager-new
Prabath Abeysekara 9 years ago
commit a6e2b235c9

@ -0,0 +1,79 @@
<api xmlns="http://ws.apache.org/ns/synapse" name="$!apiName" context="$!apiContext" transports="$!transport">
#foreach($resource in $resources)
<resource xmlns="http://ws.apache.org/ns/synapse"
#if($resource.getUriTemplate().contains("{") ||
($resource.getUriTemplate().contains("*") && !$resource.getUriTemplate().endsWith("/*")))
uri-template="$util.escapeXml($resource.getUriTemplate())"
#else
url-mapping="$resource.getUriTemplate()"
#end
methods="$resource.getMethodsAsString()" faultSequence="fault">
<inSequence>
<property name="isDefault" expression="$trp:WSO2_AM_API_DEFAULT_VERSION"/>
<filter source="$ctx:isDefault" regex="true">
<then>
<log level="custom">
<property name="STATUS" value="Faulty invoking through default API.Dropping message to avoid recursion.."/>
</log>
<payloadFactory media-type="xml">
<format>
<am:fault xmlns:am="http://wso2.org/apimanager">
<am:code>500</am:code>
<am:type>Status report</am:type>
<am:message>Internal Server Error</am:message>
<am:description>Faulty invoking through default API</am:description>
</am:fault>
</format>
<args/>
</payloadFactory>
<property name="HTTP_SC" value="500" scope="axis2"/>
<property name="RESPONSE" value="true"/>
<header name="To" action="remove"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<property name="ContentType" scope="axis2" action="remove"/>
<property name="Authorization" scope="transport" action="remove"/>
<property name="Host" scope="transport" action="remove"/>
<property name="Accept" scope="transport" action="remove"/>
<send/>
</then>
<else>
<header name="WSO2_AM_API_DEFAULT_VERSION" scope="transport" value="true"/>
#if( $transport == "https" )
<property name="uri.var.portnum" expression="get-property('https.nio.port')"/>
#else
<property name="uri.var.portnum" expression="get-property('http.nio.port')"/>
#end
<send>
<endpoint>
#if( $transport == "https" )
<http uri-template="https://localhost:{uri.var.portnum}/$!{fwdApiContext}">
#else
<http uri-template="http://localhost:{uri.var.portnum}/$!{fwdApiContext}">
#end
<timeout>
<duration>60000</duration>
<responseAction>fault</responseAction>
</timeout>
<suspendOnFailure>
<progressionFactor>1.0</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
<retryDelay>0</retryDelay>
</markForSuspension>
</http>
</endpoint>
</send>
</else>
</filter>
</inSequence>
<outSequence>
<send/>
</outSequence>
</resource>
#end ## end of resource iterator
<handlers>
<handler class="org.wso2.carbon.apimgt.gateway.handlers.common.SynapsePropertiesHandler"/>
</handlers>
</api>

@ -0,0 +1,262 @@
<!--
~ Copyright (c) 2005-2010, 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.
-->
##################### Define the macros ######################
#macro ( print_if_exist $field $default)
#if($field && "$field" !="")
$field
#else
$default
#end
#end
#macro ( print_string_if_exist $field $default)
#if($field && "$field" !="")
"$field"
#else
"$default"
#end
#end
#macro ( print_if_exist_only $tagname $field)
#if($field && "$field" !="")
<$tagname>$field</$tagname>
#else
## print nothing.
#end
#end
#macro ( print_list $tagname $list)
#if($list && "$list" !="" && $list.size() > 0)
<$tagname>
#foreach($item in $list)
$item #if( $foreach.hasNext ), #end
#end
</$tagname>
#else
## print nothing.
#end
#end
#macro ( timeout $config)
#if( $config.get("actionSelect") == "neverTimeout" )
## print nothing.
#elseif($config.get("actionDuration")|| $config.get("actionSelect"))
<timeout>
#print_if_exist_only("duration" $config.get("actionDuration"))
#print_if_exist_only("responseAction" $config.get("actionSelect"))
</timeout>
#end
<suspendOnFailure>
#print_list( "errorCodes" $config.get("suspendErrorCode"))
#print_if_exist_only("initialDuration" $config.get("suspendDuration"))
#print_if_exist_only("maximumDuration" $config.get("suspendMaxDuration"))
<progressionFactor>#print_if_exist( $config.get("factor") 1.0)</progressionFactor>
</suspendOnFailure>
<markForSuspension>
#print_list("errorCodes" $config.get("retryErroCode"))
<retriesBeforeSuspension>#print_if_exist( $config.get("retryTimeOut") 0)</retriesBeforeSuspension>
<retryDelay>#print_if_exist( $config.get("retryDelay") 0)</retryDelay>
</markForSuspension>
#end
#macro ( http_endpoint $name $ep )
<endpoint name="$name">
<http uri-template="$util.escapeXml($ep.get("url"))">
#timeout( $ep.get('config') )
</http>
#if($destinationBasedStatsEnabled)
<property name="ENDPOINT_ADDRESS" value="$util.escapeXml($ep.get("url"))"/>
#end
</endpoint>
#end
#macro ( draw_endpoint $type $endpoint_config )
#set( $endpointClass = $endpoint_config.get("endpoint_type") )
#set( $endpoints = $endpoint_config.get("${type}_endpoints"))
#set( $ep_name = "${apiName}_API${type}Endpoint_${resourceNo}")
## IF endpoint secured
#if($isEndpointSecured)
#if($isSecureVaultEnabled)
<property xmlns="http://ws.apache.org/ns/synapse" name="password" expression="wso2:vault-lookup('$securevault_alias')"/>
<property xmlns="http://ws.apache.org/ns/synapse" name="unpw" expression="fn:concat('$username',':',get-property('password'))"/>
<property xmlns="http://ws.apache.org/ns/synapse" name="Authorization" expression="fn:concat('Basic ', base64Encode(get-property('unpw')))" scope="transport"/>
#else
<property xmlns="http://ws.apache.org/ns/synapse" name="Authorization" expression="fn:concat('Basic ', base64Encode('$username:$password'))" scope="transport" />
#end
#end
<send>
#if ($endpointClass == "http")
#http_endpoint($ep_name $endpoints)
#elseif ($endpointClass == "address")
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="$ep_name">
#set( $advance_ep = $endpoints.get("config") )
<address uri="$util.escapeXml($endpoints.get("url"))"
#if($advance_ep.get("format") && $advance_ep.get("format") != "" && $advance_ep.get("format") != 'leave-as-is')
format="$advance_ep.get("format")"
#end
#if($advance_ep.get("optimize") && $advance_ep.get("optimize") != "" && $advance_ep.get("optimize") != 'leave-as-is')
optimize="$advance_ep.get("optimize")"
#end
>
#timeout( $endpoints.get('config') )
</address>
#if($destinationBasedStatsEnabled)
<property name="ENDPOINT_ADDRESS" value="$util.escapeXml($endpoints.get("url"))"/>
#end
</endpoint>
#elseif ($endpointClass == "wsdl")
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="$ep_name">
<wsdl uri="$util.escapeXml($endpoints.get("url"))" service="$!endpoint_config.get("wsdlendpointService")" port="$!endpoint_config.get("wsdlendpointPort")">
#timeout()
</wsdl>
#if($destinationBasedStatsEnabled)
<property name="ENDPOINT_ADDRESS" value="$util.escapeXml($endpoints.get("url"))"/>
#end
</endpoint>
#elseif ($endpointClass == "failover")
#set( $failover_endpoints = $endpoint_config.get("${type}_failovers"))
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="$ep_name">
<failover>
#http_endpoint("${ep_name}_0" $endpoints)
#set( $i = 1)
#foreach($endpoint in $failover_endpoints)
#http_endpoint("${ep_name}_$i" $endpoint)
#set( $i = $i + 1)
#end
</failover>
</endpoint>
#elseif ($endpointClass == "load_balance")
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="$ep_name">
#if($endpoint_config.get("sessionManagement") && $endpoint_config.get("sessionManagement") != "" && $endpoint_config.get("sessionManagement") != "none")
<session type="$endpoint_config.get("sessionManagement")">
#if($endpoint_config.get("sessionTimeOut") && $endpoint_config.get("sessionTimeOut") != "")
<sessionTimeout>$endpoint_config.get("sessionTimeOut")</sessionTimeout>
#end
</session>
#end
<loadbalance algorithm="$!endpoint_config.get("algoClassName")"
#if($endpoint_config.get("failOver") && $endpoint_config.get("failOver") != "" && $endpoint_config.get("failOver") == "False")
failover="false"
#end>
#set( $i = 0)
#foreach($endpoint in $endpoints)
#http_endpoint("${ep_name}_$i" $endpoint)
#set( $i = $i + 1)
#end
</loadbalance>
</endpoint>
#end
</send>
#if($destinationBasedStatsEnabled)
<bam>
<serverProfile name="$!profileName">
<streamConfig name="$!streamName" version="$!streamVersion"/>
</serverProfile>
</bam>
#end
#end
######################## End of Macros ######################################
<api xmlns="http://ws.apache.org/ns/synapse" name="$!apiName" context="$!apiContext" version="$!apiVersion" transports="$!transport" version-type="context">
#if($apiIsBlocked)
## if API is blocked send the API Block message
<resource faultSequence=#print_string_if_exist($faultSequence "fault")>
<inSequence>
<payloadFactory>
<format>
<am:fault xmlns:am="http://wso2.org/apimanager">
<am:code>700700</am:code>
<am:message>API blocked</am:message>
<am:description>This API has been blocked temporarily. Please try again later or contact the system administrators.</am:description>
</am:fault>
</format>
</payloadFactory>
<property name="HTTP_SC" value="503" scope="axis2"/>
<property name="RESPONSE" value="true"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<header name="To" action="remove"/>
<send/>
</inSequence>
</resource>
#else
## api not blocked
#set ($resourceNo = 0)
#foreach($resource in $resources)
<resource xmlns="http://ws.apache.org/ns/synapse"
#if($resource.getUriTemplate().contains("{") ||
($resource.getUriTemplate().contains("*") && !$resource.getUriTemplate().endsWith("/*")))
uri-template="$util.escapeXml($resource.getUriTemplate())"
#else
url-mapping="$resource.getUriTemplate()"
#end
methods="$resource.getMethodsAsString()" faultSequence=#print_string_if_exist($faultSequence "fault")>
<inSequence>
#if(!$resource.getMediationScript().equalsIgnoreCase("null"))
<script language="js">
<![CDATA[
$resource.getMediationScript()
]]>
</script>
<filter source="boolean(get-property('CONTENT_TYPE'))" regex="false">
<then>
<property name="messageType" value="application/xml" scope="axis2"/>
</then>
<else>
<property name="messageType" expression="get-property('CONTENT_TYPE')" scope="axis2"/>
</else>
</filter>
#else
<property name="HTTP_SC" value="501" scope="axis2"/>
#end
#if($resource.getMethodsAsString().contains("GET")||$resource.getMethodsAsString().contains("DELETE"))
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
#end
<respond/>
</inSequence>
<outSequence>
<send/>
</outSequence>
</resource>
#set ($resourceNo = $resourceNo + 1)
#end ## end of resource iterator
## print the handlers
#if($handlers.size() > 0)
<handlers xmlns="http://ws.apache.org/ns/synapse">
#foreach($handler in $handlers)
<handler xmlns="http://ws.apache.org/ns/synapse" class="$handler.className">
#if($handler.hasProperties())
#set ($map = $handler.getProperties() )
#foreach($property in $map.entrySet())
<property name="$!property.key" value="$!property.value"/>
#end
#end
</handler>
#end
</handlers>
#end
#if($apiStatus == 'PROTOTYPED')
#end
#end
## end of apiIsBlocked check
</api>

@ -0,0 +1,366 @@
<!--
~ Copyright (c) 2005-2010, 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.
-->
##################### Define the macros ######################
#macro ( print_if_exist $field $default)
#if($field && "$field" !="")
$field
#else
$default
#end
#end
#macro ( print_string_if_exist $field $default)
#if($field && "$field" !="")
"$field"
#else
"$default"
#end
#end
#macro ( print_if_exist_only $tagname $field)
#if($field && "$field" !="")
<$tagname>$field</$tagname>
#else
## print nothing.
#end
#end
#macro ( print_list $tagname $list)
#if($list && "$list" !="" && $list.size() > 0)
<$tagname>
#foreach($item in $list)
$item #if( $foreach.hasNext ), #end
#end
</$tagname>
#else
## print nothing.
#end
#end
#macro ( timeout $config)
#if( $config.get("actionSelect") == "neverTimeout" )
## print nothing.
#elseif($config.get("actionDuration")|| $config.get("actionSelect"))
<timeout>
#print_if_exist_only("duration" $config.get("actionDuration"))
#print_if_exist_only("responseAction" $config.get("actionSelect"))
</timeout>
#end
<suspendOnFailure>
#print_list( "errorCodes" $config.get("suspendErrorCode"))
#print_if_exist_only("initialDuration" $config.get("suspendDuration"))
#print_if_exist_only("maximumDuration" $config.get("suspendMaxDuration"))
<progressionFactor>#print_if_exist( $config.get("factor") 1.0)</progressionFactor>
</suspendOnFailure>
<markForSuspension>
#print_list("errorCodes" $config.get("retryErroCode"))
<retriesBeforeSuspension>#print_if_exist( $config.get("retryTimeOut") 0)</retriesBeforeSuspension>
<retryDelay>#print_if_exist( $config.get("retryDelay") 0)</retryDelay>
</markForSuspension>
#end
#macro ( http_endpoint $name $ep )
<endpoint name="$name">
<http uri-template="$util.escapeXml($ep.get("url"))">
#timeout( $ep.get('config') )
</http>
#if($destinationBasedStatsEnabled)
<property name="ENDPOINT_ADDRESS" value="$util.escapeXml($ep.get("url"))"/>
#end
</endpoint>
#end
#macro ( draw_endpoint $type $endpoint_config )
#set( $endpointClass = $endpoint_config.get("endpoint_type") )
#set( $endpoints = $endpoint_config.get("${type}_endpoints"))
#set( $ep_name = "${apiName}_API${type}Endpoint_${resourceNo}")
## IF endpoint secured
#if($isEndpointSecured)
#if($isSecureVaultEnabled)
<property xmlns="http://ws.apache.org/ns/synapse" name="password" expression="wso2:vault-lookup('$securevault_alias')"/>
<property xmlns="http://ws.apache.org/ns/synapse" name="unpw" expression="fn:concat('$username',':',get-property('password'))"/>
<property xmlns="http://ws.apache.org/ns/synapse" name="Authorization" expression="fn:concat('Basic ', base64Encode(get-property('unpw')))" scope="transport"/>
#else
#if($isEndpointAuthDigest)
<property xmlns="http://ws.apache.org/ns/synapse" name="UNAMEPASSWORD" value="$util.escapeXml($base64unpw)" type="STRING"/>
<property name="BACKEND_URL" value="$util.escapeXml($endpoints.get("url"))"/>
<property name="POSTFIX" expression="get-property('axis2', 'REST_URL_POSTFIX')"/>
<property name="HTTP_METHOD" expression="get-property('axis2', 'HTTP_METHOD')"/>
<property name="POST_TO_URI" value="true" scope="axis2"/>
<property name="MessageType" expression="get-property('axis2', 'messageType')"/>
<enrich>
<source type="body" clone="true"/>
<target type="property" property="MessageBody"/>
</enrich>
<call>
<endpoint name="$ep_name">
<http uri-template="$util.escapeXml($endpoints.get("url"))">
</http>
</endpoint>
</call>
<class name="org.wso2.carbon.apimgt.gateway.mediators.DigestAuthMediator"/>
<property name="Authorization" expression="get-property('AuthHeader')" scope="transport"/>
<property name="messageType" expression="get-property('MessageType')" scope="axis2"/>
<property name="HTTP_METHOD" expression="get-property('HTTP_METHOD')" scope="axis2"/>
<property name="REST_URL_POSTFIX" expression="$ctx:POSTFIX" scope="axis2"/>
<property name="POST_TO_URI" value="true" scope="axis2"/>
<enrich>
<source type="property" property="MessageBody" clone="true"/>
<target type="body"/>
</enrich>
#else
<property xmlns="http://ws.apache.org/ns/synapse" name="Authorization" expression="fn:concat('Basic ', '$base64unpw')" scope="transport"/>
#end
#end
#end
<send>
## If endpoint is http
#if ($endpointClass == "http")
#http_endpoint($ep_name $endpoints)
#elseif ($endpointClass == "address")
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="$ep_name">
#set( $advance_ep = $endpoints.get("config") )
<address uri="$util.escapeXml($endpoints.get("url"))"
#if($advance_ep.get("format") && $advance_ep.get("format") != "" && $advance_ep.get("format") != 'leave-as-is')
format="$advance_ep.get("format")"
#end
#if($advance_ep.get("optimize") && $advance_ep.get("optimize") != "" && $advance_ep.get("optimize") != 'leave-as-is')
optimize="$advance_ep.get("optimize")"
#end
>
#timeout( $endpoints.get('config') )
</address>
#if($destinationBasedStatsEnabled)
<property name="ENDPOINT_ADDRESS" value="$util.escapeXml($endpoints.get("url"))"/>
#end
</endpoint>
#elseif ($endpointClass == "wsdl")
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="$ep_name">
#if (${type} == "production")
<wsdl uri="$util.escapeXml($endpoints.get("url"))" service="$!endpoint_config.get("wsdlendpointService")" port="$!endpoint_config.get("wsdlendpointPort")">
#timeout()
</wsdl>
#else
<wsdl uri="$util.escapeXml($endpoints.get("url"))" service="$!endpoint_config.get("wsdlendpointServiceSandbox")" port="$!endpoint_config.get("wsdlendpointPortSandbox")">
#timeout()
</wsdl>
#end
#if($destinationBasedStatsEnabled)
<property name="ENDPOINT_ADDRESS" value="$util.escapeXml($endpoints.get("url"))"/>
#end
</endpoint>
#elseif ($endpointClass == "failover")
#set( $failover_endpoints = $endpoint_config.get("${type}_failovers"))
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="$ep_name">
<failover>
#http_endpoint("${ep_name}_0" $endpoints)
#set( $i = 1)
#foreach($endpoint in $failover_endpoints)
#http_endpoint("${ep_name}_$i" $endpoint)
#set( $i = $i + 1)
#end
</failover>
</endpoint>
#elseif ($endpointClass == "load_balance")
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="$ep_name">
#if($endpoint_config.get("sessionManagement") && $endpoint_config.get("sessionManagement") != "" && $endpoint_config.get("sessionManagement") != "none")
<session type="$endpoint_config.get("sessionManagement")">
#if($endpoint_config.get("sessionTimeOut") && $endpoint_config.get("sessionTimeOut") != "")
<sessionTimeout>$endpoint_config.get("sessionTimeOut")</sessionTimeout>
#end
</session>
#end
<loadbalance algorithm="$!endpoint_config.get("algoClassName")"
#if($endpoint_config.get("failOver") && $endpoint_config.get("failOver") != "" && $endpoint_config.get("failOver") == "False")
failover="false"
#end>
#set( $i = 0)
#foreach($endpoint in $endpoints)
#http_endpoint("${ep_name}_$i" $endpoint)
#set( $i = $i + 1)
#end
</loadbalance>
</endpoint>
#elseif ($endpointClass == "default")
<endpoint name="$ep_name">
<default>
</default>
</endpoint>
#end
</send>
#if($destinationBasedStatsEnabled)
<filter source="get-property('isStatEnabled')" regex="true">
<then>
<bam>
<serverProfile name="$!profileName">
<streamConfig name="$!streamName" version="$!streamVersion"/>
</serverProfile>
</bam>
</then>
</filter>
#end
#end
######################## End of Macros ######################################
<api xmlns="http://ws.apache.org/ns/synapse" name="$!apiName" context="$!apiContext" version="$!apiVersion" transports="$!transport" version-type="context">
#if($apiIsBlocked)
## if API is blocked send the API Block message
<resource methods="GET POST PUT DELETE PATCH" url-mapping="/*" faultSequence=#print_string_if_exist($faultSequence "fault")>
<inSequence>
<payloadFactory>
<format>
<am:fault xmlns:am="http://wso2.org/apimanager">
<am:code>700700</am:code>
<am:message>API blocked</am:message>
<am:description>This API has been blocked temporarily. Please try again later or contact the system administrators.</am:description>
</am:fault>
</format>
</payloadFactory>
<property name="HTTP_SC" value="503" scope="axis2"/>
<property name="RESPONSE" value="true"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<header name="To" action="remove"/>
<send/>
</inSequence>
</resource>
#else
## api not blocked
#set ($resourceNo = 0)
#foreach($resource in $resources)
<resource xmlns="http://ws.apache.org/ns/synapse"
#if($resource.getUriTemplate().contains("{") ||
($resource.getUriTemplate().contains("*") && !$resource.getUriTemplate().endsWith("/*")))
uri-template="$util.escapeXml($resource.getUriTemplate())"
#else
url-mapping="$resource.getUriTemplate()"
#end
methods="$resource.getMethodsAsString()" faultSequence=#print_string_if_exist($faultSequence "fault")>
<inSequence>
## check and set jwt
#if($jwtIsEnabled && ($apiStatus != 'PROTOTYPED'))
<class name="org.wso2.carbon.apimgt.gateway.mediators.TokenPasser"/>
#end
## check and set response caching
#if($responseCacheEnabled)
<cache scope="per-host" collector="false" hashGenerator="org.wso2.caching.digest.REQUESTHASHGenerator" timeout="$!responseCacheTimeOut">
<implementation type="memory" maxSize="500"/>
</cache>
#end
############## define the filter based on environment type production only, sandbox only , hybrid ############
#if(($environmentType == 'sandbox') || ($environmentType =='hybrid' && !$endpoint_config.get("production_endpoints") ))
#set( $filterRegex = "SANDBOX" )
#else
#set( $filterRegex = "PRODUCTION" )
#end
#if($apiStatus != 'PROTOTYPED')
<filter source="$ctx:AM_KEY_TYPE" regex="$filterRegex">
<then>
#end
<property name="api.ut.backendRequestTime" expression="get-property('SYSTEM_TIME')"/>
#if(($environmentType == 'sandbox') || ($environmentType =='hybrid' && ! $endpoint_config.get("production_endpoints") ))
#draw_endpoint( "sandbox" $endpoint_config )
#else
#draw_endpoint( "production" $endpoint_config )
#end
#if($apiStatus != 'PROTOTYPED')
</then>
<else>
#if($environmentType !='hybrid')
<payloadFactory>
<format>
<error xmlns="">
#if($environmentType == 'production')
<message>Sandbox Key Provided for Production Gateway</message>
#elseif($environmentType == 'sandbox')
<message>Production Key Provided for Sandbox Gateway</message>
#end
</error>
</format>
</payloadFactory>
<property name="ContentType" value="application/xml" scope="axis2"/>
<property name="RESPONSE" value="true"/>
<header name="To" action="remove"/>
<property name="HTTP_SC" value="401" scope="axis2"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<send/>
#else
#if($endpoint_config.get("production_endpoints") && $endpoint_config.get("sandbox_endpoints"))
#draw_endpoint( "sandbox" $endpoint_config )
#elseif($endpoint_config.get("production_endpoints"))
<sequence key="_sandbox_key_error_"/>
#elseif($endpoint_config.get("sandbox_endpoints"))
<sequence key="_production_key_error_"/>
#end
#end
</else>
</filter>
#end
</inSequence>
<outSequence>
<class name="org.wso2.carbon.apimgt.usage.publisher.APIMgtResponseHandler"/>
## check and set response caching
#if($responseCacheEnabled)
<cache scope="per-host" collector="true"/>
#end
<send/>
</outSequence>
</resource>
#set ($resourceNo = $resourceNo + 1)
#end ## end of resource iterator
## print the handlers
#if($handlers.size() > 0)
<handlers xmlns="http://ws.apache.org/ns/synapse">
#foreach($handler in $handlers)
<handler xmlns="http://ws.apache.org/ns/synapse" class="$handler.className">
#if($handler.hasProperties())
#set ($map = $handler.getProperties() )
#foreach($property in $map.entrySet())
<property name="$!property.key" value="$!property.value"/>
#end
#end
</handler>
#end
</handlers>
#end
#end
#if($apiStatus == 'PROTOTYPED')
#end
## end of apiIsBlocked check
<handlers>
<handler class="org.wso2.carbon.apimgt.gateway.handlers.security.CORSRequestHandler">
<property name="inline" value="INLINE"/>
</handler>
</handlers>
</api>

@ -111,6 +111,9 @@
<exclude>**/nimbus-jose-jwt_2.26.1.wso2v2.jar</exclude>
<exclude>**/org.wso2.carbon.hostobjects.sso_4.4.3.jar</exclude>
<exclude>**/org.wso2.carbon.hostobjects.sso_4.3.2.jar</exclude>
<!--<exclude>**/libthrift_0.8.0.wso2v1.jar</exclude>-->
<exclude>**/am#sample#calculator#v1.war</exclude>
<exclude>**/api.war</exclude>
</excludes>
</fileSet>
@ -216,6 +219,7 @@
<include>**/api-manager.xml</include>
<include>**/sso-idp-config.xml</include>
<include>**/application-authentication.xml</include>
<include>**/broker.xml</include>
</includes>
</fileSet>
<fileSet>
@ -519,6 +523,13 @@
<directory>src/api-resources/synapse-configs/default/sequences</directory>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/resources/apim-synapse-config/</outputDirectory>
</fileSet>
<fileSet>
<directory>src/api-resources/api_templates</directory>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/resources/api_templates</outputDirectory>
<includes>
<include>**/**.xml</include>
</includes>
</fileSet>
<!-- Copying synapse-config directory -->
<fileSet>
@ -843,12 +854,6 @@
<fileMode>644</fileMode>
</file>
<!-- Copying event-broker.xml -->
<file>
<source>src/repository/conf/event-broker.xml</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf</outputDirectory>
<filtered>true</filtered>
<fileMode>644</fileMode>
</file>
<file>
<source>../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/messaging-event-broker.xml</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf</outputDirectory>
@ -875,15 +880,6 @@
<fileMode>644</fileMode>
</file>
<!-- Copying thrift-authentication.xml -->
<file>
<source>
../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/identity/thrift-authentication.xml
</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf/identity
</outputDirectory>
<filtered>true</filtered>
<fileMode>644</fileMode>
</file>
<file>
<source>src/repository/conf/application-authenticators.xml</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf/security/
@ -903,6 +899,20 @@
</outputDirectory>
<fileMode>644</fileMode>
</file>
<file>
<source>src/repository/conf/identity/thrift-authentication.xml</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf/identity</outputDirectory>
<filtered>true</filtered>
<fileMode>644</fileMode>
</file>
<file>
<source>
src/repository/conf/identity/identity-providers/CDMF_DEFAULT_IDP.xml
</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf/identity/identity-providers</outputDirectory>
<filtered>true</filtered>
<fileMode>644</fileMode>
</file>
<!-- Copying governance.xml -->
<file>
<source>
@ -917,6 +927,12 @@
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf</outputDirectory>
<fileMode>644</fileMode>
</file>
<!-- Copying broker.xml -->
<file>
<source>src/repository/conf/broker.xml</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf</outputDirectory>
<fileMode>644</fileMode>
</file>
<file>
<source>
../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/tomcat/webapp-classloading.xml
@ -1368,6 +1384,14 @@
<filtered>true</filtered>
<fileMode>644</fileMode>
</file>
<file>
<source>
../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/etc/websocket-validation.properties
</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf/etc</outputDirectory>
<filtered>true</filtered>
<fileMode>644</fileMode>
</file>
<file>
<source>
../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/etc/device-analytics-config.xml
@ -1378,7 +1402,7 @@
</file>
<file>
<source>
../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/identity/identity-providers/CDMF_DEFAULT_IDP.xml
src/repository/conf/identity/identity-providers/CDMF_DEFAULT_IDP.xml
</source>
<outputDirectory>${pom.artifactId}-${pom.version}/repository/conf/identity/identity-providers</outputDirectory>
<filtered>true</filtered>

@ -94,7 +94,7 @@
jwt token, he needs to enable this parameter.
The DefaultClaimsRetriever class adds user claims from the default carbon user store.
-->
<!--ClaimsRetrieverImplClass>org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever</ClaimsRetrieverImplClass-->
<ClaimsRetrieverImplClass>org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever</ClaimsRetrieverImplClass>
<!--
The dialectURI under which the claimURIs that need to be appended to the
@ -102,17 +102,17 @@
same value is used in the keys for appending the default properties to the
JWT.
-->
<!--ConsumerDialectURI>http://wso2.org/claims</ConsumerDialectURI-->
<ConsumerDialectURI>http://wso2.org/claims</ConsumerDialectURI>
<!--
Signature algorithm. Accepts "SHA256withRSA" or "NONE". To disable signing explicitly specify "NONE".
-->
<!--SignatureAlgorithm>SHA256withRSA</SignatureAlgorithm-->
<SignatureAlgorithm>SHA256withRSA</SignatureAlgorithm>
<!--
Enable/Disable JWT generation. Default is false.
-->
<!--EnableTokenGeneration>false</EnableTokenGeneration-->
<EnableTokenGeneration>true</EnableTokenGeneration>
<!--
Remove OAuth headers from outgoing message or keep with it.
@ -161,7 +161,7 @@
<!--
Endpoint URLs for the APIs hosted in this API gateway.
-->
<GatewayEndpoint>http://${carbon.local.ip}:${mgt.transport.http.port},https://${carbon.local.ip}:${mgt.transport.https.port}</GatewayEndpoint>
<GatewayEndpoint>http://${carbon.local.ip}:${http.nio.port},https://${carbon.local.ip}:${https.nio.port}</GatewayEndpoint>
</Environment>
</Environments>

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~ Copyright (c) 2005-2010, WSO2 Inc. (http://wso2.com) 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
~ 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
~ 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.
~ 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.
-->
<axisconfig name="AxisJava2.0">
@ -58,8 +58,8 @@
<parameter name="ModulesDirectory">axis2modules</parameter>
<!-- User agent and the server details to be used in the http communication -->
<parameter name="userAgent" locked="true">WSO2 ESB 4.9.0</parameter>
<parameter name="server" locked="true">WSO2 ESB 4.9.0</parameter>
<parameter name="userAgent" locked="true">WSO2 IoT 1.0.0</parameter>
<parameter name="server" locked="true">WSO2 IoT 1.O.0</parameter>
<!-- During a fault, stacktrace can be sent with the fault message. The following flag -->
<!-- will control that behaviour -->
@ -153,9 +153,11 @@
<!-- expected to be resolved based on the content type. -->
<messageFormatters>
<messageFormatter contentType="application/x-www-form-urlencoded"
class="org.apache.synapse.commons.formatters.XFormURLEncodedFormatter"/>
class="org.apache.axis2.transport.http.XFormURLEncodedFormatter"/>
<messageFormatter contentType="multipart/form-data"
class="org.apache.axis2.transport.http.MultipartFormDataFormatter"/>
<messageFormatter contentType="text/html"
class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>
<messageFormatter contentType="application/xml"
class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>
<messageFormatter contentType="text/xml"
@ -167,25 +169,47 @@
<!--JSON Message Formatters-->
<messageFormatter contentType="application/json"
class="org.apache.synapse.commons.json.JsonStreamFormatter"/>
<!--messageFormatter contentType="application/x-www-form-urlencoded"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/-->
<!--messageFormatter contentType="multipart/form-data"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/-->
<!--messageFormatter contentType="application/xml"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/-->
<!--messageFormatter contentType="text/html"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/-->
<!--messageFormatter contentType="application/soap+xml"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/-->
<!--messageFormatter contentType="text/xml"
class="org.apache.synapse.commons.json.JsonFormatter"/>
<!--messageFormatter contentType="application/json"
class="org.apache.synapse.commons.json.JsonStreamFormatter"/-->
<messageFormatter contentType="application/json/badgerfish"
class="org.apache.axis2.json.JSONBadgerfishMessageFormatter"/>
<messageFormatter contentType="text/javascript"
class="org.apache.axis2.json.JSONMessageFormatter"/>
<!-- See https://wso2.org/jira/browse/ESBJAVA-1725 before enabling bellow line -->
<!--messageFormatter contentType=".*"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/-->
<!--messageFormatter contentType="application/x-www-form-urlencoded"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="multipart/form-data"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="multipart/related"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="application/xml"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="text/html"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="text/plain"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="application/soap+xml"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="text/xml"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="application/json"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="application/json/badgerfish"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="text/javascript"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="application/octet-stream"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/-->
<!--messageFormatter contentType="x-application/hessian"
class="org.apache.synapse.format.hessian.HessianMessageFormatter"/-->
<!--messageFormatter contentType=""
class="org.apache.synapse.format.hessian.HessianMessageFormatter"/-->
<!--messageFormatter contentType="application/edi-hl7"
class="org.wso2.carbon.business.messaging.hl7.message.HL7MessageFormatter"/-->
class="org.apache.synapse.format.hessian.HessianMessageFormatter"/>
<messageFormatter contentType=""
class="org.apache.synapse.format.hessian.HessianMessageFormatter"/-->
</messageFormatters>
<!-- ================================================= -->
@ -198,6 +222,8 @@
<messageBuilders>
<messageBuilder contentType="application/xml"
class="org.apache.axis2.builder.ApplicationXMLBuilder"/>
<messageBuilder contentType="text/html"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="application/x-www-form-urlencoded"
class="org.apache.synapse.commons.builders.XFormURLEncodedBuilder"/>
<messageBuilder contentType="multipart/form-data"
@ -207,35 +233,56 @@
<!--JSON Message Builders-->
<messageBuilder contentType="application/json"
class="org.apache.synapse.commons.json.JsonStreamBuilder"/>
class="org.apache.synapse.commons.json.JsonBuilder"/>
<!--messageBuilder contentType="application/json"
class="org.apache.synapse.commons.json.JsonStreamBuilder"/-->
<messageBuilder contentType="application/json/badgerfish"
class="org.apache.axis2.json.JSONBadgerfishOMBuilder"/>
<messageBuilder contentType="text/javascript"
class="org.apache.axis2.json.JSONBuilder"/>
<!--messageBuilder contentType="text/javascript"
class="org.apache.axis2.json.JSONStreamBuilder"/-->
<!--See https://wso2.org/jira/browse/ESBJAVA-1725 before enabling bellow line -->
<!--messageBuilder contentType=".*"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
<!--messageBuilder contentType="application/xml"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
<!--messageBuilder contentType="application/x-www-form-urlencoded"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
<!--messageBuilder contentType="multipart/form-data"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
<!--messageBuilder contentType="multipart/related"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
<!--messageBuilder contentType="application/soap+xml"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
<!--messageBuilder contentType="text/plain"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
<!--messageBuilder contentType="text/xml"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="application/x-www-form-urlencoded"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="multipart/form-data"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="multipart/related"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="application/soap+xml"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="text/plain"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="text/html"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="text/xml"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="application/json"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="application/json/badgerfish"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="text/javascript"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageBuilder contentType="application/octet-stream"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/-->
<!--messageBuilder contentType="x-application/hessian"
class="org.apache.synapse.format.hessian.HessianMessageBuilder"/-->
<!--messageBuilder contentType=""
class="org.apache.synapse.format.hessian.HessianMessageBuilder"/>
<messageBuilder contentType=""
class="org.apache.synapse.format.hessian.HessianMessageBuilder"/-->
<!--messageBuilder contentType="application/edi-hl7"
class="org.wso2.carbon.business.messaging.hl7.message.HL7MessageBuilder"/-->
</messageBuilders>
<!-- ================================================= -->
<!-- Transport Ins (Listeners) -->
<!-- ================================================= -->
<transportReceiver name="http"
class="org.apache.synapse.transport.passthru.PassThroughHttpListener">
<transportReceiver name="http" class="org.apache.synapse.transport.passthru.PassThroughHttpListener">
<parameter name="port" locked="false">8280</parameter>
<parameter name="non-blocking" locked="false">true</parameter>
<!--parameter name="bind-address" locked="false">hostname or IP address</parameter-->
@ -244,11 +291,19 @@
<!--<parameter name="priorityConfigFile" locked="false">location of priority configuration file</parameter>-->
</transportReceiver>
<transportReceiver name="https"
class="org.apache.synapse.transport.passthru.PassThroughHttpSSLListener">
<!-- the non blocking http transport based on HttpCore + NIO extensions -->
<!--transportReceiver name="http" class="org.apache.synapse.transport.nhttp.HttpCoreNIOListener">
<parameter name="port" locked="false">8280</parameter>
<parameter name="non-blocking" locked="false">true</parameter-->
<!--parameter name="bind-address" locked="false">hostname or IP address</parameter-->
<!--parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter-->
<!--parameter name="httpGetProcessor" locked="false">org.wso2.carbon.transport.nhttp.api.NHttpGetProcessor</parameter-->
<!--<parameter name="priorityConfigFile" locked="false">location of priority configuration file</parameter>
</transportReceiver-->
<transportReceiver name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLListener">
<parameter name="port" locked="false">8243</parameter>
<parameter name="non-blocking" locked="false">true</parameter>
<parameter name="HttpsProtocols">TLSv1,TLSv1.1,TLSv1.2</parameter>
<!--parameter name="bind-address" locked="false">hostname or IP address</parameter-->
<!--parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter-->
<parameter name="httpGetProcessor" locked="false">org.wso2.carbon.mediation.transport.handlers.PassThroughNHttpGetProcessor</parameter>
@ -271,13 +326,76 @@
supports optional|require or defaults to none -->
</transportReceiver>
<!-- the non blocking https transport based on HttpCore + SSL-NIO extensions -->
<!--transportReceiver name="https" class="org.apache.synapse.transport.nhttp.HttpCoreNIOSSLListener">
<parameter name="port" locked="false">8243</parameter>
<parameter name="non-blocking" locked="false">true</parameter-->
<!--parameter name="bind-address" locked="false">hostname or IP address</parameter-->
<!--parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter-->
<!--<parameter name="priorityConfigFile" locked="false">location of priority configuration file</parameter>-->
<!--parameter name="httpGetProcessor" locked="false">org.wso2.carbon.transport.nhttp.api.NHttpGetProcessor</parameter>
<parameter name="keystore" locked="false">
<KeyStore>
<Location>repository/resources/security/wso2carbon.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
<KeyPassword>wso2carbon</KeyPassword>
</KeyStore>
</parameter>
<parameter name="truststore" locked="false">
<TrustStore>
<Location>repository/resources/security/client-truststore.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
</TrustStore>
</parameter-->
<!--<parameter name="SSLVerifyClient">require</parameter>
supports optional|require or defaults to none -->
<!--/transportReceiver-->
<transportReceiver name="local" class="org.wso2.carbon.core.transports.local.CarbonLocalTransportReceiver"/>
<!-- Pass-through HTTP Transport Receivers -->
<!--<transportReceiver name="passthru-http" class="org.wso2.carbon.transport.passthru.PassThroughHttpListener">
<parameter name="port">8281</parameter>
<parameter name="non-blocking">true</parameter>-->
<!--parameter name="bind-address" locked="false">hostname or IP address</parameter-->
<!--parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter-->
<!--</transportReceiver>-->
<!--<transportReceiver name="passthru-https" class="org.wso2.carbon.transport.passthru.PassThroughHttpSSLListener">
<parameter name="port" locked="false">8244</parameter>
<parameter name="non-blocking" locked="false">true</parameter>-->
<!--parameter name="bind-address" locked="false">hostname or IP address</parameter-->
<!--parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter-->
<!--<parameter name="keystore" locked="false">
<KeyStore>
<Location>repository/resources/security/wso2carbon.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
<KeyPassword>wso2carbon</KeyPassword>
</KeyStore>
</parameter>
<parameter name="truststore" locked="false">
<TrustStore>
<Location>repository/resources/security/client-truststore.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
</TrustStore>
</parameter>-->
<!--<parameter name="SSLVerifyClient">require</parameter>
supports optional|require or defaults to none -->
<!--</transportReceiver>-->
<!--<transportReceiver name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportListener"/>-->
<!--<transportReceiver name="mailto" class="org.apache.axis2.transport.mail.MailTransportListener">-->
<!-- configure any optional POP3/IMAP properties
check com.sun.mail.pop3 and com.sun.mail.imap package documentation for more details-->
check com.sun.mail.pop3 and com.sun.mail.imap package documentation for more details-->
<!--</transportReceiver>-->
<!--<transportReceiver name="admin/https" class="org.wso2.esb.transport.tomcat.HttpsTransportListener">-->
<!--<parameter name="port" locked="false">9444</parameter>-->
<!--<parameter name="non-blocking" locked="false">true</parameter>-->
<!--</transportReceiver>-->
<!--Uncomment this and configure as appropriate for JMS transport support, after setting up your JMS environment (e.g. ActiveMQ)
@ -328,61 +446,39 @@
</parameter>
</transportReceiver-->
<!--Uncomment this and configure as appropriate for JMS transport support with WSO2 MB 2.x.x -->
<!--transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="myTopicConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">repository/conf/jndi.properties</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>
</parameter>
<parameter name="myQueueConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">repository/conf/jndi.properties</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>
<parameter name="default" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">repository/conf/jndi.properties</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>
</transportReceiver-->
<!--Uncomment this for FIX transport support
<transportReceiver name="fix" class="org.apache.synapse.transport.fix.FIXTransportListener"/>
-->
<!--transportReceiver name="hl7" class="org.wso2.carbon.business.messaging.hl7.transport.HL7TransportListener"/-->
<!-- SAP Transport Listeners -->
<!-- <transportReceiver name="idoc" class="org.wso2.carbon.transports.sap.SAPTransportListener"/> -->
<!-- <transportReceiver name="bapi" class="org.wso2.carbon.transports.sap.SAPTransportListener"/> -->
<!--Uncomment this and configure as appropriate for RabbitMQ transport support
<transportReceiver name="rabbitmq" class="org.apache.axis2.transport.rabbitmq.RabbitMQListener">
<parameter name="AMQPConnectionFactory" locked="false">
<parameter name="rabbitmq.server.host.name" locked="false">localhost</parameter>
<parameter name="rabbitmq.server.port" locked="false">5672</parameter>
<parameter name="rabbitmq.server.user.name" locked="false"></parameter>
<parameter name="rabbitmq.server.password" locked="false"></parameter>
<parameter name="rabbitmq.connection.retry.interval" locked="false">10000</parameter>
<parameter name="rabbitmq.connection.retry.count" locked="false">5</parameter>
</parameter>
</transportReceiver-->
<!--<transportReceiver name="http"-->
<!--class="org.wso2.carbon.core.transports.http.HttpTransportListener">-->
<!--
Uncomment the following if you are deploying this within an application server. You
need to specify the HTTP port of the application server
-->
<!--<parameter name="port">9763</parameter>-->
<!--
Uncomment the following to enable Apache2 mod_proxy. The port on the Apache server is 80
in this case.
-->
<!--<parameter name="proxyPort">80</parameter>-->
<!--</transportReceiver>-->
<!-- <transportReceiver name="mqtt" class="org.apache.axis2.transport.mqtt.MqttListener">
<parameter locked="false" name="mqttConFactory">
<parameter locked="false" name="mqtt.server.host.name">localhost</parameter>
<parameter name="mqtt.connection.factory">mqttConFactory</parameter>
<parameter locked="false" name="mqtt.server.port">1883</parameter>
<parameter locked="false" name="mqtt.client.id">client-id-1234</parameter>
<parameter locked="false" name="mqtt.topic.name">esb.test</parameter>
</parameter>
</transportReceiver>-->
<!--<transportReceiver name="https"-->
<!--class="org.wso2.carbon.core.transports.http.HttpsTransportListener">-->
<!--
Uncomment the following if you are deploying this within an application server. You
need to specify the HTTPS port of the application server
-->
<!--<parameter name="port">9443</parameter>-->
<!--
Uncomment the following to enable Apache2 mod_proxy. The port on the Apache server is 443
in this case.
-->
<!--<parameter name="proxyPort">443</parameter>-->
<!--</transportReceiver>-->
<!-- ================================================= -->
<!-- Transport Outs (Senders) -->
@ -390,12 +486,46 @@
<transportSender name="http" class="org.apache.synapse.transport.passthru.PassThroughHttpSender">
<parameter name="non-blocking" locked="false">true</parameter>
<!--<parameter name="warnOnHTTP500" locked="false">*</parameter>-->
<!--parameter name="http.proxyHost" locked="false">localhost</parameter-->
<!--<parameter name="http.proxyPort" locked="false">3128</parameter>-->
<!--<parameter name="http.nonProxyHosts" locked="false">localhost|moon|sun</parameter>-->
</transportSender>
<!-- the non-blocking http transport based on HttpCore + NIO extensions -->
<!--transportSender name="http" class="org.apache.synapse.transport.nhttp.HttpCoreNIOSender">
<parameter name="non-blocking" locked="false">true</parameter>
</transportSender>
<transportSender name="https" class="org.apache.synapse.transport.nhttp.HttpCoreNIOSSLSender">
<parameter name="non-blocking" locked="false">true</parameter>
<parameter name="keystore" locked="false">
<KeyStore>
<Location>repository/resources/security/wso2carbon.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
<KeyPassword>wso2carbon</KeyPassword>
</KeyStore>
</parameter>
<parameter name="truststore" locked="false">
<TrustStore>
<Location>repository/resources/security/client-truststore.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
</TrustStore>
</parameter-->
<!--<parameter name="HostnameVerifier">DefaultAndLocalhost</parameter>-->
<!--supports Strict|AllowAll|DefaultAndLocalhost or the default if none specified -->
<!--/transportSender-->
<!-- Transport sender for the non blocking local transport-->
<!--transportSender name="local" class="org.apache.axis2.transport.local.NonBlockingLocalTransportSender"/-->
<transportSender name="local" class="org.wso2.carbon.core.transports.local.CarbonLocalTransportSender"/>
<!-- Pass-through HTTP Transport Senders -->
<!--<transportSender name="passthru-http" class="org.wso2.carbon.transport.passthru.PassThroughHttpSender">
<parameter name="non-blocking" locked="false">true</parameter>
<parameter name="warnOnHTTP500" locked="false">*</parameter>-->
<!--parameter name="http.proxyHost" locked="false">localhost</parameter>
<parameter name="http.proxyPort" locked="false">3128</parameter>
<parameter name="http.nonProxyHosts" locked="false">localhost|moon|sun</parameter-->
<!--</transportSender>-->
<transportSender name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLSender">
<parameter name="non-blocking" locked="false">true</parameter>
<parameter name="keystore" locked="false">
@ -417,13 +547,29 @@
<!--supports Strict|AllowAll|DefaultAndLocalhost or the default if none specified -->
</transportSender>
<transportSender name="local" class="org.wso2.carbon.core.transports.local.CarbonLocalTransportSender"/>
<!--Uncomment this local transport to use local transport in mediation flow-->
<!--<transportSender name="local" class="org.apache.axis2.transport.local.NonBlockingLocalTransportSender"/>-->
<!--<transportSender name="passthru-https" class="org.wso2.carbon.transport.passthru.PassThroughHttpSSLSender">
<parameter name="non-blocking" locked="false">true</parameter>
<parameter name="keystore" locked="false">
<KeyStore>
<Location>repository/resources/security/wso2carbon.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
<KeyPassword>wso2carbon</KeyPassword>
</KeyStore>
</parameter>
<parameter name="truststore" locked="false">
<TrustStore>
<Location>repository/resources/security/client-truststore.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
</TrustStore>
</parameter>-->
<!--<parameter name="HostnameVerifier">DefaultAndLocalhost</parameter>-->
<!--supports Strict|AllowAll|DefaultAndLocalhost or the default if none specified -->
<!--</transportSender>-->
<!-- uncomment this and configure to use connection pools for sending messages>
<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/-->
<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/-->
<!--transportSender name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportSender"/-->
@ -443,16 +589,20 @@
<transportSender name="fix" class="org.apache.synapse.transport.fix.FIXTransportSender"/>
-->
<!--transportSender name="hl7" class="org.wso2.carbon.business.messaging.hl7.transport.HL7TransportSender"/-->
<!-- SAP Transport Senders -->
<!-- <transportSender name="idoc" class="org.wso2.carbon.transports.sap.SAPTransportSender"/> -->
<!-- <transportSender name="bapi" class="org.wso2.carbon.transports.sap.SAPTransportSender"/> -->
<!-- Uncomment this and configure to use RabbitMQ connection pools for sending messages
<transportSender name="rabbitmq" class="org.apache.axis2.transport.rabbitmq.RabbitMQSender"/-->
<!--<transportSender name="mqtt" class="org.apache.axis2.transport.mqtt.MqttSender"/>-->
<!--<transportSender name="http"-->
<!--class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">-->
<!--<parameter name="PROTOCOL">HTTP/1.1</parameter>-->
<!--<parameter name="Transfer-Encoding">chunked</parameter>-->
<!-- This parameter has been added to overcome problems encounted in SOAP action parameter -->
<!--<parameter name="OmitSOAP12Action">true</parameter>-->
<!--</transportSender>-->
<!--<transportSender name="https"-->
<!--class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">-->
<!--<parameter name="PROTOCOL">HTTP/1.1</parameter>-->
<!--<parameter name="Transfer-Encoding">chunked</parameter>-->
<!-- This parameter has been added to overcome problems encounted in SOAP action parameter -->
<!--<parameter name="OmitSOAP12Action">true</parameter>-->
<!--</transportSender>-->
<!-- ================================================= -->
<!-- Global Engaged Modules -->
@ -461,6 +611,13 @@
<!-- Comment this out to disable Addressing -->
<module ref="addressing"/>
<!--
Uncomment out the following entry if SOAP (text/xml and application/soap+xml) messages
are processed through the message relay.
-->
<!--module ref="relay"/-->
<!-- ================================================= -->
<!-- Clustering -->
<!-- ================================================= -->
@ -493,7 +650,7 @@
is deemed to have left the cluster, it will be detected by the Group Membership
Service (GMS) using a TCP ping mechanism.
-->
<parameter name="membershipScheme">wka</parameter>
<parameter name="membershipScheme">multicast</parameter>
<!--<parameter name="licenseKey">xxx</parameter>-->
<!--<parameter name="mgtCenterURL">http://localhost:8081/mancenter/</parameter>-->
@ -537,7 +694,7 @@
The TCP port used by this member. This is the port through which other nodes will
contact this member
-->
<parameter name="localMemberPort">4100</parameter>
<parameter name="localMemberPort">4000</parameter>
<!--
The bind port of this member. The difference between localMemberPort & localMemberBindPort
@ -554,13 +711,7 @@
<parameter name="properties">
<property name="backendServerURL" value="https://${hostName}:${httpsPort}/services/"/>
<property name="mgtConsoleURL" value="https://${hostName}:${httpsPort}/"/>
<!-- Manger Setup with Port Mapping-->
<!--property name="port.mapping.8280" value="9764"/>
<property name="port.mapping.8243" value="9444"/>
<property name="subDomain" value="mgt"/-->
<!-- Worker Setup-->
<!--property name="subDomain" value="worker"/-->
<property name="subDomain" value="worker"/>
</parameter>
<!--
@ -580,8 +731,8 @@
can be defined in this section.
-->
<groupManagement enable="false">
<applicationDomain name="wso2.esb.domain"
description="ESB group"
<applicationDomain name="wso2.apim.domain"
description="APIM group"
agent="org.wso2.carbon.core.clustering.hazelcast.HazelcastGroupManagementAgent"
subDomain="worker"
port="2222"/>
@ -593,7 +744,7 @@
<!-- ================================================= -->
<!--
Uncomment and configure the following section to enable transactions support
Uncomment and configure the following section to enable transactions support
-->
<!--<transaction timeout="30000">
<parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
@ -621,14 +772,17 @@
</phase>
<phase name="Validation"/>
<phase name="Transport">
<!--TEMPORALY-->
<!--handler name="TenantActiveCheckDispatcher"
class="org.wso2.carbon.tenant.dispatcher.TenantActiveCheckDispatcher">
<order phase="Transport"/>
</handler-->
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher">
<order phase="Transport"/>
</handler>
<handler name="CarbonContextConfigurator"
class="org.wso2.carbon.mediation.initializer.handler.CarbonContextConfigurator"/>
<handler name="RelaySecuirtyMessageBuilderDispatchandler"
class="org.apache.synapse.transport.passthru.util.RelaySecuirtyMessageBuilderDispatchandler"/>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher">
<order phase="Transport"/>
@ -637,19 +791,21 @@
class="org.wso2.carbon.core.transports.smtp.SMTPFaultHandler">
<order phase="Transport"/>
</handler-->
<!-- TEMPORALY-->
<!--handler name="CacheMessageBuilderDispatchandler"
class="org.wso2.carbon.mediation.initializer.handler.CacheMessageBuilderDispatchandler"/-->
<handler name="CarbonContentConfigurator"
class="org.wso2.carbon.mediation.initializer.handler.CarbonContextConfigurator"/>
</phase>
<phase name="Addressing">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
<order phase="Addressing"/>
</handler>
</phase>
<phase name="Security"/>
<phase name="PreDispatch">
<!--Uncomment following handler to enable logging in ESB log UI-->
<!--<handler name="TenantDomainSetter"-->
<!--class="org.wso2.carbon.utils.logging.handler.TenantDomainSetter"/>-->
</phase>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
@ -689,6 +845,7 @@
<!--system predefined phase-->
<!--these phase will run irrespective of the service-->
<phase name="PolicyDetermination"/>
<!--security handler for pass through -->
<phase name="PTSecurityOutPhase">
<handler name="RelaySecuirtyMessageBuilderDispatchandler"
class="org.apache.synapse.transport.passthru.util.RelaySecuirtyMessageBuilderDispatchandler"/>
@ -697,7 +854,7 @@
<phase name="Security"/>
<!--
The MsgOutObservation phase is used to observe messages just before the
The MsgOutObservation phase is used tju,o observe messages just before the
responses are sent out. In this phase, we could do some things such as SOAP message
tracing & keeping track of the time at which a particular response was sent.
@ -716,6 +873,7 @@
-->
<phase name="MsgInObservation"/>
<phase name="Validation"/>
<phase name="Transport">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher">
@ -725,13 +883,17 @@
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher">
<order phase="Transport"/>
</handler>
<handler name="CarbonContentConfigurator"
class="org.wso2.carbon.mediation.initializer.handler.CarbonContextConfigurator"/>
</phase>
<phase name="Addressing">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
<order phase="Addressing"/>
</handler>
</phase>
<phase name="Security"/>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
@ -776,4 +938,4 @@
<phase name="MsgOutObservation"/>
</phaseOrder>
</axisconfig>
</axisconfig>

@ -0,0 +1,483 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ 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.
-->
<!-- This is the root configuration file of WSO2 Message Broker (MB). Links to configurations of
associated libraries are also specified here.
[Note for developers] - If you intend to rename or modify a property name, remember to update
relevant, org.wso2.andes.configuration.enums.AndesConfiguration, enum value using the Xpath
expression of the property.
This file is ciphertool compliant. Refer PRODUCT_HOME/repository/conf/security/cipher-text.properties for examples.-->
<broker>
<coordination>
<!-- You can override the cluster node identifier of this MB node using the nodeID.
If it is left as "default", the default node ID will be generated for it. (Using IP + UUID).
The node ID of each member should ALWAYS be unique.-->
<nodeID>default</nodeID>
<!-- Thrift is used to maintain and sync slot (message groups) ranges between MB nodes. -->
<thriftServerHost>localhost</thriftServerHost>
<thriftServerPort>7611</thriftServerPort>
<!--Thrift server reconnect timeout. Value specified in SECONDS-->
<thriftServerReconnectTimeout>5</thriftServerReconnectTimeout>
<!-- Hazelcast reliable topics are used to share all notifications across the MB cluster (e.g. subscription
changes), And this property defines the time-to-live for a notification since its creation. (in Seconds) -->
<clusterNotificationTimeout>10</clusterNotificationTimeout>
</coordination>
<!-- You can enable/disable specific messaging transports in this section. By default all
transports are enabled. This section also allows you to customize the messaging flows used
within WSO2 MB. NOT performance related, but logic related. -->
<transports>
<amqp enabled="true">
<bindAddress>0.0.0.0</bindAddress>
<defaultConnection enabled="true" port="5672" />
<sslConnection enabled="true" port="8672">
<keyStore>
<location>repository/resources/security/wso2carbon.jks</location>
<password>wso2carbon</password>
</keyStore>
<trustStore>
<location>repository/resources/security/client-truststore.jks</location>
<password>wso2carbon</password>
</trustStore>
</sslConnection>
<maximumRedeliveryAttempts>10</maximumRedeliveryAttempts>
<allowSharedTopicSubscriptions>false</allowSharedTopicSubscriptions>
<allowStrictNameValidation>true</allowStrictNameValidation>
<!-- Refer repository/conf/advanced/qpid-config.xml for further AMQP-specific configurations.-->
</amqp>
<mqtt enabled="true">
<bindAddress>0.0.0.0</bindAddress>
<defaultConnection enabled="true" port="1883" />
<sslConnection enabled="true" port="8883">
<keyStore>
<location>repository/resources/security/wso2carbon.jks</location>
<password>wso2carbon</password>
</keyStore>
<trustStore>
<location>repository/resources/security/client-truststore.jks</location>
<password>wso2carbon</password>
</trustStore>
</sslConnection>
<!--All receiving events/messages will be in this ring buffer. Ring buffer size
of MQTT inbound event disruptor. Default is set to 32768 (1024 * 32)
Having a large ring buffer will have a increase memory usage and will improve performance
and vise versa -->
<inboundBufferSize>32768</inboundBufferSize>
<!-- Messages delivered to clients will be placed in this ring buffer.
Ring buffer size of MQTT delivery event disruptor. Default is set to 32768 (1024 * 32)
Having a large ring buffer will have a increase memory usage and will improve performance
and vise versa -->
<deliveryBufferSize>32768</deliveryBufferSize>
<security>
<!--
Instructs the MQTT server whether clients should always send credentials
when establishing a connection.
Possible values:
OPTIONAL: This is the default value. MQTT clients may or may not send
credentials. If a client sends credentials server will
validates it.
If client doesn't send credentials then server will not
authenticate, but allows client to establish the connection.
This behavior adheres to MQTT 3.1 specification.
REQUIRED: Clients should always provide credentials when connecting.
If client doesn't send credentials or they are invalid
server rejects the connection.
-->
<authentication>REQUIRED</authentication>
<!--Class name of the authenticator to use. class should
inherit from org.dna.mqtt.moquette.server.IAuthenticator
Note: default implementation authenticates against carbon user store
based on supplied username/password
-->
<!--<authenticator class="org.wso2.carbon.andes.authentication.andes.CarbonBasedMQTTAuthenticator"/>-->
<authenticator class="org.wso2.carbon.andes.authentication.andes.OAuth2BasedMQTTAuthenticator">
<property name="hostURL">https://localhost:9443/services/OAuth2TokenValidationService</property>
<property name="username">admin</property>
<property name="password">admin</property>
<property name="maxConnectionsPerHost">10</property>
<property name="maxTotalConnections">150</property>
</authenticator>
<!--
Instructs the MQTT server whether clients should be authorized before either publishing or subscribing
Possible values:
NOT_REQUIRED: This is the default value. MQTT clients will skip the authorization check
REQUIRED: Clients will authorized before publishing. this will execute the class given in authorzier
Note: authentication should be REQUIRED for authorization to be REQUIRED.
-->
<authorization>NOT_REQUIRED</authorization>
<!--Class name of the authorizer to use. class should
inherit from org.dna.mqtt.moquette.server.IAutherizer
Note: default implementation authorizes against carbon permission with the topic.
-->
<!--connectionPermission is required for a user to connect to broker-->
<authorizer class="org.wso2.carbon.andes.authorization.andes.CarbonPermissionBasedMQTTAuthorizer">
<property name="connectionPermission">/permission/admin/mqtt/connect</property>
</authorizer>
</security>
</mqtt>
</transports>
<!-- Depending on the database type selected in master-datasources.xml, you must enable the
relevant Data access classes here. Currently WSO2 MB Supports RDBMS(any RDBMS store).
These stores are accessed for two purposes.
1. For message persistence ("messageStore")
2. To persist and access other information relevant to messaging protocols.("contextStore").-->
<!-- By default WSO2 MB runs with H2 persistent store. If you plan to use a different
store, point to the relevant dataSource or uncomment the database appropriately.
RDBMS
=====
If you are running an RDBMS you can use the existing RDBMS implementation of stores
by pointing to the correct data source by updating the property "dataSource".
Data source entry should be present in
<MB_HOME>/repository/conf/datasources/master-datasources.xml.
-->
<persistence>
<!-- RDBMS MB Store Configuration -->
<messageStore class="org.wso2.andes.store.rdbms.RDBMSMessageStoreImpl">
<property name="dataSource">WSO2MBStoreDB</property>
<property name="storeUnavailableSQLStateClasses">08</property>
<property name="integrityViolationSQLStateClasses">23,27,44</property>
<property name="dataErrorSQLStateClasses">21,22</property>
<property name="transactionRollbackSQLStateClasses">40</property>
</messageStore>
<contextStore class="org.wso2.andes.store.rdbms.RDBMSAndesContextStoreImpl">
<property name="dataSource">WSO2MBStoreDB</property>
<property name="storeUnavailableSQLStateClasses">08</property>
<property name="integrityViolationSQLStateClasses">23,27,44</property>
<property name="dataErrorSQLStateClasses">21,22</property>
<property name="transactionRollbackSQLStateClasses">40</property>
</contextStore>
<cache>
<!-- Size of the messages cache in MBs. Setting '0' will disable the cache. -->
<size>256</size>
<!-- Expected concurrency for the cache (4 is guava default) -->
<concurrencyLevel>4</concurrencyLevel>
<!--Number of seconds cache will keep messages after they are
added (unless they are consumed and deleted).-->
<expirySeconds>2</expirySeconds>
<!--Reference type used to hold messages in memory.
weak - Using java weak references ( - results higher cache misses)
strong - ordinary references ( - higher cache hits, but not good if server
is going to run with limited heap size + under severe load).
-->
<valueReferenceType>strong</valueReferenceType>
<!--Prints cache statistics in 2 minute intervals
in carbon log ( and console)-->
<printStats>false</printStats>
</cache>
<!-- This class decides how unique IDs are generated for the MB node. This id generator is
expected to be thread safe and a implementation of interface
org.wso2.andes.server.cluster.coordination.MessageIdGenerator
NOTE: This is NOT used in MB to generate message IDs. -->
<idGenerator>org.wso2.andes.server.cluster.coordination.TimeStampBasedMessageIdGenerator</idGenerator>
<!-- This is the Task interval (in SECONDS) to check whether communication
is healthy between message store (/Database) and this server instance. -->
<storeHealthCheckInterval>10</storeHealthCheckInterval>
</persistence>
<!--Publisher transaction related configurations.-->
<transaction>
<!--Maximum batch size (Messages) for a transaction. Exceeding this limit will result
in a failure in the subsequent commit request. Default is set to 10MB. Limit is
calculated considering the payload of messages-->
<maxBatchSizeInBytes>10000000</maxBatchSizeInBytes>
</transaction>
<!-- This section allows you to tweak memory and processor allocations used by WSO2 MB.
Broken down by critical processes so you have a clear view of which parameters to change in
different scenarios. -->
<performanceTuning>
<slots>
<!--
If message publishers are slow, time taken to fill the slot (up to <windowSize>) will be longer.
This will add an latency to messages. Therefore broker will mark the slot as
ready to deliver before even the slot is entirely filled after specified time.
NOTE: specified in milliseconds.
-->
<messageAccumulationTimeout>2000</messageAccumulationTimeout>
<!--Rough estimate for size of a slot-->
<windowSize>1000</windowSize>
<!-- Time interval which broker check for slots that can be marked as 'ready to deliver'
(- slots which have a aged more than 'messageAccumulationTimeout')
NOTE: specified in milliseconds.
-->
<timerPeriod>1000</timerPeriod>
<!--Number of SlotDeliveryWorker threads that should be started-->
<workerThreadCount>5</workerThreadCount>
</slots>
<delivery>
<!-- Maximum number of undelivered messages that can have in memory. Increasing this
value increase the possibility of out of memory scenario but performance will be
improved -->
<maxNumberOfReadButUndeliveredMessages>1000</maxNumberOfReadButUndeliveredMessages>
<!-- This is the ring buffer size of the delivery disruptor. This value should be a
power of 2 (E.g. 1024, 2048, 4096). Use a small ring size if you want to reduce the
memory usage. -->
<ringBufferSize>4096</ringBufferSize>
<!--Number of parallel readers used to used to read content from message store.
Increasing this value will speed-up the message sending mechanism. But the load
on the data store will increase. -->
<parallelContentReaders>5</parallelContentReaders>
<!-- Number of parallel decompression handlers used to decompress messages before send to subscribers.
Increasing this value will speed-up the message decompressing mechanism. But the system load
will increase. -->
<parallelDecompressionHandlers>5</parallelDecompressionHandlers>
<!-- Number of parallel delivery handlers used to send messages to subscribers.
Increasing this value will speed-up the message sending mechanism. But the system load
will increase. -->
<parallelDeliveryHandlers>5</parallelDeliveryHandlers>
<!-- The size of the batch represents, at a given time the number of messages that could
be retrieved from the database. -->
<contentReadBatchSize>65000</contentReadBatchSize>
<contentCache>
<!-- Specify the maximum number of entries the cache may contain. -->
<maximumSize>100</maximumSize>
<!-- Specify the time in seconds that each entry should be
automatically removed from the cache after the entry's creation. -->
<expiryTime>120</expiryTime>
</contentCache>
<!--When delivering topic messages to multiple topic
subscribers one of following stratigies can be choosen.
1. DISCARD_NONE - Broker do not loose any message to any subscriber.
When there are slow subscribers this can cause broker
go Out of Memory.
2. SLOWEST_SUB_RATE - Broker deliver to the speed of the slowest
topic subscriber. This can cause fast subscribers
to starve. But eliminate Out of Memory issue.
3. DISCARD_ALLOWED - Broker will try best to deliver. To eliminate Out
of Memory threat broker limits sent but not acked message
count to <maxUnackedMessages>.
If it is breached, and <deliveryTimeout> is also
breached message can either be lost or actually
sent but ack is not honoured.
-->
<topicMessageDeliveryStrategy>
<strategyName>DISCARD_NONE</strategyName>
<!-- If you choose DISCARD_ALLOWED topic message delivery strategy,
broker keep messages in memory until ack is done until this timeout.
If an ack is not received under this timeout, ack will be simulated
internally and real acknowledgement is discarded.
deliveryTimeout is in seconds -->
<deliveryTimeout>60</deliveryTimeout>
</topicMessageDeliveryStrategy>
</delivery>
<ackHandling>
<!--Number of message acknowledgement handlers to process acknowledgements concurrently.
These acknowledgement handlers will batch and process acknowledgements. -->
<ackHandlerCount>1</ackHandlerCount>
<!--Maximum batch size of the acknowledgement handler. Andes process acknowledgements in
batches using Disruptor Increasing the batch size reduces the number of calls made to
database by MB. Depending on the database optimal batch size this value should be set.
Batches will be of the maximum batch size mostly in high throughput scenarios.
Underlying implementation use Disruptor for batching hence will batch message at a
lesser value than this in low throughput scenarios -->
<ackHandlerBatchSize>100</ackHandlerBatchSize>
<!-- Message delivery from server to the client will be paused temporarily if number of
delivered but unacknowledged message count reaches this size. Should be set considering
message consume rate. This is to avoid overwhelming slow subscribers. -->
<maxUnackedMessages>1000</maxUnackedMessages>
</ackHandling>
<contentHandling>
<!-- Within Andes there are content chunk handlers which convert incoming large content
chunks into max content chunk size allowed by Andes core. These handlers run in parallel
converting large content chunks to smaller chunks.
If the protocol specific content chunk size is different from the max chunk size allowed
by Andes core and there are significant number of large messages published, then having
multiple handlers will increase performance. -->
<contentChunkHandlerCount>3</contentChunkHandlerCount>
<!-- Andes core will store message content chunks according to this chunk size. Different
database will have limits and performance gains by tuning this parameter.
For instance in MySQL the maximum table column size for content is less than 65534, which
is the default chunk size of AMQP. By changing this parameter to a lesser value we can
store large content chunks converted to smaller content chunks within the DB with this
parameter. -->
<maxContentChunkSize>65500</maxContentChunkSize>
<!-- This is the configuration to allow compression of message contents, before store messages
into the database.-->
<allowCompression>false</allowCompression>
<!-- This is the configuration to change the value of the content compression threshold (in bytes).
Message contents less than this value will not compress, even compression is enabled. The recommended
message size of the smallest message before compression is 13bytes. Compress messages smaller than
13bytes will expand the message size by 0.4% -->
<contentCompressionThreshold>1000</contentCompressionThreshold>
</contentHandling>
<inboundEvents>
<!--Number of parallel writers used to write content to message store. Increasing this
value will speed-up the message receiving mechanism. But the load on the data store will
increase.-->
<parallelMessageWriters>1</parallelMessageWriters>
<!--Size of the Disruptor ring buffer for inbound event handling. For publishing at
higher rates increasing the buffer size may give some advantage on keeping messages in
memory and write.
NOTE: Buffer size should be a value of power of two -->
<bufferSize>65536</bufferSize>
<!--Maximum batch size of the batch write operation for inbound messages. MB internals
use Disruptor to batch events. Hence this batch size is set to avoid database requests
with high load (with big batch sizes) to write messages. This need to be configured in
high throughput messaging scenarios to regulate the hit on database from MB -->
<messageWriterBatchSize>70</messageWriterBatchSize>
<!--Timeout for waiting for a queue purge event to end to get the purged count. Doesn't
affect actual purging. If purge takes time, increasing the value will improve the
possibility of retrieving the correct purged count. Having a lower value doesn't stop
purge event. Getting the purged count is affected by this -->
<purgedCountTimeout>180</purgedCountTimeout>
<!--Number of parallel writers used to write content to message store for transaction
based publishing. Increasing this value will speedup commit duration for a transaction.
But the load on the data store will increase.-->
<transactionMessageWriters>1</transactionMessageWriters>
</inboundEvents>
</performanceTuning>
<!-- This section is about how you want to view messaging statistics from the admin console and
how you plan to interact with it. -->
<managementConsole>
<!--Maximum number of messages to be fetched per page using Andes message browser when browsing
queues/dlc -->
<messageBrowsePageSize>100</messageBrowsePageSize>
<!-- This property defines the maximum message content length that can be displayed at the
management console when browsing queues. If the message length exceeds the value, a
truncated content will be displayed with a statement "message content too large to display."
at the end. default value is 100000 (can roughly display a 100KB message.)
* NOTE : Increasing this value could cause delays when loading the message content page.-->
<maximumMessageDisplayLength>100000</maximumMessageDisplayLength>
</managementConsole>
<!-- Memory and resource exhaustion is something we should prevent and recover from.
This section allows you to specify the threshold at which to reduce/stop frequently intensive
operations within MB temporarily. -->
<!--
highLimit - flow control is enabled when message chunk pending to be handled by inbound
disruptor reaches above this limit
lowLimit - flow control is disabled (if enabled) when message chunk pending to be handled
by inbound disruptor reaches below this limit
-->
<flowControl>
<!-- This is the global buffer limits which enable/disable the flow control globally -->
<global>
<lowLimit>800</lowLimit>
<highLimit>8000</highLimit>
</global>
<!-- This is the channel specific buffer limits which enable/disable the flow control locally.
-->
<bufferBased>
<lowLimit>100</lowLimit>
<highLimit>1000</highLimit>
</bufferBased>
</flowControl>
<slotManagement>
<!--Set slot storage mode (RDBMS/HazelCast)-->
<storage>RDBMS</storage>
</slotManagement>
<!--
Message broker keeps track of all messages it has received as groups. These groups are termed
'Slots' (To know more information about Slots and message broker install please refer to online wiki).
Size of a slot is loosely determined by the configuration <windowSize> (and the number of
parallel publishers for specific topic/queue). Message broker cluster (or in single node) keeps
track of slots which constitutes for a large part of operating state before the cluster went down.
When first message broker node of the cluster starts up, it will read the database to recreate
the internal state to previous state.
-->
<recovery>
<!--
There could be multiple storage queues worked before entire cluster (or single node) went down.
We need to recover all remaining messages of each storage queue when first node startup and we can
read remaining message concurrently of each storage queue. Default value to set here to 5. You can
increase this value based on number of storage queues exist. Please use optimal value based on
number of storage queues to speed up warm startup.
-->
<concurrentStorageQueueReads>5</concurrentStorageQueueReads>
<!-- Virtual host sync interval seconds in for the Virtual host syncing Task which will
sync the Virtual host details across the cluster -->
<vHostSyncTaskInterval>900</vHostSyncTaskInterval>
</recovery>
</broker>

@ -0,0 +1,44 @@
<!--
~ 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.
-->
<IdentityProvider>
<IdentityProviderName>CDMF_DEFAULT_IDP</IdentityProviderName>
<DisplayName>CDMF_DEFAULT_IDP</DisplayName>
<IdentityProviderDescription></IdentityProviderDescription>
<Alias>https://localhost:9443/oauth2/token</Alias>
<IsPrimary>true</IsPrimary>
<IsFederationHub></IsFederationHub>
<HomeRealmId></HomeRealmId>
<ProvisioningRole></ProvisioningRole>
<FederatedAuthenticatorConfigs></FederatedAuthenticatorConfigs>
<DefaultAuthenticatorConfig>
</DefaultAuthenticatorConfig>
<ProvisioningConnectorConfigs>
<!--<ProvisioningConnectorConfig>
<ProvisioningProperties>
</ProvisioningProperties>
</ProvisioningConnectorConfig>-->
</ProvisioningConnectorConfigs>
<!--<DefaultProvisioningConnectorConfig></DefaultProvisioningConnectorConfig>-->
<ClaimConfig></ClaimConfig>
<Certificate>
MIIFkzCCA3sCBAKkVfcwDQYJKoZIhvcNAQEFBQAwgY0xCzAJBgNVBAYTAlNMMRAwDgYDVQQIEwdXZXN0ZXJuMRAwDgYDVQQHEwdDb2xvbWJvMQ0wCwYDVQQKEwRXU08yMRQwEgYDVQQLEwtFbmdpbmVlcmluZzESMBAGA1UEAxMJbG9jYWxob3N0MSEwHwYJKoZIhvcNAQkBFhJpb3RzZXJ2ZXJAd3NvMi5jb20wHhcNMTUxMjE3MTMxMTA0WhcNMTcxMjE2MTMxMTA0WjCBjTELMAkGA1UEBhMCU0wxEDAOBgNVBAgTB1dlc3Rlcm4xEDAOBgNVBAcTB0NvbG9tYm8xDTALBgNVBAoTBFdTTzIxFDASBgNVBAsTC0VuZ2luZWVyaW5nMRIwEAYDVQQDEwlsb2NhbGhvc3QxITAfBgkqhkiG9w0BCQEWEmlvdHNlcnZlckB3c28yLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALkiGVQ9tZOKIi/gD/toV+enq+neqOBGYQ8Fq/ABOWnK2QpGWm81+Rets5GbQ6W//D8C5TOBGqK7z+LAgdmILr1XLkvrXWoan0GPdDJ1wpc2/6XDZvM5f7Y8cmRqVPJv7AF+ImgF9dqv97gYCiujy+nNHd5Nk/60pco2LBV5SyLqqrzKXEnSGrS4zoYWpPeJ9YrXPEkW7A6AxTQK0yU9Ej4TktgafbTueythrLomKiZJj4wPxm2lA2lAZscDdws9NWrI5z/LUVLbUMxrY10Nig1liX5b1mrUk5bb1d2tqwkPrpRILKoOBJtI674SQS3GziiUiCJGIO/EGGRn1AJsC/SvnnEez3WKY/DgJ6102MWK/yWtY8NYHUX2anwMBS7UpT5A4BXdsfBz3R+iPF99FxdAGGsS4GQuuPocZaycLqoPCxpTSSxBsKMUcKpn3yaiQRd6uDuiTNt7odDOQj0Tno7uokh/HILgbzvj9EExDOsdwLVvqYmUHBPeLmiICWXfi4kyH/twPOZtV9eVnfWYx5Kwg+2Y4fIb3q4ABr0hzxaMYHQo6NOukSH1BcdAWiQIXbSFFaTZD8p6OfiZpHcQ59HT/Z8GBlCFL2xkYJFmOhXI/Cu+xrcwqEIInv7d8w3eiNQ7MneomEptLbBk9+kMsP0ubo34oOGHR9qk3Lj580c/AgMBAAEwDQYJKoZIhvcNAQEFBQADggIBADw70g2/wrgzrAM8OXBlthGbCEaXZpKwq9IJN0qu+/l+PNwF7csQhj+qW+zMrWaH1DGWJroaei1+NFFrj/pvp61rF/ZeTPGVJd7puCq++SevqIrzKyAEBtwtpXmcFhBpV/FrQAv3ODOJ3bN2wSRPZHUvARTBB3RaUI06g1jCaBzjDEGoMfSxdr5/Ty2WxTI9u9RlIs3Q52AiOmROtLPiEQZQIqfNO3cxCEWojHxPqVEZA/kQYy+rryj4H0zzSrj7QFlQhsMDw5j8bv9AcvTEGmwp29avsgnceDWinI6lwtd8zqh0ZW9QJdH0BRNCM/EkTlTUHeEg04/sOgOrlWcvEfVxDqNEtbUzU9UFxl0lkQkuRn1UdxZlvhWaFnel5iRC9b7OZvi2mkVujLyxEWlJB1tuyMLQxu6PfabBVODP5V8/+uyiiK/gwrB5rYl8RHxGoznJnI1Y3HVzKlA849CrMBaY5vnhE03cNja7QroPzLmmuXBLk2LbI1lu5nJAqKpBUPMI/IU3pF4Q7VTD2ZANI+ktGgGlM8AK4OJHWOhj8W289pWTHVjG8syPLTsaYkhgLjzZl/g9cUwn/96NJNvzd3dkT+7VgE+BJOLofq25CjZcN1M7MhWdl3vbWNj9vzL0+FCnwca8UecfvFS39PIekIvqbtP+Gw8NiYOUGIllZ0JH
</Certificate>
<PermissionAndRoleConfig></PermissionAndRoleConfig>
<JustInTimeProvisioningConfig></JustInTimeProvisioningConfig>
</IdentityProvider>

@ -148,11 +148,11 @@
<GrantTypeName>iwa:ntlm</GrantTypeName>
<GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.token.handlers.grant.iwa.ntlm.NTLMAuthenticationGrantHandler</GrantTypeHandlerImplClass>
</SupportedGrantType>
<!--<SupportedGrantType>-->
<!--<GrantTypeName>urn:ietf:params:oauth:grant-type:jwt-bearer</GrantTypeName>-->
<!--<GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler</GrantTypeHandlerImplClass>-->
<!--<GrantTypeValidatorImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTGrantValidator</GrantTypeValidatorImplClass>-->
<!--</SupportedGrantType>-->
<SupportedGrantType>
<GrantTypeName>urn:ietf:params:oauth:grant-type:jwt-bearer</GrantTypeName>
<GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler</GrantTypeHandlerImplClass>
<GrantTypeValidatorImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTGrantValidator</GrantTypeValidatorImplClass>
</SupportedGrantType>
</SupportedGrantTypes>
<OAuthCallbackHandlers>
<OAuthCallbackHandler Class="org.wso2.carbon.device.mgt.oauth.extensions.handlers.DeviceMgtOAuthCallbackHandler"/>

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ 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.
-->
<Server xmlns="http://wso2.org/projects/carbon/carbon.xml">
<JDBCPersistenceManager>
<DataSource>
<!-- Include a data source name (jndiConfigName) from the set of data sources defined in master-datasources.xml -->
<Name>jdbc/WSO2AM_DB</Name>
</DataSource>
<!-- If the identity database is created from another place and if it is required to skip schema initialization during the server start up, set the following
property to "true". -->
<!--<SkipDBSchemaCreation>true</SkipDBSchemaCreation>-->
</JDBCPersistenceManager>
<ThriftSessionDAO>org.wso2.carbon.identity.thrift.authentication.dao.DBThriftSessionDAO</ThriftSessionDAO>
<!--<ThriftSessionDAO>org.wso2.carbon.identity.thrift.authentication.dao.InMemoryThriftSessionDAO</ThriftSessionDAO>-->
<ClientTimeout>30000</ClientTimeout>
<!--<Hostname>localhost</Hostname>-->
<Port>10711</Port>
<!--30 min-->
<ThriftSessionTimeout>1800000</ThriftSessionTimeout>
</Server>

@ -18,25 +18,25 @@ INSERT INTO AM_SUBSCRIBER ( USER_ID , TENANT_ID , EMAIL_ADDRESS , DATE_SUBSCRIBE
INSERT INTO AM_SUBSCRIBER ( USER_ID , TENANT_ID , EMAIL_ADDRESS , DATE_SUBSCRIBED ) VALUES ('UDAYANGA',-1234,'UDAYANGA@WSO2.COM','2012-03-05 12:10:11');
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID ) VALUES ('APPLICATION1',1);
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID ) VALUES ('APPLICATION2',1);
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID ) VALUES ('APPLICATION3',2);
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID ) VALUES ('APPLICATION4',2);
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID ) VALUES ('APPLICATION5',3);
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID ) VALUES ('DeliciousApp',4);
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID,UUID ) VALUES ('APPLICATION1',1,'97e5871a-cee9-4c1e-a138-9c3a9038125a');
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID,UUID ) VALUES ('APPLICATION2',1,'98841b88-75d9-4ed1-bf2d-bdf7edb837c5');
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID,UUID ) VALUES ('APPLICATION3',2,'4d43fe13-366e-455b-8f4e-88ee22015719');
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID,UUID ) VALUES ('APPLICATION4',2,'0a43614b-12f5-494d-bb79-edb22fe3360a');
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID,UUID ) VALUES ('APPLICATION5',3,'ea069058-6388-40e2-bfec-39365f5333d2');
INSERT INTO AM_APPLICATION (NAME,SUBSCRIBER_ID,UUID ) VALUES ('DeliciousApp',4,'3f3e4aac-4692-4eea-a31e-7c80ee0454a8');
INSERT INTO AM_API (API_PROVIDER,API_NAME,API_VERSION,CONTEXT) VALUES ('SUMEDHA', 'API1', 'V1.0.0','/context1');
INSERT INTO AM_API (API_PROVIDER,API_NAME,API_VERSION,CONTEXT) VALUES ('PRABATH', 'API2', 'V1.0.0','/deli2');
INSERT INTO AM_API (API_PROVIDER,API_NAME,API_VERSION,CONTEXT) VALUES ('ADMIN', 'API3', 'V1.0.0','/test');
INSERT INTO AM_API (API_PROVIDER,API_NAME,API_VERSION,CONTEXT) VALUES ('DEL', 'Delicious', '1.0.0','/deli');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED ) VALUES ('T1',500,100,'2012-03-05 12:10:11');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED ) VALUES ('T1',501,101,'2012-03-05 12:10:11');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED ) VALUES ('T1',500,102,'2012-03-05 12:10:11');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED ) VALUES ('T1',502,103,'2012-03-05 12:10:11');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED ) VALUES ('T1',501,104,'2012-03-05 12:10:11');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED ) VALUES ('T1',503,105,'2012-03-05 12:10:11');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED ) VALUES ('T1',501,102,'2012-03-05 12:10:11');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED , UUID) VALUES ('T1',500,100,'2012-03-05 12:10:11','7af95c9d-6177-4101-ab3e-d3f6c1cdc4c2');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED , UUID) VALUES ('T1',501,101,'2012-03-05 12:10:11','696430b1-c564-4d82-8ea9-ea1a61db0a60');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED , UUID) VALUES ('T1',500,102,'2012-03-05 12:10:11','2cb4a9c0-7f9d-41fe-bea2-2dc7b9073188');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED , UUID) VALUES ('T1',502,103,'2012-03-05 12:10:11','95556f88-b5ed-41fc-ac83-dc8d4cd6ccae');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED , UUID) VALUES ('T1',501,104,'2012-03-05 12:10:11','f36e661b-6eef-4af2-9927-7d220993aff2');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED , UUID) VALUES ('T1',503,105,'2012-03-05 12:10:11','443afa79-848a-4be6-8fbe-c6d73ed06ced');
INSERT INTO AM_SUBSCRIPTION ( TIER_ID , API_ID , APPLICATION_ID , LAST_ACCESSED , UUID) VALUES ('T1',501,102,'2012-03-05 12:10:11','821b9664-eeca-4173-9f56-3dc6d46bd6eb');
INSERT INTO AM_SUBSCRIPTION_KEY_MAPPING (SUBSCRIPTION_ID, ACCESS_TOKEN, KEY_TYPE) VALUES (1000, 'SSDCHEJJ-AWUIS-232', 'PRODUCTION');
INSERT INTO AM_SUBSCRIPTION_KEY_MAPPING (SUBSCRIPTION_ID, ACCESS_TOKEN, KEY_TYPE) VALUES (1001, 'a1b2c3d4', 'SANDBOX');
@ -50,12 +50,18 @@ INSERT INTO IDN_OAUTH_CONSUMER_APPS ( APP_NAME , CALLBACK_URL , CONSUMER_KEY , C
INSERT INTO IDN_OAUTH_CONSUMER_APPS ( APP_NAME , CALLBACK_URL , CONSUMER_KEY , CONSUMER_SECRET ,OAUTH_VERSION , TENANT_ID , USERNAME ) VALUES (NULL,NULL,'CON2','MY PEN','2.0',0,'PRABATH');
INSERT INTO IDN_OAUTH_CONSUMER_APPS ( APP_NAME , CALLBACK_URL , CONSUMER_KEY , CONSUMER_SECRET ,OAUTH_VERSION , TENANT_ID , USERNAME ) VALUES (NULL,NULL,'CON3','MY PEN','2.0',0,'admin');
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('a1b2c3d4','UDAYANGA','DEVELOPER','CON1',NULL,'2012-01-01','SANDBOX','ACTIVE',1343714931875);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('p1q2r3s4','UDAYANGA','DEVELOPER','CON1',NULL,'2012-01-01','PRODUCTION','ACTIVE',1343714931875);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('test1','UDAYANGA','DEVELOPER','CON1',NULL,'2012-01-01','PRODUCTION','ACTIVE',1343714931875);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('test2','UDAYANGA','DEVELOPER','CON2',NULL,'2012-01-01','SANDBOX','ACTIVE',1343714931875);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('test3','UDAYANGA','DEVELOPER','CON3',NULL,'2012-01-01','PRODUCTION','ACTIVE',3600);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( TOKEN_ID, ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE_HASH , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('TI1','a1b2c3d4','UDAYANGA','DEVELOPER','CON1',NULL,'2012-01-01','SANDBOXHASH','ACTIVE',1343714931875);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( TOKEN_ID, ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE_HASH , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('TI2','p1q2r3s4','UDAYANGA','DEVELOPER','CON1',NULL,'2012-01-01','PRODUCTIONHASH','ACTIVE',1343714931875);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( TOKEN_ID, ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE_HASH , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('TI3','test1','UDAYANGA','DEVELOPER','CON1',NULL,'2012-01-01','PRODUCTIONHASH','ACTIVE',1343714931875);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( TOKEN_ID, ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE_HASH , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('TI4','test2','UDAYANGA','DEVELOPER','CON2',NULL,'2012-01-01','SANDBOXHASH','ACTIVE',1343714931875);
INSERT INTO IDN_OAUTH2_ACCESS_TOKEN ( TOKEN_ID, ACCESS_TOKEN ,AUTHZ_USER , USER_TYPE , CONSUMER_KEY , REFRESH_TOKEN ,TIME_CREATED , TOKEN_SCOPE_HASH , TOKEN_STATE ,VALIDITY_PERIOD ) VALUES ('TI5','test3','UDAYANGA','DEVELOPER','CON3',NULL,'2012-01-01','PRODUCTIONHASH','ACTIVE',3600);
INSERT INTO IDN_OAUTH2_SCOPE_ASSOCIATION (TOKEN_ID, TOKEN_SCOPE ) VALUES ('TI1','SANDBOX')
INSERT INTO IDN_OAUTH2_SCOPE_ASSOCIATION (TOKEN_ID, TOKEN_SCOPE ) VALUES ('TI2','PRODUCTION')
INSERT INTO IDN_OAUTH2_SCOPE_ASSOCIATION (TOKEN_ID, TOKEN_SCOPE ) VALUES ('TI3','PRODUCTION')
INSERT INTO IDN_OAUTH2_SCOPE_ASSOCIATION (TOKEN_ID, TOKEN_SCOPE ) VALUES ('TI4','SANDBOX')
INSERT INTO IDN_OAUTH2_SCOPE_ASSOCIATION (TOKEN_ID, TOKEN_SCOPE ) VALUES ('TI5','PRODUCTION')
SELECT * FROM AM_SUBSCRIBER;
SELECT * FROM AM_APPLICATION;
SELECT * FROM AM_SUBSCRIPTION;
SELECT * FROM AM_SUBSCRIPTION;

@ -64,7 +64,7 @@ CREATE TABLE IF NOT EXISTS IDN_OAUTH2_ACCESS_TOKEN (
TOKEN_STATE VARCHAR (25) DEFAULT 'ACTIVE',
TOKEN_STATE_ID VARCHAR (128) DEFAULT 'NONE',
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (TOKEN_ID),
PRIMARY KEY (TOKEN_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE,
CONSTRAINT CON_APP_KEY UNIQUE (CONSUMER_KEY_ID,AUTHZ_USER,TENANT_ID,USER_DOMAIN,USER_TYPE,TOKEN_SCOPE_HASH,
TOKEN_STATE,TOKEN_STATE_ID)
@ -87,6 +87,7 @@ CREATE TABLE IF NOT EXISTS IDN_OAUTH2_AUTHORIZATION_CODE (
VALIDITY_PERIOD BIGINT,
STATE VARCHAR (25) DEFAULT 'ACTIVE',
TOKEN_ID VARCHAR(255),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (CODE_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
);
@ -492,7 +493,7 @@ CREATE TABLE IF NOT EXISTS FIDO_DEVICE_STORE (
KEY_HANDLE VARCHAR(200) NOT NULL,
DEVICE_DATA LONGVARCHAR NOT NULL,
PRIMARY KEY (TENANT_ID, DOMAIN_NAME, USER_NAME, KEY_HANDLE));
CREATE TABLE IF NOT EXISTS WF_REQUEST (
UUID VARCHAR (45),
CREATED_BY VARCHAR (255),
@ -766,14 +767,14 @@ CREATE TABLE IF NOT EXISTS AM_API_SCOPES (
);
CREATE TABLE IF NOT EXISTS AM_API_DEFAULT_VERSION (
DEFAULT_VERSION_ID INT AUTO_INCREMENT,
DEFAULT_VERSION_ID INT AUTO_INCREMENT,
API_NAME VARCHAR(256) NOT NULL ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
PRIMARY KEY (DEFAULT_VERSION_ID)
);
CREATE INDEX IDX_SUB_APP_ID ON AM_SUBSCRIPTION (APPLICATION_ID, SUBSCRIPTION_ID);
-- End of API-MGT Tables --
-- End of API-MGT Tables --

@ -68,7 +68,7 @@ CREATE TABLE IDN_OAUTH2_ACCESS_TOKEN (
TOKEN_SCOPE_HASH VARCHAR(32),
TOKEN_STATE VARCHAR(25) DEFAULT 'ACTIVE',
TOKEN_STATE_ID VARCHAR (128) DEFAULT 'NONE',
SUBJECT_IDENTIFIER VARCHAR(255),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (TOKEN_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE,
CONSTRAINT CON_APP_KEY UNIQUE (CONSUMER_KEY_ID,AUTHZ_USER,TENANT_ID,USER_DOMAIN,USER_TYPE,TOKEN_SCOPE_HASH,
@ -96,6 +96,7 @@ CREATE TABLE IDN_OAUTH2_AUTHORIZATION_CODE (
VALIDITY_PERIOD BIGINT,
STATE VARCHAR (25) DEFAULT 'ACTIVE',
TOKEN_ID VARCHAR(255),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (CODE_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
);
@ -537,7 +538,7 @@ CREATE TABLE FIDO_DEVICE_STORE (
KEY_HANDLE VARCHAR(200) NOT NULL,
DEVICE_DATA VARCHAR(2048) NOT NULL,
PRIMARY KEY (TENANT_ID, DOMAIN_NAME, USER_NAME, KEY_HANDLE));
IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[WF_REQUEST]') AND TYPE IN (N'U'))
CREATE TABLE WF_REQUEST (
UUID VARCHAR (45),
@ -855,13 +856,13 @@ CREATE TABLE AM_API_SCOPES (
IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[AM_API_DEFAULT_VERSION]') AND TYPE IN (N'U'))
CREATE TABLE AM_API_DEFAULT_VERSION (
DEFAULT_VERSION_ID INTEGER NOT NULL IDENTITY,
DEFAULT_VERSION_ID INTEGER NOT NULL IDENTITY,
API_NAME VARCHAR(256) NOT NULL ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
PRIMARY KEY (DEFAULT_VERSION_ID)
);
CREATE INDEX IDX_SUB_APP_ID ON AM_SUBSCRIPTION (APPLICATION_ID, SUBSCRIPTION_ID);
CREATE INDEX IDX_SUB_APP_ID ON AM_SUBSCRIPTION (APPLICATION_ID, SUBSCRIPTION_ID);

@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS IDN_OAUTH2_ACCESS_TOKEN (
TOKEN_STATE VARCHAR(25) DEFAULT 'ACTIVE',
TOKEN_STATE_ID VARCHAR (128) DEFAULT 'NONE',
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (TOKEN_ID),
PRIMARY KEY (TOKEN_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE,
CONSTRAINT CON_APP_KEY UNIQUE (CONSUMER_KEY_ID,AUTHZ_USER,TENANT_ID,USER_DOMAIN,USER_TYPE,TOKEN_SCOPE_HASH,
TOKEN_STATE,TOKEN_STATE_ID)
@ -88,6 +88,7 @@ CREATE TABLE IF NOT EXISTS IDN_OAUTH2_AUTHORIZATION_CODE (
VALIDITY_PERIOD BIGINT,
STATE VARCHAR (25) DEFAULT 'ACTIVE',
TOKEN_ID VARCHAR(255),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (CODE_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
)ENGINE INNODB;
@ -516,7 +517,7 @@ CREATE TABLE IF NOT EXISTS FIDO_DEVICE_STORE (
DEVICE_DATA VARCHAR(2048) NOT NULL,
PRIMARY KEY (TENANT_ID, DOMAIN_NAME, USER_NAME, KEY_HANDLE)
)ENGINE INNODB;
CREATE TABLE IF NOT EXISTS WF_REQUEST (
UUID VARCHAR (45),
CREATED_BY VARCHAR (255),
@ -793,12 +794,12 @@ CREATE TABLE IF NOT EXISTS AM_API_SCOPES (
)ENGINE = INNODB;
CREATE TABLE IF NOT EXISTS AM_API_DEFAULT_VERSION (
DEFAULT_VERSION_ID INT AUTO_INCREMENT,
DEFAULT_VERSION_ID INT AUTO_INCREMENT,
API_NAME VARCHAR(256) NOT NULL ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
PRIMARY KEY (DEFAULT_VERSION_ID)
);
CREATE INDEX IDX_SUB_APP_ID ON AM_SUBSCRIPTION (APPLICATION_ID, SUBSCRIPTION_ID);
CREATE INDEX IDX_SUB_APP_ID ON AM_SUBSCRIPTION (APPLICATION_ID, SUBSCRIPTION_ID);

@ -1,7 +1,7 @@
-- Create Oracle New User and Connect
--------------------------------------
-- CREATE USER apimuser IDENTIFIED BY wso2;
-- GRANT CONNECT,RESOURCE to apimuser WITH ADMIN OPTION;
-- CREATE USER apimuser IDENTIFIED BY wso2;
-- GRANT CONNECT,RESOURCE to apimuser WITH ADMIN OPTION;
-- CONNECT apimuser/wso2
--
@ -78,8 +78,8 @@ CREATE TABLE IDN_OAUTH2_ACCESS_TOKEN (
TOKEN_SCOPE_HASH VARCHAR2 (32),
TOKEN_STATE VARCHAR2 (25) DEFAULT 'ACTIVE',
TOKEN_STATE_ID VARCHAR (128) DEFAULT 'NONE',
SUBJECT_IDENTIFIER VARCHAR2(255),
PRIMARY KEY (TOKEN_ID),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (TOKEN_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE,
CONSTRAINT CON_APP_KEY UNIQUE (CONSUMER_KEY_ID,AUTHZ_USER,TOKEN_ID,USER_DOMAIN,USER_TYPE,TOKEN_SCOPE_HASH,
TOKEN_STATE,TOKEN_STATE_ID))
@ -101,6 +101,7 @@ CREATE TABLE IDN_OAUTH2_AUTHORIZATION_CODE (
VALIDITY_PERIOD NUMBER(19),
STATE VARCHAR (25) DEFAULT 'ACTIVE',
TOKEN_ID VARCHAR(255),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (CODE_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE)
/
@ -1236,10 +1237,10 @@ CREATE OR REPLACE TRIGGER AM_EXTERNAL_STORES_TRIGGER
/
CREATE TABLE AM_API_DEFAULT_VERSION (
DEFAULT_VERSION_ID NUMBER,
DEFAULT_VERSION_ID NUMBER,
API_NAME VARCHAR(256) NOT NULL ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
PRIMARY KEY (DEFAULT_VERSION_ID)
)

@ -1,7 +1,7 @@
-- Create Oracle New User and Connect
--------------------------------------
-- CREATE USER apimuser IDENTIFIED BY wso2;
-- GRANT CONNECT,RESOURCE to apimuser WITH ADMIN OPTION;
-- CREATE USER apimuser IDENTIFIED BY wso2;
-- GRANT CONNECT,RESOURCE to apimuser WITH ADMIN OPTION;
-- CONNECT apimuser/wso2
--
@ -77,8 +77,8 @@ CREATE TABLE IDN_OAUTH2_ACCESS_TOKEN (
TOKEN_SCOPE_HASH VARCHAR2 (32),
TOKEN_STATE VARCHAR2 (25) DEFAULT 'ACTIVE',
TOKEN_STATE_ID VARCHAR (128) DEFAULT 'NONE',
SUBJECT_IDENTIFIER VARCHAR2(255),
PRIMARY KEY (TOKEN_ID),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (TOKEN_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE,
CONSTRAINT CON_APP_KEY UNIQUE (CONSUMER_KEY_ID,AUTHZ_USER,TOKEN_ID,USER_DOMAIN,USER_TYPE,TOKEN_SCOPE_HASH,
TOKEN_STATE,TOKEN_STATE_ID))
@ -100,6 +100,7 @@ CREATE TABLE IDN_OAUTH2_AUTHORIZATION_CODE (
VALIDITY_PERIOD NUMBER(19),
STATE VARCHAR (25) DEFAULT 'ACTIVE',
TOKEN_ID VARCHAR(255),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (CODE_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE)
/
@ -1233,10 +1234,10 @@ CREATE OR REPLACE TRIGGER AM_EXTERNAL_STORES_TRIGGER
/
CREATE TABLE AM_API_DEFAULT_VERSION (
DEFAULT_VERSION_ID NUMBER,
DEFAULT_VERSION_ID NUMBER,
API_NAME VARCHAR(256) NOT NULL ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
PRIMARY KEY (DEFAULT_VERSION_ID)
)

@ -73,7 +73,7 @@ CREATE TABLE IDN_OAUTH2_ACCESS_TOKEN (
TOKEN_STATE VARCHAR(25) DEFAULT 'ACTIVE',
TOKEN_STATE_ID VARCHAR (128) DEFAULT 'NONE',
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (TOKEN_ID),
PRIMARY KEY (TOKEN_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE,
CONSTRAINT CON_APP_KEY UNIQUE (CONSUMER_KEY_ID,AUTHZ_USER,TOKEN_ID,USER_DOMAIN,USER_TYPE,TOKEN_SCOPE_HASH,
TOKEN_STATE,TOKEN_STATE_ID)
@ -97,6 +97,7 @@ CREATE TABLE IDN_OAUTH2_AUTHORIZATION_CODE (
VALIDITY_PERIOD BIGINT,
STATE VARCHAR (25) DEFAULT 'ACTIVE',
TOKEN_ID VARCHAR(255),
SUBJECT_IDENTIFIER VARCHAR(255),
PRIMARY KEY (CODE_ID),
FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
);
@ -903,10 +904,10 @@ DROP TABLE IF EXISTS AM_API_DEFAULT_VERSION;
DROP SEQUENCE IF EXISTS AM_API_DEFAULT_VERSION_PK_SEQ;
CREATE SEQUENCE AM_API_DEFAULT_VERSION_PK_SEQ;
CREATE TABLE AM_API_DEFAULT_VERSION (
DEFAULT_VERSION_ID INTEGER DEFAULT NEXTVAL('am_api_default_version_pk_seq'),
DEFAULT_VERSION_ID INTEGER DEFAULT NEXTVAL('am_api_default_version_pk_seq'),
API_NAME VARCHAR(256) NOT NULL ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
API_PROVIDER VARCHAR(256) NOT NULL ,
DEFAULT_API_VERSION VARCHAR(30) ,
PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
PRIMARY KEY (DEFAULT_VERSION_ID)
);
@ -914,4 +915,4 @@ CREATE TABLE AM_API_DEFAULT_VERSION (
CREATE INDEX IDX_SUB_APP_ID ON AM_SUBSCRIPTION (APPLICATION_ID, SUBSCRIPTION_ID)
;
commit;
commit;

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>das-extensions</artifactId>
<groupId>org.wso2.iot</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.event.input.adapter.extensions</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Event Input MQTT Adapter Module</name>
<description>This provides the capability of connecting to existing broker that supports OAUTH</description>
<url>http://wso2.org</url>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.input.adapter.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.wso2</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.orbit.org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<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>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-descriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package>
org.wso2.carbon.event.input.adapter.extensions.internal,
org.wso2.carbon.event.input.adapter.extensions.internal.*
</Private-Package>
<Export-Package>
!org.wso2.carbon.event.input.adapter.extensions.internal,
!org.wso2.carbon.event.input.adapter.extensions.internal.*,
org.wso2.carbon.event.input.adapter.extensions.*
</Export-Package>
<Import-Package>
org.wso2.carbon.event.input.adapter.core,
org.wso2.carbon.event.input.adapter.core.*,
javax.xml.namespace; version=0.0.0,
org.eclipse.paho.client.mqttv3.*,
org.apache.http;version="${httpclient.version.range}",
org.apache.http.message;version="${httpclient.version.range}",
org.apache.http.client;version="${httpclient.version.range}",
org.apache.http.impl;version="${httpclient.version.range}",
org.apache.http.conn.*;version="${httpclient.version.range}",
org.apache.http.util;version="${httpclient.version.range}",
org.apache.http.client.entity;version="${httpclient.version.range}",
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.*,
javax.net.ssl,
org.apache.commons.logging,
org.apache.http.entity,
org.osgi.framework,
org.osgi.service.component,
org.wso2.carbon.context,
org.wso2.carbon.core,
javax.servlet,
javax.servlet.http,
org.apache.axiom.om.util,
org.osgi.service.http,
org.wso2.carbon.user.api,
org.wso2.carbon.user.core.service,
org.wso2.carbon.user.core.tenant,
org.wso2.carbon.utils,
org.wso2.carbon.utils.multitenancy,
org.wso2.carbon.identity.oauth2.stub;version="${carbon.identity.version.range}",
org.wso2.carbon.identity.oauth2.stub.dto;version="${carbon.identity.version.range}",
org.apache.axis2,
org.apache.axis2.client,
org.apache.axis2.context,
org.apache.axis2.transport.http,
org.apache.commons.httpclient,
org.apache.commons.httpclient.contrib.ssl,
org.apache.commons.httpclient.params,
org.apache.commons.httpclient.protocol,
org.apache.commons.pool,
org.apache.commons.pool.impl,
org.apache.log4j
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,55 @@
/*
* 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.event.input.adapter.extensions;
/**
* This is the return type of the ContentValidator.
*/
public class ContentInfo {
/**
* true if the content is valid if not when false then content will not be published.
*/
private boolean isValidContent;
/**
* msgText to be returned. eg: if the content is encrypted then we can decrypt the content and then validate and
* return it.
*/
private String msgText;
public ContentInfo(boolean isValidContent, String msgText) {
this.isValidContent = isValidContent;
this.msgText = msgText;
}
public boolean isValidContent() {
return isValidContent;
}
public void setIsValidContent(boolean isValidContent) {
this.isValidContent = isValidContent;
}
public String getMsgText() {
return msgText;
}
public void setMsgText(String msgText) {
this.msgText = msgText;
}
}

@ -0,0 +1,33 @@
/*
* 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.event.input.adapter.extensions;
import java.util.Map;
/**
* This interface will be triggered to validate the stream content before publishing.
*/
public interface ContentValidator {
/**
*
* @param params that related to input adapter to identify the client and the content
* @return
*/
ContentInfo validate(Map<String, String> params);
}

@ -0,0 +1,213 @@
/*
* Copyright (c) 2015, 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.
*/
package org.wso2.carbon.event.input.adapter.extensions.http;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapter;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException;
import org.wso2.carbon.event.input.adapter.core.exception.TestConnectionNotSupportedException;
import org.wso2.carbon.event.input.adapter.extensions.http.util.HTTPEventAdapterConstants;
import org.wso2.carbon.event.input.adapter.extensions.internal.EventAdapterServiceDataHolder;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import javax.servlet.ServletException;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public final class HTTPEventAdapter implements InputEventAdapter {
private final InputEventAdapterConfiguration eventAdapterConfiguration;
private final Map<String, String> globalProperties;
private InputEventAdapterListener eventAdaptorListener;
private final String id = UUID.randomUUID().toString();
public static ExecutorService executorService;
private static final Log log = LogFactory.getLog(HTTPEventAdapter.class);
private boolean isConnected = false;
public HTTPEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) {
this.eventAdapterConfiguration = eventAdapterConfiguration;
this.globalProperties = globalProperties;
}
@Override
public void init(InputEventAdapterListener eventAdaptorListener) throws InputEventAdapterException {
this.eventAdaptorListener = eventAdaptorListener;
//ThreadPoolExecutor will be assigned if it is null
if (executorService == null) {
int minThread;
int maxThread;
long defaultKeepAliveTime;
int jobQueueSize;
//If global properties are available those will be assigned else constant values will be assigned
if (globalProperties.get(HTTPEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME) != null) {
minThread = Integer
.parseInt(globalProperties.get(HTTPEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME));
} else {
minThread = HTTPEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE;
}
if (globalProperties.get(HTTPEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME) != null) {
maxThread = Integer
.parseInt(globalProperties.get(HTTPEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME));
} else {
maxThread = HTTPEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE;
}
if (globalProperties.get(HTTPEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME) != null) {
defaultKeepAliveTime = Integer
.parseInt(globalProperties.get(HTTPEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME));
} else {
defaultKeepAliveTime = HTTPEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_IN_MILLS;
}
if (globalProperties.get(HTTPEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME) != null) {
jobQueueSize = Integer
.parseInt(globalProperties.get(HTTPEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME));
} else {
jobQueueSize = HTTPEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE;
}
RejectedExecutionHandler rejectedExecutionHandler = new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
log.error("Exception while adding event to executor queue : " + e.getMessage(), e);
}
}
};
executorService = new ThreadPoolExecutor(minThread, maxThread, defaultKeepAliveTime, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(jobQueueSize), rejectedExecutionHandler);
}
}
@Override
public void testConnect() throws TestConnectionNotSupportedException {
throw new TestConnectionNotSupportedException("not-supported");
}
@Override
public void connect() {
registerDynamicEndpoint(eventAdapterConfiguration.getName());
isConnected = true;
}
@Override
public void disconnect() {
if (isConnected){
isConnected = false;
unregisterDynamicEndpoint(eventAdapterConfiguration.getName());
}
}
@Override
public void destroy() {
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof HTTPEventAdapter))
return false;
HTTPEventAdapter that = (HTTPEventAdapter) o;
return id.equals(that.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean isEventDuplicatedInCluster() {
return false;
}
@Override
public boolean isPolling() {
return false;
}
private void registerDynamicEndpoint(String adapterName) {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
String endpoint;
if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
endpoint = HTTPEventAdapterConstants.ENDPOINT_PREFIX + adapterName;
} else {
endpoint = HTTPEventAdapterConstants.ENDPOINT_PREFIX + HTTPEventAdapterConstants.ENDPOINT_TENANT_KEY
+ HTTPEventAdapterConstants.ENDPOINT_URL_SEPARATOR + tenantDomain
+ HTTPEventAdapterConstants.ENDPOINT_URL_SEPARATOR + adapterName;
}
try {
HttpService httpService = EventAdapterServiceDataHolder.getHTTPService();
if (httpService == null) {
throw new InputEventAdapterRuntimeException(
"HttpService not available, Error in registering endpoint " + endpoint);
}
httpService.registerServlet(endpoint, new HTTPMessageServlet(eventAdaptorListener, tenantId,
eventAdapterConfiguration),
new Hashtable(), httpService.createDefaultHttpContext());
} catch (ServletException | NamespaceException e) {
throw new InputEventAdapterRuntimeException("Error in registering endpoint " + endpoint, e);
}
}
private void unregisterDynamicEndpoint(String adapterName) {
HttpService httpService = EventAdapterServiceDataHolder.getHTTPService();
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String endpoint;
if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
endpoint = HTTPEventAdapterConstants.ENDPOINT_PREFIX + adapterName;
} else {
endpoint = HTTPEventAdapterConstants.ENDPOINT_PREFIX + HTTPEventAdapterConstants.ENDPOINT_TENANT_KEY
+ HTTPEventAdapterConstants.ENDPOINT_URL_SEPARATOR + tenantDomain
+ HTTPEventAdapterConstants.ENDPOINT_URL_SEPARATOR + adapterName;
}
if (httpService != null) {
httpService.unregister(endpoint);
}
}
}

@ -0,0 +1,158 @@
/*
* Copyright (c) 2005 - 2014, 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.
*/
package org.wso2.carbon.event.input.adapter.extensions.http;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapter;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory;
import org.wso2.carbon.event.input.adapter.core.MessageType;
import org.wso2.carbon.event.input.adapter.core.Property;
import org.wso2.carbon.event.input.adapter.extensions.http.util.HTTPEventAdapterConstants;
import org.wso2.carbon.utils.CarbonUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
/**
* The http event adapter factory class to create a http input adapter
*/
public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
private ResourceBundle resourceBundle =
ResourceBundle.getBundle("org.wso2.carbon.event.input.adapter.extensions.http.i18n.Resources", Locale.getDefault());
private int httpPort;
private int httpsPort;
private int portOffset;
public HTTPEventAdapterFactory() {
portOffset = getPortOffset();
httpPort = HTTPEventAdapterConstants.DEFAULT_HTTP_PORT + portOffset;
httpsPort = HTTPEventAdapterConstants.DEFAULT_HTTPS_PORT + portOffset;
}
@Override
public String getType() {
return HTTPEventAdapterConstants.ADAPTER_TYPE_HTTP;
}
@Override
public List<String> getSupportedMessageFormats() {
List<String> supportInputMessageTypes = new ArrayList<String>();
supportInputMessageTypes.add(MessageType.JSON);
return supportInputMessageTypes;
}
@Override
public List<Property> getPropertyList() {
List<Property> propertyList = new ArrayList<Property>();
// Transport Exposed
Property exposedTransportsProperty = new Property(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS);
exposedTransportsProperty.setRequired(true);
exposedTransportsProperty.setDisplayName(
resourceBundle.getString(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS));
exposedTransportsProperty.setOptions(
new String[]{HTTPEventAdapterConstants.HTTPS, HTTPEventAdapterConstants.HTTP,
HTTPEventAdapterConstants.LOCAL, HTTPEventAdapterConstants.ALL});
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(
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME));
contentValidator.setRequired(false);
contentValidator.setHint(
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT));
propertyList.add(contentValidator);
contentValidator.setDefaultValue(HTTPEventAdapterConstants.DEFAULT);
propertyList.add(contentValidator);
//Content Validator Params details
Property contentValidatorParams = new Property(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
contentValidatorParams.setDisplayName(
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS));
contentValidatorParams.setRequired(false);
contentValidatorParams.setHint(
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT));
propertyList.add(contentValidatorParams);
contentValidatorParams.setDefaultValue(HTTPEventAdapterConstants.MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS);
propertyList.add(contentValidatorParams);
return propertyList;
}
@Override
public String getUsageTips() {
return resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_PREFIX) + httpPort +
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_MID1) + httpsPort +
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_MID2) + httpPort +
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_MID3) + httpsPort +
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_POSTFIX);
}
@Override
public InputEventAdapter createEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) {
return new HTTPEventAdapter(eventAdapterConfiguration, globalProperties);
}
private int getPortOffset() {
return CarbonUtils.getPortFromServerConfig(HTTPEventAdapterConstants.CARBON_CONFIG_PORT_OFFSET_NODE) + 1;
}
}

@ -0,0 +1,342 @@
/*
* Copyright (c) 2005 - 2014, 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.
*/
package org.wso2.carbon.event.input.adapter.extensions.http;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
import org.wso2.carbon.event.input.adapter.extensions.ContentInfo;
import org.wso2.carbon.event.input.adapter.extensions.ContentValidator;
import org.wso2.carbon.event.input.adapter.extensions.http.oauth.OAuthTokenValidaterStubFactory;
import org.wso2.carbon.event.input.adapter.extensions.http.util.AuthenticationInfo;
import org.wso2.carbon.event.input.adapter.extensions.http.util.HTTPContentValidator;
import org.wso2.carbon.event.input.adapter.extensions.http.util.HTTPEventAdapterConstants;
import org.wso2.carbon.event.input.adapter.extensions.internal.EventAdapterServiceDataHolder;
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.user.core.service.RealmService;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This will act as the event reciver.
*/
public class HTTPMessageServlet extends HttpServlet {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String AUTH_MESSAGE_STORE_AUTHENTICATION_INFO = "AUTH_MESSAGE_STORE_AUTHENTICATION_INFO";
private static final String AUTH_FAILURE_RESPONSE = "_AUTH_FAILURE_";
private static final Pattern PATTERN = Pattern.compile("[B|b]earer\\s");
private static final String TOKEN_TYPE = "bearer";
private static String cookie;
private static Log log = LogFactory.getLog(HTTPMessageServlet.class);
private GenericObjectPool stubs;
private InputEventAdapterListener eventAdaptorListener;
private int tenantId;
private String exposedTransports;
public HTTPMessageServlet(InputEventAdapterListener eventAdaptorListener, int tenantId,
InputEventAdapterConfiguration eventAdapterConfiguration) {
this.eventAdaptorListener = eventAdaptorListener;
this.tenantId = tenantId;
this.exposedTransports = eventAdapterConfiguration.getProperties().get(
HTTPEventAdapterConstants.EXPOSED_TRANSPORTS);
this.stubs = new GenericObjectPool(new OAuthTokenValidaterStubFactory(eventAdapterConfiguration));
}
private String getBearerToken(HttpServletRequest request) {
String authorizationHeader = request.getHeader(AUTHORIZATION_HEADER);
if (authorizationHeader != null) {
Matcher matcher = PATTERN.matcher(authorizationHeader);
if (matcher.find()) {
authorizationHeader = authorizationHeader.substring(matcher.end());
}
}
return authorizationHeader;
}
private AuthenticationInfo checkAuthentication(HttpServletRequest req) {
AuthenticationInfo authenticationInfo = (AuthenticationInfo) req.getSession().getAttribute(
AUTH_MESSAGE_STORE_AUTHENTICATION_INFO);
if (authenticationInfo != null) {
return authenticationInfo;
}
String bearerToken = getBearerToken(req);
if (bearerToken == null) {
return authenticationInfo;
}
RealmService realmService = EventAdapterServiceDataHolder.getRealmService();
try {
authenticationInfo = validateToken(bearerToken);
boolean success = authenticationInfo.isAuthenticated();
if (success) {
req.getSession().setAttribute(AUTH_MESSAGE_STORE_AUTHENTICATION_INFO, authenticationInfo);
}
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("checkAuthentication() fail: " + e.getMessage(), e);
}
}
return authenticationInfo;
}
/**
* This method gets a string accessToken and validates it
*
* @param token which need to be validated.
* @return AuthenticationInfo with the validated results.
*/
private AuthenticationInfo validateToken(String token) {
OAuth2TokenValidationServiceStub tokenValidationServiceStub = null;
try {
Object stub = this.stubs.borrowObject();
if (stub != null) {
tokenValidationServiceStub = (OAuth2TokenValidationServiceStub) stub;
if (cookie != null) {
tokenValidationServiceStub._getServiceClient().getOptions().setProperty(
HTTPConstants.COOKIE_STRING, cookie);
}
return getAuthenticationInfo(token, tokenValidationServiceStub);
} else {
log.warn("Stub initialization failed.");
}
} catch (RemoteException e) {
log.error("Error on connecting with the validation endpoint.", e);
} catch (Exception e) {
log.error("Error occurred in borrowing an validation stub from the pool.", e);
} finally {
try {
if (tokenValidationServiceStub != null) {
this.stubs.returnObject(tokenValidationServiceStub);
}
} catch (Exception e) {
log.warn("Error occurred while returning the object back to the oauth token validation service " +
"stub pool.", e);
}
}
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
authenticationInfo.setAuthenticated(false);
authenticationInfo.setTenantId(-1);
return authenticationInfo;
}
/**
* This creates an AuthenticationInfo object that is used for authorization. This method will validate the token
* and
* sets the required parameters to the object.
*
* @param token that needs to be validated.
* @param tokenValidationServiceStub stub that is used to call the external service.
* @return AuthenticationInfo This contains the information related to authenticated client.
* @throws RemoteException that triggers when failing to call the external service..
*/
private AuthenticationInfo getAuthenticationInfo(String token,
OAuth2TokenValidationServiceStub tokenValidationServiceStub)
throws RemoteException, UserStoreException {
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
OAuth2TokenValidationRequestDTO validationRequest = new OAuth2TokenValidationRequestDTO();
OAuth2TokenValidationRequestDTO_OAuth2AccessToken accessToken =
new OAuth2TokenValidationRequestDTO_OAuth2AccessToken();
accessToken.setTokenType(TOKEN_TYPE);
accessToken.setIdentifier(token);
validationRequest.setAccessToken(accessToken);
boolean authenticated;
OAuth2TokenValidationResponseDTO tokenValidationResponse;
tokenValidationResponse = tokenValidationServiceStub.validate(validationRequest);
if (tokenValidationResponse == null) {
authenticationInfo.setAuthenticated(false);
return authenticationInfo;
}
authenticated = tokenValidationResponse.getValid();
if (authenticated) {
String authorizedUser = tokenValidationResponse.getAuthorizedUser();
String username = MultitenantUtils.getTenantAwareUsername(authorizedUser);
String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser);
authenticationInfo.setUsername(username);
authenticationInfo.setTenantDomain(tenantDomain);
RealmService realmService = EventAdapterServiceDataHolder.getRealmService();
int tenantId = realmService.getTenantManager().getTenantId(authenticationInfo.getTenantDomain());
authenticationInfo.setTenantId(tenantId);
} else {
if (log.isDebugEnabled()) {
log.debug("Token validation failed for token: " + token);
}
}
ServiceContext serviceContext = tokenValidationServiceStub._getServiceClient()
.getLastOperationContext().getServiceContext();
cookie = (String) serviceContext.getProperty(HTTPConstants.COOKIE_STRING);
authenticationInfo.setAuthenticated(authenticated);
return authenticationInfo;
}
private String inputStreamToString(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int i;
while ((i = in.read(buff)) > 0) {
out.write(buff, 0, i);
}
out.close();
return out.toString();
}
@Override
protected void doPost(HttpServletRequest req,
HttpServletResponse res) throws IOException {
String data = this.inputStreamToString(req.getInputStream());
if (data == null) {
log.warn("Event Object is empty/null");
return;
}
AuthenticationInfo authenticationInfo = null;
if (exposedTransports.equalsIgnoreCase(HTTPEventAdapterConstants.HTTPS)) {
if (!req.isSecure()) {
res.setStatus(403);
log.error("Only Secured endpoint is enabled for requests");
return;
} else {
authenticationInfo = this.checkAuthentication(req);
int tenantId = authenticationInfo != null ? authenticationInfo.getTenantId() : -1;
if (tenantId == -1) {
res.getOutputStream().write(AUTH_FAILURE_RESPONSE.getBytes());
res.setStatus(401);
log.error("Authentication failed for the request");
return;
} else if (tenantId != this.tenantId) {
res.getOutputStream().write(AUTH_FAILURE_RESPONSE.getBytes());
res.setStatus(401);
log.error("Authentication failed for the request");
return;
}
}
} else if (exposedTransports.equalsIgnoreCase(HTTPEventAdapterConstants.HTTP)) {
if (req.isSecure()) {
res.setStatus(403);
log.error("Only unsecured endpoint is enabled for requests");
return;
}
} else {
if (req.isSecure()) {
authenticationInfo = this.checkAuthentication(req);
int tenantId = authenticationInfo != null ? authenticationInfo.getTenantId() : -1;
if (tenantId == -1) {
res.getOutputStream().write(AUTH_FAILURE_RESPONSE.getBytes());
res.setStatus(401);
log.error("Authentication failed for the request");
return;
} else if (tenantId != this.tenantId) {
res.getOutputStream().write(AUTH_FAILURE_RESPONSE.getBytes());
res.setStatus(401);
log.error("Authentication failed for the request");
return;
}
}
}
if (log.isDebugEnabled()) {
log.debug("Message : " + data);
}
if (authenticationInfo != null) {
Map<String, String> paramMap = new HashMap<>();
Enumeration<String> reqParameterNames = req.getParameterNames();
while (reqParameterNames.hasMoreElements()) {
paramMap.put(reqParameterNames.nextElement(), req.getParameter(reqParameterNames.nextElement()));
}
paramMap.put(HTTPEventAdapterConstants.USERNAME_TAG, authenticationInfo.getUsername());
paramMap.put(HTTPEventAdapterConstants.TENANT_DOMAIN_TAG, authenticationInfo.getTenantDomain());
paramMap.put(HTTPEventAdapterConstants.PAYLOAD_TAG, data);
ContentValidator contentValidator = new HTTPContentValidator();
ContentInfo contentInfo = contentValidator.validate(paramMap);
if (contentInfo != null && contentInfo.isValidContent()) {
HTTPEventAdapter.executorService.submit(new HTTPRequestProcessor(eventAdaptorListener,
contentInfo.getMsgText(), tenantId));
}
}
}
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse res) throws IOException {
doPost(req, res);
}
public class HTTPRequestProcessor implements Runnable {
private InputEventAdapterListener inputEventAdapterListener;
private String payload;
private int tenantId;
public HTTPRequestProcessor(InputEventAdapterListener inputEventAdapterListener,
String payload, int tenantId) {
this.inputEventAdapterListener = inputEventAdapterListener;
this.payload = payload;
this.tenantId = tenantId;
}
public void run() {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
if (log.isDebugEnabled()) {
log.debug("Event received in HTTP Event Adapter - " + payload);
}
if (payload.trim() != null) {
inputEventAdapterListener.onEvent(payload);
} else {
log.warn("Dropping the empty/null event received through http adapter");
}
} catch (Exception e) {
log.error("Error while parsing http request for processing: " + e.getMessage(), e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
}

@ -0,0 +1,180 @@
/*
* 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.event.input.adapter.extensions.http.oauth;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.transport.http.HttpTransportProperties;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.log4j.Logger;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.event.input.adapter.extensions.http.oauth.exception.OAuthTokenValidationException;
import org.wso2.carbon.event.input.adapter.extensions.http.util.HTTPEventAdapterConstants;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
/**
* This follows object pool pattern to manage the stub for oauth validation service.
*/
public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
private static final Logger log = Logger.getLogger(OAuthTokenValidaterStubFactory.class);
private HttpClient httpClient;
InputEventAdapterConfiguration eventAdapterConfiguration;
public OAuthTokenValidaterStubFactory(InputEventAdapterConfiguration eventAdapterConfiguration) {
this.eventAdapterConfiguration = eventAdapterConfiguration;
this.httpClient = createHttpClient();
}
/**
* This creates a OAuth2TokenValidationServiceStub object to the pool.
*
* @return an OAuthValidationStub object
* @throws Exception thrown when creating the object.
*/
@Override
public Object makeObject() throws Exception {
return this.generateStub();
}
/**
* This is used to clean up the OAuth validation stub and releases to the object pool.
*
* @param o object that needs to be released.
* @throws Exception throws when failed to release to the pool
*/
@Override
public void passivateObject(Object o) throws Exception {
if (o instanceof OAuth2TokenValidationServiceStub) {
OAuth2TokenValidationServiceStub stub = (OAuth2TokenValidationServiceStub) o;
stub._getServiceClient().cleanupTransport();
}
}
/**
* This is used to create a stub which will be triggered through object pool factory, which will create an
* instance of it.
*
* @return OAuth2TokenValidationServiceStub stub that is used to call an external service.
* @throws OAuthTokenValidationException will be thrown when initialization failed.
*/
private OAuth2TokenValidationServiceStub generateStub() throws OAuthTokenValidationException {
OAuth2TokenValidationServiceStub stub;
try {
URL hostURL = new URL(eventAdapterConfiguration.getProperties().get(
HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL));
if (hostURL != null) {
stub = new OAuth2TokenValidationServiceStub(hostURL.toString());
if (stub != null) {
ServiceClient client = stub._getServiceClient();
client.getServiceContext().getConfigurationContext().setProperty(
HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
HttpTransportProperties.Authenticator auth =
new HttpTransportProperties.Authenticator();
auth.setPreemptiveAuthentication(true);
String username = eventAdapterConfiguration.getProperties().get(HTTPEventAdapterConstants
.USERNAME);
String password = eventAdapterConfiguration.getProperties().get(HTTPEventAdapterConstants
.PASSWORD);
auth.setPassword(username);
auth.setUsername(password);
Options options = client.getOptions();
options.setProperty(HTTPConstants.AUTHENTICATE, auth);
options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Constants.VALUE_TRUE);
client.setOptions(options);
if (hostURL.getProtocol().equals("https")) {
// set up ssl factory since axis2 https transport is used.
EasySSLProtocolSocketFactory sslProtocolSocketFactory =
createProtocolSocketFactory();
Protocol authhttps = new Protocol(hostURL.getProtocol(),
(ProtocolSocketFactory) sslProtocolSocketFactory,
hostURL.getPort());
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);
}
return stub;
}
/**
* This is required to create a trusted connection with the external entity.
* Have to manually configure it since we use CommonHTTPTransport(axis2 transport) in axis2.
*
* @return an EasySSLProtocolSocketFactory for SSL communication.
*/
private EasySSLProtocolSocketFactory createProtocolSocketFactory() throws OAuthTokenValidationException {
try {
EasySSLProtocolSocketFactory easySSLPSFactory = new EasySSLProtocolSocketFactory();
return easySSLPSFactory;
} catch (IOException e) {
String errorMsg = "Failed to initiate EasySSLProtocolSocketFactory.";
throw new OAuthTokenValidationException(errorMsg, e);
} catch (GeneralSecurityException e) {
String errorMsg = "Failed to set the key material in easy ssl factory.";
throw new OAuthTokenValidationException(errorMsg, e);
}
}
/**
* This created httpclient pool that can be used to connect to external entity. This connection can be configured
* via broker.xml by setting up the required http connection parameters.
*
* @return an instance of HttpClient that is configured with MultiThreadedHttpConnectionManager
*/
private HttpClient createHttpClient() {
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
params.setDefaultMaxConnectionsPerHost(Integer.parseInt(eventAdapterConfiguration.getProperties().get(
HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST)));
params.setMaxTotalConnections(Integer.parseInt(eventAdapterConfiguration.getProperties().get(
HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION)));
HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.setParams(params);
return new HttpClient(connectionManager);
}
}

@ -0,0 +1,56 @@
/*
* 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.event.input.adapter.extensions.http.oauth.exception;
/**
* This Exception will be thrown, when there any interference with token validation flow.
*/
public class OAuthTokenValidationException extends Exception {
private String errMessage;
public OAuthTokenValidationException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public OAuthTokenValidationException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public OAuthTokenValidationException(String msg) {
super(msg);
setErrorMessage(msg);
}
public OAuthTokenValidationException() {
super();
}
public OAuthTokenValidationException(Throwable cause) {
super(cause);
}
public String getErrorMessage() {
return errMessage;
}
public void setErrorMessage(String errMessage) {
this.errMessage = errMessage;
}
}

@ -0,0 +1,69 @@
/*
* 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.
*
*/
package org.wso2.carbon.event.input.adapter.extensions.http.util;
/**
* This will be return after authentication and this will consist of the authenticated user info.
*/
public class AuthenticationInfo {
/**
* this variable is used to check whether the client is authenticated.
*/
private boolean authenticated;
private String username;
private String tenantDomain;
private int tenantId;
/**
* returns whether the client is authenticated
*/
public boolean isAuthenticated() {
return authenticated;
}
public void setAuthenticated(boolean authenticated) {
this.authenticated = authenticated;
}
/**
* returns the authenticated client username
*/
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
/**
* return the authenticated client tenant domain
*/
public String getTenantDomain() {
return tenantDomain;
}
public void setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
}
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
}

@ -0,0 +1,76 @@
/*
* 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.event.input.adapter.extensions.http.util;
import com.jayway.jsonpath.JsonPath;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.wso2.carbon.event.input.adapter.extensions.ContentInfo;
import org.wso2.carbon.event.input.adapter.extensions.ContentValidator;
import java.util.Map;
public class HTTPContentValidator implements ContentValidator {
private static final Log log = LogFactory.getLog(HTTPContentValidator.class);
private static String JSON_ARRAY_START_CHAR = "[";
@Override
public ContentInfo validate(Map<String, String> paramMap) {
String deviceId = paramMap.get("deviceId");
String msg = paramMap.get(HTTPEventAdapterConstants.PAYLOAD_TAG);
String deviceIdJsonPath = paramMap.get(HTTPEventAdapterConstants.DEVICE_ID_JSON_PATH);
boolean status;
if (msg.startsWith(JSON_ARRAY_START_CHAR)) {
status = processMultipleEvents(msg, deviceId, deviceIdJsonPath);
} else {
status = processSingleEvent(msg, deviceId, deviceIdJsonPath);
}
return new ContentInfo(status, msg);
}
private boolean processSingleEvent(String msg, String deviceIdFromTopic, String deviceIdJsonPath) {
Object res = JsonPath.read(msg, deviceIdJsonPath);
String deviceIdFromContent = (res != null) ? res.toString() : "";
if (deviceIdFromContent.equals(deviceIdFromTopic)) {
return true;
}
return false;
}
private boolean processMultipleEvents(String msg, String deviceIdFromTopic, String deviceIdJsonPath) {
try {
JSONParser jsonParser = new JSONParser();
JSONArray jsonArray = (JSONArray) jsonParser.parse(msg);
boolean status = false;
for (int i = 0; i < jsonArray.size(); i++) {
status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath);
if (!status) {
return status;
}
}
return status;
} catch (ParseException e) {
log.error("Invalid input " + msg, e);
return false;
}
}
}

@ -0,0 +1,74 @@
/*
* 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.
*/
package org.wso2.carbon.event.input.adapter.extensions.http.util;
/**
* This holds the constants related to HTTP event adapter.
*/
public final class HTTPEventAdapterConstants {
private HTTPEventAdapterConstants() {
}
public static final String ADAPTER_TYPE_HTTP = "oauth-http";
public static final String ADAPTER_USAGE_TIPS_PREFIX = "http.usage.tips_prefix";
public static final String ADAPTER_USAGE_TIPS_MID1 = "http.usage.tips_mid1";
public static final String ADAPTER_USAGE_TIPS_MID2 = "http.usage.tips_mid2";
public static final String ADAPTER_USAGE_TIPS_MID3 = "http.usage.tips_mid3";
public static final String ADAPTER_USAGE_TIPS_POSTFIX = "http.usage.tips_postfix";
public static final int ADAPTER_MIN_THREAD_POOL_SIZE = 8;
public static final int ADAPTER_MAX_THREAD_POOL_SIZE = 100;
public static final int ADAPTER_EXECUTOR_JOB_QUEUE_SIZE = 10000;
public static final long DEFAULT_KEEP_ALIVE_TIME_IN_MILLS = 20000;
public static final String ENDPOINT_PREFIX = "/endpoints/";
public static final String ENDPOINT_URL_SEPARATOR = "/";
public static final String ENDPOINT_TENANT_KEY = "t";
public static final String ADAPTER_MIN_THREAD_POOL_SIZE_NAME = "minThread";
public static final String ADAPTER_MAX_THREAD_POOL_SIZE_NAME = "maxThread";
public static final String ADAPTER_KEEP_ALIVE_TIME_NAME = "keepAliveTimeInMillis";
public static final String ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME = "jobQueueSize";
public static final String EXPOSED_TRANSPORTS = "transports";
public static final String HTTPS = "https";
public static final String HTTP = "http";
public static final String LOCAL = "local";
public static final String ALL = "all";
public static final String CARBON_CONFIG_PORT_OFFSET_NODE = "Ports.Offset";
public static final int DEFAULT_HTTP_PORT = 9763;
public static final int DEFAULT_HTTPS_PORT = 9443;
public static final String MAXIMUM_TOTAL_HTTP_CONNECTION = "maximumTotalHttpConnection";
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 USERNAME = "username";
public static final String USERNAME_HINT = "username.hint";
public static final String PASSWORD = "password";
public static final String PASSWORD_HINT = "password.hint";
public static final String DEFAULT_STRING = "default";
public static final String MAX_HTTP_CONNECTION = "2";
public static final String MAX_TOTAL_HTTP_CONNECTION = "100";
public static final String TENANT_DOMAIN_TAG = "tenantDomain";
public static final String USERNAME_TAG = "username";
public static final String PAYLOAD_TAG = "payload";
public static final String DEVICE_ID_JSON_PATH = "device_id_json_path";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME = "contentValidation";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT = "contentValidation.hint";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS = "contentValidationParams";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT = "contentValidationParams.hint";
public static final String DEFAULT = "default";
public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS =
"device_id_json_path:meta_deviceId";
}

@ -0,0 +1,77 @@
/*
* 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.event.input.adapter.extensions.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.http.HttpService;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory;
import org.wso2.carbon.event.input.adapter.extensions.http.HTTPEventAdapterFactory;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.MQTTEventAdapterFactory;
import org.wso2.carbon.user.core.service.RealmService;
/**
* @scr.component component.name="input.iot.Mqtt.AdapterService.component" immediate="true"
*/
/**
* @scr.component name="org.wso2.carbon.event.input.adapter.extension.EventAdapterServiceComponent" 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"
* @scr.reference name="http.service" interface="org.osgi.service.http.HttpService"
* cardinality="1..1" policy="dynamic" bind="setHttpService" unbind="unsetHttpService"
*/
public class EventAdapterServiceComponent {
private static final Log log = LogFactory.getLog(EventAdapterServiceComponent.class);
protected void activate(ComponentContext context) {
try {
InputEventAdapterFactory mqttEventAdapterFactory = new MQTTEventAdapterFactory();
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
mqttEventAdapterFactory, null);
InputEventAdapterFactory httpEventEventAdapterFactory = new HTTPEventAdapterFactory();
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
httpEventEventAdapterFactory, null);
if (log.isDebugEnabled()) {
log.debug("Successfully deployed the input IoT-MQTT adapter service");
}
} catch (RuntimeException e) {
log.error("Can not create the input IoT-MQTT adapter service ", e);
}
}
protected void setRealmService(RealmService realmService) {
EventAdapterServiceDataHolder.registerRealmService(realmService);
}
protected void unsetRealmService(RealmService realmService) {
EventAdapterServiceDataHolder.registerRealmService(null);
}
protected void setHttpService(HttpService httpService) {
EventAdapterServiceDataHolder.registerHTTPService(httpService);
}
protected void unsetHttpService(HttpService httpService) {
EventAdapterServiceDataHolder.registerHTTPService(null);
}
}

@ -0,0 +1,50 @@
/*
* 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.
*/
package org.wso2.carbon.event.input.adapter.extensions.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 EventAdapterServiceDataHolder {
private static RealmService realmService;
private static HttpService httpService;
private EventAdapterServiceDataHolder() {
}
public static void registerRealmService(
RealmService realmService) {
EventAdapterServiceDataHolder.realmService = realmService;
}
public static RealmService getRealmService() {
return realmService;
}
public static void registerHTTPService(
HttpService httpService) {
EventAdapterServiceDataHolder.httpService = httpService;
}
public static HttpService getHTTPService() {
return httpService;
}
}

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.event.input.adapter.extensions.mqtt;
/**
* This holds the constants related to MQTT input adapter.
*/
public class Constants {
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 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 CLIENT_NAME = "client_name";
public static final String DEFAULT = "default";
public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS =
"device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:2";
public static final String TOPIC = "topic";
public static final String PAYLOAD = "payload";
public static final String DEVICE_ID_JSON_PATH = "device_id_json_path";
public static final String DEVICE_ID_TOPIC_HIERARCHY_INDEX = "device_id_topic_hierarchy_index";
}

@ -0,0 +1,154 @@
/*
* 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.event.input.adapter.extensions.mqtt;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapter;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException;
import org.wso2.carbon.event.input.adapter.core.exception.TestConnectionNotSupportedException;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.util.MQTTAdapterListener;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.util.MQTTBrokerConnectionConfiguration;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.util.MQTTEventAdapterConstants;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* Input MQTTEventAdapter will be used to receive events with MQTT protocol using specified broker and topic.
*/
public class MQTTEventAdapter implements InputEventAdapter {
private final InputEventAdapterConfiguration eventAdapterConfiguration;
private final Map<String, String> globalProperties;
private InputEventAdapterListener eventAdapterListener;
private final String id = UUID.randomUUID().toString();
private MQTTAdapterListener mqttAdapterListener;
private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration;
public MQTTEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) {
this.eventAdapterConfiguration = eventAdapterConfiguration;
this.globalProperties = globalProperties;
}
@Override
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;
}
String contentValidationParams = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
String params[] = contentValidationParams.split(",");
Map<String, String> paramsMap = new HashMap<>();
for (String param: params) {
String paramsKeyAndValue[] = splitOnFirst(param, ':');
if (paramsKeyAndValue.length != 2) {
throw new InputEventAdapterException("Invalid parameters for content validation - " + param);
}
paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]);
}
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),
paramsMap
);
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);
}
}
private String[] splitOnFirst(String str, char c) {
int idx = str.indexOf(c);
String head = str.substring(0, idx);
String tail = str.substring(idx + 1);
return new String[] { head, tail} ;
}
@Override
public void testConnect() throws TestConnectionNotSupportedException {
throw new TestConnectionNotSupportedException("not-supported");
}
@Override
public void connect() {
mqttAdapterListener.createConnection();
}
@Override
public void disconnect() {
if (mqttAdapterListener != null) {
mqttAdapterListener.stopListener(eventAdapterConfiguration.getName());
}
}
@Override
public void destroy() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MQTTEventAdapter)) return false;
MQTTEventAdapter that = (MQTTEventAdapter) o;
if (!id.equals(that.id)) return false;
return true;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean isEventDuplicatedInCluster() {
return true;
}
@Override
public boolean isPolling() {
return true;
}
}

@ -0,0 +1,135 @@
/*
* 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.event.input.adapter.extensions.mqtt;
import org.wso2.carbon.event.input.adapter.core.*;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.util.MQTTEventAdapterConstants;
import java.util.*;
/**
* The mqtt event adapter factory class to create a mqtt input adapter
*/
public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
private ResourceBundle resourceBundle = ResourceBundle.getBundle
("org.wso2.carbon.event.input.adapter.extensions.mqtt.i18n.Resources", Locale.getDefault());
@Override
public String getType() {
return MQTTEventAdapterConstants.ADAPTER_TYPE_MQTT;
}
@Override
public List<String> getSupportedMessageFormats() {
List<String> supportInputMessageTypes = new ArrayList<String>();
supportInputMessageTypes.add(MessageType.JSON);
return supportInputMessageTypes;
}
@Override
public List<Property> getPropertyList() {
List<Property> propertyList = new ArrayList<Property>();
// set topic
Property topicProperty = new Property(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC);
topicProperty.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC));
topicProperty.setRequired(true);
topicProperty.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC_HINT));
propertyList.add(topicProperty);
//Broker Url
Property brokerUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_URL);
brokerUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL));
brokerUrl.setRequired(true);
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);
contentValidator.setDisplayName(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME));
contentValidator.setRequired(false);
contentValidator.setHint(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT));
contentValidator.setDefaultValue(Constants.DEFAULT);
propertyList.add(contentValidator);
//Content Validator Params details
Property contentValidatorParams = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
contentValidatorParams.setDisplayName(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS));
contentValidatorParams.setRequired(false);
contentValidatorParams.setHint(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT));
contentValidatorParams.setDefaultValue(Constants.MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS);
propertyList.add(contentValidatorParams);
//Broker Username
Property userName = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME);
userName.setDisplayName(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME));
userName.setRequired(false);
userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT));
propertyList.add(userName);
//Broker Required Scopes.
Property scopes = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES);
scopes.setDisplayName(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES));
scopes.setRequired(false);
scopes.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES_HINT));
propertyList.add(scopes);
//Broker clear session
Property clearSession = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION);
clearSession.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION));
clearSession.setRequired(false);
clearSession.setOptions(new String[]{"true", "false"});
clearSession.setDefaultValue("true");
clearSession.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION_HINT));
propertyList.add(clearSession);
// set clientId
Property clientId = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID);
clientId.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID));
clientId.setRequired(false);
clientId.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID_HINT));
propertyList.add(clientId);
return propertyList;
}
@Override
public String getUsageTips() {
return null;
}
@Override
public InputEventAdapter createEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration,
Map<String, String> globalProperties) {
return new MQTTEventAdapter(eventAdapterConfiguration, globalProperties);
}
}

@ -0,0 +1,56 @@
/*
* 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.event.input.adapter.extensions.mqtt.exception;
/**
* This exception will thrown when content validator is failed to intialiaze.
*/
public class MQTTContentValidatorInitializationException extends RuntimeException {
private String errMessage;
public MQTTContentValidatorInitializationException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public MQTTContentValidatorInitializationException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public MQTTContentValidatorInitializationException(String msg) {
super(msg);
setErrorMessage(msg);
}
public MQTTContentValidatorInitializationException() {
super();
}
public MQTTContentValidatorInitializationException(Throwable cause) {
super(cause);
}
public String getErrorMessage() {
return errMessage;
}
public void setErrorMessage(String errMessage) {
this.errMessage = errMessage;
}
}

@ -0,0 +1,285 @@
/*
* 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.event.input.adapter.extensions.mqtt.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.ServerStatus;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException;
import org.wso2.carbon.event.input.adapter.extensions.ContentInfo;
import org.wso2.carbon.event.input.adapter.extensions.ContentValidator;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.Constants;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.exception.MQTTContentValidatorInitializationException;
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;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
public class MQTTAdapterListener implements MqttCallback, Runnable {
private static final Log log = LogFactory.getLog(MQTTAdapterListener.class);
private MqttClient mqttClient;
private MqttConnectOptions connectionOptions;
private boolean cleanSession;
private int keepAlive;
private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration;
private String mqttClientId;
private String topic;
private int tenantId;
private boolean connectionSucceeded = false;
ContentValidator contentValidator;
Map<String, String> contentValidationParams;
private InputEventAdapterListener eventAdapterListener = null;
public MQTTAdapterListener(MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration,
String topic, String mqttClientId,
InputEventAdapterListener inputEventAdapterListener, int tenantId) {
if(mqttClientId == null || mqttClientId.trim().isEmpty()){
mqttClientId = MqttClient.generateClientId();
}
this.mqttClientId = mqttClientId;
this.mqttBrokerConnectionConfiguration = mqttBrokerConnectionConfiguration;
this.cleanSession = mqttBrokerConnectionConfiguration.isCleanSession();
this.keepAlive = mqttBrokerConnectionConfiguration.getKeepAlive();
this.topic = topic;
this.eventAdapterListener = inputEventAdapterListener;
this.tenantId = tenantId;
//SORTING messages until the server fetches them
String temp_directory = System.getProperty("java.io.tmpdir");
MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(temp_directory);
try {
// Construct the connection options object that contains connection parameters
// such as cleanSession and LWT
connectionOptions = new MqttConnectOptions();
connectionOptions.setCleanSession(cleanSession);
connectionOptions.setKeepAliveInterval(keepAlive);
// Construct an MQTT blocking mode client
mqttClient = new MqttClient(this.mqttBrokerConnectionConfiguration.getBrokerUrl(), this.mqttClientId,
dataStore);
// Set this wrapper as the callback handler
mqttClient.setCallback(this);
String contentValidatorClassName = this.mqttBrokerConnectionConfiguration.getContentValidatorClassName();
if (contentValidatorClassName != null && contentValidatorClassName.equals(Constants.DEFAULT)) {
contentValidator = new MQTTContentValidator();
} else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) {
try {
Class<? extends ContentValidator> contentValidatorClass = Class.forName(contentValidatorClassName)
.asSubclass(ContentValidator.class);
contentValidator = contentValidatorClass.newInstance();
} catch (ClassNotFoundException e) {
throw new MQTTContentValidatorInitializationException(
"Unable to find the class authorizer: " + contentValidatorClassName, e);
} catch (InstantiationException e) {
throw new MQTTContentValidatorInitializationException(
"Unable to create an instance of :" + contentValidatorClassName, e);
} catch (IllegalAccessException e) {
throw new MQTTContentValidatorInitializationException("Access of the instance in not allowed.", e);
}
}
contentValidationParams = mqttBrokerConnectionConfiguration.getContentValidatorParams();
} catch (MqttException e) {
log.error("Exception occurred while subscribing to MQTT broker at "
+ mqttBrokerConnectionConfiguration.getBrokerUrl());
throw new InputEventAdapterRuntimeException(e);
} catch (Throwable e) {
log.error("Exception occurred while subscribing to MQTT broker at "
+ mqttBrokerConnectionConfiguration.getBrokerUrl());
throw new InputEventAdapterRuntimeException(e);
}
}
public void startListener() throws MqttException {
if (this.mqttBrokerConnectionConfiguration.getBrokerUsername() != null && this.mqttBrokerConnectionConfiguration.getDcrUrl() != null) {
String username = this.mqttBrokerConnectionConfiguration.getBrokerUsername();
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());
HttpPost postMethod = new HttpPost(dcrUrlString);
RegistrationProfile registrationProfile = new RegistrationProfile();
registrationProfile.setCallbackUrl(Constants.EMPTY_STRING);
registrationProfile.setGrantType(Constants.GRANT_TYPE);
registrationProfile.setOwner(username);
registrationProfile.setTokenScope(Constants.TOKEN_SCOPE);
registrationProfile.setApplicationType(Constants.APPLICATION_TYPE);
registrationProfile.setClientName(username + "_" + tenantId);
String jsonString = registrationProfile.toJSON();
StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
postMethod.setEntity(requestEntity);
HttpResponse httpResponse = httpClient.execute(postMethod);
String response = MQTTUtil.getResponseString(httpResponse);
try {
JSONParser jsonParser = new JSONParser();
JSONObject jsonPayload = (JSONObject) jsonParser.parse(response);
String clientId = (String) jsonPayload.get(Constants.CLIENT_ID);
String clientSecret = (String) jsonPayload.get(Constants.CLIENT_SECRET);
JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService();
AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken(
clientId, clientSecret, username, scopes);
connectionOptions.setUserName(accessTokenInfo.getAccessToken());
} 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";
log.error(msg, e);
}
} catch (MalformedURLException e) {
log.error("Invalid dcrUrl : " + dcrUrlString);
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) {
log.error("Failed to create an https connection.", e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
// Connect to the MQTT server
mqttClient.connect(connectionOptions);
// Subscribe to the requested topic
// The QoS specified is the maximum level that messages will be sent to the client at.
// For instance if QoS 1 is specified, any messages originally published at QoS 2 will
// be downgraded to 1 when delivering to the client but messages published at 1 and 0
// will be received at the same level they were published at.
mqttClient.subscribe(topic);
}
public void stopListener(String adapterName) {
if (connectionSucceeded) {
try {
// Un-subscribe accordingly and disconnect from the MQTT server.
if (!ServerStatus.getCurrentStatus().equals(ServerStatus.STATUS_SHUTTING_DOWN) || cleanSession) {
mqttClient.unsubscribe(topic);
}
mqttClient.disconnect(3000);
} catch (MqttException e) {
log.error("Can not unsubscribe from the destination " + topic
+ " with the event adapter " + adapterName, e);
}
}
//This is to stop all running reconnection threads
connectionSucceeded = true;
}
@Override
public void connectionLost(Throwable throwable) {
log.warn("MQTT connection not reachable " + throwable);
connectionSucceeded = false;
new Thread(this).start();
}
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
try {
String msgText = mqttMessage.toString();
if (log.isDebugEnabled()) {
log.debug(msgText);
}
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
if (log.isDebugEnabled()) {
log.debug("Event received in MQTT Event Adapter - " + msgText);
}
if (contentValidator != null) {
ContentInfo contentInfo;
synchronized (contentValidationParams) {
contentValidationParams.put(Constants.TOPIC, topic);
contentValidationParams.put(Constants.PAYLOAD, msgText);
contentInfo = contentValidator.validate(contentValidationParams);
contentValidationParams.remove(Constants.TOPIC);
contentValidationParams.remove(Constants.PAYLOAD);
}
if (contentInfo != null && contentInfo.isValidContent()) {
eventAdapterListener.onEvent(contentInfo.getMsgText());
}
} else {
eventAdapterListener.onEvent(msgText);
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
@Override
public void run() {
while (!connectionSucceeded) {
try {
MQTTEventAdapterConstants.initialReconnectDuration = MQTTEventAdapterConstants.initialReconnectDuration
* MQTTEventAdapterConstants.reconnectionProgressionFactor;
Thread.sleep(MQTTEventAdapterConstants.initialReconnectDuration);
startListener();
connectionSucceeded = true;
log.info("MQTT Connection successful");
} catch (InterruptedException e) {
log.error("Interruption occurred while waiting for reconnection", e);
} catch (MqttException e) {
log.error("MQTT Exception occurred when starting listener", e);
}
}
}
public void createConnection() {
new Thread(this).start();
}
}

@ -0,0 +1,122 @@
/*
* 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.event.input.adapter.extensions.mqtt.util;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.Constants;
import java.util.Map;
/**
* This holds the configurations related to MQTT Broker.
*/
public class MQTTBrokerConnectionConfiguration {
private String brokerUsername = null;
private String brokerScopes = null;
private boolean cleanSession = true;
private int keepAlive;
private String brokerUrl;
private String dcrUrl;
private String contentValidatorClassName;
private Map<String, String> contentValidatorParams;
public String getBrokerScopes() {
return brokerScopes;
}
public void setBrokerScopes(String brokerScopes) {
this.brokerScopes = brokerScopes;
}
public String getBrokerUsername() {
return brokerUsername;
}
public void setBrokerUsername(String brokerUsername) {
this.brokerUsername = brokerUsername;
}
public void setCleanSession(boolean cleanSession) {
this.cleanSession = cleanSession;
}
public boolean isCleanSession() {
return cleanSession;
}
public String getBrokerUrl() {
return brokerUrl;
}
public void setBrokerUrl(String brokerUrl) {
this.brokerUrl = brokerUrl;
}
public String getDcrUrl() {
return dcrUrl;
}
public void setDcrUrl(String dcrUrl) {
this.dcrUrl = dcrUrl;
}
public int getKeepAlive() {
return keepAlive;
}
public void setKeepAlive(int keepAlive) {
this.keepAlive = keepAlive;
}
public String getContentValidatorClassName() {
return contentValidatorClassName;
}
public void setContentValidatorClassName(String contentValidatorClassName) {
this.contentValidatorClassName = contentValidatorClassName;
}
public Map<String, String> getContentValidatorParams() {
return contentValidatorParams;
}
public void setContentValidatorParams(Map<String, String> contentValidatorParams) {
this.contentValidatorParams = contentValidatorParams;
}
public MQTTBrokerConnectionConfiguration(String brokerUrl, String brokerUsername, String brokerScopes,
String dcrUrl, String cleanSession, int keepAlive,
String contentValidatorClassName, Map<String, String> contentValidatorParams) {
this.brokerUsername = brokerUsername;
this.brokerScopes = brokerScopes;
if (brokerScopes == null) {
this.brokerScopes = Constants.EMPTY_STRING;
}
this.brokerUrl = brokerUrl;
this.dcrUrl = dcrUrl;
this.contentValidatorClassName = contentValidatorClassName;
if (cleanSession != null) {
this.cleanSession = Boolean.parseBoolean(cleanSession);
}
this.keepAlive = keepAlive;
if (contentValidatorParams != null) {
this.contentValidatorParams = contentValidatorParams;
}
}
}

@ -0,0 +1,86 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.event.input.adapter.extensions.mqtt.util;
import com.jayway.jsonpath.JsonPath;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.wso2.carbon.event.input.adapter.extensions.ContentInfo;
import org.wso2.carbon.event.input.adapter.extensions.ContentValidator;
import org.wso2.carbon.event.input.adapter.extensions.mqtt.Constants;
import java.util.Map;
public class MQTTContentValidator implements ContentValidator {
private static String JSON_ARRAY_START_CHAR = "[";
private static final Log log = LogFactory.getLog(MQTTContentValidator.class);
@Override
public ContentInfo validate(Map<String, String> params) {
String topic = params.get(Constants.TOPIC);
String topics[] = topic.split("/");
String msg = params.get(Constants.PAYLOAD);
String deviceIdJsonPath = params.get(Constants.DEVICE_ID_JSON_PATH);
String deviceIdInTopicHierarchyLevel = params.get(Constants.DEVICE_ID_TOPIC_HIERARCHY_INDEX);
int deviceIdInTopicHierarchyLevelIndex = 0;
if (deviceIdInTopicHierarchyLevel != null && !deviceIdInTopicHierarchyLevel.isEmpty()) {
deviceIdInTopicHierarchyLevelIndex = Integer.parseInt(deviceIdInTopicHierarchyLevel);
}
String deviceIdFromTopic = topics[deviceIdInTopicHierarchyLevelIndex];
boolean status;
if (msg.startsWith(JSON_ARRAY_START_CHAR)) {
status = processMultipleEvents(msg, deviceIdFromTopic, deviceIdJsonPath);
} else {
status = processSingleEvent(msg, deviceIdFromTopic, deviceIdJsonPath);
}
return new ContentInfo(status, msg);
}
private boolean processSingleEvent(String msg, String deviceIdFromTopic, String deviceIdJsonPath) {
Object res = JsonPath.read(msg, deviceIdJsonPath);
String deviceIdFromContent = (res != null) ? res.toString() : "";
if (deviceIdFromContent.equals(deviceIdFromTopic)) {
return true;
}
return false;
}
private boolean processMultipleEvents(String msg, String deviceIdFromTopic, String deviceIdJsonPath) {
try {
JSONParser jsonParser = new JSONParser();
JSONArray jsonArray = (JSONArray) jsonParser.parse(msg);
boolean status = false;
for (int i = 0; i < jsonArray.size(); i++) {
status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath);
if (!status) {
return status;
}
}
return status;
} catch (ParseException e) {
log.error("Invalid input " + msg, e);
return false;
}
}
}

@ -0,0 +1,50 @@
/*
* 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.event.input.adapter.extensions.mqtt.util;
/**
* This holds the constants related to mqtt event adapter.
*/
public class MQTTEventAdapterConstants {
public static final String ADAPTER_TYPE_MQTT = "oauth-mqtt";
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_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_DCR_URL_HINT = "dcrUrl.hint";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME = "contentValidation";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT = "contentValidation.hint";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS = "contentValidationParams";
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT = "contentValidationParams.hint";
public static final String ADAPTER_MESSAGE_TOPIC = "topic";
public static final String ADAPTER_MESSAGE_TOPIC_HINT = "topic.hint";
public static final String ADAPTER_CONF_CLIENTID = "clientId";
public static final String ADAPTER_CONF_CLIENTID_HINT = "clientId.hint";
public static final String ADAPTER_CONF_CLEAN_SESSION = "cleanSession";
public static final String ADAPTER_CONF_CLEAN_SESSION_HINT = "cleanSession.hint";
public static final String ADAPTER_CONF_KEEP_ALIVE = "keepAlive";
public static final int ADAPTER_CONF_DEFAULT_KEEP_ALIVE = 60000;
public static int initialReconnectDuration = 10000;
public static final int reconnectionProgressionFactor = 2;
}

@ -0,0 +1,99 @@
/*
* 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.event.input.adapter.extensions.mqtt.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
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;
import java.io.InputStreamReader;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
/**
* This is the utility class that is used for MQTT input adapater.
*/
public class MQTTUtil {
private static final String HTTPS_PROTOCOL = "https";
private static final Log log = LogFactory.getLog(MQTTUtil.class);
/**
* Return a http client instance
*
* @param protocol- service endpoint protocol http/https
* @return
*/
public static HttpClient getHttpClient(String protocol)
throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
HttpClient httpclient;
if (HTTPS_PROTOCOL.equals(protocol)) {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
} else {
httpclient = HttpClients.createDefault();
}
return httpclient;
}
public static String getResponseString(HttpResponse httpResponse) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
String readLine;
String response = "";
while (((readLine = br.readLine()) != null)) {
response += readLine;
}
return response;
} finally {
EntityUtils.consumeQuietly(httpResponse.getEntity());
if (br != null) {
try {
br.close();
} catch (IOException e) {
log.warn("Error while closing the connection! " + e.getMessage());
}
}
}
}
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;
}
}

@ -0,0 +1,73 @@
package org.wso2.carbon.event.input.adapter.extensions.mqtt.util;
/**
* This class represents the data that are required to register
* the oauth application.
*/
public class RegistrationProfile {
private String callbackUrl;
private String clientName;
private String tokenScope;
private String owner;
private String grantType;
private String applicationType;
private static final String TAG = RegistrationProfile.class.getSimpleName();
public String getCallbackUrl() {
return callbackUrl;
}
public void setCallbackUrl(String callBackUrl) {
this.callbackUrl = callBackUrl;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public String getTokenScope() {
return tokenScope;
}
public void setTokenScope(String tokenScope) {
this.tokenScope = tokenScope;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getGrantType() {
return grantType;
}
public void setGrantType(String grantType) {
this.grantType = grantType;
}
public String getApplicationType() {
return applicationType;
}
public void setApplicationType(String applicationType) {
this.applicationType = applicationType;
}
public String toJSON() {
String jsonString =
"{\"callbackUrl\": \"" + callbackUrl + "\",\"clientName\": \"" + clientName + "\", \"tokenScope\": " +
"\"" + tokenScope + "\", \"owner\": \"" + owner + "\"," + "\"grantType\": \"" + grantType +
"\", \"saasApp\" :false }\n";
return jsonString;
}
}

@ -0,0 +1,38 @@
#
# Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
#
# WSO2 Inc. licenses this file to you under the Apache License,
# Version 2.0 (the "License"); you may not use this file except
# in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
transports=Transport(s)
http.usage.tips_prefix=Following url formats are used to receive events</br>For super tenants:</br>&nbsp;&nbsp;<i>http://localhost:
http.usage.tips_mid1=/endpoints/&lt;event_receiver_name&gt</i></br>&nbsp;&nbsp;<i>https://localhost:
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.
contentValidation=contentValidation
contentValidation.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required)
contentValidationParams=contentValidationParams
contentValidationParams.hint=ContentValidationParams, comma seperated. (if required)

@ -0,0 +1,38 @@
#
# 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.
#
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
username=Username
username.hint=Username of the broker (if required)
scopes=Scopes
scopes.hint=Scopes required to connect to broker (if required)
dcrUrl=dcrUrl
dcrUrl.hint=dynamic client registration endpoint URL to create application (if required) eg: https://localhost:9443/dynamic-client-web/register
contentValidation=contentValidation
contentValidation.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required)
contentValidationParams=contentValidationParams
contentValidationParams.hint=ContentValidationParams, comma seperated. (if required)
url.hint=MQTT broker url tcp://localhost:1883
cleanSession=Clean Session
cleanSession.hint=Persist topic subscriptions and ack positions across client sessions
keepAlive=Keep Alive (In seconds)
events.duplicated.in.cluster=Is events duplicated in cluster

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<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>das-extensions</artifactId>
<groupId>org.wso2.iot</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.event.output.adapter.extensions.ui.endpoint</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon UI Webapp - Webapp for UI Output Event Adapter</name>
<url>http://wso2.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-websocket-api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.iot</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.extensions.ui</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.wso2</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.wso2</groupId>
<artifactId>httpcore</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.orbit.org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>secured-outputui</finalName>
</build>
</project>

@ -0,0 +1,73 @@
/*
*
* 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.
*
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import util.ServiceHolder;
import javax.websocket.CloseReason;
import javax.websocket.Session;
/**
* Interface for subscription and un-subscription for web socket
*/
public class SubscriptionEndpoint {
private static final Log log = LogFactory.getLog(SubscriptionEndpoint.class);
public SubscriptionEndpoint() {
}
/**
* Web socket onClose - Remove the registered sessions
*
* @param session - Users registered session.
* @param reason - Status code for web-socket close.
* @param streamName - StreamName extracted from the ws url.
* @param version - Version extracted from the ws url.
*/
public void onClose(Session session, CloseReason reason, String streamName, String version) {
if (log.isDebugEnabled()) {
log.debug("Closing a WebSocket due to " + reason.getReasonPhrase() + ", for session ID:" + session.getId
() +
", for request URI - " + session.getRequestURI());
}
ServiceHolder.getInstance().getUiOutputCallbackControllerService().unsubscribeWebsocket(streamName, version,
session);
}
/**
* Web socket onError - Remove the registered sessions
*
* @param session - Users registered session.
* @param throwable - Status code for web-socket close.
* @param streamName - StreamName extracted from the ws url.
* @param version - Version extracted from the ws url.
*/
public void onError(Session session, Throwable throwable, String streamName, String version) {
log.error(
"Error occurred in session ID: " + session.getId() + ", for request URI - " + session.getRequestURI() +
", " + throwable.getMessage(), throwable);
ServiceHolder.getInstance().getUiOutputCallbackControllerService().unsubscribeWebsocket(streamName, version,
session);
}
}

@ -0,0 +1,134 @@
/*
* 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.
*/
import oauth.OAuthTokenValdiator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import util.ServiceHolder;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import util.AuthenticationInfo;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
* Connect to web socket with Super tenant
*/
@ServerEndpoint(value = "/{streamname}/{version}")
public class SuperTenantSubscriptionEndpoint extends SubscriptionEndpoint {
private static final Log log = LogFactory.getLog(SuperTenantSubscriptionEndpoint.class);
/**
* Web socket onOpen - When client sends a message
*
* @param session - Users registered session.
* @param streamName - StreamName extracted from the ws url.
* @param version - Version extracted from the ws url.
*/
@OnOpen
public void onOpen(Session session, @PathParam("streamname") String streamName,
@PathParam("version") String version) {
if (log.isDebugEnabled()) {
log.debug("WebSocket opened, for Session id: " + session.getId() + ", for the Stream:" + streamName);
}
AuthenticationInfo authenticationInfo = OAuthTokenValdiator.getInstance().validateToken(session);
//TODO Authorization
if (authenticationInfo != null && authenticationInfo.isAuthenticated()) {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID);
ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName,
version, session);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
} else {
try {
session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "Unauthorized Access"));
} catch (IOException e) {
log.error("Failed to disconnect the unauthorized client.");
}
}
}
/**
* Web socket onMessage - When client sens a message
*
* @param session - Users registered session.
* @param message - Status code for web-socket close.
* @param streamName - StreamName extracted from the ws url.
*/
@OnMessage
public void onMessage(Session session, String message, @PathParam("streamname") String streamName) {
if (log.isDebugEnabled()) {
log.debug("Received and dropped message from client. Message: " + message + ", " +
"for Session id: " + session.getId() + ", for the Stream:" + streamName);
}
}
/**
* Web socket onClose - Remove the registered sessions
*
* @param session - Users registered session.
* @param reason - Status code for web-socket close.
* @param streamName - StreamName extracted from the ws url.
* @param version - Version extracted from the ws url.
*/
@OnClose
public void onClose(Session session, CloseReason reason, @PathParam("streamname") String streamName,
@PathParam("version") String version) {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID);
super.onClose(session, reason, streamName, version);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
/**
* Web socket onError - Remove the registered sessions
*
* @param session - Users registered session.
* @param throwable - Status code for web-socket close.
* @param streamName - StreamName extracted from the ws url.
* @param version - Version extracted from the ws url.
*/
@OnError
public void onError(Session session, Throwable throwable, @PathParam("streamname") String streamName,
@PathParam("version") String version) {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID);
super.onError(session, throwable, streamName, version);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}

@ -0,0 +1,134 @@
/*
* 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.
*/
import oauth.OAuthTokenValdiator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import util.ServiceHolder;
import util.AuthenticationInfo;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
* Connect to web socket with a tenant
*/
@ServerEndpoint(value = "/t/{tdomain}/{streamname}/{version}")
public class TenantSubscriptionEndpoint extends SubscriptionEndpoint {
private static final Log log = LogFactory.getLog(TenantSubscriptionEndpoint.class);
/**
* Web socket onOpen - When client sends a message
*
* @param session - Users registered session.
* @param streamName - StreamName extracted from the ws url.
* @param version - Version extracted from the ws url.
* @param tdomain - Tenant domain extracted from ws url.
*/
@OnOpen
public void onOpen (Session session, @PathParam("streamname") String streamName ,
@PathParam("version") String version, @PathParam("tdomain") String tdomain) {
if (log.isDebugEnabled()) {
log.debug("WebSocket opened, for Session id: "+session.getId()+", for the Stream:"+streamName);
}
AuthenticationInfo authenticationInfo = OAuthTokenValdiator.getInstance().validateToken(session);
//TODO Authorization
if (authenticationInfo != null && authenticationInfo.isAuthenticated()) {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tdomain, true);
ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName,
version, session);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
} else {
try {
session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "Unauthorized Access"));
} catch (IOException e) {
log.error("Failed to disconnect the unauthorized client.");
}
}
}
/**
* Web socket onMessage - When client sens a message
*
* @param session - Users registered session.
* @param message - Status code for web-socket close.
* @param streamName - StreamName extracted from the ws url.
*/
@OnMessage
public void onMessage (Session session, String message, @PathParam("streamname") String streamName, @PathParam("tdomain") String tdomain) {
if (log.isDebugEnabled()) {
log.debug("Received and dropped message from client. Message: " + message+", for Session id: "+session.getId()+", for tenant domain"+tdomain+", for the Adaptor:"+streamName);
}
}
/**
* Web socket onClose - Remove the registered sessions
*
* @param session - Users registered session.
* @param reason - Status code for web-socket close.
* @param streamName - StreamName extracted from the ws url.
* @param version - Version extracted from the ws url.
*/
@OnClose
public void onClose (Session session, CloseReason reason, @PathParam("streamname") String streamName,
@PathParam("version") String version, @PathParam("tdomain") String tdomain) {
try {
PrivilegedCarbonContext.getThreadLocalCarbonContext().startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tdomain,true);
super.onClose(session, reason, streamName, version);
} finally {
PrivilegedCarbonContext.getThreadLocalCarbonContext().endTenantFlow();
}
}
/**
* Web socket onError - Remove the registered sessions
*
* @param session - Users registered session.
* @param throwable - Status code for web-socket close.
* @param streamName - StreamName extracted from the ws url.
* @param version - Version extracted from the ws url.
*/
@OnError
public void onError (Session session, Throwable throwable, @PathParam("streamname") String streamName,
@PathParam("version") String version, @PathParam("tdomain") String tdomain) {
try {
PrivilegedCarbonContext.getThreadLocalCarbonContext().startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tdomain, true);
super.onError(session, throwable, streamName, version);
} finally {
PrivilegedCarbonContext.getThreadLocalCarbonContext().endTenantFlow();
}
}
}

@ -0,0 +1,201 @@
/*
* 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.
*
*/
package oauth;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
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 util.AuthenticationInfo;
import javax.websocket.Session;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;
import java.util.Properties;
/**
* This acts as a contract point for OAuth token validation.
*/
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 QUERY_STRING_SEPERATOR = "&";
private static final String QUERY_KEY_VALUE_SEPERATOR = "=";
private static final String TOKEN_TYPE = "bearer";
private static final String TOKEN_IDENTIFIER = "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 config file " + WEBSOCKET_CONFIG_LOCATION);
}
}
/**
* This method gets a string accessToken and validates it
*
* @param session which need to be validated.
* @return AuthenticationInfo with the validated results.
*/
public AuthenticationInfo validateToken(Session session) {
String token = getTokenFromSession(session);
if (token == null) {
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
authenticationInfo.setAuthenticated(false);
return authenticationInfo;
}
OAuth2TokenValidationServiceStub tokenValidationServiceStub = null;
try {
Object stub = this.stubs.borrowObject();
if (stub != null) {
tokenValidationServiceStub = (OAuth2TokenValidationServiceStub) stub;
if (cookie != null) {
tokenValidationServiceStub._getServiceClient().getOptions().setProperty(
HTTPConstants.COOKIE_STRING, cookie);
}
return getAuthenticationInfo(token, tokenValidationServiceStub);
} else {
log.warn("Stub initialization failed.");
}
} catch (RemoteException e) {
log.error("Error on connecting with the validation endpoint.", e);
} catch (Exception e) {
log.error("Error occurred in borrowing an validation stub from the pool.", e);
} finally {
try {
if (tokenValidationServiceStub != null) {
this.stubs.returnObject(tokenValidationServiceStub);
}
} catch (Exception e) {
log.warn("Error occurred while returning the object back to the oauth token validation service " +
"stub pool.", e);
}
}
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
authenticationInfo.setAuthenticated(false);
return authenticationInfo;
}
/**
* This creates an AuthenticationInfo object that is used for authorization. This method will validate the token
* and
* sets the required parameters to the object.
*
* @param token that needs to be validated.
* @param tokenValidationServiceStub stub that is used to call the external service.
* @return AuthenticationInfo This contains the information related to authenticated client.
* @throws RemoteException that triggers when failing to call the external service..
*/
private AuthenticationInfo getAuthenticationInfo(String token,
OAuth2TokenValidationServiceStub tokenValidationServiceStub)
throws RemoteException, UserStoreException {
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
OAuth2TokenValidationRequestDTO validationRequest = new OAuth2TokenValidationRequestDTO();
OAuth2TokenValidationRequestDTO_OAuth2AccessToken accessToken =
new OAuth2TokenValidationRequestDTO_OAuth2AccessToken();
accessToken.setTokenType(TOKEN_TYPE);
accessToken.setIdentifier(token);
validationRequest.setAccessToken(accessToken);
boolean authenticated;
OAuth2TokenValidationResponseDTO tokenValidationResponse;
tokenValidationResponse = tokenValidationServiceStub.validate(validationRequest);
if (tokenValidationResponse == null) {
authenticationInfo.setAuthenticated(false);
return authenticationInfo;
}
authenticated = tokenValidationResponse.getValid();
if (authenticated) {
String authorizedUser = tokenValidationResponse.getAuthorizedUser();
String username = MultitenantUtils.getTenantAwareUsername(authorizedUser);
String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser);
authenticationInfo.setUsername(username);
authenticationInfo.setTenantDomain(tenantDomain);
} else {
if (log.isDebugEnabled()) {
log.debug("Token validation failed for token: " + token);
}
}
ServiceContext serviceContext = tokenValidationServiceStub._getServiceClient()
.getLastOperationContext().getServiceContext();
cookie = (String) serviceContext.getProperty(HTTPConstants.COOKIE_STRING);
authenticationInfo.setAuthenticated(authenticated);
return authenticationInfo;
}
/**
* Retrieve JWT configs from registry.
*/
private Properties getWebSocketConfig() throws IOException {
Properties properties = new Properties();
File configFile =new File(WEBSOCKET_CONFIG_LOCATION);
if (configFile.exists()) {
InputStream fileInputStream = new FileInputStream(configFile);
if (fileInputStream != null) {
properties.load(fileInputStream);
}
}
return properties;
}
private String getTokenFromSession(Session session) {
String queryString = session.getQueryString();
if (queryString != null) {
String[] allQueryParamPairs = queryString.split(QUERY_STRING_SEPERATOR);
for (String keyValuePair : allQueryParamPairs) {
String[] queryParamPair = keyValuePair.split(QUERY_KEY_VALUE_SEPERATOR);
if (queryParamPair.length != 2) {
log.warn("Invalid query string [" + queryString + "] passed in.");
break;
}
if (queryParamPair[0].equals(TOKEN_IDENTIFIER)) {
return queryParamPair[1];
}
}
}
return null;
}
}

@ -0,0 +1,177 @@
/*
* 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 oauth;
import oauth.exception.OAuthTokenValidationException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.transport.http.HttpTransportProperties;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.log4j.Logger;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
import util.UIConstants;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.Properties;
/**
* This follows object pool pattern to manage the stub for oauth validation service.
*/
public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory {
private static final Logger log = Logger.getLogger(OAuthTokenValidaterStubFactory.class);
private HttpClient httpClient;
Properties tokenValidationProperties;
public OAuthTokenValidaterStubFactory(Properties tokenValidationProperties) {
this.tokenValidationProperties = tokenValidationProperties;
this.httpClient = createHttpClient();
}
/**
* This creates a OAuth2TokenValidationServiceStub object to the pool.
*
* @return an OAuthValidationStub object
* @throws Exception thrown when creating the object.
*/
@Override
public Object makeObject() throws Exception {
return this.generateStub();
}
/**
* This is used to clean up the OAuth validation stub and releases to the object pool.
*
* @param o object that needs to be released.
* @throws Exception throws when failed to release to the pool
*/
@Override
public void passivateObject(Object o) throws Exception {
if (o instanceof OAuth2TokenValidationServiceStub) {
OAuth2TokenValidationServiceStub stub = (OAuth2TokenValidationServiceStub) o;
stub._getServiceClient().cleanupTransport();
}
}
/**
* This is used to create a stub which will be triggered through object pool factory, which will create an
* instance of it.
*
* @return OAuth2TokenValidationServiceStub stub that is used to call an external service.
* @throws OAuthTokenValidationException will be thrown when initialization failed.
*/
private OAuth2TokenValidationServiceStub generateStub() throws OAuthTokenValidationException {
OAuth2TokenValidationServiceStub stub;
try {
URL hostURL = new URL(tokenValidationProperties.getProperty((UIConstants.TOKEN_VALIDATION_ENDPOINT_URL)));
if (hostURL != null) {
stub = new OAuth2TokenValidationServiceStub(hostURL.toString());
if (stub != null) {
ServiceClient client = stub._getServiceClient();
client.getServiceContext().getConfigurationContext().setProperty(
HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
HttpTransportProperties.Authenticator auth =
new HttpTransportProperties.Authenticator();
auth.setPreemptiveAuthentication(true);
String username = tokenValidationProperties.getProperty(UIConstants.USERNAME);
String password = tokenValidationProperties.getProperty(UIConstants.PASSWORD);
auth.setPassword(username);
auth.setUsername(password);
Options options = client.getOptions();
options.setProperty(HTTPConstants.AUTHENTICATE, auth);
options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Constants.VALUE_TRUE);
client.setOptions(options);
if (hostURL.getProtocol().equals("https")) {
// set up ssl factory since axis2 https transport is used.
EasySSLProtocolSocketFactory sslProtocolSocketFactory =
createProtocolSocketFactory();
Protocol authhttps = new Protocol(hostURL.getProtocol(),
(ProtocolSocketFactory) sslProtocolSocketFactory,
hostURL.getPort());
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);
}
return stub;
}
/**
* This is required to create a trusted connection with the external entity.
* Have to manually configure it since we use CommonHTTPTransport(axis2 transport) in axis2.
*
* @return an EasySSLProtocolSocketFactory for SSL communication.
*/
private EasySSLProtocolSocketFactory createProtocolSocketFactory() throws OAuthTokenValidationException {
try {
EasySSLProtocolSocketFactory easySSLPSFactory = new EasySSLProtocolSocketFactory();
return easySSLPSFactory;
} catch (IOException e) {
String errorMsg = "Failed to initiate EasySSLProtocolSocketFactory.";
throw new OAuthTokenValidationException(errorMsg, e);
} catch (GeneralSecurityException e) {
String errorMsg = "Failed to set the key material in easy ssl factory.";
throw new OAuthTokenValidationException(errorMsg, e);
}
}
/**
* This created httpclient pool that can be used to connect to external entity. This connection can be configured
* via broker.xml by setting up the required http connection parameters.
*
* @return an instance of HttpClient that is configured with MultiThreadedHttpConnectionManager
*/
private HttpClient createHttpClient() {
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
params.setDefaultMaxConnectionsPerHost(Integer.parseInt(tokenValidationProperties.getProperty(
UIConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST)));
params.setMaxTotalConnections(Integer.parseInt(tokenValidationProperties.getProperty(
UIConstants.MAXIMUM_TOTAL_HTTP_CONNECTION)));
HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.setParams(params);
return new HttpClient(connectionManager);
}
}

@ -0,0 +1,56 @@
/*
* 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 oauth.exception;
/**
* This Exception will be thrown, when there any interference with token validation flow.
*/
public class OAuthTokenValidationException extends Exception {
private String errMessage;
public OAuthTokenValidationException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public OAuthTokenValidationException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public OAuthTokenValidationException(String msg) {
super(msg);
setErrorMessage(msg);
}
public OAuthTokenValidationException() {
super();
}
public OAuthTokenValidationException(Throwable cause) {
super(cause);
}
public String getErrorMessage() {
return errMessage;
}
public void setErrorMessage(String errMessage) {
this.errMessage = errMessage;
}
}

@ -0,0 +1,60 @@
/*
* 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.
*
*/
package util;
/**
* This is returned after authentication.
*/
public class AuthenticationInfo {
/**
* this variable is used to check whether the client is authenticated.
*/
private boolean authenticated;
private String username;
private String tenantDomain;
/**
* returns whether the client is authenticated
*/
public boolean isAuthenticated() {
return authenticated;
}
public void setAuthenticated(boolean authenticated) {
this.authenticated = authenticated;
}
/**
* returns the authenticated client username
*/
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
/**
* return the authenticated client tenant domain
*/
public String getTenantDomain() {
return tenantDomain;
}
public void setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
}
}

@ -0,0 +1,27 @@
package util;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.event.output.adapter.extensions.ui.UIOutputCallbackControllerService;
public class ServiceHolder {
private static ServiceHolder instance;
private UIOutputCallbackControllerService uiOutputCallbackControllerService;
private ServiceHolder(){
uiOutputCallbackControllerService = (UIOutputCallbackControllerService) PrivilegedCarbonContext
.getThreadLocalCarbonContext().getOSGiService(UIOutputCallbackControllerService.class, null);
}
public synchronized static ServiceHolder getInstance(){
if (instance==null){
instance= new ServiceHolder();
}
return instance;
}
public UIOutputCallbackControllerService getUiOutputCallbackControllerService() {
return uiOutputCallbackControllerService;
}
}

@ -0,0 +1,38 @@
/*
*
* *
* * 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 util;
/**
* This class contains the constants related to ui client.
*/
public class UIConstants {
private UIConstants() {
}
public static final String ADAPTER_UI_COLON = ":";
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 USERNAME = "username";
public static final String PASSWORD = "password";
}

@ -0,0 +1,24 @@
<!--
~ 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.
-->
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Output WebSocket</display-name>
</web-app>

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<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>das-extensions</artifactId>
<groupId>org.wso2.iot</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.event.output.adapter.extensions.ui</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Event Output UI Adapter Module</name>
<description>org.wso2.carbon.event.output.adapter.ui provides the back-end functionality of
ui event adapter
</description>
<url>http://wso2.org</url>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.core</artifactId>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.databridge.commons</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.stream.core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-descriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package>
org.wso2.carbon.event.output.adapter.extensions.ui.internal,
org.wso2.carbon.event.output.adapter.extensions.ui.internal.*
</Private-Package>
<Export-Package>
!org.wso2.carbon.event.output.adapter.extensions.ui.internal,
!org.wso2.carbon.event.output.adapter.extensions.ui.internal.*,
org.wso2.carbon.event.output.adapter.extensions.ui.*
</Export-Package>
<Import-Package>
org.wso2.carbon.event.output.adapter.core.*,
javax.xml.namespace; version=0.0.0,
org.apache.axis2,
org.apache.axis2.client,
org.apache.axis2.context,
org.apache.axis2.transport.http,
org.apache.commons.httpclient,
org.apache.commons.httpclient.contrib.ssl,
org.apache.commons.httpclient.params,
org.apache.commons.httpclient.protocol,
org.apache.commons.pool,
org.apache.commons.pool.impl,
org.apache.log4j,
com.google.gson,
javax.websocket,
org.apache.commons.logging,
org.osgi.framework,
org.osgi.service.component,
org.wso2.carbon.context,
org.wso2.carbon.databridge.commons,
org.wso2.carbon.event.stream.core,
org.wso2.carbon.event.stream.core.exception,
org.wso2.carbon.utils
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,459 @@
/*
*
* 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.event.output.adapter.extensions.ui;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.databridge.commons.Attribute;
import org.wso2.carbon.databridge.commons.Event;
import org.wso2.carbon.databridge.commons.StreamDefinition;
import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil;
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.exception.OutputEventAdapterException;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterRuntimeException;
import org.wso2.carbon.event.output.adapter.core.exception.TestConnectionNotSupportedException;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.ds.OutputAdaptorEventStreamServiceValueHolder;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.util.UIEventAdapterConstants;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.UIOutputCallbackControllerServiceImpl;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.ds.UIEventAdaptorServiceInternalValueHolder;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.util.CEPWebSocketSession;
import org.wso2.carbon.event.stream.core.EventStreamService;
import org.wso2.carbon.event.stream.core.exception.EventStreamConfigurationException;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Contains the life cycle of executions regarding the UI Adapter
*/
public class UIEventAdapter implements OutputEventAdapter {
private static final Log log = LogFactory.getLog(UIEventAdapter.class);
private OutputEventAdapterConfiguration eventAdapterConfiguration;
private Map<String, String> globalProperties;
private int queueSize;
private LinkedBlockingDeque<Object> streamSpecificEvents;
private static ThreadPoolExecutor executorService;
private int tenantId;
private boolean doLogDroppedMessage;
private String streamId;
private StreamDefinition streamDefinition;
private List<Attribute> streamMetaAttributes;
private List<Attribute> streamCorrelationAttributes;
private List<Attribute> streamPayloadAttributes;
public UIEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration, Map<String,
String> globalProperties) {
this.eventAdapterConfiguration = eventAdapterConfiguration;
this.globalProperties = globalProperties;
this.doLogDroppedMessage = true;
}
@Override
public void init() throws OutputEventAdapterException {
tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
//ExecutorService will be assigned if it is null
if (executorService == null) {
int minThread;
int maxThread;
long defaultKeepAliveTime;
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) {
minThread = Integer.parseInt(globalProperties.get(
UIEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME));
} else {
minThread = UIEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE;
}
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME) != null) {
maxThread = Integer.parseInt(globalProperties.get(
UIEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME));
} else {
maxThread = UIEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE;
}
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME) != null) {
defaultKeepAliveTime = Integer.parseInt(globalProperties.get(
UIEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME));
} else {
defaultKeepAliveTime = UIEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_IN_MILLIS;
}
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME) != null) {
jobQueSize = Integer.parseInt(globalProperties.get(
UIEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME));
} else {
jobQueSize = UIEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE;
}
executorService = new ThreadPoolExecutor(minThread, maxThread, defaultKeepAliveTime, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(jobQueSize));
}
streamId = eventAdapterConfiguration.getOutputStreamIdOfWso2eventMessageFormat();
if (streamId == null || streamId.isEmpty()) {
throw new OutputEventAdapterRuntimeException("UI event adapter needs a output stream id");
}
// fetch the "streamDefinition" corresponding to the "streamId" and then fetch the different attribute types
// of the streamDefinition corresponding to the event's streamId. They are required when validating values in
// the events against the streamDef attributes.
streamDefinition = getStreamDefinition(streamId);
streamMetaAttributes = streamDefinition.getMetaData();
streamCorrelationAttributes = streamDefinition.getCorrelationData();
streamPayloadAttributes = streamDefinition.getPayloadData();
ConcurrentHashMap<Integer, ConcurrentHashMap<String, String>> tenantSpecifcEventOutputAdapterMap =
UIEventAdaptorServiceInternalValueHolder.getTenantSpecificOutputEventStreamAdapterMap();
ConcurrentHashMap<String, String> streamSpecifAdapterMap = tenantSpecifcEventOutputAdapterMap.get(tenantId);
if (streamSpecifAdapterMap == null) {
streamSpecifAdapterMap = new ConcurrentHashMap<String, String>();
if (null != tenantSpecifcEventOutputAdapterMap.putIfAbsent(tenantId, streamSpecifAdapterMap)) {
streamSpecifAdapterMap = tenantSpecifcEventOutputAdapterMap.get(tenantId);
}
}
String adapterName = streamSpecifAdapterMap.get(streamId);
if (adapterName != null) {
throw new OutputEventAdapterException(("An Output ui event adapter \"" + adapterName + "\" is already" +
" exist for stream id \"" + streamId + "\""));
} else {
streamSpecifAdapterMap.put(streamId, eventAdapterConfiguration.getName());
ConcurrentHashMap<Integer, ConcurrentHashMap<String, LinkedBlockingDeque<Object>>> tenantSpecificStreamMap =
UIEventAdaptorServiceInternalValueHolder.getTenantSpecificStreamEventMap();
ConcurrentHashMap<String, LinkedBlockingDeque<Object>> streamSpecificEventsMap =
tenantSpecificStreamMap.get(tenantId);
if (streamSpecificEventsMap == null) {
streamSpecificEventsMap = new ConcurrentHashMap<String, LinkedBlockingDeque<Object>>();
if (null != tenantSpecificStreamMap.putIfAbsent(tenantId, streamSpecificEventsMap)) {
streamSpecificEventsMap = tenantSpecificStreamMap.get(tenantId);
}
}
streamSpecificEvents = streamSpecificEventsMap.get(streamId);
if (streamSpecificEvents == null) {
streamSpecificEvents = new LinkedBlockingDeque<Object>();
if (null != streamSpecificEventsMap.putIfAbsent(streamId, streamSpecificEvents)) {
streamSpecificEvents = streamSpecificEventsMap.get(streamId);
}
}
}
if (globalProperties.get(UIEventAdapterConstants.ADAPTER_EVENT_QUEUE_SIZE_NAME) != null) {
try {
queueSize = Integer.parseInt(
globalProperties.get(UIEventAdapterConstants.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;
}
} else {
queueSize = UIEventAdapterConstants.EVENTS_QUEUE_SIZE;
}
}
@Override
public void testConnect() throws TestConnectionNotSupportedException {
throw new TestConnectionNotSupportedException("Test connection is not available");
}
@Override
public void connect() {
//Not needed
}
@Override
public void publish(Object message, Map<String, String> dynamicProperties) {
Event event = (Event) message;
StringBuilder eventBuilder = new StringBuilder("[");
if (streamSpecificEvents.size() == queueSize) {
streamSpecificEvents.removeFirst();
}
eventBuilder.append(event.getTimeStamp());
if (event.getMetaData() != null) {
eventBuilder.append(",");
Object[] metaData = event.getMetaData();
for (int i = 0; i < metaData.length; i++) {
eventBuilder.append("\"");
eventBuilder.append(metaData[i]);
eventBuilder.append("\"");
if (i != (metaData.length - 1)) {
eventBuilder.append(",");
}
}
}
if (event.getCorrelationData() != null) {
Object[] correlationData = event.getCorrelationData();
eventBuilder.append(",");
for (int i = 0; i < correlationData.length; i++) {
eventBuilder.append("\"");
eventBuilder.append(correlationData[i]);
eventBuilder.append("\"");
if (i != (correlationData.length - 1)) {
eventBuilder.append(",");
}
}
}
if (event.getPayloadData() != null) {
Object[] payloadData = event.getPayloadData();
eventBuilder.append(",");
for (int i = 0; i < payloadData.length; i++) {
eventBuilder.append("\"");
eventBuilder.append(payloadData[i]);
eventBuilder.append("\"");
if (i != (payloadData.length - 1)) {
eventBuilder.append(",");
}
}
}
eventBuilder.append("]");
String eventString = eventBuilder.toString();
Object[] eventValues = new Object[UIEventAdapterConstants.INDEX_TWO];
eventValues[UIEventAdapterConstants.INDEX_ZERO] = eventString;
eventValues[UIEventAdapterConstants.INDEX_ONE] = System.currentTimeMillis();
streamSpecificEvents.add(eventValues);
// fetch all valid sessions checked against any queryParameters provided when subscribing.
CopyOnWriteArrayList<CEPWebSocketSession> validSessions = getValidSessions(event);
try {
executorService.execute(new WebSocketSender(validSessions, eventString));
} catch (RejectedExecutionException e) {
EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message, "Job queue is full", e, log,
tenantId);
}
}
@Override
public void disconnect() {
//Not needed
}
@Override
public void destroy() {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
ConcurrentHashMap<String, String> tenantSpecificAdapterMap = UIEventAdaptorServiceInternalValueHolder
.getTenantSpecificOutputEventStreamAdapterMap().get(tenantId);
if (tenantSpecificAdapterMap != null && streamId != null) {
tenantSpecificAdapterMap.remove(streamId); //Removing outputadapter and streamId
}
ConcurrentHashMap<String, LinkedBlockingDeque<Object>> tenantSpecificStreamEventMap =
UIEventAdaptorServiceInternalValueHolder.getTenantSpecificStreamEventMap().get(tenantId);
if (tenantSpecificStreamEventMap != null && streamId != null) {
//Removing the streamId and events registered for the output adapter
tenantSpecificStreamEventMap.remove(streamId);
}
}
@Override
public boolean isPolled() {
return true;
}
/**
* Fetch the StreamDefinition corresponding to the given StreamId from the EventStreamService.
*
* @param streamId the streamId of this UIEventAdaptor.
* @return the "StreamDefinition" object corresponding to the streamId of this EventAdaptor.
* @throws OutputEventAdapterException if the "EventStreamService" OSGI service is unavailable/unregistered or if
* the matching Steam-Definition for the given StreamId cannot be retrieved.
*/
private StreamDefinition getStreamDefinition(String streamId) throws OutputEventAdapterException {
EventStreamService eventStreamService = OutputAdaptorEventStreamServiceValueHolder.getEventStreamService();
if (eventStreamService != null) {
try {
return eventStreamService.getStreamDefinition(streamId);
} catch (EventStreamConfigurationException e) {
String adaptorType = eventAdapterConfiguration.getType();
String adaptorName = eventAdapterConfiguration.getName();
String errorMsg = "Error while retrieving Stream-Definition for Stream with id [" + streamId + "] " +
"for Adaptor [" + adaptorName + "] of type [" + adaptorType + "].";
log.error(errorMsg);
throw new OutputEventAdapterException(errorMsg, e);
}
}
throw new OutputEventAdapterException(
"Could not retrieve the EventStreamService whilst trying to fetch the Stream-Definition of Stream " +
"with Id [" + streamId + "].");
}
/**
* Fetches all valid web-socket sessions from the entire pool of subscribed sessions. The validity is checked
* against any queryString provided when subscribing to the web-socket endpoint.
*
* @param event the current event received and that which needs to be published to subscribed sessions.
* @return a list of all validated web-socket sessions against the queryString values.
*/
private CopyOnWriteArrayList<CEPWebSocketSession> getValidSessions(Event event) {
CopyOnWriteArrayList<CEPWebSocketSession> validSessions = new CopyOnWriteArrayList<>();
UIOutputCallbackControllerServiceImpl uiOutputCallbackControllerServiceImpl =
UIEventAdaptorServiceInternalValueHolder.getUIOutputCallbackRegisterServiceImpl();
// get all subscribed web-socket sessions.
CopyOnWriteArrayList<CEPWebSocketSession> cepWebSocketSessions =
uiOutputCallbackControllerServiceImpl.getSessions(tenantId, streamId);
for (CEPWebSocketSession cepWebSocketSession : cepWebSocketSessions) {
boolean isValidSession = validateEventAgainstSessionFilters(event, cepWebSocketSession);
if (isValidSession) {
validSessions.add(cepWebSocketSession);
}
}
return validSessions;
}
/**
* Processes the given session's validity to receive the current "event" against any queryParams that was used at
* the time when the web-socket-session is subscribed. This method can be extended to validate the event against
* any additional attribute of the given session too.
*
* @param event the current event received and that which needs to be published to subscribed
* sessions.
* @param cepWebSocketSession the session which needs validated for its authenticity to receive this event.
* @return "true" if the session is valid to receive the event else "false".
*/
private boolean validateEventAgainstSessionFilters(Event event, CEPWebSocketSession cepWebSocketSession) {
// fetch the queryString Key:Value pair map of the given session.
Map<String, String> queryParamValuePairs = cepWebSocketSession.getQueryParamValuePairs();
if (queryParamValuePairs != null) {
// fetch the different attribute values received as part of the current event.
Object[] eventMetaData = event.getMetaData();
Object[] eventCorrelationData = event.getCorrelationData();
Object[] eventPayloadData = event.getPayloadData();
if (streamMetaAttributes != null) {
for (int i = 0; i < streamMetaAttributes.size(); i++) {
String attributeName = streamMetaAttributes.get(i).getName();
String queryValue = queryParamValuePairs.get(attributeName);
if (queryValue != null &&
(eventMetaData == null || !eventMetaData[i].toString().equals(queryValue))) {
return false;
}
}
}
if (streamCorrelationAttributes != null) {
for (int i = 0; i < streamCorrelationAttributes.size(); i++) {
String attributeName = streamCorrelationAttributes.get(i).getName();
String queryValue = queryParamValuePairs.get(attributeName);
if (queryValue != null &&
(eventCorrelationData == null || !eventCorrelationData[i].toString().equals(queryValue))) {
return false;
}
}
}
if (streamPayloadAttributes != null) {
for (int i = 0; i < streamPayloadAttributes.size(); i++) {
String attributeName = streamPayloadAttributes.get(i).getName();
String queryValue = queryParamValuePairs.get(attributeName);
if (queryValue != null && (eventPayloadData == null || !eventPayloadData[i].toString().equals(
queryValue))) {
return false;
}
}
}
}
return true;
}
private class WebSocketSender implements Runnable {
private String message;
private CopyOnWriteArrayList<CEPWebSocketSession> cepWebSocketSessions;
public WebSocketSender(CopyOnWriteArrayList<CEPWebSocketSession> cepWebSocketSessions, String message) {
this.cepWebSocketSessions = cepWebSocketSessions;
this.message = message;
}
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p/>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
if (cepWebSocketSessions != null) {
doLogDroppedMessage = true;
for (CEPWebSocketSession cepWebSocketSession : cepWebSocketSessions) {
synchronized (cepWebSocketSession) {
try {
cepWebSocketSession.getSession().getBasicRemote().sendText(message);
} catch (IOException e) {
EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message,
"Cannot send to endpoint", e, log, tenantId);
}
}
}
} else if (doLogDroppedMessage) {
EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message, "No clients registered", log,
tenantId);
doLogDroppedMessage = false;
}
}
}
}

@ -0,0 +1,89 @@
/*
*
* 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.event.output.adapter.extensions.ui;
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 org.wso2.carbon.event.output.adapter.extensions.ui.internal.util.UIEventAdapterConstants;
import org.wso2.carbon.utils.CarbonUtils;
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.event.output.adapter.extensions.ui.i18n" +
".Resources", Locale.getDefault());
private int httpPort;
private int httpsPort;
private int portOffset;
public UIEventAdapterFactory() {
portOffset = getPortOffset();
httpPort = UIEventAdapterConstants.DEFAULT_HTTP_PORT + portOffset;
httpsPort = UIEventAdapterConstants.DEFAULT_HTTPS_PORT + portOffset;
}
@Override
public String getType() {
return UIEventAdapterConstants.ADAPTER_TYPE_UI;
}
@Override
public List<String> getSupportedMessageFormats() {
List<String> supportedMessageFormats = new ArrayList<String>();
supportedMessageFormats.add(MessageType.WSO2EVENT);
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);
}
private int getPortOffset() {
return CarbonUtils.getPortFromServerConfig(UIEventAdapterConstants.CARBON_CONFIG_PORT_OFFSET_NODE) + 1;
}
}

@ -0,0 +1,61 @@
/*
*
* 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.event.output.adapter.extensions.ui;
import com.google.gson.JsonObject;
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 {
/**
* Used to subscribe the session id and stream id for later web socket connectivity
*
* @param streamName - Stream name which user register to.
* @param version - Stream version which user uses.
* @param session - Session which user registered.
* @return
*/
public void subscribeWebsocket(String streamName, String version, Session session);
/**
* Used to return events per streamId
*
* @param streamName - Stream name which user register to.
* @param version - Stream version which user uses.
* @param session - Session which user subscribed to.
* @return the events list.
*/
public void unsubscribeWebsocket(String streamName, String version, Session session);
/**
* Used to return events per http GET request.
*
* @param streamName - Stream name which user register to.
* @param version - Stream version which user uses.
* @param lastUpdatedTime - Last dispatched events time.
* @return the events list.
*/
public JsonObject retrieveEvents(String streamName, String version, String lastUpdatedTime);
}

@ -0,0 +1,210 @@
/*
*
* 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.event.output.adapter.extensions.ui.internal;
import com.google.gson.JsonObject;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.event.output.adapter.extensions.ui.UIOutputCallbackControllerService;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.util.CEPWebSocketSession;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.util.UIEventAdapterConstants;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.ds.UIEventAdaptorServiceInternalValueHolder;
import javax.websocket.Session;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque;
/**
* Service implementation class which exposes to front end
*/
public class UIOutputCallbackControllerServiceImpl implements UIOutputCallbackControllerService {
private ConcurrentHashMap<Integer, ConcurrentHashMap<String, CopyOnWriteArrayList<CEPWebSocketSession>>>
outputEventAdaptorSessionMap;
public UIOutputCallbackControllerServiceImpl() {
outputEventAdaptorSessionMap =
new ConcurrentHashMap<Integer, ConcurrentHashMap<String, CopyOnWriteArrayList<CEPWebSocketSession>>>();
}
/**
* Used to subscribe the session id and stream id for later web socket connectivity
*
* @param streamName - Stream name which user register to.
* @param version - Stream version which user uses.
* @param session - Session which user registered.
* @return
*/
public void subscribeWebsocket(String streamName, String version, Session session) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
if (version == null || " ".equals(version)) {
version = UIEventAdapterConstants.ADAPTER_UI_DEFAULT_OUTPUT_STREAM_VERSION;
}
String streamId = streamName + UIEventAdapterConstants.ADAPTER_UI_COLON + version;
ConcurrentHashMap<String, CopyOnWriteArrayList<CEPWebSocketSession>> tenantSpecificAdaptorMap =
outputEventAdaptorSessionMap.get(tenantId);
if (tenantSpecificAdaptorMap == null) {
tenantSpecificAdaptorMap = new ConcurrentHashMap<String, CopyOnWriteArrayList<CEPWebSocketSession>>();
if (null != outputEventAdaptorSessionMap.putIfAbsent(tenantId, tenantSpecificAdaptorMap)) {
tenantSpecificAdaptorMap = outputEventAdaptorSessionMap.get(tenantId);
}
}
CopyOnWriteArrayList<CEPWebSocketSession> adapterSpecificSessions = tenantSpecificAdaptorMap.get(streamId);
if (adapterSpecificSessions == null) {
adapterSpecificSessions = new CopyOnWriteArrayList<CEPWebSocketSession>();
if (null != tenantSpecificAdaptorMap.putIfAbsent(streamId, adapterSpecificSessions)) {
adapterSpecificSessions = tenantSpecificAdaptorMap.get(streamId);
}
}
CEPWebSocketSession cepWebSocketSession = new CEPWebSocketSession(session);
adapterSpecificSessions.add(cepWebSocketSession);
}
/**
* Used to return registered sessions per streamId
*
* @param tenantId - Tenant id of the user.
* @param streamId - Stream name and version which user register to.
* @return the sessions list.
*/
public CopyOnWriteArrayList<CEPWebSocketSession> getSessions(int tenantId, String streamId) {
ConcurrentHashMap<String, CopyOnWriteArrayList<CEPWebSocketSession>> tenantSpecificAdaptorMap = outputEventAdaptorSessionMap.get(tenantId);
if (tenantSpecificAdaptorMap != null) {
return tenantSpecificAdaptorMap.get(streamId);
}
return null;
}
/**
* Used to return events per streamId
*
* @param tenanId - Tenant id of the user.
* @param streamName - Stream name which user register to.
* @param version - Stream version which user uses.
* @return the events list.
*/
public LinkedBlockingDeque<Object> getEvents(int tenanId, String streamName, String version) {
ConcurrentHashMap<String, LinkedBlockingDeque<Object>> tenantSpecificStreamMap =
UIEventAdaptorServiceInternalValueHolder.getTenantSpecificStreamEventMap().get(tenanId);
if (tenantSpecificStreamMap != null) {
String streamId = streamName + UIEventAdapterConstants.ADAPTER_UI_COLON + version;
return tenantSpecificStreamMap.get(streamId);
}
return null;
}
/**
* Used to return events per streamId
*
* @param streamName - Stream name which user register to.
* @param version - Stream version which user uses.
* @param session - Session which user subscribed to.
* @return the events list.
*/
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;
}
String id = streamName + UIEventAdapterConstants.ADAPTER_UI_COLON + version;
ConcurrentHashMap<String, CopyOnWriteArrayList<CEPWebSocketSession>> tenantSpecificAdaptorMap = outputEventAdaptorSessionMap.get(tenantId);
if (tenantSpecificAdaptorMap != null) {
CopyOnWriteArrayList<CEPWebSocketSession> adapterSpecificSessions = tenantSpecificAdaptorMap.get(id);
if (adapterSpecificSessions != null) {
CEPWebSocketSession sessionToRemove = null;
for (Iterator<CEPWebSocketSession> iterator = adapterSpecificSessions.iterator(); iterator.hasNext(); ) {
CEPWebSocketSession cepWebSocketSession = iterator.next();
if (session.getId().equals(cepWebSocketSession.getSession().getId())) {
sessionToRemove = cepWebSocketSession;
break;
}
}
if (sessionToRemove != null) {
adapterSpecificSessions.remove(sessionToRemove);
}
}
}
}
/**
* Used to return events per http GET request.
*
* @param streamName - Stream name which user register to.
* @param version - Stream version which user uses.
* @param lastUpdatedTime - Last dispatched events time.
* @return the events list.
*/
@Override
public JsonObject retrieveEvents(String streamName, String version, String lastUpdatedTime) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
LinkedBlockingDeque<Object> allEvents = getEvents(tenantId, streamName, version);
//List<Object> eventsListToBeSent;
Object lastEventTime = null;
JsonObject eventsData;
if (allEvents != null) {
eventsData = new JsonObject();
Boolean firstFilteredValue = true;
long sentTimeStamp = Long.parseLong(lastUpdatedTime);
//eventsListToBeSent = new ArrayList<Object>();
StringBuilder allEventsAsString = new StringBuilder("[");
// set Iterator as descending
Iterator iterator = allEvents.descendingIterator();
while (iterator.hasNext()) {
Object[] eventValues = (Object[]) iterator.next();
long eventTimeStamp = (Long) eventValues[UIEventAdapterConstants.INDEX_ONE];
if (sentTimeStamp < eventTimeStamp) {
if (!firstFilteredValue) {
allEventsAsString.append(",");
}
firstFilteredValue = false;
String eventString = (String) eventValues[UIEventAdapterConstants.INDEX_ZERO];
allEventsAsString.append(eventString);
}
}
allEventsAsString.append("]");
if (allEvents.size() != 0) {
Object[] lastObj = (Object[]) allEvents.getLast();
lastEventTime = lastObj[UIEventAdapterConstants.INDEX_ONE];
eventsData.addProperty("lastEventTime", String.valueOf(lastEventTime));
}
eventsData.addProperty("events", allEventsAsString.toString());
return eventsData;
}
return null;
}
}

@ -0,0 +1,37 @@
/*
* 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.
*
*/
package org.wso2.carbon.event.output.adapter.extensions.ui.internal.ds;
import org.wso2.carbon.event.stream.core.EventStreamService;
/**
* This class holds a reference to the current EventStream OSGI service component "eventStreamService.component" in the
* OSGI runtime.
*/
public class OutputAdaptorEventStreamServiceValueHolder {
private static EventStreamService eventStreamService;
public static void registerEventStreamService(EventStreamService eventBuilderService) {
OutputAdaptorEventStreamServiceValueHolder.eventStreamService = eventBuilderService;
}
public static EventStreamService getEventStreamService() {
return OutputAdaptorEventStreamServiceValueHolder.eventStreamService;
}
public static void unregisterEventStreamService(EventStreamService eventStreamService) {
OutputAdaptorEventStreamServiceValueHolder.eventStreamService = null;
}
}

@ -0,0 +1,56 @@
/*
*
* 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.event.output.adapter.extensions.ui.internal.ds;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.UIOutputCallbackControllerServiceImpl;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingDeque;
/**
* Creates a holder of type UIOutputCallbackRegisterServiceImpl.
*/
public final class UIEventAdaptorServiceInternalValueHolder {
private static UIOutputCallbackControllerServiceImpl UIOutputCallbackRegisterServiceImpl;
private static ConcurrentHashMap<Integer,ConcurrentHashMap<String, String>> tenantSpecificOutputEventStreamAdapterMap = new
ConcurrentHashMap<Integer,ConcurrentHashMap<String, String>>();
private static ConcurrentHashMap<Integer, ConcurrentHashMap<String, LinkedBlockingDeque<Object>>> tenantSpecificStreamEventMap
= new ConcurrentHashMap<Integer, ConcurrentHashMap<String, LinkedBlockingDeque<Object>>>();
public static void registerUIOutputCallbackRegisterServiceInternal(
UIOutputCallbackControllerServiceImpl UIOutputCallbackRegisterServiceImpl) {
UIEventAdaptorServiceInternalValueHolder.UIOutputCallbackRegisterServiceImpl =
UIOutputCallbackRegisterServiceImpl;
}
public static UIOutputCallbackControllerServiceImpl getUIOutputCallbackRegisterServiceImpl() {
return UIEventAdaptorServiceInternalValueHolder.UIOutputCallbackRegisterServiceImpl;
}
public static ConcurrentHashMap<Integer,ConcurrentHashMap<String, String>> getTenantSpecificOutputEventStreamAdapterMap() {
return tenantSpecificOutputEventStreamAdapterMap;
}
public static ConcurrentHashMap<Integer, ConcurrentHashMap<String, LinkedBlockingDeque<Object>>>
getTenantSpecificStreamEventMap() {
return tenantSpecificStreamEventMap;
}
}

@ -0,0 +1,80 @@
/*
*
* 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.event.output.adapter.extensions.ui.internal.ds;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory;
import org.wso2.carbon.event.output.adapter.extensions.ui.UIEventAdapterFactory;
import org.wso2.carbon.event.output.adapter.extensions.ui.UIOutputCallbackControllerService;
import org.wso2.carbon.event.output.adapter.extensions.ui.internal.UIOutputCallbackControllerServiceImpl;
import org.wso2.carbon.event.stream.core.EventStreamService;
/**
* @scr.component component.name="output.extensions.Ui.AdapterService.component" immediate="true"
* @scr.reference name="eventStreamService.service"
* interface="org.wso2.carbon.event.stream.core.EventStreamService" cardinality="1..1"
* policy="dynamic" bind="setEventStreamService" unbind="unsetEventStreamService"
*/
public class UILocalEventAdapterDS {
private static final Log log = LogFactory.getLog(UILocalEventAdapterDS.class);
/**
* initialize the ui adapter service here service here.
*
* @param context
*/
protected void activate(ComponentContext context) {
try {
OutputEventAdapterFactory uiEventAdapterFactory = new UIEventAdapterFactory();
context.getBundleContext().registerService(OutputEventAdapterFactory.class.getName(), uiEventAdapterFactory, null);
UIOutputCallbackControllerServiceImpl UIOutputCallbackRegisterServiceImpl = new UIOutputCallbackControllerServiceImpl();
context.getBundleContext().registerService(UIOutputCallbackControllerService.class.getName(),
UIOutputCallbackRegisterServiceImpl, null);
UIEventAdaptorServiceInternalValueHolder.registerUIOutputCallbackRegisterServiceInternal(
UIOutputCallbackRegisterServiceImpl);
if (log.isDebugEnabled()) {
log.debug("Successfully deployed the output ui adapter service");
}
} catch (RuntimeException e) {
log.error("Can not create the output ui adapter service ", e);
}
}
protected void setEventStreamService(EventStreamService eventStreamService) {
if (log.isDebugEnabled()) {
log.debug("Setting the EventStreamService reference for the UILocalEventAdaptor Service");
}
OutputAdaptorEventStreamServiceValueHolder.registerEventStreamService(eventStreamService);
}
protected void unsetEventStreamService(EventStreamService eventStreamService) {
if (log.isDebugEnabled()) {
log.debug("Un-Setting the EventStreamService reference for the UILocalEventAdaptor Service");
}
OutputAdaptorEventStreamServiceValueHolder.unregisterEventStreamService(eventStreamService);
}
}

@ -0,0 +1,62 @@
package org.wso2.carbon.event.output.adapter.extensions.ui.internal.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.websocket.Session;
import java.util.HashMap;
import java.util.Map;
/**
* This is wrapper class over the javax.websocket.Session implementation. This class contains additional attributes
* of the Session object derived from processing some of the (default) existing attributes.
* Ex: Query-String's [Key:Value] Map derived from the queryString attribute of the original class.
*/
public class CEPWebSocketSession {
private static final Log log = LogFactory.getLog(CEPWebSocketSession.class);
private static final String QUERY_STRING_SEPERATOR = "&";
private static final String QUERY_KEY_VALUE_SEPERATOR = "=";
private Map<String, String> queryParamValuePairs = null;
private Session session;
public CEPWebSocketSession(Session session) {
this.session = session;
setQueryParamValuePairs();
}
public Map<String, String> getQueryParamValuePairs() {
return queryParamValuePairs;
}
public Session getSession() {
return session;
}
/**
* Processes the queryString from the current instance's Session attribute and constructs a map of Query
* Key:Value pair.
*/
private void setQueryParamValuePairs() {
if (session.getQueryString() != null) {
String queryString = session.getQueryString();
String[] allQueryParamPairs = queryString.split(QUERY_STRING_SEPERATOR);
for (String keyValuePair : allQueryParamPairs) {
String[] thisQueryParamPair = keyValuePair.split(QUERY_KEY_VALUE_SEPERATOR);
if (thisQueryParamPair.length != 2) {
log.warn("Invalid query string [" + queryString + "] passed in.");
break;
}
if (queryParamValuePairs == null) {
queryParamValuePairs = new HashMap<>();
}
queryParamValuePairs.put(thisQueryParamPair[0], thisQueryParamPair[1]);
}
}
}
}

@ -0,0 +1,54 @@
/*
*
* Copyright (c) 2014-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.event.output.adapter.extensions.ui.internal.util;
/**
* This class contains the constants related to ui Output Event Adaptor.
*/
public class UIEventAdapterConstants {
private UIEventAdapterConstants() {
}
public static final String ADAPTER_TYPE_UI = "iot-ui";
public static final String ADAPTER_USAGE_TIPS_PREFIX = "ui.usage.tips_prefix";
public static final String ADAPTER_USAGE_TIPS_POSTFIX = "ui.usage.tips_postfix";
public static final String ADAPTER_UI_DEFAULT_OUTPUT_STREAM_VERSION = "1.0.0";
public static final String ADAPTER_UI_COLON = ":";
public static final int INDEX_ZERO = 0;
public static final int INDEX_ONE = 1;
public static final int INDEX_TWO = 2;
public static final int ADAPTER_MIN_THREAD_POOL_SIZE = 8;
public static final int ADAPTER_MAX_THREAD_POOL_SIZE = 100;
public static final int ADAPTER_EXECUTOR_JOB_QUEUE_SIZE = 2000;
public static final long DEFAULT_KEEP_ALIVE_TIME_IN_MILLIS = 20000;
public static final String ADAPTER_MIN_THREAD_POOL_SIZE_NAME = "minThread";
public static final String ADAPTER_MAX_THREAD_POOL_SIZE_NAME = "maxThread";
public static final String ADAPTER_KEEP_ALIVE_TIME_NAME = "keepAliveTimeInMillis";
public static final String ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME = "jobQueueSize";
public static final String ADAPTER_EVENT_QUEUE_SIZE_NAME = "eventQueueSize";
public static final int EVENTS_QUEUE_SIZE = 30;
public static final String CARBON_CONFIG_PORT_OFFSET_NODE = "Ports.Offset";
public static final int DEFAULT_HTTP_PORT = 9763;
public static final int DEFAULT_HTTPS_PORT = 9443;
}

@ -0,0 +1,22 @@
#
# 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.
#
output.event.stream.name=Output Stream Name
output.event.stream.version=Output Stream Version
ui.usage.tips_prefix=There must be an UI output adaptor for each stream to be visualized
ui.usage.tips_postfix= via Analytics Dashboard.

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<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/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.wso2.iot</groupId>
<artifactId>iot-extensions</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>das-extensions</artifactId>
<packaging>pom</packaging>
<name>WSO2 Carbon - DAS Extension</name>
<url>http://wso2.org</url>
<modules>
<module>org.wso2.carbon.event.input.adapter.extensions</module>
<module>org.wso2.carbon.event.output.adapter.extensions.ui</module>
<module>org.wso2.carbon.event.output.adapter.extensions.ui.endpoint</module>
</modules>
</project>

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<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>das-extensions-feature</artifactId>
<groupId>org.wso2.iot</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.event.adapter.extensions.server.feature</artifactId>
<packaging>pom</packaging>
<name>WSO2 Carbon - Event Input Adapter Server Feature</name>
<url>http://wso2.org</url>
<description>This feature contains the bundles required for Input Event Adapter functionality</description>
<dependencies>
<dependency>
<groupId>org.wso2.iot</groupId>
<artifactId>org.wso2.carbon.event.input.adapter.extensions</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.iot</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.extensions.ui</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wso2.iot</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.extensions.ui.endpoint</artifactId>
<version>${carbon.iot.device.mgt.version}</version>
<type>war</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/maven-shared-archive-resources/webapps/</outputDirectory>
<destFileName>secured-outputui.war</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.wso2.maven</groupId>
<artifactId>carbon-p2-plugin</artifactId>
<version>${carbon.p2.plugin.version}</version>
<executions>
<execution>
<id>4-p2-feature-generation</id>
<phase>package</phase>
<goals>
<goal>p2-feature-gen</goal>
</goals>
<configuration>
<id>org.wso2.carbon.event.adapter.extensions.server</id>
<propertiesFile>../../etc/feature.properties</propertiesFile>
<adviceFile>
<properties>
<propertyDef>org.wso2.carbon.p2.category.type:server</propertyDef>
<propertyDef>org.eclipse.equinox.p2.type.group:true</propertyDef>
</properties>
</adviceFile>
<bundles>
<bundleDef>
org.wso2.iot:org.wso2.carbon.event.input.adapter.extensions:${carbon.iot.device.mgt.version}
</bundleDef>
<bundleDef>
org.wso2.iot:org.wso2.carbon.event.output.adapter.extensions.ui:${carbon.iot.device.mgt.version}
</bundleDef>
</bundles>
<importFeatures>
<importFeatureDef>org.wso2.carbon.core.server:${carbon.kernel.version}</importFeatureDef>
<importFeatureDef>org.wso2.carbon.identity.jwt.client.extension:${carbon.device.mgt.version}</importFeatureDef>
</importFeatures>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,20 @@
#
# Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
#
# WSO2 Inc. licenses this file to you under the Apache License,
# Version 2.0 (the "License"); you may not use this file except
# in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
custom = true
root.agent=conf

@ -0,0 +1,4 @@
instructions.configure = \
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.event.adapter.extensions.server_${feature.version}/webapps/,target:${installFolder}/../../deployment/server/webapps/,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.event.adapter.extensions.server_${feature.version}/websocket-validation.properties,target:${installFolder}/../../conf/etc/websocket-validation.properties,overwrite:true);\

@ -0,0 +1,5 @@
tokenValidationEndpoint=https://localhost:9443/services/OAuth2TokenValidationService
username=admin
password=admin
maximumHttpConnectionPerHost=2
maximumTotalHttpConnection=100

@ -0,0 +1,40 @@
<?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/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.wso2.iot</groupId>
<artifactId>iot-extensions</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>das-extensions-feature</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - Device Management, DAS Extensions Feature</name>
<url>http://wso2.org</url>
<modules>
<module>org.wso2.carbon.event.adapter.extensions.server.feature</module>
</modules>
</project>

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<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/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.wso2.iot</groupId>
<artifactId>wso2iot-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-extensions</artifactId>
<packaging>pom</packaging>
<name>WSO2 Carbon - IoT Extensions</name>
<url>http://wso2.org</url>
<modules>
<module>components/das-extensions</module>
<module>features/das-extensions-feature</module>
</modules>
</project>

@ -384,10 +384,13 @@
org.apache.axis2.transport:org.apache.axis2.transport.mail.feature:${axis2-transports.wso2.version}
</featureArtifactDef>
<!--- MDM Features -->
<!--- IoT Server Features -->
<featureArtifactDef>
org.wso2.iot:org.wso2.iot.styles.feature:${carbon.iot.device.mgt.version}
</featureArtifactDef>
<featureArtifactDef>
org.wso2.iot:org.wso2.carbon.event.adapter.extensions.server.feature:${carbon.iot.device.mgt.version}
</featureArtifactDef>
<!-- Mediation Features -->
<featureArtifactDef>
@ -723,7 +726,7 @@
org.wso2.carbon.analytics:org.wso2.carbon.analytics.stream.persistence.server.feature:${carbon.analytics.version}
</featureArtifactDef>
<featureArtifactDef>
org.wso2.carbon.event-processing:org.wso2.carbon.event.execution.manager.feature:${carbon.event-processing.version}
org.wso2.carbon.analytics-common:org.wso2.carbon.event.execution.manager.feature:${carbon.analytics.common.version}
</featureArtifactDef>
<!-- START - Tools -->
<featureArtifactDef>
@ -746,21 +749,15 @@
<!-- MB Features -->
<featureArtifactDef>
org.wso2.carbon.messaging:org.wso2.carbon.andes.feature:${carbon.messaging.version}
</featureArtifactDef>
<featureArtifactDef>
org.wso2.mb:org.wso2.mb.styles.feature:${product.mb.version}
</featureArtifactDef>
<featureArtifactDef>
org.wso2.mb:org.wso2.stratos.mb.dashboard.ui.feature:${product.mb.version}
org.wso2.carbon.messaging:org.wso2.carbon.andes.server.feature:${carbon.messaging.version}
</featureArtifactDef>
<featureArtifactDef>
org.wso2.carbon.metrics:org.wso2.carbon.metrics.feature:${carbon.metrics.version}
</featureArtifactDef>
<!--JWT grant type handler-->
<!--<featureArtifactDef>-->
<!--org.wso2.carbon.identity:org.wso2.carbon.identity.oauth2.grant.jwt.feature:${identity.jwt.extension.version}-->
<!--</featureArtifactDef>-->
<featureArtifactDef>
org.wso2.carbon.identity:org.wso2.carbon.identity.oauth2.grant.jwt.feature:${identity.jwt.extension.version}
</featureArtifactDef>
</featureArtifacts>
</configuration>
</execution>
@ -784,6 +781,10 @@
<id>org.wso2.iot.styles.feature.group</id>
<version>${carbon.iot.device.mgt.version}</version>
</feature>
<feature>
<id>org.wso2.carbon.event.adapter.extensions.server.feature.group</id>
<version>${carbon.iot.device.mgt.version}</version>
</feature>
<!-- End of IoTServer Features -->
<!-- Device Management Features -->
@ -878,7 +879,6 @@
<id>org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature.group</id>
<version>${carbon.device.mgt.plugin.version}</version>
</feature>
<!-- Carbon Deployment Features -->
<feature>
<id>org.wso2.carbon.webapp.mgt.feature.group</id>
@ -1544,7 +1544,7 @@
</feature>
<feature>
<id>org.wso2.carbon.event.execution.manager.feature.group</id>
<version>${carbon.event-processing.version}</version>
<version>${carbon.analytics.common.version}</version>
</feature>
<!-- ************** END - EVENT PROCESSING FEATURES ************ -->
@ -1567,26 +1567,18 @@
<version>${carbon.dashboard.version}</version>
</feature>
<feature>
<id>org.wso2.carbon.messaging.andes.feature.group</id>
<id>org.wso2.carbon.andes.server.feature.group</id>
<version>${carbon.messaging.version}</version>
</feature>
<feature>
<id>org.wso2.mb.styles.feature.group</id>
<version>${product.mb.version}</version>
</feature>
<feature>
<id>org.wso2.stratos.mb.dashboard.ui.feature.group</id>
<version>${product.mb.version}</version>
</feature>
<feature>
<id>org.wso2.carbon.metrics.feature.group</id>
<version>${carbon.metrics.version}</version>
</feature>
<!--jwt grant type handler-->
<!--<feature>-->
<!--<id>org.wso2.carbon.identity.oauth2.grant.jwt.feature.group</id>-->
<!--<version>${identity.jwt.extension.version}</version>-->
<!--</feature>-->
<feature>
<id>org.wso2.carbon.identity.oauth2.grant.jwt.feature.group</id>
<version>${identity.jwt.extension.version}</version>
</feature>
</features>
</configuration>
</execution>

@ -39,6 +39,7 @@
<modules>
<module>modules/tools</module>
<module>modules/iotserver-ui</module>
<module>modules/iot-extensions</module>
<module>modules/features</module>
<module>modules/p2-profile-gen</module>
<module>modules/distribution</module>
@ -493,16 +494,16 @@
<artifactId>org.wso2.carbon.policy.mgt.core</artifactId>
<version>${carbon.device.mgt.version}</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.wso2.carbon.devicemgt</groupId>-->
<!--<artifactId>org.wso2.carbon.device.mgt.analytics</artifactId>-->
<!--<version>${carbon.device.mgt.version}</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<version>${carbon.device.mgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
<version>${carbon.device.mgt.version}</version>
</dependency>
<!--MDM dependencies-->
<dependency>
@ -978,6 +979,85 @@
<version>${cipher.tool.version}</version>
</dependency>
<!--http client dependencies-->
<dependency>
<groupId>org.apache.httpcomponents.wso2</groupId>
<artifactId>httpcore</artifactId>
<version>${httpcore.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.orbit.org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
<version>${json-simple.version}</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>${json.path.version}</version>
</dependency>
<!--websocket dependency-->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>${javax.websocket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-websocket-api</artifactId>
<version>${tomcat.websocket.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>${javax.version}</version>
</dependency>
<!--Das extension dependency-->
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.core</artifactId>
<version>${carbon.analytics.common.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.input.adapter.core</artifactId>
<version>${carbon.analytics.common.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.stream.core</artifactId>
<version>${carbon.analytics.common.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.databridge.commons</artifactId>
<version>${carbon.analytics.common.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.iot</groupId>
<artifactId>org.wso2.carbon.event.input.adapter.extensions</artifactId>
<version>${carbon.iot.device.mgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.iot</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.extensions.ui</artifactId>
<version>${carbon.iot.device.mgt.version}</version>
</dependency>
<!--mqtt-->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>${eclipse.paho.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -1027,6 +1107,7 @@
<!-- Carbon Identity -->
<carbon.identity.version>5.0.7</carbon.identity.version>
<carbon.identity.version.range>[5.0.7, 6.0.0)</carbon.identity.version.range>
<!-- Carbon Multi-tenancy -->
<carbon.multitenancy.version>4.5.0</carbon.multitenancy.version>
@ -1054,7 +1135,7 @@
<carbon.mediation.version>4.5.1</carbon.mediation.version>
<!-- Carbon Analytics Common (DAS) -->
<carbon.analytics.common.version>5.0.11</carbon.analytics.common.version>
<carbon.analytics.common.version>5.0.12-alpha</carbon.analytics.common.version>
<!-- Tomcat -->
<orbit.tomcat.version>7.0.59.wso2v1</orbit.tomcat.version>
@ -1069,11 +1150,11 @@
<axis2-transports.wso2.version>1.1.0-wso2v17</axis2-transports.wso2.version>
<!--DAS-->
<carbon.analytics.version>1.0.5</carbon.analytics.version>
<carbon.analytics.version>1.0.6-ALPHA</carbon.analytics.version>
<cipher.tool.version>1.0.0-wso2v3</cipher.tool.version>
<carbon.dashboard.version>1.0.13</carbon.dashboard.version>
<shindig.version>1.0.0</shindig.version>
<carbon.event-processing.version>2.0.12</carbon.event-processing.version>
<carbon.event-processing.version>2.0.13-alpha</carbon.event-processing.version>
<carbon.data.version>4.3.4</carbon.data.version>
<orbit.version.commons-httpclient>3.1.0.wso2v2</orbit.version.commons-httpclient>
@ -1112,12 +1193,26 @@
<project.scm.id>github-scm</project.scm.id>
<!-- MB Features -->
<carbon.messaging.version>3.1.0</carbon.messaging.version>
<product.mb.version>3.1.0</product.mb.version>
<carbon.messaging.version>3.1.2</carbon.messaging.version>
<product.mb.version>3.1.2</product.mb.version>
<carbon.metrics.version>1.2.0</carbon.metrics.version>
<!--JWT grant type extension feature-->
<identity.jwt.extension.version>1.0.0</identity.jwt.extension.version>
<!--http client version-->
<httpclient.version>4.3.1.wso2v2</httpclient.version>
<httpclient.version.range>[4.3.1, 5.0.0)</httpclient.version.range>
<httpcore.version>4.3.3.wso2v1</httpcore.version>
<!--json version-->
<json-simple.version>1.1.wso2v1</json-simple.version>
<json.path.version>0.9.1</json.path.version>
<!--websocket related lib versions-->
<tomcat.websocket.version>7.0.54</tomcat.websocket.version>
<javax.websocket.version>1.0</javax.websocket.version>
<javax.version>2.0</javax.version>
<!--mqtt version-->
<eclipse.paho.version>1.0.2</eclipse.paho.version>
</properties>
<scm>
@ -1305,16 +1400,6 @@
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>wso2-staging</id>
<name>WSO2 internal Repository</name>
<url>http://maven.wso2.org/nexus/content/repositories/orgwso2carbonapimgt-174/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</releases>
</repository>
</repositories>
</project>

Loading…
Cancel
Save