<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~~~~~~licensing~~~~~~
  events-rest
  ==========
  Copyright (C) 2020 - 2023 EmDev LLC
  ==========
  You may not use this file except in accordance with the License Terms of the Copyright
  Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
  rights to the Software and any copies are the property of the Copyright Holder. Unless
  it is explicitly allowed the Copyright Holder, the User is prohibited from using the
  Software for commercial purposes to provide services to third parties.
  
  The Copyright Holder hereby declares that the Software is provided on an "AS IS".
  Under no circumstances does the Copyright Holder guarantee or promise that the
  Software provided by him will be suitable or not suitable for the specific purposes
  of the User, that the Software will meet all commercial and personal subjective
  expectations of the User, that the Software will work properly, without technical
  errors, quickly and uninterruptedly.
  
  Under no circumstances shall the Copyright Holder or its Affiliates is not liable
  to the User for any direct or indirect losses of the User, his expenses or actual
  damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
  or damage to data, property, etc.
  ~~~~~~/licensing~~~~~~
  -->

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
           xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf"
           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">

    <cm:property-placeholder
            persistent-id="ru.entaxy.esb.system.event.rest" update-strategy="reload">
        <cm:default-properties>
            <cm:property name="service.host" value="http://localhost"/>

            <cm:property name="service.port.management" value="9090"/>
            <cm:property name="service.root.path.management" value="/topic-management"/>

            <cm:property name="service.port.subscription" value="9092"/>
            <cm:property name="service.root.path.subscription" value="/topic-subscription"/>

            <cm:property name="mode.dev" value="false"/>
        </cm:default-properties>
    </cm:property-placeholder>

    <reference id="pooledConnectionFactory" interface="javax.jms.ConnectionFactory"/>

    <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
        <property name="connectionFactory" ref="pooledConnectionFactory"/>
    </bean>

    <bean id="topicProcessor" class="ru.entaxy.esb.system.core.events.rest.TopicProcessor"/>

    <reference id="systemInterceptor"
               interface="org.apache.cxf.phase.PhaseInterceptor"
               filter="(type=system)"
               timeout="30000"
               availability="mandatory"/>
    <reference id="serviceInterceptor"
               interface="org.apache.cxf.phase.PhaseInterceptor"
               filter="(type=service)"
               timeout="30000"
               availability="mandatory"/>
    <reference id="authInterceptor" interface="org.apache.cxf.phase.PhaseInterceptor"
               filter="(type=authentication)"/>

    <camelcxf:rsServer id="rsManagement"
                       address="${service.host}:${service.port.management}${service.root.path.management}"
                       serviceClass="ru.entaxy.esb.system.core.events.rest.ManagementService"
                       loggingFeatureEnabled="true" loggingSizeLimit="50">
        <camelcxf:inInterceptors>
            <ref component-id="authInterceptor"/>
            <ref component-id="serviceInterceptor"/>
        </camelcxf:inInterceptors>
    </camelcxf:rsServer>

    <camelcxf:rsServer id="rsSubscription"
                       address="${service.host}:${service.port.subscription}${service.root.path.subscription}"
                       serviceClass="ru.entaxy.esb.system.core.events.rest.SubscriptionService"
                       loggingFeatureEnabled="true" loggingSizeLimit="50">
        <camelcxf:inInterceptors>
            <ref component-id="authInterceptor"/>
            <ref component-id="systemInterceptor"/>
        </camelcxf:inInterceptors>
    </camelcxf:rsServer>


    <bean id="subscriptionResponse" class="ru.entaxy.esb.system.core.events.rest.response.SubscriptionResponse"/>

    <bean id="responseAggregator" class="ru.entaxy.esb.system.core.events.rest.aggregation.ResponseAggregator"/>

    <reference id="permissionChecker"
               interface="ru.entaxy.esb.system.core.permission.handler.PermissionChecker"
               timeout="30000"
               availability="mandatory"/>

    <camelContext id="rest-context" xmlns="http://camel.apache.org/schema/blueprint">

        <route id="eventManagement">
            <from uri="cxfrs:bean:rsManagement?bindingStyle=SimpleConsumer"/>
            <log message="Events topic management operation ${header.operationName}" loggingLevel="DEBUG"/>
            <toD uri="direct:${header.operationName}"/>
        </route>

        <route id="eventSubscription">
            <from uri="cxfrs:bean:rsSubscription?bindingStyle=SimpleConsumer"/>
            <log message="Events topic subscription operation ${header.operationName}" loggingLevel="DEBUG"/>
            <toD uri="direct:${header.operationName}"/>
        </route>

        <route id="topicCreate">
            <from uri="direct:create"/>
            <log message="Received - create: ${body}" loggingLevel="TRACE"/>

            <!--        JSON -->
            <!--        { "topicName": "boomNews" } -->

            <doTry>
                <setProperty name="topicName">
                    <jsonpath>$.topicName</jsonpath>
                </setProperty>
                <setProperty name="possibleSubscribers">
                    <jsonpath suppressExceptions="true">$.possibleSubscribers</jsonpath>
                </setProperty>
                <setProperty name="possiblePublishers">
                    <jsonpath suppressExceptions="true">$.possiblePublishers</jsonpath>
                </setProperty>
                <doCatch>
                    <exception>org.apache.camel.ExpressionEvaluationException</exception>
                    <log message="CreateTopic: Body is not JSON" loggingLevel="ERROR"/>
                </doCatch>
            </doTry>

            <choice>
                <when>
                    <simple>${exchangeProperty.topicName} != null &amp;&amp; ${exchangeProperty.topicName} != ""
                        &amp;&amp; ${header.X-ForwardedUser} != null &amp;&amp; ${header.X-ForwardedUser} != ""
                    </simple>
                    <log message="CreateTopic: ${exchangeProperty.topicName}" loggingLevel="TRACE"/>

                    <doTry>
                        <bean
                                ref="topicProcessor"
                                method="registerTopic(${header.X-ForwardedUser}, ${exchangeProperty.topicName}, ${exchangeProperty.possibleSubscribers}, ${exchangeProperty.possiblePublishers})"/>
                        <choice>
                            <when>
                                <simple>${exchangeProperty.DELETED}</simple>
                                <!--							Restore topic  -->
                                <to uri="direct:restoreSubscriberRoutes"/>
                                <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                    <constant>200</constant>
                                </setHeader>
                            </when>
                            <otherwise>
                                <setProperty name="BODY_HOLDER">
                                    <simple>${body}</simple>
                                </setProperty>
                                <!-- 							Create topic in broker						 -->
                                <setBody>
                                    <constant>null</constant>
                                </setBody>
                                <toD uri="jms:topic:${exchangeProperty.topicName}?exchangePattern=InOnly"/>

                                <setBody>
                                    <simple>${exchangeProperty.BODY_HOLDER}</simple>
                                </setBody>
                                <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                    <constant>201</constant>
                                </setHeader>
                            </otherwise>
                        </choice>

                        <marshal>
                            <json library="Gson"/>
                        </marshal>

                        <doCatch>
                            <exception>ru.entaxy.esb.system.core.events.rest.exception.TopicAlreadyExist</exception>
                            <setBody>
                                <simple>{ "title": "Topic already exists", "topicName": "${exchangeProperty.topicName}"
                                    }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>200</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>java.lang.Exception</exception>
                            <log message="Subscription: Unknown exception ${exception.stacktrace}"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Internal Server Error", "detail": "Unknown exception", "reason":
                                    "${exception.message}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>500</constant>
                            </setHeader>
                        </doCatch>
                    </doTry>

                </when>
                <otherwise>
                    <log message="CreateTopic: Bad request" loggingLevel="ERROR"/>
                    <setBody>
                        <simple>{ "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or login
                            not defined" }
                        </simple>
                    </setBody>
                    <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                        <constant>400</constant>
                    </setHeader>
                </otherwise>
            </choice>

        </route>

        <route>
            <from uri="direct:checkTopic"/>
            <doTry>
                <bean
                        ref="topicProcessor"
                        method="getTopic(${exchangeProperty.topicName})"/>

                <setProperty name="DELETED">
                    <simple resultType="boolean">${body.deleted}</simple>
                </setProperty>

                <doCatch>
                    <exception>java.lang.Exception</exception>
                    <!-- do nothing -->
                </doCatch>
            </doTry>
        </route>


        <route id="topicUpdate">
            <from uri="direct:update"/>
            <log message="Received - update: ${body}" loggingLevel="TRACE"/>
            <doTry>
                <setProperty name="topicName">
                    <jsonpath>$.topicName</jsonpath>
                </setProperty>
                <setProperty name="possibleSubscribers">
                    <jsonpath suppressExceptions="true">$.possibleSubscribers</jsonpath>
                </setProperty>
                <setProperty name="possiblePublishers">
                    <jsonpath suppressExceptions="true">$.possiblePublishers</jsonpath>
                </setProperty>
                <doCatch>
                    <exception>org.apache.camel.ExpressionEvaluationException</exception>
                    <log message="UpdateTopic: Body is not JSON ${exception.stacktrace}" loggingLevel="ERROR"/>
                </doCatch>
            </doTry>

            <choice>
                <when>
                    <simple>${exchangeProperty.topicName} != null &amp;&amp; ${exchangeProperty.topicName} != ""
                        &amp;&amp; ${header.X-ForwardedUser} != null &amp;&amp; ${header.X-ForwardedUser} != ""
                    </simple>
                    <log message="UpdateTopic: ${exchangeProperty.topicName}" loggingLevel="TRACE"/>

                    <doTry>
                        <bean
                                ref="topicProcessor"
                                method="getTopic(${exchangeProperty.topicName})"/>

                        <setProperty name="DELETED">
                            <simple resultType="boolean">${body.deleted}</simple>
                        </setProperty>

                        <bean
                                ref="topicProcessor"
                                method="updateTopic(${header.X-ForwardedUser}, ${exchangeProperty.topicName}, ${exchangeProperty.possibleSubscribers}, ${exchangeProperty.possiblePublishers})"/>

                        <when>
                            <simple>${exchangeProperty.DELETED}</simple>
                            <to uri="direct:restoreSubscriberRoutes"/>
                        </when>

                        <marshal>
                            <json library="Gson"/>
                        </marshal>
                        <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                            <constant>200</constant>
                        </setHeader>

                        <doCatch>
                            <exception>java.lang.Exception</exception>
                            <log message="Subscription: Unknown exception ${exception.stacktrace}"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Internal Server Error", "detail": "Unknown exception", "reason":
                                    "${exception.message}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>500</constant>
                            </setHeader>
                        </doCatch>
                    </doTry>

                </when>
                <otherwise>
                    <log message="CreateTopic: Bad request" loggingLevel="ERROR"/>
                    <setBody>
                        <simple>{ "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or login
                            not defined" }
                        </simple>
                    </setBody>
                    <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                        <constant>400</constant>
                    </setHeader>
                </otherwise>
            </choice>

        </route>

        <route id="restoreSubscriberRoutes">
            <from uri="direct:restoreSubscriberRoutes"/>
            <setProperty name="BODY_HOLDER">
                <simple>${body}</simple>
            </setProperty>

            <bean
                    ref="topicProcessor"
                    method="getTopic(${exchangeProperty.topicName})"/>
            <bean
                    ref="topicProcessor"
                    method="getTopicSubscriptions(${body})"/>

            <to uri="direct-vm:prepareSubscriberRoutes"/>

            <setBody>
                <simple>${exchangeProperty.BODY_HOLDER}</simple>
            </setBody>
        </route>

        <route id="topicDelete">
            <from uri="direct:delete"/>
            <log message="Received - delete: ${body}" loggingLevel="TRACE"/>
            <doTry>
                <setProperty name="topicName">
                    <jsonpath>$.topicName</jsonpath>
                </setProperty>
                <doCatch>
                    <exception>org.apache.camel.ExpressionEvaluationException</exception>
                    <log message="CreateTopic: Body is not JSON" loggingLevel="ERROR"/>
                </doCatch>
            </doTry>

            <choice>
                <when>
                    <simple>${exchangeProperty.topicName} != null &amp;&amp; ${exchangeProperty.topicName} != ""
                        &amp;&amp; ${header.X-ForwardedUser} != null &amp;&amp; ${header.X-ForwardedUser} != ""
                    </simple>
                    <log message="DeleteTopic: ${exchangeProperty.topicName}" loggingLevel="TRACE"/>

                    <doTry>
                        <bean
                                ref="topicProcessor"
                                method="getActualTopic(${exchangeProperty.topicName})"/>

                        <bean
                                ref="topicProcessor"
                                method="getTopicSubscriptions(${body})"/>

                        <to uri="direct-vm:deleteSubscriberRoutes"/>

                        <bean
                                ref="topicProcessor"
                                method="deleteTopic(${exchangeProperty.topicName})"/>

                        <bean
                                beanType="ru.entaxy.esb.system.core.events.rest.response.JsonSuccessResponse"
                                method="getInstance('Topic mark as deleted', ${exchangeProperty.topicName})"/>
                        <marshal>
                            <json library="Gson"/>
                        </marshal>
                        <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                            <constant>200</constant>
                        </setHeader>

                        <doCatch>
                            <exception>ru.entaxy.esb.system.core.events.rest.exception.TopicNotFound</exception>
                            <setBody>
                                <simple>{ "title": "Topic not registered", "topicName": "${exchangeProperty.topicName}"
                                    }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>400</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>java.lang.Exception</exception>
                            <log message="Subscription: Unknown exception ${exception.stacktrace}"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Internal Server Error", "detail": "Unknown exception", "reason":
                                    "${exception.message}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>500</constant>
                            </setHeader>
                        </doCatch>
                    </doTry>

                </when>
                <otherwise>
                    <log message="CreateTopic: Bad request" loggingLevel="ERROR"/>
                    <setBody>
                        <simple>{ "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or login
                            not defined" }
                        </simple>
                    </setBody>
                    <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                        <constant>400</constant>
                    </setHeader>
                </otherwise>
            </choice>
        </route>

        <route id="topicClean">
            <from uri="direct:clean"/>
            <log message="Received - clean command" loggingLevel="TRACE"/>

            <doTry>
                <to uri="direct-vm:cleanProcess"/>

                <bean
                        beanType="ru.entaxy.esb.system.core.events.rest.response.CleanResponse"
                        method="getInstance('Cleaned', ${body})"/>

                <marshal>
                    <json library="Gson"/>
                </marshal>
                <doCatch>
                    <exception>java.lang.Exception</exception>
                    <log message="Subscription: Unknown exception ${exception.stacktrace}" loggingLevel="ERROR"/>
                    <setBody>
                        <simple>{ "title": "Internal Server Error", "detail": "Unknown exception", "reason":
                            "${exception.message}" }
                        </simple>
                    </setBody>
                    <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                        <constant>500</constant>
                    </setHeader>
                </doCatch>
            </doTry>
        </route>

        <route id="topicSubscribe">
            <from uri="direct:subscribe"/>
            <log message="Received - subscribe: ${body}" loggingLevel="TRACE"/>

            <!-- JSON -->
            <!--        {"topicName": "boom","subscriptionType": "PUSH"("PULL")} -->

            <setProperty name="subscribe">
                <simple resultType="java.lang.Boolean">true</simple>
            </setProperty>

            <to uri="direct:prepareSubscription"/>
        </route>

        <route id="topicUnsubscribe">
            <from uri="direct:unsubscribe"/>
            <convertBodyTo type="java.lang.String"/>
            <log message="Received - unsubscribe: ${body}" loggingLevel="TRACE"/>

            <!-- JSON -->
            <!--        {"topicName": "boom"} -->

            <setProperty name="subscribe">
                <simple resultType="java.lang.Boolean">false</simple>
            </setProperty>

            <to uri="direct:prepareSubscription"/>
        </route>

        <route id="prepareSubscription">
            <from uri="direct:prepareSubscription"/>

            <doTry>
                <setProperty name="systemUuids">
                    <jsonpath>$.systemUuids</jsonpath>
                </setProperty>
                <doCatch>
                    <exception>org.apache.camel.ExpressionEvaluationException</exception>
                </doCatch>
            </doTry>

            <doTry>
                <setProperty name="topicName">
                    <jsonpath>$.topicName</jsonpath>
                </setProperty>
                <doCatch>
                    <exception>org.apache.camel.ExpressionEvaluationException</exception>
                    <log message="CreateSubscription: Body is not JSON" loggingLevel="ERROR"/>
                </doCatch>
            </doTry>

            <choice>
                <when>
                    <simple>${exchangeProperty.systemUuids} != null &amp;&amp; ${exchangeProperty.systemUuids} != ""
                    </simple>
                    <!--                      TODO  improve get serviceName-->
                    <setProperty name="serviceName">
                        <simple>{{service.root.path.subscription}}</simple>
                    </setProperty>
                    <setProperty name="serviceName">
                        <simple>${exchangeProperty.serviceName.substring(1)}</simple>
                    </setProperty>

                    <log message="ServiceName ${exchangeProperty.serviceName}" loggingLevel="DEBUG"/>
                    <log message="X-ForwardedUserId ${headers.X-ForwardedUserId}" loggingLevel="DEBUG"/>

                    <setProperty name="permissionCheck">
                        <simple>bean:permissionChecker?method=check(${headers.X-ForwardedUserId}, 'account',
                            ${exchangeProperty.serviceName}, 'service', 'manage')
                        </simple>
                    </setProperty>

                    <!-- 					<toD uri="permission:checkException?objectId=${headers.X-ForwardedUserId}&amp;objectType=account&amp;subjectId=${exchangeProperty.serviceName}&amp;subjectType=service&amp;action=manage" /> -->

                    <choice>
                        <when>
                            <simple>${exchangeProperty.permissionCheck}</simple>

                            <split strategyRef="responseAggregator">
                                <jsonpath>$.systemUuids</jsonpath>

                                <log message="Subscribe ${body}" loggingLevel="TRACE"/>
                                <doTry>
                                    <setHeader name="X-SystemUuid">
                                        <jsonpath>$.systemUuid</jsonpath>
                                    </setHeader>
                                    <setProperty name="subscriptionType">
                                        <jsonpath>$.subscriptionType</jsonpath>
                                    </setProperty>
                                    <doCatch>
                                        <exception>org.apache.camel.ExpressionEvaluationException</exception>
                                        <log message="CreateSubscription: Body is not JSON" loggingLevel="ERROR"/>
                                    </doCatch>
                                </doTry>

                                <to uri="direct:subscription"/>
                            </split>

                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>200</constant>
                            </setHeader>

                            <log message="X-SystemUuid after process ${headers.X-SystemUuid}" loggingLevel="TRACE"/>
                        </when>
                        <otherwise>
                            <log message="Subscription: Account ${headers.X-ForwardedUser} without MANAGE permission"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Forbidden", "detail": "No MANAGE permission" }</simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>403</constant>
                            </setHeader>
                        </otherwise>
                    </choice>

                </when>

                <otherwise>
                    <doTry>
                        <setProperty name="subscriptionType">
                            <jsonpath>$.subscriptionType</jsonpath>
                        </setProperty>
                        <doCatch>
                            <exception>org.apache.camel.ExpressionEvaluationException</exception>
                            <!-- 				       			<log message="CreateSubscription: Body is not JSON" loggingLevel="ERROR"/> -->
                        </doCatch>
                    </doTry>

                    <to uri="direct:subscription"/>
                </otherwise>
            </choice>
        </route>

        <route id="subscription">
            <from uri="direct:subscription"/>

            <choice>
                <when>
                    <simple>${exchangeProperty.topicName} != null &amp;&amp; ${exchangeProperty.topicName} != ""
                        &amp;&amp; ${header.X-SystemUuid} != null &amp;&amp; ${header.X-SystemUuid} != ""
                    </simple>
                    <log message="Subscription: subscribe ${exchangeProperty.subscribe} to ${exchangeProperty.topicName} system ${header.X-SystemUuid}"
                         loggingLevel="INFO"/>

                    <doTry>
                        <choice>
                            <when>
                                <simple>${exchangeProperty.subscribe}</simple>

                                <log message="Title ${bean:subscriptionResponse.title}" loggingLevel="TRACE"/>

                                <to uri="direct:checkExistingSubscription"/>

                                <setProperty name="responseTitle">
                                    <constant>Subscription created</constant>
                                </setProperty>

                                <when>
                                    <simple>${exchangeProperty.ALREADY_EXIST} == false</simple>
                                    <bean ref="topicProcessor"
                                          method="subscribe(${header.X-SystemUuid}, ${header.topicName}, ${exchangeProperty.subscriptionType})"/>
                                    <to uri="direct-vm:prepareSubscriberConsumer"/>
                                </when>
                                <when>
                                    <simple>${exchangeProperty.DELETED}</simple>
                                    <bean ref="topicProcessor" method="restoreSubscription(${body})"/>

                                    <to uri="direct-vm:prepareSubscriberRoute"/>
                                    <setProperty name="responseTitle">
                                        <constant>Subscription restored</constant>
                                    </setProperty>
                                </when>

                                <bean
                                        beanType="ru.entaxy.esb.system.core.events.rest.response.SubscriptionResponse"
                                        method="getInstance(${exchangeProperty.responseTitle}, ${exchangeProperty.topicName}, ${header.X-SystemUuid}, ${exchangeProperty.subscriptionType})"/>

                                <marshal>
                                    <json library="Gson"/>
                                </marshal>
                                <!-- 									<setBody><simple>{ "title": "Subscription created", "topicName": "${exchangeProperty.topicName}", "systemUUID": "${header.X-SystemUuid}", "subscriptionType": "${exchangeProperty.subscriptionType}"}</simple></setBody> -->
                                <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                    <constant>201</constant>
                                </setHeader>
                            </when>
                            <otherwise>
                                <bean ref="topicProcessor"
                                      method="unsubscribe(${header.X-SystemUuid}, ${exchangeProperty.topicName})"/>
                                <to uri="direct-vm:deleteSubscriberRoute"/>

                                <bean
                                        beanType="ru.entaxy.esb.system.core.events.rest.response.SubscriptionResponse"
                                        method="getInstance('Subscription mark as deleted', ${exchangeProperty.topicName}, ${header.X-SystemUuid}, ${null})"/>

                                <marshal>
                                    <json library="Gson"/>
                                </marshal>
                                <!-- 										<setBody><simple>{ "title": "Subscription deleted", "topicName": "${exchangeProperty.topicName}", "systemUUID": "${header.X-SystemUuid}"}</simple></setBody> -->
                                <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                    <constant>200</constant>
                                </setHeader>
                            </otherwise>
                        </choice>

                        <doCatch>
                            <exception>ru.entaxy.esb.system.core.events.rest.exception.SubscriptionNotFound</exception>
                            <setBody>
                                <simple>{ "title": "Subscription not found", "topicName":
                                    "${exchangeProperty.topicName}", "systemUUID": "${header.X-SystemUuid}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>404</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>ru.entaxy.esb.system.core.events.rest.exception.TopicNotFound</exception>
                            <setBody>
                                <simple>{ "title": "Topic not registered", "topicName": "${exchangeProperty.topicName}"
                                    }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>400</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>ru.entaxy.esb.system.core.events.rest.exception.SystemNotFound</exception>
                            <log message="Subscription: System not found ${header.X-SystemUuid}" loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Internal Server Error", "detail": "System not found
                                    ${header.X-SystemUuid}", "reason": "${exception.message}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>500</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>ru.entaxy.esb.system.core.events.rest.exception.UnknownSubscriptionType
                            </exception>
                            <log message="Subscription: Unknown subscription type ${header.subscriptionType}"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Internal Server Error", "detail": "Unknown subscription type
                                    ${exchangeProperty.subscriptionType}", "reason": "${exception.message}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>500</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>javax.ws.rs.ForbiddenException</exception>
                            <log message="Subscription: No permission to subscribe to topic ${header.topicName} for system ${header.X-SystemName}"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Forbidden", "detail": "No permission to subscribe for system
                                    ${header.X-SystemUuid}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>403</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>java.lang.Exception</exception>
                            <log message="Subscription: Unknown exception ${exception.stacktrace}"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Internal Server Error", "detail": "Unknown exception", "reason":
                                    "${exception.message}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>500</constant>
                            </setHeader>
                        </doCatch>
                    </doTry>
                </when>
                <otherwise>
                    <log message="Subscription: Bad request" loggingLevel="ERROR"/>
                    <setBody>
                        <simple>{ "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or system
                            not defined" }
                        </simple>
                    </setBody>
                    <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                        <constant>400</constant>
                    </setHeader>
                </otherwise>
            </choice>
        </route>

        <route id="checkExistingSubscription">
            <from uri="direct:checkExistingSubscription"/>
            <bean ref="topicProcessor"
                  method="getExistingSubscription(${header.X-SystemUuid}, ${exchangeProperty.topicName})"/>

            <setProperty name="ALREADY_EXIST">
                <simple resultType="java.lang.Boolean">false</simple>
            </setProperty>
            <when>
                <simple>${body} != null &amp;&amp; ${exchangeProperty.subscriptionType} != null</simple>
                <choice>
                    <when>
                        <simple>${body.getType().equalsName(${exchangeProperty.subscriptionType})} == false</simple>
                        <to uri="direct-vm:deleteSubscriberConsumer"/>
                    </when>
                    <otherwise>
                        <setProperty name="ALREADY_EXIST">
                            <simple resultType="java.lang.Boolean">true</simple>
                        </setProperty>
                    </otherwise>
                </choice>
            </when>

            <when>
                <simple>${body} != null</simple>
                <setProperty name="DELETED">
                    <simple resultType="java.lang.Boolean">${body.deleted}</simple>
                </setProperty>
            </when>
        </route>

        <route id="publishing">
            <from uri="direct:publish"/>
            <log message="Received - publish: ${body}" loggingLevel="TRACE"/>
            <!--        JSON -->
            <!--        { "topicName": "boomNews", "message": "messageText" } -->

            <doTry>
                <setProperty name="topicName">
                    <jsonpath>$.topicName</jsonpath>
                </setProperty>
                <setProperty name="message">
                    <jsonpath>$.message</jsonpath>
                </setProperty>
                <doCatch>
                    <exception>org.apache.camel.ExpressionEvaluationException</exception>
                    <log message="Publishing: Body is not JSON" loggingLevel="ERROR"/>
                </doCatch>
            </doTry>

            <choice>
                <when>
                    <simple>${exchangeProperty.topicName} != null &amp;&amp; ${exchangeProperty.topicName} != ""
                        &amp;&amp; ${exchangeProperty.message} != null &amp;&amp; ${exchangeProperty.message} != ""
                        &amp;&amp; ${header.X-SystemUuid} != null &amp;&amp; ${header.X-SystemUuid} != ""
                    </simple>

                    <doTry>
                        <log
                                message="Publishing: ${exchangeProperty.topicName} message ${exchangeProperty.message}"
                                loggingLevel="DEBUG"/>

                        <bean ref="topicProcessor" method="getActualTopic(${header.topicName})"/>

                        <toD uri="permission:checkException?objectId=${body.getId()}&amp;objectType=event-topic&amp;subjectId=${header.X-SystemId}&amp;subjectType=system&amp;action=publish"/>

						<setHeader name="ENTAXY_Source">
							<simple>${header.X-SystemName}</simple>
						</setHeader>
						<setHeader name="ENTAXY_SourceType">
							<constant>system.name</constant>
						</setHeader>

                        <setBody>
                            <simple>${exchangeProperty.message}</simple>
                        </setBody>
                        <toD uri="jms:topic:${exchangeProperty.topicName}?exchangePattern=InOnly"/>

                        <bean
                                beanType="ru.entaxy.esb.system.core.events.rest.response.JsonSuccessResponse"
                                method="getInstance('Message published', ${exchangeProperty.topicName})"/>

                        <marshal>
                            <json library="Gson"/>
                        </marshal>
                        <!-- 						<setBody> -->
                        <!-- 							<simple>{ "title": "Message published", "topicName": "${exchangeProperty.topicName}" }</simple> -->
                        <!-- 						</setBody> -->
                        <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                            <constant>200</constant>
                        </setHeader>

                        <doCatch>
                            <exception>ru.entaxy.esb.system.core.events.rest.exception.TopicNotFound</exception>
                            <setBody>
                                <simple>{ "title": "Topic not registered", "topicName": "${exchangeProperty.topicName}"
                                    }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>400</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>java.lang.IllegalAccessException</exception>
                            <log message="Subscription: No permission to publish to topic ${header.topicName} for system ${header.X-SystemName}"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Forbidden", "detail": "No permission to publishing" }</simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>403</constant>
                            </setHeader>
                        </doCatch>
                        <doCatch>
                            <exception>java.lang.Exception</exception>
                            <log message="Subscription: Unknown exception ${exception.stacktrace}"
                                 loggingLevel="ERROR"/>
                            <setBody>
                                <simple>{ "title": "Internal Server Error", "detail": "Unknown exception", "reason":
                                    "${exception.message}" }
                                </simple>
                            </setBody>
                            <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                                <constant>500</constant>
                            </setHeader>
                        </doCatch>
                    </doTry>

                </when>
                <otherwise>
                    <log message="Publishing: Bad request ${body}"
                         loggingLevel="ERROR"/>
                    <setBody>
                        <simple>{ "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or system
                            not defined" }
                        </simple>
                    </setBody>
                    <setHeader name="Exchange.HTTP_RESPONSE_CODE">
                        <constant>400</constant>
                    </setHeader>
                </otherwise>
            </choice>
        </route>

    </camelContext>

</blueprint>
