com.shazam.dataengineering.pipelinebuilder.GraphWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.shazam.dataengineering.pipelinebuilder.GraphWriter.java

Source

/*
 * Copyright 2015 Shazam Entertainment Limited
 *
 * 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.shazam.dataengineering.pipelinebuilder;

import com.amazonaws.services.datapipeline.model.Field;
import org.jgrapht.ext.DOTExporter;
import org.jgrapht.ext.EdgeNameProvider;
import org.jgrapht.ext.IntegerNameProvider;
import org.jgrapht.ext.VertexNameProvider;
import org.jgrapht.graph.ClassBasedEdgeFactory;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DirectedMultigraph;

import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * Class responsible for writing out DOT representation of the pipeline.
 */
public class GraphWriter {

    @SuppressWarnings("unchecked")
    public void writeDOT(Writer writer, PipelineObject pipeline) {
        DirectedMultigraph graph = getGraph(pipeline);

        DOTExporter dot = new DOTExporter(new IntegerNameProvider(), new PipelineVertexNameProvider(),
                new PipelineEdgeNameProvider());

        dot.export(writer, graph);
    }

    /**
     * Build DAG of the pipeline for writing to DOT
     * Only generates activity information. Full graphs tend to be very noisy.
     *
     * @return DirectedMultigraph representation of the pipeline
     */
    @SuppressWarnings("unchecked")
    private DirectedMultigraph getGraph(PipelineObject pipeline) {
        DirectedMultigraph graph = new DirectedMultigraph<com.amazonaws.services.datapipeline.model.PipelineObject, RelationshipEdge>(
                new ClassBasedEdgeFactory<com.amazonaws.services.datapipeline.model.PipelineObject, RelationshipEdge>(
                        RelationshipEdge.class));

        // Maintain map for easier edge creation
        HashMap<String, com.amazonaws.services.datapipeline.model.PipelineObject> idToPipeline = new HashMap<String, com.amazonaws.services.datapipeline.model.PipelineObject>();

        List<com.amazonaws.services.datapipeline.model.PipelineObject> awsObjects = pipeline.getAWSObjects();
        for (com.amazonaws.services.datapipeline.model.PipelineObject awsObject : awsObjects) {
            // Ignore everything except activities
            if (!awsObject.getId().equals("Default")) {
                for (Field field : awsObject.getFields()) {
                    // Only add activities to the DOT
                    if (field.getKey().equals("type") && field.getStringValue().contains("Activity")) {
                        idToPipeline.put(awsObject.getId(), awsObject);
                        graph.addVertex(awsObject);
                    }
                }
            }
        }

        for (com.amazonaws.services.datapipeline.model.PipelineObject awsObject : (Set<com.amazonaws.services.datapipeline.model.PipelineObject>) graph
                .vertexSet()) {
            List<Field> fields = awsObject.getFields();
            for (Field field : fields) {
                if (field.getRefValue() != null && idToPipeline.containsKey(field.getRefValue())) {
                    graph.addEdge(awsObject, idToPipeline.get(field.getRefValue()),
                            new RelationshipEdge<com.amazonaws.services.datapipeline.model.PipelineObject>(
                                    awsObject, idToPipeline.get(field.getRefValue()), field.getKey()));
                }
            }
        }

        return graph;
    }

    private class PipelineVertexNameProvider
            implements VertexNameProvider<com.amazonaws.services.datapipeline.model.PipelineObject> {
        public String getVertexName(com.amazonaws.services.datapipeline.model.PipelineObject object) {
            if (object == null) {
                return "none";
            } else if (object.getName() != null && !object.getName().isEmpty()) {
                String label = object.getName() + "\nID: " + object.getId();
                for (Field field : object.getFields()) {
                    if (field.getKey().equals("type")) {
                        label += "\nType: " + field.getStringValue();
                    }
                }

                return clean(label);
            } else {
                return clean(object.toString());
            }
        }

        private String clean(String input) {
            return input.replaceAll("\"", "\'");
        }
    }

    private class PipelineEdgeNameProvider implements EdgeNameProvider<RelationshipEdge> {
        public String getEdgeName(RelationshipEdge edge) {
            if (edge == null) {
                return "none";
            } else {
                return edge.toString().replaceAll("\"", "\'");
            }
        }
    }

    public static class RelationshipEdge<V> extends DefaultEdge {
        private V v1;
        private V v2;
        private String label;

        public RelationshipEdge(V v1, V v2, String label) {
            this.v1 = v1;
            this.v2 = v2;
            this.label = label;
        }

        public V getV1() {
            return v1;
        }

        public V getV2() {
            return v2;
        }

        public String toString() {
            return label;
        }
    }
}