Java tutorial
/* * Copyright 2017-present Open Networking Laboratory * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onosproject.routing; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import org.onosproject.incubator.net.intf.Interface; import org.onosproject.incubator.net.intf.InterfaceEvent; import org.onosproject.incubator.net.intf.InterfaceListener; import org.onosproject.incubator.net.intf.InterfaceService; import org.onosproject.net.DeviceId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Stream; import static com.google.common.base.Preconditions.checkNotNull; /** * Manages which interfaces are part of the router when the configuration is * updated, and handles the provisioning/unprovisioning of interfaces when they * are added/removed. */ public class RouterInterfaceManager { private final Logger log = LoggerFactory.getLogger(getClass()); private final Consumer<Interface> provisioner; private final Consumer<Interface> unprovisioner; private Set<String> configuredInterfaces = Collections.emptySet(); private Set<Interface> provisioned = new HashSet<>(); private InterfaceService interfaceService; private InterfaceListener listener = new InternalInterfaceListener(); private final DeviceId routerDeviceId; /** * Creates a new router interface manager. * * @param deviceId router device ID * @param configuredInterfaces names of interfaces configured for this router * @param interfaceService interface service * @param provisioner consumer that will provision new interfaces * @param unprovisioner consumer that will unprovision old interfaces */ public RouterInterfaceManager(DeviceId deviceId, Set<String> configuredInterfaces, InterfaceService interfaceService, Consumer<Interface> provisioner, Consumer<Interface> unprovisioner) { this.routerDeviceId = checkNotNull(deviceId); this.provisioner = checkNotNull(provisioner); this.unprovisioner = checkNotNull(unprovisioner); this.interfaceService = checkNotNull(interfaceService); this.configuredInterfaces = checkNotNull(configuredInterfaces); provision(); interfaceService.addListener(listener); } /** * Cleans up the router and unprovisions all interfaces. */ public void cleanup() { interfaceService.removeListener(listener); unprovision(); } /** * Retrieves the set of configured interface names. * * @return interface names */ public Set<String> configuredInterfaces() { return configuredInterfaces; } /** * Changes the set of interfaces configured on the router. * * @param newConfiguredInterfaces new set of router interfaces */ public void changeConfiguredInterfaces(Set<String> newConfiguredInterfaces) { Set<String> oldConfiguredInterfaces = configuredInterfaces; configuredInterfaces = ImmutableSet.copyOf(newConfiguredInterfaces); if (newConfiguredInterfaces.isEmpty() && !oldConfiguredInterfaces.isEmpty()) { // Reverted to using all interfaces. Provision interfaces that // weren't previously in the configured list getInterfacesForDevice(routerDeviceId).filter(intf -> !oldConfiguredInterfaces.contains(intf.name())) .forEach(this::provision); } else if (!newConfiguredInterfaces.isEmpty() && oldConfiguredInterfaces.isEmpty()) { // Began using an interface list. Unprovision interfaces that // are not in the new interface list. getInterfacesForDevice(routerDeviceId).filter(intf -> !newConfiguredInterfaces.contains(intf.name())) .forEach(this::unprovision); } else { // The existing interface list was changed. Set<String> toUnprovision = Sets.difference(oldConfiguredInterfaces, newConfiguredInterfaces); Set<String> toProvision = Sets.difference(newConfiguredInterfaces, oldConfiguredInterfaces); toUnprovision.forEach(name -> getInterfacesForDevice(routerDeviceId) .filter(intf -> intf.name().equals(name)).findFirst().ifPresent(this::unprovision)); toProvision.forEach(name -> getInterfacesForDevice(routerDeviceId) .filter(intf -> intf.name().equals(name)).findFirst().ifPresent(this::provision)); } configuredInterfaces = newConfiguredInterfaces; } private void provision() { getInterfacesForDevice(routerDeviceId).filter(this::shouldUse).forEach(this::provision); } private void unprovision() { getInterfacesForDevice(routerDeviceId).filter(this::shouldUse).forEach(this::unprovision); } private void provision(Interface intf) { if (!provisioned.contains(intf) && shouldUse(intf)) { log.info("Provisioning interface {}", intf); provisioner.accept(intf); provisioned.add(intf); } } private void unprovision(Interface intf) { if (provisioned.contains(intf)) { log.info("Unprovisioning interface {}", intf); unprovisioner.accept(intf); provisioned.remove(intf); } } private boolean shouldUse(Interface intf) { return configuredInterfaces.isEmpty() || configuredInterfaces.contains(intf.name()); } private Stream<Interface> getInterfacesForDevice(DeviceId deviceId) { return interfaceService.getInterfaces().stream() .filter(intf -> intf.connectPoint().deviceId().equals(deviceId)); } private class InternalInterfaceListener implements InterfaceListener { @Override public void event(InterfaceEvent event) { Interface intf = event.subject(); switch (event.type()) { case INTERFACE_ADDED: provision(intf); break; case INTERFACE_UPDATED: // TODO break; case INTERFACE_REMOVED: unprovision(intf); break; default: break; } } } }