Package org.apache.tuscany.sca.binding.notification

Source Code of org.apache.tuscany.sca.binding.notification.NotificationReferenceBindingProvider

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF 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.apache.tuscany.sca.binding.notification;

import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;

import org.apache.axiom.om.OMElement;
import org.apache.tuscany.sca.binding.notification.encoding.Broker;
import org.apache.tuscany.sca.binding.notification.encoding.ConnectionOverride;
import org.apache.tuscany.sca.binding.notification.encoding.Constants;
import org.apache.tuscany.sca.binding.notification.encoding.EncodingObject;
import org.apache.tuscany.sca.binding.notification.encoding.EncodingRegistry;
import org.apache.tuscany.sca.binding.notification.encoding.EncodingUtils;
import org.apache.tuscany.sca.binding.notification.encoding.EndpointReference;
import org.apache.tuscany.sca.binding.notification.encoding.ReplaceBrokerConnection;
import org.apache.tuscany.sca.binding.notification.encoding.Subscribe;
import org.apache.tuscany.sca.binding.notification.util.NotificationServlet;
import org.apache.tuscany.sca.binding.notification.util.URIUtil;
import org.apache.tuscany.sca.binding.notification.util.NotificationServlet.NotificationServletStreamHandler;
import org.apache.tuscany.sca.host.http.ServletHost;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;

