Search in sources :

Example 31 with FlowCapableNode

use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode in project openflowplugin by opendaylight.

the class SyncPlanPushStrategyIncrementalImpl method flushAddGroupPortionAndBarrier.

private ListenableFuture<RpcResult<Void>> flushAddGroupPortionAndBarrier(final InstanceIdentifier<FlowCapableNode> nodeIdent, final ItemSyncBox<Group> groupsPortion) {
    final List<ListenableFuture<RpcResult<AddGroupOutput>>> allResults = new ArrayList<>();
    final List<ListenableFuture<RpcResult<UpdateGroupOutput>>> allUpdateResults = new ArrayList<>();
    for (Group group : groupsPortion.getItemsToPush()) {
        final KeyedInstanceIdentifier<Group, GroupKey> groupIdent = nodeIdent.child(Group.class, group.getKey());
        allResults.add(JdkFutureAdapters.listenInPoolThread(groupForwarder.add(groupIdent, group, nodeIdent)));
    }
    for (ItemSyncBox.ItemUpdateTuple<Group> groupTuple : groupsPortion.getItemsToUpdate()) {
        final Group existingGroup = groupTuple.getOriginal();
        final Group group = groupTuple.getUpdated();
        final KeyedInstanceIdentifier<Group, GroupKey> groupIdent = nodeIdent.child(Group.class, group.getKey());
        allUpdateResults.add(JdkFutureAdapters.listenInPoolThread(groupForwarder.update(groupIdent, existingGroup, group, nodeIdent)));
    }
    final ListenableFuture<RpcResult<Void>> singleVoidAddResult = Futures.transform(Futures.allAsList(allResults), ReconcileUtil.<AddGroupOutput>createRpcResultCondenser("group add"), MoreExecutors.directExecutor());
    final ListenableFuture<RpcResult<Void>> singleVoidUpdateResult = Futures.transform(Futures.allAsList(allUpdateResults), ReconcileUtil.<UpdateGroupOutput>createRpcResultCondenser("group update"), MoreExecutors.directExecutor());
    final ListenableFuture<RpcResult<Void>> summaryResult = Futures.transform(Futures.allAsList(singleVoidAddResult, singleVoidUpdateResult), ReconcileUtil.<Void>createRpcResultCondenser("group add/update"), MoreExecutors.directExecutor());
    return Futures.transformAsync(summaryResult, ReconcileUtil.chainBarrierFlush(PathUtil.digNodePath(nodeIdent), transactionService), MoreExecutors.directExecutor());
}
Also used : Group(org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group) UpdateGroupOutput(org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput) ItemSyncBox(org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox) ArrayList(java.util.ArrayList) GroupKey(org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey) RpcResult(org.opendaylight.yangtools.yang.common.RpcResult) AddGroupOutput(org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput) ListenableFuture(com.google.common.util.concurrent.ListenableFuture)

Example 32 with FlowCapableNode

use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode in project openflowplugin by opendaylight.

the class SimplifiedConfigListener method processNodeModification.

/**
 * Update cache. If operational data are present, choose appropriate data and start syncup.
 * Otherwise skip incoming change.
 */
@Override
protected Optional<ListenableFuture<Boolean>> processNodeModification(final DataTreeModification<FlowCapableNode> modification) {
    final InstanceIdentifier<FlowCapableNode> nodePath = modification.getRootPath().getRootIdentifier();
    final NodeId nodeId = PathUtil.digNodeId(nodePath);
    configSnapshot.updateCache(nodeId, Optional.fromNullable(modification.getRootNode().getDataAfter()));
    final Optional<FlowCapableNode> operationalNode = operationalDao.loadByNodeId(nodeId);
    if (!operationalNode.isPresent()) {
        LOG.debug("Skip syncup, {} operational is not present", nodeId.getValue());
        return Optional.absent();
    }
    final DataObjectModification<FlowCapableNode> configModification = modification.getRootNode();
    final FlowCapableNode dataBefore = configModification.getDataBefore();
    final FlowCapableNode dataAfter = configModification.getDataAfter();
    final ListenableFuture<Boolean> endResult;
    if (dataBefore == null && dataAfter != null) {
        endResult = onNodeAdded(nodePath, dataAfter, operationalNode.get());
    } else if (dataBefore != null && dataAfter == null) {
        endResult = onNodeDeleted(nodePath, dataBefore);
    } else {
        endResult = onNodeUpdated(nodePath, dataBefore, dataAfter);
    }
    return Optional.of(endResult);
}
Also used : FlowCapableNode(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode) NodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId)

