Madan Jampani
Committed by Gerrit Code Review

Replaced GossipHostStore with a implementation built on top of EventuallyConsistentMap

Change-Id: I6b580727e5f4bb03e606c87a6748e6fbb90223e7
1 -/*
2 - * Copyright 2014 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.net.host;
17 -
18 -import org.onosproject.net.HostId;
19 -import org.onosproject.store.Timestamp;
20 -
21 -/**
22 - * Interface for a logical clock service that issues per host timestamps.
23 - */
24 -public interface HostClockService {
25 -
26 - /**
27 - * Returns a new timestamp for the specified host.
28 - * @param hostId identifier for the host.
29 - * @return timestamp.
30 - */
31 - Timestamp getTimestamp(HostId hostId);
32 -}
...@@ -27,7 +27,6 @@ import org.onosproject.net.flowobjective.FlowObjectiveService; ...@@ -27,7 +27,6 @@ import org.onosproject.net.flowobjective.FlowObjectiveService;
27 import org.onosproject.net.group.GroupService; 27 import org.onosproject.net.group.GroupService;
28 import org.onosproject.net.host.HostAdminService; 28 import org.onosproject.net.host.HostAdminService;
29 import org.onosproject.net.host.HostService; 29 import org.onosproject.net.host.HostService;
30 -import org.onosproject.net.host.HostClockService;
31 import org.onosproject.net.intent.IntentService; 30 import org.onosproject.net.intent.IntentService;
32 import org.onosproject.net.intent.IntentExtensionService; 31 import org.onosproject.net.intent.IntentExtensionService;
33 import org.onosproject.net.intent.IntentClockService; 32 import org.onosproject.net.intent.IntentClockService;
...@@ -136,8 +135,6 @@ public final class PolicyBuilder { ...@@ -136,8 +135,6 @@ public final class PolicyBuilder {
136 new PermissionInfo(ServicePermission.class.getName(), 135 new PermissionInfo(ServicePermission.class.getName(),
137 HostService.class.getName(), ServicePermission.GET), 136 HostService.class.getName(), ServicePermission.GET),
138 new PermissionInfo(ServicePermission.class.getName(), 137 new PermissionInfo(ServicePermission.class.getName(),
139 - HostClockService.class.getName(), ServicePermission.GET),
140 - new PermissionInfo(ServicePermission.class.getName(),
141 IntentService.class.getName(), ServicePermission.GET), 138 IntentService.class.getName(), ServicePermission.GET),
142 new PermissionInfo(ServicePermission.class.getName(), 139 new PermissionInfo(ServicePermission.class.getName(),
143 IntentClockService.class.getName(), ServicePermission.GET), 140 IntentClockService.class.getName(), ServicePermission.GET),
...@@ -209,8 +206,6 @@ public final class PolicyBuilder { ...@@ -209,8 +206,6 @@ public final class PolicyBuilder {
209 GroupService.class.getName())); 206 GroupService.class.getName()));
210 serviceDirectory.put(Permission.GROUP_EVENT, ImmutableSet.of( 207 serviceDirectory.put(Permission.GROUP_EVENT, ImmutableSet.of(
211 GroupService.class.getName())); 208 GroupService.class.getName()));
212 - serviceDirectory.put(Permission.HOST_READ, ImmutableSet.of(
213 - HostService.class.getName(), HostClockService.class.getName()));
214 serviceDirectory.put(Permission.HOST_WRITE, ImmutableSet.of( 209 serviceDirectory.put(Permission.HOST_WRITE, ImmutableSet.of(
215 HostService.class.getName())); 210 HostService.class.getName()));
216 serviceDirectory.put(Permission.HOST_EVENT, ImmutableSet.of( 211 serviceDirectory.put(Permission.HOST_EVENT, ImmutableSet.of(
......
1 +package org.onosproject.store.host.impl;
2 +
3 +import static org.onosproject.net.DefaultAnnotations.merge;
4 +import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
5 +import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
6 +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
7 +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
8 +import static org.slf4j.LoggerFactory.getLogger;
9 +
10 +import java.util.Collection;
11 +import java.util.Collections;
12 +import java.util.Objects;
13 +import java.util.Set;
14 +import java.util.concurrent.ConcurrentHashMap;
15 +import java.util.function.Predicate;
16 +import java.util.stream.Collectors;
17 +
18 +import org.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Reference;
22 +import org.apache.felix.scr.annotations.ReferenceCardinality;
23 +import org.apache.felix.scr.annotations.Service;
24 +import org.onlab.packet.IpAddress;
25 +import org.onlab.packet.MacAddress;
26 +import org.onlab.packet.VlanId;
27 +import org.onlab.util.KryoNamespace;
28 +import org.onosproject.net.Annotations;
29 +import org.onosproject.net.ConnectPoint;
30 +import org.onosproject.net.DefaultAnnotations;
31 +import org.onosproject.net.DefaultHost;
32 +import org.onosproject.net.DeviceId;
33 +import org.onosproject.net.Host;
34 +import org.onosproject.net.HostId;
35 +import org.onosproject.net.host.HostDescription;
36 +import org.onosproject.net.host.HostEvent;
37 +import org.onosproject.net.host.HostStore;
38 +import org.onosproject.net.host.HostStoreDelegate;
39 +import org.onosproject.net.host.PortAddresses;
40 +import org.onosproject.net.host.HostEvent.Type;
41 +import org.onosproject.net.provider.ProviderId;
42 +import org.onosproject.store.AbstractStore;
43 +import org.onosproject.store.serializers.KryoNamespaces;
44 +import org.onosproject.store.service.EventuallyConsistentMap;
45 +import org.onosproject.store.service.EventuallyConsistentMapEvent;
46 +import org.onosproject.store.service.EventuallyConsistentMapListener;
47 +import org.onosproject.store.service.LogicalClockService;
48 +import org.onosproject.store.service.StorageService;
49 +import org.slf4j.Logger;
50 +
51 +import com.google.common.collect.HashMultimap;
52 +import com.google.common.collect.ImmutableSet;
53 +import com.google.common.collect.Multimap;
54 +import com.google.common.collect.Multimaps;
55 +import com.google.common.collect.SetMultimap;
56 +import com.google.common.collect.Sets;
57 +import static com.google.common.collect.Multimaps.newSetMultimap;
58 +import static com.google.common.collect.Multimaps.synchronizedSetMultimap;
59 +import static com.google.common.collect.Sets.newConcurrentHashSet;
60 +
61 +/**
62 + * Manages the inventory of hosts using a {@code EventuallyConsistentMap}.
63 + */
64 +@Component(immediate = true)
65 +@Service
66 +public class ECHostStore
67 + extends AbstractStore<HostEvent, HostStoreDelegate>
68 + implements HostStore {
69 +
70 + private final Logger log = getLogger(getClass());
71 +
72 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 + protected StorageService storageService;
74 +
75 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 + protected LogicalClockService clockService;
77 +
78 + // Hosts tracked by their location
79 + private final Multimap<ConnectPoint, Host> locations
80 + = synchronizedSetMultimap(newSetMultimap(new ConcurrentHashMap<>(),
81 + () -> newConcurrentHashSet()));
82 + private final SetMultimap<ConnectPoint, PortAddresses> portAddresses =
83 + Multimaps.synchronizedSetMultimap(
84 + HashMultimap.<ConnectPoint, PortAddresses>create());
85 +
86 + private EventuallyConsistentMap<HostId, DefaultHost> hosts;
87 +
88 + private EventuallyConsistentMapListener<HostId, DefaultHost> hostLocationTracker =
89 + new HostLocationTracker();
90 +
91 + @Activate
92 + public void activate() {
93 + KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder()
94 + .register(KryoNamespaces.API);
95 +
96 + hosts = storageService.<HostId, DefaultHost>eventuallyConsistentMapBuilder()
97 + .withName("onos-hosts")
98 + .withSerializer(hostSerializer)
99 + .withTimestampProvider((k, v) -> clockService.getTimestamp())
100 + .build();
101 +
102 + hosts.addListener(hostLocationTracker);
103 +
104 + log.info("Started");
105 + }
106 +
107 + @Deactivate
108 + public void deactivate() {
109 + hosts.removeListener(hostLocationTracker);
110 + hosts.destroy();
111 + locations.clear();
112 + portAddresses.clear();
113 +
114 + log.info("Stopped");
115 + }
116 +
117 + @Override
118 + public HostEvent createOrUpdateHost(ProviderId providerId,
119 + HostId hostId,
120 + HostDescription hostDescription) {
121 + DefaultHost currentHost = hosts.get(hostId);
122 + if (currentHost == null) {
123 + DefaultHost newhost = new DefaultHost(
124 + providerId,
125 + hostId,
126 + hostDescription.hwAddress(),
127 + hostDescription.vlan(),
128 + hostDescription.location(),
129 + ImmutableSet.copyOf(hostDescription.ipAddress()));
130 + hosts.put(hostId, newhost);
131 + return new HostEvent(HOST_ADDED, newhost);
132 + }
133 + return updateHost(providerId, hostId, hostDescription, currentHost);
134 + }
135 +
136 + @Override
137 + public HostEvent removeHost(HostId hostId) {
138 + Host host = hosts.remove(hostId);
139 + return host != null ? new HostEvent(HOST_REMOVED, host) : null;
140 + }
141 +
142 + @Override
143 + public int getHostCount() {
144 + return hosts.size();
145 + }
146 +
147 + @Override
148 + public Iterable<Host> getHosts() {
149 + return ImmutableSet.copyOf(hosts.values());
150 + }
151 +
152 + @Override
153 + public Host getHost(HostId hostId) {
154 + return hosts.get(hostId);
155 + }
156 +
157 + @Override
158 + public Set<Host> getHosts(VlanId vlanId) {
159 + return filter(hosts.values(), host -> Objects.equals(host.vlan(), vlanId));
160 + }
161 +
162 + @Override
163 + public Set<Host> getHosts(MacAddress mac) {
164 + return filter(hosts.values(), host -> Objects.equals(host.mac(), mac));
165 + }
166 +
167 + @Override
168 + public Set<Host> getHosts(IpAddress ip) {
169 + return filter(hosts.values(), host -> host.ipAddresses().contains(ip));
170 + }
171 +
172 + @Override
173 + public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
174 + return ImmutableSet.copyOf(locations.get(connectPoint));
175 + }
176 +
177 + @Override
178 + public Set<Host> getConnectedHosts(DeviceId deviceId) {
179 + return locations.entries()
180 + .stream()
181 + .filter(entry -> entry.getKey().deviceId().equals(deviceId))
182 + .map(entry -> entry.getValue())
183 + .collect(Collectors.toSet());
184 + }
185 +
186 + @Override
187 + public void updateAddressBindings(PortAddresses addresses) {
188 + portAddresses.put(addresses.connectPoint(), addresses);
189 + }
190 +
191 + @Override
192 + public void removeAddressBindings(PortAddresses addresses) {
193 + portAddresses.remove(addresses.connectPoint(), addresses);
194 + }
195 +
196 + @Override
197 + public void clearAddressBindings(ConnectPoint connectPoint) {
198 + portAddresses.removeAll(connectPoint);
199 + }
200 +
201 + @Override
202 + public Set<PortAddresses> getAddressBindings() {
203 + return ImmutableSet.copyOf(portAddresses.values());
204 + }
205 +
206 + @Override
207 + public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
208 + synchronized (portAddresses) {
209 + Set<PortAddresses> addresses = portAddresses.get(connectPoint);
210 + return addresses == null ? Collections.emptySet() : ImmutableSet.copyOf(addresses);
211 + }
212 + }
213 +
214 + private Set<Host> filter(Collection<DefaultHost> collection, Predicate<DefaultHost> predicate) {
215 + return collection.stream().filter(predicate).collect(Collectors.toSet());
216 + }
217 +
218 + // checks for type of update to host, sends appropriate event
219 + private HostEvent updateHost(ProviderId providerId,
220 + HostId hostId,
221 + HostDescription descr,
222 + DefaultHost currentHost) {
223 +
224 + final boolean hostMoved = !currentHost.location().equals(descr.location());
225 + if (hostMoved ||
226 + !currentHost.ipAddresses().containsAll(descr.ipAddress()) ||
227 + !descr.annotations().keys().isEmpty()) {
228 +
229 + Set<IpAddress> addresses = Sets.newHashSet(currentHost.ipAddresses());
230 + addresses.addAll(descr.ipAddress());
231 + Annotations annotations = merge((DefaultAnnotations) currentHost.annotations(),
232 + descr.annotations());
233 +
234 + DefaultHost updatedHost = new DefaultHost(providerId, currentHost.id(),
235 + currentHost.mac(), currentHost.vlan(),
236 + descr.location(),
237 + addresses,
238 + annotations);
239 +
240 + // TODO: We need a way to detect conflicting changes and abort update.
241 + hosts.put(hostId, updatedHost);
242 + locations.remove(currentHost.location(), currentHost);
243 + locations.put(updatedHost.location(), updatedHost);
244 +
245 + HostEvent.Type eventType = hostMoved ? Type.HOST_MOVED : Type.HOST_UPDATED;
246 + return new HostEvent(eventType, updatedHost);
247 + }
248 + return null;
249 + }
250 +
251 + private class HostLocationTracker implements EventuallyConsistentMapListener<HostId, DefaultHost> {
252 +
253 + @Override
254 + public void event(EventuallyConsistentMapEvent<HostId, DefaultHost> event) {
255 + DefaultHost host = event.value();
256 + if (event.type() == PUT) {
257 + locations.put(host.location(), host);
258 + } else if (event.type() == REMOVE) {
259 + locations.remove(host.location(), host);
260 + }
261 + }
262 + }
263 +}
1 -/*
2 - * Copyright 2014-2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.host.impl;
17 -
18 -import com.google.common.collect.FluentIterable;
19 -import com.google.common.collect.HashMultimap;
20 -import com.google.common.collect.ImmutableList;
21 -import com.google.common.collect.ImmutableSet;
22 -import com.google.common.collect.Multimap;
23 -import com.google.common.collect.Multimaps;
24 -import com.google.common.collect.SetMultimap;
25 -import org.apache.commons.lang3.RandomUtils;
26 -import org.apache.felix.scr.annotations.Activate;
27 -import org.apache.felix.scr.annotations.Component;
28 -import org.apache.felix.scr.annotations.Deactivate;
29 -import org.apache.felix.scr.annotations.Reference;
30 -import org.apache.felix.scr.annotations.ReferenceCardinality;
31 -import org.apache.felix.scr.annotations.Service;
32 -import org.onlab.packet.IpAddress;
33 -import org.onlab.packet.MacAddress;
34 -import org.onlab.packet.VlanId;
35 -import org.onlab.util.KryoNamespace;
36 -import org.onosproject.cluster.ClusterService;
37 -import org.onosproject.cluster.ControllerNode;
38 -import org.onosproject.cluster.NodeId;
39 -import org.onosproject.net.Annotations;
40 -import org.onosproject.net.AnnotationsUtil;
41 -import org.onosproject.net.ConnectPoint;
42 -import org.onosproject.net.DefaultAnnotations;
43 -import org.onosproject.net.DefaultHost;
44 -import org.onosproject.net.DeviceId;
45 -import org.onosproject.net.Host;
46 -import org.onosproject.net.HostId;
47 -import org.onosproject.net.HostLocation;
48 -import org.onosproject.net.host.DefaultHostDescription;
49 -import org.onosproject.net.host.HostClockService;
50 -import org.onosproject.net.host.HostDescription;
51 -import org.onosproject.net.host.HostEvent;
52 -import org.onosproject.net.host.HostEvent.Type;
53 -import org.onosproject.net.host.HostStore;
54 -import org.onosproject.net.host.HostStoreDelegate;
55 -import org.onosproject.net.host.PortAddresses;
56 -import org.onosproject.net.provider.ProviderId;
57 -import org.onosproject.store.AbstractStore;
58 -import org.onosproject.store.Timestamp;
59 -import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
60 -import org.onosproject.store.cluster.messaging.ClusterMessage;
61 -import org.onosproject.store.cluster.messaging.ClusterMessageHandler;
62 -import org.onosproject.store.cluster.messaging.MessageSubject;
63 -import org.onosproject.store.impl.Timestamped;
64 -import org.onosproject.store.serializers.KryoSerializer;
65 -import org.onosproject.store.serializers.custom.DistributedStoreSerializers;
66 -import org.slf4j.Logger;
67 -
68 -import java.io.IOException;
69 -import java.util.Collections;
70 -import java.util.HashMap;
71 -import java.util.HashSet;
72 -import java.util.Map;
73 -import java.util.Map.Entry;
74 -import java.util.Set;
75 -import java.util.concurrent.ConcurrentHashMap;
76 -import java.util.concurrent.ExecutorService;
77 -import java.util.concurrent.ScheduledExecutorService;
78 -import java.util.concurrent.TimeUnit;
79 -
80 -import static com.google.common.base.Preconditions.checkNotNull;
81 -import static com.google.common.collect.Multimaps.newSetMultimap;
82 -import static com.google.common.collect.Multimaps.synchronizedSetMultimap;
83 -import static com.google.common.collect.Sets.newConcurrentHashSet;
84 -import static java.util.concurrent.Executors.newCachedThreadPool;
85 -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
86 -import static org.onlab.util.Tools.groupedThreads;
87 -import static org.onlab.util.Tools.minPriority;
88 -import static org.onosproject.cluster.ControllerNodeToNodeId.toNodeId;
89 -import static org.onosproject.net.DefaultAnnotations.merge;
90 -import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
91 -import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
92 -import static org.onosproject.store.host.impl.GossipHostStoreMessageSubjects.*;
93 -import static org.slf4j.LoggerFactory.getLogger;
94 -
95 -/**
96 - * Manages inventory of end-station hosts in distributed data store
97 - * that uses optimistic replication and gossip based techniques.
98 - */
99 -@Component(immediate = true)
100 -@Service
101 -public class GossipHostStore
102 - extends AbstractStore<HostEvent, HostStoreDelegate>
103 - implements HostStore {
104 -
105 - private final Logger log = getLogger(getClass());
106 -
107 - // TODO: make this configurable
108 - private int hostsExpected = 2000000;
109 -
110 - // Host inventory
111 - private final Map<HostId, StoredHost> hosts = new ConcurrentHashMap<>(hostsExpected, 0.75f, 16);
112 -
113 - private final Map<HostId, Timestamped<Host>> removedHosts = new ConcurrentHashMap<>(hostsExpected, 0.75f, 16);
114 -
115 - // Hosts tracked by their location
116 - private final Multimap<ConnectPoint, Host> locations
117 - = synchronizedSetMultimap(newSetMultimap(new ConcurrentHashMap<>(),
118 - () -> newConcurrentHashSet()));
119 -
120 - private final SetMultimap<ConnectPoint, PortAddresses> portAddresses =
121 - Multimaps.synchronizedSetMultimap(
122 - HashMultimap.<ConnectPoint, PortAddresses>create());
123 -
124 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
125 - protected HostClockService hostClockService;
126 -
127 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
128 - protected ClusterCommunicationService clusterCommunicator;
129 -
130 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
131 - protected ClusterService clusterService;
132 -
133 - private static final KryoSerializer SERIALIZER = new KryoSerializer() {
134 - @Override
135 - protected void setupKryoPool() {
136 - serializerPool = KryoNamespace.newBuilder()
137 - .register(DistributedStoreSerializers.STORE_COMMON)
138 - .nextId(DistributedStoreSerializers.STORE_CUSTOM_BEGIN)
139 - .register(InternalHostEvent.class)
140 - .register(InternalHostRemovedEvent.class)
141 - .register(HostFragmentId.class)
142 - .register(HostAntiEntropyAdvertisement.class)
143 - .build();
144 - }
145 - };
146 -
147 - private ExecutorService executor;
148 -
149 - private ScheduledExecutorService backgroundExecutor;
150 -
151 - // TODO: Make these anti-entropy params configurable
152 - private long initialDelaySec = 5;
153 - private long periodSec = 5;
154 -
155 - @Activate
156 - public void activate() {
157 -
158 - executor = newCachedThreadPool(groupedThreads("onos/host", "fg-%d"));
159 -
160 - backgroundExecutor =
161 - newSingleThreadScheduledExecutor(minPriority(groupedThreads("onos/host", "bg-%d")));
162 -
163 - clusterCommunicator.addSubscriber(
164 - HOST_UPDATED_MSG,
165 - new InternalHostEventListener(), executor);
166 - clusterCommunicator.addSubscriber(
167 - HOST_REMOVED_MSG,
168 - new InternalHostRemovedEventListener(), executor);
169 - clusterCommunicator.addSubscriber(
170 - HOST_ANTI_ENTROPY_ADVERTISEMENT,
171 - new InternalHostAntiEntropyAdvertisementListener(), backgroundExecutor);
172 -
173 - // start anti-entropy thread
174 - backgroundExecutor.scheduleAtFixedRate(new SendAdvertisementTask(),
175 - initialDelaySec, periodSec, TimeUnit.SECONDS);
176 -
177 - log.info("Started");
178 - }
179 -
180 - @Deactivate
181 - public void deactivate() {
182 - executor.shutdownNow();
183 - backgroundExecutor.shutdownNow();
184 - try {
185 - if (!backgroundExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
186 - log.error("Timeout during executor shutdown");
187 - }
188 - } catch (InterruptedException e) {
189 - log.error("Error during executor shutdown", e);
190 - }
191 -
192 - hosts.clear();
193 - removedHosts.clear();
194 - locations.clear();
195 - portAddresses.clear();
196 -
197 - log.info("Stopped");
198 - }
199 -
200 - @Override
201 - public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
202 - HostDescription hostDescription) {
203 - Timestamp timestamp = hostClockService.getTimestamp(hostId);
204 - HostEvent event = createOrUpdateHostInternal(providerId, hostId, hostDescription, timestamp);
205 - if (event != null) {
206 - log.debug("Notifying peers of a host topology event for providerId: "
207 - + "{}; hostId: {}; hostDescription: {}", providerId, hostId, hostDescription);
208 - notifyPeers(new InternalHostEvent(providerId, hostId, hostDescription, timestamp));
209 - }
210 - return event;
211 - }
212 -
213 - private HostEvent createOrUpdateHostInternal(ProviderId providerId, HostId hostId,
214 - HostDescription hostDescription, Timestamp timestamp) {
215 - // If this host was previously removed, first ensure
216 - // this new request is "newer"
217 - if (isHostRemoved(hostId, timestamp)) {
218 - log.debug("Ignoring update for removed host {}@{}",
219 - hostDescription, timestamp);
220 - return null;
221 - }
222 - StoredHost host = hosts.get(hostId);
223 - if (host == null) {
224 - return createHost(providerId, hostId, hostDescription, timestamp);
225 - }
226 - return updateHost(providerId, hostId, host, hostDescription, timestamp);
227 - }
228 -
229 - /**
230 - * @param hostId host identifier
231 - * @param timestamp timstamp to compare with
232 - * @return true if given timestamp is more recent timestamp compared to
233 - * the timestamp Host was removed.
234 - */
235 - private boolean isHostRemoved(HostId hostId, Timestamp timestamp) {
236 - Timestamped<Host> removedInfo = removedHosts.get(hostId);
237 - if (removedInfo != null) {
238 - if (removedInfo.isNewerThan(timestamp)) {
239 - return true;
240 - }
241 - removedHosts.remove(hostId, removedInfo);
242 - }
243 - return false;
244 - }
245 -
246 - // creates a new host and sends HOST_ADDED
247 - private HostEvent createHost(ProviderId providerId, HostId hostId,
248 - HostDescription descr, Timestamp timestamp) {
249 - synchronized (this) {
250 - StoredHost newhost = new StoredHost(timestamp, providerId, hostId,
251 - descr.hwAddress(),
252 - descr.vlan(),
253 - descr.location(),
254 - ImmutableSet.copyOf(descr.ipAddress()));
255 - StoredHost concAdd = hosts.putIfAbsent(hostId, newhost);
256 - if (concAdd != null) {
257 - // concurrent add detected, retry from start
258 - return updateHost(providerId, hostId, concAdd, descr, timestamp);
259 - }
260 - locations.put(descr.location(), newhost);
261 - return new HostEvent(HOST_ADDED, newhost);
262 - }
263 - }
264 -
265 - // checks for type of update to host, sends appropriate event
266 - private HostEvent updateHost(ProviderId providerId, HostId hostId, StoredHost oldHost,
267 - HostDescription descr, Timestamp timestamp) {
268 -
269 - if (timestamp.compareTo(oldHost.timestamp()) < 0) {
270 - // new timestamp is older
271 - log.debug("Ignoring outdated host update {}@{}", descr, timestamp);
272 - return null;
273 - }
274 -
275 - final boolean hostMoved = !oldHost.location().equals(descr.location());
276 - if (hostMoved ||
277 - !oldHost.ipAddresses().containsAll(descr.ipAddress()) ||
278 - !descr.annotations().keys().isEmpty()) {
279 -
280 - Set<IpAddress> addresses = new HashSet<>(oldHost.ipAddresses());
281 - addresses.addAll(descr.ipAddress());
282 - Annotations annotations = merge((DefaultAnnotations) oldHost.annotations(),
283 - descr.annotations());
284 -
285 - Timestamp newTimestamp = timestamp;
286 - // if merged Set/Annotation differ from description...
287 - final boolean deltaUpdate = !descr.ipAddress().equals(addresses) ||
288 - !AnnotationsUtil.isEqual(descr.annotations(), annotations);
289 - if (deltaUpdate) {
290 - // ..then local existing info had something description didn't
291 - newTimestamp = hostClockService.getTimestamp(hostId);
292 - log.debug("delta update detected on {}, substepping timestamp to {}",
293 - hostId, newTimestamp);
294 - }
295 -
296 - StoredHost updated = new StoredHost(newTimestamp,
297 - providerId, oldHost.id(),
298 - oldHost.mac(), oldHost.vlan(),
299 - descr.location(),
300 - addresses,
301 - annotations);
302 - synchronized (this) {
303 - boolean replaced = hosts.replace(hostId, oldHost, updated);
304 - if (!replaced) {
305 - // concurrent update, retry
306 - return createOrUpdateHostInternal(providerId, hostId, descr, timestamp);
307 - }
308 - locations.remove(oldHost.location(), oldHost);
309 - locations.put(updated.location(), updated);
310 -
311 - HostEvent.Type eventType;
312 - if (hostMoved) {
313 - eventType = Type.HOST_MOVED;
314 - } else {
315 - eventType = Type.HOST_UPDATED;
316 - }
317 - return new HostEvent(eventType, updated);
318 - }
319 - }
320 - return null;
321 - }
322 -
323 - @Override
324 - public HostEvent removeHost(HostId hostId) {
325 - Timestamp timestamp = hostClockService.getTimestamp(hostId);
326 - HostEvent event = removeHostInternal(hostId, timestamp);
327 - if (event != null) {
328 - log.debug("Notifying peers of a host removed topology event for hostId: {}", hostId);
329 - notifyPeers(new InternalHostRemovedEvent(hostId, timestamp));
330 - }
331 - return event;
332 - }
333 -
334 - private HostEvent removeHostInternal(HostId hostId, Timestamp timestamp) {
335 - synchronized (this) {
336 - Host host = hosts.remove(hostId);
337 - if (host != null) {
338 - locations.remove((host.location()), host);
339 - removedHosts.put(hostId, new Timestamped<>(host, timestamp));
340 - return new HostEvent(HOST_REMOVED, host);
341 - }
342 - return null;
343 - }
344 - }
345 -
346 - @Override
347 - public int getHostCount() {
348 - return hosts.size();
349 - }
350 -
351 - @Override
352 - public Iterable<Host> getHosts() {
353 - return ImmutableSet.<Host>copyOf(hosts.values());
354 - }
355 -
356 - @Override
357 - public Host getHost(HostId hostId) {
358 - return hosts.get(hostId);
359 - }
360 -
361 - @Override
362 - public Set<Host> getHosts(VlanId vlanId) {
363 - Set<Host> vlanset = new HashSet<>();
364 - for (Host h : hosts.values()) {
365 - if (h.vlan().equals(vlanId)) {
366 - vlanset.add(h);
367 - }
368 - }
369 - return vlanset;
370 - }
371 -
372 - @Override
373 - public Set<Host> getHosts(MacAddress mac) {
374 - Set<Host> macset = new HashSet<>();
375 - for (Host h : hosts.values()) {
376 - if (h.mac().equals(mac)) {
377 - macset.add(h);
378 - }
379 - }
380 - return macset;
381 - }
382 -
383 - @Override
384 - public Set<Host> getHosts(IpAddress ip) {
385 - Set<Host> ipset = new HashSet<>();
386 - for (Host h : hosts.values()) {
387 - if (h.ipAddresses().contains(ip)) {
388 - ipset.add(h);
389 - }
390 - }
391 - return ipset;
392 - }
393 -
394 - @Override
395 - public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
396 - return ImmutableSet.copyOf(locations.get(connectPoint));
397 - }
398 -
399 - @Override
400 - public Set<Host> getConnectedHosts(DeviceId deviceId) {
401 - Set<Host> hostset = new HashSet<>();
402 - for (ConnectPoint p : locations.keySet()) {
403 - if (p.deviceId().equals(deviceId)) {
404 - hostset.addAll(locations.get(p));
405 - }
406 - }
407 - return hostset;
408 - }
409 -
410 - @Override
411 - public void updateAddressBindings(PortAddresses addresses) {
412 - portAddresses.put(addresses.connectPoint(), addresses);
413 - }
414 -
415 - @Override
416 - public void removeAddressBindings(PortAddresses addresses) {
417 - portAddresses.remove(addresses.connectPoint(), addresses);
418 - }
419 -
420 - @Override
421 - public void clearAddressBindings(ConnectPoint connectPoint) {
422 - portAddresses.removeAll(connectPoint);
423 - }
424 -
425 - @Override
426 - public Set<PortAddresses> getAddressBindings() {
427 - synchronized (portAddresses) {
428 - return ImmutableSet.copyOf(portAddresses.values());
429 - }
430 - }
431 -
432 - @Override
433 - public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
434 - synchronized (portAddresses) {
435 - Set<PortAddresses> addresses = portAddresses.get(connectPoint);
436 -
437 - if (addresses == null) {
438 - return Collections.emptySet();
439 - } else {
440 - return ImmutableSet.copyOf(addresses);
441 - }
442 - }
443 - }
444 -
445 - private static final class StoredHost extends DefaultHost {
446 - private final Timestamp timestamp;
447 -
448 - /**
449 - * Creates an end-station host using the supplied information.
450 - *
451 - * @param providerId provider identity
452 - * @param id host identifier
453 - * @param mac host MAC address
454 - * @param vlan host VLAN identifier
455 - * @param location host location
456 - * @param ips host IP addresses
457 - * @param annotations optional key/value annotations
458 - */
459 - public StoredHost(Timestamp timestamp, ProviderId providerId, HostId id,
460 - MacAddress mac, VlanId vlan, HostLocation location,
461 - Set<IpAddress> ips, Annotations... annotations) {
462 - super(providerId, id, mac, vlan, location, ips, annotations);
463 - this.timestamp = checkNotNull(timestamp);
464 - }
465 -
466 - public Timestamp timestamp() {
467 - return timestamp;
468 - }
469 - }
470 -
471 - private void notifyPeers(InternalHostRemovedEvent event) {
472 - broadcastMessage(HOST_REMOVED_MSG, event);
473 - }
474 -
475 - private void notifyPeers(InternalHostEvent event) {
476 - broadcastMessage(HOST_UPDATED_MSG, event);
477 - }
478 -
479 - private void broadcastMessage(MessageSubject subject, Object event) {
480 - clusterCommunicator.broadcast(event, subject, SERIALIZER::encode);
481 - }
482 -
483 - private void unicastMessage(NodeId peer,
484 - MessageSubject subject,
485 - Object event) throws IOException {
486 - clusterCommunicator.unicast(event, subject, SERIALIZER::encode, peer);
487 - }
488 -
489 - private void notifyDelegateIfNotNull(HostEvent event) {
490 - if (event != null) {
491 - notifyDelegate(event);
492 - }
493 - }
494 -
495 - private final class InternalHostEventListener
496 - implements ClusterMessageHandler {
497 - @Override
498 - public void handle(ClusterMessage message) {
499 -
500 - log.debug("Received host update event from peer: {}", message.sender());
501 - InternalHostEvent event = SERIALIZER.decode(message.payload());
502 -
503 - ProviderId providerId = event.providerId();
504 - HostId hostId = event.hostId();
505 - HostDescription hostDescription = event.hostDescription();
506 - Timestamp timestamp = event.timestamp();
507 -
508 - try {
509 - notifyDelegateIfNotNull(createOrUpdateHostInternal(providerId,
510 - hostId,
511 - hostDescription,
512 - timestamp));
513 - } catch (Exception e) {
514 - log.warn("Exception thrown handling host removed", e);
515 - }
516 - }
517 - }
518 -
519 - private final class InternalHostRemovedEventListener
520 - implements ClusterMessageHandler {
521 - @Override
522 - public void handle(ClusterMessage message) {
523 -
524 - log.debug("Received host removed event from peer: {}", message.sender());
525 - InternalHostRemovedEvent event = SERIALIZER.decode(message.payload());
526 -
527 - HostId hostId = event.hostId();
528 - Timestamp timestamp = event.timestamp();
529 -
530 - try {
531 - notifyDelegateIfNotNull(removeHostInternal(hostId, timestamp));
532 - } catch (Exception e) {
533 - log.warn("Exception thrown handling host removed", e);
534 - }
535 - }
536 - }
537 -
538 - private final class SendAdvertisementTask implements Runnable {
539 -
540 - @Override
541 - public void run() {
542 - if (Thread.currentThread().isInterrupted()) {
543 - log.info("Interrupted, quitting");
544 - return;
545 - }
546 -
547 - try {
548 - final NodeId self = clusterService.getLocalNode().id();
549 - Set<ControllerNode> nodes = clusterService.getNodes();
550 -
551 - ImmutableList<NodeId> nodeIds = FluentIterable.from(nodes)
552 - .transform(toNodeId())
553 - .toList();
554 -
555 - if (nodeIds.size() == 1 && nodeIds.get(0).equals(self)) {
556 - log.trace("No other peers in the cluster.");
557 - return;
558 - }
559 -
560 - NodeId peer;
561 - do {
562 - int idx = RandomUtils.nextInt(0, nodeIds.size());
563 - peer = nodeIds.get(idx);
564 - } while (peer.equals(self));
565 -
566 - HostAntiEntropyAdvertisement ad = createAdvertisement();
567 -
568 - if (Thread.currentThread().isInterrupted()) {
569 - log.info("Interrupted, quitting");
570 - return;
571 - }
572 -
573 - try {
574 - unicastMessage(peer, HOST_ANTI_ENTROPY_ADVERTISEMENT, ad);
575 - } catch (IOException e) {
576 - log.debug("Failed to send anti-entropy advertisement to {}", peer);
577 - return;
578 - }
579 - } catch (Exception e) {
580 - // catch all Exception to avoid Scheduled task being suppressed.
581 - log.error("Exception thrown while sending advertisement", e);
582 - }
583 - }
584 - }
585 -
586 - private HostAntiEntropyAdvertisement createAdvertisement() {
587 - final NodeId self = clusterService.getLocalNode().id();
588 -
589 - Map<HostFragmentId, Timestamp> timestamps = new HashMap<>(hosts.size());
590 - Map<HostId, Timestamp> tombstones = new HashMap<>(removedHosts.size());
591 -
592 - hosts.forEach((hostId, hostInfo) -> {
593 - final ProviderId providerId = hostInfo.providerId();
594 - timestamps.put(new HostFragmentId(hostId, providerId), hostInfo.timestamp());
595 - });
596 -
597 - removedHosts.forEach((hostId, timestamped) -> {
598 - tombstones.put(hostId, timestamped.timestamp());
599 - });
600 -
601 - return new HostAntiEntropyAdvertisement(self, timestamps, tombstones);
602 - }
603 -
604 - private synchronized void handleAntiEntropyAdvertisement(HostAntiEntropyAdvertisement ad) {
605 -
606 - final NodeId sender = ad.sender();
607 -
608 - for (Entry<HostId, StoredHost> host : hosts.entrySet()) {
609 - // for each locally live Hosts...
610 - final HostId hostId = host.getKey();
611 - final StoredHost localHost = host.getValue();
612 - final ProviderId providerId = localHost.providerId();
613 - final HostFragmentId hostFragId = new HostFragmentId(hostId, providerId);
614 - final Timestamp localLiveTimestamp = localHost.timestamp();
615 -
616 - Timestamp remoteTimestamp = ad.timestamps().get(hostFragId);
617 - if (remoteTimestamp == null) {
618 - remoteTimestamp = ad.tombstones().get(hostId);
619 - }
620 - if (remoteTimestamp == null ||
621 - localLiveTimestamp.compareTo(remoteTimestamp) > 0) {
622 -
623 - // local is more recent, push
624 - // TODO: annotation is lost
625 - final HostDescription desc = new DefaultHostDescription(
626 - localHost.mac(),
627 - localHost.vlan(),
628 - localHost.location(),
629 - localHost.ipAddresses());
630 - try {
631 - unicastMessage(sender, HOST_UPDATED_MSG,
632 - new InternalHostEvent(providerId, hostId, desc, localHost.timestamp()));
633 - } catch (IOException e1) {
634 - log.debug("Failed to send advertisement response", e1);
635 - }
636 - }
637 -
638 - final Timestamp remoteDeadTimestamp = ad.tombstones().get(hostId);
639 - if (remoteDeadTimestamp != null &&
640 - remoteDeadTimestamp.compareTo(localLiveTimestamp) > 0) {
641 - // sender has recent remove
642 - notifyDelegateIfNotNull(removeHostInternal(hostId, remoteDeadTimestamp));
643 - }
644 - }
645 -
646 - for (Entry<HostId, Timestamped<Host>> dead : removedHosts.entrySet()) {
647 - // for each locally dead Hosts
648 - final HostId hostId = dead.getKey();
649 - final Timestamp localDeadTimestamp = dead.getValue().timestamp();
650 -
651 - // TODO: pick proper ProviderId, when supporting multi-provider
652 - final ProviderId providerId = dead.getValue().value().providerId();
653 - final HostFragmentId hostFragId = new HostFragmentId(hostId, providerId);
654 -
655 - final Timestamp remoteLiveTimestamp = ad.timestamps().get(hostFragId);
656 - if (remoteLiveTimestamp != null &&
657 - localDeadTimestamp.compareTo(remoteLiveTimestamp) > 0) {
658 - // sender has zombie, push
659 - try {
660 - unicastMessage(sender, HOST_REMOVED_MSG,
661 - new InternalHostRemovedEvent(hostId, localDeadTimestamp));
662 - } catch (IOException e1) {
663 - log.debug("Failed to send advertisement response", e1);
664 - }
665 - }
666 - }
667 -
668 - for (Entry<HostId, Timestamp> e : ad.tombstones().entrySet()) {
669 - // for each remote tombstone advertisement...
670 - final HostId hostId = e.getKey();
671 - final Timestamp adRemoveTimestamp = e.getValue();
672 -
673 - final StoredHost storedHost = hosts.get(hostId);
674 - if (storedHost == null) {
675 - continue;
676 - }
677 - if (adRemoveTimestamp.compareTo(storedHost.timestamp()) > 0) {
678 - // sender has recent remove info, locally remove
679 - notifyDelegateIfNotNull(removeHostInternal(hostId, adRemoveTimestamp));
680 - }
681 - }
682 -
683 - // if remote ad has something unknown, actively sync
684 - for (HostFragmentId key : ad.timestamps().keySet()) {
685 - if (!hosts.containsKey(key.hostId())) {
686 - HostAntiEntropyAdvertisement myAd = createAdvertisement();
687 - try {
688 - unicastMessage(sender, HOST_ANTI_ENTROPY_ADVERTISEMENT, myAd);
689 - break;
690 - } catch (IOException e) {
691 - log.debug("Failed to send reactive anti-entropy advertisement to {}", sender);
692 - }
693 - }
694 - }
695 - }
696 -
697 - private final class InternalHostAntiEntropyAdvertisementListener
698 - implements ClusterMessageHandler {
699 -
700 - @Override
701 - public void handle(ClusterMessage message) {
702 - log.trace("Received Host Anti-Entropy advertisement from peer: {}", message.sender());
703 - HostAntiEntropyAdvertisement advertisement = SERIALIZER.decode(message.payload());
704 - try {
705 - handleAntiEntropyAdvertisement(advertisement);
706 - } catch (Exception e) {
707 - log.warn("Exception thrown handling Host advertisements", e);
708 - }
709 - }
710 - }
711 -}
1 -/*
2 - * Copyright 2014-2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.host.impl;
17 -
18 -import org.onosproject.store.cluster.messaging.MessageSubject;
19 -
20 -public final class GossipHostStoreMessageSubjects {
21 - private GossipHostStoreMessageSubjects() {}
22 -
23 - public static final MessageSubject HOST_UPDATED_MSG
24 - = new MessageSubject("peer-host-updated");
25 - public static final MessageSubject HOST_REMOVED_MSG
26 - = new MessageSubject("peer-host-removed");
27 - public static final MessageSubject HOST_ANTI_ENTROPY_ADVERTISEMENT
28 - = new MessageSubject("host-enti-entropy-advertisement");;
29 -}
1 -/*
2 - * Copyright 2014 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.host.impl;
17 -
18 -import static com.google.common.base.Preconditions.checkNotNull;
19 -
20 -import java.util.Map;
21 -
22 -import org.onosproject.cluster.NodeId;
23 -import org.onosproject.net.HostId;
24 -import org.onosproject.store.Timestamp;
25 -
26 -/**
27 - * Host AE Advertisement message.
28 - */
29 -public final class HostAntiEntropyAdvertisement {
30 -
31 - private final NodeId sender;
32 - private final Map<HostFragmentId, Timestamp> timestamps;
33 - private final Map<HostId, Timestamp> tombstones;
34 -
35 -
36 - public HostAntiEntropyAdvertisement(NodeId sender,
37 - Map<HostFragmentId, Timestamp> timestamps,
38 - Map<HostId, Timestamp> tombstones) {
39 - this.sender = checkNotNull(sender);
40 - this.timestamps = checkNotNull(timestamps);
41 - this.tombstones = checkNotNull(tombstones);
42 - }
43 -
44 - public NodeId sender() {
45 - return sender;
46 - }
47 -
48 - public Map<HostFragmentId, Timestamp> timestamps() {
49 - return timestamps;
50 - }
51 -
52 - public Map<HostId, Timestamp> tombstones() {
53 - return tombstones;
54 - }
55 -
56 - // For serializer
57 - @SuppressWarnings("unused")
58 - private HostAntiEntropyAdvertisement() {
59 - this.sender = null;
60 - this.timestamps = null;
61 - this.tombstones = null;
62 - }
63 -}
1 -/*
2 - * Copyright 2014 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.host.impl;
17 -
18 -import static org.slf4j.LoggerFactory.getLogger;
19 -
20 -import org.apache.felix.scr.annotations.Activate;
21 -import org.apache.felix.scr.annotations.Component;
22 -import org.apache.felix.scr.annotations.Deactivate;
23 -import org.apache.felix.scr.annotations.Service;
24 -import org.onosproject.net.HostId;
25 -import org.onosproject.net.host.HostClockService;
26 -import org.onosproject.store.Timestamp;
27 -import org.onosproject.store.service.WallClockTimestamp;
28 -import org.slf4j.Logger;
29 -
30 -/**
31 - * HostClockService to issue Timestamps based on local wallclock time.
32 - */
33 -@Component(immediate = true)
34 -@Service
35 -public class HostClockManager implements HostClockService {
36 -
37 - private final Logger log = getLogger(getClass());
38 -
39 - @Activate
40 - public void activate() {
41 - log.info("Started");
42 - }
43 -
44 - @Deactivate
45 - public void deactivate() {
46 - log.info("Stopped");
47 - }
48 -
49 - @Override
50 - public Timestamp getTimestamp(HostId hostId) {
51 - return new WallClockTimestamp();
52 - }
53 -}
1 -/*
2 - * Copyright 2014 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.host.impl;
17 -
18 -import java.util.Objects;
19 -
20 -import org.onosproject.net.HostId;
21 -import org.onosproject.net.provider.ProviderId;
22 -
23 -import com.google.common.base.MoreObjects;
24 -
25 -/**
26 - * Identifier for HostDescription from a Provider.
27 - */
28 -public final class HostFragmentId {
29 - public final ProviderId providerId;
30 - public final HostId hostId;
31 -
32 - public HostFragmentId(HostId hostId, ProviderId providerId) {
33 - this.providerId = providerId;
34 - this.hostId = hostId;
35 - }
36 -
37 - public HostId hostId() {
38 - return hostId;
39 - }
40 -
41 - public ProviderId providerId() {
42 - return providerId;
43 - }
44 -
45 - @Override
46 - public int hashCode() {
47 - return Objects.hash(providerId, hostId);
48 - }
49 -
50 - @Override
51 - public boolean equals(Object obj) {
52 - if (this == obj) {
53 - return true;
54 - }
55 - if (!(obj instanceof HostFragmentId)) {
56 - return false;
57 - }
58 - HostFragmentId that = (HostFragmentId) obj;
59 - return Objects.equals(this.hostId, that.hostId) &&
60 - Objects.equals(this.providerId, that.providerId);
61 - }
62 -
63 - @Override
64 - public String toString() {
65 - return MoreObjects.toStringHelper(getClass())
66 - .add("providerId", providerId)
67 - .add("hostId", hostId)
68 - .toString();
69 - }
70 -
71 - // for serializer
72 - @SuppressWarnings("unused")
73 - private HostFragmentId() {
74 - this.providerId = null;
75 - this.hostId = null;
76 - }
77 -}
1 -/*
2 - * Copyright 2014 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.host.impl;
17 -
18 -import org.onosproject.net.HostId;
19 -import org.onosproject.net.host.HostDescription;
20 -import org.onosproject.net.provider.ProviderId;
21 -import org.onosproject.store.Timestamp;
22 -
23 -/**
24 - * Information published by GossipHostStore to notify peers of a host
25 - * change (create/update) event.
26 - */
27 -public class InternalHostEvent {
28 -
29 - private final ProviderId providerId;
30 - private final HostId hostId;
31 - private final HostDescription hostDescription;
32 - private final Timestamp timestamp;
33 -
34 - public InternalHostEvent(ProviderId providerId, HostId hostId,
35 - HostDescription hostDescription, Timestamp timestamp) {
36 - this.providerId = providerId;
37 - this.hostId = hostId;
38 - this.hostDescription = hostDescription;
39 - this.timestamp = timestamp;
40 - }
41 -
42 - public ProviderId providerId() {
43 - return providerId;
44 - }
45 -
46 - public HostId hostId() {
47 - return hostId;
48 - }
49 -
50 - public HostDescription hostDescription() {
51 - return hostDescription;
52 - }
53 -
54 - public Timestamp timestamp() {
55 - return timestamp;
56 - }
57 -
58 - // Needed for serialization.
59 - @SuppressWarnings("unused")
60 - private InternalHostEvent() {
61 - providerId = null;
62 - hostId = null;
63 - hostDescription = null;
64 - timestamp = null;
65 - }
66 -}
1 -/*
2 - * Copyright 2014 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.host.impl;
17 -
18 -import org.onosproject.net.HostId;
19 -import org.onosproject.store.Timestamp;
20 -
21 -/**
22 - * Information published by GossipHostStore to notify peers of a host
23 - * removed event.
24 - */
25 -public class InternalHostRemovedEvent {
26 -
27 - private final HostId hostId;
28 - private final Timestamp timestamp;
29 -
30 - public InternalHostRemovedEvent(HostId hostId, Timestamp timestamp) {
31 - this.hostId = hostId;
32 - this.timestamp = timestamp;
33 - }
34 -
35 - public HostId hostId() {
36 - return hostId;
37 - }
38 -
39 - public Timestamp timestamp() {
40 - return timestamp;
41 - }
42 -
43 - // for serialization.
44 - @SuppressWarnings("unused")
45 - private InternalHostRemovedEvent() {
46 - hostId = null;
47 - timestamp = null;
48 - }
49 -}
1 -/*
2 - * Copyright 2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.intent.impl;
17 -
18 -import org.onosproject.store.cluster.messaging.MessageSubject;
19 -
20 -/**
21 - * Message subjects for internal gossip intent store node-to-node messages.
22 - */
23 -public final class GossipIntentStoreMessageSubjects {
24 - private GossipIntentStoreMessageSubjects() {}
25 -
26 - public static final MessageSubject INTENT_UPDATED_MSG
27 - = new MessageSubject("peer-intent-updated");
28 - public static final MessageSubject INTENT_SET_INSTALLABLES_MSG
29 - = new MessageSubject("peer-intent-set-installables");
30 - public static final MessageSubject INTENT_ANTI_ENTROPY_ADVERTISEMENT
31 - = new MessageSubject("intent-anti-entropy-advertisement");
32 -}
1 -/*
2 - * Copyright 2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.intent.impl;
17 -
18 -import org.apache.felix.scr.annotations.Activate;
19 -import org.apache.felix.scr.annotations.Component;
20 -import org.apache.felix.scr.annotations.Deactivate;
21 -import org.apache.felix.scr.annotations.Service;
22 -import org.onosproject.net.intent.IntentClockService;
23 -import org.onosproject.net.intent.IntentId;
24 -import org.onosproject.store.Timestamp;
25 -import org.onosproject.store.service.WallClockTimestamp;
26 -import org.slf4j.Logger;
27 -
28 -import static org.slf4j.LoggerFactory.getLogger;
29 -
30 -/**
31 - * IntentClockService that issues timestamps based on local wallclock time.
32 - */
33 -@Component(immediate = true)
34 -@Service
35 -public class IntentClockManager implements IntentClockService {
36 -
37 - private final Logger log = getLogger(getClass());
38 -
39 - @Activate
40 - public void activate() {
41 - log.info("Started");
42 - }
43 -
44 - @Deactivate
45 - public void deactivate() {
46 - log.info("Stopped");
47 - }
48 -
49 - @Override
50 - public Timestamp getTimestamp(IntentId intentId) {
51 - return new WallClockTimestamp();
52 - }
53 -}
1 -/*
2 - * Copyright 2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.intent.impl;
17 -
18 -import org.onosproject.net.intent.Intent;
19 -import org.onosproject.net.intent.IntentId;
20 -import org.onosproject.net.intent.IntentState;
21 -import org.onosproject.store.Timestamp;
22 -
23 -/**
24 - * Information published by GossipIntentStore to notify peers of an intent
25 - * creation or state update event.
26 - */
27 -public class InternalIntentEvent {
28 -
29 - private final IntentId intentId;
30 - private final Intent intent;
31 - private final IntentState state;
32 - private final Timestamp timestamp;
33 -
34 - public InternalIntentEvent(IntentId intentId, Intent intent, IntentState state,
35 - Timestamp timestamp) {
36 - this.intentId = intentId;
37 - this.intent = intent;
38 - this.state = state;
39 - this.timestamp = timestamp;
40 - }
41 -
42 - public IntentId intentId() {
43 - return intentId;
44 - }
45 -
46 - public Intent intent() {
47 - return intent;
48 - }
49 -
50 - public IntentState state() {
51 - return state;
52 - }
53 -
54 - public Timestamp timestamp() {
55 - return timestamp;
56 - }
57 -
58 - // Needed for serialization.
59 - @SuppressWarnings("unused")
60 - private InternalIntentEvent() {
61 - intentId = null;
62 - intent = null;
63 - state = null;
64 - timestamp = null;
65 - }
66 -}
1 -/*
2 - * Copyright 2015 Open Networking Laboratory
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - */
16 -package org.onosproject.store.intent.impl;
17 -
18 -import org.onosproject.net.intent.Intent;
19 -import org.onosproject.net.intent.IntentId;
20 -import org.onosproject.store.Timestamp;
21 -
22 -import java.util.List;
23 -
24 -/**
25 - * Information published by GossipIntentStore to notify peers of an intent
26 - * set installables event.
27 - */
28 -public class InternalSetInstallablesEvent {
29 -
30 - private final IntentId intentId;
31 - private final List<Intent> installables;
32 - private final Timestamp timestamp;
33 -
34 - public InternalSetInstallablesEvent(IntentId intentId,
35 - List<Intent> installables,
36 - Timestamp timestamp) {
37 - this.intentId = intentId;
38 - this.installables = installables;
39 - this.timestamp = timestamp;
40 - }
41 -
42 - public IntentId intentId() {
43 - return intentId;
44 - }
45 -
46 - public List<Intent> installables() {
47 - return installables;
48 - }
49 -
50 - public Timestamp timestamp() {
51 - return timestamp;
52 - }
53 -
54 - // Needed for serialization.
55 - @SuppressWarnings("unused")
56 - private InternalSetInstallablesEvent() {
57 - intentId = null;
58 - installables = null;
59 - timestamp = null;
60 - }
61 -}
...@@ -51,6 +51,7 @@ import org.onosproject.net.ConnectPoint; ...@@ -51,6 +51,7 @@ import org.onosproject.net.ConnectPoint;
51 import org.onosproject.net.DefaultAnnotations; 51 import org.onosproject.net.DefaultAnnotations;
52 import org.onosproject.net.DefaultDevice; 52 import org.onosproject.net.DefaultDevice;
53 import org.onosproject.net.DefaultEdgeLink; 53 import org.onosproject.net.DefaultEdgeLink;
54 +import org.onosproject.net.DefaultHost;
54 import org.onosproject.net.DefaultLink; 55 import org.onosproject.net.DefaultLink;
55 import org.onosproject.net.DefaultPath; 56 import org.onosproject.net.DefaultPath;
56 import org.onosproject.net.DefaultPort; 57 import org.onosproject.net.DefaultPort;
...@@ -267,6 +268,7 @@ public final class KryoNamespaces { ...@@ -267,6 +268,7 @@ public final class KryoNamespaces {
267 DefaultControllerNode.class, 268 DefaultControllerNode.class,
268 DefaultDevice.class, 269 DefaultDevice.class,
269 DefaultDeviceDescription.class, 270 DefaultDeviceDescription.class,
271 + DefaultHost.class,
270 DefaultLinkDescription.class, 272 DefaultLinkDescription.class,
271 Port.class, 273 Port.class,
272 DefaultPortDescription.class, 274 DefaultPortDescription.class,
......