All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fabric3.fabric.node.ChannelResolverImpl Maven / Gradle / Ivy

/*
 * Fabric3
 * Copyright (c) 2009-2015 Metaform Systems
 *
 * 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.fabric3.fabric.node;

import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.fabric3.api.host.Fabric3Exception;
import org.fabric3.api.model.type.component.Component;
import org.fabric3.api.model.type.component.Consumer;
import org.fabric3.api.model.type.component.Producer;
import org.fabric3.api.model.type.contract.DataType;
import org.fabric3.api.model.type.java.InjectingComponentType;
import org.fabric3.api.node.NotFoundException;
import org.fabric3.fabric.container.builder.ChannelConnector;
import org.fabric3.fabric.container.builder.channel.ChannelBuilderRegistry;
import org.fabric3.fabric.domain.LogicalComponentManager;
import org.fabric3.fabric.domain.generator.channel.ChannelGenerator;
import org.fabric3.fabric.domain.generator.channel.ConnectionGenerator;
import org.fabric3.fabric.node.nonmanaged.NonManagedConnectionSource;
import org.fabric3.fabric.node.nonmanaged.NonManagedConnectionTarget;
import org.fabric3.fabric.node.nonmanaged.NonManagedImplementation;
import org.fabric3.spi.container.channel.ChannelConnection;
import org.fabric3.spi.container.channel.ChannelResolver;
import org.fabric3.spi.model.instance.LogicalChannel;
import org.fabric3.spi.model.instance.LogicalComponent;
import org.fabric3.spi.model.instance.LogicalCompositeComponent;
import org.fabric3.spi.model.instance.LogicalConsumer;
import org.fabric3.spi.model.instance.LogicalProducer;
import org.fabric3.spi.model.physical.DeliveryType;
import org.fabric3.spi.model.physical.PhysicalChannel;
import org.fabric3.spi.model.physical.PhysicalChannelConnection;
import org.fabric3.spi.model.type.java.JavaServiceContract;
import org.fabric3.spi.model.type.java.JavaType;
import org.fabric3.spi.util.Closeable;
import org.oasisopen.sca.annotation.Reference;
import static org.fabric3.fabric.domain.generator.channel.ChannelDirection.CONSUMER;
import static org.fabric3.fabric.domain.generator.channel.ChannelDirection.PRODUCER;

/**
 *
 */
public class ChannelResolverImpl implements ChannelResolver {
    private static final URI SYNTHETIC_CONTRIBUTION = URI.create("SyntheticContribution");

    private Introspector introspector;
    private LogicalComponentManager lcm;
    private ChannelGenerator channelGenerator;
    private ConnectionGenerator connectionGenerator;
    private ChannelBuilderRegistry channelBuilderRegistry;
    private ChannelConnector channelConnector;
    private AtomicInteger counter = new AtomicInteger();

    public ChannelResolverImpl(@Reference Introspector introspector,
                               @Reference(name = "lcm") LogicalComponentManager lcm,
                               @Reference ChannelGenerator channelGenerator,
                               @Reference ConnectionGenerator connectionGenerator,
                               @Reference ChannelBuilderRegistry channelBuilderRegistry,
                               @Reference ChannelConnector channelConnector) {
        this.introspector = introspector;
        this.lcm = lcm;
        this.channelGenerator = channelGenerator;
        this.connectionGenerator = connectionGenerator;
        this.channelBuilderRegistry = channelBuilderRegistry;
        this.channelConnector = channelConnector;
    }

    public  T getProducer(Class interfaze, String name) throws Fabric3Exception {
        return getProducer(interfaze, name, null);
    }

    public  T getProducer(Class interfaze, String name, String topic) {
        LogicalChannel logicalChannel = getChannel(name);
        LogicalProducer producer = createProducer(interfaze, logicalChannel.getUri());
        PhysicalChannel physicalChannel = channelGenerator.generate(logicalChannel, SYNTHETIC_CONTRIBUTION, PRODUCER);

        channelBuilderRegistry.build(physicalChannel);

        Map channels = Collections.singletonMap(logicalChannel, DeliveryType.DEFAULT);
        List connections = connectionGenerator.generateProducer(producer, channels);

        // connect the connections and return the non-managed source so the proxy can be returned to the client
        NonManagedConnectionSource source = connect(topic, connections);
        return interfaze.cast(source.getProxy());
    }

    public  T getConsumer(Class interfaze, String name) {
        return getConsumer(interfaze, name, null);
    }

