blob: 371e0d240f257559fb8fcb9be196bbaf0f7c970a [file] [log] [blame]
/*
* Copyright 2015-present Open Networking Laboratory
*
* 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.onlab.stc;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Maps;
import org.onlab.stc.MonitorLayout.Box;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import static org.onlab.stc.Coordinator.Status.IN_PROGRESS;
/**
* Scenario test monitor.
*/
public class Monitor implements StepProcessListener {
private final ObjectMapper mapper = new ObjectMapper();
private final Coordinator coordinator;
private final Compiler compiler;
private final MonitorLayout layout;
private MonitorDelegate delegate;
private Map<Step, Box> boxes = Maps.newHashMap();
/**
* Creates a new shared process flow monitor.
*
* @param coordinator process flow coordinator
* @param compiler scenario compiler
*/
Monitor(Coordinator coordinator, Compiler compiler) {
this.coordinator = coordinator;
this.compiler = compiler;
this.layout = new MonitorLayout(compiler);
coordinator.addListener(this);
}
/**
* Sets the process monitor delegate.
*
* @param delegate process monitor delegate
*/
void setDelegate(MonitorDelegate delegate) {
this.delegate = delegate;
}
/**
* Notifies the process monitor delegate with the specified event.
*
* @param event JSON event data
*/
public void notify(ObjectNode event) {
if (delegate != null) {
delegate.notify(event);
}
}
/**
* Returns the scenario process flow as JSON data.
*
* @return scenario process flow data
*/
ObjectNode scenarioData() {
ObjectNode root = mapper.createObjectNode();
ArrayNode steps = mapper.createArrayNode();
ArrayNode requirements = mapper.createArrayNode();
ProcessFlow pf = compiler.processFlow();
pf.getVertexes().forEach(step -> add(step, steps));
pf.getEdges().forEach(requirement -> add(requirement, requirements));
root.set("steps", steps);
root.set("requirements", requirements);
try (FileWriter fw = new FileWriter("/tmp/data.json");
PrintWriter pw = new PrintWriter(fw)) {
pw.println(root.toString());
} catch (IOException e) {
e.printStackTrace();
}
return root;
}
private void add(Step step, ArrayNode steps) {
Box box = layout.get(step);
ObjectNode sn = mapper.createObjectNode()
.put("name", step.name())
.put("isGroup", step instanceof Group)
.put("status", status(coordinator.getStatus(step)))
.put("tier", box.tier())
.put("depth", box.depth());
if (step.group() != null) {
sn.put("group", step.group().name());
}
steps.add(sn);
}
private String status(Coordinator.Status status) {
return status.toString().toLowerCase();
}
private void add(Dependency requirement, ArrayNode requirements) {
ObjectNode rn = mapper.createObjectNode();
rn.put("src", requirement.src().name())
.put("dst", requirement.dst().name())
.put("isSoft", requirement.isSoft());
requirements.add(rn);
}
@Override
public void onStart(Step step, String command) {
notify(event(step, status(IN_PROGRESS)));
}
@Override
public void onCompletion(Step step, Coordinator.Status status) {
notify(event(step, status(status)));
}
@Override
public void onOutput(Step step, String line) {
}
private ObjectNode event(Step step, String status) {
ObjectNode event = mapper.createObjectNode()
.put("name", step.name())
.put("status", status);
return event;
}
}