/* * 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.openstacknetworking.impl; import com.google.common.base.Strings; import com.google.common.collect.ImmutableSet; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Service; import org.onosproject.core.CoreService; import org.onosproject.event.ListenerRegistry; import org.onosproject.openstacknetworking.api.Constants; import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService; import org.onosproject.openstacknetworking.api.OpenstackRouterEvent; import org.onosproject.openstacknetworking.api.OpenstackRouterListener; import org.onosproject.openstacknetworking.api.OpenstackRouterService; import org.onosproject.openstacknetworking.api.OpenstackRouterStore; import org.onosproject.openstacknetworking.api.OpenstackRouterStoreDelegate; import org.openstack4j.model.network.NetFloatingIP; import org.openstack4j.model.network.Router; import org.openstack4j.model.network.RouterInterface; import org.slf4j.Logger; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; /** * Provides implementation of administering and interfacing OpenStack router and * floating IP address. */ @Service @Component(immediate = true) public class OpenstackRouterManager extends ListenerRegistry<OpenstackRouterEvent, OpenstackRouterListener> implements OpenstackRouterAdminService, OpenstackRouterService { protected final Logger log = getLogger(getClass()); private static final String MSG_ROUTER = "OpenStack router %s %s"; private static final String MSG_ROUTER_IFACE = "OpenStack router interface %s %s"; private static final String MSG_FLOATING_IP = "OpenStack floating IP %s %s"; private static final String MSG_CREATED = "created"; private static final String MSG_UPDATED = "updated"; private static final String MSG_REMOVED = "removed"; private static final String ERR_NULL_ROUTER = "OpenStack router cannot be null"; private static final String ERR_NULL_ROUTER_ID = "OpenStack router ID cannot be null"; private static final String ERR_NULL_ROUTER_NAME = "OpenStack router name cannot be null"; private static final String ERR_NULL_IFACE = "OpenStack router interface cannot be null"; private static final String ERR_NULL_IFACE_ROUTER_ID = "OpenStack router interface router ID cannot be null"; private static final String ERR_NULL_IFACE_PORT_ID = "OpenStack router interface port ID cannot be null"; private static final String ERR_NULL_FLOATING = "OpenStack floating IP cannot be null"; private static final String ERR_NULL_FLOATING_ID = "OpenStack floating IP cannot be null"; private static final String ERR_IN_USE = " still in use"; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected CoreService coreService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected OpenstackRouterStore osRouterStore; private final OpenstackRouterStoreDelegate delegate = new InternalRouterStoreDelegate(); @Activate protected void activate() { coreService.registerApplication(Constants.OPENSTACK_NETWORKING_APP_ID); osRouterStore.setDelegate(delegate); log.info("Started"); } @Deactivate protected void deactivate() { osRouterStore.unsetDelegate(delegate); log.info("Stopped"); } @Override public void createRouter(Router osRouter) { checkNotNull(osRouter, ERR_NULL_ROUTER); checkArgument(!Strings.isNullOrEmpty(osRouter.getId()), ERR_NULL_ROUTER_ID); checkArgument(!Strings.isNullOrEmpty(osRouter.getName()), ERR_NULL_ROUTER_NAME); osRouterStore.createRouter(osRouter); log.info(String.format(MSG_ROUTER, osRouter.getName(), MSG_CREATED)); } @Override public void updateRouter(Router osRouter) { checkNotNull(osRouter, ERR_NULL_ROUTER); checkArgument(!Strings.isNullOrEmpty(osRouter.getId()), ERR_NULL_ROUTER_ID); checkArgument(!Strings.isNullOrEmpty(osRouter.getName()), ERR_NULL_ROUTER_NAME); osRouterStore.updateRouter(osRouter); log.info(String.format(MSG_ROUTER, osRouter.getId(), MSG_UPDATED)); } @Override public void removeRouter(String routerId) { checkArgument(!Strings.isNullOrEmpty(routerId), ERR_NULL_ROUTER_ID); synchronized (this) { if (isRouterInUse(routerId)) { final String error = String.format(MSG_ROUTER, routerId, ERR_IN_USE); throw new IllegalStateException(error); } Router osRouter = osRouterStore.removeRouter(routerId); if (osRouter != null) { log.info(String.format(MSG_ROUTER, osRouter.getName(), MSG_REMOVED)); } } } @Override public void addRouterInterface(RouterInterface osIface) { checkNotNull(osIface, ERR_NULL_IFACE); checkArgument(!Strings.isNullOrEmpty(osIface.getId()), ERR_NULL_IFACE_ROUTER_ID); checkArgument(!Strings.isNullOrEmpty(osIface.getPortId()), ERR_NULL_IFACE_PORT_ID); osRouterStore.addRouterInterface(osIface); log.info(String.format(MSG_ROUTER_IFACE, osIface.getPortId(), MSG_CREATED)); } @Override public void updateRouterInterface(RouterInterface osIface) { checkNotNull(osIface, ERR_NULL_IFACE); checkArgument(!Strings.isNullOrEmpty(osIface.getId()), ERR_NULL_IFACE_ROUTER_ID); checkArgument(!Strings.isNullOrEmpty(osIface.getPortId()), ERR_NULL_IFACE_PORT_ID); osRouterStore.updateRouterInterface(osIface); log.info(String.format(MSG_ROUTER_IFACE, osIface.getPortId(), MSG_UPDATED)); } @Override public void removeRouterInterface(String osIfaceId) { checkArgument(!Strings.isNullOrEmpty(osIfaceId), ERR_NULL_IFACE_PORT_ID); synchronized (this) { if (isRouterIfaceInUse(osIfaceId)) { final String error = String.format(MSG_ROUTER, osIfaceId, ERR_IN_USE); throw new IllegalStateException(error); } RouterInterface osIface = osRouterStore.removeRouterInterface(osIfaceId); if (osIface != null) { log.info(String.format(MSG_ROUTER_IFACE, osIface.getPortId(), MSG_REMOVED)); } } } @Override public void createFloatingIp(NetFloatingIP osFloatingIp) { checkNotNull(osFloatingIp, ERR_NULL_FLOATING); checkArgument(!Strings.isNullOrEmpty(osFloatingIp.getId()), ERR_NULL_FLOATING_ID); osRouterStore.createFloatingIp(osFloatingIp); log.info(String.format(MSG_FLOATING_IP, osFloatingIp.getId(), MSG_CREATED)); } @Override public void updateFloatingIp(NetFloatingIP osFloatingIp) { checkNotNull(osFloatingIp, ERR_NULL_FLOATING); checkArgument(!Strings.isNullOrEmpty(osFloatingIp.getId()), ERR_NULL_FLOATING_ID); osRouterStore.updateFloatingIp(osFloatingIp); log.info(String.format(MSG_FLOATING_IP, osFloatingIp.getId(), MSG_UPDATED)); } @Override public void removeFloatingIp(String floatingIpId) { checkArgument(!Strings.isNullOrEmpty(floatingIpId), ERR_NULL_FLOATING_ID); synchronized (this) { if (isFloatingIpInUse(floatingIpId)) { final String error = String.format(MSG_FLOATING_IP, floatingIpId, ERR_IN_USE); throw new IllegalStateException(error); } NetFloatingIP osFloatingIp = osRouterStore.removeFloatingIp(floatingIpId); if (osFloatingIp != null) { log.info(String.format(MSG_FLOATING_IP, osFloatingIp.getId(), MSG_REMOVED)); } } } @Override public void clear() { osRouterStore.clear(); } @Override public Router router(String routerId) { checkArgument(!Strings.isNullOrEmpty(routerId), ERR_NULL_ROUTER_ID); return osRouterStore.router(routerId); } @Override public Set<Router> routers() { return osRouterStore.routers(); } @Override public RouterInterface routerInterface(String osIfaceId) { checkArgument(!Strings.isNullOrEmpty(osIfaceId), ERR_NULL_IFACE_PORT_ID); return osRouterStore.routerInterface(osIfaceId); } @Override public Set<RouterInterface> routerInterfaces() { return osRouterStore.routerInterfaces(); } @Override public Set<RouterInterface> routerInterfaces(String routerId) { Set<RouterInterface> osIfaces = osRouterStore.routerInterfaces().stream() .filter(iface -> Objects.equals(iface.getId(), routerId)) .collect(Collectors.toSet()); return ImmutableSet.copyOf(osIfaces); } @Override public NetFloatingIP floatingIp(String floatingIpId) { checkArgument(!Strings.isNullOrEmpty(floatingIpId), ERR_NULL_FLOATING_ID); return osRouterStore.floatingIp(floatingIpId); } @Override public Set<NetFloatingIP> floatingIps() { return osRouterStore.floatingIps(); } @Override public Set<NetFloatingIP> floatingIps(String routerId) { Set<NetFloatingIP> osFloatingIps = osRouterStore.floatingIps().stream() .filter(fip -> Objects.equals(fip.getRouterId(), routerId)) .collect(Collectors.toSet()); return ImmutableSet.copyOf(osFloatingIps); } private boolean isRouterInUse(String routerId) { // TODO add checking return false; } private boolean isRouterIfaceInUse(String osIfaceId) { // TODO add checking return false; } private boolean isFloatingIpInUse(String floatingIpId) { // TODO add checking return false; } private class InternalRouterStoreDelegate implements OpenstackRouterStoreDelegate { @Override public void notify(OpenstackRouterEvent event) { if (event != null) { log.trace("send oepnstack routing event {}", event); process(event); } } } }