+
+
+
+ private void reconciliationPreProcess(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+
+ List<InstanceIdentifier<StaleFlow>> staleFlowsToBeBulkDeleted = Lists.newArrayList();
+ List<InstanceIdentifier<StaleGroup>> staleGroupsToBeBulkDeleted = Lists.newArrayList();
+ List<InstanceIdentifier<StaleMeter>> staleMetersToBeBulkDeleted = Lists.newArrayList();
+
+
+ ReadOnlyTransaction trans = provider.getReadTranaction();
+ Optional<FlowCapableNode> flowNode = Optional.absent();
+
+ try {
+ flowNode = trans.read(LogicalDatastoreType.CONFIGURATION, nodeIdent).get();
+ }
+ catch (Exception e) {
+ LOG.error("Reconciliation Pre-Processing Fail with read Config/DS for Node {} !", nodeIdent, e);
+ }
+
+ if (flowNode.isPresent()) {
+
+ LOG.debug("Proceeding with deletion of stale-marked Flows on switch {} using Openflow interface",
+ nodeIdent.toString());
+ /* Stale-Flows - Stale-marked Flows have to be removed first for safety */
+ List<Table> tables = flowNode.get().getTable() != null
+ ? flowNode.get().getTable() : Collections.<Table> emptyList();
+ for (Table table : tables) {
+ final KeyedInstanceIdentifier<Table, TableKey> tableIdent =
+ nodeIdent.child(Table.class, table.getKey());
+ List<StaleFlow> staleFlows = table.getStaleFlow() != null ? table.getStaleFlow() : Collections.<StaleFlow> emptyList();
+ for (StaleFlow staleFlow : staleFlows) {
+
+ FlowBuilder flowBuilder = new FlowBuilder(staleFlow);
+ Flow toBeDeletedFlow = flowBuilder.setId(staleFlow.getId()).build();
+
+ final KeyedInstanceIdentifier<Flow, FlowKey> flowIdent =
+ tableIdent.child(Flow.class, toBeDeletedFlow.getKey());
+
+
+ this.provider.getFlowCommiter().remove(flowIdent, toBeDeletedFlow, nodeIdent);
+
+ staleFlowsToBeBulkDeleted.add(getStaleFlowInstanceIdentifier(staleFlow, nodeIdent));
+ }
+ }
+
+
+ LOG.debug("Proceeding with deletion of stale-marked Groups for switch {} using Openflow interface",
+ nodeIdent.toString());
+
+ // TODO: Should we collate the futures of RPC-calls to be sure that groups are Flows are fully deleted
+ // before attempting to delete groups - just in case there are references
+
+ /* Stale-marked Groups - Can be deleted after flows */
+ List<StaleGroup> staleGroups = flowNode.get().getStaleGroup() != null
+ ? flowNode.get().getStaleGroup() : Collections.<StaleGroup> emptyList();
+ for (StaleGroup staleGroup : staleGroups) {
+
+ GroupBuilder groupBuilder = new GroupBuilder(staleGroup);
+ Group toBeDeletedGroup = groupBuilder.setGroupId(staleGroup.getGroupId()).build();
+
+ final KeyedInstanceIdentifier<Group, GroupKey> groupIdent =
+ nodeIdent.child(Group.class, toBeDeletedGroup.getKey());
+
+ this.provider.getGroupCommiter().add(groupIdent, toBeDeletedGroup, nodeIdent);
+
+ staleGroupsToBeBulkDeleted.add(getStaleGroupInstanceIdentifier(staleGroup, nodeIdent));
+ }
+
+ LOG.debug("Proceeding with deletion of stale-marked Meters for switch {} using Openflow interface",
+ nodeIdent.toString());
+ /* Stale-marked Meters - can be deleted anytime - so least priority */
+ List<StaleMeter> staleMeters = flowNode.get().getStaleMeter() != null
+ ? flowNode.get().getStaleMeter() : Collections.<StaleMeter> emptyList();
+
+ for (StaleMeter staleMeter : staleMeters) {
+
+ MeterBuilder meterBuilder = new MeterBuilder(staleMeter);
+ Meter toBeDeletedMeter = meterBuilder.setMeterId(staleMeter.getMeterId()).build();
+
+ final KeyedInstanceIdentifier<Meter, MeterKey> meterIdent =
+ nodeIdent.child(Meter.class, toBeDeletedMeter.getKey());
+
+
+ this.provider.getMeterCommiter().add(meterIdent, toBeDeletedMeter, nodeIdent);
+
+ staleMetersToBeBulkDeleted.add(getStaleMeterInstanceIdentifier(staleMeter, nodeIdent));
+ }
+
+ }
+ /* clean transaction */
+ trans.close();
+
+ LOG.debug("Deleting all stale-marked flows/groups/meters of for switch {} in Configuration DS",
+ nodeIdent.toString());
+ // Now, do the bulk deletions
+ deleteDSStaleFlows(staleFlowsToBeBulkDeleted);
+ deleteDSStaleGroups(staleGroupsToBeBulkDeleted);
+ deleteDSStaleMeters(staleMetersToBeBulkDeleted);
+
+ }
+
+
+ private void deleteDSStaleFlows(List<InstanceIdentifier<StaleFlow>> flowsForBulkDelete){
+ ImmutableList.Builder<InstanceIdentifier<StaleFlow>> builder = ImmutableList.builder();
+ ImmutableList<InstanceIdentifier<StaleFlow>> bulkDelFlows = builder.addAll(flowsForBulkDelete.iterator()).build();
+
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+
+ for (InstanceIdentifier<StaleFlow> staleFlowIId : flowsForBulkDelete){
+ writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, staleFlowIId);
+ }
+
+ CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTransaction.submit();
+ handleStaleEntityDeletionResultFuture(submitFuture);
+ }
+
+ private void deleteDSStaleGroups(List<InstanceIdentifier<StaleGroup>> groupsForBulkDelete){
+ ImmutableList.Builder<InstanceIdentifier<StaleGroup>> builder = ImmutableList.builder();
+ ImmutableList<InstanceIdentifier<StaleGroup>> bulkDelGroups = builder.addAll(groupsForBulkDelete.iterator()).build();
+
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+
+ for (InstanceIdentifier<StaleGroup> staleGroupIId : groupsForBulkDelete){
+ writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, staleGroupIId);
+ }
+
+ CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTransaction.submit();
+ handleStaleEntityDeletionResultFuture(submitFuture);
+
+ }
+
+ private void deleteDSStaleMeters(List<InstanceIdentifier<StaleMeter>> metersForBulkDelete){
+ ImmutableList.Builder<InstanceIdentifier<StaleMeter>> builder = ImmutableList.builder();
+ ImmutableList<InstanceIdentifier<StaleMeter>> bulkDelGroups = builder.addAll(metersForBulkDelete.iterator()).build();
+
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+
+ for (InstanceIdentifier<StaleMeter> staleMeterIId : metersForBulkDelete){
+ writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, staleMeterIId);
+ }
+
+ CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTransaction.submit();
+ handleStaleEntityDeletionResultFuture(submitFuture);
+
+
+ }
+
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlow> getStaleFlowInstanceIdentifier(StaleFlow staleFlow, InstanceIdentifier<FlowCapableNode> nodeIdent) {
+ return nodeIdent
+ .child(Table.class, new TableKey(staleFlow.getTableId()))
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlow.class,
+ new StaleFlowKey(new FlowId(staleFlow.getId())));
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.StaleGroup> getStaleGroupInstanceIdentifier(StaleGroup staleGroup, InstanceIdentifier<FlowCapableNode> nodeIdent) {
+ return nodeIdent
+ .child(StaleGroup.class, new StaleGroupKey(new GroupId(staleGroup.getGroupId())));
+ }
+
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.StaleMeter> getStaleMeterInstanceIdentifier(StaleMeter staleMeter, InstanceIdentifier<FlowCapableNode> nodeIdent) {
+ return nodeIdent
+ .child(StaleMeter.class, new StaleMeterKey(new MeterId(staleMeter.getMeterId())));
+ }
+
+
+ private void handleStaleEntityDeletionResultFuture(CheckedFuture<Void, TransactionCommitFailedException> submitFuture) {
+ Futures.addCallback(submitFuture, new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(Void result) { LOG.debug("Stale entity removal success");
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ LOG.error("Stale entity removal failed {}", t);
+ }
+ });
+
+ }
+
+
+
+
+