blob: 242bdc8e97bf3ce3ae6ac9e5c885f91933363b9e [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* 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.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.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
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.
*/
@Component(immediate = true, service = { OpenstackRouterAdminService.class, OpenstackRouterService.class })
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)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
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 openstack routing event {}", event);
process(event);
}
}
}
}