Search in sources :

Example 6 with TransactionRequired

use of org.openkilda.persistence.tx.TransactionRequired in project open-kilda by telstra.

the class MirrorGroupIdPool method allocate.

/**
 * Allocates a group id for the flow path.
 */
@TransactionRequired
public MirrorGroup allocate(SwitchId switchId, String flowId, PathId pathId, MirrorGroupType type, MirrorDirection direction) {
    GroupId nextGroupId = nextGroupIds.get(switchId);
    if (nextGroupId != null && nextGroupId.getValue() > 0) {
        if (nextGroupId.compareTo(maxGroupId) <= 0 && !mirrorGroupRepository.exists(switchId, nextGroupId)) {
            MirrorGroup mirrorGroup = addMirrorGroup(flowId, pathId, switchId, nextGroupId, type, direction);
            nextGroupIds.put(switchId, new GroupId(nextGroupId.getValue() + 1));
            return mirrorGroup;
        } else {
            nextGroupIds.remove(switchId);
        }
    }
    // The pool requires (re-)initialization.
    if (!nextGroupIds.containsKey(switchId)) {
        long numOfPools = (maxGroupId.getValue() - minGroupId.getValue()) / poolSize;
        if (numOfPools > 1) {
            long poolToTake = Math.abs(new Random().nextInt()) % numOfPools;
            Optional<GroupId> availableGroupId = mirrorGroupRepository.findFirstUnassignedGroupId(switchId, new GroupId(minGroupId.getValue() + poolToTake * poolSize), new GroupId(minGroupId.getValue() + (poolToTake + 1) * poolSize - 1));
            if (availableGroupId.isPresent()) {
                nextGroupId = availableGroupId.get();
                MirrorGroup mirrorGroup = addMirrorGroup(flowId, pathId, switchId, nextGroupId, type, direction);
                nextGroupIds.put(switchId, new GroupId(nextGroupId.getValue() + 1));
                return mirrorGroup;
            }
        }
        // The pool requires full scan.
        nextGroupId = new GroupId(-1);
        nextGroupIds.put(switchId, nextGroupId);
    }
    if (nextGroupId != null && nextGroupId.getValue() == -1) {
        Optional<GroupId> availableMeter = mirrorGroupRepository.findFirstUnassignedGroupId(switchId, minGroupId, maxGroupId);
        if (availableMeter.isPresent()) {
            nextGroupId = availableMeter.get();
            MirrorGroup mirrorGroup = addMirrorGroup(flowId, pathId, switchId, nextGroupId, type, direction);
            nextGroupIds.put(switchId, new GroupId(nextGroupId.getValue() + 1));
            return mirrorGroup;
        }
    }
    throw new ResourceNotAvailableException(format("No group id available for switch %s", switchId));
}
Also used : MirrorGroup(org.openkilda.model.MirrorGroup) Random(java.util.Random) GroupId(org.openkilda.model.GroupId) TransactionRequired(org.openkilda.persistence.tx.TransactionRequired)

Aggregations

TransactionRequired (org.openkilda.persistence.tx.TransactionRequired)6 Random (java.util.Random)5 ResourceNotAvailableException (org.openkilda.wfm.share.flow.resources.ResourceNotAvailableException)2 String.format (java.lang.String.format)1 Comparator (java.util.Comparator)1 List (java.util.List)1 Optional (java.util.Optional)1 Collectors (java.util.stream.Collectors)1 FlowPath (org.openkilda.model.FlowPath)1 GroupId (org.openkilda.model.GroupId)1 MeterId (org.openkilda.model.MeterId)1 MirrorGroup (org.openkilda.model.MirrorGroup)1 PathId (org.openkilda.model.PathId)1 PathSegment (org.openkilda.model.PathSegment)1 PathSegmentData (org.openkilda.model.PathSegment.PathSegmentData)1 PersistenceException (org.openkilda.persistence.exceptions.PersistenceException)1 FermaPersistentImplementation (org.openkilda.persistence.ferma.FermaPersistentImplementation)1 PathSegmentFrame (org.openkilda.persistence.ferma.frames.PathSegmentFrame)1 PathIdConverter (org.openkilda.persistence.ferma.frames.converters.PathIdConverter)1 IslRepository (org.openkilda.persistence.repositories.IslRepository)1