alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Conflicts:
	core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java

Change-Id: I23a7b1bff399c95499a39f7a00563650f58b7210
Showing 92 changed files with 2042 additions and 191 deletions
......@@ -4,19 +4,17 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import org.apache.commons.lang.NotImplementedException;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.host.PortAddresses;
import org.onlab.onos.sdnip.config.Interface;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import com.google.common.collect.Sets;
/**
* Provides IntefaceService using PortAddresses data from the HostService.
* Provides InterfaceService using PortAddresses data from the HostService.
*/
public class HostToInterfaceAdaptor implements InterfaceService {
......@@ -52,8 +50,17 @@ public class HostToInterfaceAdaptor implements InterfaceService {
@Override
public Interface getMatchingInterface(IpAddress ipAddress) {
// TODO implement
throw new NotImplementedException("getMatchingInteface is not yet implemented");
checkNotNull(ipAddress);
for (PortAddresses portAddresses : hostService.getAddressBindings()) {
for (IpPrefix p : portAddresses.ips()) {
if (p.contains(ipAddress)) {
return new Interface(portAddresses);
}
}
}
return null;
}
}
......
......@@ -64,6 +64,7 @@ public class SdnIp implements SdnIpService {
bgpSessionManager.startUp(2000); // TODO
// TODO need to disable link discovery on external ports
}
@Deactivate
......
package org.onlab.onos.sdnip;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.host.PortAddresses;
import org.onlab.onos.sdnip.config.Interface;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
/**
* Unit tests for the HostToInterfaceAdaptor class.
*/
public class HostToInterfaceAdaptorTest {
private HostService hostService;
private HostToInterfaceAdaptor adaptor;
private Set<PortAddresses> portAddresses;
private Map<ConnectPoint, Interface> interfaces;
private static final ConnectPoint CP1 = new ConnectPoint(
DeviceId.deviceId("of:1"), PortNumber.portNumber(1));
private static final ConnectPoint CP2 = new ConnectPoint(
DeviceId.deviceId("of:1"), PortNumber.portNumber(2));
private static final ConnectPoint CP3 = new ConnectPoint(
DeviceId.deviceId("of:2"), PortNumber.portNumber(1));
private static final ConnectPoint NON_EXISTENT_CP = new ConnectPoint(
DeviceId.deviceId("doesnotexist"), PortNumber.portNumber(1));
private static final PortAddresses DEFAULT_PA = new PortAddresses(
NON_EXISTENT_CP, null, null);
@Before
public void setUp() throws Exception {
hostService = createMock(HostService.class);
portAddresses = Sets.newHashSet();
interfaces = Maps.newHashMap();
createPortAddressesAndInterface(CP1,
Sets.newHashSet(IpPrefix.valueOf("192.168.1.1/24")),
MacAddress.valueOf("00:00:00:00:00:01"));
// Two addresses in the same subnet
createPortAddressesAndInterface(CP2,
Sets.newHashSet(IpPrefix.valueOf("192.168.2.1/24"),
IpPrefix.valueOf("192.168.2.2/24")),
MacAddress.valueOf("00:00:00:00:00:02"));
// Two addresses in different subnets
createPortAddressesAndInterface(CP3,
Sets.newHashSet(IpPrefix.valueOf("192.168.3.1/24"),
IpPrefix.valueOf("192.168.4.1/24")),
MacAddress.valueOf("00:00:00:00:00:03"));
expect(hostService.getAddressBindings()).andReturn(portAddresses).anyTimes();
replay(hostService);
adaptor = new HostToInterfaceAdaptor(hostService);
}
/**
* Creates both a PortAddresses and an Interface for the given inputs and
* places them in the correct global data stores.
*
* @param cp the connect point
* @param ips the set of IP addresses
* @param mac the MAC address
*/
private void createPortAddressesAndInterface(
ConnectPoint cp, Set<IpPrefix> ips, MacAddress mac) {
PortAddresses pa = new PortAddresses(cp, ips, mac);
portAddresses.add(pa);
expect(hostService.getAddressBindingsForPort(cp)).andReturn(pa).anyTimes();
Interface intf = new Interface(cp, ips, mac);
interfaces.put(cp, intf);
}
/**
* Tests {@link HostToInterfaceAdaptor#getInterfaces()}.
* Verifies that the set of interfaces returned matches what is expected
* based on the input PortAddresses data.
*/
@Test
public void testGetInterfaces() {
Set<Interface> adaptorIntfs = adaptor.getInterfaces();
assertEquals(3, adaptorIntfs.size());
assertTrue(adaptorIntfs.contains(this.interfaces.get(CP1)));
assertTrue(adaptorIntfs.contains(this.interfaces.get(CP2)));
assertTrue(adaptorIntfs.contains(this.interfaces.get(CP3)));
}
/**
* Tests {@link HostToInterfaceAdaptor#getInterface(ConnectPoint)}.
* Verifies that the correct interface is returned for a given connect
* point.
*/
@Test
public void testGetInterface() {
assertEquals(this.interfaces.get(CP1), adaptor.getInterface(CP1));
assertEquals(this.interfaces.get(CP2), adaptor.getInterface(CP2));
assertEquals(this.interfaces.get(CP3), adaptor.getInterface(CP3));
// Try and get an interface for a connect point with no addresses
reset(hostService);
expect(hostService.getAddressBindingsForPort(NON_EXISTENT_CP))
.andReturn(DEFAULT_PA).anyTimes();
replay(hostService);
assertNull(adaptor.getInterface(NON_EXISTENT_CP));
}
/**
* Tests {@link HostToInterfaceAdaptor#getInterface(ConnectPoint)} in the
* case that the input connect point is null.
* Verifies that a NullPointerException is thrown.
*/
@Test(expected = NullPointerException.class)
public void testGetInterfaceNull() {
adaptor.getInterface(null);
}
/**
* Tests {@link HostToInterfaceAdaptor#getMatchingInterface(IpAddress)}.
* Verifies that the correct interface is returned based on the given IP
* address.
*/
@Test
public void testGetMatchingInterface() {
assertEquals(this.interfaces.get(CP1),
adaptor.getMatchingInterface(IpAddress.valueOf("192.168.1.100")));
assertEquals(this.interfaces.get(CP2),
adaptor.getMatchingInterface(IpAddress.valueOf("192.168.2.100")));
assertEquals(this.interfaces.get(CP3),
adaptor.getMatchingInterface(IpAddress.valueOf("192.168.3.100")));
assertEquals(this.interfaces.get(CP3),
adaptor.getMatchingInterface(IpAddress.valueOf("192.168.4.100")));
// Try and match an address we don't have subnet configured for
assertNull(adaptor.getMatchingInterface(IpAddress.valueOf("1.1.1.1")));
}
/**
* Tests {@link HostToInterfaceAdaptor#getMatchingInterface(IpAddress)} in the
* case that the input IP address is null.
* Verifies that a NullPointerException is thrown.
*/
@Test(expected = NullPointerException.class)
public void testGetMatchingInterfaceNull() {
adaptor.getMatchingInterface(null);
}
}
......@@ -18,10 +18,13 @@
*/
package org.onlab.onos.cli;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.commands.Option;
import org.apache.karaf.shell.console.OsgiCommandSupport;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.CoreService;
import org.onlab.onos.net.Annotations;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceNotFoundException;
......@@ -76,6 +79,34 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport {
}
/**
* Produces a string image of the specified key/value annotations.
*
* @param annotations key/value annotations
* @return string image with ", k1=v1, k2=v2, ..." pairs
*/
public static String annotations(Annotations annotations) {
StringBuilder sb = new StringBuilder();
for (String key : annotations.keys()) {
sb.append(", ").append(key).append('=').append(annotations.value(key));
}
return sb.toString();
}
/**
* Produces a JSON object from the specified key/value annotations.
*
* @param annotations key/value annotations
* @return JSON object
*/
public static ObjectNode annotations(ObjectMapper mapper, Annotations annotations) {
ObjectNode result = mapper.createObjectNode();
for (String key : annotations.keys()) {
result.put(key, annotations.value(key));
}
return result;
}
/**
* Executes this command.
*/
protected abstract void execute();
......
......@@ -43,7 +43,7 @@ import static org.onlab.onos.net.DeviceId.deviceId;
description = "Lists all ports or all ports of a device")
public class DevicePortsListCommand extends DevicesListCommand {
private static final String FMT = " port=%s, state=%s";
private static final String FMT = " port=%s, state=%s%s";
@Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
required = false, multiValued = false)
......@@ -112,7 +112,8 @@ public class DevicePortsListCommand extends DevicesListCommand {
if (isIncluded(port)) {
ports.add(mapper.createObjectNode()
.put("port", port.number().toString())
.put("isEnabled", port.isEnabled()));
.put("isEnabled", port.isEnabled())
.set("annotations", annotations(mapper, port.annotations())));
}
}
return result.put("device", device.id().toString()).set("ports", ports);
......@@ -131,7 +132,8 @@ public class DevicePortsListCommand extends DevicesListCommand {
Collections.sort(ports, Comparators.PORT_COMPARATOR);
for (Port port : ports) {
if (isIncluded(port)) {
print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled");
print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled",
annotations(port.annotations()));
}
}
}
......
......@@ -41,7 +41,7 @@ import static com.google.common.collect.Lists.newArrayList;
public class DevicesListCommand extends AbstractShellCommand {
private static final String FMT =
"id=%s, available=%s, role=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s";
"id=%s, available=%s, role=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s%s";
@Override
protected void execute() {
......@@ -89,7 +89,8 @@ public class DevicesListCommand extends AbstractShellCommand {
.put("mfr", device.manufacturer())
.put("hw", device.hwVersion())
.put("sw", device.swVersion())
.put("serial", device.serialNumber());
.put("serial", device.serialNumber())
.set("annotations", annotations(mapper, device.annotations()));
}
return result;
}
......@@ -117,7 +118,7 @@ public class DevicesListCommand extends AbstractShellCommand {
print(FMT, device.id(), service.isAvailable(device.id()),
service.getRole(device.id()), device.type(),
device.manufacturer(), device.hwVersion(), device.swVersion(),
device.serialNumber());
device.serialNumber(), annotations(device.annotations()));
}
}
......
......@@ -42,7 +42,7 @@ import static com.google.common.collect.Lists.newArrayList;
public class HostsListCommand extends AbstractShellCommand {
private static final String FMT =
"id=%s, mac=%s, location=%s/%s, vlan=%s, ip(s)=%s";
"id=%s, mac=%s, location=%s/%s, vlan=%s, ip(s)=%s%s";
@Override
protected void execute() {
......@@ -80,6 +80,7 @@ public class HostsListCommand extends AbstractShellCommand {
.put("vlan", host.vlan().toString());
result.set("location", loc);
result.set("ips", ips);
result.set("annotations", annotations(mapper, host.annotations()));
return result;
}
......@@ -105,7 +106,8 @@ public class HostsListCommand extends AbstractShellCommand {
print(FMT, host.id(), host.mac(),
host.location().deviceId(),
host.location().port(),
host.vlan(), host.ipAddresses());
host.vlan(), host.ipAddresses(),
annotations(host.annotations()));
}
}
}
......
......@@ -38,7 +38,7 @@ import static org.onlab.onos.net.DeviceId.deviceId;
description = "Lists all infrastructure links")
public class LinksListCommand extends AbstractShellCommand {
private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s";
private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s%s";
private static final String COMPACT = "%s/%s-%s/%s";
@Argument(index = 0, name = "uri", description = "Device ID",
......@@ -85,6 +85,7 @@ public class LinksListCommand extends AbstractShellCommand {
ObjectNode result = mapper.createObjectNode();
result.set("src", json(mapper, link.src()));
result.set("dst", json(mapper, link.dst()));
result.set("annotations", annotations(mapper, link.annotations()));
return result;
}
......@@ -109,7 +110,8 @@ public class LinksListCommand extends AbstractShellCommand {
*/
public static String linkString(Link link) {
return String.format(FMT, link.src().deviceId(), link.src().port(),
link.dst().deviceId(), link.dst().port(), link.type());
link.dst().deviceId(), link.dst().port(), link.type(),
annotations(link.annotations()));
}
/**
......
......@@ -13,7 +13,7 @@ public interface DeviceProvider extends Provider {
/**
* Triggers an asynchronous probe of the specified device, intended to
* determine whether the host is present or not. An indirect result of this
* determine whether the device is present or not. An indirect result of this
* should be invocation of
* {@link org.onlab.onos.net.device.DeviceProviderService#deviceConnected} )} or
* {@link org.onlab.onos.net.device.DeviceProviderService#deviceDisconnected}
......
package org.onlab.onos.net.intent;
//TODO is this the right package?
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import static com.google.common.base.Preconditions.checkNotNull;
......
package org.onlab.onos.net.intent;
//TODO is this the right package?
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.Objects;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.List;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
/**
* An interface of the class which is assigned to BatchOperation.
*/
public interface BatchOperationTarget {
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.List;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import static com.google.common.base.MoreObjects.toStringHelper;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import static com.google.common.base.MoreObjects.toStringHelper;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.HashMap;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.LinkedList;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import com.google.common.base.Objects;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.intent.BatchOperationTarget;
/**
* Represents a generalized match &amp; action pair to be applied to
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
import org.onlab.onos.net.intent.BatchOperationEntry;
public class FlowRuleBatchEntry
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.Collection;
import org.onlab.onos.net.intent.BatchOperation;
public class FlowRuleBatchOperation
extends BatchOperation<FlowRuleBatchEntry> {
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.event.AbstractEvent;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.event.EventListener;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.concurrent.Future;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.intent.BatchOperation;
import org.onlab.onos.net.provider.Provider;
/**
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.net.provider.ProviderRegistry;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.net.DeviceId;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.concurrent.Future;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.ApplicationId;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.store.StoreDelegate;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.Set;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import java.util.List;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow;
import org.onlab.onos.net.PortNumber;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow.criteria;
import static com.google.common.base.MoreObjects.toStringHelper;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow.criteria;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
* Traffic selection criteria model.
*/
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow.instructions;
/**
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow.instructions;
import static com.google.common.base.MoreObjects.toStringHelper;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow.instructions;
import static com.google.common.base.MoreObjects.toStringHelper;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.flow.instructions;
import static com.google.common.base.MoreObjects.toStringHelper;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
* Traffic treatment model.
*/
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
* Flow rule model &amp; related services API definitions.
*/
......
package org.onlab.onos.net.intent;
//TODO is this the right package?
/**
* An interface of the class which is assigned to BatchOperation.
*/
public interface BatchOperationTarget {
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import com.google.common.collect.ImmutableSet;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import com.google.common.base.MoreObjects;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.NetworkResource;
import org.onlab.onos.net.flow.BatchOperationTarget;
import java.util.Collection;
import java.util.Objects;
......
package org.onlab.onos.net.intent;
/**
* A list of intent operations.
*/
public class IntentBatchOperation extends
BatchOperation<BatchOperationEntry<IntentBatchOperation.Operator, ?>> {
/**
* The intent operators.
*/
public enum Operator {
ADD,
REMOVE,
}
/**
* Adds an add-intent operation.
*
* @param intent the intent to be added
* @return the IntentBatchOperation object if succeeded, null otherwise
*/
public IntentBatchOperation addAddIntentOperation(Intent intent) {
return (null == super.addOperation(
new BatchOperationEntry<Operator, Intent>(Operator.ADD, intent)))
? null : this;
}
/**
* Adds a remove-intent operation.
*
* @param id the ID of intent to be removed
* @return the IntentBatchOperation object if succeeded, null otherwise
*/
public IntentBatchOperation addRemoveIntentOperation(IntentId id) {
return (null == super.addOperation(
new BatchOperationEntry<Operator, IntentId>(Operator.REMOVE, id)))
? null : this;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import java.util.List;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import org.onlab.onos.event.AbstractEvent;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
/**
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import java.util.Map;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import org.onlab.onos.net.flow.BatchOperationTarget;
/**
* Intent identifier suitable as an external key.
* <p/>
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import java.util.List;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import org.onlab.onos.event.EventListener;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
/**
* Abstraction of an intent-related operation, e.g. add, remove, replace.
*/
public class IntentOperation {
private final Type type;
private final IntentId intentId;
private final Intent intent;
/**
* Operation type.
*/
enum Type {
/**
* Indicates that an intent should be added.
*/
SUBMIT,
/**
* Indicates that an intent should be removed.
*/
WITHDRAW,
/**
* Indicates that an intent should be replaced with another.
*/
REPLACE
}
/**
* Creates an intent operation.
*
* @param type operation type
* @param intentId identifier of the intent subject to the operation
* @param intent intent subject
*/
IntentOperation(Type type, IntentId intentId, Intent intent) {
this.type = type;
this.intentId = intentId;
this.intent = intent;
}
/**
* Returns the type of the operation.
*
* @return operation type
*/
public Type type() {
return type;
}
/**
* Returns the identifier of the intent to which this operation applies.
*
* @return intent identifier
*/
public IntentId intentId() {
return intentId;
}
/**
* Returns the intent to which this operation applied. For remove,
* this can be null.
*
* @return intent that is the subject of the operation; null for remove
*/
public Intent intent() {
return intent;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import com.google.common.collect.ImmutableList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.onos.net.intent.IntentOperation.Type.REPLACE;
import static org.onlab.onos.net.intent.IntentOperation.Type.SUBMIT;
import static org.onlab.onos.net.intent.IntentOperation.Type.WITHDRAW;
/**
* Abstraction of a batch of intent submit/withdraw operations.
* Batch of intent submit/withdraw/replace operations.
*/
public final class IntentOperations {
private final List<IntentOperation> operations;
/**
* Creates a batch of intent operations using the supplied list.
*
* @param operations list of intent operations
*/
private IntentOperations(List<IntentOperation> operations) {
this.operations = operations;
}
/**
* List of operations that need to be executed as a unit.
*
* @return list of intent operations
*/
public List<IntentOperation> operations() {
return operations;
}
/**
* Returns a builder for intent operation batches.
*
* @return intent operations builder
*/
public interface IntentOperations {
public static Builder builder() {
return new Builder();
}
// TODO: elaborate once the revised BatchOperation scheme is in place
/**
* Builder for batches of intent operations.
*/
public static final class Builder {
private final ImmutableList.Builder<IntentOperation> builder = ImmutableList.builder();
// Public construction is forbidden.
private Builder() {
}
/**
* Adds an intent submit operation.
*
* @param intent intent to be submitted
* @return self
*/
public Builder addSubmitOperation(Intent intent) {
checkNotNull(intent, "Intent cannot be null");
builder.add(new IntentOperation(SUBMIT, intent.id(), intent));
return this;
}
/**
* Adds an intent submit operation.
*
* @param oldIntentId intent to be replaced
* @param newIntent replacement intent
* @return self
*/
public Builder addReplaceOperation(IntentId oldIntentId, Intent newIntent) {
checkNotNull(oldIntentId, "Intent ID cannot be null");
checkNotNull(newIntent, "Intent cannot be null");
builder.add(new IntentOperation(REPLACE, oldIntentId, newIntent));
return this;
}
/**
* Adds an intent submit operation.
*
* @param intentId identifier of the intent to be withdrawn
* @return self
*/
public Builder addWithdrawOperation(IntentId intentId) {
checkNotNull(intentId, "Intent ID cannot be null");
builder.add(new IntentOperation(WITHDRAW, intentId, null));
return this;
}
/**
* Builds a batch of intent operations.
*
* @return immutable batch of intent operations
*/
public IntentOperations build() {
return new IntentOperations(builder.build());
}
}
}
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import java.util.List;
import java.util.concurrent.Future;
/**
* Service for application submitting or withdrawing their intents.
......@@ -28,6 +47,14 @@ public interface IntentService {
void withdraw(Intent intent);
/**
* Replaces the specified intent with a new one.
*
* @param oldIntentId identifier of the old intent being replaced
* @param newIntent new intent replacing the old one
*/
void replace(IntentId oldIntentId, Intent newIntent);
/**
* Submits a batch of submit &amp; withdraw operations. Such a batch is
* assumed to be processed together.
* <p/>
......@@ -36,7 +63,7 @@ public interface IntentService {
*
* @param operations batch of intent operations
*/
void execute(IntentOperations operations);
Future<IntentOperations> execute(IntentOperations operations);
/**
* Returns an iterable of intents currently in the system.
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
/**
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import org.onlab.onos.store.Store;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import org.onlab.onos.store.StoreDelegate;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import com.google.common.base.MoreObjects;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import com.google.common.base.MoreObjects;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import com.google.common.base.MoreObjects;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import com.google.common.base.MoreObjects;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.onos.net.intent;
import com.google.common.base.MoreObjects;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
* Set of abstractions for conveying high-level intents for treatment of
* selected network traffic by allowing applications to express the
......
......@@ -9,6 +9,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* Fake implementation of the intent service to assist in developing tests of
......@@ -171,11 +172,17 @@ public class FakeIntentManager implements TestableIntentService {
}
@Override
public void execute(IntentOperations operations) {
public void replace(IntentId oldIntentId, Intent newIntent) {
// TODO: implement later
}
@Override
public Future<IntentOperations> execute(IntentOperations operations) {
// TODO: implement later
return null;
}
@Override
public Set<Intent> getIntents() {
return Collections.unmodifiableSet(new HashSet<>(intents.values()));
}
......
......@@ -161,6 +161,17 @@ public class DeviceManager
}
}
// Queries a device for port information.
private void queryPortInfo(DeviceId deviceId) {
Device device = store.getDevice(deviceId);
// FIXME: Device might not be there yet. (eventual consistent)
if (device == null) {
return;
}
DeviceProvider provider = getProvider(device.providerId());
provider.triggerProbe(device);
}
@Override
public void removeDevice(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
......@@ -210,8 +221,6 @@ public class DeviceManager
log.info("Device {} connected", deviceId);
// check my Role
MastershipRole role = mastershipService.requestRoleFor(deviceId);
log.info("## - our role for {} is {} [master is {}]", deviceId, role,
mastershipService.getMasterFor(deviceId));
if (role != MastershipRole.MASTER) {
// TODO: Do we need to explicitly tell the Provider that
// this instance is no longer the MASTER? probably not
......@@ -265,7 +274,6 @@ public class DeviceManager
// but if I was the last STANDBY connection, etc. and no one else
// was there to mark the device offline, this instance may need to
// temporarily request for Master Role and mark offline.
log.info("## for {} role is {}", deviceId, mastershipService.getLocalRole(deviceId));
if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) {
log.debug("Device {} disconnected, but I am not the master", deviceId);
//let go of ability to be backup
......@@ -373,7 +381,6 @@ public class DeviceManager
final DeviceId did = event.subject();
final NodeId myNodeId = clusterService.getLocalNode().id();
log.info("## got Mastershipevent for dev {}", did);
if (myNodeId.equals(event.roleInfo().master())) {
MastershipTerm term = termService.getMastershipTerm(did);
......@@ -384,7 +391,6 @@ public class DeviceManager
return;
}
log.info("## setting term for CPS as new master for {}", did);
// only set the new term if I am the master
deviceClockProviderService.setMastershipTerm(did, term);
......@@ -404,6 +410,7 @@ public class DeviceManager
device.serialNumber(), device.chassisId()));
}
//TODO re-collect device information to fix potential staleness
queryPortInfo(did);
applyRole(did, MastershipRole.MASTER);
} else if (event.roleInfo().backups().contains(myNodeId)) {
applyRole(did, MastershipRole.STANDBY);
......
......@@ -126,7 +126,13 @@ public class IntentManager
// FIXME: implement this method
@Override
public void execute(IntentOperations operations) {
public void replace(IntentId oldIntentId, Intent newIntent) {
throw new UnsupportedOperationException("execute() is not implemented yet");
}
// FIXME: implement this method
@Override
public Future<IntentOperations> execute(IntentOperations operations) {
throw new UnsupportedOperationException("execute() is not implemented yet");
}
......
......@@ -15,6 +15,7 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry
implements EventDeliveryService {
@Override
@SuppressWarnings("unchecked")
public void post(Event event) {
EventSink sink = getSink(event.getClass());
checkState(sink != null, "No sink for event %s", event);
......
package org.onlab.onos.net.flow.impl;
import static java.util.Collections.EMPTY_LIST;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
......@@ -53,7 +50,7 @@ import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.flow.criteria.Criterion;
import org.onlab.onos.net.flow.instructions.Instruction;
import org.onlab.onos.net.intent.BatchOperation;
import org.onlab.onos.net.flow.BatchOperation;
import org.onlab.onos.net.provider.AbstractProvider;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore;
......@@ -63,6 +60,16 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import static java.util.Collections.EMPTY_LIST;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
/**
* Test codifying the flow rule service & flow rule provider service contracts.
*/
......@@ -175,6 +182,7 @@ public class FlowRuleManagerTest {
// TODO: If preserving iteration order is a requirement, redo FlowRuleStore.
//backing store is sensitive to the order of additions/removals
@SuppressWarnings("unchecked")
private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
Iterable<FlowEntry> rules = service.getFlowEntries(DID);
......@@ -542,6 +550,7 @@ public class FlowRuleManagerTest {
}
@Override
@SuppressWarnings("unchecked")
public CompletedBatchOperation get()
throws InterruptedException, ExecutionException {
return new CompletedBatchOperation(true, EMPTY_LIST);
......
......@@ -290,12 +290,17 @@ public class GossipDeviceStore
private DeviceEvent updateDevice(ProviderId providerId,
Device oldDevice,
Device newDevice, Timestamp newTimestamp) {
// We allow only certain attributes to trigger update
if (!Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) ||
!Objects.equals(oldDevice.swVersion(), newDevice.swVersion()) ||
!AnnotationsUtil.isEqual(oldDevice.annotations(), newDevice.annotations())) {
boolean propertiesChanged =
!Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) ||
!Objects.equals(oldDevice.swVersion(), newDevice.swVersion());
boolean annotationsChanged =
!AnnotationsUtil.isEqual(oldDevice.annotations(), newDevice.annotations());
// Primary providers can respond to all changes, but ancillary ones
// should respond only to annotation changes.
if ((providerId.isAncillary() && annotationsChanged) ||
(!providerId.isAncillary() && (propertiesChanged || annotationsChanged))) {
boolean replaced = devices.replace(newDevice.id(), oldDevice, newDevice);
if (!replaced) {
verify(replaced,
......
......@@ -35,6 +35,8 @@ public class InternalDeviceEventSerializer extends Serializer<InternalDeviceEven
Class<InternalDeviceEvent> type) {
ProviderId providerId = (ProviderId) kryo.readClassAndObject(input);
DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
@SuppressWarnings("unchecked")
Timestamped<DeviceDescription> deviceDescription
= (Timestamped<DeviceDescription>) kryo.readClassAndObject(input);
......
......@@ -37,6 +37,8 @@ public class InternalPortEventSerializer extends Serializer<InternalPortEvent> {
Class<InternalPortEvent> type) {
ProviderId providerId = (ProviderId) kryo.readClassAndObject(input);
DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
@SuppressWarnings("unchecked")
Timestamped<List<PortDescription>> portDescriptions
= (Timestamped<List<PortDescription>>) kryo.readClassAndObject(input);
......
......@@ -70,15 +70,16 @@ public class SimpleDeviceStore
public static final String DEVICE_NOT_FOUND = "Device with ID %s not found";
// collection of Description given from various providers
// Collection of Description given from various providers
private final ConcurrentMap<DeviceId, Map<ProviderId, DeviceDescriptions>>
deviceDescs = Maps.newConcurrentMap();
// cache of Device and Ports generated by compositing descriptions from providers
// Cache of Device and Ports generated by compositing descriptions from providers
private final ConcurrentMap<DeviceId, Device> devices = Maps.newConcurrentMap();
private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, Port>> devicePorts = Maps.newConcurrentMap();
private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, Port>>
devicePorts = Maps.newConcurrentMap();
// available(=UP) devices
// Available (=UP) devices
private final Set<DeviceId> availableDevices = Sets.newConcurrentHashSet();
......@@ -115,13 +116,11 @@ public class SimpleDeviceStore
public DeviceEvent createOrUpdateDevice(ProviderId providerId,
DeviceId deviceId,
DeviceDescription deviceDescription) {
Map<ProviderId, DeviceDescriptions> providerDescs
= getOrCreateDeviceDescriptions(deviceId);
synchronized (providerDescs) {
// locking per device
DeviceDescriptions descs
= getOrCreateProviderDeviceDescriptions(providerDescs,
providerId,
......@@ -145,7 +144,6 @@ public class SimpleDeviceStore
// Creates the device and returns the appropriate event if necessary.
// Guarded by deviceDescs value (=Device lock)
private DeviceEvent createDevice(ProviderId providerId, Device newDevice) {
// update composed device cache
Device oldDevice = devices.putIfAbsent(newDevice.id(), newDevice);
verify(oldDevice == null,
......@@ -162,14 +160,21 @@ public class SimpleDeviceStore
// Updates the device and returns the appropriate event if necessary.
// Guarded by deviceDescs value (=Device lock)
private DeviceEvent updateDevice(ProviderId providerId, Device oldDevice, Device newDevice) {
// We allow only certain attributes to trigger update
if (!Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) ||
!Objects.equals(oldDevice.swVersion(), newDevice.swVersion()) ||
!AnnotationsUtil.isEqual(oldDevice.annotations(), newDevice.annotations())) {
boolean propertiesChanged =
!Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) ||
!Objects.equals(oldDevice.swVersion(), newDevice.swVersion());
boolean annotationsChanged =
!AnnotationsUtil.isEqual(oldDevice.annotations(), newDevice.annotations());
// Primary providers can respond to all changes, but ancillary ones
// should respond only to annotation changes.
if ((providerId.isAncillary() && annotationsChanged) ||
(!providerId.isAncillary() && (propertiesChanged || annotationsChanged))) {
boolean replaced = devices.replace(newDevice.id(), oldDevice, newDevice);
if (!replaced) {
// FIXME: Is the enclosing if required here?
verify(replaced,
"Replacing devices cache failed. PID:%s [expected:%s, found:%s, new=%s]",
providerId, oldDevice, devices.get(newDevice.id())
......@@ -214,7 +219,6 @@ public class SimpleDeviceStore
public List<DeviceEvent> updatePorts(ProviderId providerId,
DeviceId deviceId,
List<PortDescription> portDescriptions) {
Device device = devices.get(deviceId);
checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
......@@ -327,7 +331,6 @@ public class SimpleDeviceStore
private DeviceDescriptions getOrCreateProviderDeviceDescriptions(
Map<ProviderId, DeviceDescriptions> device,
ProviderId providerId, DeviceDescription deltaDesc) {
synchronized (device) {
DeviceDescriptions r = device.get(providerId);
if (r == null) {
......@@ -447,7 +450,7 @@ public class SimpleDeviceStore
annotations = merge(annotations, e.getValue().getDeviceDesc().annotations());
}
return new DefaultDevice(primary, deviceId , type, manufacturer,
return new DefaultDevice(primary, deviceId, type, manufacturer,
hwVersion, swVersion, serialNumber,
chassisId, annotations);
}
......
......@@ -110,8 +110,7 @@ public interface OpenFlowSwitch {
*
* @param role the failed role
*/
void returnRoleAssertFailure(RoleState role);
public void returnRoleAssertFailure(RoleState role);
/**
* Indicates if this switch is optical.
......@@ -120,5 +119,4 @@ public interface OpenFlowSwitch {
*/
public boolean isOptical();
}
......
......@@ -20,6 +20,12 @@ public interface OpenFlowSwitchListener {
public void switchRemoved(Dpid dpid);
/**
* Notify that the switch has changed in some way.
* @param dpid the switch that changed
*/
public void switchChanged(Dpid dpid);
/**
* Notify that a port has changed.
* @param dpid the switch on which the change happened.
* @param status the new state of the port.
......
......@@ -565,6 +565,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
@Override
void processOFStatisticsReply(OFChannelHandler h,
OFStatsReply m) {
if (m.getStatsType().equals(OFStatsType.PORT_DESC)) {
h.sw.setPortDescReply((OFPortDescStatsReply) m);
}
h.dispatchMessage(m);
}
......@@ -608,6 +611,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
h.dispatchMessage(m);
}
@Override
void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) {
h.sw.setFeaturesReply(m);
h.dispatchMessage(m);
}
};
private final boolean handshakeComplete;
......
......@@ -27,6 +27,8 @@ import org.onlab.onos.openflow.controller.driver.OpenFlowAgent;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -146,6 +148,11 @@ public class OpenFlowControllerImpl implements OpenFlowController {
l.portChanged(dpid, (OFPortStatus) msg);
}
break;
case FEATURES_REPLY:
for (OpenFlowSwitchListener l : ofSwitchListener) {
l.switchChanged(dpid);
}
break;
case PACKET_IN:
OpenFlowPacketContext pktCtx = DefaultOpenFlowPacketContext
.packetContextFromPacketIn(this.getSwitch(dpid),
......@@ -154,9 +161,15 @@ public class OpenFlowControllerImpl implements OpenFlowController {
p.handlePacket(pktCtx);
}
break;
case STATS_REPLY:
OFStatsReply reply = (OFStatsReply) msg;
if (reply.getStatsType().equals(OFStatsType.PORT_DESC)) {
for (OpenFlowSwitchListener l : ofSwitchListener) {
l.switchChanged(dpid);
}
}
case FLOW_REMOVED:
case ERROR:
case STATS_REPLY:
case BARRIER_REPLY:
executor.submit(new OFMessageHandler(dpid, msg));
break;
......
......@@ -23,7 +23,9 @@ import org.onlab.onos.openflow.controller.OpenFlowController;
import org.onlab.onos.openflow.controller.OpenFlowSwitch;
import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
import org.onlab.onos.openflow.controller.RoleState;
import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
import org.onlab.packet.ChassisId;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFPortConfig;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortState;
......@@ -89,6 +91,28 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
@Override
public void triggerProbe(Device device) {
LOG.info("Triggering probe on device {}", device.id());
// 1. check device liveness
// FIXME if possible, we might want this to be part of
// OpenFlowSwitch interface so the driver interface isn't misused.
OpenFlowSwitch sw = controller.getSwitch(dpid(device.id().uri()));
if (!((OpenFlowSwitchDriver) sw).isConnected()) {
providerService.deviceDisconnected(device.id());
return;
}
// 2. Prompt an update of port information. Do we have an XID for this?
OFFactory fact = sw.factory();
switch (fact.getVersion()) {
case OF_10:
sw.sendMsg(fact.buildFeaturesRequest().setXid(0).build());
break;
case OF_13:
sw.sendMsg(fact.buildPortDescStatsRequest().setXid(0).build());
break;
default:
LOG.warn("Unhandled protocol version");
}
}
@Override
......@@ -141,6 +165,17 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
providerService.deviceDisconnected(deviceId(uri(dpid)));
}
@Override
public void switchChanged(Dpid dpid) {
if (providerService == null) {
return;
}
DeviceId did = deviceId(uri(dpid));
OpenFlowSwitch sw = controller.getSwitch(dpid);
providerService.updatePorts(did, buildPortDescriptions(sw.getPorts()));
}
@Override
public void portChanged(Dpid dpid, OFPortStatus status) {
PortDescription portDescription = buildPortDescription(status.getDesc());
......
......@@ -31,7 +31,7 @@ import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
import org.onlab.onos.net.flow.FlowRuleProvider;
import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
import org.onlab.onos.net.flow.FlowRuleProviderService;
import org.onlab.onos.net.intent.BatchOperation;
import org.onlab.onos.net.flow.BatchOperation;
import org.onlab.onos.net.provider.AbstractProvider;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.net.topology.TopologyService;
......@@ -243,6 +243,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
@Override
public void switchChanged(Dpid dpid) {
}
@Override
public void portChanged(Dpid dpid, OFPortStatus status) {
//TODO: Decide whether to evict flows internal store.
}
......@@ -323,6 +327,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
return false;
}
}
private class InstallationFuture implements Future<CompletedBatchOperation> {
......
......@@ -118,6 +118,12 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
}
@Override
public void switchChanged(Dpid dpid) {
//might not need to do anything since DeviceManager is notified
}
@Override
public void portChanged(Dpid dpid, OFPortStatus status) {
LinkDiscovery ld = discoverers.get(dpid);
......
......@@ -6,6 +6,7 @@ import com.google.common.collect.MutableClassToInstanceMap;
/**
* Service directory implementation suitable for testing.
*/
@SuppressWarnings("unchecked")
public class TestServiceDirectory implements ServiceDirectory {
private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create();
......
/*
Geometry library - based on work by Mike Bostock.
*/
(function() {
if (typeof geo == 'undefined') {
geo = {};
}
var tolerance = 1e-10;
function eq(a, b) {
return (Math.abs(a - b) < tolerance);
}
function gt(a, b) {
return (a - b > -tolerance);
}
function lt(a, b) {
return gt(b, a);
}
geo.eq = eq;
geo.gt = gt;
geo.lt = lt;
geo.LineSegment = function(x1, y1, x2, y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
// Ax + By = C
this.a = y2 - y1;
this.b = x1 - x2;
this.c = x1 * this.a + y1 * this.b;
if (eq(this.a, 0) && eq(this.b, 0)) {
throw new Error(
'Cannot construct a LineSegment with two equal endpoints.');
}
};
geo.LineSegment.prototype.intersect = function(that) {
var d = (this.x1 - this.x2) * (that.y1 - that.y2) -
(this.y1 - this.y2) * (that.x1 - that.x2);
if (eq(d, 0)) {
// The two lines are parallel or very close.
return {
x : NaN,
y : NaN
};
}
var t1 = this.x1 * this.y2 - this.y1 * this.x2,
t2 = that.x1 * that.y2 - that.y1 * that.x2,
x = (t1 * (that.x1 - that.x2) - t2 * (this.x1 - this.x2)) / d,
y = (t1 * (that.y1 - that.y2) - t2 * (this.y1 - this.y2)) / d,
in1 = (gt(x, Math.min(this.x1, this.x2)) && lt(x, Math.max(this.x1, this.x2)) &&
gt(y, Math.min(this.y1, this.y2)) && lt(y, Math.max(this.y1, this.y2))),
in2 = (gt(x, Math.min(that.x1, that.x2)) && lt(x, Math.max(that.x1, that.x2)) &&
gt(y, Math.min(that.y1, that.y2)) && lt(y, Math.max(that.y1, that.y2)));
return {
x : x,
y : y,
in1 : in1,
in2 : in2
};
};
geo.LineSegment.prototype.x = function(y) {
// x = (C - By) / a;
if (this.a) {
return (this.c - this.b * y) / this.a;
} else {
// a == 0 -> horizontal line
return NaN;
}
};
geo.LineSegment.prototype.y = function(x) {
// y = (C - Ax) / b;
if (this.b) {
return (this.c - this.a * x) / this.b;
} else {
// b == 0 -> vertical line
return NaN;
}
};
geo.LineSegment.prototype.length = function() {
return Math.sqrt(
(this.y2 - this.y1) * (this.y2 - this.y1) +
(this.x2 - this.x1) * (this.x2 - this.x1));
};
geo.LineSegment.prototype.offset = function(x, y) {
return new geo.LineSegment(
this.x1 + x, this.y1 + y,
this.x2 + x, this.y2 + y);
};
})();
......@@ -14,6 +14,7 @@
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="onos.css">
<script src="geometry.js"></script>
<script src="onosui.js"></script>
</head>
......@@ -32,20 +33,20 @@
<div id="view"></div>
</div>
// Initialize the UI...
<!-- Initialize the UI...-->
<script type="text/javascript">
var ONOS = $.onos({note: "config, if needed"});
</script>
// include module files
// + mast.js
// + nav.js
// + .... application views
<!-- include module files-->
<!-- + mast.js-->
<!-- + nav.js-->
<!-- + .... application views-->
// for now, we are just bootstrapping the network visualization
<!-- for now, we are just bootstrapping the network visualization-->
<script src="network.js" type="text/javascript"></script>
// finally, build the UI
<!-- finally, build the UI-->
<script type="text/javascript">
$(ONOS.buildUi);
</script>
......
......@@ -10,11 +10,16 @@
var api = onos.api;
var config = {
layering: false,
jsonUrl: 'network.json',
iconUrl: {
pkt: 'pkt.png',
opt: 'opt.png'
},
mastHeight: 32,
force: {
linkDistance: 150,
linkStrength: 0.9,
linkDistance: 240,
linkStrength: 0.8,
charge: -400,
ticksWithoutCollisions: 50,
marginLR: 20,
......@@ -26,8 +31,9 @@
}
},
labels: {
padLR: 3,
padTB: 2,
imgPad: 22,
padLR: 8,
padTB: 6,
marginLR: 3,
marginTB: 2
},
......@@ -53,7 +59,7 @@
d3.json(config.jsonUrl, function (err, data) {
if (err) {
alert('Oops! Error reading JSON...\n\n' +
'URL: ' + jsonUrl + '\n\n' +
'URL: ' + config.jsonUrl + '\n\n' +
'Error: ' + err.message);
return;
}
......@@ -100,7 +106,7 @@
network.data.nodes.forEach(function(n) {
var ypc = yPosConstraintForNode(n),
ix = Math.random() * 0.8 * nw + 0.1 * nw,
ix = Math.random() * 0.6 * nw + 0.2 * nw,
iy = ypc * nh,
node = {
id: n.id,
......@@ -153,10 +159,48 @@
.attr('height', view.height)
.append('g')
.attr('transform', config.force.translate());
// .attr('id', 'zoomable')
// .call(d3.behavior.zoom().on("zoom", zoomRedraw));
// function zoomRedraw() {
// d3.select("#zoomable").attr("transform",
// "translate(" + d3.event.translate + ")"
// + " scale(" + d3.event.scale + ")");
// }
// TODO: svg.append('defs') for markers?
// TODO: move glow/blur stuff to util script
var glow = network.svg.append('filter')
.attr('x', '-50%')
.attr('y', '-50%')
.attr('width', '200%')
.attr('height', '200%')
.attr('id', 'blue-glow');
glow.append('feColorMatrix')
.attr('type', 'matrix')
.attr('values', '0 0 0 0 0 ' +
'0 0 0 0 0 ' +
'0 0 0 0 .7 ' +
'0 0 0 1 0 ');
glow.append('feGaussianBlur')
.attr('stdDeviation', 3)
.attr('result', 'coloredBlur');
glow.append('feMerge').selectAll('feMergeNode')
.data(['coloredBlur', 'SourceGraphic'])
.enter().append('feMergeNode')
.attr('in', String);
// TODO: svg.append('defs')
// TODO: glow/blur stuff
// TODO: legend (and auto adjust on scroll)
// $('#view').on('scroll', function() {
//
// });
network.link = network.svg.append('g').selectAll('.link')
.data(network.force.links(), function(d) {return d.id})
......@@ -164,37 +208,103 @@
.attr('class', 'link');
// TODO: drag behavior
// TODO: closest node deselect
network.draggedThreshold = d3.scale.linear()
.domain([0, 0.1])
.range([5, 20])
.clamp(true);
function dragged(d) {
var threshold = network.draggedThreshold(network.force.alpha()),
dx = d.oldX - d.px,
dy = d.oldY - d.py;
if (Math.abs(dx) >= threshold || Math.abs(dy) >= threshold) {
d.dragged = true;
}
return d.dragged;
}
network.drag = d3.behavior.drag()
.origin(function(d) { return d; })
.on('dragstart', function(d) {
d.oldX = d.x;
d.oldY = d.y;
d.dragged = false;
d.fixed |= 2;
})
.on('drag', function(d) {
d.px = d3.event.x;
d.py = d3.event.y;
if (dragged(d)) {
if (!network.force.alpha()) {
network.force.alpha(.025);
}
}
})
.on('dragend', function(d) {
if (!dragged(d)) {
selectObject(d, this);
}
d.fixed &= ~6;
});
$('#view').on('click', function(e) {
if (!$(e.target).closest('.node').length) {
deselectObject();
}
});
// TODO: add drag, mouseover, mouseout behaviors
network.node = network.svg.selectAll('.node')
.data(network.force.nodes(), function(d) {return d.id})
.enter().append('g')
.attr('class', 'node')
.attr('class', function(d) {
return 'node ' + d.type;
})
.attr('transform', function(d) {
return translate(d.x, d.y);
})
// .call(network.drag)
.on('mouseover', function(d) {})
.on('mouseout', function(d) {});
.call(network.drag)
.on('mouseover', function(d) {
if (!selected.obj) {
if (network.mouseoutTimeout) {
clearTimeout(network.mouseoutTimeout);
network.mouseoutTimeout = null;
}
highlightObject(d);
}
})
.on('mouseout', function(d) {
if (!selected.obj) {
if (network.mouseoutTimeout) {
clearTimeout(network.mouseoutTimeout);
network.mouseoutTimeout = null;
}
network.mouseoutTimeout = setTimeout(function() {
highlightObject(null);
}, 160);
}
});
// TODO: augment stroke and fill functions
network.nodeRect = network.node.append('rect')
// TODO: css for node rects
.attr('rx', 5)
.attr('ry', 5)
.attr('stroke', function(d) { return '#000'})
.attr('fill', function(d) { return '#ddf'})
.attr('width', 60)
.attr('height', 24);
.attr('width', 126)
.attr('height', 40);
network.node.each(function(d) {
var node = d3.select(this),
rect = node.select('rect');
var text = node.append('text')
rect = node.select('rect'),
img = node.append('svg:image')
.attr('x', -16)
.attr('y', -16)
.attr('width', 32)
.attr('height', 32)
.attr('xlink:href', iconUrl(d)),
text = node.append('text')
.text(d.id)
.attr('dx', '1em')
.attr('dy', '2.1em');
.attr('dy', '1.1em'),
dummy;
});
// this function is scheduled to happen soon after the given thread ends
......@@ -207,12 +317,64 @@
first = true;
// NOTE: probably unnecessary code if we only have one line.
text.each(function() {
var box = this.getBBox();
if (first || box.x < bounds.x1) {
bounds.x1 = box.x;
}
if (first || box.y < bounds.y1) {
bounds.y1 = box.y;
}
if (first || box.x + box.width < bounds.x2) {
bounds.x2 = box.x + box.width;
}
if (first || box.y + box.height < bounds.y2) {
bounds.y2 = box.y + box.height;
}
first = false;
}).attr('text-anchor', 'middle');
var lab = config.labels,
oldWidth = bounds.x2 - bounds.x1;
bounds.x1 -= oldWidth / 2;
bounds.x2 -= oldWidth / 2;
bounds.x1 -= (lab.padLR + lab.imgPad);
bounds.y1 -= lab.padTB;
bounds.x2 += lab.padLR;
bounds.y2 += lab.padTB;
node.select('rect')
.attr('x', bounds.x1)
.attr('y', bounds.y1)
.attr('width', bounds.x2 - bounds.x1)
.attr('height', bounds.y2 - bounds.y1);
node.select('image')
.attr('x', bounds.x1);
d.extent = {
left: bounds.x1 - lab.marginLR,
right: bounds.x2 + lab.marginLR,
top: bounds.y1 - lab.marginTB,
bottom: bounds.y2 + lab.marginTB
};
d.edge = {
left : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x1, bounds.y2),
right : new geo.LineSegment(bounds.x2, bounds.y1, bounds.x2, bounds.y2),
top : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x2, bounds.y1),
bottom : new geo.LineSegment(bounds.x1, bounds.y2, bounds.x2, bounds.y2)
};
// ====
});
network.numTicks = 0;
network.preventCollisions = false;
network.force.start();
for (var i = 0; i < config.ticksWithoutCollisions; i++) {
for (var i = 0; i < config.force.ticksWithoutCollisions; i++) {
network.force.tick();
}
network.preventCollisions = true;
......@@ -221,22 +383,78 @@
}
function iconUrl(d) {
return config.iconUrl[d.type];
}
function translate(x, y) {
return 'translate(' + x + ',' + y + ')';
}
function preventCollisions() {
var quadtree = d3.geom.quadtree(network.nodes);
network.nodes.forEach(function(n) {
var nx1 = n.x + n.extent.left,
nx2 = n.x + n.extent.right,
ny1 = n.y + n.extent.top,
ny2 = n.y + n.extent.bottom;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && quad.point !== n) {
// check if the rectangles intersect
var p = quad.point,
px1 = p.x + p.extent.left,
px2 = p.x + p.extent.right,
py1 = p.y + p.extent.top,
py2 = p.y + p.extent.bottom,
ix = (px1 <= nx2 && nx1 <= px2 && py1 <= ny2 && ny1 <= py2);
if (ix) {
var xa1 = nx2 - px1, // shift n left , p right
xa2 = px2 - nx1, // shift n right, p left
ya1 = ny2 - py1, // shift n up , p down
ya2 = py2 - ny1, // shift n down , p up
adj = Math.min(xa1, xa2, ya1, ya2);
if (adj == xa1) {
n.x -= adj / 2;
p.x += adj / 2;
} else if (adj == xa2) {
n.x += adj / 2;
p.x -= adj / 2;
} else if (adj == ya1) {
n.y -= adj / 2;
p.y += adj / 2;
} else if (adj == ya2) {
n.y += adj / 2;
p.y -= adj / 2;
}
}
return ix;
}
});
});
}
function tick(e) {
network.numTicks++;
if (config.layering) {
// adjust the y-coord of each node, based on y-pos constraints
// network.nodes.forEach(function (n) {
// var z = e.alpha * n.constraint.weight;
// if (!isNaN(n.constraint.y)) {
// n.y = (n.constraint.y * z + n.y * (1 - z));
// }
// });
network.nodes.forEach(function (n) {
var z = e.alpha * n.constraint.weight;
if (!isNaN(n.constraint.y)) {
n.y = (n.constraint.y * z + n.y * (1 - z));
}
});
}
if (network.preventCollisions) {
preventCollisions();
}
// TODO: use intersection technique for source end of link also
network.link
.attr('x1', function(d) {
return d.source.x;
......@@ -244,11 +462,24 @@
.attr('y1', function(d) {
return d.source.y;
})
.attr('x2', function(d) {
return d.target.x;
})
.attr('y2', function(d) {
return d.target.y;
.each(function(d) {
var x = d.target.x,
y = d.target.y,
line = new geo.LineSegment(d.source.x, d.source.y, x, y);
for (var e in d.target.edge) {
var ix = line.intersect(d.target.edge[e].offset(x,y));
if (ix.in1 && ix.in2) {
x = ix.x;
y = ix.y;
break;
}
}
d3.select(this)
.attr('x2', x)
.attr('y2', y);
});
network.node
......
......@@ -7,50 +7,50 @@
},
"nodes": [
{
"id": "switch-1",
"id": "sample1",
"type": "opt",
"status": "good"
},
{
"id": "switch-2",
"id": "00:00:00:00:00:00:00:02",
"type": "opt",
"status": "good"
},
{
"id": "switch-3",
"id": "00:00:00:00:00:00:00:03",
"type": "opt",
"status": "good"
},
{
"id": "switch-4",
"id": "00:00:00:00:00:00:00:04",
"type": "opt",
"status": "good"
},
{
"id": "switch-11",
"id": "00:00:00:00:00:00:00:11",
"type": "pkt",
"status": "good"
},
{
"id": "switch-12",
"id": "00:00:00:00:00:00:00:12",
"type": "pkt",
"status": "good"
},
{
"id": "switch-13",
"id": "00:00:00:00:00:00:00:13",
"type": "pkt",
"status": "good"
}
],
"links": [
{ "src": "switch-1", "dst": "switch-2" },
{ "src": "switch-1", "dst": "switch-3" },
{ "src": "switch-1", "dst": "switch-4" },
{ "src": "switch-2", "dst": "switch-3" },
{ "src": "switch-2", "dst": "switch-4" },
{ "src": "switch-3", "dst": "switch-4" },
{ "src": "switch-13", "dst": "switch-3" },
{ "src": "switch-12", "dst": "switch-2" },
{ "src": "switch-11", "dst": "switch-1" }
{ "src": "sample1", "dst": "00:00:00:00:00:00:00:02" },
{ "src": "sample1", "dst": "00:00:00:00:00:00:00:03" },
{ "src": "sample1", "dst": "00:00:00:00:00:00:00:04" },
{ "src": "00:00:00:00:00:00:00:02", "dst": "00:00:00:00:00:00:00:03" },
{ "src": "00:00:00:00:00:00:00:02", "dst": "00:00:00:00:00:00:00:04" },
{ "src": "00:00:00:00:00:00:00:03", "dst": "00:00:00:00:00:00:00:04" },
{ "src": "00:00:00:00:00:00:00:13", "dst": "00:00:00:00:00:00:00:03" },
{ "src": "00:00:00:00:00:00:00:12", "dst": "00:00:00:00:00:00:00:02" },
{ "src": "00:00:00:00:00:00:00:11", "dst": "sample1" }
]
}
......
......@@ -13,7 +13,7 @@ body, html {
*/
span.title {
color: red;
color: darkblue;
font-size: 16pt;
font-style: italic;
}
......@@ -30,7 +30,7 @@ span.right {
* === DEBUGGING ======
*/
svg {
border: 1px dashed red;
/*border: 1px dashed red;*/
}
......@@ -64,36 +64,47 @@ marker#end {
-moz-transition: opacity 250ms;
}
.node text {
fill: #000;
/*differentiate between packet and optical nodes*/
svg .node.pkt rect {
fill: #77a;
}
svg .node.opt rect {
fill: #7a7;
}
svg .node text {
fill: white;
font: 10px sans-serif;
pointer-events: none;
}
.node.selected rect {
svg .node.selected rect {
filter: url(#blue-glow);
}
.link.inactive,
.node.inactive rect,
.node.inactive text {
svg .link.inactive,
svg .node.inactive rect,
svg .node.inactive text,
svg .node.inactive image {
opacity: .2;
}
.node.inactive.selected rect,
.node.inactive.selected text {
svg .node.inactive.selected rect,
svg .node.inactive.selected text,
svg .node.inactive.selected image {
opacity: .6;
}
.legend {
svg .legend {
position: fixed;
}
.legend .category rect {
svg .legend .category rect {
stroke-width: 1px;
}
.legend .category text {
svg .legend .category text {
fill: #000;
font: 10px sans-serif;
pointer-events: none;
......@@ -110,15 +121,15 @@ marker#end {
#frame {
width: 100%;
height: 100%;
background-color: #ffd;
background-color: #cdf;
}
#mast {
height: 32px;
background-color: #dda;
background-color: #abe;
vertical-align: baseline;
}
#main {
background-color: #99b;
background-color: #99c;
}
......