com.olacabs.fabric.compute.builder.Linker.java Source code

Java tutorial

Introduction

Here is the source code for com.olacabs.fabric.compute.builder.Linker.java

Source

/*
 * Copyright 2016 ANI Technologies Pvt. Ltd.
 *
 * 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 com.olacabs.fabric.compute.builder;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SharedMetricRegistries;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.olacabs.fabric.compute.ProcessingContext;
import com.olacabs.fabric.compute.pipeline.ComputationPipeline;
import com.olacabs.fabric.compute.pipeline.NotificationBus;
import com.olacabs.fabric.compute.pipeline.PipelineStage;
import com.olacabs.fabric.compute.processor.ProcessorBase;
import com.olacabs.fabric.compute.source.PipelineSource;
import com.olacabs.fabric.compute.source.PipelineStreamSource;
import com.olacabs.fabric.model.common.ComponentMetadata;
import com.olacabs.fabric.model.computation.ComputationSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * TODO javadoc.
 */
public class Linker {
    private static final Logger LOGGER = LoggerFactory.getLogger(Linker.class);

    private static final String DEFAULT_REGISTRY_NAME = "metrics-registry";

    private final Loader loader;
    private MetricRegistry metricRegistry;

    public Linker(Loader loader) {
        this(loader, SharedMetricRegistries.getOrCreate(DEFAULT_REGISTRY_NAME));
    }

    public Linker(Loader loader, MetricRegistry metricRegistry) {
        this.loader = loader;
        this.metricRegistry = metricRegistry;
    }

    public ComputationPipeline build(ComputationSpec spec) {
        final NotificationBus notificationBus = new NotificationBus(spec.getProperties());
        final ProcessingContext processingContext = new ProcessingContext();
        processingContext.setTopologyName(spec.getName());
        ComputationPipeline pipeline = ComputationPipeline.builder();
        pipeline.notificationBus(notificationBus);
        pipeline.computationName(spec.getName());
        Map<String, PipelineStreamSource> sources = Maps.newHashMap();
        Map<String, PipelineStage> stages = Maps.newHashMap();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        spec.getSources().forEach(sourceMetadata -> {
            final ComponentMetadata meta = sourceMetadata.getMeta();
            PipelineSource source = null;
            final String errorMessage = String.format("Source object not loaded properly [%s:%s:%s]",
                    meta.getNamespace(), meta.getName(), meta.getVersion());
            try {
                PipelineSource sourceCopy = loader.loadSource(meta);
                if (sourceCopy != null) {
                    source = sourceCopy.getClass().getDeclaredConstructor().newInstance();
                }
            } catch (Exception e) {
                throw new RuntimeException(errorMessage, e);
            }
            Preconditions.checkNotNull(source, errorMessage);
            LOGGER.info("Loaded source: {}:{}:{}", meta.getNamespace(), meta.getName(), meta.getVersion());
            PipelineStreamSource sourceStage = PipelineStreamSource.builder().instanceId(sourceMetadata.getId())
                    .properties(sourceMetadata.getProperties()).notificationBus(notificationBus)
                    .sourceMetadata(sourceMetadata.getMeta()).source(source).processingContext(processingContext)
                    .objectMapper(objectMapper).registry(metricRegistry).build();
            pipeline.addSource(sourceStage);
            sources.put(sourceMetadata.getId(), sourceStage);
        });
        spec.getProcessors().forEach(processorMetadata -> {
            final ComponentMetadata meta = processorMetadata.getMeta();
            ProcessorBase processorBase = null;
            final String errorMessage = String.format("Processor object not loaded properly [%s:%s:%s]",
                    meta.getNamespace(), meta.getName(), meta.getVersion());
            try {
                ProcessorBase processorBaseCopy = loader.loadProcessor(meta);
                if (processorBaseCopy != null) {
                    processorBase = processorBaseCopy.getClass().getDeclaredConstructor().newInstance();
                }
            } catch (Exception e) {
                throw new RuntimeException(errorMessage, e);
            }
            Preconditions.checkNotNull(processorBase, errorMessage);
            LOGGER.info("Loaded processor: {}:{}:{}", meta.getNamespace(), meta.getName(), meta.getVersion());

            PipelineStage stage = PipelineStage.builder().instanceId(processorMetadata.getId())
                    .properties(processorMetadata.getProperties()).notificationBus(notificationBus)
                    .processorMetadata(processorMetadata.getMeta()).processor(processorBase)
                    .context(processingContext).build();
            pipeline.addPipelineStage(stage);
            stages.put(processorMetadata.getId(), stage);
        });
        spec.getConnections().forEach(connection -> {
            switch (connection.getFromType()) {
            case SOURCE:
                pipeline.connect(sources.get(connection.getFrom()), stages.get(connection.getTo()));
                break;

            case PROCESSOR:
                pipeline.connect(stages.get(connection.getFrom()), stages.get(connection.getTo()));
                break;
            default:
                break;

            }
        });
        return pipeline;
    }
}