/**
* The runtime representaion of the notification reference binding
*
* @version $Rev$ $Date$
*/
public class NotificationReferenceBindingProvider
        implements ReferenceBindingProvider, NotificationServletStreamHandler {

    private static final String producerPathBase = "/producer";
    private NotificationReferenceBindingInvoker invoker;
    private RuntimeComponentReference reference;
    private NotificationBinding notificationBinding;
    private ServletHost servletHost;
    private NotificationTypeManager ntm;
    private EncodingRegistry encodingRegistry;
    private URI notificationType;
    private URL myUrl;
    private URL remoteNtmUrl;
    private boolean started;
    private NotificationBrokerManager brokerManager;

    public NotificationReferenceBindingProvider(NotificationBinding notificationBinding,
                                                RuntimeComponent component,
                                                RuntimeComponentReference reference,
                                                ServletHost servletHost,
                                                NotificationTypeManager ntm,
                                                EncodingRegistry encodingRegistry,
                                                String httpUrl,
                                                NotificationBrokerManager brokerManager) {
        this.invoker = null;
        this.notificationBinding = notificationBinding;
        this.reference = reference;
        this.servletHost = servletHost;
        this.ntm = ntm;
        this.encodingRegistry = encodingRegistry;
        this.notificationType = notificationBinding.getNotificationType();
        String ntmAddress = notificationBinding.getNtmAddress();
        String notificationTypePath = URIUtil.getPath(notificationType);
        try {
            this.myUrl = new URL(httpUrl + producerPathBase + notificationTypePath);
            this.remoteNtmUrl = null;
            if (ntmAddress != null && notificationType != null) {
                remoteNtmUrl = new URL(ntmAddress + notificationTypePath);
            }
        }
        catch(Exception e) {
            throw new RuntimeException(e);
        }
        this.started = false;
        this.brokerManager = brokerManager;
       
        URI uri = URI.create(component.getURI() + "/" + notificationBinding.getName());
        notificationBinding.setURI(uri.toString());
        Interface interfaze = reference.getInterfaceContract().getInterface();
        interfaze.setDefaultDataBinding(OMElement.class.getName());
        for (Operation operation : interfaze.getOperations()) {
            operation.setNonBlocking(false);
        }
    }
   
    public NotificationBinding getBinding() {
        return notificationBinding;
    }
   
    public URL getURL() {
        return myUrl;
    }

    public boolean isStarted() {
        return started;
    }

    public Invoker createInvoker(Operation operation, boolean isCallback) {
        if (isCallback) {
            throw new UnsupportedOperationException();
        }
        if (invoker == null) {
            invoker = new NotificationReferenceBindingInvoker(operation);
        }
        return invoker;
    }

    public InterfaceContract getBindingInterfaceContract() {
        return reference.getInterfaceContract();
    }

    public void start() {
        if (started) {
            return;
        }

        brokerManager.referenceProviderStarted(notificationType, this, remoteNtmUrl);
        started = true;
    }

    public void stop() {
    }
   
    public void deployProducer() {
        List<URL> consumerList = new ArrayList<URL>();
        String sequenceType;
        try {
            sequenceType = ntm.newProducer(notificationType, myUrl, remoteNtmUrl, consumerList);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
        if (Constants.EndConsumers.equals(sequenceType)) {
            for (URL consumerUrl : consumerList) {
                invoker.addSubscriberUrl(consumerUrl);
            }
        }
        else if (Constants.BrokerConsumers.equals(sequenceType)) {
            // Pick a broker consumer, for now the first one
            URL consumerUrl = consumerList.get(0);
            invoker.addSubscriberUrl(consumerUrl);
        }

        servletHost.addServletMapping(myUrl.toString(), new NotificationServlet(this));
    }
   
    public void deployBroker(String brokerID, EndpointReference brokerConsumerEPR, List<EndpointReference> consumerList) {
        if (brokerConsumerEPR != null) {
            invoker.addSubscriber(brokerConsumerEPR);           
        }
        if (consumerList != null && !consumerList.isEmpty()) {
            for (EndpointReference consumerEPR : consumerList) {
                invoker.addSubscriber(consumerEPR);
            }
        }
        invoker.setBrokerID(brokerID);
        servletHost.addServletMapping(myUrl.toString(), new NotificationServlet(this));
    }
   
    public void undeployBroker(URL brokerConsumerUrl) {
        EndpointReference brokerConsumerEpr = EncodingUtils.createEndpointReference(brokerConsumerUrl, invoker.getBrokerID());
        ntm.removeBroker(brokerConsumerEpr, invoker.getNeighborBrokerConsumerEprs(), remoteNtmUrl);
        invoker.removeBrokerSubscribers();
    }
   
    public void handle(Map<String, String> headers, ServletInputStream istream, int contentLength, ServletOutputStream ostream) {

        try {
            EncodingObject eo = EncodingUtils.decodeFromStream(encodingRegistry, istream);
            if (eo instanceof Subscribe) {
                Subscribe sub = (Subscribe)eo;
                invoker.addSubscriber(sub.getConsumerReference().getReference());
            }
            else if (eo instanceof ConnectionOverride) {
                ConnectionOverride co = (ConnectionOverride)eo;
                invoker.replaceSubscribers(co.getBrokerConsumerReference().getReference());
            }
            else if (eo instanceof ReplaceBrokerConnection) {
                ReplaceBrokerConnection rbc = (ReplaceBrokerConnection)eo;
                URL removedBrokerConsumerEpr = rbc.getRemovedBroker().getReference().getEndpointAddress().getAddress();
                if (rbc.getNeighbors() != null) {
                    int choice = rbc.getNeighbors().getBrokerSequence().size() - 1;
                    Broker chosenBroker = rbc.getNeighbors().getBrokerSequence().get(choice);
                    invoker.replaceBrokerSubscriber(removedBrokerConsumerEpr,
                                                    chosenBroker.getBrokerConsumerReference().getReference());
                    brokerManager.replaceConsumersBrokerConnection(notificationType,
                                                                   chosenBroker.getBrokerProducerReference().getReference());
                }
                else {
                    invoker.replaceBrokerSubscriber(removedBrokerConsumerEpr, null);
                }
            }
            else {
                throw new RuntimeException("Unknown encoding object");
            }
        } catch(Throwable e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
TOP

Related Classes of org.apache.tuscany.sca.binding.notification.NotificationReferenceBindingProvider

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.