Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
Showing
70 changed files
with
866 additions
and
162 deletions
| 1 | +package org.onlab.onos.cli; | ||
| 2 | + | ||
| 3 | +import org.apache.karaf.shell.commands.Command; | ||
| 4 | +import org.onlab.onos.cluster.ClusterService; | ||
| 5 | +import org.onlab.onos.cluster.ControllerNode; | ||
| 6 | + | ||
| 7 | +import java.util.Collections; | ||
| 8 | +import java.util.Comparator; | ||
| 9 | +import java.util.List; | ||
| 10 | + | ||
| 11 | +import static com.google.common.collect.Lists.newArrayList; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * Lists all controller cluster nodes. | ||
| 15 | + */ | ||
| 16 | +@Command(scope = "onos", name = "nodes", | ||
| 17 | + description = "Lists all controller cluster nodes") | ||
| 18 | +public class NodesListCommand extends AbstractShellCommand { | ||
| 19 | + | ||
| 20 | + private static final String FMT = | ||
| 21 | + "id=%s, ip=%s, state=%s %s"; | ||
| 22 | + | ||
| 23 | + protected static final Comparator<ControllerNode> ID_COMPARATOR = | ||
| 24 | + new Comparator<ControllerNode>() { | ||
| 25 | + @Override | ||
| 26 | + public int compare(ControllerNode ci1, ControllerNode ci2) { | ||
| 27 | + return ci1.id().toString().compareTo(ci2.id().toString()); | ||
| 28 | + } | ||
| 29 | + }; | ||
| 30 | + | ||
| 31 | + @Override | ||
| 32 | + protected Object doExecute() throws Exception { | ||
| 33 | + ClusterService service = getService(ClusterService.class); | ||
| 34 | + List<ControllerNode> nodes = newArrayList(service.getNodes()); | ||
| 35 | + Collections.sort(nodes, ID_COMPARATOR); | ||
| 36 | + ControllerNode self = service.getLocalNode(); | ||
| 37 | + for (ControllerNode node : nodes) { | ||
| 38 | + print(FMT, node.id(), node.ip(), | ||
| 39 | + service.getState(node.id()), | ||
| 40 | + node.equals(self) ? "*" : ""); | ||
| 41 | + } | ||
| 42 | + return null; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | +} |
| ... | @@ -2,6 +2,9 @@ | ... | @@ -2,6 +2,9 @@ |
| 2 | 2 | ||
| 3 | <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | 3 | <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> |
| 4 | <command> | 4 | <command> |
| 5 | + <action class="org.onlab.onos.cli.NodesListCommand"/> | ||
| 6 | + </command> | ||
| 7 | + <command> | ||
| 5 | <action class="org.onlab.onos.cli.net.FlowsListCommand"/> | 8 | <action class="org.onlab.onos.cli.net.FlowsListCommand"/> |
| 6 | </command> | 9 | </command> |
| 7 | <command> | 10 | <command> | ... | ... |
| ... | @@ -5,10 +5,10 @@ import org.onlab.onos.event.AbstractEvent; | ... | @@ -5,10 +5,10 @@ import org.onlab.onos.event.AbstractEvent; |
| 5 | /** | 5 | /** |
| 6 | * Describes cluster-related event. | 6 | * Describes cluster-related event. |
| 7 | */ | 7 | */ |
| 8 | -public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerInstance> { | 8 | +public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerNode> { |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | - * Type of device events. | 11 | + * Type of cluster-related events. |
| 12 | */ | 12 | */ |
| 13 | public enum Type { | 13 | public enum Type { |
| 14 | /** | 14 | /** |
| ... | @@ -24,14 +24,13 @@ public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerIns | ... | @@ -24,14 +24,13 @@ public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerIns |
| 24 | /** | 24 | /** |
| 25 | * Signifies that a cluster instance became active. | 25 | * Signifies that a cluster instance became active. |
| 26 | */ | 26 | */ |
| 27 | - INSTANCE_ACTIVE, | 27 | + INSTANCE_ACTIVATED, |
| 28 | 28 | ||
| 29 | /** | 29 | /** |
| 30 | * Signifies that a cluster instance became inactive. | 30 | * Signifies that a cluster instance became inactive. |
| 31 | */ | 31 | */ |
| 32 | - INSTANCE_INACTIVE | 32 | + INSTANCE_DEACTIVATED |
| 33 | } | 33 | } |
| 34 | - // TODO: do we need to fix the verv/adjective mix? discuss | ||
| 35 | 34 | ||
| 36 | /** | 35 | /** |
| 37 | * Creates an event of a given type and for the specified instance and the | 36 | * Creates an event of a given type and for the specified instance and the |
| ... | @@ -40,7 +39,7 @@ public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerIns | ... | @@ -40,7 +39,7 @@ public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerIns |
| 40 | * @param type cluster event type | 39 | * @param type cluster event type |
| 41 | * @param instance cluster device subject | 40 | * @param instance cluster device subject |
| 42 | */ | 41 | */ |
| 43 | - public ClusterEvent(Type type, ControllerInstance instance) { | 42 | + public ClusterEvent(Type type, ControllerNode instance) { |
| 44 | super(type, instance); | 43 | super(type, instance); |
| 45 | } | 44 | } |
| 46 | 45 | ||
| ... | @@ -51,7 +50,7 @@ public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerIns | ... | @@ -51,7 +50,7 @@ public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerIns |
| 51 | * @param instance event device subject | 50 | * @param instance event device subject |
| 52 | * @param time occurrence time | 51 | * @param time occurrence time |
| 53 | */ | 52 | */ |
| 54 | - public ClusterEvent(Type type, ControllerInstance instance, long time) { | 53 | + public ClusterEvent(Type type, ControllerNode instance, long time) { |
| 55 | super(type, instance, time); | 54 | super(type, instance, time); |
| 56 | } | 55 | } |
| 57 | 56 | ... | ... |
| 1 | package org.onlab.onos.cluster; | 1 | package org.onlab.onos.cluster; |
| 2 | 2 | ||
| 3 | +import org.onlab.onos.event.EventListener; | ||
| 4 | + | ||
| 3 | /** | 5 | /** |
| 4 | - * Controller cluster identity. | 6 | + * Entity capable of receiving device cluster-related events. |
| 5 | */ | 7 | */ |
| 6 | -public interface InstanceId { | 8 | +public interface ClusterEventListener extends EventListener<ClusterEvent> { |
| 7 | } | 9 | } | ... | ... |
| ... | @@ -3,27 +3,53 @@ package org.onlab.onos.cluster; | ... | @@ -3,27 +3,53 @@ package org.onlab.onos.cluster; |
| 3 | import java.util.Set; | 3 | import java.util.Set; |
| 4 | 4 | ||
| 5 | /** | 5 | /** |
| 6 | - * Service for obtaining information about the individual instances within | 6 | + * Service for obtaining information about the individual nodes within |
| 7 | * the controller cluster. | 7 | * the controller cluster. |
| 8 | */ | 8 | */ |
| 9 | public interface ClusterService { | 9 | public interface ClusterService { |
| 10 | 10 | ||
| 11 | /** | 11 | /** |
| 12 | + * Returns the local controller node. | ||
| 13 | + * | ||
| 14 | + * @return local controller node | ||
| 15 | + */ | ||
| 16 | + ControllerNode getLocalNode(); | ||
| 17 | + | ||
| 18 | + /** | ||
| 12 | * Returns the set of current cluster members. | 19 | * Returns the set of current cluster members. |
| 13 | * | 20 | * |
| 14 | * @return set of cluster members | 21 | * @return set of cluster members |
| 15 | */ | 22 | */ |
| 16 | - Set<ControllerInstance> getInstances(); | 23 | + Set<ControllerNode> getNodes(); |
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * Returns the specified controller node. | ||
| 27 | + * | ||
| 28 | + * @param nodeId controller node identifier | ||
| 29 | + * @return controller node | ||
| 30 | + */ | ||
| 31 | + ControllerNode getNode(NodeId nodeId); | ||
| 17 | 32 | ||
| 18 | /** | 33 | /** |
| 19 | - * Returns the availability state of the specified controller instance. | 34 | + * Returns the availability state of the specified controller node. |
| 20 | * | 35 | * |
| 36 | + * @param nodeId controller node identifier | ||
| 21 | * @return availability state | 37 | * @return availability state |
| 22 | */ | 38 | */ |
| 23 | - ControllerInstance.State getState(ControllerInstance instance); | 39 | + ControllerNode.State getState(NodeId nodeId); |
| 24 | - // TODO: determine if this would be better attached to ControllerInstance directly | ||
| 25 | 40 | ||
| 41 | + /** | ||
| 42 | + * Adds the specified cluster event listener. | ||
| 43 | + * | ||
| 44 | + * @param listener the cluster listener | ||
| 45 | + */ | ||
| 46 | + void addListener(ClusterEventListener listener); | ||
| 26 | 47 | ||
| 27 | - // addListener, removeListener | 48 | + /** |
| 49 | + * Removes the specified cluster event listener. | ||
| 50 | + * | ||
| 51 | + * @param listener the cluster listener | ||
| 52 | + */ | ||
| 53 | + void removeListener(ClusterEventListener listener); | ||
| 28 | 54 | ||
| 29 | } | 55 | } | ... | ... |
| 1 | +package org.onlab.onos.cluster; | ||
| 2 | + | ||
| 3 | +import java.util.Set; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * Manages inventory of controller cluster nodes; not intended for direct use. | ||
| 7 | + */ | ||
| 8 | +public interface ClusterStore { | ||
| 9 | + | ||
| 10 | + /** | ||
| 11 | + * Returns the local controller instance. | ||
| 12 | + * | ||
| 13 | + * @return local controller instance | ||
| 14 | + */ | ||
| 15 | + ControllerNode getLocalNode(); | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * Returns the set of current cluster members. | ||
| 19 | + * | ||
| 20 | + * @return set of cluster members | ||
| 21 | + */ | ||
| 22 | + Set<ControllerNode> getNodes(); | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * Returns the specified controller instance. | ||
| 26 | + * | ||
| 27 | + * @param nodeId controller instance identifier | ||
| 28 | + * @return controller instance | ||
| 29 | + */ | ||
| 30 | + ControllerNode getNode(NodeId nodeId); | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * Returns the availability state of the specified controller instance. | ||
| 34 | + * | ||
| 35 | + * @param nodeId controller instance identifier | ||
| 36 | + * @return availability state | ||
| 37 | + */ | ||
| 38 | + ControllerNode.State getState(NodeId nodeId); | ||
| 39 | + | ||
| 40 | +} |
| ... | @@ -5,7 +5,7 @@ import org.onlab.packet.IpPrefix; | ... | @@ -5,7 +5,7 @@ import org.onlab.packet.IpPrefix; |
| 5 | /** | 5 | /** |
| 6 | * Represents a controller instance as a member in a cluster. | 6 | * Represents a controller instance as a member in a cluster. |
| 7 | */ | 7 | */ |
| 8 | -public interface ControllerInstance { | 8 | +public interface ControllerNode { |
| 9 | 9 | ||
| 10 | /** Represents the operational state of the instance. */ | 10 | /** Represents the operational state of the instance. */ |
| 11 | public enum State { | 11 | public enum State { |
| ... | @@ -26,7 +26,7 @@ public interface ControllerInstance { | ... | @@ -26,7 +26,7 @@ public interface ControllerInstance { |
| 26 | * | 26 | * |
| 27 | * @return instance identifier | 27 | * @return instance identifier |
| 28 | */ | 28 | */ |
| 29 | - InstanceId id(); | 29 | + NodeId id(); |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | * Returns the IP address of the controller instance. | 32 | * Returns the IP address of the controller instance. | ... | ... |
| 1 | +package org.onlab.onos.cluster; | ||
| 2 | + | ||
| 3 | +import org.onlab.packet.IpPrefix; | ||
| 4 | + | ||
| 5 | +import java.util.Objects; | ||
| 6 | + | ||
| 7 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * Default implementation of a controller instance descriptor. | ||
| 11 | + */ | ||
| 12 | +public class DefaultControllerNode implements ControllerNode { | ||
| 13 | + | ||
| 14 | + private final NodeId id; | ||
| 15 | + private final IpPrefix ip; | ||
| 16 | + | ||
| 17 | + // For serialization | ||
| 18 | + private DefaultControllerNode() { | ||
| 19 | + this.id = null; | ||
| 20 | + this.ip = null; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * Creates a new instance with the specified id and IP address. | ||
| 25 | + * | ||
| 26 | + * @param id instance identifier | ||
| 27 | + * @param ip instance IP address | ||
| 28 | + */ | ||
| 29 | + public DefaultControllerNode(NodeId id, IpPrefix ip) { | ||
| 30 | + this.id = id; | ||
| 31 | + this.ip = ip; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + @Override | ||
| 35 | + public NodeId id() { | ||
| 36 | + return id; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + @Override | ||
| 40 | + public IpPrefix ip() { | ||
| 41 | + return ip; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + @Override | ||
| 45 | + public int hashCode() { | ||
| 46 | + return Objects.hash(id); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @Override | ||
| 50 | + public boolean equals(Object o) { | ||
| 51 | + if (this == o) { | ||
| 52 | + return true; | ||
| 53 | + } | ||
| 54 | + if (o instanceof DefaultControllerNode) { | ||
| 55 | + DefaultControllerNode that = (DefaultControllerNode) o; | ||
| 56 | + return Objects.equals(this.id, that.id); | ||
| 57 | + } | ||
| 58 | + return false; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + @Override | ||
| 62 | + public String toString() { | ||
| 63 | + return toStringHelper(this).add("id", id).add("ip", ip).toString(); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | +} |
| ... | @@ -15,6 +15,6 @@ public interface MastershipAdminService { | ... | @@ -15,6 +15,6 @@ public interface MastershipAdminService { |
| 15 | * @param deviceId device identifier | 15 | * @param deviceId device identifier |
| 16 | * @param role requested role | 16 | * @param role requested role |
| 17 | */ | 17 | */ |
| 18 | - void setRole(InstanceId instance, DeviceId deviceId, MastershipRole role); | 18 | + void setRole(NodeId instance, DeviceId deviceId, MastershipRole role); |
| 19 | 19 | ||
| 20 | } | 20 | } | ... | ... |
| ... | @@ -8,7 +8,7 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -8,7 +8,7 @@ import org.onlab.onos.net.DeviceId; |
| 8 | */ | 8 | */ |
| 9 | public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceId> { | 9 | public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceId> { |
| 10 | 10 | ||
| 11 | - InstanceId master; | 11 | + NodeId master; |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | * Type of mastership events. | 14 | * Type of mastership events. |
| ... | @@ -28,7 +28,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI | ... | @@ -28,7 +28,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI |
| 28 | * @param device event device subject | 28 | * @param device event device subject |
| 29 | * @param master master ID subject | 29 | * @param master master ID subject |
| 30 | */ | 30 | */ |
| 31 | - protected MastershipEvent(Type type, DeviceId device, InstanceId master) { | 31 | + protected MastershipEvent(Type type, DeviceId device, NodeId master) { |
| 32 | super(type, device); | 32 | super(type, device); |
| 33 | this.master = master; | 33 | this.master = master; |
| 34 | } | 34 | } |
| ... | @@ -42,7 +42,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI | ... | @@ -42,7 +42,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI |
| 42 | * @param master master ID subject | 42 | * @param master master ID subject |
| 43 | * @param time occurrence time | 43 | * @param time occurrence time |
| 44 | */ | 44 | */ |
| 45 | - protected MastershipEvent(Type type, DeviceId device, InstanceId master, long time) { | 45 | + protected MastershipEvent(Type type, DeviceId device, NodeId master, long time) { |
| 46 | super(type, device, time); | 46 | super(type, device, time); |
| 47 | this.master = master; | 47 | this.master = master; |
| 48 | } | 48 | } |
| ... | @@ -52,7 +52,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI | ... | @@ -52,7 +52,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI |
| 52 | * | 52 | * |
| 53 | * @return master ID subject | 53 | * @return master ID subject |
| 54 | */ | 54 | */ |
| 55 | - public InstanceId master() { | 55 | + public NodeId master() { |
| 56 | return master; | 56 | return master; |
| 57 | } | 57 | } |
| 58 | } | 58 | } | ... | ... |
| ... | @@ -6,5 +6,4 @@ import org.onlab.onos.event.EventListener; | ... | @@ -6,5 +6,4 @@ import org.onlab.onos.event.EventListener; |
| 6 | * Entity capable of receiving device mastership-related events. | 6 | * Entity capable of receiving device mastership-related events. |
| 7 | */ | 7 | */ |
| 8 | public interface MastershipListener extends EventListener<MastershipEvent> { | 8 | public interface MastershipListener extends EventListener<MastershipEvent> { |
| 9 | - | ||
| 10 | } | 9 | } | ... | ... |
| ... | @@ -19,15 +19,15 @@ public interface MastershipService { | ... | @@ -19,15 +19,15 @@ public interface MastershipService { |
| 19 | * @param deviceId the identifier of the device | 19 | * @param deviceId the identifier of the device |
| 20 | * @return the ID of the master controller for the device | 20 | * @return the ID of the master controller for the device |
| 21 | */ | 21 | */ |
| 22 | - InstanceId getMasterFor(DeviceId deviceId); | 22 | + NodeId getMasterFor(DeviceId deviceId); |
| 23 | 23 | ||
| 24 | /** | 24 | /** |
| 25 | * Returns the devices for which a controller is master. | 25 | * Returns the devices for which a controller is master. |
| 26 | * | 26 | * |
| 27 | - * @param instanceId the ID of the controller | 27 | + * @param nodeId the ID of the controller |
| 28 | * @return a set of device IDs | 28 | * @return a set of device IDs |
| 29 | */ | 29 | */ |
| 30 | - Set<DeviceId> getDevicesOf(InstanceId instanceId); | 30 | + Set<DeviceId> getDevicesOf(NodeId nodeId); |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| 33 | * Returns the mastership status of this controller for a given device. | 33 | * Returns the mastership status of this controller for a given device. |
| ... | @@ -38,14 +38,14 @@ public interface MastershipService { | ... | @@ -38,14 +38,14 @@ public interface MastershipService { |
| 38 | MastershipRole requestRoleFor(DeviceId deviceId); | 38 | MastershipRole requestRoleFor(DeviceId deviceId); |
| 39 | 39 | ||
| 40 | /** | 40 | /** |
| 41 | - * Adds the specified mastership listener. | 41 | + * Adds the specified mastership change listener. |
| 42 | * | 42 | * |
| 43 | * @param listener the mastership listener | 43 | * @param listener the mastership listener |
| 44 | */ | 44 | */ |
| 45 | void addListener(MastershipListener listener); | 45 | void addListener(MastershipListener listener); |
| 46 | 46 | ||
| 47 | /** | 47 | /** |
| 48 | - * Removes the specified device listener. | 48 | + * Removes the specified mastership change listener. |
| 49 | * | 49 | * |
| 50 | * @param listener the mastership listener | 50 | * @param listener the mastership listener |
| 51 | */ | 51 | */ | ... | ... |
| ... | @@ -6,11 +6,12 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -6,11 +6,12 @@ import org.onlab.onos.net.DeviceId; |
| 6 | import org.onlab.onos.net.MastershipRole; | 6 | import org.onlab.onos.net.MastershipRole; |
| 7 | 7 | ||
| 8 | /** | 8 | /** |
| 9 | - * Manages inventory of mastership roles for devices, across controller instances. | 9 | + * Manages inventory of mastership roles for devices, across controller |
| 10 | + * instances; not intended for direct use. | ||
| 10 | */ | 11 | */ |
| 11 | public interface MastershipStore { | 12 | public interface MastershipStore { |
| 12 | 13 | ||
| 13 | - // three things to map: InstanceId, DeviceId, MastershipRole | 14 | + // three things to map: NodeId, DeviceId, MastershipRole |
| 14 | 15 | ||
| 15 | /** | 16 | /** |
| 16 | * Sets a device's role for a specified controller instance. | 17 | * Sets a device's role for a specified controller instance. |
| ... | @@ -20,8 +21,8 @@ public interface MastershipStore { | ... | @@ -20,8 +21,8 @@ public interface MastershipStore { |
| 20 | * @param role new role | 21 | * @param role new role |
| 21 | * @return a mastership event | 22 | * @return a mastership event |
| 22 | */ | 23 | */ |
| 23 | - MastershipEvent setRole( | 24 | + MastershipEvent setRole(NodeId instance, DeviceId deviceId, |
| 24 | - InstanceId instance, DeviceId deviceId, MastershipRole role); | 25 | + MastershipRole role); |
| 25 | 26 | ||
| 26 | /** | 27 | /** |
| 27 | * Adds or updates the mastership information for a device. | 28 | * Adds or updates the mastership information for a device. |
| ... | @@ -31,8 +32,8 @@ public interface MastershipStore { | ... | @@ -31,8 +32,8 @@ public interface MastershipStore { |
| 31 | * @param role new role | 32 | * @param role new role |
| 32 | * @return a mastership event | 33 | * @return a mastership event |
| 33 | */ | 34 | */ |
| 34 | - MastershipEvent addOrUpdateDevice( | 35 | + MastershipEvent addOrUpdateDevice(NodeId instance, DeviceId deviceId, |
| 35 | - InstanceId instance, DeviceId deviceId, MastershipRole role); | 36 | + MastershipRole role); |
| 36 | 37 | ||
| 37 | /** | 38 | /** |
| 38 | * Returns the master for a device. | 39 | * Returns the master for a device. |
| ... | @@ -40,22 +41,22 @@ public interface MastershipStore { | ... | @@ -40,22 +41,22 @@ public interface MastershipStore { |
| 40 | * @param deviceId the device identifier | 41 | * @param deviceId the device identifier |
| 41 | * @return the instance identifier of the master | 42 | * @return the instance identifier of the master |
| 42 | */ | 43 | */ |
| 43 | - InstanceId getMaster(DeviceId deviceId); | 44 | + NodeId getMaster(DeviceId deviceId); |
| 44 | 45 | ||
| 45 | /** | 46 | /** |
| 46 | * Returns the devices that a controller instance is master of. | 47 | * Returns the devices that a controller instance is master of. |
| 47 | * | 48 | * |
| 48 | - * @param instanceId the instance identifier | 49 | + * @param nodeId the instance identifier |
| 49 | * @return a set of device identifiers | 50 | * @return a set of device identifiers |
| 50 | */ | 51 | */ |
| 51 | - Set<DeviceId> getDevices(InstanceId instanceId); | 52 | + Set<DeviceId> getDevices(NodeId nodeId); |
| 52 | 53 | ||
| 53 | /** | 54 | /** |
| 54 | * Returns the role of a device for a specific controller instance. | 55 | * Returns the role of a device for a specific controller instance. |
| 55 | * | 56 | * |
| 56 | - * @param instanceId the instance identifier | 57 | + * @param nodeId the instance identifier |
| 57 | - * @param deviceId the device identifiers | 58 | + * @param deviceId the device identifiers |
| 58 | * @return the role | 59 | * @return the role |
| 59 | */ | 60 | */ |
| 60 | - MastershipRole getRole(InstanceId instanceId, DeviceId deviceId); | 61 | + MastershipRole getRole(NodeId nodeId, DeviceId deviceId); |
| 61 | } | 62 | } | ... | ... |
| 1 | +package org.onlab.onos.cluster; | ||
| 2 | + | ||
| 3 | +import java.util.Objects; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * Controller cluster identity. | ||
| 7 | + */ | ||
| 8 | +public class NodeId { | ||
| 9 | + | ||
| 10 | + private final String id; | ||
| 11 | + | ||
| 12 | + // Default constructor for serialization | ||
| 13 | + protected NodeId() { | ||
| 14 | + id = null; | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * Creates a new cluster node identifier from the specified string. | ||
| 19 | + * | ||
| 20 | + * @param id string identifier | ||
| 21 | + */ | ||
| 22 | + public NodeId(String id) { | ||
| 23 | + this.id = id; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + @Override | ||
| 27 | + public int hashCode() { | ||
| 28 | + return Objects.hash(id); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + @Override | ||
| 32 | + public boolean equals(Object obj) { | ||
| 33 | + if (this == obj) { | ||
| 34 | + return true; | ||
| 35 | + } | ||
| 36 | + if (obj instanceof NodeId) { | ||
| 37 | + final NodeId other = (NodeId) obj; | ||
| 38 | + return Objects.equals(this.id, other.id); | ||
| 39 | + } | ||
| 40 | + return false; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + public String toString() { | ||
| 45 | + return id; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | +} |
| ... | @@ -66,6 +66,9 @@ public class ConnectPoint { | ... | @@ -66,6 +66,9 @@ public class ConnectPoint { |
| 66 | 66 | ||
| 67 | @Override | 67 | @Override |
| 68 | public boolean equals(Object obj) { | 68 | public boolean equals(Object obj) { |
| 69 | + if (this == obj) { | ||
| 70 | + return true; | ||
| 71 | + } | ||
| 69 | if (obj instanceof ConnectPoint) { | 72 | if (obj instanceof ConnectPoint) { |
| 70 | final ConnectPoint other = (ConnectPoint) obj; | 73 | final ConnectPoint other = (ConnectPoint) obj; |
| 71 | return Objects.equals(this.elementId, other.elementId) && | 74 | return Objects.equals(this.elementId, other.elementId) && | ... | ... |
| ... | @@ -85,6 +85,9 @@ public class DefaultDevice extends AbstractElement implements Device { | ... | @@ -85,6 +85,9 @@ public class DefaultDevice extends AbstractElement implements Device { |
| 85 | 85 | ||
| 86 | @Override | 86 | @Override |
| 87 | public boolean equals(Object obj) { | 87 | public boolean equals(Object obj) { |
| 88 | + if (this == obj) { | ||
| 89 | + return true; | ||
| 90 | + } | ||
| 88 | if (obj instanceof DefaultDevice) { | 91 | if (obj instanceof DefaultDevice) { |
| 89 | final DefaultDevice other = (DefaultDevice) obj; | 92 | final DefaultDevice other = (DefaultDevice) obj; |
| 90 | return Objects.equals(this.id, other.id) && | 93 | return Objects.equals(this.id, other.id) && | ... | ... |
| ... | @@ -63,6 +63,9 @@ public class DefaultHost extends AbstractElement implements Host { | ... | @@ -63,6 +63,9 @@ public class DefaultHost extends AbstractElement implements Host { |
| 63 | 63 | ||
| 64 | @Override | 64 | @Override |
| 65 | public boolean equals(Object obj) { | 65 | public boolean equals(Object obj) { |
| 66 | + if (this == obj) { | ||
| 67 | + return true; | ||
| 68 | + } | ||
| 66 | if (obj instanceof DefaultHost) { | 69 | if (obj instanceof DefaultHost) { |
| 67 | final DefaultHost other = (DefaultHost) obj; | 70 | final DefaultHost other = (DefaultHost) obj; |
| 68 | return Objects.equals(this.id, other.id) && | 71 | return Objects.equals(this.id, other.id) && | ... | ... |
| ... | @@ -53,6 +53,9 @@ public class DefaultLink extends AbstractModel implements Link { | ... | @@ -53,6 +53,9 @@ public class DefaultLink extends AbstractModel implements Link { |
| 53 | 53 | ||
| 54 | @Override | 54 | @Override |
| 55 | public boolean equals(Object obj) { | 55 | public boolean equals(Object obj) { |
| 56 | + if (this == obj) { | ||
| 57 | + return true; | ||
| 58 | + } | ||
| 56 | if (obj instanceof DefaultLink) { | 59 | if (obj instanceof DefaultLink) { |
| 57 | final DefaultLink other = (DefaultLink) obj; | 60 | final DefaultLink other = (DefaultLink) obj; |
| 58 | return Objects.equals(this.src, other.src) && | 61 | return Objects.equals(this.src, other.src) && | ... | ... |
| ... | @@ -57,11 +57,14 @@ public class DefaultPath extends DefaultLink implements Path { | ... | @@ -57,11 +57,14 @@ public class DefaultPath extends DefaultLink implements Path { |
| 57 | 57 | ||
| 58 | @Override | 58 | @Override |
| 59 | public int hashCode() { | 59 | public int hashCode() { |
| 60 | - return 31 * super.hashCode() + Objects.hash(links); | 60 | + return Objects.hash(links); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | @Override | 63 | @Override |
| 64 | public boolean equals(Object obj) { | 64 | public boolean equals(Object obj) { |
| 65 | + if (this == obj) { | ||
| 66 | + return true; | ||
| 67 | + } | ||
| 65 | if (obj instanceof DefaultPath) { | 68 | if (obj instanceof DefaultPath) { |
| 66 | final DefaultPath other = (DefaultPath) obj; | 69 | final DefaultPath other = (DefaultPath) obj; |
| 67 | return Objects.equals(this.links, other.links); | 70 | return Objects.equals(this.links, other.links); | ... | ... |
| ... | @@ -58,6 +58,9 @@ public class DefaultPort implements Port { | ... | @@ -58,6 +58,9 @@ public class DefaultPort implements Port { |
| 58 | 58 | ||
| 59 | @Override | 59 | @Override |
| 60 | public boolean equals(Object obj) { | 60 | public boolean equals(Object obj) { |
| 61 | + if (this == obj) { | ||
| 62 | + return true; | ||
| 63 | + } | ||
| 61 | if (obj instanceof DefaultPort) { | 64 | if (obj instanceof DefaultPort) { |
| 62 | final DefaultPort other = (DefaultPort) obj; | 65 | final DefaultPort other = (DefaultPort) obj; |
| 63 | return Objects.equals(this.element.id(), other.element.id()) && | 66 | return Objects.equals(this.element.id(), other.element.id()) && | ... | ... |
| ... | @@ -7,9 +7,6 @@ import java.net.URI; | ... | @@ -7,9 +7,6 @@ import java.net.URI; |
| 7 | */ | 7 | */ |
| 8 | public final class DeviceId extends ElementId { | 8 | public final class DeviceId extends ElementId { |
| 9 | 9 | ||
| 10 | - // Default constructor for serialization | ||
| 11 | - protected DeviceId() {} | ||
| 12 | - | ||
| 13 | // Public construction is prohibited | 10 | // Public construction is prohibited |
| 14 | private DeviceId(URI uri) { | 11 | private DeviceId(URI uri) { |
| 15 | super(uri); | 12 | super(uri); | ... | ... |
| ... | @@ -40,6 +40,9 @@ public abstract class ElementId { | ... | @@ -40,6 +40,9 @@ public abstract class ElementId { |
| 40 | 40 | ||
| 41 | @Override | 41 | @Override |
| 42 | public boolean equals(Object obj) { | 42 | public boolean equals(Object obj) { |
| 43 | + if (this == obj) { | ||
| 44 | + return true; | ||
| 45 | + } | ||
| 43 | if (obj instanceof ElementId) { | 46 | if (obj instanceof ElementId) { |
| 44 | final ElementId that = (ElementId) obj; | 47 | final ElementId that = (ElementId) obj; |
| 45 | return this.getClass() == that.getClass() && | 48 | return this.getClass() == that.getClass() && | ... | ... |
| ... | @@ -79,6 +79,9 @@ public final class PortNumber { | ... | @@ -79,6 +79,9 @@ public final class PortNumber { |
| 79 | 79 | ||
| 80 | @Override | 80 | @Override |
| 81 | public boolean equals(Object obj) { | 81 | public boolean equals(Object obj) { |
| 82 | + if (this == obj) { | ||
| 83 | + return true; | ||
| 84 | + } | ||
| 82 | if (obj instanceof PortNumber) { | 85 | if (obj instanceof PortNumber) { |
| 83 | final PortNumber other = (PortNumber) obj; | 86 | final PortNumber other = (PortNumber) obj; |
| 84 | return this.number == other.number; | 87 | return this.number == other.number; | ... | ... |
| ... | @@ -10,7 +10,7 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -10,7 +10,7 @@ import org.onlab.onos.net.provider.ProviderId; |
| 10 | import java.util.List; | 10 | import java.util.List; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| 13 | - * Manages inventory of infrastructure devices. | 13 | + * Manages inventory of infrastructure devices; not intended for direct use. |
| 14 | */ | 14 | */ |
| 15 | public interface DeviceStore { | 15 | public interface DeviceStore { |
| 16 | 16 | ... | ... |
| ... | @@ -147,7 +147,6 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -147,7 +147,6 @@ public class DefaultFlowRule implements FlowRule { |
| 147 | * @see java.lang.Object#equals(java.lang.Object) | 147 | * @see java.lang.Object#equals(java.lang.Object) |
| 148 | */ | 148 | */ |
| 149 | public boolean equals(Object obj) { | 149 | public boolean equals(Object obj) { |
| 150 | - | ||
| 151 | if (this == obj) { | 150 | if (this == obj) { |
| 152 | return true; | 151 | return true; |
| 153 | } | 152 | } | ... | ... |
| ... | @@ -3,7 +3,7 @@ package org.onlab.onos.net.flow; | ... | @@ -3,7 +3,7 @@ package org.onlab.onos.net.flow; |
| 3 | import org.onlab.onos.net.DeviceId; | 3 | import org.onlab.onos.net.DeviceId; |
| 4 | 4 | ||
| 5 | /** | 5 | /** |
| 6 | - * Manages inventory of flow rules. | 6 | + * Manages inventory of flow rules; not intended for direct use. |
| 7 | */ | 7 | */ |
| 8 | public interface FlowRuleStore { | 8 | public interface FlowRuleStore { |
| 9 | 9 | ... | ... |
| ... | @@ -12,8 +12,7 @@ import org.onlab.packet.VlanId; | ... | @@ -12,8 +12,7 @@ import org.onlab.packet.VlanId; |
| 12 | import java.util.Set; | 12 | import java.util.Set; |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | - * Manages inventory of end-station hosts. It may do so using whatever | 15 | + * Manages inventory of end-station hosts; not intended for direct use. |
| 16 | - * means are appropriate. | ||
| 17 | */ | 16 | */ |
| 18 | public interface HostStore { | 17 | public interface HostStore { |
| 19 | 18 | ... | ... |
| ... | @@ -8,8 +8,7 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -8,8 +8,7 @@ import org.onlab.onos.net.provider.ProviderId; |
| 8 | import java.util.Set; | 8 | import java.util.Set; |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | - * Manages inventory of infrastructure links. It may do so using whatever | 11 | + * Manages inventory of infrastructure links; not intended for direct use. |
| 12 | - * means are appropriate. | ||
| 13 | */ | 12 | */ |
| 14 | public interface LinkStore { | 13 | public interface LinkStore { |
| 15 | 14 | ... | ... |
| ... | @@ -54,6 +54,9 @@ public class DefaultInboundPacket implements InboundPacket { | ... | @@ -54,6 +54,9 @@ public class DefaultInboundPacket implements InboundPacket { |
| 54 | 54 | ||
| 55 | @Override | 55 | @Override |
| 56 | public boolean equals(Object obj) { | 56 | public boolean equals(Object obj) { |
| 57 | + if (this == obj) { | ||
| 58 | + return true; | ||
| 59 | + } | ||
| 57 | if (obj instanceof InboundPacket) { | 60 | if (obj instanceof InboundPacket) { |
| 58 | final DefaultInboundPacket other = (DefaultInboundPacket) obj; | 61 | final DefaultInboundPacket other = (DefaultInboundPacket) obj; |
| 59 | return Objects.equals(this.receivedFrom, other.receivedFrom) && | 62 | return Objects.equals(this.receivedFrom, other.receivedFrom) && | ... | ... |
| ... | @@ -12,12 +12,6 @@ public class ProviderId { | ... | @@ -12,12 +12,6 @@ public class ProviderId { |
| 12 | private final String scheme; | 12 | private final String scheme; |
| 13 | private final String id; | 13 | private final String id; |
| 14 | 14 | ||
| 15 | - // Default constructor for serialization | ||
| 16 | - protected ProviderId() { | ||
| 17 | - scheme = null; | ||
| 18 | - id = null; | ||
| 19 | - } | ||
| 20 | - | ||
| 21 | /** | 15 | /** |
| 22 | * Creates a new provider identifier from the specified string. | 16 | * Creates a new provider identifier from the specified string. |
| 23 | * The providers are expected to follow the reverse DNS convention, e.g. | 17 | * The providers are expected to follow the reverse DNS convention, e.g. |
| ... | @@ -40,6 +34,15 @@ public class ProviderId { | ... | @@ -40,6 +34,15 @@ public class ProviderId { |
| 40 | return scheme; | 34 | return scheme; |
| 41 | } | 35 | } |
| 42 | 36 | ||
| 37 | + /** | ||
| 38 | + * Returns the device URI scheme specific id portion. | ||
| 39 | + * | ||
| 40 | + * @return id | ||
| 41 | + */ | ||
| 42 | + public String id() { | ||
| 43 | + return id; | ||
| 44 | + } | ||
| 45 | + | ||
| 43 | @Override | 46 | @Override |
| 44 | public int hashCode() { | 47 | public int hashCode() { |
| 45 | return Objects.hash(scheme, id); | 48 | return Objects.hash(scheme, id); |
| ... | @@ -50,12 +53,12 @@ public class ProviderId { | ... | @@ -50,12 +53,12 @@ public class ProviderId { |
| 50 | if (this == obj) { | 53 | if (this == obj) { |
| 51 | return true; | 54 | return true; |
| 52 | } | 55 | } |
| 53 | - if (obj == null || getClass() != obj.getClass()) { | 56 | + if (obj instanceof ProviderId) { |
| 54 | - return false; | 57 | + final ProviderId other = (ProviderId) obj; |
| 58 | + return Objects.equals(this.scheme, other.scheme) && | ||
| 59 | + Objects.equals(this.id, other.id); | ||
| 55 | } | 60 | } |
| 56 | - final ProviderId other = (ProviderId) obj; | 61 | + return false; |
| 57 | - return Objects.equals(this.scheme, other.scheme) && | ||
| 58 | - Objects.equals(this.id, other.id); | ||
| 59 | } | 62 | } |
| 60 | 63 | ||
| 61 | @Override | 64 | @Override | ... | ... |
| ... | @@ -43,6 +43,9 @@ public final class ClusterId { | ... | @@ -43,6 +43,9 @@ public final class ClusterId { |
| 43 | 43 | ||
| 44 | @Override | 44 | @Override |
| 45 | public boolean equals(Object obj) { | 45 | public boolean equals(Object obj) { |
| 46 | + if (this == obj) { | ||
| 47 | + return true; | ||
| 48 | + } | ||
| 46 | if (obj instanceof ClusterId) { | 49 | if (obj instanceof ClusterId) { |
| 47 | final ClusterId other = (ClusterId) obj; | 50 | final ClusterId other = (ClusterId) obj; |
| 48 | return Objects.equals(this.id, other.id); | 51 | return Objects.equals(this.id, other.id); | ... | ... |
| ... | @@ -59,6 +59,9 @@ public class DefaultTopologyCluster implements TopologyCluster { | ... | @@ -59,6 +59,9 @@ public class DefaultTopologyCluster implements TopologyCluster { |
| 59 | 59 | ||
| 60 | @Override | 60 | @Override |
| 61 | public boolean equals(Object obj) { | 61 | public boolean equals(Object obj) { |
| 62 | + if (this == obj) { | ||
| 63 | + return true; | ||
| 64 | + } | ||
| 62 | if (obj instanceof DefaultTopologyCluster) { | 65 | if (obj instanceof DefaultTopologyCluster) { |
| 63 | final DefaultTopologyCluster other = (DefaultTopologyCluster) obj; | 66 | final DefaultTopologyCluster other = (DefaultTopologyCluster) obj; |
| 64 | return Objects.equals(this.id, other.id) && | 67 | return Objects.equals(this.id, other.id) && | ... | ... |
| ... | @@ -50,6 +50,9 @@ public class DefaultTopologyEdge implements TopologyEdge { | ... | @@ -50,6 +50,9 @@ public class DefaultTopologyEdge implements TopologyEdge { |
| 50 | 50 | ||
| 51 | @Override | 51 | @Override |
| 52 | public boolean equals(Object obj) { | 52 | public boolean equals(Object obj) { |
| 53 | + if (this == obj) { | ||
| 54 | + return true; | ||
| 55 | + } | ||
| 53 | if (obj instanceof DefaultTopologyEdge) { | 56 | if (obj instanceof DefaultTopologyEdge) { |
| 54 | final DefaultTopologyEdge other = (DefaultTopologyEdge) obj; | 57 | final DefaultTopologyEdge other = (DefaultTopologyEdge) obj; |
| 55 | return Objects.equals(this.link, other.link); | 58 | return Objects.equals(this.link, other.link); | ... | ... |
| ... | @@ -32,6 +32,9 @@ public class DefaultTopologyVertex implements TopologyVertex { | ... | @@ -32,6 +32,9 @@ public class DefaultTopologyVertex implements TopologyVertex { |
| 32 | 32 | ||
| 33 | @Override | 33 | @Override |
| 34 | public boolean equals(Object obj) { | 34 | public boolean equals(Object obj) { |
| 35 | + if (this == obj) { | ||
| 36 | + return true; | ||
| 37 | + } | ||
| 35 | if (obj instanceof DefaultTopologyVertex) { | 38 | if (obj instanceof DefaultTopologyVertex) { |
| 36 | final DefaultTopologyVertex other = (DefaultTopologyVertex) obj; | 39 | final DefaultTopologyVertex other = (DefaultTopologyVertex) obj; |
| 37 | return Objects.equals(this.deviceId, other.deviceId); | 40 | return Objects.equals(this.deviceId, other.deviceId); | ... | ... |
| ... | @@ -11,8 +11,7 @@ import java.util.List; | ... | @@ -11,8 +11,7 @@ import java.util.List; |
| 11 | import java.util.Set; | 11 | import java.util.Set; |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | - * Manages inventory of topology snapshots. It may do so using whatever | 14 | + * Manages inventory of topology snapshots; not intended for direct use. |
| 15 | - * means appropriate. | ||
| 16 | */ | 15 | */ |
| 17 | public interface TopologyStore { | 16 | public interface TopologyStore { |
| 18 | 17 | ... | ... |
| 1 | +package org.onlab.onos.cluster.impl; | ||
| 2 | + | ||
| 3 | +import org.apache.felix.scr.annotations.Activate; | ||
| 4 | +import org.apache.felix.scr.annotations.Component; | ||
| 5 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 6 | +import org.apache.felix.scr.annotations.Reference; | ||
| 7 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 8 | +import org.apache.felix.scr.annotations.Service; | ||
| 9 | +import org.onlab.onos.cluster.ClusterEvent; | ||
| 10 | +import org.onlab.onos.cluster.ClusterEventListener; | ||
| 11 | +import org.onlab.onos.cluster.ClusterService; | ||
| 12 | +import org.onlab.onos.cluster.ClusterStore; | ||
| 13 | +import org.onlab.onos.cluster.ControllerNode; | ||
| 14 | +import org.onlab.onos.cluster.NodeId; | ||
| 15 | +import org.onlab.onos.event.AbstractListenerRegistry; | ||
| 16 | +import org.onlab.onos.event.EventDeliveryService; | ||
| 17 | +import org.slf4j.Logger; | ||
| 18 | + | ||
| 19 | +import java.util.Set; | ||
| 20 | + | ||
| 21 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 22 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * Implementation of the cluster service. | ||
| 26 | + */ | ||
| 27 | +@Component(immediate = true) | ||
| 28 | +@Service | ||
| 29 | +public class ClusterManager implements ClusterService { | ||
| 30 | + | ||
| 31 | + public static final String INSTANCE_ID_NULL = "Instance ID cannot be null"; | ||
| 32 | + private final Logger log = getLogger(getClass()); | ||
| 33 | + | ||
| 34 | + protected final AbstractListenerRegistry<ClusterEvent, ClusterEventListener> | ||
| 35 | + listenerRegistry = new AbstractListenerRegistry<>(); | ||
| 36 | + | ||
| 37 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 38 | + protected ClusterStore store; | ||
| 39 | + | ||
| 40 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 41 | + protected EventDeliveryService eventDispatcher; | ||
| 42 | + | ||
| 43 | + @Activate | ||
| 44 | + public void activate() { | ||
| 45 | + eventDispatcher.addSink(ClusterEvent.class, listenerRegistry); | ||
| 46 | + log.info("Started"); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @Deactivate | ||
| 50 | + public void deactivate() { | ||
| 51 | + eventDispatcher.removeSink(ClusterEvent.class); | ||
| 52 | + log.info("Stopped"); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + public ControllerNode getLocalNode() { | ||
| 57 | + return store.getLocalNode(); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public Set<ControllerNode> getNodes() { | ||
| 62 | + return store.getNodes(); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @Override | ||
| 66 | + public ControllerNode getNode(NodeId nodeId) { | ||
| 67 | + checkNotNull(nodeId, INSTANCE_ID_NULL); | ||
| 68 | + return store.getNode(nodeId); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + @Override | ||
| 72 | + public ControllerNode.State getState(NodeId nodeId) { | ||
| 73 | + checkNotNull(nodeId, INSTANCE_ID_NULL); | ||
| 74 | + return store.getState(nodeId); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + @Override | ||
| 78 | + public void addListener(ClusterEventListener listener) { | ||
| 79 | + listenerRegistry.addListener(listener); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + @Override | ||
| 83 | + public void removeListener(ClusterEventListener listener) { | ||
| 84 | + listenerRegistry.removeListener(listener); | ||
| 85 | + } | ||
| 86 | +} |
| ... | @@ -33,7 +33,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -33,7 +33,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 33 | import static org.slf4j.LoggerFactory.getLogger; | 33 | import static org.slf4j.LoggerFactory.getLogger; |
| 34 | 34 | ||
| 35 | /** | 35 | /** |
| 36 | - * Provides basic implementation of the device SB & NB APIs. | 36 | + * Provides implementation of the device SB & NB APIs. |
| 37 | */ | 37 | */ |
| 38 | @Component(immediate = true) | 38 | @Component(immediate = true) |
| 39 | @Service | 39 | @Service | ... | ... |
| ... | @@ -33,6 +33,9 @@ import org.slf4j.Logger; | ... | @@ -33,6 +33,9 @@ import org.slf4j.Logger; |
| 33 | 33 | ||
| 34 | import com.google.common.collect.Lists; | 34 | import com.google.common.collect.Lists; |
| 35 | 35 | ||
| 36 | +/** | ||
| 37 | + * Provides implementation of the flow NB & SB APIs. | ||
| 38 | + */ | ||
| 36 | @Component(immediate = true) | 39 | @Component(immediate = true) |
| 37 | @Service | 40 | @Service |
| 38 | public class FlowRuleManager | 41 | public class FlowRuleManager | ... | ... |
| ... | @@ -112,7 +112,7 @@ public class DistributedDeviceManagerTest { | ... | @@ -112,7 +112,7 @@ public class DistributedDeviceManagerTest { |
| 112 | mgr.deactivate(); | 112 | mgr.deactivate(); |
| 113 | 113 | ||
| 114 | dstore.deactivate(); | 114 | dstore.deactivate(); |
| 115 | - dstore.theInstance.shutdown(); | 115 | + ((TestDistributedDeviceStore) dstore).shutdownHz(); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | private void connectDevice(DeviceId deviceId, String swVersion) { | 118 | private void connectDevice(DeviceId deviceId, String swVersion) { |
| ... | @@ -290,5 +290,12 @@ public class DistributedDeviceManagerTest { | ... | @@ -290,5 +290,12 @@ public class DistributedDeviceManagerTest { |
| 290 | } | 290 | } |
| 291 | }; | 291 | }; |
| 292 | } | 292 | } |
| 293 | + | ||
| 294 | + /** | ||
| 295 | + * Shutdowns the hazelcast instance. | ||
| 296 | + */ | ||
| 297 | + public void shutdownHz() { | ||
| 298 | + theInstance.shutdown(); | ||
| 299 | + } | ||
| 293 | } | 300 | } |
| 294 | } | 301 | } | ... | ... |
| 1 | +package org.onlab.onos.store.cluster.impl; | ||
| 2 | + | ||
| 3 | +import com.google.common.collect.ImmutableSet; | ||
| 4 | +import com.hazelcast.core.HazelcastInstance; | ||
| 5 | +import com.hazelcast.core.Member; | ||
| 6 | +import org.apache.felix.scr.annotations.Activate; | ||
| 7 | +import org.apache.felix.scr.annotations.Component; | ||
| 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.apache.felix.scr.annotations.Service; | ||
| 12 | +import org.onlab.onos.cluster.ClusterStore; | ||
| 13 | +import org.onlab.onos.cluster.ControllerNode; | ||
| 14 | +import org.onlab.onos.cluster.DefaultControllerNode; | ||
| 15 | +import org.onlab.onos.cluster.NodeId; | ||
| 16 | +import org.onlab.onos.store.StoreService; | ||
| 17 | +import org.onlab.packet.IpPrefix; | ||
| 18 | +import org.slf4j.Logger; | ||
| 19 | + | ||
| 20 | +import java.util.Set; | ||
| 21 | + | ||
| 22 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * Distributed implementation of the cluster nodes store. | ||
| 26 | + */ | ||
| 27 | +@Component(immediate = true) | ||
| 28 | +@Service | ||
| 29 | +public class DistributedClusterStore implements ClusterStore { | ||
| 30 | + | ||
| 31 | + private final Logger log = getLogger(getClass()); | ||
| 32 | + | ||
| 33 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 34 | + protected StoreService storeService; | ||
| 35 | + | ||
| 36 | + private HazelcastInstance theInstance; | ||
| 37 | + | ||
| 38 | + // FIXME: experimental implementation; enhance to assure persistence and | ||
| 39 | + // visibility to nodes that are not currently in the cluster | ||
| 40 | + | ||
| 41 | + @Activate | ||
| 42 | + public void activate() { | ||
| 43 | + log.info("Started"); | ||
| 44 | + theInstance = storeService.getHazelcastInstance(); | ||
| 45 | + | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @Deactivate | ||
| 49 | + public void deactivate() { | ||
| 50 | + log.info("Stopped"); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + @Override | ||
| 54 | + public ControllerNode getLocalNode() { | ||
| 55 | + return node(theInstance.getCluster().getLocalMember()); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + @Override | ||
| 59 | + public Set<ControllerNode> getNodes() { | ||
| 60 | + ImmutableSet.Builder<ControllerNode> builder = ImmutableSet.builder(); | ||
| 61 | + for (Member member : theInstance.getCluster().getMembers()) { | ||
| 62 | + builder.add(node(member)); | ||
| 63 | + } | ||
| 64 | + return builder.build(); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + @Override | ||
| 68 | + public ControllerNode getNode(NodeId nodeId) { | ||
| 69 | + for (Member member : theInstance.getCluster().getMembers()) { | ||
| 70 | + if (member.getUuid().equals(nodeId.toString())) { | ||
| 71 | + return node(member); | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + return null; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + @Override | ||
| 78 | + public ControllerNode.State getState(NodeId nodeId) { | ||
| 79 | + return ControllerNode.State.ACTIVE; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + // Creates a controller node descriptor from the Hazelcast member. | ||
| 83 | + private ControllerNode node(Member member) { | ||
| 84 | + return new DefaultControllerNode(new NodeId(member.getUuid()), | ||
| 85 | + IpPrefix.valueOf(member.getSocketAddress().getAddress().getAddress())); | ||
| 86 | + } | ||
| 87 | +} |
| ... | @@ -16,6 +16,9 @@ import com.esotericsoftware.kryo.serializers.CollectionSerializer; | ... | @@ -16,6 +16,9 @@ import com.esotericsoftware.kryo.serializers.CollectionSerializer; |
| 16 | import com.google.common.collect.ImmutableSet; | 16 | import com.google.common.collect.ImmutableSet; |
| 17 | 17 | ||
| 18 | // TODO move to util, etc. | 18 | // TODO move to util, etc. |
| 19 | +/** | ||
| 20 | + * Kryo Serializer for {@link DefaultPort}. | ||
| 21 | + */ | ||
| 19 | public final class DefaultPortSerializer extends | 22 | public final class DefaultPortSerializer extends |
| 20 | Serializer<DefaultPort> { | 23 | Serializer<DefaultPort> { |
| 21 | 24 | ||
| ... | @@ -23,6 +26,9 @@ public final class DefaultPortSerializer extends | ... | @@ -23,6 +26,9 @@ public final class DefaultPortSerializer extends |
| 23 | = new CollectionSerializer(IpPrefix.class, | 26 | = new CollectionSerializer(IpPrefix.class, |
| 24 | new IpPrefixSerializer(), false); | 27 | new IpPrefixSerializer(), false); |
| 25 | 28 | ||
| 29 | + /** | ||
| 30 | + * Default constructor. | ||
| 31 | + */ | ||
| 26 | public DefaultPortSerializer() { | 32 | public DefaultPortSerializer() { |
| 27 | // non-null, immutable | 33 | // non-null, immutable |
| 28 | super(false, true); | 34 | super(false, true); | ... | ... |
| ... | @@ -44,6 +44,10 @@ import org.onlab.onos.store.StoreService; | ... | @@ -44,6 +44,10 @@ import org.onlab.onos.store.StoreService; |
| 44 | import org.onlab.util.KryoPool; | 44 | import org.onlab.util.KryoPool; |
| 45 | import org.slf4j.Logger; | 45 | import org.slf4j.Logger; |
| 46 | 46 | ||
| 47 | +import com.esotericsoftware.kryo.Kryo; | ||
| 48 | +import com.esotericsoftware.kryo.Serializer; | ||
| 49 | +import com.esotericsoftware.kryo.io.Input; | ||
| 50 | +import com.esotericsoftware.kryo.io.Output; | ||
| 47 | import com.google.common.base.Optional; | 51 | import com.google.common.base.Optional; |
| 48 | import com.google.common.cache.CacheBuilder; | 52 | import com.google.common.cache.CacheBuilder; |
| 49 | import com.google.common.cache.CacheLoader; | 53 | import com.google.common.cache.CacheLoader; |
| ... | @@ -68,103 +72,26 @@ import de.javakaffee.kryoserializers.URISerializer; | ... | @@ -68,103 +72,26 @@ import de.javakaffee.kryoserializers.URISerializer; |
| 68 | @Service | 72 | @Service |
| 69 | public class DistributedDeviceStore implements DeviceStore { | 73 | public class DistributedDeviceStore implements DeviceStore { |
| 70 | 74 | ||
| 71 | - /** | ||
| 72 | - * An IMap EntryListener, which reflects each remote event to cache. | ||
| 73 | - * | ||
| 74 | - * @param <K> IMap key type after deserialization | ||
| 75 | - * @param <V> IMap value type after deserialization | ||
| 76 | - */ | ||
| 77 | - public static final class RemoteEventHandler<K, V> extends | ||
| 78 | - EntryAdapter<byte[], byte[]> { | ||
| 79 | - | ||
| 80 | - private LoadingCache<K, Optional<V>> cache; | ||
| 81 | - | ||
| 82 | - /** | ||
| 83 | - * Constructor. | ||
| 84 | - * | ||
| 85 | - * @param cache cache to update | ||
| 86 | - */ | ||
| 87 | - public RemoteEventHandler( | ||
| 88 | - LoadingCache<K, Optional<V>> cache) { | ||
| 89 | - this.cache = checkNotNull(cache); | ||
| 90 | - } | ||
| 91 | - | ||
| 92 | - @Override | ||
| 93 | - public void mapCleared(MapEvent event) { | ||
| 94 | - cache.invalidateAll(); | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - @Override | ||
| 98 | - public void entryUpdated(EntryEvent<byte[], byte[]> event) { | ||
| 99 | - cache.put(POOL.<K>deserialize(event.getKey()), | ||
| 100 | - Optional.of(POOL.<V>deserialize( | ||
| 101 | - event.getValue()))); | ||
| 102 | - } | ||
| 103 | - | ||
| 104 | - @Override | ||
| 105 | - public void entryRemoved(EntryEvent<byte[], byte[]> event) { | ||
| 106 | - cache.invalidate(POOL.<DeviceId>deserialize(event.getKey())); | ||
| 107 | - } | ||
| 108 | - | ||
| 109 | - @Override | ||
| 110 | - public void entryAdded(EntryEvent<byte[], byte[]> event) { | ||
| 111 | - entryUpdated(event); | ||
| 112 | - } | ||
| 113 | - } | ||
| 114 | - | ||
| 115 | - /** | ||
| 116 | - * CacheLoader to wrap Map value with Optional, | ||
| 117 | - * to handle negative hit on underlying IMap. | ||
| 118 | - * | ||
| 119 | - * @param <K> IMap key type after deserialization | ||
| 120 | - * @param <V> IMap value type after deserialization | ||
| 121 | - */ | ||
| 122 | - public static final class OptionalCacheLoader<K, V> extends | ||
| 123 | - CacheLoader<K, Optional<V>> { | ||
| 124 | - | ||
| 125 | - private IMap<byte[], byte[]> rawMap; | ||
| 126 | - | ||
| 127 | - /** | ||
| 128 | - * Constructor. | ||
| 129 | - * | ||
| 130 | - * @param rawMap underlying IMap | ||
| 131 | - */ | ||
| 132 | - public OptionalCacheLoader(IMap<byte[], byte[]> rawMap) { | ||
| 133 | - this.rawMap = checkNotNull(rawMap); | ||
| 134 | - } | ||
| 135 | - | ||
| 136 | - @Override | ||
| 137 | - public Optional<V> load(K key) throws Exception { | ||
| 138 | - byte[] keyBytes = serialize(key); | ||
| 139 | - byte[] valBytes = rawMap.get(keyBytes); | ||
| 140 | - if (valBytes == null) { | ||
| 141 | - return Optional.absent(); | ||
| 142 | - } | ||
| 143 | - V dev = deserialize(valBytes); | ||
| 144 | - return Optional.of(dev); | ||
| 145 | - } | ||
| 146 | - } | ||
| 147 | - | ||
| 148 | private final Logger log = getLogger(getClass()); | 75 | private final Logger log = getLogger(getClass()); |
| 149 | 76 | ||
| 150 | public static final String DEVICE_NOT_FOUND = "Device with ID %s not found"; | 77 | public static final String DEVICE_NOT_FOUND = "Device with ID %s not found"; |
| 151 | 78 | ||
| 152 | // FIXME Slice out types used in common to separate pool/namespace. | 79 | // FIXME Slice out types used in common to separate pool/namespace. |
| 153 | private static final KryoPool POOL = KryoPool.newBuilder() | 80 | private static final KryoPool POOL = KryoPool.newBuilder() |
| 154 | - .register(URI.class, new URISerializer()) | ||
| 155 | .register( | 81 | .register( |
| 156 | ArrayList.class, | 82 | ArrayList.class, |
| 83 | + HashMap.class, | ||
| 157 | 84 | ||
| 158 | - ProviderId.class, | ||
| 159 | Device.Type.class, | 85 | Device.Type.class, |
| 160 | 86 | ||
| 161 | - DeviceId.class, | ||
| 162 | DefaultDevice.class, | 87 | DefaultDevice.class, |
| 163 | MastershipRole.class, | 88 | MastershipRole.class, |
| 164 | - HashMap.class, | ||
| 165 | Port.class, | 89 | Port.class, |
| 166 | Element.class | 90 | Element.class |
| 167 | ) | 91 | ) |
| 92 | + .register(URI.class, new URISerializer()) | ||
| 93 | + .register(ProviderId.class, new ProviderIdSerializer()) | ||
| 94 | + .register(DeviceId.class, new DeviceIdSerializer()) | ||
| 168 | .register(PortNumber.class, new PortNumberSerializer()) | 95 | .register(PortNumber.class, new PortNumberSerializer()) |
| 169 | .register(DefaultPort.class, new DefaultPortSerializer()) | 96 | .register(DefaultPort.class, new DefaultPortSerializer()) |
| 170 | .build() | 97 | .build() |
| ... | @@ -190,7 +117,7 @@ public class DistributedDeviceStore implements DeviceStore { | ... | @@ -190,7 +117,7 @@ public class DistributedDeviceStore implements DeviceStore { |
| 190 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 117 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 191 | protected StoreService storeService; | 118 | protected StoreService storeService; |
| 192 | 119 | ||
| 193 | - /*protected*/public HazelcastInstance theInstance; | 120 | + protected HazelcastInstance theInstance; |
| 194 | 121 | ||
| 195 | 122 | ||
| 196 | @Activate | 123 | @Activate |
| ... | @@ -517,4 +444,94 @@ public class DistributedDeviceStore implements DeviceStore { | ... | @@ -517,4 +444,94 @@ public class DistributedDeviceStore implements DeviceStore { |
| 517 | return POOL.deserialize(bytes); | 444 | return POOL.deserialize(bytes); |
| 518 | } | 445 | } |
| 519 | 446 | ||
| 447 | + public static final class DeviceIdSerializer extends Serializer<DeviceId> { | ||
| 448 | + | ||
| 449 | + @Override | ||
| 450 | + public void write(Kryo kryo, Output output, DeviceId object) { | ||
| 451 | + kryo.writeObject(output, object.uri()); | ||
| 452 | + } | ||
| 453 | + | ||
| 454 | + @Override | ||
| 455 | + public DeviceId read(Kryo kryo, Input input, Class<DeviceId> type) { | ||
| 456 | + final URI uri = kryo.readObject(input, URI.class); | ||
| 457 | + return DeviceId.deviceId(uri); | ||
| 458 | + } | ||
| 459 | + } | ||
| 460 | + | ||
| 461 | + /** | ||
| 462 | + * An IMap EntryListener, which reflects each remote event to cache. | ||
| 463 | + * | ||
| 464 | + * @param <K> IMap key type after deserialization | ||
| 465 | + * @param <V> IMap value type after deserialization | ||
| 466 | + */ | ||
| 467 | + public static final class RemoteEventHandler<K, V> extends | ||
| 468 | + EntryAdapter<byte[], byte[]> { | ||
| 469 | + | ||
| 470 | + private LoadingCache<K, Optional<V>> cache; | ||
| 471 | + | ||
| 472 | + /** | ||
| 473 | + * Constructor. | ||
| 474 | + * | ||
| 475 | + * @param cache cache to update | ||
| 476 | + */ | ||
| 477 | + public RemoteEventHandler( | ||
| 478 | + LoadingCache<K, Optional<V>> cache) { | ||
| 479 | + this.cache = checkNotNull(cache); | ||
| 480 | + } | ||
| 481 | + | ||
| 482 | + @Override | ||
| 483 | + public void mapCleared(MapEvent event) { | ||
| 484 | + cache.invalidateAll(); | ||
| 485 | + } | ||
| 486 | + | ||
| 487 | + @Override | ||
| 488 | + public void entryUpdated(EntryEvent<byte[], byte[]> event) { | ||
| 489 | + cache.put(POOL.<K>deserialize(event.getKey()), | ||
| 490 | + Optional.of(POOL.<V>deserialize( | ||
| 491 | + event.getValue()))); | ||
| 492 | + } | ||
| 493 | + | ||
| 494 | + @Override | ||
| 495 | + public void entryRemoved(EntryEvent<byte[], byte[]> event) { | ||
| 496 | + cache.invalidate(POOL.<DeviceId>deserialize(event.getKey())); | ||
| 497 | + } | ||
| 498 | + | ||
| 499 | + @Override | ||
| 500 | + public void entryAdded(EntryEvent<byte[], byte[]> event) { | ||
| 501 | + entryUpdated(event); | ||
| 502 | + } | ||
| 503 | + } | ||
| 504 | + | ||
| 505 | + /** | ||
| 506 | + * CacheLoader to wrap Map value with Optional, | ||
| 507 | + * to handle negative hit on underlying IMap. | ||
| 508 | + * | ||
| 509 | + * @param <K> IMap key type after deserialization | ||
| 510 | + * @param <V> IMap value type after deserialization | ||
| 511 | + */ | ||
| 512 | + public static final class OptionalCacheLoader<K, V> extends | ||
| 513 | + CacheLoader<K, Optional<V>> { | ||
| 514 | + | ||
| 515 | + private IMap<byte[], byte[]> rawMap; | ||
| 516 | + | ||
| 517 | + /** | ||
| 518 | + * Constructor. | ||
| 519 | + * | ||
| 520 | + * @param rawMap underlying IMap | ||
| 521 | + */ | ||
| 522 | + public OptionalCacheLoader(IMap<byte[], byte[]> rawMap) { | ||
| 523 | + this.rawMap = checkNotNull(rawMap); | ||
| 524 | + } | ||
| 525 | + | ||
| 526 | + @Override | ||
| 527 | + public Optional<V> load(K key) throws Exception { | ||
| 528 | + byte[] keyBytes = serialize(key); | ||
| 529 | + byte[] valBytes = rawMap.get(keyBytes); | ||
| 530 | + if (valBytes == null) { | ||
| 531 | + return Optional.absent(); | ||
| 532 | + } | ||
| 533 | + V dev = deserialize(valBytes); | ||
| 534 | + return Optional.of(dev); | ||
| 535 | + } | ||
| 536 | + } | ||
| 520 | } | 537 | } | ... | ... |
| ... | @@ -8,8 +8,14 @@ import com.esotericsoftware.kryo.io.Input; | ... | @@ -8,8 +8,14 @@ import com.esotericsoftware.kryo.io.Input; |
| 8 | import com.esotericsoftware.kryo.io.Output; | 8 | import com.esotericsoftware.kryo.io.Output; |
| 9 | 9 | ||
| 10 | // TODO move to util, etc. | 10 | // TODO move to util, etc. |
| 11 | +/** | ||
| 12 | + * Kryo Serializer for {@link IpPrefix}. | ||
| 13 | + */ | ||
| 11 | public final class IpPrefixSerializer extends Serializer<IpPrefix> { | 14 | public final class IpPrefixSerializer extends Serializer<IpPrefix> { |
| 12 | 15 | ||
| 16 | + /** | ||
| 17 | + * Default constructor. | ||
| 18 | + */ | ||
| 13 | public IpPrefixSerializer() { | 19 | public IpPrefixSerializer() { |
| 14 | // non-null, immutable | 20 | // non-null, immutable |
| 15 | super(false, true); | 21 | super(false, true); | ... | ... |
| ... | @@ -8,9 +8,15 @@ import com.esotericsoftware.kryo.io.Input; | ... | @@ -8,9 +8,15 @@ import com.esotericsoftware.kryo.io.Input; |
| 8 | import com.esotericsoftware.kryo.io.Output; | 8 | import com.esotericsoftware.kryo.io.Output; |
| 9 | 9 | ||
| 10 | // TODO move to util, etc. | 10 | // TODO move to util, etc. |
| 11 | +/** | ||
| 12 | + * Serializer for {@link PortNumber}. | ||
| 13 | + */ | ||
| 11 | public final class PortNumberSerializer extends | 14 | public final class PortNumberSerializer extends |
| 12 | Serializer<PortNumber> { | 15 | Serializer<PortNumber> { |
| 13 | 16 | ||
| 17 | + /** | ||
| 18 | + * Default constructor. | ||
| 19 | + */ | ||
| 14 | public PortNumberSerializer() { | 20 | public PortNumberSerializer() { |
| 15 | // non-null, immutable | 21 | // non-null, immutable |
| 16 | super(false, true); | 22 | super(false, true); | ... | ... |
| 1 | +package org.onlab.onos.store.device.impl; | ||
| 2 | + | ||
| 3 | +import org.onlab.onos.net.provider.ProviderId; | ||
| 4 | + | ||
| 5 | +import com.esotericsoftware.kryo.Kryo; | ||
| 6 | +import com.esotericsoftware.kryo.Serializer; | ||
| 7 | +import com.esotericsoftware.kryo.io.Input; | ||
| 8 | +import com.esotericsoftware.kryo.io.Output; | ||
| 9 | + | ||
| 10 | +//TODO move to util, etc. | ||
| 11 | +/** | ||
| 12 | + * Serializer for {@link ProviderId}. | ||
| 13 | + */ | ||
| 14 | +public class ProviderIdSerializer extends Serializer<ProviderId> { | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * Default constructor. | ||
| 18 | + */ | ||
| 19 | + public ProviderIdSerializer() { | ||
| 20 | + // non-null, immutable | ||
| 21 | + super(false, true); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public void write(Kryo kryo, Output output, ProviderId object) { | ||
| 26 | + output.writeString(object.scheme()); | ||
| 27 | + output.writeString(object.id()); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + @Override | ||
| 31 | + public ProviderId read(Kryo kryo, Input input, Class<ProviderId> type) { | ||
| 32 | + String scheme = input.readString(); | ||
| 33 | + String id = input.readString(); | ||
| 34 | + return new ProviderId(scheme, id); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | +} |
| ... | @@ -28,6 +28,9 @@ class PathKey { | ... | @@ -28,6 +28,9 @@ class PathKey { |
| 28 | 28 | ||
| 29 | @Override | 29 | @Override |
| 30 | public boolean equals(Object obj) { | 30 | public boolean equals(Object obj) { |
| 31 | + if (this == obj) { | ||
| 32 | + return true; | ||
| 33 | + } | ||
| 31 | if (obj instanceof PathKey) { | 34 | if (obj instanceof PathKey) { |
| 32 | final PathKey other = (PathKey) obj; | 35 | final PathKey other = (PathKey) obj; |
| 33 | return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst); | 36 | return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst); | ... | ... |
| 1 | +package org.onlab.onos.net.trivial.impl; | ||
| 2 | + | ||
| 3 | +import com.google.common.collect.ImmutableSet; | ||
| 4 | +import org.apache.felix.scr.annotations.Activate; | ||
| 5 | +import org.apache.felix.scr.annotations.Component; | ||
| 6 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 7 | +import org.apache.felix.scr.annotations.Service; | ||
| 8 | +import org.onlab.onos.cluster.ClusterStore; | ||
| 9 | +import org.onlab.onos.cluster.ControllerNode; | ||
| 10 | +import org.onlab.onos.cluster.DefaultControllerNode; | ||
| 11 | +import org.onlab.onos.cluster.NodeId; | ||
| 12 | +import org.onlab.packet.IpPrefix; | ||
| 13 | +import org.slf4j.Logger; | ||
| 14 | + | ||
| 15 | +import java.util.Set; | ||
| 16 | + | ||
| 17 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * Manages inventory of infrastructure DEVICES using trivial in-memory | ||
| 21 | + * structures implementation. | ||
| 22 | + */ | ||
| 23 | +@Component(immediate = true) | ||
| 24 | +@Service | ||
| 25 | +public class SimpleClusterStore implements ClusterStore { | ||
| 26 | + | ||
| 27 | + public static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1"); | ||
| 28 | + | ||
| 29 | + private final Logger log = getLogger(getClass()); | ||
| 30 | + | ||
| 31 | + private ControllerNode instance; | ||
| 32 | + | ||
| 33 | + @Activate | ||
| 34 | + public void activate() { | ||
| 35 | + instance = new DefaultControllerNode(new NodeId("local"), LOCALHOST); | ||
| 36 | + log.info("Started"); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + @Deactivate | ||
| 40 | + public void deactivate() { | ||
| 41 | + log.info("Stopped"); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + @Override | ||
| 46 | + public ControllerNode getLocalNode() { | ||
| 47 | + return instance; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + @Override | ||
| 51 | + public Set<ControllerNode> getNodes() { | ||
| 52 | + return ImmutableSet.of(instance); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + public ControllerNode getNode(NodeId nodeId) { | ||
| 57 | + return instance.id().equals(nodeId) ? instance : null; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public ControllerNode.State getState(NodeId nodeId) { | ||
| 62 | + return ControllerNode.State.ACTIVE; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | +} |
| ... | @@ -35,7 +35,7 @@ import static org.onlab.onos.net.device.DeviceEvent.Type.*; | ... | @@ -35,7 +35,7 @@ import static org.onlab.onos.net.device.DeviceEvent.Type.*; |
| 35 | import static org.slf4j.LoggerFactory.getLogger; | 35 | import static org.slf4j.LoggerFactory.getLogger; |
| 36 | 36 | ||
| 37 | /** | 37 | /** |
| 38 | - * Manages inventory of infrastructure DEVICES using trivial in-memory | 38 | + * Manages inventory of infrastructure devices using trivial in-memory |
| 39 | * structures implementation. | 39 | * structures implementation. |
| 40 | */ | 40 | */ |
| 41 | @Component(immediate = true) | 41 | @Component(immediate = true) | ... | ... |
| ... | @@ -179,6 +179,9 @@ public class SimpleLinkStore implements LinkStore { | ... | @@ -179,6 +179,9 @@ public class SimpleLinkStore implements LinkStore { |
| 179 | 179 | ||
| 180 | @Override | 180 | @Override |
| 181 | public boolean equals(Object obj) { | 181 | public boolean equals(Object obj) { |
| 182 | + if (this == obj) { | ||
| 183 | + return true; | ||
| 184 | + } | ||
| 182 | if (obj instanceof LinkKey) { | 185 | if (obj instanceof LinkKey) { |
| 183 | final LinkKey other = (LinkKey) obj; | 186 | final LinkKey other = (LinkKey) obj; |
| 184 | return Objects.equals(this.src, other.src) && | 187 | return Objects.equals(this.src, other.src) && | ... | ... |
| ... | @@ -392,7 +392,7 @@ | ... | @@ -392,7 +392,7 @@ |
| 392 | <group> | 392 | <group> |
| 393 | <title>Core Subsystems</title> | 393 | <title>Core Subsystems</title> |
| 394 | <packages> | 394 | <packages> |
| 395 | - org.onlab.onos.net.device.impl:org.onlab.onos.net.link.impl:org.onlab.onos.net.host.impl:org.onlab.onos.net.topology.impl:org.onlab.onos.net.packet.impl:org.onlab.onos.net.flow.impl:org.onlab.onos.net.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.impl:org.onlab.onos.event.impl:org.onlab.onos.store.* | 395 | + org.onlab.onos.cluster.impl:org.onlab.onos.store:org.onlab.onos.net.device.impl:org.onlab.onos.net.link.impl:org.onlab.onos.net.host.impl:org.onlab.onos.net.topology.impl:org.onlab.onos.net.packet.impl:org.onlab.onos.net.flow.impl:org.onlab.onos.net.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.cluster:org.onlab.onos.event.impl:org.onlab.onos.store.* |
| 396 | </packages> | 396 | </packages> |
| 397 | </group> | 397 | </group> |
| 398 | <group> | 398 | <group> | ... | ... |
| ... | @@ -6,6 +6,7 @@ export ONOS_ROOT=${ONOS_ROOT:-~/onos-next} | ... | @@ -6,6 +6,7 @@ export ONOS_ROOT=${ONOS_ROOT:-~/onos-next} |
| 6 | # M2 repository and Karaf gold bits | 6 | # M2 repository and Karaf gold bits |
| 7 | export M2_REPO=${M2_REPO:-~/.m2/repository} | 7 | export M2_REPO=${M2_REPO:-~/.m2/repository} |
| 8 | export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-3.0.1.zip} | 8 | export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-3.0.1.zip} |
| 9 | +export KARAF_TAR=${KARAF_TAR:-~/Downloads/apache-karaf-3.0.1.tar.gz} | ||
| 9 | export KARAF_DIST=$(basename $KARAF_ZIP .zip) | 10 | export KARAF_DIST=$(basename $KARAF_ZIP .zip) |
| 10 | 11 | ||
| 11 | # ONOS Version and onos.tar.gz staging environment | 12 | # ONOS Version and onos.tar.gz staging environment | ... | ... |
| ... | @@ -13,7 +13,7 @@ rm -fr $ONOS_STAGE # Remove this when package script is completed | ... | @@ -13,7 +13,7 @@ rm -fr $ONOS_STAGE # Remove this when package script is completed |
| 13 | 13 | ||
| 14 | # Make sure we have the original apache karaf bits first | 14 | # Make sure we have the original apache karaf bits first |
| 15 | [ ! -d $M2_REPO ] && echo "M2 repository $M2_REPO not found" && exit 1 | 15 | [ ! -d $M2_REPO ] && echo "M2 repository $M2_REPO not found" && exit 1 |
| 16 | -[ ! -f $KARAF_ZIP ] && echo "Apache Karaf bits $KARAF_ZIP not found" && exit 1 | 16 | +[ ! -f $KARAF_ZIP -a ! -f $KARAF_TAR ] && echo "Apache Karaf bits $KARAF_ZIP or $KARAF_TAR not found" && exit 1 |
| 17 | [ -d $ONOS_STAGE ] && echo "ONOS stage $ONOS_STAGE already exists" && exit 1 | 17 | [ -d $ONOS_STAGE ] && echo "ONOS stage $ONOS_STAGE already exists" && exit 1 |
| 18 | 18 | ||
| 19 | # Create the stage directory and warp into it | 19 | # Create the stage directory and warp into it |
| ... | @@ -21,7 +21,8 @@ mkdir -p $ONOS_STAGE | ... | @@ -21,7 +21,8 @@ mkdir -p $ONOS_STAGE |
| 21 | cd $ONOS_STAGE | 21 | cd $ONOS_STAGE |
| 22 | 22 | ||
| 23 | # Unroll the Apache Karaf bits, prune them and make ONOS top-level directories. | 23 | # Unroll the Apache Karaf bits, prune them and make ONOS top-level directories. |
| 24 | -unzip -q $KARAF_ZIP && rm -rf $KARAF_DIST/demos | 24 | +[ -f $KARAF_ZIP ] && unzip -q $KARAF_ZIP && rm -rf $KARAF_DIST/demos |
| 25 | +[ -f $KARAF_TAR ] && tar zxf $KARAF_TAR && rm -rf $KARAF_DIST/demos | ||
| 25 | mkdir bin | 26 | mkdir bin |
| 26 | 27 | ||
| 27 | # Stage the ONOS admin scripts and patch in Karaf service wrapper extras | 28 | # Stage the ONOS admin scripts and patch in Karaf service wrapper extras |
| ... | @@ -33,15 +34,15 @@ cp -r $ONOS_ROOT/tools/package/etc/* $KARAF_DIST/etc | ... | @@ -33,15 +34,15 @@ cp -r $ONOS_ROOT/tools/package/etc/* $KARAF_DIST/etc |
| 33 | mkdir -p $KARAF_DIST/system/org/onlab | 34 | mkdir -p $KARAF_DIST/system/org/onlab |
| 34 | cp -r $M2_REPO/org/onlab $KARAF_DIST/system/org/ | 35 | cp -r $M2_REPO/org/onlab $KARAF_DIST/system/org/ |
| 35 | 36 | ||
| 36 | -# Wrapper & Cellar Patching ---------------------------------------------------- | 37 | +# Cellar Patching -------------------------------------------------------------- |
| 37 | 38 | ||
| 38 | # Patch the Apache Karaf distribution file to add Cellar features repository | 39 | # Patch the Apache Karaf distribution file to add Cellar features repository |
| 39 | -perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.apache.karaf.cellar/apache-karaf-cellar/3.0.0/xml/features|" \ | 40 | +#perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.apache.karaf.cellar/apache-karaf-cellar/3.0.0/xml/features|" \ |
| 40 | - $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg | 41 | +# $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg |
| 41 | 42 | ||
| 42 | # Patch the Apache Karaf distribution file to load ONOS features | 43 | # Patch the Apache Karaf distribution file to load ONOS features |
| 43 | -perl -pi.old -e 's|^(featuresBoot=.*)|\1,cellar|' \ | 44 | +#perl -pi.old -e 's|^(featuresBoot=.*)|\1,cellar|' \ |
| 44 | - $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg | 45 | +# $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg |
| 45 | 46 | ||
| 46 | # ONOS Patching ---------------------------------------------------------------- | 47 | # ONOS Patching ---------------------------------------------------------------- |
| 47 | 48 | ||
| ... | @@ -49,6 +50,10 @@ perl -pi.old -e 's|^(featuresBoot=.*)|\1,cellar|' \ | ... | @@ -49,6 +50,10 @@ perl -pi.old -e 's|^(featuresBoot=.*)|\1,cellar|' \ |
| 49 | perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_VERSION/xml/features|" \ | 50 | perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_VERSION/xml/features|" \ |
| 50 | $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg | 51 | $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg |
| 51 | 52 | ||
| 53 | +# Patch the Apache Karaf distribution file to load ONOS features | ||
| 54 | +perl -pi.old -e 's|^(featuresBoot=.*)|\1,onos-api,onos-core,onos-cli,onos-rest,onos-gui,onos-openflow,onos-app-tvue,onos-app-fwd|' \ | ||
| 55 | + $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg | ||
| 56 | + | ||
| 52 | # Patch the Apache Karaf distribution with ONOS branding bundle | 57 | # Patch the Apache Karaf distribution with ONOS branding bundle |
| 53 | cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_VERSION/onos-branding-*.jar \ | 58 | cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_VERSION/onos-branding-*.jar \ |
| 54 | $ONOS_STAGE/$KARAF_DIST/lib | 59 | $ONOS_STAGE/$KARAF_DIST/lib | ... | ... |
| ... | @@ -46,10 +46,7 @@ alias gui='open http://localhost:8181/onos/tvue' | ... | @@ -46,10 +46,7 @@ alias gui='open http://localhost:8181/onos/tvue' |
| 46 | # Test related conveniences | 46 | # Test related conveniences |
| 47 | 47 | ||
| 48 | # SSH to a specified ONOS instance | 48 | # SSH to a specified ONOS instance |
| 49 | -function sshctl { | 49 | +alias sshctl=onos-ssh |
| 50 | - [ -n "$1" ] && OCI=$1 && shift | ||
| 51 | - ssh -Y sdn@$OCI "$@" | ||
| 52 | -} | ||
| 53 | 50 | ||
| 54 | # Applies the settings in the specified cell file or lists current cell definition | 51 | # Applies the settings in the specified cell file or lists current cell definition |
| 55 | # if no cell file is given. | 52 | # if no cell file is given. | ... | ... |
| ... | @@ -21,7 +21,8 @@ ssh $remote " | ... | @@ -21,7 +21,8 @@ ssh $remote " |
| 21 | 21 | ||
| 22 | echo 'Installing ONOS bundles...' | 22 | echo 'Installing ONOS bundles...' |
| 23 | $onos cluster:feature-install default onos-api 1>>$LOG 2>&1 | 23 | $onos cluster:feature-install default onos-api 1>>$LOG 2>&1 |
| 24 | - $onos cluster:feature-install default onos-core 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 | ||
| 25 | $onos cluster:feature-install default onos-openflow 1>>$LOG 2>&1 | 26 | $onos cluster:feature-install default onos-openflow 1>>$LOG 2>&1 |
| 26 | $onos cluster:feature-install default onos-cli 1>>$LOG 2>&1 | 27 | $onos cluster:feature-install default onos-cli 1>>$LOG 2>&1 |
| 27 | # $onos cluster:feature-install default onos-gui 1>>$LOG 2>&1 | 28 | # $onos cluster:feature-install default onos-gui 1>>$LOG 2>&1 | ... | ... |
| ... | @@ -27,6 +27,9 @@ ssh $remote " | ... | @@ -27,6 +27,9 @@ ssh $remote " |
| 27 | # Install the upstart configuration file. | 27 | # Install the upstart configuration file. |
| 28 | sudo cp $ONOS_INSTALL_DIR/debian/onos.conf /etc/init/onos.conf | 28 | sudo cp $ONOS_INSTALL_DIR/debian/onos.conf /etc/init/onos.conf |
| 29 | 29 | ||
| 30 | + # Remove any previous ON.Lab bits from ~/.m2 repo | ||
| 31 | + rm -fr ~/.m2/repository/org/onlab | ||
| 32 | + | ||
| 30 | # Ignite the ONOS service. | 33 | # Ignite the ONOS service. |
| 31 | sudo service onos start | 34 | sudo service onos start |
| 32 | " | 35 | " | ... | ... |
tools/test/bin/onos-patch-vm
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +#------------------------------------------------------------------------------- | ||
| 3 | +# Remotely patches the ONOS VM to tailor its hostname. | ||
| 4 | +#------------------------------------------------------------------------------- | ||
| 5 | + | ||
| 6 | +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | ||
| 7 | +. $ONOS_ROOT/tools/build/envDefaults | ||
| 8 | + | ||
| 9 | +address=${1:-$OCI} | ||
| 10 | +remote=$ONOS_USER@$address | ||
| 11 | +name=${2:-onos-1} | ||
| 12 | + | ||
| 13 | +[ -z "$address" ] && echo "Null address not allowed" >&2 && exit 1 | ||
| 14 | +[ -z "$name" ] && echo "Null name not allowed" >&2 && exit 1 | ||
| 15 | + | ||
| 16 | +ssh $remote " | ||
| 17 | + sudo perl -pi.bak -e \"s/127.0.1.1.*/127.0.1.1 $name/g\" /etc/hosts | ||
| 18 | + sudo echo $name /etc/hostname | ||
| 19 | + sudo hostname $name | ||
| 20 | +" | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
tools/test/bin/onos-push-keys
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +#------------------------------------------------------------------------------- | ||
| 3 | +# Pushes the local id_rsa.pub to the remote ONOS host authorized_keys. | ||
| 4 | +#------------------------------------------------------------------------------- | ||
| 5 | + | ||
| 6 | +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | ||
| 7 | +. $ONOS_ROOT/tools/build/envDefaults | ||
| 8 | + | ||
| 9 | +remote=$ONOS_USER@${1:-$OCI} | ||
| 10 | + | ||
| 11 | +scp -q ~/.ssh/id_rsa.pub $remote:/tmp | ||
| 12 | +ssh $remote "cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys" | ||
| 13 | +ssh -n -o PasswordAuthentication=no $remote true |
tools/test/bin/onos-ssh
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +#------------------------------------------------------------------------------- | ||
| 3 | +# Logs in to the remote ONOS instance. | ||
| 4 | +#------------------------------------------------------------------------------- | ||
| 5 | + | ||
| 6 | +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | ||
| 7 | +. $ONOS_ROOT/tools/build/envDefaults | ||
| 8 | + | ||
| 9 | +[ -n "$1" ] && OCI=$1 && shift | ||
| 10 | +ssh -Y $ONOS_USER@$OCI "$@" |
tools/test/bin/onos-verify-cell
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +#------------------------------------------------------------------------------- | ||
| 3 | +# Verifies connectivity to each node in ONOS cell. | ||
| 4 | +#------------------------------------------------------------------------------- | ||
| 5 | + | ||
| 6 | +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | ||
| 7 | +. $ONOS_ROOT/tools/build/envDefaults | ||
| 8 | + | ||
| 9 | +for node in $(env | sort | egrep "OC[0-9]+" | cut -d= -f2); do | ||
| 10 | + printf "%s: " $node; ssh -n -o PasswordAuthentication=no $ONOS_USER@$node date | ||
| 11 | +done | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
tools/test/bin/onos-wait-for-start
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +#------------------------------------------------------------------------------- | ||
| 3 | +# Waits for ONOS to reach run-level 100. | ||
| 4 | +#------------------------------------------------------------------------------- | ||
| 5 | + | ||
| 6 | +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | ||
| 7 | +. $ONOS_ROOT/tools/build/envDefaults | ||
| 8 | + | ||
| 9 | +remote=$ONOS_USER@${1:-$OCI} | ||
| 10 | + | ||
| 11 | +ssh $remote " | ||
| 12 | + # Wait until we reach the run-level 100 | ||
| 13 | + running="" | ||
| 14 | + while [ -z \$running ]; do | ||
| 15 | + $ONOS_INSTALL_DIR/bin/onos bundle:list 2>/dev/null | \ | ||
| 16 | + grep -q 'START LEVEL 100' && running=1 || sleep 2 | ||
| 17 | + done | ||
| 18 | + | ||
| 19 | +" |
| ... | @@ -41,6 +41,9 @@ public abstract class AbstractEdge<V extends Vertex> implements Edge<V> { | ... | @@ -41,6 +41,9 @@ public abstract class AbstractEdge<V extends Vertex> implements Edge<V> { |
| 41 | 41 | ||
| 42 | @Override | 42 | @Override |
| 43 | public boolean equals(Object obj) { | 43 | public boolean equals(Object obj) { |
| 44 | + if (this == obj) { | ||
| 45 | + return true; | ||
| 46 | + } | ||
| 44 | if (obj instanceof AbstractEdge) { | 47 | if (obj instanceof AbstractEdge) { |
| 45 | final AbstractEdge other = (AbstractEdge) obj; | 48 | final AbstractEdge other = (AbstractEdge) obj; |
| 46 | return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst); | 49 | return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst); | ... | ... |
| ... | @@ -80,6 +80,9 @@ public class AdjacencyListsGraph<V extends Vertex, E extends Edge<V>> | ... | @@ -80,6 +80,9 @@ public class AdjacencyListsGraph<V extends Vertex, E extends Edge<V>> |
| 80 | 80 | ||
| 81 | @Override | 81 | @Override |
| 82 | public boolean equals(Object obj) { | 82 | public boolean equals(Object obj) { |
| 83 | + if (this == obj) { | ||
| 84 | + return true; | ||
| 85 | + } | ||
| 83 | if (obj instanceof AdjacencyListsGraph) { | 86 | if (obj instanceof AdjacencyListsGraph) { |
| 84 | AdjacencyListsGraph that = (AdjacencyListsGraph) obj; | 87 | AdjacencyListsGraph that = (AdjacencyListsGraph) obj; |
| 85 | return this.getClass() == that.getClass() && | 88 | return this.getClass() == that.getClass() && | ... | ... |
| ... | @@ -107,6 +107,9 @@ public class DefaultMutablePath<V extends Vertex, E extends Edge<V>> implements | ... | @@ -107,6 +107,9 @@ public class DefaultMutablePath<V extends Vertex, E extends Edge<V>> implements |
| 107 | 107 | ||
| 108 | @Override | 108 | @Override |
| 109 | public boolean equals(Object obj) { | 109 | public boolean equals(Object obj) { |
| 110 | + if (this == obj) { | ||
| 111 | + return true; | ||
| 112 | + } | ||
| 110 | if (obj instanceof DefaultMutablePath) { | 113 | if (obj instanceof DefaultMutablePath) { |
| 111 | final DefaultMutablePath other = (DefaultMutablePath) obj; | 114 | final DefaultMutablePath other = (DefaultMutablePath) obj; |
| 112 | return Objects.equals(this.cost, other.cost) && | 115 | return Objects.equals(this.cost, other.cost) && | ... | ... |
| ... | @@ -72,6 +72,9 @@ public class DefaultPath<V extends Vertex, E extends Edge<V>> implements Path<V, | ... | @@ -72,6 +72,9 @@ public class DefaultPath<V extends Vertex, E extends Edge<V>> implements Path<V, |
| 72 | 72 | ||
| 73 | @Override | 73 | @Override |
| 74 | public boolean equals(Object obj) { | 74 | public boolean equals(Object obj) { |
| 75 | + if (this == obj) { | ||
| 76 | + return true; | ||
| 77 | + } | ||
| 75 | if (obj instanceof DefaultPath) { | 78 | if (obj instanceof DefaultPath) { |
| 76 | final DefaultPath other = (DefaultPath) obj; | 79 | final DefaultPath other = (DefaultPath) obj; |
| 77 | return Objects.equals(this.src, other.src) && | 80 | return Objects.equals(this.src, other.src) && | ... | ... |
| ... | @@ -166,6 +166,9 @@ public class Heap<T> { | ... | @@ -166,6 +166,9 @@ public class Heap<T> { |
| 166 | 166 | ||
| 167 | @Override | 167 | @Override |
| 168 | public boolean equals(Object obj) { | 168 | public boolean equals(Object obj) { |
| 169 | + if (this == obj) { | ||
| 170 | + return true; | ||
| 171 | + } | ||
| 169 | if (obj instanceof Heap) { | 172 | if (obj instanceof Heap) { |
| 170 | Heap that = (Heap) obj; | 173 | Heap that = (Heap) obj; |
| 171 | return this.getClass() == that.getClass() && | 174 | return this.getClass() == that.getClass() && | ... | ... |
| ... | @@ -39,6 +39,9 @@ public class TestEdge extends AbstractEdge<TestVertex> { | ... | @@ -39,6 +39,9 @@ public class TestEdge extends AbstractEdge<TestVertex> { |
| 39 | 39 | ||
| 40 | @Override | 40 | @Override |
| 41 | public boolean equals(Object obj) { | 41 | public boolean equals(Object obj) { |
| 42 | + if (this == obj) { | ||
| 43 | + return true; | ||
| 44 | + } | ||
| 42 | if (obj instanceof TestEdge) { | 45 | if (obj instanceof TestEdge) { |
| 43 | final TestEdge other = (TestEdge) obj; | 46 | final TestEdge other = (TestEdge) obj; |
| 44 | return super.equals(obj) && Objects.equals(this.weight, other.weight); | 47 | return super.equals(obj) && Objects.equals(this.weight, other.weight); | ... | ... |
| ... | @@ -20,6 +20,9 @@ public class TestVertex implements Vertex { | ... | @@ -20,6 +20,9 @@ public class TestVertex implements Vertex { |
| 20 | 20 | ||
| 21 | @Override | 21 | @Override |
| 22 | public boolean equals(Object obj) { | 22 | public boolean equals(Object obj) { |
| 23 | + if (this == obj) { | ||
| 24 | + return true; | ||
| 25 | + } | ||
| 23 | if (obj instanceof TestVertex) { | 26 | if (obj instanceof TestVertex) { |
| 24 | final TestVertex other = (TestVertex) obj; | 27 | final TestVertex other = (TestVertex) obj; |
| 25 | return Objects.equals(this.name, other.name); | 28 | return Objects.equals(this.name, other.name); | ... | ... |
-
Please register or login to post a comment