package org.opendaylight.unimgr.mef.nrp.ovs.util;
import com.google.common.collect.Sets;
-import org.opendaylight.unimgr.mef.nrp.common.ResourceNotAvailableException;
-import org.opendaylight.unimgr.mef.nrp.ovs.exception.VlanPoolExhaustedException;
-import org.opendaylight.unimgr.utils.NullAwareDatastoreGetter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import java.text.MessageFormat;
import java.util.HashSet;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.unimgr.mef.nrp.common.NrpDao;
+import org.opendaylight.unimgr.mef.nrp.common.ResourceNotAvailableException;
+import org.opendaylight.unimgr.mef.nrp.ovs.exception.VlanPoolExhaustedException;
+import org.opendaylight.yang.gen.v1.urn.mef.yang.mef.common.types.rev180321.PositiveInteger;
+import org.opendaylight.yang.gen.v1.urn.odl.unimgr.yang.unimgr.ext.rev170531.NodeSvmAugmentation;
+import org.opendaylight.yang.gen.v1.urn.odl.unimgr.yang.unimgr.ext.rev170531.NodeSvmAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.odl.unimgr.yang.unimgr.ext.rev170531.context.topology.node.ServiceVlanMap;
+import org.opendaylight.yang.gen.v1.urn.odl.unimgr.yang.unimgr.ext.rev170531.context.topology.node.ServiceVlanMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev180307.Uuid;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev180307.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev180307.topology.NodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Class responsible for generate Vlan ID or check if given Vlan ID is not used.
* @author marek.ryznar@amartus.com
*/
public class VlanUtils {
- private Set<Integer> usedVlans = new HashSet<>();
- private final static Set<Integer> possibleVlans = IntStream.range(1, 4094).boxed().collect(Collectors.toSet());
- private final static String VLAN_POOL_EXHAUSTED_ERROR_MESSAGE = "All VLAN IDs are in use. VLAN pool exhausted.";
+ private final Set<Integer> usedVlans = new HashSet<>();
+ private Node node;
+ private final DataBroker dataBroker;
+
+ private static final Set<Integer> POSSIBLE_VLANS = IntStream.range(1, 4094).boxed().collect(Collectors.toSet());
+ private static final String VLAN_POOL_EXHAUSTED_ERROR_MESSAGE = "All VLAN IDs are in use. VLAN pool exhausted.";
- private final static Logger LOG = LoggerFactory.getLogger(VlanUtils.class);
+ private static final Logger LOG = LoggerFactory.getLogger(VlanUtils.class);
- public VlanUtils(List<NullAwareDatastoreGetter<Node>> nodes) throws ResourceNotAvailableException {
- getAllVlanIDs(nodes);
+
+ public VlanUtils(DataBroker dataBroker, String nodeId) throws ResourceNotAvailableException {
+ this.dataBroker = dataBroker;
+ try {
+ node = new NrpDao(dataBroker.newReadOnlyTransaction()).getNode(new Uuid(nodeId));
+ if (node == null) {
+ throw new ResourceNotAvailableException(MessageFormat.format("Node {} not found", nodeId));
+ }
+ } catch (ReadFailedException e) {
+ LOG.warn("Node {} not found", nodeId);
+ throw new ResourceNotAvailableException(MessageFormat.format("Node {} not found", nodeId));
+ }
+
+ node.augmentation(NodeSvmAugmentation.class)
+ .getServiceVlanMap()
+ .forEach(serviceVlanMap -> usedVlans.add(serviceVlanMap.getVlanId().getValue().intValue()));
}
/**
- * Method return given vlan ID (if it is not used in OVS network) or generate new one.
+ * Method return vlan ID for service if stored in node property (service-vlan-map) or generate new one.
+ * @param serviceName service name
*/
- public Integer generateVlanID() throws ResourceNotAvailableException {
- return generateVid();
- }
-
- public boolean isVlanInUse(Integer vlanId) {
- return usedVlans.contains(vlanId);
+ public Integer getVlanID(String serviceName) throws ResourceNotAvailableException {
+ Optional<ServiceVlanMap> o = node.augmentation(NodeSvmAugmentation.class).getServiceVlanMap().stream()
+ .filter(serviceVlanMap -> serviceVlanMap.getServiceId().equals(serviceName))
+ .findFirst();
+ return o.isPresent() ? o.get().getVlanId().getValue().intValue() : generateVid(serviceName);
}
- private Integer generateVid() throws VlanPoolExhaustedException {
- Set<Integer> difference = Sets.difference(possibleVlans, usedVlans);
+ private Integer generateVid(String serviceName) throws VlanPoolExhaustedException {
+ Set<Integer> difference = Sets.difference(POSSIBLE_VLANS, usedVlans);
if (difference.isEmpty()) {
LOG.warn(VLAN_POOL_EXHAUSTED_ERROR_MESSAGE);
throw new VlanPoolExhaustedException(VLAN_POOL_EXHAUSTED_ERROR_MESSAGE);
}
- return difference.iterator().next();
- }
-
- private void getAllVlanIDs(List<NullAwareDatastoreGetter<Node>> nodes) throws ResourceNotAvailableException {
- for (NullAwareDatastoreGetter<Node> node : nodes) {
- if (node.get().isPresent()) {
- Table table = OpenFlowUtils.getTable(node.get().get());
- if (table != null && table.getFlow() != null) {
- for (Flow flow : table.getFlow()) {
- checkFlows(flow);
- }
- }
- }
- }
+ return updateNodeNewServiceVLAN(serviceName,difference.iterator().next());
}
- private void checkFlows(Flow flow) {
- getVlanFromActions(flow);
- Integer vid = getVlanFromMatch(flow.getMatch().getVlanMatch());
- if (vid != null && !usedVlans.contains(vid)) {
- usedVlans.add(vid);
- }
+ private Integer updateNodeNewServiceVLAN(String serviceName, Integer vlanId) {
+ List<ServiceVlanMap> list = node.augmentation(NodeSvmAugmentation.class).getServiceVlanMap();
+ list.add(new ServiceVlanMapBuilder()
+ .setServiceId(serviceName)
+ .setVlanId(PositiveInteger.getDefaultInstance(vlanId.toString())).build());
+ node = new NodeBuilder(node).addAugmentation(NodeSvmAugmentation.class,
+ new NodeSvmAugmentationBuilder().setServiceVlanMap(list).build()).build();
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ new NrpDao(tx).updateNode(node);
+ tx.submit();
+ return vlanId;
}
- private Integer getVlanFromMatch(VlanMatch vlanMatch) {
- if (vlanMatch != null &&
- vlanMatch.getVlanId() != null &&
- vlanMatch.getVlanId().getVlanId() != null)
- {
- return vlanMatch.getVlanId().getVlanId().getValue();
- }
- return null;
- }
-
- private void getVlanFromActions(Flow flow) {
- if (flow.getInstructions() != null &&
- !flow.getInstructions().getInstruction().isEmpty())
- {
- for (Instruction instruction : flow.getInstructions().getInstruction()) {
- ApplyActionsCase applyActionsCase = (ApplyActionsCase) instruction.getInstruction();
- ApplyActions applyActions = applyActionsCase.getApplyActions();
- List<Action> actions = applyActions.getAction();
- checkActions(actions);
- }
- }
- }
-
- private void checkActions(List<Action> actions) {
- for ( Action action:actions ) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action concreteAction = action.getAction();
- if ( concreteAction instanceof SetField ) {
- SetField setField = (SetField) concreteAction;
- if ( setField.getVlanMatch() != null ) {
- Integer vid = getVlanFromMatch(setField.getVlanMatch());
- if ( vid != null && !usedVlans.contains(vid)) {
- usedVlans.add(vid);
- }
- }
- }
- }
+ public void releaseServiceVlan(String serviceName) {
+ List<ServiceVlanMap> list = node.augmentation(NodeSvmAugmentation.class).getServiceVlanMap();
+ list.removeIf(serviceVlanMap -> serviceVlanMap.getServiceId().equals(serviceName));
+ node = new NodeBuilder(node).addAugmentation(NodeSvmAugmentation.class,
+ new NodeSvmAugmentationBuilder().setServiceVlanMap(list).build()).build();
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ new NrpDao(tx).updateNode(node);
+ tx.submit();
}
}