Example 33 with FlowCapableNode

use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode in project openflowplugin by opendaylight.

the class SimplifiedOperationalListener method reconciliation.

/**
 * If node is present in config DS diff between wanted configuration (in config DS) and actual device
 * configuration (coming from operational) should be calculated and sent to device.
 * @param modification from DS
 * @return optional syncup future
 */
private Optional<ListenableFuture<Boolean>> reconciliation(final DataTreeModification<Node> modification) {
    final NodeId nodeId = ModificationUtil.nodeId(modification);
    final Optional<FlowCapableNode> nodeConfiguration = configDao.loadByNodeId(nodeId);
    if (nodeConfiguration.isPresent()) {
        LOG.debug("Reconciliation {}: {}", dsType(), nodeId.getValue());
        final InstanceIdentifier<FlowCapableNode> nodePath = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(ModificationUtil.nodeId(modification))).augmentation(FlowCapableNode.class);
        final FlowCapableNode fcOperationalNode = ModificationUtil.flowCapableNodeAfter(modification);
        final SyncupEntry syncupEntry = new SyncupEntry(nodeConfiguration.get(), LogicalDatastoreType.CONFIGURATION, fcOperationalNode, dsType());
        return Optional.of(reactor.syncup(nodePath, syncupEntry));
    } else {
        LOG.debug("Config not present for reconciliation: {}", nodeId.getValue());
        reconciliationRegistry.unregisterIfRegistered(nodeId);
        return skipModification(modification);
    }
}
Also used : FlowCapableNode(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode) FlowCapableNode(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode) Node(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node) NodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId) SyncupEntry(org.opendaylight.openflowplugin.applications.frsync.util.SyncupEntry) NodeKey(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey)

Example 34 with FlowCapableNode

use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode in project openflowplugin by opendaylight.

the class SyncReactorGuardDecorator method syncup.

@Override
public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> flowcapableNodePath, final SyncupEntry syncupEntry) {
    final NodeId nodeId = PathUtil.digNodeId(flowcapableNodePath);
    final long stampBeforeGuard = System.nanoTime();
    final Semaphore guard = semaphoreKeeper.summonGuardAndAcquire(flowcapableNodePath);
    if (Objects.isNull(guard)) {
        return Futures.immediateFuture(Boolean.FALSE);
    }
    final long stampAfterGuard = System.nanoTime();
    if (LOG.isDebugEnabled()) {
        LOG.debug("Syncup guard acquired and running for {} ", nodeId.getValue());
    }
    final ListenableFuture<Boolean> endResult = delegate.syncup(flowcapableNodePath, syncupEntry);
    Futures.addCallback(endResult, createSyncupCallback(guard, stampBeforeGuard, stampAfterGuard, nodeId), MoreExecutors.directExecutor());
    return endResult;
}
Also used : NodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId) Semaphore(java.util.concurrent.Semaphore)

Example 35 with FlowCapableNode

use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode in project openflowplugin by opendaylight.

the class SyncReactorImpl method syncup.

