private void processBridgeDeletion(
      AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {

    for (InstanceIdentifier<?> removedBridge : changes.getRemovedPaths()) {
      if (removedBridge.getTargetType().equals(OvsdbBridgeAugmentation.class)) {
        Node bridgeParentNode = getNode(changes.getOriginalData(), removedBridge);
        if (bridgeParentNode == null) {
          // Throwing this warning to catch the behavior change of southbound plugin.
          LOG.warn(
              "Bridge's {} parent node details are not present in original data"
                  + ", it should not happen",
              removedBridge);
          continue;
        }
        // Fetch data of removed bridge from original data
        @SuppressWarnings("unchecked")
        OvsdbBridgeAugmentation removedBridgeAugmentationData =
            getDataChanges(
                changes.getOriginalData(),
                (InstanceIdentifier<OvsdbBridgeAugmentation>) removedBridge);

        LOG.debug(
            "processBridgeDeletion <{}> deletion on Node <{}>", removedBridge, bridgeParentNode);
        ovsdbUpdate(
            bridgeParentNode,
            removedBridgeAugmentationData,
            OvsdbInventoryListener.OvsdbType.BRIDGE,
            Action.DELETE);
      }
    }
  }
 @Test
 public void l3ContextIidTest() {
   L3ContextId l3ContextId = mock(L3ContextId.class);
   InstanceIdentifier<L3Context> identifier = IidFactory.l3ContextIid(tenantId, l3ContextId);
   Assert.assertEquals(l3ContextId, InstanceIdentifier.keyOf(identifier).getId());
   Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
 }
  private void processPortDeletion(
      AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {

    for (InstanceIdentifier<?> removedPort : changes.getRemovedPaths()) {
      if (removedPort.getTargetType().equals(OvsdbTerminationPointAugmentation.class)) {
        Node tpParentNode = getNode(changes.getOriginalData(), removedPort);
        if (tpParentNode == null) {
          // Throwing this warning in case behavior of southbound plugin changes.
          LOG.warn(
              "Port's {} parent node details are not present in original data, "
                  + "it should not happen",
              removedPort);
          continue;
        }
        // Fetch data of removed port from original data
        @SuppressWarnings("unchecked")
        OvsdbTerminationPointAugmentation removedTPAugmentationData =
            getDataChanges(
                changes.getOriginalData(),
                (InstanceIdentifier<OvsdbTerminationPointAugmentation>) removedPort);

        LOG.trace("processPortDeletion <{}> deletion on Node <{}>", removedPort, tpParentNode);
        ovsdbUpdate(
            tpParentNode,
            removedTPAugmentationData,
            OvsdbInventoryListener.OvsdbType.PORT,
            Action.DELETE);
      }
    }
  }
  private void processOvsdbDisconnect(
      AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {

    for (InstanceIdentifier<?> removedOvsdbNode : changes.getRemovedPaths()) {
      if (removedOvsdbNode.getTargetType().equals(OvsdbNodeAugmentation.class)) {
        // Get top node to get details of all the bridge/termination point augmentation
        // in case we want to do any cleanup task while processing node disconnection
        Node parentNode = getNode(changes.getOriginalData(), removedOvsdbNode);
        if (parentNode == null) {
          // Throwing this warning in case behavior of southbound plugin changes.
          LOG.warn(
              "OvsdbNode's {} parent node details are not present in original data,"
                  + " it should not happen",
              parentNode);
          continue;
        }
        // Fetch data of removed connection info from original data
        @SuppressWarnings("unchecked")
        OvsdbNodeAugmentation removedOvsdbNodeAugmentationData =
            getDataChanges(
                changes.getOriginalData(),
                (InstanceIdentifier<OvsdbNodeAugmentation>) removedOvsdbNode);

        LOG.trace("processOvsdbDisconnect: {} ", removedOvsdbNode);
        //// Assuming Openvswitch type represent the ovsdb node connection and not OvsdbType.NODE

        ovsdbUpdate(
            parentNode,
            removedOvsdbNodeAugmentationData,
            OvsdbInventoryListener.OvsdbType.NODE,
            Action.DELETE);
      }
    }
  }
 @Test
 public void subnetIidTest() {
   SubnetId subnetId = mock(SubnetId.class);
   InstanceIdentifier<Subnet> identifier = IidFactory.subnetIid(tenantId, subnetId);
   Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
   Assert.assertEquals(subnetId, identifier.firstKeyOf(Subnet.class).getId());
 }
 @Test
 public void classifierInstanceIidTest() {
   ClassifierName classifierName = mock(ClassifierName.class);
   InstanceIdentifier<ClassifierInstance> identifier =
       IidFactory.classifierInstanceIid(tenantId, classifierName);
   Assert.assertEquals(classifierName, InstanceIdentifier.keyOf(identifier).getName());
   Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
 }
 @Test
 public void actionInstanceIidTest() {
   ActionName actionName = mock(ActionName.class);
   InstanceIdentifier<ActionInstance> identifier =
       IidFactory.actionInstanceIid(tenantId, actionName);
   Assert.assertEquals(actionName, InstanceIdentifier.keyOf(identifier).getName());
   Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
 }
 @Test
 public void l2BridgeDomainIidTest() {
   L2BridgeDomainId l2BridgeDomainId = mock(L2BridgeDomainId.class);
   InstanceIdentifier<L2BridgeDomain> identifier =
       IidFactory.l2BridgeDomainIid(tenantId, l2BridgeDomainId);
   Assert.assertEquals(l2BridgeDomainId, InstanceIdentifier.keyOf(identifier).getId());
   Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
 }
 @Test
 public void l3EndpointIidTest() {
   L3ContextId l3ContextId = mock(L3ContextId.class);
   IpAddress ipAddress = mock(IpAddress.class);
   InstanceIdentifier<EndpointL3> identifier = IidFactory.l3EndpointIid(l3ContextId, ipAddress);
   Assert.assertEquals(l3ContextId, InstanceIdentifier.keyOf(identifier).getL3Context());
   Assert.assertEquals(ipAddress, InstanceIdentifier.keyOf(identifier).getIpAddress());
 }
 @Test
 public void ruleIdTest() {
   InstanceIdentifier<Rule> identifier =
       IidFactory.ruleIid(tenantId, contractId, subjectName, ruleName);
   Assert.assertEquals(ruleName, InstanceIdentifier.keyOf(identifier).getName());
   Assert.assertEquals(subjectName, identifier.firstKeyOf(Subject.class).getName());
   Assert.assertEquals(contractId, identifier.firstKeyOf(Contract.class).getId());
   Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
 }
 @Test
 public void consumerNamedSelectorIidTest() {
   SelectorName consumerSelectorName = mock(SelectorName.class);
   InstanceIdentifier<ConsumerNamedSelector> identifier =
       IidFactory.consumerNamedSelectorIid(tenantId, epgId, consumerSelectorName);
   Assert.assertEquals(consumerSelectorName, InstanceIdentifier.keyOf(identifier).getName());
   Assert.assertEquals(epgId, identifier.firstKeyOf(EndpointGroup.class).getId());
   Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
 }
 @Test
 public void endpointL3PrefixIidTest() {
   L3ContextId l3Context = mock(L3ContextId.class);
   IpPrefix ipPrefix = mock(IpPrefix.class);
   InstanceIdentifier<EndpointL3Prefix> identifier =
       IidFactory.endpointL3PrefixIid(l3Context, ipPrefix);
   Assert.assertEquals(l3Context, InstanceIdentifier.keyOf(identifier).getL3Context());
   Assert.assertEquals(ipPrefix, InstanceIdentifier.keyOf(identifier).getIpPrefix());
 }
 @Test
 public void subjectIidTest() {
   SubjectName subjectName = mock(SubjectName.class);
   InstanceIdentifier<Subject> identifier =
       IidFactory.subjectIid(tenantId, contractId, subjectName);
   Assert.assertEquals(subjectName, InstanceIdentifier.keyOf(identifier).getName());
   Assert.assertEquals(contractId, identifier.firstKeyOf(Contract.class).getId());
   Assert.assertEquals(tenantId, identifier.firstKeyOf(Tenant.class).getId());
 }
  @Test
  public void endpointIidTest() {
    L2BridgeDomainId l2Context = mock(L2BridgeDomainId.class);
    MacAddress macAddress = mock(MacAddress.class);
    InstanceIdentifier<Endpoint> identifier = IidFactory.endpointIid(l2Context, macAddress);
    Assert.assertEquals(l2Context, InstanceIdentifier.keyOf(identifier).getL2Context());
    Assert.assertEquals(macAddress, InstanceIdentifier.keyOf(identifier).getMacAddress());

    EndpointKey key = mock(EndpointKey.class);
    identifier = IidFactory.endpointIid(key);
    Assert.assertEquals(key, identifier.firstKeyOf(Endpoint.class));
  }
  private void nodeUpdated(final InstanceIdentifier<?> key, final Node node) {
    Preconditions.checkNotNull(key);
    if (!validateNode(node)) {
      LOG.warn("NodeUpdated event : Node [{}] is null or not valid.", key.toString());
      return;
    }

    LOG.info("Netconf event source [{}] is updating...", key.toString());
    NetconfEventSourceRegistration nesr = registrationMap.get(key);
    if (nesr != null) {
      nesr.updateStatus();
    } else {
      nodeCreated(key, node);
    }
  }
 private void nodeCreated(final InstanceIdentifier<?> key, final Node node) {
   Preconditions.checkNotNull(key);
   if (!validateNode(node)) {
     LOG.warn("NodeCreated event : Node [{}] is null or not valid.", key.toString());
     return;
   }
   LOG.info("Netconf event source [{}] is creating...", key.toString());
   NetconfEventSourceRegistration nesr = NetconfEventSourceRegistration.create(key, node, this);
   if (nesr != null) {
     NetconfEventSourceRegistration nesrOld = registrationMap.put(key, nesr);
     if (nesrOld != null) {
       nesrOld.close();
     }
   }
 }
 @Test
 public void testAddDeleteToTxChain() {
   InstanceIdentifier<Nodes> dummyII = InstanceIdentifier.create(Nodes.class);
   deviceContext.addDeleteToTxChain(LogicalDatastoreType.CONFIGURATION, dummyII);
   verify(txChainManager)
       .addDeleteOperationTotTxChain(eq(LogicalDatastoreType.CONFIGURATION), eq(dummyII));
 }
  /**
   * Reads a SFG from the datastore
   *
   * <p>
   *
   * @param serviceFunctionType function type
   * @return ServiceFunctionGroup object or null if not found
   */
  protected static ServiceFunctionGroup getServiceFunctionGroupByType(
      Class<? extends ServiceFunctionTypeIdentity> serviceFunctionType) {
    printTraceStart(LOG);
    ServiceFunctionGroup sfg = null;
    InstanceIdentifier<ServiceFunctionGroups> sfgIID;
    sfgIID = InstanceIdentifier.builder(ServiceFunctionGroups.class).build();

    ServiceFunctionGroups sfgs =
        SfcDataStoreAPI.readTransactionAPI(sfgIID, LogicalDatastoreType.CONFIGURATION);

    if (sfgs != null) {
      for (ServiceFunctionGroup element : sfgs.getServiceFunctionGroup()) {
        if (element.getType().equals(serviceFunctionType)) {
          sfg = element;
          LOG.debug("found group " + sfg + " that matches type " + serviceFunctionType);
          break;
        }
      }
    }
    if (sfg == null) {
      LOG.debug("didn't found group " + sfg + " that matches type " + serviceFunctionType);
    }
    printTraceStop(LOG);
    return sfg;
  }
 private void nodeRemoved(final InstanceIdentifier<?> key) {
   Preconditions.checkNotNull(key);
   LOG.info("Netconf event source [{}] is removing...", key.toString());
   NetconfEventSourceRegistration nesr = registrationMap.remove(key);
   if (nesr != null) {
     nesr.close();
   }
 }
  @Override
  public void writeList() {
    int txSubmitted = 0;
    int writeCnt = 0;

    BindingTransactionChain chain = bindingDataBroker.createTransactionChain(this);
    WriteTransaction tx = chain.newWriteOnlyTransaction();

    for (OuterList element : this.list) {
      InstanceIdentifier<OuterList> iid =
          InstanceIdentifier.create(TestExec.class).child(OuterList.class, element.getKey());
      if (oper == StartTestInput.Operation.PUT) {
        tx.put(LogicalDatastoreType.CONFIGURATION, iid, element);
      } else {
        tx.merge(LogicalDatastoreType.CONFIGURATION, iid, element);
      }

      writeCnt++;

      if (writeCnt == writesPerTx) {
        txSubmitted++;
        Futures.addCallback(
            tx.submit(),
            new FutureCallback<Void>() {
              @Override
              public void onSuccess(final Void result) {
                txOk++;
              }

              @Override
              public void onFailure(final Throwable t) {
                LOG.error("Transaction failed, {}", t);
                txError++;
              }
            });
        tx = chain.newWriteOnlyTransaction();
        writeCnt = 0;
      }
    }

    // *** Clean up and close the transaction chain ***
    // Submit the outstanding transaction even if it's empty and wait for it to finish
    // We need to empty the transaction chain before closing it
    try {
      txSubmitted++;
      tx.submit().checkedGet();
      txOk++;
    } catch (TransactionCommitFailedException e) {
      LOG.error("Transaction failed", e);
      txError++;
    }
    try {
      chain.close();
    } catch (IllegalStateException e) {
      LOG.error("Transaction close failed,", e);
    }
    LOG.info("Transactions: submitted {}, completed {}", txSubmitted, (txOk + txError));
  }
 private static InstanceIdentifier<Flow> createFlowIid(
     Flow flow, InstanceIdentifier<Node> nodeIid) {
   return nodeIid
       .builder()
       .augmentation(FlowCapableNode.class)
       .child(Table.class, new TableKey(flow.getTableId()))
       .child(Flow.class, new FlowKey(flow.getId()))
       .build();
 }
 public static InstanceIdentifier<Node> getInstanceIdentifier(Node node) {
   TopologyKey NETCONF_TOPOLOGY_KEY =
       new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()));
   InstanceIdentifier<Node> nodeII =
       InstanceIdentifier.create(NetworkTopology.class)
           .child(Topology.class, NETCONF_TOPOLOGY_KEY)
           .child(Node.class, node.getKey());
   return nodeII;
 }
public class TopologyDataChangeCounter implements DataChangeListener, TransactionChainListener {

  private static final Logger LOG = LoggerFactory.getLogger(TopologyDataChangeCounter.class);

  protected static final InstanceIdentifier<DataChangeCounter> IID =
      InstanceIdentifier.builder(DataChangeCounter.class).build();

  private final DataBroker dataBroker;
  private final BindingTransactionChain chain;
  private final AtomicLong count;

  public TopologyDataChangeCounter(final DataBroker dataBroker) {
    this.dataBroker = dataBroker;
    this.chain = this.dataBroker.createTransactionChain(this);
    this.count = new AtomicLong(0);
    putCount(this.count.get());
    LOG.debug("Data change counter initiated");
  }

  @Override
  public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
    putCount(this.count.incrementAndGet());
    LOG.debug("Data change #{}", this.count.get());
  }

  public void close() {
    final WriteTransaction wTx = this.dataBroker.newWriteOnlyTransaction();
    wTx.delete(LogicalDatastoreType.OPERATIONAL, IID);
    wTx.submit();
    this.chain.close();
    LOG.debug("Data change counter removed");
  }

  private void putCount(final long count) {
    final WriteTransaction wTx = this.chain.newWriteOnlyTransaction();
    wTx.put(
        LogicalDatastoreType.OPERATIONAL,
        IID,
        new DataChangeCounterBuilder().setCount(count).build());
    wTx.submit();
  }

  @Override
  public void onTransactionChainFailed(
      final TransactionChain<?, ?> chain,
      final AsyncTransaction<?, ?> transaction,
      final Throwable cause) {
    chain.close();
    LOG.warn("Transaction chain failure. Transaction: {}", transaction, cause);
  }

  @Override
  public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
    LOG.debug("Transaction chain successful. {}", chain);
  }
}
  public static InstanceIdentifier<Mapping> createMappingIid(
      LispAddressContainer eid, int mask, MappingOrigin orig) {
    Preconditions.checkNotNull(eid, "Mapping needs an EID entry!");

    InstanceIdKey iidKey = new InstanceIdKey(new IidUri(Long.toString(getLispInstanceId(eid))));
    MappingKey eidKey = new MappingKey(new EidUri(getURIAddressString(eid, mask)), orig);
    return InstanceIdentifier.create(MappingDatabase.class)
        .child(InstanceId.class, iidKey)
        .child(Mapping.class, eidKey);
  }
  public static InstanceIdentifier<AuthenticationKey> createAuthenticationKeyIid(
      LispAddressContainer eid, int mask) {
    Preconditions.checkNotNull(eid, "Key needs and EID entry!");

    InstanceIdKey iidKey = new InstanceIdKey(new IidUri(Long.toString(getLispInstanceId(eid))));
    AuthenticationKeyKey authKeyKey =
        new AuthenticationKeyKey(new EidUri(getURIAddressString(eid, mask)));
    return InstanceIdentifier.create(MappingDatabase.class)
        .child(InstanceId.class, iidKey)
        .child(AuthenticationKey.class, authKeyKey);
  }
  @Override
  public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
    for (InstanceIdentifier<?> key : change.getCreatedConfigurationData().keySet()) {
      if (Meter.class.equals(key.getTargetType())) {
        request();
      }
    }

    final DataModificationTransaction trans = startTransaction();
    for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
      if (Meter.class.equals(key.getTargetType())) {
        @SuppressWarnings("unchecked")
        InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>) key;

        InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
            InstanceIdentifier.builder(meter).augmentation(NodeMeterStatistics.class).toInstance();
        trans.removeOperationalData(nodeMeterStatisticsAugmentation);
      }
    }
    trans.commit();
  }
  private <T extends DataObject> T getDataChanges(
      Map<InstanceIdentifier<?>, DataObject> changes, InstanceIdentifier<T> path) {

    for (Map.Entry<InstanceIdentifier<?>, DataObject> change : changes.entrySet()) {
      if (change.getKey().getTargetType().equals(path.getTargetType())) {
        @SuppressWarnings("unchecked")
        T dataObject = (T) change.getValue();
        return dataObject;
      }
    }
    return null;
  }
 public void start() {
   InstanceIdentifier<Node> path =
       InstanceIdentifier.create(NetworkTopology.class)
           .child(Topology.class, new TopologyKey(MdsalHelper.OVSDB_TOPOLOGY_ID))
           .child(Node.class);
   registration =
       dataBroker.registerDataChangeListener(
           LogicalDatastoreType.OPERATIONAL, path, this, DataChangeScope.SUBTREE);
   LOG.info(
       "netvirt OvsdbDataChangeListener: dataBroker= {}, registration= {}",
       dataBroker,
       registration);
   triggerUpdates();
 }
  /**
   * Reads a SFG from the datastore
   *
   * <p>
   *
   * @param serviceFunctionGroupName name
   * @return ServiceFunctionGroup object or null if not found
   */
  public static ServiceFunctionGroup readServiceFunctionGroup(String serviceFunctionGroupName) {
    printTraceStart(LOG);
    ServiceFunctionGroup sfg;
    InstanceIdentifier<ServiceFunctionGroup> sfgIID;
    ServiceFunctionGroupKey serviceFunctionGroupKey =
        new ServiceFunctionGroupKey(serviceFunctionGroupName);
    sfgIID =
        InstanceIdentifier.builder(ServiceFunctionGroups.class)
            .child(ServiceFunctionGroup.class, serviceFunctionGroupKey)
            .build();

    sfg = SfcDataStoreAPI.readTransactionAPI(sfgIID, LogicalDatastoreType.CONFIGURATION);
    printTraceStop(LOG);
    return sfg;
  }
  /**
   * Puts a SFG in the datastore
   *
   * <p>
   *
   * @param sfg the ServiceFunctionGroup to put
   * @return boolean success or failure
   */
  public static boolean putServiceFunctionGroup(ServiceFunctionGroup sfg) {
    boolean ret;
    printTraceStart(LOG);
    InstanceIdentifier<ServiceFunctionGroup> sfgEntryIID =
        InstanceIdentifier.builder(ServiceFunctionGroups.class)
            .child(ServiceFunctionGroup.class, sfg.getKey())
            .build();

    ret =
        SfcDataStoreAPI.writePutTransactionAPI(
            sfgEntryIID, sfg, LogicalDatastoreType.CONFIGURATION);

    printTraceStop(LOG);
    return ret;
  }