private void unsetRoutes(OpenstackRouter osRouter, OpenstackSubnet osSubNet) { Set<OpenstackSubnet> routableSubNets = routableSubNets(osRouter.id()); Tools.stream(hostService.getHosts()) .filter(h -> Objects.equals(h.annotations().value(NETWORK_ID), osSubNet.id())) .forEach(h -> removeRoutingRules(h, routableSubNets)); routableSubNets.forEach( n -> { Tools.stream(hostService.getHosts()) .filter(h -> Objects.equals(h.annotations().value(SUBNET_ID), n.id())) .forEach(h -> removeRoutingRules(h, ImmutableSet.of(osSubNet))); log.debug("Removed between {} to {}", n.name(), osSubNet.name()); }); }
@Override public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) { NodeId master = mastershipService.getMasterFor(deviceId); if (master == null) { log.debug("Failed to getFlowEntries: No master for {}", deviceId); return Collections.emptyList(); } if (Objects.equal(local, master)) { return flowTable.getFlowEntries(deviceId); } log.trace( "Forwarding getFlowEntries to {}, which is the primary (master) for device {}", master, deviceId); return Tools.futureGetOrElse( clusterCommunicator.sendAndReceive( deviceId, FlowStoreMessageSubjects.GET_DEVICE_FLOW_ENTRIES, SERIALIZER::encode, SERIALIZER::decode, master), FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, Collections.emptyList()); }
@Activate public void activate() { discreteConsumers = service .<DiscreteResource, ResourceConsumer>consistentMapBuilder() .withName(DISCRETE_CONSUMER_MAP) .withSerializer(SERIALIZER) .build(); continuousConsumers = service .<ResourceId, ContinuousResourceAllocation>consistentMapBuilder() .withName(CONTINUOUS_CONSUMER_MAP) .withSerializer(SERIALIZER) .build(); childMap = service .<DiscreteResource, Set<Resource>>consistentMapBuilder() .withName(CHILD_MAP) .withSerializer(SERIALIZER) .build(); Tools.retryable( () -> childMap.put(Resource.ROOT, new LinkedHashSet<>()), ConsistentMapException.class, MAX_RETRIES, RETRY_DELAY); log.info("Started"); }
@Override public FlowEntry getFlowEntry(FlowRule rule) { NodeId master = mastershipService.getMasterFor(rule.deviceId()); if (master == null) { log.debug("Failed to getFlowEntry: No master for {}", rule.deviceId()); return null; } if (Objects.equal(local, master)) { return flowTable.getFlowEntry(rule); } log.trace( "Forwarding getFlowEntry to {}, which is the primary (master) for device {}", master, rule.deviceId()); return Tools.futureGetOrElse( clusterCommunicator.sendAndReceive( rule, FlowStoreMessageSubjects.GET_FLOW_ENTRY, SERIALIZER::encode, SERIALIZER::decode, master), FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null); }
@Override public IdBlock getIdBlock(String topic) { AtomicCounter counter = topicCounters.computeIfAbsent( topic, name -> storageService.atomicCounterBuilder().withName(name).build()); Long blockBase = Tools.retryable(counter::getAndAdd, StorageException.class, MAX_TRIES, RETRY_DELAY_MS) .apply(DEFAULT_BLOCK_SIZE); return new IdBlock(blockBase, DEFAULT_BLOCK_SIZE); }
@Modified private void modified(ComponentContext context) { Boolean boolEnabled = Tools.isPropertyEnabled(context.getProperties(), "enabled"); if (boolEnabled != null) { if (enabled && !boolEnabled) { enabled = false; disable(); } else if (!enabled && boolEnabled) { enabled = true; enable(); } } }
/** * Extracts properties from the component configuration context. * * @param context the component context */ private void readComponentConfiguration(ComponentContext context) { Dictionary<?, ?> properties = context.getProperties(); Boolean flag; flag = Tools.isPropertyEnabled(properties, "purgeOnDisconnection"); if (flag == null) { log.info( "PurgeOnDisconnection is not configured, " + "using current value of {}", purgeOnDisconnection); } else { purgeOnDisconnection = flag; log.info( "Configured. PurgeOnDisconnection is {}", purgeOnDisconnection ? "enabled" : "disabled"); } }
private void setRoutes(OpenstackRouter osRouter, Optional<Host> host) { Set<OpenstackSubnet> routableSubNets = routableSubNets(osRouter.id()); if (routableSubNets.size() < 2) { // no other subnet interface is connected to this router, do nothing return; } Set<String> routableSubNetIds = routableSubNets.stream().map(OpenstackSubnet::id).collect(Collectors.toSet()); Set<Host> hosts = host.isPresent() ? ImmutableSet.of(host.get()) : Tools.stream(hostService.getHosts()) .filter(h -> routableSubNetIds.contains(h.annotations().value(SUBNET_ID))) .collect(Collectors.toSet()); hosts.forEach(h -> populateRoutingRules(h, routableSubNets)); }
@Override public Set<FlowEntry> getPreviousFlowStatistic(ConnectPoint connectPoint) { final DeviceId deviceId = connectPoint.deviceId(); NodeId master = mastershipService.getMasterFor(deviceId); if (master == null) { log.warn("No master for {}", deviceId); return Collections.emptySet(); } if (Objects.equal(local, master)) { return getPreviousStatisticInternal(connectPoint); } else { return Tools.futureGetOrElse( clusterCommunicator.sendAndReceive( connectPoint, GET_PREVIOUS, SERIALIZER::encode, SERIALIZER::decode, master), STATISTIC_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, Collections.emptySet()); } }
@Override public CompletableFuture<Versioned<V>> computeIf( K key, Predicate<? super V> condition, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { checkNotNull(key, ERROR_NULL_KEY); checkNotNull(condition, "predicate function cannot be null"); checkNotNull(remappingFunction, "Remapping function cannot be null"); AtomicReference<MapEvent<K, V>> mapEvent = new AtomicReference<>(); return get(key) .thenCompose( r1 -> { V existingValue = r1 == null ? null : r1.value(); // if the condition evaluates to false, return existing value. if (!condition.test(existingValue)) { return CompletableFuture.completedFuture(r1); } AtomicReference<V> computedValue = new AtomicReference<>(); // if remappingFunction throws an exception, return the exception. try { computedValue.set(remappingFunction.apply(key, existingValue)); } catch (Exception e) { return Tools.exceptionalFuture(e); } // if the computed value is null, remove current value if one exists. // throw an exception if concurrent modification is detected. if (computedValue.get() == null) { if (r1 != null) { return remove(key, r1.version()) .thenApply( result -> { if (result) { mapEvent.set(new MapEvent<>(name, MapEvent.Type.REMOVE, key, r1)); return null; } else { throw new ConsistentMapException.ConcurrentModification(); } }); } else { return CompletableFuture.completedFuture(null); } } else { // replace current value; throw an exception if concurrent modification is detected if (r1 != null) { return replaceAndGet(key, r1.version(), computedValue.get()) .thenApply( v -> { if (v.isPresent()) { mapEvent.set( new MapEvent<>(name, MapEvent.Type.UPDATE, key, v.get())); return v.get(); } else { throw new ConsistentMapException.ConcurrentModification(); } }); } else { return putIfAbsentAndGet(key, computedValue.get()) .thenApply( result -> { if (!result.isPresent()) { throw new ConsistentMapException.ConcurrentModification(); } else { mapEvent.set( new MapEvent<>(name, MapEvent.Type.INSERT, key, result.get())); return result.get(); } }); } } }) .whenComplete((result, error) -> notifyListeners(mapEvent.get())); }