--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+@SuppressWarnings("rawtypes")
+public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChangeListener<D> {
+ private static final Logger Log = LoggerFactory.getLogger(DataWaitListener.class);
+ InstanceIdentifier<D> objectIdentifierId;
+ private ListenerRegistration<DataWaitListener> dataWaitListenerRegistration;
+ Boolean dataAvailable = false;
+ private int maxRetries;
+ LogicalDatastoreType logicalDatastoreType;
+ DataWaitGetter<D> getData;
+ private final long waitMillisec = 1000;
+
+
+ public DataWaitListener(final DataBroker dataBroker, final InstanceIdentifier<D> objectIdentifierId,
+ int maxRetiries, LogicalDatastoreType logicalDatastoreType, final DataWaitGetter<D> getData) {
+ super(dataBroker);
+ this.objectIdentifierId = objectIdentifierId;
+ this.maxRetries = maxRetiries;
+ this.logicalDatastoreType = logicalDatastoreType;
+ this.getData = getData;
+ registerListener();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void registerListener() {
+ try {
+ final DataTreeIdentifier<D> dataTreeIid = new DataTreeIdentifier<D>(
+ LogicalDatastoreType.CONFIGURATION, objectIdentifierId);
+ dataWaitListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
+ Log.info("DataWaitListener created and registered");
+ } catch (final Exception e) {
+ Log.error("DataWaitListener DataChange listener registration failed !", e);
+ throw new IllegalStateException("DataWaitListener registration Listener failed.", e);
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ dataWaitListenerRegistration.close();
+ }
+
+ @Override
+ public void add(DataTreeModification<D> newDataObject) {
+ if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
+ Log.info("data {} created", newDataObject.getRootNode().getIdentifier());
+ }
+ synchronized (dataAvailable) {
+ dataAvailable.notifyAll();
+ }
+ }
+
+ @Override
+ public void remove(DataTreeModification<D> removedDataObject) {
+ }
+
+ @Override
+ public void update(DataTreeModification<D> modifiedDataObject) {
+ if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
+ Log.info("data {} updated", modifiedDataObject.getRootNode().getIdentifier());
+ }
+ synchronized (dataAvailable) {
+ dataAvailable.notifyAll();
+ }
+ }
+
+ private boolean dataAvailable() {
+ Optional<D> objectInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ objectIdentifierId);
+ if (!objectInstance.isPresent()) {
+ Log.debug("Data for {} doesn't exist, waiting more", objectIdentifierId);
+ return false;
+ }
+ if (getData.get(objectInstance.get()) != null) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean waitForData () {
+ return waitForData(maxRetries);
+ }
+
+
+ public boolean waitForData(int retry) {
+ synchronized (dataAvailable) {
+ dataAvailable = dataAvailable();
+ if (dataAvailable == true) {
+ return true;
+ } else if (retry <= 0) {
+ return false;
+ }
+ try {
+ dataAvailable.wait(waitMillisec);
+ } catch (InterruptedException e1) {
+ }
+ }
+ return waitForData(--retry);
+ }
+}
public static void addDirectSubnetToVpn(DataBroker dataBroker,
final NotificationPublishService notificationPublishService, String vpnName, String subnetName,
- IpPrefix subnetIpPrefix, String interfaceName) {
- InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
- .child(ElanInstance.class, new ElanInstanceKey(subnetName)).build();
- Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
- elanIdentifierId);
- if (!elanInstance.isPresent()) {
+ IpPrefix subnetIpPrefix, String interfaceName, int waitForElan) {
+ InstanceIdentifier<ElanInstance> elanIdentifierId = NetvirtUtils.getElanInstanceInstanceIdentifier(subnetName);
+
+ @SuppressWarnings("resource") // AutoCloseable
+ DataWaitListener<ElanInstance> elanTagWaiter = new DataWaitListener<ElanInstance>(
+ dataBroker, elanIdentifierId, 10, LogicalDatastoreType.CONFIGURATION, el -> el.getElanTag());
+ if ( !elanTagWaiter.waitForData()) {
logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
return;
}
- Long elanTag = elanInstance.get().getElanTag() != null ? elanInstance.get().getElanTag()
- : elanInstance.get().getSegmentationId();
Uuid subnetId = new Uuid(subnetName);
logger.info("Adding subnet {} {} to elan map", subnetId, subnetId);
logger.info("Adding port {} to subnet {}", interfaceName, subnetName);
updateSubnetmapNodeWithPorts(dataBroker, subnetId, new Uuid(interfaceName), null);
+ Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ elanIdentifierId);
+ Long elanTag = elanInstance.get().getElanTag();
+
logger.info("Publish subnet {}", subnetName);
publishSubnetAddNotification(notificationPublishService, subnetId, subnetIp, vpnName, elanTag);
logger.info("Finished Working on subnet {}", subnetName);
private ListenerRegistration<SubnetListener> subnetListenerRegistration;
private final NotificationPublishService notificationPublishService;
private final IGwMacListener gwMacListener;
-
+ private final int waitForElanInterval;
public SubnetListener(final DataBroker dataBroker, final NotificationPublishService notPublishService,
- final IGwMacListener gwMacListener ) {
+ final IGwMacListener gwMacListener, int sleepInterval) {
super(dataBroker);
this.notificationPublishService = notPublishService;
this.gwMacListener = gwMacListener;
+ this.waitForElanInterval = sleepInterval;
registerListener();
}
}
NetvirtVpnUtils.addDirectSubnetToVpn(dataBroker, notificationPublishService, ipvcVpn.getVpnId(),
- vpnElan.getElanId(), newSubnet.getSubnet(), vpnElan.getElanPort());
+ vpnElan.getElanId(), newSubnet.getSubnet(), vpnElan.getElanPort(), waitForElanInterval);
}