Abhishek Dwaraki
Committed by Ray Milkey

ONOS-400 Topology creation and up time formatting fixes

Change-Id: Iaf6d4dbbc1c7eaae9465a2d931d40f07a75ad07d
...@@ -15,7 +15,11 @@ ...@@ -15,7 +15,11 @@
15 */ 15 */
16 package org.onosproject.cli.net; 16 package org.onosproject.cli.net;
17 17
18 -import com.fasterxml.jackson.databind.ObjectMapper; 18 +import java.text.DateFormat;
19 +import java.text.SimpleDateFormat;
20 +import java.util.Calendar;
21 +import java.util.concurrent.TimeUnit;
22 +
19 import org.apache.karaf.shell.commands.Command; 23 import org.apache.karaf.shell.commands.Command;
20 import org.apache.karaf.shell.commands.Option; 24 import org.apache.karaf.shell.commands.Option;
21 import org.onosproject.cli.AbstractShellCommand; 25 import org.onosproject.cli.AbstractShellCommand;
...@@ -23,18 +27,20 @@ import org.onosproject.net.topology.Topology; ...@@ -23,18 +27,20 @@ import org.onosproject.net.topology.Topology;
23 import org.onosproject.net.topology.TopologyProvider; 27 import org.onosproject.net.topology.TopologyProvider;
24 import org.onosproject.net.topology.TopologyService; 28 import org.onosproject.net.topology.TopologyService;
25 29
30 +import com.fasterxml.jackson.databind.ObjectMapper;
31 +
26 /** 32 /**
27 * Lists summary of the current topology. 33 * Lists summary of the current topology.
28 */ 34 */
29 @Command(scope = "onos", name = "topology", 35 @Command(scope = "onos", name = "topology",
30 - description = "Lists summary of the current topology") 36 +description = "Lists summary of the current topology")
31 public class TopologyCommand extends AbstractShellCommand { 37 public class TopologyCommand extends AbstractShellCommand {
32 38
33 - private static final String FMT = 39 + private static final String FMT = "created=%s, uptime=%s, devices=%d, links=%d, clusters=%d";
34 - "time=%s, devices=%d, links=%d, clusters=%d";
35 40
36 - @Option(name = "-r", aliases = "--recompute", description = "Trigger topology re-computation", 41 + @Option(name = "-r", aliases = "--recompute",
37 - required = false, multiValued = false) 42 + description = "Trigger topology re-computation", required = false,
43 + multiValued = false)
38 private boolean recompute = false; 44 private boolean recompute = false;
39 45
40 protected TopologyService service; 46 protected TopologyService service;
...@@ -51,19 +57,75 @@ public class TopologyCommand extends AbstractShellCommand { ...@@ -51,19 +57,75 @@ public class TopologyCommand extends AbstractShellCommand {
51 @Override 57 @Override
52 protected void execute() { 58 protected void execute() {
53 init(); 59 init();
60 + long topologyUptime =
61 + Math.max(0, (System.currentTimeMillis() - topology.creationTime()));
54 if (recompute) { 62 if (recompute) {
55 get(TopologyProvider.class).triggerRecompute(); 63 get(TopologyProvider.class).triggerRecompute();
56 64
57 } else if (outputJson()) { 65 } else if (outputJson()) {
58 - print("%s", new ObjectMapper().createObjectNode() 66 + print("%s",
59 - .put("time", topology.time()) 67 + new ObjectMapper()
60 - .put("deviceCount", topology.deviceCount()) 68 + .createObjectNode()
61 - .put("linkCount", topology.linkCount()) 69 + .put("time", topology.time())
62 - .put("clusterCount", topology.clusterCount())); 70 + .put("created", formatCreationTime(topology.creationTime()))
71 + .put("uptime", formatElapsedTime(topologyUptime))
72 + .put("deviceCount", topology.deviceCount())
73 + .put("linkCount", topology.linkCount())
74 + .put("clusterCount", topology.clusterCount()));
63 } else { 75 } else {
64 - print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(), 76 + print(FMT, formatCreationTime(topology.creationTime()),
65 - topology.clusterCount()); 77 + formatElapsedTime(topologyUptime),
78 + topology.deviceCount(), topology.linkCount(),
79 + topology.clusterCount());
66 } 80 }
67 } 81 }
68 82
83 + /**
84 + * Converts millis to a formatted elapsed time string.
85 + *
86 + * @param millis Duration in millis to convert to a string
87 + *
88 + * @return Formatted string: "D days, H hrs, M mins, S secs".
89 + */
90 + private static String formatElapsedTime(long millis) {
91 + if (millis < 0) {
92 + throw new IllegalArgumentException("Interval less than zero. "
93 + + "Possible unsynchronized timestamps");
94 + }
95 +
96 + final long days = TimeUnit.MILLISECONDS.toDays(millis);
97 + millis -= TimeUnit.DAYS.toMillis(days);
98 + final long hours = TimeUnit.MILLISECONDS.toHours(millis);
99 + millis -= TimeUnit.HOURS.toMillis(hours);
100 + final long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
101 + millis -= TimeUnit.MINUTES.toMillis(minutes);
102 + final long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
103 +
104 + final StringBuilder topologyUptimeString = new StringBuilder(64);
105 + topologyUptimeString.append(days);
106 + topologyUptimeString.append(" days, ");
107 + topologyUptimeString.append(hours);
108 + topologyUptimeString.append(" hrs, ");
109 + topologyUptimeString.append(minutes);
110 + topologyUptimeString.append(" mins, ");
111 + topologyUptimeString.append(seconds);
112 + topologyUptimeString.append(" secs");
113 +
114 + return (topologyUptimeString.toString());
115 + }
116 +
117 + /**
118 + * Converts millis to a formatted Date String.
119 + *
120 + * @param millis Duration in millis to convert to a string
121 + *
122 + * @return Formatted string: yyyy-MM-dd HH:mm:ss.
123 + */
124 + private static String formatCreationTime(long millis) {
125 + final DateFormat dateFormatter =
126 + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
127 + Calendar calendar = Calendar.getInstance();
128 + calendar.setTimeInMillis(millis);
129 + return (dateFormatter.format(calendar.getTime()));
130 + }
69 } 131 }
......
...@@ -34,30 +34,60 @@ import com.google.common.collect.Maps; ...@@ -34,30 +34,60 @@ import com.google.common.collect.Maps;
34 * Default implementation of an immutable topology graph data carrier. 34 * Default implementation of an immutable topology graph data carrier.
35 */ 35 */
36 public class DefaultGraphDescription extends AbstractDescription 36 public class DefaultGraphDescription extends AbstractDescription
37 - implements GraphDescription { 37 +implements GraphDescription {
38 38
39 private static final Logger log = getLogger(DefaultGraphDescription.class); 39 private static final Logger log = getLogger(DefaultGraphDescription.class);
40 40
41 private final long nanos; 41 private final long nanos;
42 + private final long creationTime;
42 private final ImmutableSet<TopologyVertex> vertexes; 43 private final ImmutableSet<TopologyVertex> vertexes;
43 private final ImmutableSet<TopologyEdge> edges; 44 private final ImmutableSet<TopologyEdge> edges;
44 45
45 - private final Map<DeviceId, TopologyVertex> vertexesById = Maps.newHashMap(); 46 + private final Map<DeviceId, TopologyVertex> vertexesById = Maps
47 + .newHashMap();
46 48
47 /** 49 /**
48 * Creates a minimal topology graph description to allow core to construct 50 * Creates a minimal topology graph description to allow core to construct
49 * and process the topology graph. 51 * and process the topology graph.
50 * 52 *
51 - * @param nanos time in nanos of when the topology description was created 53 + * @param nanos time in nanos of when the topology description was created
52 - * @param devices collection of infrastructure devices 54 + *
53 - * @param links collection of infrastructure links 55 + * @param devices collection of infrastructure devices
56 + *
57 + * @param links collection of infrastructure links
58 + *
54 * @param annotations optional key/value annotations map 59 * @param annotations optional key/value annotations map
60 + *
55 */ 61 */
62 + @Deprecated
56 public DefaultGraphDescription(long nanos, Iterable<Device> devices, 63 public DefaultGraphDescription(long nanos, Iterable<Device> devices,
57 - Iterable<Link> links, 64 + Iterable<Link> links,
58 - SparseAnnotations... annotations) { 65 + SparseAnnotations... annotations) {
66 + this(nanos, System.currentTimeMillis(), devices, links, annotations);
67 + }
68 +
69 + /**
70 + * Creates a minimal topology graph description to allow core to construct
71 + * and process the topology graph.
72 + *
73 + * @param nanos time in nanos of when the topology description was created
74 + *
75 + * @param millis time in millis of when the topology description was created
76 + *
77 + * @param devices collection of infrastructure devices
78 + *
79 + * @param links collection of infrastructure links
80 + *
81 + * @param annotations optional key/value annotations map
82 + *
83 + */
84 + public DefaultGraphDescription(long nanos, long millis,
85 + Iterable<Device> devices,
86 + Iterable<Link> links,
87 + SparseAnnotations... annotations) {
59 super(annotations); 88 super(annotations);
60 this.nanos = nanos; 89 this.nanos = nanos;
90 + this.creationTime = millis;
61 this.vertexes = buildVertexes(devices); 91 this.vertexes = buildVertexes(devices);
62 this.edges = buildEdges(links); 92 this.edges = buildEdges(links);
63 vertexesById.clear(); 93 vertexesById.clear();
...@@ -69,6 +99,11 @@ public class DefaultGraphDescription extends AbstractDescription ...@@ -69,6 +99,11 @@ public class DefaultGraphDescription extends AbstractDescription
69 } 99 }
70 100
71 @Override 101 @Override
102 + public long creationTime() {
103 + return creationTime;
104 + }
105 +
106 + @Override
72 public ImmutableSet<TopologyVertex> vertexes() { 107 public ImmutableSet<TopologyVertex> vertexes() {
73 return vertexes; 108 return vertexes;
74 } 109 }
...@@ -79,7 +114,8 @@ public class DefaultGraphDescription extends AbstractDescription ...@@ -79,7 +114,8 @@ public class DefaultGraphDescription extends AbstractDescription
79 } 114 }
80 115
81 // Builds a set of topology vertexes from the specified list of devices 116 // Builds a set of topology vertexes from the specified list of devices
82 - private ImmutableSet<TopologyVertex> buildVertexes(Iterable<Device> devices) { 117 + private ImmutableSet<TopologyVertex>
118 + buildVertexes(Iterable<Device> devices) {
83 ImmutableSet.Builder<TopologyVertex> vertexes = ImmutableSet.builder(); 119 ImmutableSet.Builder<TopologyVertex> vertexes = ImmutableSet.builder();
84 for (Device device : devices) { 120 for (Device device : devices) {
85 TopologyVertex vertex = new DefaultTopologyVertex(device.id()); 121 TopologyVertex vertex = new DefaultTopologyVertex(device.id());
...@@ -95,7 +131,8 @@ public class DefaultGraphDescription extends AbstractDescription ...@@ -95,7 +131,8 @@ public class DefaultGraphDescription extends AbstractDescription
95 for (Link link : links) { 131 for (Link link : links) {
96 try { 132 try {
97 edges.add(new DefaultTopologyEdge(vertexOf(link.src()), 133 edges.add(new DefaultTopologyEdge(vertexOf(link.src()),
98 - vertexOf(link.dst()), link)); 134 + vertexOf(link.dst()),
135 + link));
99 } catch (IllegalArgumentException e) { 136 } catch (IllegalArgumentException e) {
100 log.debug("Ignoring {}, missing vertex", link); 137 log.debug("Ignoring {}, missing vertex", link);
101 } 138 }
......
...@@ -15,9 +15,10 @@ ...@@ -15,9 +15,10 @@
15 */ 15 */
16 package org.onosproject.net.topology; 16 package org.onosproject.net.topology;
17 17
18 -import com.google.common.collect.ImmutableSet;
19 import org.onosproject.net.Description; 18 import org.onosproject.net.Description;
20 19
20 +import com.google.common.collect.ImmutableSet;
21 +
21 /** 22 /**
22 * Describes attribute(s) of a network graph. 23 * Describes attribute(s) of a network graph.
23 */ 24 */
...@@ -32,6 +33,14 @@ public interface GraphDescription extends Description { ...@@ -32,6 +33,14 @@ public interface GraphDescription extends Description {
32 long timestamp(); 33 long timestamp();
33 34
34 /** 35 /**
36 + * Returns the creation timestamp of the graph description. This is
37 + * expressed in system millis to allow proper date and time formatting.
38 + *
39 + * @return graph description creation timestamp in millis
40 + */
41 + long creationTime();
42 +
43 + /**
35 * Returns the set of topology graph vertexes. 44 * Returns the set of topology graph vertexes.
36 * 45 *
37 * @return set of graph vertexes 46 * @return set of graph vertexes
...@@ -46,4 +55,3 @@ public interface GraphDescription extends Description { ...@@ -46,4 +55,3 @@ public interface GraphDescription extends Description {
46 ImmutableSet<TopologyEdge> edges(); 55 ImmutableSet<TopologyEdge> edges();
47 56
48 } 57 }
49 -
......
...@@ -23,16 +23,24 @@ import org.onosproject.net.Provided; ...@@ -23,16 +23,24 @@ import org.onosproject.net.Provided;
23 public interface Topology extends Provided { 23 public interface Topology extends Provided {
24 24
25 /** 25 /**
26 - * Returns the time, specified in system nanos of when the topology 26 + * Returns the time, specified in system nanos of when the topology became
27 - * became available. 27 + * available.
28 * 28 *
29 * @return time in system nanos 29 * @return time in system nanos
30 */ 30 */
31 long time(); 31 long time();
32 32
33 /** 33 /**
34 - * Returns the time, specified in system nanos of how long the topology 34 + * Returns the time, specified in system millis of when the topology became
35 - * took to compute. 35 + * available.
36 + *
37 + * @return time in system nanos
38 + */
39 + long creationTime();
40 +
41 + /**
42 + * Returns the time, specified in system nanos of how long the topology took
43 + * to compute.
36 * 44 *
37 * @return elapsed time in system nanos 45 * @return elapsed time in system nanos
38 */ 46 */
...@@ -53,7 +61,6 @@ public interface Topology extends Provided { ...@@ -53,7 +61,6 @@ public interface Topology extends Provided {
53 */ 61 */
54 int deviceCount(); 62 int deviceCount();
55 63
56 -
57 /** 64 /**
58 * Returns the number of infrastructure links in the topology. 65 * Returns the number of infrastructure links in the topology.
59 * 66 *
......
...@@ -15,7 +15,21 @@ ...@@ -15,7 +15,21 @@
15 */ 15 */
16 package org.onosproject.net.topology.impl; 16 package org.onosproject.net.topology.impl;
17 17
18 -import com.google.common.collect.ImmutableList; 18 +import static com.google.common.base.Strings.isNullOrEmpty;
19 +import static java.util.concurrent.Executors.newFixedThreadPool;
20 +import static org.onlab.util.Tools.groupedThreads;
21 +import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
22 +import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
23 +import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
24 +import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_REMOVED;
25 +import static org.slf4j.LoggerFactory.getLogger;
26 +
27 +import java.util.Collections;
28 +import java.util.Dictionary;
29 +import java.util.List;
30 +import java.util.Timer;
31 +import java.util.concurrent.ExecutorService;
32 +
19 import org.apache.felix.scr.annotations.Activate; 33 import org.apache.felix.scr.annotations.Activate;
20 import org.apache.felix.scr.annotations.Component; 34 import org.apache.felix.scr.annotations.Component;
21 import org.apache.felix.scr.annotations.Deactivate; 35 import org.apache.felix.scr.annotations.Deactivate;
...@@ -42,28 +56,16 @@ import org.onosproject.net.topology.TopologyProviderService; ...@@ -42,28 +56,16 @@ import org.onosproject.net.topology.TopologyProviderService;
42 import org.osgi.service.component.ComponentContext; 56 import org.osgi.service.component.ComponentContext;
43 import org.slf4j.Logger; 57 import org.slf4j.Logger;
44 58
45 -import java.util.Collections; 59 +import com.google.common.collect.ImmutableList;
46 -import java.util.Dictionary;
47 -import java.util.List;
48 -import java.util.Timer;
49 -import java.util.concurrent.ExecutorService;
50 -
51 -import static com.google.common.base.Strings.isNullOrEmpty;
52 -import static java.util.concurrent.Executors.newFixedThreadPool;
53 -import static org.onlab.util.Tools.groupedThreads;
54 -import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
55 -import static org.onosproject.net.device.DeviceEvent.Type.*;
56 -import static org.slf4j.LoggerFactory.getLogger;
57 60
58 /** 61 /**
59 - * Default implementation of a network topology provider that feeds off 62 + * Default implementation of a network topology provider that feeds off device
60 - * device and link subsystem events to trigger assembly and computation of 63 + * and link subsystem events to trigger assembly and computation of new topology
61 - * new topology snapshots. 64 + * snapshots.
62 */ 65 */
63 @Component(immediate = true) 66 @Component(immediate = true)
64 @Service 67 @Service
65 -public class DefaultTopologyProvider extends AbstractProvider 68 +public class DefaultTopologyProvider extends AbstractProvider implements TopologyProvider {
66 - implements TopologyProvider {
67 69
68 private static final int MAX_THREADS = 8; 70 private static final int MAX_THREADS = 8;
69 private static final int DEFAULT_MAX_EVENTS = 1000; 71 private static final int DEFAULT_MAX_EVENTS = 1000;
...@@ -71,7 +73,8 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -71,7 +73,8 @@ public class DefaultTopologyProvider extends AbstractProvider
71 private static final int DEFAULT_MAX_BATCH_MS = 50; 73 private static final int DEFAULT_MAX_BATCH_MS = 50;
72 74
73 // FIXME: Replace with a system-wide timer instance; 75 // FIXME: Replace with a system-wide timer instance;
74 - // TODO: Convert to use HashedWheelTimer or produce a variant of that; then decide which we want to adopt 76 + // TODO: Convert to use HashedWheelTimer or produce a variant of that; then
77 + // decide which we want to adopt
75 private static final Timer TIMER = new Timer("onos-topo-event-batching"); 78 private static final Timer TIMER = new Timer("onos-topo-event-batching");
76 79
77 @Property(name = "maxEvents", intValue = DEFAULT_MAX_EVENTS, 80 @Property(name = "maxEvents", intValue = DEFAULT_MAX_EVENTS,
...@@ -100,8 +103,8 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -100,8 +103,8 @@ public class DefaultTopologyProvider extends AbstractProvider
100 private volatile boolean isStarted = false; 103 private volatile boolean isStarted = false;
101 104
102 private TopologyProviderService providerService; 105 private TopologyProviderService providerService;
103 - private DeviceListener deviceListener = new InternalDeviceListener(); 106 + private final DeviceListener deviceListener = new InternalDeviceListener();
104 - private LinkListener linkListener = new InternalLinkListener(); 107 + private final LinkListener linkListener = new InternalLinkListener();
105 108
106 private Accumulator<Event> accumulator; 109 private Accumulator<Event> accumulator;
107 private ExecutorService executor; 110 private ExecutorService executor;
...@@ -115,7 +118,8 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -115,7 +118,8 @@ public class DefaultTopologyProvider extends AbstractProvider
115 118
116 @Activate 119 @Activate
117 public synchronized void activate(ComponentContext context) { 120 public synchronized void activate(ComponentContext context) {
118 - executor = newFixedThreadPool(MAX_THREADS, groupedThreads("onos/topo", "build-%d")); 121 + executor = newFixedThreadPool(MAX_THREADS,
122 + groupedThreads("onos/topo", "build-%d"));
119 accumulator = new TopologyChangeAccumulator(); 123 accumulator = new TopologyChangeAccumulator();
120 logConfig("Configured"); 124 logConfig("Configured");
121 125
...@@ -171,21 +175,23 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -171,21 +175,23 @@ public class DefaultTopologyProvider extends AbstractProvider
171 newMaxIdleMs = DEFAULT_MAX_IDLE_MS; 175 newMaxIdleMs = DEFAULT_MAX_IDLE_MS;
172 } 176 }
173 177
174 - if (newMaxEvents != maxEvents || newMaxBatchMs != maxBatchMs || newMaxIdleMs != maxIdleMs) { 178 + if ((newMaxEvents != maxEvents) || (newMaxBatchMs != maxBatchMs)
179 + || (newMaxIdleMs != maxIdleMs)) {
175 maxEvents = newMaxEvents; 180 maxEvents = newMaxEvents;
176 maxBatchMs = newMaxBatchMs; 181 maxBatchMs = newMaxBatchMs;
177 maxIdleMs = newMaxIdleMs; 182 maxIdleMs = newMaxIdleMs;
178 - accumulator = maxEvents > 1 ? new TopologyChangeAccumulator() : null; 183 + accumulator = maxEvents > 1 ? new TopologyChangeAccumulator()
184 + : null;
179 logConfig("Reconfigured"); 185 logConfig("Reconfigured");
180 } 186 }
181 } 187 }
182 188
183 private void logConfig(String prefix) { 189 private void logConfig(String prefix) {
184 - log.info("{} with maxEvents = {}; maxBatchMs = {}; maxIdleMs = {}; accumulator={}", 190 + log.info(
185 - prefix, maxEvents, maxBatchMs, maxIdleMs, accumulator != null); 191 + "{} with maxEvents = {}; maxBatchMs = {}; maxIdleMs = {}; accumulator={}",
192 + prefix, maxEvents, maxBatchMs, maxIdleMs, accumulator != null);
186 } 193 }
187 194
188 -
189 @Override 195 @Override
190 public void triggerRecompute() { 196 public void triggerRecompute() {
191 triggerTopologyBuild(Collections.<Event>emptyList()); 197 triggerTopologyBuild(Collections.<Event>emptyList());
...@@ -195,7 +201,8 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -195,7 +201,8 @@ public class DefaultTopologyProvider extends AbstractProvider
195 * Triggers assembly of topology data citing the specified events as the 201 * Triggers assembly of topology data citing the specified events as the
196 * reason. 202 * reason.
197 * 203 *
198 - * @param reasons events which triggered the topology change 204 + * @param reasons
205 + * events which triggered the topology change
199 */ 206 */
200 private synchronized void triggerTopologyBuild(List<Event> reasons) { 207 private synchronized void triggerTopologyBuild(List<Event> reasons) {
201 if (executor != null) { 208 if (executor != null) {
...@@ -209,8 +216,9 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -209,8 +216,9 @@ public class DefaultTopologyProvider extends AbstractProvider
209 if (isStarted) { 216 if (isStarted) {
210 GraphDescription desc = 217 GraphDescription desc =
211 new DefaultGraphDescription(System.nanoTime(), 218 new DefaultGraphDescription(System.nanoTime(),
212 - deviceService.getAvailableDevices(), 219 + System.currentTimeMillis(),
213 - linkService.getActiveLinks()); 220 + deviceService.getAvailableDevices(),
221 + linkService.getActiveLinks());
214 providerService.topologyChanged(desc, reasons); 222 providerService.topologyChanged(desc, reasons);
215 } 223 }
216 } 224 }
...@@ -228,8 +236,8 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -228,8 +236,8 @@ public class DefaultTopologyProvider extends AbstractProvider
228 @Override 236 @Override
229 public void event(DeviceEvent event) { 237 public void event(DeviceEvent event) {
230 DeviceEvent.Type type = event.type(); 238 DeviceEvent.Type type = event.type();
231 - if (type == DEVICE_ADDED || type == DEVICE_REMOVED || 239 + if ((type == DEVICE_ADDED) || (type == DEVICE_REMOVED) ||
232 - type == DEVICE_AVAILABILITY_CHANGED) { 240 + (type == DEVICE_AVAILABILITY_CHANGED)) {
233 processEvent(event); 241 processEvent(event);
234 } 242 }
235 } 243 }
...@@ -268,7 +276,8 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -268,7 +276,8 @@ public class DefaultTopologyProvider extends AbstractProvider
268 try { 276 try {
269 buildTopology(reasons); 277 buildTopology(reasons);
270 } catch (Exception e) { 278 } catch (Exception e) {
271 - log.warn("Unable to compute topology due to: {}", e.getMessage()); 279 + log.warn("Unable to compute topology due to: {}",
280 + e.getMessage());
272 log.debug("Unable to compute topology", e); 281 log.debug("Unable to compute topology", e);
273 } 282 }
274 } 283 }
......
...@@ -61,6 +61,11 @@ public class TopologyResourceTest extends ResourceTest { ...@@ -61,6 +61,11 @@ public class TopologyResourceTest extends ResourceTest {
61 } 61 }
62 62
63 @Override 63 @Override
64 + public long creationTime() {
65 + return 22222L;
66 + }
67 +
68 + @Override
64 public long computeCost() { 69 public long computeCost() {
65 return 0; 70 return 0;
66 } 71 }
......