Package org.switchyard.component.camel.common.handler

Source Code of org.switchyard.component.camel.common.handler.InboundHandler

/*
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors.
*
* 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.switchyard.component.camel.common.handler;

import java.net.URI;

import javax.xml.namespace.QName;

import org.apache.camel.model.RouteDefinition;
import org.switchyard.Exchange;
import org.switchyard.ServiceDomain;
import org.switchyard.SwitchYardException;
import org.switchyard.common.camel.SwitchYardCamelContext;
import org.switchyard.component.camel.common.CamelConstants;
import org.switchyard.component.camel.common.CommonCamelLogger;
import org.switchyard.component.camel.common.CommonCamelMessages;
import org.switchyard.component.camel.common.model.CamelBindingModel;
import org.switchyard.component.camel.common.transaction.TransactionHelper;
import org.switchyard.deploy.BaseServiceHandler;
import org.switchyard.runtime.event.ExchangeCompletionEvent;

/**
* An ExchangeHandler that acts as a gateway/entrypoint for Camel Components.
*
* This gives access to all component of Apache Camel and works by creating a
* Camel route that looks something like this
* <pre>
* from("CamelComponentURI").to("switchyard://serviceName");
* </pre>
*
* @author Daniel Bevenius
*
* @param <T> Type of the binding.
*/
public class InboundHandler<T extends CamelBindingModel> extends BaseServiceHandler {

    private static final String NAMESPACE_POLICY_REF = "org.switchyard.namespaceContextPolicy";

    private final T _camelBindingModel;
    private final SwitchYardCamelContext _camelContext;
    private final QName _serviceName;

    /**
     * Sole constructor.
     *
     * @param camelBindingModel The {@link CamelBindingModel}.
     * @param camelContext The camel context instance.
     * @param serviceName The target service name.
     * @param domain the service domain.
     */
    public InboundHandler(final T camelBindingModel, final SwitchYardCamelContext camelContext, final QName serviceName, final ServiceDomain domain) {
        super(domain);
        _camelBindingModel = camelBindingModel;
        _camelContext = camelContext;
        _serviceName = serviceName;

        try {
            _camelContext.addRouteDefinition(createRouteDefinition());
        } catch (final Exception e) {
            throw new SwitchYardException(e);
        }
    }

    /**
     * Creates route definition applicable for actual camel binding model.
     *
     * @return Route definition handling given binding.
     */
    protected RouteDefinition createRouteDefinition() {
        final RouteDefinition route = new RouteDefinition();

        route.routeId(getRouteId()).from(getComponentUri().toString());
        addTransactionPolicy(route);
        addNamespacePolicy(route);
       
        route.setProperty(ExchangeCompletionEvent.GATEWAY_NAME).simple(getBindingModel().getName(), String.class)
            .setProperty(CamelConstants.APPLICATION_NAMESPACE).constant(_serviceName.getNamespaceURI())
            .process(new MessageComposerProcessor(getBindingModel()))
            .process(new OperationSelectorProcessor(getServiceName(), getBindingModel()))
            .to(getSwitchyardEndpointUri());
       
        return route;
    }

    /**
     * Get route id for given binding.
     *
     * @return Camel route id.
     */
    public String getRouteId() {
        return getBindingModel().getClass().getSimpleName() + "/" + getServiceName().getLocalPart() + "@"
                + getBindingModel().getName() + "#" + getBindingModel().getComponentURI().hashCode();
    }

    protected QName getServiceName() {
        return _serviceName;
    }

    /**
     * Add transacted DSL element to route if necessary.
     *
     * This method checks if component uri contains transaction manager reference
     * and puts
     *
     * @param route Route definition.
     * @param componentURI Component uri.
     * @return
     */
    protected RouteDefinition addTransactionPolicy(final RouteDefinition route) {
        if (TransactionHelper.useTransactionManager(getComponentUri(), _camelContext)) {
            route.transacted(CamelConstants.TRANSACTED_REF);
        }
       
        return route;
    }
   
    /**
     * Only add a namespace policy if the policy ref can be resolved, which will
     * be the case on EAP but not on Karaf.
     */
    protected RouteDefinition addNamespacePolicy(final RouteDefinition route) {
        if (_camelContext.getRegistry().lookupByName(NAMESPACE_POLICY_REF) != null) {
            route.routePolicyRef(NAMESPACE_POLICY_REF);
        }
        return route;
    }

    protected URI getComponentUri() {
        return getBindingModel().getComponentURI();
    }

    protected String getSwitchyardEndpointUri() {
        return CamelConstants.SWITCHYARD_COMPONENT_NAME + "://" + getServiceName().getLocalPart();
    }

    protected T getBindingModel() {
        return _camelBindingModel;
    }
   
    protected SwitchYardCamelContext getSwitchYardCamelContext() {
        return _camelContext;
    }

    /**
     * Will create the Camel route and add it to the camel context.
     */
    @Override
    protected void doStart() {
        try {
            RouteDefinition route = _camelContext.getRouteDefinition(getRouteId());
            if (route == null) {
                // may have been removed if this was stopped
                route = createRouteDefinition();
                _camelContext.addRouteDefinition(route);
            }
            if (route.isStartable(_camelContext)) {
                _camelContext.startRoute(getRouteId());
            }
        } catch (Exception ex) {
            throw CommonCamelMessages.MESSAGES.failedToStartRouteForService(_serviceName.toString(), ex);
        }
    }

    /**
     * Suspends the route.
     */
    @Override
    protected void doStop() {
        try {
            _camelContext.stopRoute(getRouteId());
        } catch (Exception ex) {
            throw CommonCamelMessages.MESSAGES.failedToStopRouteForService(_serviceName.toString(), ex);
        }
        try {
            _camelContext.removeRoute(getRouteId());
        } catch (Exception ex) {
            CommonCamelLogger.ROOT_LOGGER.failedToRemoveRouteForService(_serviceName.toString(), ex);
        }
    }

    /**
     * This is a noop for this handler. This handler is only responsible for setting up
     * a route in camel and the {@link SwitchyardComponent} will take care of calling
     * the configured SwitchYard service.
     *
     * @param switchYardExchange Message exchange.
     */
    @Override
    public void handleMessage(final Exchange switchYardExchange) {
    }

    @Override
    public void handleFault(final Exchange exchange) {
        System.out.println(exchange.getMessage().getContent());
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((_camelBindingModel == null) ? 0 : _camelBindingModel.getComponentURI().hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
       
        final InboundHandler<?> other = (InboundHandler<?>) obj;
        if (_camelBindingModel == null) {
            if (other._camelBindingModel != null) {
                return false;
            }
        } else if (!_camelBindingModel.getComponentURI().equals(other._camelBindingModel.getComponentURI())) {
            return false;
        }
        return true;
    }

}
TOP

Related Classes of org.switchyard.component.camel.common.handler.InboundHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.