package org.opennaas.extensions.router.capability.chassis;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opennaas.core.resources.ActivatorException;
import org.opennaas.core.resources.IResource;
import org.opennaas.core.resources.action.IAction;
import org.opennaas.core.resources.action.IActionSet;
import org.opennaas.core.resources.capability.AbstractCapability;
import org.opennaas.core.resources.capability.CapabilityException;
import org.opennaas.core.resources.descriptor.CapabilityDescriptor;
import org.opennaas.core.resources.descriptor.ResourceDescriptor;
import org.opennaas.core.resources.descriptor.ResourceDescriptorConstants;
import org.opennaas.extensions.queuemanager.IQueueManagerCapability;
import org.opennaas.extensions.router.model.ComputerSystem;
import org.opennaas.extensions.router.model.LogicalPort;
import org.opennaas.extensions.router.model.ManagedSystemElement.OperationalStatus;
import org.opennaas.extensions.router.model.NetworkPort;
import org.opennaas.extensions.router.model.ProtocolEndpoint;
import org.opennaas.extensions.router.model.ProtocolEndpoint.ProtocolIFType;
import org.opennaas.extensions.router.model.utils.ModelHelper;
import org.opennaas.extensions.router.model.wrappers.AddInterfacesToLogicalRouterRequest;
import org.opennaas.extensions.router.model.wrappers.RemoveInterfacesFromLogicalRouterRequest;
import org.opennaas.extensions.router.model.wrappers.SetEncapsulationLabelRequest;
import org.opennaas.extensions.router.model.wrappers.SetEncapsulationRequest;
public class ChassisCapability extends AbstractCapability implements IChassisCapability {
public static final String CAPABILITY_TYPE = "chassis";
Log log = LogFactory.getLog(ChassisCapability.class);
private String resourceId = "";
/**
* @param descriptor
* @param resourceId
*/
public ChassisCapability(CapabilityDescriptor descriptor, String resourceId) {
super(descriptor);
this.resourceId = resourceId;
log.debug("Built new Chassis Capability");
}
/*
* (non-Javadoc)
*
* @see org.opennaas.core.resources.caactivatepability.AbstractCapability#activate()
*/
@Override
public void activate() throws CapabilityException {
registerService(Activator.getContext(), CAPABILITY_TYPE, getResourceType(), getResourceName(), IChassisCapability.class.getName());
super.activate();
}
/*
* (non-Javadoc)
*
* @see org.opennaas.core.resources.capability.AbstractCapability#deactivate()
*/
@Override
public void deactivate() throws CapabilityException {
registration.unregister();
super.deactivate();
}
/*
* (non-Javadoc)
*
* @see org.opennaas.core.resources.capability.ICapability#getCapabilityName()
*/
@Override
public String getCapabilityName() {
return CAPABILITY_TYPE;
}
/*
* (non-Javadoc)
*
* @see org.opennaas.core.resources.capability.AbstractCapability#getActionSet()
*/
@Override
// TODO MOVE TO A PARENT
public IActionSet getActionSet() throws CapabilityException {
String name = this.descriptor.getPropertyValue(ResourceDescriptorConstants.ACTION_NAME);
String version = this.descriptor.getPropertyValue(ResourceDescriptorConstants.ACTION_VERSION);
try {
// TODO do not use Activator for this, use injection instead
return Activator.getChassisActionSetService(name, version);
} catch (ActivatorException e) {
throw new CapabilityException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.opennaas.core.resources.capability.AbstractCapability#queueAction(org.opennaas.core.resources.action.IAction)
*/
@Override
public void queueAction(IAction action) throws CapabilityException {
getQueueManager(resourceId).queueAction(action);
}
/**
*
* @return QueuemanagerService this capability is associated to.
* @throws CapabilityException
* if desired queueManagerService could not be retrieved.
*/
private IQueueManagerCapability getQueueManager(String resourceId) throws CapabilityException {
try {
return Activator.getQueueManagerService(resourceId);
} catch (ActivatorException e) {
throw new CapabilityException("Failed to get QueueManagerService for resource " + resourceId, e);
}
}
/*
* IChassisService Implementation
*/
/*
* (non-Javadoc)
*
* @see org.opennaas.extensions.router.capability.chassis.IChassisCapability#upPhysicalInterface(org.opennaas.extensions.router.model.LogicalPort)
*/
@Override
public void upPhysicalInterface(LogicalPort iface) throws CapabilityException {
log.info("Start of upPhysicalInterface call");
iface.setOperationalStatus(OperationalStatus.OK);
IAction action = createActionAndCheckParams(ChassisActionSet.CONFIGURESTATUS, iface);
queueAction(action);
log.info("End of upPhysicalInterface call");
}
/*
* (non-Javadoc)
*
* @see
* org.opennaas.extensions.router.capability.chassis.IChassisCapability#downPhysicalInterface(org.opennaas.extensions.router.model.LogicalPort)
*/
@Override
public void downPhysicalInterface(LogicalPort iface) throws CapabilityException {
log.info("Start of downPhysicalInterface call");
iface.setOperationalStatus(OperationalStatus.STOPPED);
IAction action = createActionAndCheckParams(ChassisActionSet.CONFIGURESTATUS, iface);
queueAction(action);
log.info("End of downPhysicalInterface call");
}
/*
* (non-Javadoc)
*
* @see org.opennaas.extensions.router.capability.chassis.IChassisCapability#createSubInterface(org.opennaas.extensions.router.model.NetworkPort)
*/
@Override
public void createSubInterface(NetworkPort iface) throws CapabilityException {
log.info("Start of createSubInterface call");
IAction action = createActionAndCheckParams(ChassisActionSet.CONFIGURESUBINTERFACE, iface);
queueAction(action);
log.info("End of createSubInterface call");
}
/*
* (non-Javadoc)
*
* @see org.opennaas.extensions.router.capability.chassis.IChassisCapability#deleteSubInterface(org.opennaas.extensions.router.model.NetworkPort)
*/
@Override
public void deleteSubInterface(NetworkPort iface) throws CapabilityException {
log.info("Start of deleteSubInterface call");
IAction action = createActionAndCheckParams(ChassisActionSet.DELETESUBINTERFACE, iface);
queueAction(action);
log.info("End of deleteSubInterface call");
}
/*
* (non-Javadoc)
*
* @see org.opennaas.extensions.router.capability.chassis.IChassisCapability#setEncapsulation(org.opennaas.extensions.router.model.wrappers.
* SetEncapsulationRequest)
*/
@Override
public void setEncapsulation(SetEncapsulationRequest request) throws CapabilityException {
setEncapsulation(request.getIface(), request.getEncapsulation());
}
/*
* (non-Javadoc)
*
* @see org.opennaas.extensions.router.capability.chassis.IChassisCapability#setEncapsulation(org.opennaas.extensions.router.model.LogicalPort,
* org.opennaas.extensions.router.model.ProtocolEndpoint.ProtocolIFType)
*/
@Override
public void setEncapsulation(LogicalPort iface, ProtocolIFType encapsulationType) throws CapabilityException {
log.info("Start of setEncapsulation call");
if (!encapsulationType.equals(ProtocolIFType.UNKNOWN)) {
ProtocolEndpoint encapsulationEndpoint = new ProtocolEndpoint();
encapsulationEndpoint.setProtocolIFType(encapsulationType);
iface.addProtocolEndpoint(encapsulationEndpoint);
}
removeCurrentEncapsulation(iface);
setDesiredEncapsulation(iface);
log.info("End of setEncapsulation call");
}
/*
* (non-Javadoc)
*
* @see org.opennaas.extensions.router.capability.chassis.IChassisCapability#setEncapsulationLabel(org.opennaas.extensions.router.model.wrappers.
* SetEncapsulationLabelRequest)
*/
@Override
public void setEncapsulationLabel(SetEncapsulationLabelRequest request) throws CapabilityException {
setEncapsulationLabel(request.getIface(), request.getEncapsulationLabel());
}
/*
* (non-Javadoc)
*
* @see
* org.opennaas.extensions.router.capability.chassis.IChassisCapability#setEncapsulationLabel(org.opennaas.extensions.router.model.LogicalPort,
* java.lang.String)
*/
@Override
public void setEncapsulationLabel(LogicalPort iface, String encapsulationLabel) throws CapabilityException {
log.info("Start of setEncapsulationLabel call");
// specify label in iface
// we use the name of the endpoint to store the encapsulation label
// and mark protocolType as unknown (it will be discovered by opennaas)
ProtocolEndpoint protocolEndpoint = new ProtocolEndpoint();
protocolEndpoint.setName(encapsulationLabel);
protocolEndpoint.setProtocolIFType(ProtocolIFType.UNKNOWN);
iface.addProtocolEndpoint(protocolEndpoint);
// FIXME it assumes there is only TAGGED_ETHERNET and NO encapsulation
IAction action = createActionAndCheckParams(ChassisActionSet.SET_VLANID, iface);
queueAction(action);
log.info("End of setEncapsulationLabel call");
}
/*
* (non-Javadoc)
*
* @see
* org.opennaas.extensions.router.capability.chassis.IChassisCapability#createLogicalRouter(org.opennaas.extensions.router.model.ComputerSystem)
*/
@Override
public void createLogicalRouter(ComputerSystem logicalRouter) throws CapabilityException {
log.info("Start of createLogicalRouter call");
if (isVirtual(resource)) {
throw new CapabilityException("UnsupportedOperation: Cannot create logical routers from a logical router");
}
IAction action = createActionAndCheckParams(ChassisActionSet.CREATELOGICALROUTER, logicalRouter);
queueAction(action);
List<LogicalPort> interfaces = new ArrayList<LogicalPort>();
interfaces.addAll(ModelHelper.getInterfaces(logicalRouter));
addInterfacesToLogicalRouter(logicalRouter, interfaces);
log.info("End of createLogicalRouter call");
}
/*
* (non-Javadoc)
*
* @see
* org.opennaas.extensions.router.capability.chassis.IChassisCapability#deleteLogicalRouter(org.opennaas.extensions.router.model.ComputerSystem)
*/
@Override
public void deleteLogicalRouter(ComputerSystem logicalRouter) throws CapabilityException {
log.info("Start of deleteLogicalRouter call");
if (isVirtual(resource)) {
throw new CapabilityException("UnsupportedOperation: Cannot delete logical routers from a logical router");
}
// By default, interfaces are not transfered back to the physical router.
// Instead, their configuration is lost. If the user wants to maintain them,
// it can be done launching removeInterfacesFromLogicalRouter(desiredInterfaces) before deleting it.
// List<LogicalPort> interfaces = new ArrayList<LogicalPort>();
// interfaces.addAll(ModelHelper.getInterfaces(logicalRouter));
// removeInterfacesFromLogicalRouter(logicalRouter, interfaces);
IAction action = createActionAndCheckParams(ChassisActionSet.DELETELOGICALROUTER, logicalRouter);
queueAction(action);
log.info("E of deleteLogicalRouter call");
}
/*
* (non-Javadoc)
*
* @see
* org.opennaas.extensions.router.capability.chassis.IChassisCapability#addInterfacesToLogicalRouter(org.opennaas.extensions.router.model.wrappers
* .AddInterfacesToLogicalRouterRequest)
*/
@Override
public void addInterfacesToLogicalRouter(AddInterfacesToLogicalRouterRequest request) throws CapabilityException {
addInterfacesToLogicalRouter(request.getLogicalRouter(), request.getInterfaces());
}
/*
* (non-Javadoc)
*
* @see org.opennaas.extensions.router.capability.chassis.IChassisCapability#addInterfacesToLogicalRouter(org.opennaas.extensions.router.model.
* ComputerSystem, java.util.List)
*/
@Override
public void addInterfacesToLogicalRouter(ComputerSystem logicalRouter, List<LogicalPort> interfaces) throws CapabilityException {
log.info("Start of addInterfacesToLogicalRouter call");
if (isVirtual(resource)) {
throw new CapabilityException("UnsupportedOperation: Cannot interact with logical routers from a logical router");
}
IAction action;
ComputerSystem logicalRouterStub;
for (LogicalPort interfaceToAdd : interfaces) {
logicalRouterStub = new ComputerSystem();
logicalRouterStub.setName(logicalRouter.getName());
logicalRouterStub.setElementName(logicalRouter.getElementName());
logicalRouterStub.addLogicalDevice(interfaceToAdd);
action = createActionAndCheckParams(ChassisActionSet.ADDINTERFACETOLOGICALROUTER, logicalRouterStub);
queueAction(action);
}
log.info("End of addInterfacesToLogicalRouter call");
}
/*
* (non-Javadoc)
*
* @see
* org.opennaas.extensions.router.capability.chassis.IChassisCapability#removeInterfacesFromLogicalRouter(org.opennaas.extensions.router.model
* .wrappers.RemoveInterfacesFromLogicalRouterRequest)
*/
@Override
public void removeInterfacesFromLogicalRouter(RemoveInterfacesFromLogicalRouterRequest request) throws CapabilityException {
removeInterfacesFromLogicalRouter(request.getLogicalRouter(), request.getInterfaces());
}
/*
* (non-Javadoc)
*
* @see
* org.opennaas.extensions.router.capability.chassis.IChassisCapability#removeInterfacesFromLogicalRouter(org.opennaas.extensions.router.model
* .ComputerSystem, java.util.List)
*/
@Override
public void removeInterfacesFromLogicalRouter(ComputerSystem logicalRouter, List<LogicalPort> interfaces) throws CapabilityException {
log.info("Start of removeInterfacesFromLogicalRouter call");
if (isVirtual(resource)) {
throw new CapabilityException("UnsupportedOperation: Cannot interact with logical routers from a logical router");
}
IAction action;
ComputerSystem logicalRouterStub;
for (LogicalPort interfaceToAdd : interfaces) {
logicalRouterStub = new ComputerSystem();
logicalRouterStub.setName(logicalRouter.getName());
logicalRouterStub.setElementName(logicalRouter.getElementName());
logicalRouterStub.addLogicalDevice(interfaceToAdd);
action = createActionAndCheckParams(ChassisActionSet.REMOVEINTERFACEFROMLOGICALROUTER, logicalRouterStub);
queueAction(action);
}
log.info("End of removeInterfacesFromLogicalRouter call");
}
/**
* @param port
* @return
*/
private boolean requiresTaggedEthernetEncapsulation(LogicalPort port) {
boolean hasTaggedEthernetEndpoint = false;
for (ProtocolEndpoint endpoint : port.getProtocolEndpoint()) {
if (endpoint.getProtocolIFType().equals(ProtocolIFType.LAYER_2_VLAN_USING_802_1Q)) {
hasTaggedEthernetEndpoint = true;
break;
}
}
return hasTaggedEthernetEndpoint;
}
/**
* @param port
* @return
*/
private boolean requiresNoEncapsulation(LogicalPort port) {
return port.getProtocolEndpoint().isEmpty();
}
/**
* @param port
* @throws CapabilityException
*/
private void removeCurrentEncapsulation(LogicalPort port) throws CapabilityException {
// FIXME it assumes there is only TAGGED_ETHERNET and NO encapsulation
if (requiresTaggedEthernetEncapsulation(port)) {
// nothing to remove, as current can only be no encapsulation or required one
} else {
// it is save to remove TAGGED_ETHERNET, as current can only be tagged or none
// and removing when it does not exists does not fail
IAction action = createActionAndCheckParams(ChassisActionSet.REMOVE_TAGGEDETHERNET_ENCAPSULATION, port);
queueAction(action);
}
}
/**
* @param port
* @throws CapabilityException
*/
private void setDesiredEncapsulation(LogicalPort port) throws CapabilityException {
if (requiresNoEncapsulation(port)) {
// nothing to set
} else {
if (requiresTaggedEthernetEncapsulation(port)) {
IAction action = createActionAndCheckParams(ChassisActionSet.SET_TAGGEDETHERNET_ENCAPSULATION, port);
queueAction(action);
} else {
throw new CapabilityException("Unsupported encapsulation type");
}
}
}
private boolean isVirtual(IResource resource) {
return resource.getResourceDescriptor().getProperties() != null &&
resource.getResourceDescriptor().getProperties().get(ResourceDescriptor.VIRTUAL) != null &&
resource.getResourceDescriptor().getProperties().get(ResourceDescriptor.VIRTUAL).equals("true");
}
}