use of org.apache.gobblin.runtime.api.ServiceNode in project incubator-gobblin by apache.
the class MultiHopsFlowToJobSpecCompilerTest method testDijkstraPathFinding.
@Test(dependsOnMethods = "testWeightedGraphConstruction")
public void testDijkstraPathFinding() {
FlowSpec flowSpec = initFlowSpec();
TopologySpec topologySpec_1 = initTopologySpec(TOPOLOGY_SPEC_STORE_DIR, TEST_SOURCE_NAME, TEST_HOP_NAME_A, TEST_HOP_NAME_B, TEST_SINK_NAME);
TopologySpec topologySpec_2 = initTopologySpec(TOPOLOGY_SPEC_STORE_DIR_SECOND, TEST_SOURCE_NAME, TEST_HOP_NAME_B, TEST_HOP_NAME_C, TEST_SINK_NAME);
this.compilerWithTemplateCalague.onAddSpec(topologySpec_1);
this.compilerWithTemplateCalague.onAddSpec(topologySpec_2);
// Get the edge -> Change the weight -> Materialized the edge change back to graph -> compile again -> Assertion
this.compilerWithTemplateCalague.compileFlow(flowSpec);
DirectedWeightedMultigraph<ServiceNode, FlowEdge> weightedGraph = compilerWithTemplateCalague.getWeightedGraph();
FlowEdge a2b = weightedGraph.getEdge(vertexHopA, vertexHopB);
FlowEdge b2c = weightedGraph.getEdge(vertexHopB, vertexHopC);
FlowEdge c2s = weightedGraph.getEdge(vertexHopC, vertexSink);
weightedGraph.setEdgeWeight(a2b, 1.99);
weightedGraph.setEdgeWeight(b2c, 0.1);
weightedGraph.setEdgeWeight(c2s, 0.2);
// Best route: Src - B(1) - C(0.1) - sink (0.2)
this.compilerWithTemplateCalague.compileFlow(flowSpec);
List<FlowEdge> edgeList = dijkstraBasedPathFindingHelper(vertexSource, vertexSink, weightedGraph);
FlowEdge src2b = weightedGraph.getEdge(vertexSource, vertexHopB);
FlowEdge b2C = weightedGraph.getEdge(vertexHopB, vertexHopC);
FlowEdge c2sink = weightedGraph.getEdge(vertexHopC, vertexSink);
Assert.assertEquals(edgeList.get(0).getEdgeIdentity(), src2b.getEdgeIdentity());
Assert.assertEquals(edgeList.get(1).getEdgeIdentity(), b2C.getEdgeIdentity());
Assert.assertEquals(edgeList.get(2).getEdgeIdentity(), c2sink.getEdgeIdentity());
this.compilerWithTemplateCalague.onDeleteSpec(topologySpec_1.getUri(), "");
this.compilerWithTemplateCalague.onDeleteSpec(topologySpec_2.getUri(), "");
}
use of org.apache.gobblin.runtime.api.ServiceNode in project incubator-gobblin by apache.
the class IdentityFlowToJobSpecCompiler method compileFlow.
@Override
public Map<Spec, SpecExecutor> compileFlow(Spec spec) {
Preconditions.checkNotNull(spec);
Preconditions.checkArgument(spec instanceof FlowSpec, "IdentityFlowToJobSpecCompiler only converts FlowSpec to JobSpec");
long startTime = System.nanoTime();
Map<Spec, SpecExecutor> specExecutorMap = Maps.newLinkedHashMap();
FlowSpec flowSpec = (FlowSpec) spec;
String source = flowSpec.getConfig().getString(ServiceConfigKeys.FLOW_SOURCE_IDENTIFIER_KEY);
String destination = flowSpec.getConfig().getString(ServiceConfigKeys.FLOW_DESTINATION_IDENTIFIER_KEY);
log.info(String.format("Compiling flow for source: %s and destination: %s", source, destination));
JobSpec jobSpec = jobSpecGenerator(flowSpec);
for (TopologySpec topologySpec : topologySpecMap.values()) {
try {
Map<ServiceNode, ServiceNode> capabilities = (Map<ServiceNode, ServiceNode>) topologySpec.getSpecExecutor().getCapabilities().get();
for (Map.Entry<ServiceNode, ServiceNode> capability : capabilities.entrySet()) {
log.info(String.format("Evaluating current JobSpec: %s against TopologySpec: %s with " + "capability of source: %s and destination: %s ", jobSpec.getUri(), topologySpec.getUri(), capability.getKey(), capability.getValue()));
if (source.equals(capability.getKey().getNodeName()) && destination.equals(capability.getValue().getNodeName())) {
specExecutorMap.put(jobSpec, topologySpec.getSpecExecutor());
log.info(String.format("Current JobSpec: %s is executable on TopologySpec: %s. Added TopologySpec as candidate.", jobSpec.getUri(), topologySpec.getUri()));
log.info("Since we found a candidate executor, we will not try to compute more. " + "(Intended limitation for IdentityFlowToJobSpecCompiler)");
return specExecutorMap;
}
}
} catch (InterruptedException | ExecutionException e) {
Instrumented.markMeter(this.flowCompilationFailedMeter);
throw new RuntimeException("Cannot determine topology capabilities", e);
}
}
Instrumented.markMeter(this.flowCompilationSuccessFulMeter);
Instrumented.updateTimer(this.flowCompilationTimer, System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
return specExecutorMap;
}
use of org.apache.gobblin.runtime.api.ServiceNode in project incubator-gobblin by apache.
the class MultiHopsFlowToJobSpecCompilerTest method testWeightedGraphConstruction.
@Test
public void testWeightedGraphConstruction() {
FlowSpec flowSpec = initFlowSpec();
TopologySpec topologySpec = initTopologySpec(TOPOLOGY_SPEC_STORE_DIR, TEST_SOURCE_NAME, TEST_HOP_NAME_A, TEST_HOP_NAME_B, TEST_SINK_NAME);
this.compilerWithTemplateCalague.onAddSpec(topologySpec);
// invocation of compileFlow trigger the weighedGraph construction
this.compilerWithTemplateCalague.compileFlow(flowSpec);
DirectedWeightedMultigraph<ServiceNode, FlowEdge> weightedGraph = compilerWithTemplateCalague.getWeightedGraph();
Assert.assertTrue(weightedGraph.containsVertex(vertexSource));
Assert.assertTrue(weightedGraph.containsVertex(vertexHopA));
Assert.assertTrue(weightedGraph.containsVertex(vertexHopB));
Assert.assertTrue(weightedGraph.containsVertex(vertexSink));
FlowEdge edgeSrc2A = new LoadBasedFlowEdgeImpl(vertexSource, vertexHopA, topologySpec.getSpecExecutor());
FlowEdge edgeA2B = new LoadBasedFlowEdgeImpl(vertexHopA, vertexHopB, topologySpec.getSpecExecutor());
FlowEdge edgeB2Sink = new LoadBasedFlowEdgeImpl(vertexHopB, vertexSink, topologySpec.getSpecExecutor());
Assert.assertTrue(weightedGraph.containsEdge(edgeSrc2A));
Assert.assertTrue(weightedGraph.containsEdge(edgeA2B));
Assert.assertTrue(weightedGraph.containsEdge(edgeB2Sink));
Assert.assertTrue(edgeEqual(weightedGraph.getEdge(vertexSource, vertexHopA), edgeSrc2A));
Assert.assertTrue(edgeEqual(weightedGraph.getEdge(vertexHopA, vertexHopB), edgeA2B));
Assert.assertTrue(edgeEqual(weightedGraph.getEdge(vertexHopB, vertexSink), edgeB2Sink));
this.compilerWithTemplateCalague.onDeleteSpec(topologySpec.getUri(), "");
}
use of org.apache.gobblin.runtime.api.ServiceNode in project incubator-gobblin by apache.
the class MultiHopsFlowToJobSpecCompiler method userSpecifiedPathVerificator.
// If path specified not existed, return false;
// else return true.
private boolean userSpecifiedPathVerificator(Map<Spec, SpecExecutor> specExecutorInstanceMap, FlowSpec flowSpec) {
Map<Spec, SpecExecutor> tmpSpecExecutorInstanceMap = new HashMap<>();
List<String> userSpecfiedPath = Arrays.asList(optionalUserSpecifiedPath.get().split(","));
for (int i = 0; i < userSpecfiedPath.size() - 1; i++) {
ServiceNode sourceNode = new BaseServiceNodeImpl(userSpecfiedPath.get(i));
ServiceNode targetNode = new BaseServiceNodeImpl(userSpecfiedPath.get(i + 1));
if (weightedGraph.containsVertex(sourceNode) && weightedGraph.containsVertex(targetNode) && weightedGraph.containsEdge(sourceNode, targetNode)) {
tmpSpecExecutorInstanceMap.put(convertHopToJobSpec(sourceNode, targetNode, flowSpec), (((LoadBasedFlowEdgeImpl) weightedGraph.getEdge(sourceNode, targetNode)).getSpecExecutorInstance()));
} else {
log.error("User Specified Path is invalid");
return false;
}
}
specExecutorInstanceMap.putAll(tmpSpecExecutorInstanceMap);
return true;
}
use of org.apache.gobblin.runtime.api.ServiceNode in project incubator-gobblin by apache.
the class MultiHopsFlowToJobSpecCompiler method findPath.
// Basically a dijkstra path finding for connecting source and sink by multiple hops in between.
// If there's any user-specified prioritization, conduct the DFS and see if the user-specified path is available.
// there's no updates on TopologySpec, or user should be aware of the possibility
// that a topologySpec not being reflected in findPath.
private void findPath(Map<Spec, SpecExecutor> specExecutorInstanceMap, Spec spec) {
inMemoryWeightGraphGenerator();
FlowSpec flowSpec = (FlowSpec) spec;
if (optionalUserSpecifiedPath.isPresent()) {
log.info("Starting to evaluate user's specified path ... ");
if (userSpecifiedPathVerificator(specExecutorInstanceMap, flowSpec)) {
log.info("User specified path[ " + optionalUserSpecifiedPath.get() + "] successfully verified.");
return;
} else {
log.error("Will not execute user specified path[ " + optionalUserSpecifiedPath.get() + "]");
log.info("Start to execute FlowCompiler's algorithm for valid data movement path");
}
}
ServiceNode sourceNode = new BaseServiceNodeImpl(flowSpec.getConfig().getString(ServiceConfigKeys.FLOW_SOURCE_IDENTIFIER_KEY));
ServiceNode targetNode = new BaseServiceNodeImpl(flowSpec.getConfig().getString(ServiceConfigKeys.FLOW_DESTINATION_IDENTIFIER_KEY));
List<FlowEdge> resultEdgePath = dijkstraBasedPathFindingHelper(sourceNode, targetNode, this.weightedGraph);
for (int i = 0; i < resultEdgePath.size(); i++) {
FlowEdge tmpFlowEdge = resultEdgePath.get(i);
ServiceNode edgeSrcNode = ((LoadBasedFlowEdgeImpl) tmpFlowEdge).getSourceNode();
ServiceNode edgeTgtNode = ((LoadBasedFlowEdgeImpl) tmpFlowEdge).getTargetNode();
specExecutorInstanceMap.put(convertHopToJobSpec(edgeSrcNode, edgeTgtNode, flowSpec), ((LoadBasedFlowEdgeImpl) (resultEdgePath.get(i))).getSpecExecutorInstance());
}
}
Aggregations