alshabib

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

Showing 55 changed files with 699 additions and 177 deletions
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
23 <artifactId>onos-api</artifactId> 23 <artifactId>onos-api</artifactId>
24 </dependency> 24 </dependency>
25 <dependency> 25 <dependency>
26 + <groupId>org.onlab.onos</groupId>
27 + <artifactId>onlab-osgi</artifactId>
28 + </dependency>
29 + <dependency>
26 <groupId>org.osgi</groupId> 30 <groupId>org.osgi</groupId>
27 <artifactId>org.osgi.core</artifactId> 31 <artifactId>org.osgi.core</artifactId>
28 </dependency> 32 </dependency>
......
1 package org.onlab.onos.cli; 1 package org.onlab.onos.cli;
2 2
3 import org.apache.karaf.shell.console.OsgiCommandSupport; 3 import org.apache.karaf.shell.console.OsgiCommandSupport;
4 -import org.osgi.framework.BundleContext; 4 +import org.onlab.osgi.DefaultServiceDirectory;
5 -import org.osgi.framework.FrameworkUtil; 5 +import org.onlab.osgi.ServiceNotFoundException;
6 6
7 /** 7 /**
8 * Base abstraction of Karaf shell commands. 8 * Base abstraction of Karaf shell commands.
...@@ -15,10 +15,10 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { ...@@ -15,10 +15,10 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport {
15 * @param serviceClass service class 15 * @param serviceClass service class
16 * @param <T> type of service 16 * @param <T> type of service
17 * @return service implementation 17 * @return service implementation
18 + * @throws org.onlab.osgi.ServiceNotFoundException if service is unavailable
18 */ 19 */
19 public static <T> T get(Class<T> serviceClass) { 20 public static <T> T get(Class<T> serviceClass) {
20 - BundleContext bc = FrameworkUtil.getBundle(AbstractShellCommand.class).getBundleContext(); 21 + return DefaultServiceDirectory.getService(serviceClass);
21 - return bc.getService(bc.getServiceReference(serviceClass));
22 } 22 }
23 23
24 /** 24 /**
...@@ -27,7 +27,7 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { ...@@ -27,7 +27,7 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport {
27 * @param format format string; see {@link String#format} 27 * @param format format string; see {@link String#format}
28 * @param args arguments 28 * @param args arguments
29 */ 29 */
30 - public static void print(String format, Object... args) { 30 + public void print(String format, Object... args) {
31 System.out.println(String.format(format, args)); 31 System.out.println(String.format(format, args));
32 } 32 }
33 33
...@@ -37,8 +37,23 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { ...@@ -37,8 +37,23 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport {
37 * @param format format string; see {@link String#format} 37 * @param format format string; see {@link String#format}
38 * @param args arguments 38 * @param args arguments
39 */ 39 */
40 - public static void error(String format, Object... args) { 40 + public void error(String format, Object... args) {
41 System.err.println(String.format(format, args)); 41 System.err.println(String.format(format, args));
42 } 42 }
43 43
44 + /**
45 + * Executes this command.
46 + */
47 + protected abstract void execute();
48 +
49 + @Override
50 + protected Object doExecute() throws Exception {
51 + try {
52 + execute();
53 + } catch (ServiceNotFoundException e) {
54 + error(e.getMessage());
55 + }
56 + return null;
57 + }
58 +
44 } 59 }
......
...@@ -29,8 +29,8 @@ public class NodesListCommand extends AbstractShellCommand { ...@@ -29,8 +29,8 @@ public class NodesListCommand extends AbstractShellCommand {
29 }; 29 };
30 30
31 @Override 31 @Override
32 - protected Object doExecute() throws Exception { 32 + protected void execute() {
33 - ClusterService service = getService(ClusterService.class); 33 + ClusterService service = get(ClusterService.class);
34 List<ControllerNode> nodes = newArrayList(service.getNodes()); 34 List<ControllerNode> nodes = newArrayList(service.getNodes());
35 Collections.sort(nodes, ID_COMPARATOR); 35 Collections.sort(nodes, ID_COMPARATOR);
36 ControllerNode self = service.getLocalNode(); 36 ControllerNode self = service.getLocalNode();
...@@ -39,7 +39,6 @@ public class NodesListCommand extends AbstractShellCommand { ...@@ -39,7 +39,6 @@ public class NodesListCommand extends AbstractShellCommand {
39 service.getState(node.id()), 39 service.getState(node.id()),
40 node.equals(self) ? "*" : ""); 40 node.equals(self) ? "*" : "");
41 } 41 }
42 - return null;
43 } 42 }
44 43
45 } 44 }
......
...@@ -31,7 +31,7 @@ public class ClusterDevicesCommand extends ClustersListCommand { ...@@ -31,7 +31,7 @@ public class ClusterDevicesCommand extends ClustersListCommand {
31 }; 31 };
32 32
33 @Override 33 @Override
34 - protected Object doExecute() throws Exception { 34 + protected void execute() {
35 int cid = Integer.parseInt(id); 35 int cid = Integer.parseInt(id);
36 init(); 36 init();
37 TopologyCluster cluster = service.getCluster(topology, clusterId(cid)); 37 TopologyCluster cluster = service.getCluster(topology, clusterId(cid));
...@@ -44,8 +44,6 @@ public class ClusterDevicesCommand extends ClustersListCommand { ...@@ -44,8 +44,6 @@ public class ClusterDevicesCommand extends ClustersListCommand {
44 print("%s", deviceId); 44 print("%s", deviceId);
45 } 45 }
46 } 46 }
47 -
48 - return null;
49 } 47 }
50 48
51 49
......
...@@ -20,7 +20,7 @@ public class ClusterLinksCommand extends ClustersListCommand { ...@@ -20,7 +20,7 @@ public class ClusterLinksCommand extends ClustersListCommand {
20 String id = null; 20 String id = null;
21 21
22 @Override 22 @Override
23 - protected Object doExecute() throws Exception { 23 + protected void execute() {
24 int cid = Integer.parseInt(id); 24 int cid = Integer.parseInt(id);
25 init(); 25 init();
26 TopologyCluster cluster = service.getCluster(topology, clusterId(cid)); 26 TopologyCluster cluster = service.getCluster(topology, clusterId(cid));
...@@ -31,7 +31,6 @@ public class ClusterLinksCommand extends ClustersListCommand { ...@@ -31,7 +31,6 @@ public class ClusterLinksCommand extends ClustersListCommand {
31 print(linkString(link)); 31 print(linkString(link));
32 } 32 }
33 } 33 }
34 - return null;
35 } 34 }
36 35
37 } 36 }
......
...@@ -27,7 +27,7 @@ public class ClustersListCommand extends TopologyCommand { ...@@ -27,7 +27,7 @@ public class ClustersListCommand extends TopologyCommand {
27 }; 27 };
28 28
29 @Override 29 @Override
30 - protected Object doExecute() throws Exception { 30 + protected void execute() {
31 init(); 31 init();
32 List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology)); 32 List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology));
33 Collections.sort(clusters, ID_COMPARATOR); 33 Collections.sort(clusters, ID_COMPARATOR);
...@@ -35,7 +35,6 @@ public class ClustersListCommand extends TopologyCommand { ...@@ -35,7 +35,6 @@ public class ClustersListCommand extends TopologyCommand {
35 for (TopologyCluster cluster : clusters) { 35 for (TopologyCluster cluster : clusters) {
36 print(FMT, cluster.id().index(), cluster.deviceCount(), cluster.linkCount()); 36 print(FMT, cluster.id().index(), cluster.deviceCount(), cluster.linkCount());
37 } 37 }
38 - return null;
39 } 38 }
40 39
41 } 40 }
......
...@@ -35,8 +35,8 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -35,8 +35,8 @@ public class DevicePortsListCommand extends DevicesListCommand {
35 }; 35 };
36 36
37 @Override 37 @Override
38 - protected Object doExecute() throws Exception { 38 + protected void execute() {
39 - DeviceService service = getService(DeviceService.class); 39 + DeviceService service = get(DeviceService.class);
40 if (uri == null) { 40 if (uri == null) {
41 for (Device device : getSortedDevices(service)) { 41 for (Device device : getSortedDevices(service)) {
42 printDevice(service, device); 42 printDevice(service, device);
...@@ -49,7 +49,6 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -49,7 +49,6 @@ public class DevicePortsListCommand extends DevicesListCommand {
49 printDevice(service, device); 49 printDevice(service, device);
50 } 50 }
51 } 51 }
52 - return null;
53 } 52 }
54 53
55 @Override 54 @Override
......
...@@ -18,9 +18,8 @@ public class DeviceRemoveCommand extends AbstractShellCommand { ...@@ -18,9 +18,8 @@ public class DeviceRemoveCommand extends AbstractShellCommand {
18 String uri = null; 18 String uri = null;
19 19
20 @Override 20 @Override
21 - protected Object doExecute() throws Exception { 21 + protected void execute() {
22 - getService(DeviceAdminService.class).removeDevice(DeviceId.deviceId(uri)); 22 + get(DeviceAdminService.class).removeDevice(DeviceId.deviceId(uri));
23 - return null;
24 } 23 }
25 24
26 } 25 }
......
...@@ -23,11 +23,10 @@ public class DeviceRoleCommand extends AbstractShellCommand { ...@@ -23,11 +23,10 @@ public class DeviceRoleCommand extends AbstractShellCommand {
23 String role = null; 23 String role = null;
24 24
25 @Override 25 @Override
26 - protected Object doExecute() throws Exception { 26 + protected void execute() {
27 MastershipRole mastershipRole = MastershipRole.valueOf(role.toUpperCase()); 27 MastershipRole mastershipRole = MastershipRole.valueOf(role.toUpperCase());
28 - getService(DeviceAdminService.class).setRole(DeviceId.deviceId(uri), 28 + get(DeviceAdminService.class).setRole(DeviceId.deviceId(uri),
29 mastershipRole); 29 mastershipRole);
30 - return null;
31 } 30 }
32 31
33 } 32 }
......
...@@ -29,12 +29,11 @@ public class DevicesListCommand extends AbstractShellCommand { ...@@ -29,12 +29,11 @@ public class DevicesListCommand extends AbstractShellCommand {
29 }; 29 };
30 30
31 @Override 31 @Override
32 - protected Object doExecute() throws Exception { 32 + protected void execute() {
33 - DeviceService service = getService(DeviceService.class); 33 + DeviceService service = get(DeviceService.class);
34 for (Device device : getSortedDevices(service)) { 34 for (Device device : getSortedDevices(service)) {
35 printDevice(service, device); 35 printDevice(service, device);
36 } 36 }
37 - return null;
38 } 37 }
39 38
40 /** 39 /**
......
...@@ -34,14 +34,13 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -34,14 +34,13 @@ public class FlowsListCommand extends AbstractShellCommand {
34 }; 34 };
35 35
36 @Override 36 @Override
37 - protected Object doExecute() throws Exception { 37 + protected void execute() {
38 - DeviceService deviceService = getService(DeviceService.class); 38 + DeviceService deviceService = get(DeviceService.class);
39 - FlowRuleService service = getService(FlowRuleService.class); 39 + FlowRuleService service = get(FlowRuleService.class);
40 Map<Device, List<FlowRule>> flows = getSortedFlows(deviceService, service); 40 Map<Device, List<FlowRule>> flows = getSortedFlows(deviceService, service);
41 for (Device d : deviceService.getDevices()) { 41 for (Device d : deviceService.getDevices()) {
42 printFlows(d, flows.get(d)); 42 printFlows(d, flows.get(d));
43 } 43 }
44 - return null;
45 } 44 }
46 45
47 46
......
...@@ -29,12 +29,11 @@ public class HostsListCommand extends AbstractShellCommand { ...@@ -29,12 +29,11 @@ public class HostsListCommand extends AbstractShellCommand {
29 }; 29 };
30 30
31 @Override 31 @Override
32 - protected Object doExecute() throws Exception { 32 + protected void execute() {
33 - HostService service = getService(HostService.class); 33 + HostService service = get(HostService.class);
34 for (Host host : getSortedHosts(service)) { 34 for (Host host : getSortedHosts(service)) {
35 printHost(host); 35 printHost(host);
36 } 36 }
37 - return null;
38 } 37 }
39 38
40 /** 39 /**
......
...@@ -23,14 +23,13 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -23,14 +23,13 @@ public class LinksListCommand extends AbstractShellCommand {
23 String uri = null; 23 String uri = null;
24 24
25 @Override 25 @Override
26 - protected Object doExecute() throws Exception { 26 + protected void execute() {
27 - LinkService service = getService(LinkService.class); 27 + LinkService service = get(LinkService.class);
28 Iterable<Link> links = uri != null ? 28 Iterable<Link> links = uri != null ?
29 service.getDeviceLinks(deviceId(uri)) : service.getLinks(); 29 service.getDeviceLinks(deviceId(uri)) : service.getLinks();
30 for (Link link : links) { 30 for (Link link : links) {
31 print(linkString(link)); 31 print(linkString(link));
32 } 32 }
33 - return null;
34 } 33 }
35 34
36 /** 35 /**
......
...@@ -29,13 +29,12 @@ public class PathListCommand extends TopologyCommand { ...@@ -29,13 +29,12 @@ public class PathListCommand extends TopologyCommand {
29 String dst = null; 29 String dst = null;
30 30
31 @Override 31 @Override
32 - protected Object doExecute() throws Exception { 32 + protected void execute() {
33 init(); 33 init();
34 Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst)); 34 Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst));
35 for (Path path : paths) { 35 for (Path path : paths) {
36 print(pathString(path)); 36 print(pathString(path));
37 } 37 }
38 - return null;
39 } 38 }
40 39
41 /** 40 /**
......
...@@ -23,16 +23,15 @@ public class TopologyCommand extends AbstractShellCommand { ...@@ -23,16 +23,15 @@ public class TopologyCommand extends AbstractShellCommand {
23 * Initializes the context for all cluster commands. 23 * Initializes the context for all cluster commands.
24 */ 24 */
25 protected void init() { 25 protected void init() {
26 - service = getService(TopologyService.class); 26 + service = get(TopologyService.class);
27 topology = service.currentTopology(); 27 topology = service.currentTopology();
28 } 28 }
29 29
30 @Override 30 @Override
31 - protected Object doExecute() throws Exception { 31 + protected void execute() {
32 init(); 32 init();
33 print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(), 33 print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(),
34 topology.clusterCount(), topology.pathCount()); 34 topology.clusterCount(), topology.pathCount());
35 - return null;
36 } 35 }
37 36
38 } 37 }
......
...@@ -16,7 +16,7 @@ import org.onlab.onos.net.host.HostService; ...@@ -16,7 +16,7 @@ import org.onlab.onos.net.host.HostService;
16 public class WipeOutCommand extends ClustersListCommand { 16 public class WipeOutCommand extends ClustersListCommand {
17 17
18 @Override 18 @Override
19 - protected Object doExecute() throws Exception { 19 + protected void execute() {
20 DeviceAdminService deviceAdminService = get(DeviceAdminService.class); 20 DeviceAdminService deviceAdminService = get(DeviceAdminService.class);
21 DeviceService deviceService = get(DeviceService.class); 21 DeviceService deviceService = get(DeviceService.class);
22 for (Device device : deviceService.getDevices()) { 22 for (Device device : deviceService.getDevices()) {
...@@ -28,7 +28,6 @@ public class WipeOutCommand extends ClustersListCommand { ...@@ -28,7 +28,6 @@ public class WipeOutCommand extends ClustersListCommand {
28 for (Host host : hostService.getHosts()) { 28 for (Host host : hostService.getHosts()) {
29 hostAdminService.removeHost(host.id()); 29 hostAdminService.removeHost(host.id());
30 } 30 }
31 - return null;
32 } 31 }
33 32
34 33
......
1 +package org.onlab.onos.cluster;
2 +
3 +import org.onlab.onos.net.MastershipRole;
4 +import org.onlab.onos.net.provider.Provider;
5 +
6 +/**
7 + * Abstraction of a mastership information provider.
8 + */
9 +public interface MastershipProvider extends Provider {
10 + // do we get role info from the local OFcontroller impl?
11 + // needs to also read from distributed store and emit events?
12 + // roleChanged(DeviceId deviceId, MastershipRole newRole);
13 +}
1 +package org.onlab.onos.cluster;
2 +
3 +import org.onlab.onos.net.DeviceId;
4 +import org.onlab.onos.net.MastershipRole;
5 +import org.onlab.onos.net.provider.ProviderService;
6 +
7 +public interface MastershipProviderService extends
8 + ProviderService<MastershipProvider> {
9 +
10 + /**
11 + * Signals the core that mastership has changed for a device.
12 + *
13 + * @param deviceId the device ID
14 + * @param role the new mastership role of this controller instance
15 + */
16 + void roleChanged(NodeId nodeId, DeviceId deviceId, MastershipRole role);
17 +
18 +}
...@@ -37,6 +37,9 @@ public interface MastershipService { ...@@ -37,6 +37,9 @@ public interface MastershipService {
37 */ 37 */
38 MastershipRole requestRoleFor(DeviceId deviceId); 38 MastershipRole requestRoleFor(DeviceId deviceId);
39 39
40 + // TODO: add facet for requesting a different master than the current one;
41 + // abandon mastership (due to loss of connection)
42 +
40 /** 43 /**
41 * Adds the specified mastership change listener. 44 * Adds the specified mastership change listener.
42 * 45 *
......
...@@ -25,7 +25,7 @@ public interface MastershipStore { ...@@ -25,7 +25,7 @@ public interface MastershipStore {
25 MastershipRole role); 25 MastershipRole role);
26 26
27 /** 27 /**
28 - * Adds or updates the mastership information for a device. 28 + * Adds or updates mastership information for a device.
29 * 29 *
30 * @param instance controller instance identifier 30 * @param instance controller instance identifier
31 * @param deviceId device identifier 31 * @param deviceId device identifier
......
...@@ -2,13 +2,7 @@ package org.onlab.onos.net; ...@@ -2,13 +2,7 @@ package org.onlab.onos.net;
2 2
3 import static com.google.common.base.MoreObjects.toStringHelper; 3 import static com.google.common.base.MoreObjects.toStringHelper;
4 4
5 -import java.util.Collections;
6 import java.util.Objects; 5 import java.util.Objects;
7 -import java.util.Set;
8 -
9 -import org.onlab.packet.IpPrefix;
10 -
11 -import com.google.common.collect.ImmutableSet;
12 6
13 /** 7 /**
14 * Default port implementation. 8 * Default port implementation.
...@@ -19,36 +13,18 @@ public class DefaultPort implements Port { ...@@ -19,36 +13,18 @@ public class DefaultPort implements Port {
19 private final PortNumber number; 13 private final PortNumber number;
20 private final boolean isEnabled; 14 private final boolean isEnabled;
21 15
22 - // Attributes
23 - private final Set<IpPrefix> ipAddresses;
24 -
25 - /**
26 - * Creates a network element attributed to the specified provider.
27 - *
28 - * @param element parent network element
29 - * @param number port number
30 - * @param isEnabled indicator whether the port is up and active
31 - */
32 - public DefaultPort(Element element, PortNumber number,
33 - boolean isEnabled) {
34 - this(element, number, isEnabled, null);
35 - }
36 -
37 /** 16 /**
38 * Creates a network element attributed to the specified provider. 17 * Creates a network element attributed to the specified provider.
39 * 18 *
40 * @param element parent network element 19 * @param element parent network element
41 * @param number port number 20 * @param number port number
42 * @param isEnabled indicator whether the port is up and active 21 * @param isEnabled indicator whether the port is up and active
43 - * @param ipAddresses set of IP addresses assigned to the port
44 */ 22 */
45 public DefaultPort(Element element, PortNumber number, 23 public DefaultPort(Element element, PortNumber number,
46 - boolean isEnabled, Set<IpPrefix> ipAddresses) { 24 + boolean isEnabled) {
47 this.element = element; 25 this.element = element;
48 this.number = number; 26 this.number = number;
49 this.isEnabled = isEnabled; 27 this.isEnabled = isEnabled;
50 - this.ipAddresses = (ipAddresses == null) ? Collections.<IpPrefix>emptySet() :
51 - ImmutableSet.copyOf(ipAddresses);
52 } 28 }
53 29
54 @Override 30 @Override
...@@ -94,9 +70,4 @@ public class DefaultPort implements Port { ...@@ -94,9 +70,4 @@ public class DefaultPort implements Port {
94 return element; 70 return element;
95 } 71 }
96 72
97 - @Override
98 - public Set<IpPrefix> ipAddresses() {
99 - return ipAddresses;
100 - }
101 -
102 } 73 }
......
1 package org.onlab.onos.net; 1 package org.onlab.onos.net;
2 2
3 -import java.util.Set;
4 -
5 -import org.onlab.packet.IpPrefix;
6 3
7 /** 4 /**
8 * Abstraction of a network port. 5 * Abstraction of a network port.
...@@ -32,12 +29,4 @@ public interface Port { ...@@ -32,12 +29,4 @@ public interface Port {
32 29
33 // set of port attributes 30 // set of port attributes
34 31
35 - /**
36 - * Returns the set of IP addresses that are logically configured on this
37 - * port.
38 - *
39 - * @return the set of IP addresses configured on the port. The set is empty
40 - * if no addresses are configured.
41 - */
42 - Set<IpPrefix> ipAddresses();
43 } 32 }
......
...@@ -15,7 +15,7 @@ public interface DeviceAdminService { ...@@ -15,7 +15,7 @@ public interface DeviceAdminService {
15 * @param role requested role 15 * @param role requested role
16 * @deprecated Will be removed in favor of MastershipAdminService.setRole() 16 * @deprecated Will be removed in favor of MastershipAdminService.setRole()
17 */ 17 */
18 - @Deprecated 18 +// @Deprecated
19 void setRole(DeviceId deviceId, MastershipRole role); 19 void setRole(DeviceId deviceId, MastershipRole role);
20 20
21 /** 21 /**
......
1 package org.onlab.onos.net.host; 1 package org.onlab.onos.net.host;
2 2
3 +import java.util.Set;
4 +
5 +import org.onlab.onos.net.ConnectPoint;
3 import org.onlab.onos.net.HostId; 6 import org.onlab.onos.net.HostId;
7 +import org.onlab.packet.IpAddress;
8 +import org.onlab.packet.MacAddress;
4 9
5 /** 10 /**
6 * Service for administering the inventory of end-station hosts. 11 * Service for administering the inventory of end-station hosts.
...@@ -14,4 +19,42 @@ public interface HostAdminService { ...@@ -14,4 +19,42 @@ public interface HostAdminService {
14 */ 19 */
15 void removeHost(HostId hostId); 20 void removeHost(HostId hostId);
16 21
22 + /**
23 + * Binds an IP address and optional MAC address to the given connection
24 + * point.
25 + * <p/>
26 + * This method will overwrite any previously held address information for
27 + * the connection point.
28 + *
29 + * @param ip the IP address to bind to the connection point. This parameter
30 + * is mandatory and cannot be null.
31 + * @param mac the optional MAC address to bind to the connection point. Can
32 + * be set to null if no MAC address needs to be bound.
33 + * @param connectPoint the connection point to bind the addresses to
34 + */
35 + void bindAddressesToPort(IpAddress ip, MacAddress mac, ConnectPoint connectPoint);
36 +
37 + /**
38 + * Removes all address information for the given connection point.
39 + *
40 + * @param connectPoint the connection point to remove address information
41 + */
42 + void unbindAddressesFromPort(ConnectPoint connectPoint);
43 +
44 + /**
45 + * Returns the addresses information for all connection points.
46 + *
47 + * @return the set of address bindings for all connection points
48 + */
49 + Set<PortAddresses> getAddressBindings();
50 +
51 + /**
52 + * Retrieves the addresses that have been bound to the given connection
53 + * point.
54 + *
55 + * @param connectPoint the connection point to retrieve address bindings
56 + * for
57 + * @return addresses bound to the port
58 + */
59 + PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint);
17 } 60 }
......
...@@ -6,6 +6,7 @@ import org.onlab.onos.net.ConnectPoint; ...@@ -6,6 +6,7 @@ import org.onlab.onos.net.ConnectPoint;
6 import org.onlab.onos.net.DeviceId; 6 import org.onlab.onos.net.DeviceId;
7 import org.onlab.onos.net.Host; 7 import org.onlab.onos.net.Host;
8 import org.onlab.onos.net.HostId; 8 import org.onlab.onos.net.HostId;
9 +import org.onlab.packet.IpAddress;
9 import org.onlab.packet.IpPrefix; 10 import org.onlab.packet.IpPrefix;
10 import org.onlab.packet.MacAddress; 11 import org.onlab.packet.MacAddress;
11 import org.onlab.packet.VlanId; 12 import org.onlab.packet.VlanId;
...@@ -87,7 +88,7 @@ public interface HostService { ...@@ -87,7 +88,7 @@ public interface HostService {
87 * 88 *
88 * @param ip IP address of the host to monitor 89 * @param ip IP address of the host to monitor
89 */ 90 */
90 - void monitorIp(IpPrefix ip); 91 + void startMonitoringIp(IpAddress ip);
91 92
92 /** 93 /**
93 * Stops the host service from monitoring an IP address. 94 * Stops the host service from monitoring an IP address.
...@@ -95,7 +96,18 @@ public interface HostService { ...@@ -95,7 +96,18 @@ public interface HostService {
95 * @param ip IP address to stop monitoring 96 * @param ip IP address to stop monitoring
96 */ 97 */
97 // TODO clients can cancel other client's requests 98 // TODO clients can cancel other client's requests
98 - void stopMonitoringIp(IpPrefix ip); 99 + void stopMonitoringIp(IpAddress ip);
100 +
101 + /**
102 + * Requests the host service to resolve the MAC address for the given IP
103 + * address.
104 + * <p/>
105 + * This will trigger a notification to the host listeners if the MAC
106 + * address is found.
107 + *
108 + * @param ip IP address to find the MAC address for
109 + */
110 + void requestMac(IpAddress ip);
99 111
100 /** 112 /**
101 * Adds the specified host listener. 113 * Adds the specified host listener.
......
1 package org.onlab.onos.net.host; 1 package org.onlab.onos.net.host;
2 2
3 +import java.util.Set;
4 +
3 import org.onlab.onos.net.ConnectPoint; 5 import org.onlab.onos.net.ConnectPoint;
4 import org.onlab.onos.net.DeviceId; 6 import org.onlab.onos.net.DeviceId;
5 import org.onlab.onos.net.Host; 7 import org.onlab.onos.net.Host;
...@@ -9,8 +11,6 @@ import org.onlab.packet.IpPrefix; ...@@ -9,8 +11,6 @@ import org.onlab.packet.IpPrefix;
9 import org.onlab.packet.MacAddress; 11 import org.onlab.packet.MacAddress;
10 import org.onlab.packet.VlanId; 12 import org.onlab.packet.VlanId;
11 13
12 -import java.util.Set;
13 -
14 /** 14 /**
15 * Manages inventory of end-station hosts; not intended for direct use. 15 * Manages inventory of end-station hosts; not intended for direct use.
16 */ 16 */
...@@ -98,4 +98,34 @@ public interface HostStore { ...@@ -98,4 +98,34 @@ public interface HostStore {
98 */ 98 */
99 Set<Host> getConnectedHosts(DeviceId deviceId); 99 Set<Host> getConnectedHosts(DeviceId deviceId);
100 100
101 + /**
102 + * Updates the address information for a given port.
103 + *
104 + * @param addresses the port and address information
105 + */
106 + void updateAddressBindings(PortAddresses addresses);
107 +
108 + /**
109 + * Removes any previously stored address information for a given connection
110 + * point.
111 + *
112 + * @param connectPoint the connection point
113 + */
114 + void removeAddressBindings(ConnectPoint connectPoint);
115 +
116 + /**
117 + * Returns the address bindings stored for all connection points.
118 + *
119 + * @return the set of address bindings
120 + */
121 + Set<PortAddresses> getAddressBindings();
122 +
123 + /**
124 + * Returns the address bindings for a particular connection point.
125 + *
126 + * @param connectPoint the connection point to return address information
127 + * for
128 + * @return address information for the connection point
129 + */
130 + PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint);
101 } 131 }
......
1 +package org.onlab.onos.net.host;
2 +
3 +import org.onlab.onos.net.ConnectPoint;
4 +import org.onlab.packet.IpAddress;
5 +import org.onlab.packet.MacAddress;
6 +
7 +/**
8 + * Represents address information bound to a port.
9 + */
10 +public interface PortAddresses {
11 +
12 + /**
13 + * Returns the connection point this address information is bound to.
14 + *
15 + * @return the connection point
16 + */
17 + ConnectPoint connectPoint();
18 +
19 + /**
20 + * Returns the IP address bound to the port.
21 + *
22 + * @return the IP address
23 + */
24 + IpAddress ip();
25 +
26 + /**
27 + * Returns the MAC address bound to the port.
28 + *
29 + * @return the MAC address if one is bound, otherwise null
30 + */
31 + MacAddress mac();
32 +}
...@@ -6,6 +6,7 @@ import org.onlab.onos.net.ConnectPoint; ...@@ -6,6 +6,7 @@ import org.onlab.onos.net.ConnectPoint;
6 import org.onlab.onos.net.DeviceId; 6 import org.onlab.onos.net.DeviceId;
7 import org.onlab.onos.net.Host; 7 import org.onlab.onos.net.Host;
8 import org.onlab.onos.net.HostId; 8 import org.onlab.onos.net.HostId;
9 +import org.onlab.packet.IpAddress;
9 import org.onlab.packet.IpPrefix; 10 import org.onlab.packet.IpPrefix;
10 import org.onlab.packet.MacAddress; 11 import org.onlab.packet.MacAddress;
11 import org.onlab.packet.VlanId; 12 import org.onlab.packet.VlanId;
...@@ -55,11 +56,15 @@ public class HostServiceAdapter implements HostService { ...@@ -55,11 +56,15 @@ public class HostServiceAdapter implements HostService {
55 } 56 }
56 57
57 @Override 58 @Override
58 - public void monitorIp(IpPrefix ip) { 59 + public void startMonitoringIp(IpAddress ip) {
59 } 60 }
60 61
61 @Override 62 @Override
62 - public void stopMonitoringIp(IpPrefix ip) { 63 + public void stopMonitoringIp(IpAddress ip) {
64 + }
65 +
66 + @Override
67 + public void requestMac(IpAddress ip) {
63 } 68 }
64 69
65 @Override 70 @Override
......
1 +package org.onlab.onos.cluster.impl;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.Set;
6 +
7 +import org.apache.felix.scr.annotations.Activate;
8 +import org.apache.felix.scr.annotations.Deactivate;
9 +import org.apache.felix.scr.annotations.Reference;
10 +import org.apache.felix.scr.annotations.ReferenceCardinality;
11 +import org.onlab.onos.cluster.MastershipAdminService;
12 +import org.onlab.onos.cluster.MastershipEvent;
13 +import org.onlab.onos.cluster.MastershipListener;
14 +import org.onlab.onos.cluster.MastershipProvider;
15 +import org.onlab.onos.cluster.MastershipProviderService;
16 +import org.onlab.onos.cluster.MastershipService;
17 +import org.onlab.onos.cluster.MastershipStore;
18 +import org.onlab.onos.cluster.NodeId;
19 +import org.onlab.onos.event.AbstractListenerRegistry;
20 +import org.onlab.onos.event.EventDeliveryService;
21 +import org.onlab.onos.net.DeviceId;
22 +import org.onlab.onos.net.MastershipRole;
23 +import org.onlab.onos.net.provider.AbstractProviderRegistry;
24 +import org.onlab.onos.net.provider.AbstractProviderService;
25 +import org.slf4j.Logger;
26 +
27 +import static com.google.common.base.Preconditions.checkNotNull;
28 +
29 +public class MastershipManager
30 + extends AbstractProviderRegistry<MastershipProvider, MastershipProviderService>
31 + implements MastershipService, MastershipAdminService {
32 +
33 + private static final String NODE_ID_NULL = "Node ID cannot be null";
34 + private static final String DEVICE_ID_NULL = "Device ID cannot be null";
35 + private static final String ROLE_NULL = "Mastership role cannot be null";
36 +
37 + private final Logger log = getLogger(getClass());
38 +
39 + protected final AbstractListenerRegistry<MastershipEvent, MastershipListener>
40 + listenerRegistry = new AbstractListenerRegistry<>();
41 +
42 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
43 + protected MastershipStore store;
44 +
45 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
46 + protected EventDeliveryService eventDispatcher;
47 +
48 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 + protected ClusterManager clusterManager;
50 +
51 + @Activate
52 + public void activate() {
53 + eventDispatcher.addSink(MastershipEvent.class, listenerRegistry);
54 + log.info("Started");
55 + }
56 +
57 + @Deactivate
58 + public void deactivate() {
59 + eventDispatcher.removeSink(MastershipEvent.class);
60 + log.info("Stopped");
61 + }
62 +
63 + @Override
64 + public void setRole(NodeId nodeId, DeviceId deviceId, MastershipRole role) {
65 + checkNotNull(nodeId, NODE_ID_NULL);
66 + checkNotNull(deviceId, DEVICE_ID_NULL);
67 + checkNotNull(role, ROLE_NULL);
68 + store.setRole(nodeId, deviceId, role);
69 + }
70 +
71 + @Override
72 + public NodeId getMasterFor(DeviceId deviceId) {
73 + checkNotNull(deviceId, DEVICE_ID_NULL);
74 + return store.getMaster(deviceId);
75 + }
76 +
77 + @Override
78 + public Set<DeviceId> getDevicesOf(NodeId nodeId) {
79 + checkNotNull(nodeId, NODE_ID_NULL);
80 + return store.getDevices(nodeId);
81 + }
82 +
83 + @Override
84 + public MastershipRole requestRoleFor(DeviceId deviceId) {
85 + checkNotNull(deviceId, DEVICE_ID_NULL);
86 + NodeId id = clusterManager.getLocalNode().id();
87 + return store.getRole(id, deviceId);
88 + }
89 +
90 + @Override
91 + public void addListener(MastershipListener listener) {
92 + checkNotNull(listener);
93 + listenerRegistry.addListener(listener);
94 + }
95 +
96 + @Override
97 + public void removeListener(MastershipListener listener) {
98 + checkNotNull(listener);
99 + listenerRegistry.removeListener(listener);
100 + }
101 +
102 + @Override
103 + protected MastershipProviderService createProviderService(
104 + MastershipProvider provider) {
105 + return new InternalMastershipProviderService(provider);
106 + }
107 +
108 + private class InternalMastershipProviderService
109 + extends AbstractProviderService<MastershipProvider>
110 + implements MastershipProviderService {
111 +
112 + protected InternalMastershipProviderService(MastershipProvider provider) {
113 + super(provider);
114 + }
115 +
116 + @Override
117 + public void roleChanged(NodeId nodeId, DeviceId deviceId, MastershipRole role) {
118 + // TODO Auto-generated method stub
119 + MastershipEvent event =
120 + store.addOrUpdateDevice(nodeId, deviceId, role);
121 + post(event);
122 + }
123 + }
124 +
125 + // Posts the specified event to the local event dispatcher.
126 + private void post(MastershipEvent event) {
127 + if (event != null && eventDispatcher != null) {
128 + eventDispatcher.post(event);
129 + }
130 + }
131 +
132 +}
1 +package org.onlab.onos.net.host.impl;
2 +
3 +import org.onlab.onos.net.ConnectPoint;
4 +import org.onlab.onos.net.host.PortAddresses;
5 +import org.onlab.packet.IpAddress;
6 +import org.onlab.packet.MacAddress;
7 +
8 +public class DefaultPortAddresses implements PortAddresses {
9 +
10 + private final ConnectPoint connectPoint;
11 + private final IpAddress ipAddress;
12 + private final MacAddress macAddress;
13 +
14 + public DefaultPortAddresses(ConnectPoint connectPoint,
15 + IpAddress ip, MacAddress mac) {
16 + this.connectPoint = connectPoint;
17 + this.ipAddress = ip;
18 + this.macAddress = mac;
19 + }
20 +
21 + @Override
22 + public ConnectPoint connectPoint() {
23 + return connectPoint;
24 + }
25 +
26 + @Override
27 + public IpAddress ip() {
28 + return ipAddress;
29 + }
30 +
31 + @Override
32 + public MacAddress mac() {
33 + return macAddress;
34 + }
35 +
36 +}
...@@ -26,8 +26,10 @@ import org.onlab.onos.net.host.HostProviderRegistry; ...@@ -26,8 +26,10 @@ import org.onlab.onos.net.host.HostProviderRegistry;
26 import org.onlab.onos.net.host.HostProviderService; 26 import org.onlab.onos.net.host.HostProviderService;
27 import org.onlab.onos.net.host.HostService; 27 import org.onlab.onos.net.host.HostService;
28 import org.onlab.onos.net.host.HostStore; 28 import org.onlab.onos.net.host.HostStore;
29 +import org.onlab.onos.net.host.PortAddresses;
29 import org.onlab.onos.net.provider.AbstractProviderRegistry; 30 import org.onlab.onos.net.provider.AbstractProviderRegistry;
30 import org.onlab.onos.net.provider.AbstractProviderService; 31 import org.onlab.onos.net.provider.AbstractProviderService;
32 +import org.onlab.packet.IpAddress;
31 import org.onlab.packet.IpPrefix; 33 import org.onlab.packet.IpPrefix;
32 import org.onlab.packet.MacAddress; 34 import org.onlab.packet.MacAddress;
33 import org.onlab.packet.VlanId; 35 import org.onlab.packet.VlanId;
...@@ -118,13 +120,18 @@ public class HostManager ...@@ -118,13 +120,18 @@ public class HostManager
118 } 120 }
119 121
120 @Override 122 @Override
121 - public void monitorIp(IpPrefix ip) { 123 + public void startMonitoringIp(IpAddress ip) {
122 - // TODO pass through to SimpleHostMonitor 124 + // TODO pass through to HostMonitor
123 } 125 }
124 126
125 @Override 127 @Override
126 - public void stopMonitoringIp(IpPrefix ip) { 128 + public void stopMonitoringIp(IpAddress ip) {
127 - // TODO pass through to SimpleHostMonitor 129 + // TODO pass through to HostMonitor
130 + }
131 +
132 + @Override
133 + public void requestMac(IpAddress ip) {
134 + // TODO Auto-generated method stub
128 } 135 }
129 136
130 @Override 137 @Override
...@@ -147,6 +154,27 @@ public class HostManager ...@@ -147,6 +154,27 @@ public class HostManager
147 } 154 }
148 } 155 }
149 156
157 + @Override
158 + public void bindAddressesToPort(IpAddress ip, MacAddress mac,
159 + ConnectPoint connectPoint) {
160 + store.updateAddressBindings(new DefaultPortAddresses(connectPoint, ip, mac));
161 + }
162 +
163 + @Override
164 + public void unbindAddressesFromPort(ConnectPoint connectPoint) {
165 + store.removeAddressBindings(connectPoint);
166 + }
167 +
168 + @Override
169 + public Set<PortAddresses> getAddressBindings() {
170 + return store.getAddressBindings();
171 + }
172 +
173 + @Override
174 + public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) {
175 + return store.getAddressBindingsForPort(connectPoint);
176 + }
177 +
150 // Personalized host provider service issued to the supplied provider. 178 // Personalized host provider service issued to the supplied provider.
151 private class InternalHostProviderService 179 private class InternalHostProviderService
152 extends AbstractProviderService<HostProvider> 180 extends AbstractProviderService<HostProvider>
......
...@@ -6,7 +6,6 @@ import java.util.concurrent.TimeUnit; ...@@ -6,7 +6,6 @@ import java.util.concurrent.TimeUnit;
6 6
7 import org.jboss.netty.util.Timeout; 7 import org.jboss.netty.util.Timeout;
8 import org.jboss.netty.util.TimerTask; 8 import org.jboss.netty.util.TimerTask;
9 -import org.onlab.onos.net.Device;
10 import org.onlab.onos.net.Host; 9 import org.onlab.onos.net.Host;
11 import org.onlab.onos.net.Port; 10 import org.onlab.onos.net.Port;
12 import org.onlab.onos.net.device.DeviceService; 11 import org.onlab.onos.net.device.DeviceService;
...@@ -89,7 +88,7 @@ public class HostMonitor implements TimerTask { ...@@ -89,7 +88,7 @@ public class HostMonitor implements TimerTask {
89 // else (ip isn't in any configured subnet) 88 // else (ip isn't in any configured subnet)
90 // send out all non-external edge ports 89 // send out all non-external edge ports
91 90
92 - for (Device device : deviceService.getDevices()) { 91 + /*for (Device device : deviceService.getDevices()) {
93 for (Port port : deviceService.getPorts(device.id())) { 92 for (Port port : deviceService.getPorts(device.id())) {
94 for (IpPrefix ip : port.ipAddresses()) { 93 for (IpPrefix ip : port.ipAddresses()) {
95 if (ip.contains(targetIp)) { 94 if (ip.contains(targetIp)) {
...@@ -98,7 +97,7 @@ public class HostMonitor implements TimerTask { ...@@ -98,7 +97,7 @@ public class HostMonitor implements TimerTask {
98 } 97 }
99 } 98 }
100 } 99 }
101 - } 100 + }*/
102 101
103 } 102 }
104 103
......
1 package org.onlab.onos.net.device.impl; 1 package org.onlab.onos.net.device.impl;
2 2
3 +import com.google.common.collect.Iterables;
4 +import com.hazelcast.config.Config;
5 +import com.hazelcast.core.Hazelcast;
3 import com.hazelcast.core.HazelcastInstance; 6 import com.hazelcast.core.HazelcastInstance;
4 import org.junit.After; 7 import org.junit.After;
5 import org.junit.Before; 8 import org.junit.Before;
6 import org.junit.Test; 9 import org.junit.Test;
7 import org.onlab.onos.event.Event; 10 import org.onlab.onos.event.Event;
11 +import org.onlab.onos.event.impl.TestEventDispatcher;
8 import org.onlab.onos.net.Device; 12 import org.onlab.onos.net.Device;
9 import org.onlab.onos.net.DeviceId; 13 import org.onlab.onos.net.DeviceId;
10 import org.onlab.onos.net.MastershipRole; 14 import org.onlab.onos.net.MastershipRole;
...@@ -23,13 +27,9 @@ import org.onlab.onos.net.device.DeviceService; ...@@ -23,13 +27,9 @@ import org.onlab.onos.net.device.DeviceService;
23 import org.onlab.onos.net.device.PortDescription; 27 import org.onlab.onos.net.device.PortDescription;
24 import org.onlab.onos.net.provider.AbstractProvider; 28 import org.onlab.onos.net.provider.AbstractProvider;
25 import org.onlab.onos.net.provider.ProviderId; 29 import org.onlab.onos.net.provider.ProviderId;
26 -import org.onlab.onos.event.impl.TestEventDispatcher;
27 import org.onlab.onos.store.StoreService; 30 import org.onlab.onos.store.StoreService;
28 import org.onlab.onos.store.device.impl.DistributedDeviceStore; 31 import org.onlab.onos.store.device.impl.DistributedDeviceStore;
29 - 32 +import org.onlab.onos.store.impl.StoreManager;
30 -import com.google.common.collect.Iterables;
31 -import com.hazelcast.config.Config;
32 -import com.hazelcast.core.Hazelcast;
33 33
34 import java.util.ArrayList; 34 import java.util.ArrayList;
35 import java.util.Iterator; 35 import java.util.Iterator;
...@@ -64,6 +64,7 @@ public class DistributedDeviceManagerTest { ...@@ -64,6 +64,7 @@ public class DistributedDeviceManagerTest {
64 64
65 private DeviceManager mgr; 65 private DeviceManager mgr;
66 66
67 + protected StoreManager storeManager;
67 protected DeviceService service; 68 protected DeviceService service;
68 protected DeviceAdminService admin; 69 protected DeviceAdminService admin;
69 protected DeviceProviderRegistry registry; 70 protected DeviceProviderRegistry registry;
...@@ -89,7 +90,11 @@ public class DistributedDeviceManagerTest { ...@@ -89,7 +90,11 @@ public class DistributedDeviceManagerTest {
89 config.getNetworkConfig().getJoin() 90 config.getNetworkConfig().getJoin()
90 .getMulticastConfig() 91 .getMulticastConfig()
91 .setEnabled(false); 92 .setEnabled(false);
92 - dstore = new TestDistributedDeviceStore(Hazelcast.newHazelcastInstance(config)); 93 +
94 + storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
95 + storeManager.activate();
96 +
97 + dstore = new TestDistributedDeviceStore(storeManager);
93 dstore.activate(); 98 dstore.activate();
94 mgr.store = dstore; 99 mgr.store = dstore;
95 mgr.eventDispatcher = new TestEventDispatcher(); 100 mgr.eventDispatcher = new TestEventDispatcher();
...@@ -112,7 +117,7 @@ public class DistributedDeviceManagerTest { ...@@ -112,7 +117,7 @@ public class DistributedDeviceManagerTest {
112 mgr.deactivate(); 117 mgr.deactivate();
113 118
114 dstore.deactivate(); 119 dstore.deactivate();
115 - ((TestDistributedDeviceStore) dstore).shutdownHz(); 120 + storeManager.deactivate();
116 } 121 }
117 122
118 private void connectDevice(DeviceId deviceId, String swVersion) { 123 private void connectDevice(DeviceId deviceId, String swVersion) {
...@@ -282,20 +287,19 @@ public class DistributedDeviceManagerTest { ...@@ -282,20 +287,19 @@ public class DistributedDeviceManagerTest {
282 } 287 }
283 288
284 private class TestDistributedDeviceStore extends DistributedDeviceStore { 289 private class TestDistributedDeviceStore extends DistributedDeviceStore {
285 - public TestDistributedDeviceStore(final HazelcastInstance hazelcastInstance) { 290 + public TestDistributedDeviceStore(StoreService storeService) {
286 - storeService = new StoreService() { 291 + this.storeService = storeService;
287 - @Override
288 - public HazelcastInstance getHazelcastInstance() {
289 - return hazelcastInstance;
290 - }
291 - };
292 } 292 }
293 + }
293 294
294 - /** 295 + private class TestStoreManager extends StoreManager {
295 - * Shutdowns the hazelcast instance. 296 + TestStoreManager(HazelcastInstance instance) {
296 - */ 297 + this.instance = instance;
297 - public void shutdownHz() { 298 + }
298 - theInstance.shutdown(); 299 +
300 + @Override
301 + public void activate() {
302 + setupKryoPool();
299 } 303 }
300 } 304 }
301 } 305 }
......
...@@ -15,4 +15,22 @@ public interface StoreService { ...@@ -15,4 +15,22 @@ public interface StoreService {
15 */ 15 */
16 HazelcastInstance getHazelcastInstance(); 16 HazelcastInstance getHazelcastInstance();
17 17
18 + /**
19 + * Serializes the specified object into bytes using one of the
20 + * pre-registered serializers.
21 + *
22 + * @param obj object to be serialized
23 + * @return serialized bytes
24 + */
25 + public byte[] serialize(final Object obj);
26 +
27 + /**
28 + * Deserializes the specified bytes into an object using one of the
29 + * pre-registered serializers.
30 + *
31 + * @param bytes bytes to be deserialized
32 + * @return deserialized object
33 + */
34 + public <T> T deserialize(final byte[] bytes);
35 +
18 } 36 }
......
1 /** 1 /**
2 * Implementation of a distributed cluster node store using Hazelcast. 2 * Implementation of a distributed cluster node store using Hazelcast.
3 */ 3 */
4 -package org.onlab.onos.store.cluster.impl;
...\ No newline at end of file ...\ No newline at end of file
4 +package org.onlab.onos.store.cluster.impl;
......
1 -package org.onlab.onos.store.device.impl; 1 +package org.onlab.onos.store.impl;
2 2
3 import java.util.concurrent.Callable; 3 import java.util.concurrent.Callable;
4 import java.util.concurrent.ExecutionException; 4 import java.util.concurrent.ExecutionException;
...@@ -7,9 +7,24 @@ import com.google.common.base.Optional; ...@@ -7,9 +7,24 @@ import com.google.common.base.Optional;
7 import com.google.common.cache.ForwardingLoadingCache.SimpleForwardingLoadingCache; 7 import com.google.common.cache.ForwardingLoadingCache.SimpleForwardingLoadingCache;
8 import com.google.common.cache.LoadingCache; 8 import com.google.common.cache.LoadingCache;
9 9
10 +/**
11 + * Wrapper around LoadingCache to handle negative hit scenario.
12 + * <p>
13 + * When the LoadingCache returned Absent,
14 + * this implementation will invalidate the entry immediately to avoid
15 + * caching negative hits.
16 + *
17 + * @param <K> Cache key type
18 + * @param <V> Cache value type. (Optional{@literal <V>})
19 + */
10 public class AbsentInvalidatingLoadingCache<K, V> extends 20 public class AbsentInvalidatingLoadingCache<K, V> extends
11 SimpleForwardingLoadingCache<K, Optional<V>> { 21 SimpleForwardingLoadingCache<K, Optional<V>> {
12 22
23 + /**
24 + * Constructor.
25 + *
26 + * @param delegate actual {@link LoadingCache} to delegate loading.
27 + */
13 public AbsentInvalidatingLoadingCache(LoadingCache<K, Optional<V>> delegate) { 28 public AbsentInvalidatingLoadingCache(LoadingCache<K, Optional<V>> delegate) {
14 super(delegate); 29 super(delegate);
15 } 30 }
......
1 +package org.onlab.onos.store.impl;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import org.onlab.onos.store.StoreService;
6 +
7 +import com.google.common.base.Optional;
8 +import com.google.common.cache.CacheLoader;
9 +import com.hazelcast.core.IMap;
10 +
11 +/**
12 + * CacheLoader to wrap Map value with Optional,
13 + * to handle negative hit on underlying IMap.
14 + *
15 + * @param <K> IMap key type after deserialization
16 + * @param <V> IMap value type after deserialization
17 + */
18 +public final class OptionalCacheLoader<K, V> extends
19 + CacheLoader<K, Optional<V>> {
20 +
21 + private final StoreService storeService;
22 + private IMap<byte[], byte[]> rawMap;
23 +
24 + /**
25 + * Constructor.
26 + *
27 + * @param storeService to use for serialization
28 + * @param rawMap underlying IMap
29 + */
30 + public OptionalCacheLoader(StoreService storeService, IMap<byte[], byte[]> rawMap) {
31 + this.storeService = checkNotNull(storeService);
32 + this.rawMap = checkNotNull(rawMap);
33 + }
34 +
35 + @Override
36 + public Optional<V> load(K key) throws Exception {
37 + byte[] keyBytes = storeService.serialize(key);
38 + byte[] valBytes = rawMap.get(keyBytes);
39 + if (valBytes == null) {
40 + return Optional.absent();
41 + }
42 + V dev = storeService.deserialize(valBytes);
43 + return Optional.of(dev);
44 + }
45 +}
...@@ -2,14 +2,33 @@ package org.onlab.onos.store.impl; ...@@ -2,14 +2,33 @@ package org.onlab.onos.store.impl;
2 2
3 import com.hazelcast.core.Hazelcast; 3 import com.hazelcast.core.Hazelcast;
4 import com.hazelcast.core.HazelcastInstance; 4 import com.hazelcast.core.HazelcastInstance;
5 +import de.javakaffee.kryoserializers.URISerializer;
5 import org.apache.felix.scr.annotations.Activate; 6 import org.apache.felix.scr.annotations.Activate;
6 import org.apache.felix.scr.annotations.Component; 7 import org.apache.felix.scr.annotations.Component;
7 import org.apache.felix.scr.annotations.Deactivate; 8 import org.apache.felix.scr.annotations.Deactivate;
8 import org.apache.felix.scr.annotations.Service; 9 import org.apache.felix.scr.annotations.Service;
10 +import org.onlab.onos.net.DefaultDevice;
11 +import org.onlab.onos.net.DefaultPort;
12 +import org.onlab.onos.net.Device;
13 +import org.onlab.onos.net.DeviceId;
14 +import org.onlab.onos.net.Element;
15 +import org.onlab.onos.net.MastershipRole;
16 +import org.onlab.onos.net.Port;
17 +import org.onlab.onos.net.PortNumber;
18 +import org.onlab.onos.net.provider.ProviderId;
9 import org.onlab.onos.store.StoreService; 19 import org.onlab.onos.store.StoreService;
20 +import org.onlab.onos.store.serializers.DefaultPortSerializer;
21 +import org.onlab.onos.store.serializers.DeviceIdSerializer;
22 +import org.onlab.onos.store.serializers.PortNumberSerializer;
23 +import org.onlab.onos.store.serializers.ProviderIdSerializer;
24 +import org.onlab.util.KryoPool;
10 import org.slf4j.Logger; 25 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 26 import org.slf4j.LoggerFactory;
12 27
28 +import java.net.URI;
29 +import java.util.ArrayList;
30 +import java.util.HashMap;
31 +
13 /** 32 /**
14 * Auxiliary bootstrap of distributed store. 33 * Auxiliary bootstrap of distributed store.
15 */ 34 */
...@@ -20,15 +39,45 @@ public class StoreManager implements StoreService { ...@@ -20,15 +39,45 @@ public class StoreManager implements StoreService {
20 private final Logger log = LoggerFactory.getLogger(getClass()); 39 private final Logger log = LoggerFactory.getLogger(getClass());
21 40
22 protected HazelcastInstance instance; 41 protected HazelcastInstance instance;
42 + private KryoPool serializerPool;
43 +
23 44
24 @Activate 45 @Activate
25 public void activate() { 46 public void activate() {
26 instance = Hazelcast.newHazelcastInstance(); 47 instance = Hazelcast.newHazelcastInstance();
48 + setupKryoPool();
27 log.info("Started"); 49 log.info("Started");
28 } 50 }
29 51
52 + /**
53 + * Sets up the common serialzers pool.
54 + */
55 + protected void setupKryoPool() {
56 + // FIXME Slice out types used in common to separate pool/namespace.
57 + serializerPool = KryoPool.newBuilder()
58 + .register(
59 + ArrayList.class,
60 + HashMap.class,
61 +
62 + Device.Type.class,
63 +
64 + DefaultDevice.class,
65 + MastershipRole.class,
66 + Port.class,
67 + Element.class
68 + )
69 + .register(URI.class, new URISerializer())
70 + .register(ProviderId.class, new ProviderIdSerializer())
71 + .register(DeviceId.class, new DeviceIdSerializer())
72 + .register(PortNumber.class, new PortNumberSerializer())
73 + .register(DefaultPort.class, new DefaultPortSerializer())
74 + .build()
75 + .populate(10);
76 + }
77 +
30 @Deactivate 78 @Deactivate
31 public void deactivate() { 79 public void deactivate() {
80 + instance.shutdown();
32 log.info("Stopped"); 81 log.info("Stopped");
33 } 82 }
34 83
...@@ -36,4 +85,19 @@ public class StoreManager implements StoreService { ...@@ -36,4 +85,19 @@ public class StoreManager implements StoreService {
36 public HazelcastInstance getHazelcastInstance() { 85 public HazelcastInstance getHazelcastInstance() {
37 return instance; 86 return instance;
38 } 87 }
88 +
89 +
90 + @Override
91 + public byte[] serialize(final Object obj) {
92 + return serializerPool.serialize(obj);
93 + }
94 +
95 + @Override
96 + public <T> T deserialize(final byte[] bytes) {
97 + if (bytes == null) {
98 + return null;
99 + }
100 + return serializerPool.deserialize(bytes);
101 + }
102 +
39 } 103 }
......
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
2 * Common abstractions and facilities for implementing distributed store 2 * Common abstractions and facilities for implementing distributed store
3 * using Hazelcast. 3 * using Hazelcast.
4 */ 4 */
5 -package org.onlab.onos.store;
...\ No newline at end of file ...\ No newline at end of file
5 +package org.onlab.onos.store;
......
1 -package org.onlab.onos.store.device.impl; 1 +package org.onlab.onos.store.serializers;
2 -
3 -import java.util.ArrayList;
4 -import java.util.Collection;
5 2
6 import org.onlab.onos.net.DefaultPort; 3 import org.onlab.onos.net.DefaultPort;
7 import org.onlab.onos.net.Element; 4 import org.onlab.onos.net.Element;
8 import org.onlab.onos.net.PortNumber; 5 import org.onlab.onos.net.PortNumber;
9 -import org.onlab.packet.IpPrefix;
10 6
11 import com.esotericsoftware.kryo.Kryo; 7 import com.esotericsoftware.kryo.Kryo;
12 import com.esotericsoftware.kryo.Serializer; 8 import com.esotericsoftware.kryo.Serializer;
13 import com.esotericsoftware.kryo.io.Input; 9 import com.esotericsoftware.kryo.io.Input;
14 import com.esotericsoftware.kryo.io.Output; 10 import com.esotericsoftware.kryo.io.Output;
15 -import com.esotericsoftware.kryo.serializers.CollectionSerializer;
16 -import com.google.common.collect.ImmutableSet;
17 11
18 // TODO move to util, etc. 12 // TODO move to util, etc.
19 /** 13 /**
...@@ -22,10 +16,6 @@ import com.google.common.collect.ImmutableSet; ...@@ -22,10 +16,6 @@ import com.google.common.collect.ImmutableSet;
22 public final class DefaultPortSerializer extends 16 public final class DefaultPortSerializer extends
23 Serializer<DefaultPort> { 17 Serializer<DefaultPort> {
24 18
25 - private final CollectionSerializer ipAddrSerializer
26 - = new CollectionSerializer(IpPrefix.class,
27 - new IpPrefixSerializer(), false);
28 -
29 /** 19 /**
30 * Default constructor. 20 * Default constructor.
31 */ 21 */
...@@ -39,8 +29,6 @@ public final class DefaultPortSerializer extends ...@@ -39,8 +29,6 @@ public final class DefaultPortSerializer extends
39 kryo.writeClassAndObject(output, object.element()); 29 kryo.writeClassAndObject(output, object.element());
40 kryo.writeObject(output, object.number()); 30 kryo.writeObject(output, object.number());
41 output.writeBoolean(object.isEnabled()); 31 output.writeBoolean(object.isEnabled());
42 - kryo.writeObject(output, object.ipAddresses(),
43 - ipAddrSerializer);
44 } 32 }
45 33
46 @Override 34 @Override
...@@ -49,11 +37,7 @@ public final class DefaultPortSerializer extends ...@@ -49,11 +37,7 @@ public final class DefaultPortSerializer extends
49 Element element = (Element) kryo.readClassAndObject(input); 37 Element element = (Element) kryo.readClassAndObject(input);
50 PortNumber number = kryo.readObject(input, PortNumber.class); 38 PortNumber number = kryo.readObject(input, PortNumber.class);
51 boolean isEnabled = input.readBoolean(); 39 boolean isEnabled = input.readBoolean();
52 - @SuppressWarnings("unchecked")
53 - Collection<IpPrefix> ipAddresses = kryo.readObject(
54 - input, ArrayList.class, ipAddrSerializer);
55 40
56 - return new DefaultPort(element, number, isEnabled, 41 + return new DefaultPort(element, number, isEnabled);
57 - ImmutableSet.copyOf(ipAddresses));
58 } 42 }
59 } 43 }
......
1 +package org.onlab.onos.store.serializers;
2 +
3 +import java.net.URI;
4 +
5 +import org.onlab.onos.net.DeviceId;
6 +
7 +import com.esotericsoftware.kryo.Kryo;
8 +import com.esotericsoftware.kryo.Serializer;
9 +import com.esotericsoftware.kryo.io.Input;
10 +import com.esotericsoftware.kryo.io.Output;
11 +
12 +//TODO move to util, etc.
13 +/**
14 +* Kryo Serializer for {@link DeviceId}.
15 +*/
16 +public final class DeviceIdSerializer extends Serializer<DeviceId> {
17 +
18 + @Override
19 + public void write(Kryo kryo, Output output, DeviceId object) {
20 + kryo.writeObject(output, object.uri());
21 + }
22 +
23 + @Override
24 + public DeviceId read(Kryo kryo, Input input, Class<DeviceId> type) {
25 + final URI uri = kryo.readObject(input, URI.class);
26 + return DeviceId.deviceId(uri);
27 + }
28 +}
1 -package org.onlab.onos.store.device.impl; 1 +package org.onlab.onos.store.serializers;
2 2
3 import org.onlab.packet.IpPrefix; 3 import org.onlab.packet.IpPrefix;
4 4
......
1 -package org.onlab.onos.store.device.impl; 1 +package org.onlab.onos.store.serializers;
2 2
3 import org.onlab.onos.net.PortNumber; 3 import org.onlab.onos.net.PortNumber;
4 4
......
1 -package org.onlab.onos.store.device.impl; 1 +package org.onlab.onos.store.serializers;
2 2
3 import org.onlab.onos.net.provider.ProviderId; 3 import org.onlab.onos.net.provider.ProviderId;
4 4
......
1 +/**
2 + * Various Kryo serializers for use in distributed stores.
3 + */
4 +package org.onlab.onos.store.serializers;
...@@ -24,15 +24,16 @@ import org.onlab.onos.net.HostId; ...@@ -24,15 +24,16 @@ import org.onlab.onos.net.HostId;
24 import org.onlab.onos.net.host.HostDescription; 24 import org.onlab.onos.net.host.HostDescription;
25 import org.onlab.onos.net.host.HostEvent; 25 import org.onlab.onos.net.host.HostEvent;
26 import org.onlab.onos.net.host.HostStore; 26 import org.onlab.onos.net.host.HostStore;
27 +import org.onlab.onos.net.host.PortAddresses;
27 import org.onlab.onos.net.provider.ProviderId; 28 import org.onlab.onos.net.provider.ProviderId;
28 import org.onlab.packet.IpPrefix; 29 import org.onlab.packet.IpPrefix;
29 import org.onlab.packet.MacAddress; 30 import org.onlab.packet.MacAddress;
30 import org.onlab.packet.VlanId; 31 import org.onlab.packet.VlanId;
32 +import org.slf4j.Logger;
31 33
32 import com.google.common.collect.HashMultimap; 34 import com.google.common.collect.HashMultimap;
33 import com.google.common.collect.ImmutableSet; 35 import com.google.common.collect.ImmutableSet;
34 import com.google.common.collect.Multimap; 36 import com.google.common.collect.Multimap;
35 -import org.slf4j.Logger;
36 37
37 /** 38 /**
38 * Manages inventory of end-station hosts using trivial in-memory 39 * Manages inventory of end-station hosts using trivial in-memory
...@@ -50,6 +51,9 @@ public class SimpleHostStore implements HostStore { ...@@ -50,6 +51,9 @@ public class SimpleHostStore implements HostStore {
50 // Hosts tracked by their location 51 // Hosts tracked by their location
51 private final Multimap<ConnectPoint, Host> locations = HashMultimap.create(); 52 private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
52 53
54 + private final Map<ConnectPoint, PortAddresses> portAddresses =
55 + new ConcurrentHashMap<>();
56 +
53 @Activate 57 @Activate
54 public void activate() { 58 public void activate() {
55 log.info("Started"); 59 log.info("Started");
...@@ -192,4 +196,24 @@ public class SimpleHostStore implements HostStore { ...@@ -192,4 +196,24 @@ public class SimpleHostStore implements HostStore {
192 return hostset; 196 return hostset;
193 } 197 }
194 198
199 + @Override
200 + public void updateAddressBindings(PortAddresses addresses) {
201 + portAddresses.put(addresses.connectPoint(), addresses);
202 + }
203 +
204 + @Override
205 + public void removeAddressBindings(ConnectPoint connectPoint) {
206 + portAddresses.remove(connectPoint);
207 + }
208 +
209 + @Override
210 + public Set<PortAddresses> getAddressBindings() {
211 + return new HashSet<>(portAddresses.values());
212 + }
213 +
214 + @Override
215 + public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) {
216 + return portAddresses.get(connectPoint);
217 + }
218 +
195 } 219 }
......
...@@ -172,6 +172,11 @@ ...@@ -172,6 +172,11 @@
172 </dependency> 172 </dependency>
173 <dependency> 173 <dependency>
174 <groupId>org.onlab.onos</groupId> 174 <groupId>org.onlab.onos</groupId>
175 + <artifactId>onlab-osgi</artifactId>
176 + <version>${project.version}</version>
177 + </dependency>
178 + <dependency>
179 + <groupId>org.onlab.onos</groupId>
175 <artifactId>onlab-junit</artifactId> 180 <artifactId>onlab-junit</artifactId>
176 <version>1.0.0-SNAPSHOT</version> 181 <version>1.0.0-SNAPSHOT</version>
177 <scope>test</scope> 182 <scope>test</scope>
......
...@@ -30,6 +30,7 @@ alias mci='mvn clean install' ...@@ -30,6 +30,7 @@ alias mci='mvn clean install'
30 30
31 # Short-hand for ONOS build from the top of the source tree. 31 # Short-hand for ONOS build from the top of the source tree.
32 alias ob='o && mvn clean install javadoc:aggregate' 32 alias ob='o && mvn clean install javadoc:aggregate'
33 +alias ot='onos-test'
33 34
34 # Short-hand for tailing the ONOS (karaf) log 35 # Short-hand for tailing the ONOS (karaf) log
35 alias tl='$ONOS_ROOT/tools/dev/watchLog' 36 alias tl='$ONOS_ROOT/tools/dev/watchLog'
...@@ -46,7 +47,8 @@ alias gui='open http://localhost:8181/onos/tvue' ...@@ -46,7 +47,8 @@ alias gui='open http://localhost:8181/onos/tvue'
46 # Test related conveniences 47 # Test related conveniences
47 48
48 # SSH to a specified ONOS instance 49 # SSH to a specified ONOS instance
49 -alias sshctl=onos-ssh 50 +alias sshctl='onos-ssh'
51 +alias sshnet='onos-ssh $OCN'
50 52
51 # Applies the settings in the specified cell file or lists current cell definition 53 # Applies the settings in the specified cell file or lists current cell definition
52 # if no cell file is given. 54 # if no cell file is given.
...@@ -62,6 +64,7 @@ function cell { ...@@ -62,6 +64,7 @@ function cell {
62 env | egrep "ONOS_CELL" 64 env | egrep "ONOS_CELL"
63 env | egrep "OCI" 65 env | egrep "OCI"
64 env | egrep "OC[0-9]+" | sort 66 env | egrep "OC[0-9]+" | sort
67 + env | egrep "OCN"
65 fi 68 fi
66 } 69 }
67 70
......
...@@ -8,25 +8,4 @@ ...@@ -8,25 +8,4 @@
8 8
9 remote=$ONOS_USER@${1:-$OCI} 9 remote=$ONOS_USER@${1:-$OCI}
10 10
11 -LOG=$ONOS_INSTALL_DIR/config.log 11 +echo "Deprecated!"
12 -onos=$ONOS_INSTALL_DIR/bin/onos
13 -
14 -ssh $remote "
15 - # Wait until we reach the run-level 100
16 - echo 'Waiting for cluster bootstrap...'
17 - running=""
18 - while [ -z \$running ]; do
19 - $onos bundle:list 2>>$LOG | grep -q 'START LEVEL 100' && running=1 || sleep 2
20 - done
21 -
22 - echo 'Installing ONOS bundles...'
23 - $onos cluster:feature-install default onos-api 1>>$LOG 2>&1
24 - # $onos cluster:feature-install default onos-core 1>>$LOG 2>&1
25 - $onos cluster:feature-install default onos-core-trivial 1>>$LOG 2>&1
26 - $onos cluster:feature-install default onos-openflow 1>>$LOG 2>&1
27 - $onos cluster:feature-install default onos-cli 1>>$LOG 2>&1
28 - # $onos cluster:feature-install default onos-gui 1>>$LOG 2>&1
29 - # $onos cluster:feature-install default onos-rest 1>>$LOG 2>&1
30 - $onos cluster:feature-install default onos-app-tvue 1>>$LOG 2>&1
31 - $onos cluster:feature-install default onos-app-fwd 1>>$LOG 2>&1
32 -"
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -14,6 +14,7 @@ trap "ssh $remote 'ps -ef | grep \"tail -n 512\" | grep -v grep | cut -c10-15 | ...@@ -14,6 +14,7 @@ trap "ssh $remote 'ps -ef | grep \"tail -n 512\" | grep -v grep | cut -c10-15 |
14 14
15 ssh $remote " 15 ssh $remote "
16 while true; do 16 while true; do
17 + echo ==================================================================
17 [ ! -f $LOG ] && sleep 2 && continue 18 [ ! -f $LOG ] && sleep 2 && continue
18 tail -n 512 --follow=name $LOG --sleep-interval 2 19 tail -n 512 --follow=name $LOG --sleep-interval 2
19 done 20 done
......
1 +#!/bin/bash
2 +#-------------------------------------------------------------------------------
3 +# Launches the ONOS tests on the current cell environment.
4 +#-------------------------------------------------------------------------------
5 +
6 +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 +. $ONOS_ROOT/tools/build/envDefaults
8 +
9 +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
10 +
11 +onos-package
12 +for node in $nodes; do onos-install -f $node; done
13 +for node in $nodes; do onos-wait-for-start $node; done
...@@ -6,6 +6,6 @@ ...@@ -6,6 +6,6 @@
6 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 6 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 . $ONOS_ROOT/tools/build/envDefaults 7 . $ONOS_ROOT/tools/build/envDefaults
8 8
9 -for node in $(env | sort | egrep "OC[0-9]+" | cut -d= -f2); do 9 +for node in $(env | sort | egrep "OC[0-9N]+" | cut -d= -f2); do
10 printf "%s: " $node; ssh -n -o PasswordAuthentication=no $ONOS_USER@$node date 10 printf "%s: " $node; ssh -n -o PasswordAuthentication=no $ONOS_USER@$node date
11 done 11 done
...\ No newline at end of file ...\ No newline at end of file
......
1 -# Default virtual box ONOS instances 1,2 & 3 1 +# Default virtual box ONOS instances 1,2 & ONOS mininet box
2 2
3 export OC1="192.168.56.101" 3 export OC1="192.168.56.101"
4 export OC2="192.168.56.102" 4 export OC2="192.168.56.102"
5 -export OC3="192.168.56.103" 5 +
6 +export OCN="192.168.56.103"
6 7
7 8
......
...@@ -2,18 +2,37 @@ package org.onlab.osgi; ...@@ -2,18 +2,37 @@ package org.onlab.osgi;
2 2
3 import org.osgi.framework.BundleContext; 3 import org.osgi.framework.BundleContext;
4 import org.osgi.framework.FrameworkUtil; 4 import org.osgi.framework.FrameworkUtil;
5 +import org.osgi.framework.ServiceReference;
5 6
6 /** 7 /**
7 * Default implementation of the service directory using OSGi framework utilities. 8 * Default implementation of the service directory using OSGi framework utilities.
8 */ 9 */
9 public class DefaultServiceDirectory implements ServiceDirectory { 10 public class DefaultServiceDirectory implements ServiceDirectory {
10 - @Override 11 +
11 - public <T> T get(Class<T> serviceClass) { 12 + /**
13 + * Returns the reference to the implementation of the specified service.
14 + *
15 + * @param serviceClass service class
16 + * @param <T> type of service
17 + * @return service implementation
18 + */
19 + public static <T> T getService(Class<T> serviceClass) {
12 BundleContext bc = FrameworkUtil.getBundle(serviceClass).getBundleContext(); 20 BundleContext bc = FrameworkUtil.getBundle(serviceClass).getBundleContext();
13 - T impl = bc.getService(bc.getServiceReference(serviceClass)); 21 + if (bc != null) {
14 - if (impl == null) { 22 + ServiceReference<T> reference = bc.getServiceReference(serviceClass);
15 - throw new ServiceNotFoundException("Service " + serviceClass.getName() + " not found"); 23 + if (reference != null) {
24 + T impl = bc.getService(reference);
25 + if (impl != null) {
26 + return impl;
27 + }
28 + }
16 } 29 }
17 - return impl; 30 + throw new ServiceNotFoundException("Service " + serviceClass.getName() + " not found");
31 + }
32 +
33 + @Override
34 + public <T> T get(Class<T> serviceClass) {
35 + return getService(serviceClass);
18 } 36 }
37 +
19 } 38 }
......