    public  T getConsumer(Class interfaze, String name, String topic) {
        LogicalChannel logicalChannel = getChannel(name);
        LogicalConsumer consumer = createConsumer(interfaze, logicalChannel.getUri());
        PhysicalChannel physicalChannel = channelGenerator.generate(logicalChannel, SYNTHETIC_CONTRIBUTION, CONSUMER);

        channelBuilderRegistry.build(physicalChannel);

        Map channels = Collections.singletonMap(logicalChannel, DeliveryType.DEFAULT);
        List connections = connectionGenerator.generateConsumer(consumer, channels);

        PhysicalChannelConnection connection = connections.get(0);  // safe as there is only one connection
        connection.setTopic(topic);
        connection.getSource().setTopic(topic);
        connection.getTarget().setTopic(topic);
        channelConnector.connect(connection);

        NonManagedConnectionTarget target = (NonManagedConnectionTarget) connection.getTarget();
        return interfaze.cast(target.getProxy());
    }

    public Object subscribe(Class type, String name, String id, String topic, java.util.function.Consumer consumer) {
        LogicalChannel logicalChannel = getChannel(name);
        LogicalConsumer logicalConsumer = createConsumer(type, logicalChannel.getUri());
        PhysicalChannel physicalChannel = channelGenerator.generate(logicalChannel, SYNTHETIC_CONTRIBUTION, CONSUMER);

        channelBuilderRegistry.build(physicalChannel);

        Map channels = Collections.singletonMap(logicalChannel, DeliveryType.DEFAULT);
        List connections = connectionGenerator.generateConsumer(logicalConsumer, channels);

        // Two connections will be created: one from the binding to the channel, the other from the channel to the component
        // the closeable will be set on the connection from the binding to the channel; it must be passed to the component
        Closeable closeable = null;
        for (PhysicalChannelConnection connection : connections) {
            connection.setTopic(topic);
            connection.getSource().setTopic(topic);
            connection.getTarget().setTopic(topic);
            connection.getTarget().setConsumer(consumer);
            ChannelConnection channelConnection = channelConnector.connect(connection);
            if (channelConnection.getCloseable() != null) {
                closeable = channelConnection.getCloseable();
            }

        }
        return closeable;
    }

    private NonManagedConnectionSource connect(String topic, List connections) {
        NonManagedConnectionSource source = null;
        for (PhysicalChannelConnection connection : connections) {
            connection.setTopic(topic);
            connection.getSource().setTopic(topic);
            connection.getTarget().setTopic(topic);
            channelConnector.connect(connection);
            if (connection.getSource() instanceof NonManagedConnectionSource) {
                source = (NonManagedConnectionSource) connection.getSource();
            }
        }
        if (source == null) {
            throw new Fabric3Exception("NonManagedConnectionSource not found publishing to topic: " + topic);
        }
        return source;
    }

    private  LogicalConsumer createConsumer(Class type, URI channelUri) {
        JavaServiceContract contract = introspector.introspect(type);
        LogicalCompositeComponent domain = lcm.getDomainComposite();
        String root = domain.getUri().toString();

        LogicalComponent logicalComponent = createComponent(Object.class, domain, root);

        DataType dataType = new JavaType(type);
        Consumer consumer = new Consumer("consumer", dataType, true);

        int pos = counter.getAndIncrement();
        LogicalConsumer logicalConsumer = new LogicalConsumer(URI.create(root + "/F3Synthetic#consumer" + pos), consumer, logicalComponent);
        logicalConsumer.setServiceContract(contract);
        logicalConsumer.addSource(channelUri);
        return logicalConsumer;
    }

    private LogicalChannel getChannel(String name) throws Fabric3Exception {
        LogicalCompositeComponent domainComponent = lcm.getDomainComposite();
        String domainRoot = domainComponent.getUri().toString();
        URI channelUri = URI.create(domainRoot + "/" + name);
        LogicalChannel logicalChannel = domainComponent.getChannel(channelUri);
        if (logicalChannel == null) {
            throw new NotFoundException("Channel not found: " + name);
        }
        return logicalChannel;
    }

    private  LogicalProducer createProducer(Class interfaze, URI channelUri) throws Fabric3Exception {
        JavaServiceContract contract = introspector.introspect(interfaze);

        LogicalCompositeComponent domain = lcm.getDomainComposite();
        String root = domain.getUri().toString();

        LogicalComponent logicalComponent = createComponent(interfaze, domain, root);

        Producer producer = new Producer("producer", contract);

        int pos = counter.getAndIncrement();
        LogicalProducer logicalProducer = new LogicalProducer(URI.create(root + "/F3Synthetic#producer" + pos), producer, logicalComponent);
        logicalProducer.setServiceContract(contract);
        logicalProducer.addTarget(channelUri);
        return logicalProducer;
    }

    private  LogicalComponent createComponent(Class interfaze, LogicalCompositeComponent domain, String root) {
        URI componentUri = URI.create(root + "/F3Synthetic");

        InjectingComponentType componentType = new InjectingComponentType();
        NonManagedImplementation implementation = new NonManagedImplementation();
        implementation.setComponentType(componentType);
        Component component = new Component<>("F3Synthetic");
        component.setContributionUri(ContributionResolver.getContribution(interfaze));
        component.setImplementation(implementation);
        return new LogicalComponent<>(componentUri, component, domain);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy