+ if (fibListenerRegistration != null) {
+ try {
+ fibListenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.error("Error when cleaning up Fib entries DataChangeListener.", e);
+ }
+ fibListenerRegistration = null;
+ }
+ LOG.trace("VPN Manager Closed");
+ }
+
+ private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path) {
+
+ ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+ Optional<T> result = Optional.absent();
+ try {
+ result = tx.read(datastoreType, path).get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.put(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
+ }
+
+ private VpnInstance getVpnForRD(String rd) {
+ InstanceIdentifier<VpnInstances> id = InstanceIdentifier.create(VpnInstances.class);
+ Optional<VpnInstances> vpnInstances = read(LogicalDatastoreType.OPERATIONAL, id);
+ if(vpnInstances.isPresent()) {
+ List<VpnInstance> vpns = vpnInstances.get().getVpnInstance();
+ for(VpnInstance vpn : vpns) {
+ if(vpn.getIpv4Family().getRouteDistinguisher().equals(rd)) {
+ return vpn;
+ }
+ }
+ }
+ return null;
+ }
+
+ private Integer getUniqueId(String idKey) {
+ GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
+ .setPoolName(VpnConstants.VPN_IDPOOL_NAME)
+ .setIdKey(idKey).build();
+
+ try {
+ Future<RpcResult<GetUniqueIdOutput>> result = idManager.getUniqueId(getIdInput);
+ RpcResult<GetUniqueIdOutput> rpcResult = result.get();
+ if(rpcResult.isSuccessful()) {
+ return rpcResult.getResult().getIdValue().intValue();
+ } else {
+ LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
+ }
+ } catch (NullPointerException | InterruptedException | ExecutionException e) {
+ LOG.warn("Exception when getting Unique Id",e);
+ }
+ return 0;
+ }
+
+ private <T extends DataObject> void delete(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.delete(datastoreType, path);
+ Futures.addCallback(tx.submit(), DEFAULT_CALLBACK);
+ }
+
+ private class FibEntriesListener extends AbstractDataChangeListener<VrfEntry> {
+
+ public FibEntriesListener() {
+ super(VrfEntry.class);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<VrfEntry> identifier,
+ VrfEntry del) {
+ LOG.trace("Remove Fib event - Key : {}, value : {} ", identifier, del);
+ final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
+ String rd = key.getRouteDistinguisher();
+ Long label = del.getLabel();
+ VpnInstance vpn = getVpnForRD(rd);
+ if(vpn != null) {
+ InstanceIdentifier<VpnInstance> id = VpnUtil.getVpnInstanceIdentifier(vpn.getVpnInstanceName());
+ InstanceIdentifier<VpnInstance1> augId = id.augmentation(VpnInstance1.class);
+ Optional<VpnInstance1> vpnAugmenation = read(LogicalDatastoreType.OPERATIONAL, augId);
+ if(vpnAugmenation.isPresent()) {
+ VpnInstance1 vpnAug = vpnAugmenation.get();
+ List<Long> routeIds = vpnAug.getRouteEntryId();
+ if(routeIds == null) {
+ LOG.debug("Fib Route entry is empty.");
+ return;
+ }
+ LOG.debug("Removing label from vpn info - {}", label);
+ routeIds.remove(label);
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, augId,
+ new VpnInstance1Builder(vpnAug).setRouteEntryId(routeIds).build(), DEFAULT_CALLBACK);
+ } else {
+ LOG.warn("VPN Augmentation not found for vpn instance {}", vpn.getVpnInstanceName());
+ }
+ } else {
+ LOG.warn("No VPN Instance found for RD: {}", rd);
+ }
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<VrfEntry> identifier,
+ VrfEntry original, VrfEntry update) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<VrfEntry> identifier,
+ VrfEntry add) {
+ LOG.trace("Add Vrf Entry event - Key : {}, value : {}", identifier, add);
+ final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
+ String rd = key.getRouteDistinguisher();
+ Long label = add.getLabel();
+ VpnInstance vpn = getVpnForRD(rd);
+ if(vpn != null) {
+ InstanceIdentifier<VpnInstance> id = VpnUtil.getVpnInstanceIdentifier(vpn.getVpnInstanceName());
+ InstanceIdentifier<VpnInstance1> augId = id.augmentation(VpnInstance1.class);
+ Optional<VpnInstance1> vpnAugmenation = read(LogicalDatastoreType.OPERATIONAL, augId);
+ if(vpnAugmenation.isPresent()) {
+ VpnInstance1 vpnAug = vpnAugmenation.get();
+ List<Long> routeIds = vpnAug.getRouteEntryId();
+ if(routeIds == null) {
+ routeIds = new ArrayList<>();
+ }
+ LOG.debug("Adding label to vpn info - {}", label);
+ routeIds.add(label);
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, augId,
+ new VpnInstance1Builder(vpnAug).setRouteEntryId(routeIds).build(), DEFAULT_CALLBACK);
+ } else {
+ LOG.warn("VPN Augmentation not found for vpn instance {}", vpn.getVpnInstanceName());
+ }
+ } else {
+ LOG.warn("No VPN Instance found for RD: {}", rd);
+ }
+ }