@Override
public ListenableFuture<Boolean> syncup(final InstanceIdentifier<FlowCapableNode> nodeIdent, final SyncupEntry syncupEntry) {
    final NodeId nodeId = PathUtil.digNodeId(nodeIdent);
    FlowCapableNode configTree = syncupEntry.getAfter();
    FlowCapableNode operationalTree = syncupEntry.getBefore();
    final SyncCrudCounters counters = new SyncCrudCounters();
    /**
     * instructions:
     *  - extract diff changes and prepare change steps in safe order
     *    - optimization: decide if updates needed
     *  - execute chosen implementation (e.g. conventional API, bulk API, flat bulk API)
     *  - recommended order follows:
     * reconciliation strategy - phase 1: - add/update missing objects in following order:
     *  - table features - groups (reordered) - meters - flows
     * reconciliation strategy - phase 2: - remove redundant objects in following order:
     *  - flows - meters - groups (reordered)
     */
    final List<ItemSyncBox<Group>> groupsToAddOrUpdate = extractGroupsToAddOrUpdate(nodeId, configTree, operationalTree);
    final ItemSyncBox<Meter> metersToAddOrUpdate = extractMetersToAddOrUpdate(nodeId, configTree, operationalTree);
    final Map<TableKey, ItemSyncBox<Flow>> flowsToAddOrUpdate = extractFlowsToAddOrUpdate(nodeId, configTree, operationalTree);
    final Map<TableKey, ItemSyncBox<Flow>> flowsToRemove = extractFlowsToRemove(nodeId, configTree, operationalTree);
    final ItemSyncBox<Meter> metersToRemove = extractMetersToRemove(nodeId, configTree, operationalTree);
    final List<ItemSyncBox<Group>> groupsToRemove = extractGroupsToRemove(nodeId, configTree, operationalTree);
    final SynchronizationDiffInput input = new SynchronizationDiffInput(nodeIdent, groupsToAddOrUpdate, metersToAddOrUpdate, flowsToAddOrUpdate, flowsToRemove, metersToRemove, groupsToRemove);
    final ListenableFuture<RpcResult<Void>> bootstrapResultFuture = RpcResultBuilder.<Void>success().buildFuture();
    final ListenableFuture<RpcResult<Void>> resultVehicle = syncPlanPushStrategy.executeSyncStrategy(bootstrapResultFuture, input, counters);
    return Futures.transform(resultVehicle, input1 -> {
        if (input1 == null) {
            return false;
        }
        if (LOG.isDebugEnabled()) {
            final CrudCounts flowCrudCounts = counters.getFlowCrudCounts();
            final CrudCounts meterCrudCounts = counters.getMeterCrudCounts();
            final CrudCounts groupCrudCounts = counters.getGroupCrudCounts();
            LOG.debug("Syncup outcome[{}] (added/updated/removed): flow={}/{}/{}, group={}/{}/{}, " + "meter={}/{}/{}, errors={}", nodeId.getValue(), flowCrudCounts.getAdded(), flowCrudCounts.getUpdated(), flowCrudCounts.getRemoved(), groupCrudCounts.getAdded(), groupCrudCounts.getUpdated(), groupCrudCounts.getRemoved(), meterCrudCounts.getAdded(), meterCrudCounts.getUpdated(), meterCrudCounts.getRemoved(), Arrays.toString(input1.getErrors().toArray()));
        }
        return input1.isSuccessful();
    }, MoreExecutors.directExecutor());
}
Also used : ItemSyncBox(org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox) Meter(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter) FlowCapableNode(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode) RpcResult(org.opendaylight.yangtools.yang.common.RpcResult) TableKey(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey) CrudCounts(org.opendaylight.openflowplugin.applications.frsync.util.CrudCounts) NodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId) SyncCrudCounters(org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters) SynchronizationDiffInput(org.opendaylight.openflowplugin.applications.frsync.impl.strategy.SynchronizationDiffInput)

Aggregations

FlowCapableNode (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode)48 NodeRef (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef)29 RpcResult (org.opendaylight.yangtools.yang.common.RpcResult)26 Node (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node)22 TableKey (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey)20 ArrayList (java.util.ArrayList)17 Table (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table)15 Flow (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow)15 Group (org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group)15 NodeKey (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey)15 Test (org.junit.Test)14 ReadOnlyTransaction (org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction)14 Uri (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri)13 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)11 Meter (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter)11 NodeId (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId)10 FlowKey (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey)9 GroupKey (org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey)9 CrudCounts (org.opendaylight.openflowplugin.applications.frsync.util.CrudCounts)8 FlowCapableNodeBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder)8