From: Ed Warnicke Date: Sat, 1 Feb 2014 16:09:03 +0000 (+0000) Subject: Merge changes I805ec065,Idc9995b1 X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~539 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=c61d22e4dc73fdaba09aa8c0b189ea7459679e03;hp=b825b2a5b92734113eae6c9c1176ec160ec8776b Merge changes I805ec065,Idc9995b1 * changes: Change unprotected netconf address from 0.0.0.0 to 127.0.0.1 . Refactor config-persister: clean up exception handling and netconf client. --- diff --git a/opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml b/opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml index 70742bd550..ebb9302b78 100644 --- a/opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml +++ b/opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml @@ -9,8 +9,8 @@ UTF-8 http://nexus.opendaylight.org/content - 0.6.1 - 0.6.1 + 0.6.2-SNAPSHOT + 0.6.2-SNAPSHOT 2.3.7 diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 47b31fb805..9d4f838992 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -69,7 +69,7 @@ 1.3.1 2.3.7 4.8.1 - 0.6.1 + 0.6.2-SNAPSHOT 0.4.2-SNAPSHOT 0.5.2-SNAPSHOT diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java index f833460766..bcade93352 100644 --- a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java @@ -8,12 +8,15 @@ package org.opendaylight.controller.config.persist.storage.directory.autodetect; import java.io.File; +import java.io.IOException; import java.util.List; import junit.framework.Assert; import org.junit.Test; import org.junit.matchers.JUnitMatchers; import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; import org.opendaylight.controller.config.persist.test.PropertiesProviderTest; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; public class AutodetectDirectoryPersisterTest { @@ -37,5 +40,52 @@ public class AutodetectDirectoryPersisterTest { String snapFromXml = configs.get(1).getConfigSnapshot(); org.junit.Assert.assertThat(snapFromXml, JUnitMatchers.containsString("xml")); - Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities()); } + Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities()); + } + + @Test + public void testInvalidXml() throws Exception { + File resourcePath = FileTypeTest.getResourceAsFile("/bad_controller.xml.config"); + File parentFile = resourcePath.getParentFile(); + + AutodetectDirectoryStorageAdapter adapter = new AutodetectDirectoryStorageAdapter(); + + PropertiesProviderTest pp = new PropertiesProviderTest(); + pp.addProperty("directoryStorage",parentFile.getPath()); + AutodetectDirectoryPersister persister = (AutodetectDirectoryPersister) adapter.instantiate(pp); + try { + List configs = persister.loadLastConfigs(); + fail("An exception of type " + IllegalStateException.class + " was expected"); + } catch (IllegalStateException ise){ + String message = ise.getMessage(); + assertThat(message, JUnitMatchers.containsString("Unable to restore configuration snapshot from ")); + } + + } + + @Test + public void testPersistConfig() throws Exception { + File resourcePath = FileTypeTest.getResourceAsFile("/combined/1controller.txt.config"); + File parentFile = resourcePath.getParentFile(); + + AutodetectDirectoryStorageAdapter adapter = new AutodetectDirectoryStorageAdapter(); + + PropertiesProviderTest pp = new PropertiesProviderTest(); + pp.addProperty("directoryStorage",parentFile.getPath()); + AutodetectDirectoryPersister persister = (AutodetectDirectoryPersister) adapter.instantiate(pp); + List configs = null; + try { + configs = persister.loadLastConfigs(); + } catch (IOException e) { + fail("An exception of type " + UnsupportedOperationException.class + " was expected"); + } + Assert.assertEquals(2, configs.size()); + try { + persister.persistConfig(configs.get(0)); + } catch (UnsupportedOperationException uoe){ + String message = uoe.getMessage(); + assertThat(message,JUnitMatchers.containsString("This adapter is read only. Please set readonly=true on class")); + } + } + } diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/bad_controller.xml.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/bad_controller.xml.config new file mode 100644 index 0000000000..3f6a3375d0 --- /dev/null +++ b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/bad_controller.xml.config @@ -0,0 +1,10 @@ + + + cap2 + capa a + + + xml + + \ No newline at end of file diff --git a/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/CapabilityHandler.java b/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/CapabilityHandler.java deleted file mode 100644 index d384df6989..0000000000 --- a/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/CapabilityHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.persist.storage.file.xml.model; - -import javax.xml.bind.ValidationEventHandler; -import javax.xml.bind.annotation.DomHandler; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; -import java.io.StringReader; -import java.io.StringWriter; - -class CapabilityHandler implements DomHandler { - - private static final String START_TAG = ""; - private static final String END_TAG = ""; - - private StringWriter xmlWriter = new StringWriter(); - - public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) { - xmlWriter.getBuffer().setLength(0); - return new StreamResult(xmlWriter); - } - - public String getElement(StreamResult rt) { - String xml = rt.getWriter().toString(); - int beginIndex = xml.indexOf(START_TAG) + START_TAG.length(); - int endIndex = xml.indexOf(END_TAG); - return xml.substring(beginIndex, endIndex); - } - - public Source marshal(String n, ValidationEventHandler errorHandler) { - try { - String xml = START_TAG + n.trim() + END_TAG; - StringReader xmlReader = new StringReader(xml); - return new StreamSource(xmlReader); - } catch(Exception e) { - throw new RuntimeException(e); - } - } - -} diff --git a/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java b/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java index 0e4cce544f..5322f6357a 100644 --- a/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java +++ b/opendaylight/config/config-persister-file-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/file/xml/FileStorageAdapterTest.java @@ -10,6 +10,8 @@ package org.opendaylight.controller.config.persist.storage.file.xml; import com.google.common.base.Charsets; import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; import java.nio.file.Files; import java.util.List; import java.util.SortedSet; @@ -29,6 +31,8 @@ public class FileStorageAdapterTest { private static int i; private File file; + private static final String NON_EXISTENT_DIRECTORY = "./nonExistentDir/"; + private static final String NON_EXISTENT_FILE = "nonExistent.txt"; @Before public void setUp() throws Exception { @@ -39,6 +43,32 @@ public class FileStorageAdapterTest { i = 1; } + @Test + public void testNewFile() throws Exception { + XmlFileStorageAdapter storage = new XmlFileStorageAdapter(); + PropertiesProviderTest pp = new PropertiesProviderTest(); + pp.addProperty("fileStorage",NON_EXISTENT_DIRECTORY+NON_EXISTENT_FILE); + pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE)); + storage.instantiate(pp); + + final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() { + @Override + public String getConfigSnapshot() { + return createConfig(); + } + + @Override + public SortedSet getCapabilities() { + return createCaps(); + } + }; + storage.persistConfig(holder); + + storage.persistConfig(holder); + + Assert.assertEquals(storage.toString().replace("\\","/"),"XmlFileStorageAdapter [storage="+NON_EXISTENT_DIRECTORY+NON_EXISTENT_FILE+"]"); + delete(new File(NON_EXISTENT_DIRECTORY)); + } @Test public void testFileAdapter() throws Exception { XmlFileStorageAdapter storage = new XmlFileStorageAdapter(); @@ -191,4 +221,12 @@ public class FileStorageAdapterTest { return "" + i++ + ""; } + private void delete(File f) throws IOException { + if (f.isDirectory()) { + for (File c : f.listFiles()) + delete(c); + } + if (!f.delete()) + throw new FileNotFoundException("Failed to delete file: " + f); + } } diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index dca781e7ec..28637bcf46 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -369,12 +369,12 @@ org.opendaylight.yangtools yang-binding - 0.6.1 + ${yangtools.version} org.opendaylight.yangtools binding-type-provider - 0.6.1 + ${yangtools.version} org.opendaylight.yangtools diff --git a/opendaylight/md-sal/clustered-data-store/implementation/pom.xml b/opendaylight/md-sal/clustered-data-store/implementation/pom.xml index c1e2fecedd..e6cfee15e1 100644 --- a/opendaylight/md-sal/clustered-data-store/implementation/pom.xml +++ b/opendaylight/md-sal/clustered-data-store/implementation/pom.xml @@ -72,7 +72,7 @@ org.opendaylight.yangtools maven-sal-api-gen-plugin - 0.6.1 + ${yangtools.version} jar diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-meter-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-meter-types.yang index 1686cad3de..6d1405019c 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-meter-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-meter-types.yang @@ -73,38 +73,46 @@ module opendaylight-meter-types { choice band-type { case drop { leaf drop-rate { + description "Rate for dropping packets"; type uint32; } leaf drop-burst-size { + description "Size of bursts"; type uint32; } } case dscp-remark { leaf dscp-remark-rate { + description "Rate for remarking packets"; type uint32; } leaf dscp-remark-burst-size { + description "Size of bursts"; type uint32; } leaf perc_level { + description "Number of drop precedence level to add"; type uint8; } } case experimenter { leaf experimenter-rate { + description "Rate for remarking packets"; type uint32; } leaf experimenter-burst-size { + description "Size of bursts"; type uint32; } leaf experimenter { + description "Experimenter id"; type uint32; } } @@ -118,22 +126,27 @@ module opendaylight-meter-types { grouping meter { leaf flags { + description "Meter configuration flags"; type meter-flags; } leaf meter-id { + description "Meter instance"; type meter-id; } leaf barrier { + description "If true, barrier message is sent"; type boolean; } leaf meter-name { + description "Name of meter instance"; type string; } leaf container-name { + description "Name of container"; type string; } @@ -141,20 +154,24 @@ module opendaylight-meter-types { list meter-band-header { key "band-id"; leaf band-id { + description "Meter band id"; type band-id; } container meter-band-types { leaf flags { + description "Meter band flags"; type meter-band-type; } } leaf band-rate { + description "Rate for this band"; type uint32; } leaf band-burst-size { + description "Size of bursts"; type uint32; } uses band-type; diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index fa6f94bfed..674ea240eb 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -102,7 +102,6 @@ - 0.6.1 UTF-8 http://nexus.opendaylight.org/content @@ -464,23 +463,6 @@ maven-jar-plugin 2.4 - - org.apache.maven.plugins - maven-javadoc-plugin - 2.8.1 - - maven - false - - - - - aggregate - - site - - - org.apache.maven.plugins diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java index cb201c5fd1..c28b03eb65 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java @@ -7,14 +7,17 @@ */ package org.opendaylight.controller.sal.binding.api; +import java.util.EventListener; import java.util.concurrent.ExecutorService; import org.opendaylight.controller.md.sal.common.api.notify.NotificationPublishService; +import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.Notification; public interface NotificationProviderService extends NotificationService, NotificationPublishService { + /** * Deprecated. Use {@link #publish(Notification)}. * @@ -34,7 +37,8 @@ public interface NotificationProviderService extends NotificationService, Notifi /** * Publishes a notification. * - * @param Notification notification to publish. + * @param Notification + * notification to publish. * */ @Override @@ -46,4 +50,12 @@ public interface NotificationProviderService extends NotificationService, Notifi */ @Override void publish(Notification notification, ExecutorService service); + + ListenerRegistration registerInterestListener( + NotificationInterestListener interestListener); + + public interface NotificationInterestListener extends EventListener { + + void onNotificationSubscribtion(Class notificationType); + } } diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java new file mode 100644 index 0000000000..d7cb926775 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. 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.controller.sal.binding.api.data; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.common.api.TransactionStatus; +import org.opendaylight.yangtools.concepts.Delegator; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; + +import com.google.common.base.Preconditions; + +/** + * Synchronized wrapper for DataModificationTransaction. + * + * To get instance of synchronized wrapper use {@link #from(DataModificationTransaction)} + * + */ +public final class SynchronizedTransaction implements DataModificationTransaction,Delegator { + + private final DataModificationTransaction delegate; + + private SynchronizedTransaction(DataModificationTransaction delegate) { + this.delegate = delegate; + } + + /** + * Returns synchronized wrapper on supplied transaction. + * + * @param transaction Transaction for which synchronized wrapper should be created. + * @return Synchronized wrapper over transaction. + */ + public static final SynchronizedTransaction from(DataModificationTransaction transaction) { + Preconditions.checkArgument(transaction != null, "Transaction must not be null."); + if (transaction instanceof SynchronizedTransaction) { + return (SynchronizedTransaction) transaction; + } + return new SynchronizedTransaction(transaction); + } + + @Override + public synchronized Map, DataObject> getCreatedOperationalData() { + return delegate.getCreatedOperationalData(); + } + + @Override + public synchronized Map, DataObject> getCreatedConfigurationData() { + return delegate.getCreatedConfigurationData(); + } + + @Override + public synchronized DataObject readOperationalData(InstanceIdentifier path) { + return delegate.readOperationalData(path); + } + + @Override + public synchronized TransactionStatus getStatus() { + return delegate.getStatus(); + } + + @Override + public synchronized Map, DataObject> getUpdatedOperationalData() { + return delegate.getUpdatedOperationalData(); + } + + @Deprecated + public synchronized void putRuntimeData(InstanceIdentifier path, DataObject data) { + delegate.putRuntimeData(path, data); + } + + @Override + public synchronized Object getIdentifier() { + return delegate.getIdentifier(); + } + + @Override + public synchronized DataObject readConfigurationData(InstanceIdentifier path) { + return delegate.readConfigurationData(path); + } + + @Override + public synchronized Future> commit() { + return delegate.commit(); + } + + @Override + public synchronized void putOperationalData(InstanceIdentifier path, DataObject data) { + delegate.putOperationalData(path, data); + } + + @Override + public synchronized void putConfigurationData(InstanceIdentifier path, DataObject data) { + delegate.putConfigurationData(path, data); + } + + @Override + public synchronized Map, DataObject> getUpdatedConfigurationData() { + return delegate.getUpdatedConfigurationData(); + } + + @Deprecated + public synchronized void removeRuntimeData(InstanceIdentifier path) { + delegate.removeRuntimeData(path); + } + + @Override + public synchronized void removeOperationalData(InstanceIdentifier path) { + delegate.removeOperationalData(path); + } + + @Override + public synchronized void removeConfigurationData(InstanceIdentifier path) { + delegate.removeConfigurationData(path); + } + + @Override + public synchronized Set> getRemovedConfigurationData() { + return delegate.getRemovedConfigurationData(); + } + + @Override + public synchronized Set> getRemovedOperationalData() { + return delegate.getRemovedOperationalData(); + } + + @Override + public synchronized Map, DataObject> getOriginalConfigurationData() { + return delegate.getOriginalConfigurationData(); + } + + @Override + public synchronized ListenerRegistration registerListener(DataTransactionListener listener) { + return delegate.registerListener(listener); + } + + @Override + public synchronized Map, DataObject> getOriginalOperationalData() { + return delegate.getOriginalOperationalData(); + } + + @Override + public synchronized DataModificationTransaction getDelegate() { + return delegate; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((delegate == null) ? 0 : delegate.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()){ + return false; + } + SynchronizedTransaction other = (SynchronizedTransaction) obj; + if (delegate == null) { + if (other.delegate != null) { + return false; + } + } else if (!delegate.equals(other.delegate)) { + return false; + } + return true; + } +} + diff --git a/opendaylight/md-sal/sal-binding-broker/pom.xml b/opendaylight/md-sal/sal-binding-broker/pom.xml index ea50e943ca..e5a74e42a1 100644 --- a/opendaylight/md-sal/sal-binding-broker/pom.xml +++ b/opendaylight/md-sal/sal-binding-broker/pom.xml @@ -56,7 +56,7 @@ org.opendaylight.yangtools maven-sal-api-gen-plugin - 0.6.1 + ${yangtools.version} jar diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend index 52aa8d0290..d997af5912 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend @@ -21,14 +21,20 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration import org.opendaylight.yangtools.concepts.Registration import org.opendaylight.yangtools.yang.binding.Notification import org.slf4j.LoggerFactory -import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder import com.google.common.collect.Multimaps - -class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { +import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder import com.google.common.collect.Multimaps +import org.opendaylight.yangtools.concepts.util.ListenerRegistry +import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener +class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { + + val ListenerRegistry interestListeners = ListenerRegistry.create; + val Multimap, NotificationListener> listeners; @Property var ExecutorService executor; + + val logger = LoggerFactory.getLogger(NotificationBrokerImpl) new() { listeners = Multimaps.synchronizedSetMultimap(HashMultimap.create()) @@ -101,14 +107,26 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab NotificationListener listener) { val reg = new GenericNotificationRegistration(notificationType, listener, this); listeners.put(notificationType, listener); + announceNotificationSubscription(notificationType); return reg; } + + def announceNotificationSubscription(Class notification) { + for (listener : interestListeners) { + try { + listener.instance.onNotificationSubscribtion(notification); + } catch (Exception e) { + logger.error("", e.message) + } + } + } override registerNotificationListener( org.opendaylight.yangtools.yang.binding.NotificationListener listener) { val invoker = SingletonHolder.INVOKER_FACTORY.invokerFor(listener); for (notifyType : invoker.supportedNotifications) { listeners.put(notifyType, invoker.invocationProxy) + announceNotificationSubscription(notifyType) } val registration = new GeneratedListenerRegistration(listener, invoker,this); return registration as Registration; @@ -128,6 +146,14 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab //FIXME: implement properly. } + override registerInterestListener(NotificationInterestListener interestListener) { + val registration = interestListeners.register(interestListener); + + for(notification : listeners.keySet) { + interestListener.onNotificationSubscribtion(notification); + } + return registration + } } class GenericNotificationRegistration extends AbstractObjectRegistration> implements ListenerRegistration> { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java index a21b3f1a61..978c79ea02 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingDomConnectorDeployer.java @@ -80,12 +80,14 @@ public class BindingDomConnectorDeployer { connector.startDataForwarding(); } - public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService baService, NotificationPublishService domService) { + public static void startNotificationForwarding(BindingIndependentConnector connector, + NotificationProviderService baService, NotificationPublishService domService) { if(connector.isNotificationForwarding()) { return; } - - // FIXME + connector.setBindingNotificationService(baService); + connector.setDomNotificationService(domService); + connector.startNotificationForwarding(); } // diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java index aaed12f740..5630664a67 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java @@ -17,6 +17,7 @@ import java.lang.reflect.Proxy; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -37,6 +38,8 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader; import org.opendaylight.controller.md.sal.common.api.routing.RouteChange; import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider; @@ -55,6 +58,8 @@ import org.opendaylight.controller.sal.core.api.Provider; import org.opendaylight.controller.sal.core.api.RpcImplementation; import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.core.api.notify.NotificationListener; +import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils; @@ -65,6 +70,7 @@ import org.opendaylight.yangtools.yang.binding.BindingMapping; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.binding.util.BindingReflections; import org.opendaylight.yangtools.yang.common.QName; @@ -93,7 +99,7 @@ public class BindingIndependentConnector implements // private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class); - @SuppressWarnings( "deprecation") + @SuppressWarnings("deprecation") private static final InstanceIdentifier ROOT = InstanceIdentifier.builder().toInstance(); private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier @@ -101,7 +107,6 @@ public class BindingIndependentConnector implements // private final static Method EQUALS_METHOD; - private BindingIndependentMappingService mappingService; private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService; @@ -146,10 +151,13 @@ public class BindingIndependentConnector implements // private org.opendaylight.controller.sal.dom.broker.spi.RpcRouter biRouter; + private NotificationProviderService baNotifyService; + + private NotificationPublishService domNotificationService; static { try { - EQUALS_METHOD = Object.class.getMethod("equals", Object.class); + EQUALS_METHOD = Object.class.getMethod("equals", Object.class); } catch (Exception e) { throw new RuntimeException(e); } @@ -311,7 +319,7 @@ public class BindingIndependentConnector implements // baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance()); baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance()); } - if(biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) { + if (biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) { biRouter = (org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) biRpcRegistry; } rpcForwarding = true; @@ -320,7 +328,11 @@ public class BindingIndependentConnector implements // public void startNotificationForwarding() { checkState(!notificationForwarding, "Connector is already forwarding notifications."); - notificationForwarding = true; + if (baNotifyService != null && domNotificationService != null) { + baNotifyService.registerInterestListener(new DomToBindingNotificationForwarder()); + + notificationForwarding = true; + } } protected void setMappingService(BindingIndependentMappingService mappingService) { @@ -616,7 +628,7 @@ public class BindingIndependentConnector implements // } createDefaultDomForwarder(); } catch (Exception e) { - LOG.error("Could not forward Rpcs of type {}", service.getName(),e); + LOG.error("Could not forward Rpcs of type {}", service.getName(), e); } registrations = registrationsBuilder.build(); } @@ -635,13 +647,13 @@ public class BindingIndependentConnector implements // @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if(EQUALS_METHOD.equals(method)) { + if (EQUALS_METHOD.equals(method)) { return false; } RpcInvocationStrategy strategy = strategiesByMethod.get(method); checkState(strategy != null); checkArgument(args.length <= 2); - if(args.length == 1) { + if (args.length == 1) { checkArgument(args[0] instanceof DataObject); return strategy.forwardToDomBroker((DataObject) args[0]); } @@ -719,9 +731,10 @@ public class BindingIndependentConnector implements // RpcInvocationStrategy strategy = null; if (outputClass.isPresent()) { if (inputClass.isPresent()) { - strategy = new DefaultInvocationStrategy(rpc,targetMethod, outputClass.get(), inputClass.get()); + strategy = new DefaultInvocationStrategy(rpc, targetMethod, outputClass.get(), inputClass + .get()); } else { - strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod); + strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod); } } else if(inputClass.isPresent()){ strategy = new NoOutputInvocationStrategy(rpc,targetMethod, inputClass.get()); @@ -740,7 +753,7 @@ public class BindingIndependentConnector implements // protected final Method targetMethod; protected final QName rpc; - public RpcInvocationStrategy(QName rpc,Method targetMethod) { + public RpcInvocationStrategy(QName rpc, Method targetMethod) { this.targetMethod = targetMethod; this.rpc = rpc; } @@ -766,19 +779,25 @@ public class BindingIndependentConnector implements // @SuppressWarnings({ "rawtypes", "unchecked" }) public DefaultInvocationStrategy(QName rpc, Method targetMethod, Class outputClass, Class inputClass) { - super(rpc,targetMethod); + super(rpc, targetMethod); this.outputClass = new WeakReference(outputClass); this.inputClass = new WeakReference(inputClass); } + @SuppressWarnings("unchecked") @Override public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); - Future> result = (Future>) targetMethod.invoke(rpcService, bindingInput); - if (result == null) { + Future> futureResult = (Future>) targetMethod.invoke(rpcService, bindingInput); + if (futureResult == null) { return Rpcs.getRpcResult(false); } - RpcResult bindingResult = result.get(); + RpcResult bindingResult = futureResult.get(); + final Object resultObj = bindingResult.getResult(); + if (resultObj instanceof DataObject) { + final CompositeNode output = mappingService.toDataDom((DataObject)resultObj); + return Rpcs.getRpcResult(true, output, Collections.emptySet()); + } return Rpcs.getRpcResult(true); } @@ -786,16 +805,16 @@ public class BindingIndependentConnector implements // public Future> forwardToDomBroker(DataObject input) { if(biRouter != null) { CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.>of(xml)); + CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); RpcResult result = biRouter.invokeRpc(rpc, wrappedXml); Object baResultValue = null; - if(result.getResult() != null) { + if (result.getResult() != null) { baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), result.getResult()); } RpcResult baResult = Rpcs.getRpcResult(result.isSuccessful(), baResultValue, result.getErrors()); - return Futures.>immediateFuture(baResult); + return Futures.> immediateFuture(baResult); } - return Futures.>immediateFuture(Rpcs.getRpcResult(false)); + return Futures.> immediateFuture(Rpcs.getRpcResult(false)); } } @@ -803,7 +822,7 @@ public class BindingIndependentConnector implements // private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy { public NoInputNoOutputInvocationStrategy(QName rpc, Method targetMethod) { - super(rpc,targetMethod); + super(rpc, targetMethod); } public RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception { @@ -874,4 +893,54 @@ public class BindingIndependentConnector implements // public BindingIndependentMappingService getMappingService() { return mappingService; } + + public void setBindingNotificationService(NotificationProviderService baService) { + this.baNotifyService = baService; + + } + + public void setDomNotificationService(NotificationPublishService domService) { + this.domNotificationService = domService; + } + + private class DomToBindingNotificationForwarder implements NotificationInterestListener, NotificationListener { + + private ConcurrentMap>> notifications = new ConcurrentHashMap<>(); + private Set supportedNotifications = new HashSet<>(); + + @Override + public Set getSupportedNotifications() { + return Collections.unmodifiableSet(supportedNotifications); + } + + @Override + public void onNotification(CompositeNode notification) { + QName qname = notification.getNodeType(); + WeakReference> potential = notifications.get(qname); + if (potential != null) { + Class potentialClass = potential.get(); + if (potentialClass != null) { + final DataContainer baNotification = mappingService.dataObjectFromDataDom(potentialClass, + notification); + + if (baNotification instanceof Notification) { + baNotifyService.publish((Notification) baNotification); + } + } + } + } + + @Override + public void onNotificationSubscribtion(Class notificationType) { + QName qname = BindingReflections.findQName(notificationType); + if (qname != null) { + WeakReference> already = notifications.putIfAbsent(qname, + new WeakReference>(notificationType)); + if (already == null) { + domNotificationService.addNotificationListener(qname, this); + supportedNotifications.add(qname); + } + } + } + } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java deleted file mode 100644 index 7b94845e8c..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMountPointForwarder.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. 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.controller.sal.binding.impl.connect.dom; - -import java.util.concurrent.ConcurrentMap; - -import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance; -import org.opendaylight.controller.sal.binding.api.mount.MountProviderService; -import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; -import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class BindingIndependentMountPointForwarder { - - private MountProvisionService domMountService; - private MountProviderService baMountService; - private BindingIndependentMappingService mappingService; - - private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager(); - private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager(); - - private ConcurrentMap, BindingIndependentConnector> connectors; - private ConcurrentMap, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded; - private ListenerRegistration domListenerRegistration; - private ListenerRegistration baListenerRegistration; - - public MountProvisionService getDomMountService() { - return domMountService; - } - - public void setDomMountService(MountProvisionService domMountService) { - this.domMountService = domMountService; - } - - public void start() { - if(domMountService != null && baMountService != null) { - domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager); - baListenerRegistration = baMountService.registerProvisionListener(bindingForwardingManager); - } - } - - private void tryToDeployConnector(InstanceIdentifier baPath, - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) { - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath); - if(previous != null) { - return; - } - MountProviderInstance baMountPoint = baMountService.getMountPoint(baPath); - MountProvisionInstance domMountPoint = domMountService.getMountPoint(biPath); - BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint); - connectors.put(baPath, connector); - connector.startDataForwarding(); - connector.startRpcForwarding(); - connector.startNotificationForwarding(); - } - - private BindingIndependentConnector createForwarder(InstanceIdentifier path, MountProviderInstance baMountPoint, - MountProvisionInstance domMountPoint) { - BindingIndependentConnector connector = new BindingIndependentConnector(); - - connector.setBindingDataService(baMountPoint); - connector.setBindingRpcRegistry(baMountPoint); - //connector.setBindingNotificationBroker(baMountPoint); - - connector.setDomDataService(domMountPoint); - connector.setDomRpcRegistry(domMountPoint); - //connector.setDomNotificationBroker(domMountPoint); - return connector; - } - - public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) { - InstanceIdentifier baPath; - try { - baPath = mappingService.fromDataDom(domPath); - BindingIndependentConnector potentialConnector = connectors.get(baPath); - if(potentialConnector != null) { - return; - } - tryToDeployConnector(baPath,domPath); - } catch (DeserializationException e) { - - } - } - - public synchronized void tryToDeployBindingForwarder(InstanceIdentifier baPath) { - BindingIndependentConnector potentialConnector =connectors.get(baPath); - if(potentialConnector != null) { - return; - } - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(baPath); - tryToDeployConnector(baPath, domPath); - } - - public synchronized void undeployBindingForwarder(InstanceIdentifier baPath) { - // FIXME: Implement closeMountPoint - } - - public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) { - // FIXME: Implement closeMountPoint - } - - private class DomMountPointForwardingManager implements MountProvisionListener { - - @Override - public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) { - tryToDeployDomForwarder(path); - } - - @Override - public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) { - undeployDomForwarder(path); - } - } - - private class BindingMountPointForwardingManager implements - org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener { - - @Override - public void onMountPointCreated(InstanceIdentifier path) { - tryToDeployBindingForwarder(path); - } - - @Override - public void onMountPointRemoved(InstanceIdentifier path) { - undeployBindingForwarder(path); - } - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java index c90f6fdb47..8c74008990 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedBindingBrokerImpl.java @@ -108,7 +108,7 @@ public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implem BindingDomConnectorDeployer.startRpcForwarding(mountConnector, baMountPoint, domMountPoint); BindingDomConnectorDeployer.startNotificationForwarding(mountConnector, baMountPoint, domMountPoint); // connector.setDomNotificationBroker(domMountPoint); - return connector; + return mountConnector; } public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) { diff --git a/opendaylight/md-sal/sal-binding-config/pom.xml b/opendaylight/md-sal/sal-binding-config/pom.xml index aec9fe4e33..d87e272032 100644 --- a/opendaylight/md-sal/sal-binding-config/pom.xml +++ b/opendaylight/md-sal/sal-binding-config/pom.xml @@ -69,7 +69,7 @@ org.opendaylight.yangtools maven-sal-api-gen-plugin - 0.6.1 + ${yangtools.version} jar diff --git a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java index 2a8ebe869c..c7d6640ce1 100644 --- a/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java +++ b/opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java @@ -99,4 +99,10 @@ public abstract class AbstractBindingSalProviderInstance registerInterestListener( + NotificationInterestListener interestListener) { + return getNotificationBrokerChecked().registerInterestListener(interestListener); + } } diff --git a/opendaylight/md-sal/sal-common-api/pom.xml b/opendaylight/md-sal/sal-common-api/pom.xml index 437051e346..5dd08d062d 100644 --- a/opendaylight/md-sal/sal-common-api/pom.xml +++ b/opendaylight/md-sal/sal-common-api/pom.xml @@ -26,7 +26,6 @@ org.opendaylight.yangtools concepts - 0.6.1 org.osgi diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend index 927975ca53..2c3b0188f4 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend @@ -45,6 +45,8 @@ import org.slf4j.LoggerFactory import static com.google.common.base.Preconditions.* import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent import com.google.common.collect.Multimaps +import java.util.concurrent.locks.Lock +import java.util.concurrent.locks.ReentrantLock abstract class AbstractDataBroker

, D, DCL extends DataChangeListener> implements DataModificationTransactionFactory, // DataReader, // @@ -70,16 +72,20 @@ DataProvisionService { Multimap> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.create()); Multimap> commitHandlers = Multimaps.synchronizedSetMultimap(HashMultimap.create()); + + private val Lock registrationLock = new ReentrantLock; val ListenerRegistry>> commitHandlerRegistrationListeners = new ListenerRegistry(); public new() { } protected def /*Iterator>,D>>*/ affectedCommitHandlers( - HashSet

paths) { - return FluentIterable.from(commitHandlers.asMap.entrySet).filter[key.isAffectedBy(paths)] // - .transformAndConcat[value] // - .transform[instance].toList() + HashSet

paths) { + return withLock(registrationLock) [| + return FluentIterable.from(commitHandlers.asMap.entrySet).filter[key.isAffectedBy(paths)] // + .transformAndConcat[value] // + .transform[instance].toList() + ] } override final readConfigurationData(P path) { @@ -88,43 +94,56 @@ DataProvisionService { override final readOperationalData(P path) { return dataReadRouter.readOperationalData(path); - } - - override final registerCommitHandler(P path, DataCommitHandler commitHandler) { - val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this); - commitHandlers.put(path, registration) - LOG.trace("Registering Commit Handler {} for path: {}",commitHandler,path); - for(listener : commitHandlerRegistrationListeners) { - try { - listener.instance.onRegister(registration); - } catch (Exception e) { - LOG.error("Unexpected exception in listener {} during invoking onRegister",listener.instance,e); - } - } - return registration; + } + + private static def withLock(Lock lock,Callable method) { + lock.lock + try { + return method.call + } finally { + lock.unlock + } + } + + override final registerCommitHandler(P path, DataCommitHandler commitHandler) { + return withLock(registrationLock) [| + val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this); + commitHandlers.put(path, registration) + LOG.trace("Registering Commit Handler {} for path: {}",commitHandler,path); + for(listener : commitHandlerRegistrationListeners) { + try { + listener.instance.onRegister(registration); + } catch (Exception e) { + LOG.error("Unexpected exception in listener {} during invoking onRegister",listener.instance,e); + } + } + return registration; + ] } override final def registerDataChangeListener(P path, DCL listener) { - val reg = new DataChangeListenerRegistration(path, listener, this); - listeners.put(path, reg); - val initialConfig = dataReadRouter.readConfigurationData(path); - val initialOperational = dataReadRouter.readOperationalData(path); - val event = createInitialListenerEvent(path,initialConfig,initialOperational); - listener.onDataChanged(event); - return reg; + return withLock(registrationLock) [| + val reg = new DataChangeListenerRegistration(path, listener, this); + listeners.put(path, reg); + val initialConfig = dataReadRouter.readConfigurationData(path); + val initialOperational = dataReadRouter.readOperationalData(path); + val event = createInitialListenerEvent(path,initialConfig,initialOperational); + listener.onDataChanged(event); + return reg; + ] } final def registerDataReader(P path, DataReader reader) { - - val confReg = dataReadRouter.registerConfigurationReader(path, reader); - val dataReg = dataReadRouter.registerOperationalReader(path, reader); - - return new CompositeObjectRegistration(reader, Arrays.asList(confReg, dataReg)); + return withLock(registrationLock) [| + val confReg = dataReadRouter.registerConfigurationReader(path, reader); + val dataReg = dataReadRouter.registerOperationalReader(path, reader); + + return new CompositeObjectRegistration(reader, Arrays.asList(confReg, dataReg)); + ] } override registerCommitHandlerListener(RegistrationListener> commitHandlerListener) { val ret = commitHandlerRegistrationListeners.register(commitHandlerListener); - return ret; } @@ -133,21 +152,25 @@ DataProvisionService { } - protected final def removeListener(DataChangeListenerRegistration registration) { - listeners.remove(registration.path, registration); + protected final def removeListener(DataChangeListenerRegistration registration) { + return withLock(registrationLock) [| + listeners.remove(registration.path, registration); + ] } protected final def removeCommitHandler(DataCommitHandlerRegistrationImpl registration) { - commitHandlers.remove(registration.path, registration); - - LOG.trace("Removing Commit Handler {} for path: {}",registration.instance,registration.path); - for(listener : commitHandlerRegistrationListeners) { - try { - listener.instance.onUnregister(registration); - } catch (Exception e) { - LOG.error("Unexpected exception in listener {} during invoking onUnregister",listener.instance,e); - } - } + return withLock(registrationLock) [| + commitHandlers.remove(registration.path, registration); + LOG.trace("Removing Commit Handler {} for path: {}",registration.instance,registration.path); + for(listener : commitHandlerRegistrationListeners) { + try { + listener.instance.onUnregister(registration); + } catch (Exception e) { + LOG.error("Unexpected exception in listener {} during invoking onUnregister",listener.instance,e); + } + } + return null; + ] } protected final def getActiveCommitHandlers() { @@ -155,12 +178,14 @@ DataProvisionService { } protected def /*Iterator>,D>>*/ affectedListenersWithInitialState( - HashSet

paths) { - return FluentIterable.from(listeners.asMap.entrySet).filter[key.isAffectedBy(paths)].transform [ - val operationalState = readOperationalData(key) - val configurationState = readConfigurationData(key) - return new ListenerStateCapture(key, value, operationalState, configurationState) - ].toList() + HashSet

paths) { + return withLock(registrationLock) [| + return FluentIterable.from(listeners.asMap.entrySet).filter[key.isAffectedBy(paths)].transform [ + val operationalState = readOperationalData(key) + val configurationState = readConfigurationData(key) + return new ListenerStateCapture(key, value, operationalState, configurationState) + ].toList() + ] } protected def boolean isAffectedBy(P key, Set

paths) { @@ -267,12 +292,13 @@ package class TwoPhaseCommit

, D, DCL extends DataChangeListene affectedPaths.addAll(transaction.createdOperationalData.keySet); affectedPaths.addAll(transaction.updatedOperationalData.keySet); affectedPaths.addAll(transaction.removedOperationalData); - + val listeners = dataBroker.affectedListenersWithInitialState(affectedPaths); val transactionId = transaction.identifier; log.trace("Transaction: {} Started.",transactionId); + log.trace("Transaction: {} Affected Subtrees:",transactionId,affectedPaths); // requesting commits val Iterable> commitHandlers = dataBroker.affectedCommitHandlers(affectedPaths); val List> handlerTransactions = new ArrayList(); @@ -283,6 +309,7 @@ package class TwoPhaseCommit

, D, DCL extends DataChangeListene } catch (Exception e) { log.error("Transaction: {} Request Commit failed", transactionId,e); dataBroker.failedTransactionsCount.andIncrement + transaction.changeStatus(TransactionStatus.FAILED) return rollback(handlerTransactions, e); } val List> results = new ArrayList(); @@ -293,11 +320,13 @@ package class TwoPhaseCommit

, D, DCL extends DataChangeListene listeners.publishDataChangeEvent(); } catch (Exception e) { log.error("Transaction: {} Finish Commit failed",transactionId, e); - dataBroker.failedTransactionsCount.andIncrement + dataBroker.failedTransactionsCount.andIncrement + transaction.changeStatus(TransactionStatus.FAILED) return rollback(handlerTransactions, e); } log.trace("Transaction: {} Finished successfully.",transactionId); - dataBroker.finishedTransactionsCount.andIncrement; + dataBroker.finishedTransactionsCount.andIncrement; + transaction.changeStatus(TransactionStatus.COMMITED) return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet()); } diff --git a/opendaylight/md-sal/sal-common-util/pom.xml b/opendaylight/md-sal/sal-common-util/pom.xml index 2ec66b57a3..3a9b00dce0 100644 --- a/opendaylight/md-sal/sal-common-util/pom.xml +++ b/opendaylight/md-sal/sal-common-util/pom.xml @@ -21,7 +21,6 @@ org.opendaylight.yangtools concepts - 0.6.1 com.google.guava diff --git a/opendaylight/md-sal/sal-dom-api/pom.xml b/opendaylight/md-sal/sal-dom-api/pom.xml index 76d80d15f7..d7b0296ce1 100644 --- a/opendaylight/md-sal/sal-dom-api/pom.xml +++ b/opendaylight/md-sal/sal-dom-api/pom.xml @@ -59,7 +59,7 @@ org.opendaylight.yangtools maven-sal-api-gen-plugin - 0.6.1 + ${yangtools.version} jar diff --git a/opendaylight/md-sal/sal-dom-broker/pom.xml b/opendaylight/md-sal/sal-dom-broker/pom.xml index 5b883d7c42..8b193e03aa 100644 --- a/opendaylight/md-sal/sal-dom-broker/pom.xml +++ b/opendaylight/md-sal/sal-dom-broker/pom.xml @@ -104,7 +104,7 @@ org.opendaylight.yangtools maven-sal-api-gen-plugin - 0.6.1 + ${yangtools.version} jar diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend index 098cd922ed..023f906a67 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend @@ -44,7 +44,6 @@ class MountPointManagerImpl implements MountProvisionService { def registerMountPoint(MountPointImpl impl) { //dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper); //dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper); - } override registerProvisionListener(MountProvisionListener listener) { diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend index 37236718ef..cc44613e44 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend @@ -85,7 +85,7 @@ class DataReaderRouter extends AbstractDataReadRouter> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.>create()); - +// private Registration defaultListener; + private void sendNotification(CompositeNode notification) { - QName type = notification.getNodeType(); - Collection> toNotify = listeners.get(type); + final QName type = notification.getNodeType(); + final Collection> toNotify = listeners.get(type); log.trace("Publishing notification " + type); - if (toNotify == null) { - // No listeners were registered - returns. + if ((toNotify == null) || toNotify.isEmpty()) { + log.debug("No listener registered for handling of notification {}", type); return; } @@ -59,17 +60,17 @@ public class NotificationRouterImpl implements NotificationRouter { log.error("Uncaught exception in NotificationListener", e); } } - } @Override public void publish(CompositeNode notification) { sendNotification(notification); } - + @Override public Registration addNotificationListener(QName notification, NotificationListener listener) { ListenerRegistration ret = new ListenerRegistration(notification, listener); + listeners.put(notification, ret); return ret; } diff --git a/opendaylight/md-sal/sal-netconf-connector/pom.xml b/opendaylight/md-sal/sal-netconf-connector/pom.xml index f90c966ba3..597b02ebb5 100644 --- a/opendaylight/md-sal/sal-netconf-connector/pom.xml +++ b/opendaylight/md-sal/sal-netconf-connector/pom.xml @@ -247,7 +247,7 @@ org.opendaylight.yangtools maven-sal-api-gen-plugin - 0.6.1 + ${yangtools.version} jar diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java index 87cbf13ea0..69fe4aa190 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java @@ -78,17 +78,11 @@ class NetconfDeviceListener extends NetconfClientSessionListener { */ public void onNotification(final NetconfClientSession session, final NetconfMessage message) { this.device.logger.debug("Received NETCONF notification.", message); - CompositeNode _notificationBody = null; - CompositeNode _compositeNode = null; + CompositeNode domNotification = null; if (message != null) { - _compositeNode = NetconfMapping.toCompositeNode(message,device.getSchemaContext()); + domNotification = NetconfMapping.toNotificationNode(message, device.getSchemaContext()); } - if (_compositeNode != null) { - _notificationBody = NetconfDeviceListener.getNotificationBody(_compositeNode); - } - final CompositeNode domNotification = _notificationBody; - boolean _notEquals = (!Objects.equal(domNotification, null)); - if (_notEquals) { + if (domNotification != null) { MountProvisionInstance _mountInstance = null; if (this.device != null) { _mountInstance = this.device.getMountInstance(); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend index 965df60cfb..76a5506df3 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend @@ -33,6 +33,8 @@ import com.google.common.base.Preconditions import com.google.common.base.Optional import org.opendaylight.yangtools.yang.model.api.SchemaContext import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition +import java.util.Set class NetconfMapping { @@ -103,7 +105,19 @@ class NetconfMapping { } static def CompositeNode toCompositeNode(NetconfMessage message,Optional ctx) { - return null//message.toRpcResult().result; + //TODO: implement general normalization to normalize incoming Netconf Message + // for Schema Context counterpart + return null + } + + static def CompositeNode toNotificationNode(NetconfMessage message,Optional ctx) { + if (ctx.present) { + val schemaContext = ctx.get + val notifications = schemaContext.notifications + val document = message.document + return XmlDocumentUtils.notificationToDomNodes(document, Optional.>fromNullable(notifications)) + } + return null } static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node,Optional ctx) { @@ -134,11 +148,11 @@ class NetconfMapping { if(isDataRetrievalReply(rpc)) { val xmlData = message.document.dataSubtree - val dataNodes = XmlDocumentUtils.toDomNodes(xmlData,Optional.of(context.get.dataDefinitions)) + val dataNodes = XmlDocumentUtils.toDomNodes(xmlData, Optional.of(context.get.dataDefinitions)) val it = ImmutableCompositeNode.builder() setQName(NETCONF_RPC_REPLY_QNAME) - add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME,dataNodes)); + add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME, dataNodes)); rawRpc = it.toInstance; //sys(xmlData) diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml b/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml index 619b42be05..ae31c2382f 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml @@ -189,7 +189,7 @@ org.opendaylight.yangtools maven-sal-api-gen-plugin - 0.6.1 + ${yangtools.version} jar diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java deleted file mode 100644 index 557adb6129..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.sal.rest.api; - -public class Draft01 { - public static class MediaTypes { - public static final String API = "application/vnd.yang.api"; - public static final String DATASTORE = "application/vnd.yang.datastore"; - public static final String DATA = "application/vnd.yang.data"; - public static final String EVENT = "application/vnd.yang.event"; - public static final String OPERATION = "application/vnd.yang.operation"; - public static final String PATCH = "application/vnd.yang.patch"; - } -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java index 60a8f285a2..848f2c48ab 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.sal.rest.api; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -23,33 +24,28 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode; /** * The URI hierarchy for the RESTCONF resources consists of an entry - * point container, 3 top-level resources, and 1 field. Refer to - * Section 5 for details on each URI. - *

    + * point container, 4 top-level resources, and 1 field. + *
      *
    • /restconf - {@link #getRoot()} - *
      • /config - *
      • /operational - {@link #readAllData()} - Added in Draft02 - *
      • /datastore - {@link #readAllData()} - *
          - *
        • /(top-level-data-nodes) (config=true or false) - *
        - *
      • /modules - *
        • /module - *
        • /name - *
        • /revision - *
        • /namespace - *
        • /feature - *
        • /deviation - *
        - *
      • /operations - *
          - *
        • /(custom protocol operations) - *
        - *
      • /version (field) + *
          + *
        • /config - {@link #readConfigurationData(String)} + * {@link #updateConfigurationData(String, CompositeNode)} + * {@link #createConfigurationData(CompositeNode)} + * {@link #createConfigurationData(String, CompositeNode)} + * {@link #deleteConfigurationData(String)} + *
        • /operational - {@link #readOperationalData(String)} + *
        • /modules - {@link #getModules()} + *
            + *
          • /module + *
          + *
        • /operations - {@link #invokeRpc(String, CompositeNode)} + * {@link #invokeRpc(String, CompositeNode)} + *
        • /version (field) *
        + *
      */ @Path("/") -public interface RestconfService extends RestconfServiceLegacy { +public interface RestconfService { public static final String XML = "+xml"; public static final String JSON = "+json"; @@ -59,26 +55,25 @@ public interface RestconfService extends RestconfServiceLegacy { @GET @Path("/modules") - @Produces({Draft01.MediaTypes.API+JSON,Draft01.MediaTypes.API+XML, - Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML}) + @Produces({Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML}) public StructuredData getModules(); @POST @Path("/operations/{identifier}") - @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, - Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + @Produces({Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+XML, + Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - @Consumes({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, - Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + @Consumes({Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+XML, + Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload); @POST @Path("/operations/{identifier}") - @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, - Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, + @Produces({Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+XML, + Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - public StructuredData invokeRpc(@PathParam("identifier") String identifier); + public StructuredData invokeRpc(@PathParam("identifier") String identifier, @DefaultValue("") String noPayload); @GET @Path("/config/{identifier:.+}") diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java deleted file mode 100644 index 7d6cbfe919..0000000000 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. 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.controller.sal.rest.api; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.opendaylight.controller.sal.restconf.impl.StructuredData; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; - -public interface RestconfServiceLegacy { - - public static final String XML = "+xml"; - public static final String JSON = "+json"; - - @Deprecated - @GET - @Path("/datastore") - @Produces({Draft01.MediaTypes.DATASTORE+JSON,Draft01.MediaTypes.DATASTORE+XML}) - public StructuredData readAllData(); - - @Deprecated - @GET - @Path("/datastore/{identifier:.+}") - @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, - MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - public StructuredData readData(@PathParam("identifier") String identifier); - - @Deprecated - @POST - @Path("/datastore/{identifier:.+}") - @Consumes({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, - MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - public Response createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload); - - @Deprecated - @PUT - @Path("/datastore/{identifier:.+}") - @Consumes({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, - MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - public Response updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload); - -} diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java index 357b599ec7..226eff44e1 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java @@ -134,7 +134,7 @@ class JsonMapper { private DataSchemaNode findFirstSchemaForNode(Node node, Set dataSchemaNode) { for (DataSchemaNode dsn : dataSchemaNode) { - if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) { + if (node.getNodeType().equals(dsn.getQName())) { return dsn; } else if (dsn instanceof ChoiceNode) { for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) { @@ -252,14 +252,18 @@ class JsonMapper { result.append("/"); writeModuleNameAndIdentifier(result, identityValue); - if (identityValue.getPredicates() != null) { + if (identityValue.getPredicates() != null && !identityValue.getPredicates().isEmpty()) { for (Predicate predicate : identityValue.getPredicates()) { IdentityValue identityValuePredicate = predicate.getName(); result.append("["); - writeModuleNameAndIdentifier(result, identityValuePredicate); - result.append("=\""); + if (identityValuePredicate == null) { + result.append("."); + } else { + writeModuleNameAndIdentifier(result, identityValuePredicate); + } + result.append("='"); result.append(predicate.getValue()); - result.append("\""); + result.append("'"); result.append("]"); } } @@ -300,10 +304,16 @@ class JsonMapper { String nameForOutput = node.getNodeType().getLocalName(); if (schema.isAugmenting()) { ControllerContext contContext = ControllerContext.getInstance(); - CharSequence moduleName; - moduleName = contContext.toRestconfIdentifier(schema.getQName()); + CharSequence moduleName = null; + if (mountPoint == null) { + moduleName = contContext.toRestconfIdentifier(schema.getQName()); + } else { + moduleName = contContext.toRestconfIdentifier(mountPoint, schema.getQName()); + } if (moduleName != null) { nameForOutput = moduleName.toString(); + } else { + logger.info("Module '{}' was not found in schema from mount point", schema.getQName()); } } writer.name(nameForOutput); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java index f3995707f3..0d73485c80 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java @@ -20,13 +20,12 @@ import javax.ws.rs.core.Response; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.Provider; -import org.opendaylight.controller.sal.rest.api.Draft01; import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.api.RestconfService; import org.opendaylight.yangtools.yang.data.api.CompositeNode; @Provider -@Consumes({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON, +@Consumes({ Draft02.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.OPERATION + RestconfService.JSON, MediaType.APPLICATION_JSON }) public enum JsonToCompositeNodeProvider implements MessageBodyReader { INSTANCE; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToJsonProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToJsonProvider.java index e4c4993244..22e08d97f4 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToJsonProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToJsonProvider.java @@ -21,7 +21,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import org.opendaylight.controller.sal.rest.api.Draft01; import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.api.RestconfService; import org.opendaylight.controller.sal.restconf.impl.ResponseException; @@ -32,7 +31,7 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import com.google.gson.stream.JsonWriter; @Provider -@Produces({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON, +@Produces({ Draft02.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.OPERATION + RestconfService.JSON, MediaType.APPLICATION_JSON }) public enum StructuredDataToJsonProvider implements MessageBodyWriter { INSTANCE; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java index bbe156d3c4..b6d8c953a9 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java @@ -26,7 +26,6 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import org.opendaylight.controller.sal.rest.api.Draft01; import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.api.RestconfService; import org.opendaylight.controller.sal.restconf.impl.ResponseException; @@ -38,7 +37,7 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @Provider -@Produces({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML, +@Produces({ Draft02.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.OPERATION + RestconfService.XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML }) public enum StructuredDataToXmlProvider implements MessageBodyWriter { INSTANCE; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeProvider.java index f03431291e..13d617031a 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeProvider.java @@ -21,14 +21,13 @@ import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.Provider; import javax.xml.stream.XMLStreamException; -import org.opendaylight.controller.sal.rest.api.Draft01; import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.api.RestconfService; import org.opendaylight.controller.sal.restconf.impl.ResponseException; import org.opendaylight.yangtools.yang.data.api.CompositeNode; @Provider -@Consumes({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML, +@Consumes({ Draft02.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.OPERATION + RestconfService.XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML }) public enum XmlToCompositeNodeProvider implements MessageBodyReader { INSTANCE; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index 7d32194b1f..2dfe5062c8 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -216,13 +216,20 @@ class ControllerContext implements SchemaServiceListener { var module = uriToModuleName.get(qname.namespace) if (module === null) { val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); - if(moduleSchema === null) throw new IllegalArgumentException() + if(moduleSchema === null) return null uriToModuleName.put(qname.namespace, moduleSchema.name) module = moduleSchema.name; } return '''«module»:«qname.localName»'''; } + def CharSequence toRestconfIdentifier(MountInstance mountPoint, QName qname) { + val moduleSchema = mountPoint?.schemaContext.findModuleByNamespaceAndRevision(qname.namespace, qname.revision); + if(moduleSchema === null) return null + val module = moduleSchema.name; + return '''«module»:«qname.localName»'''; + } + private static dispatch def DataSchemaNode childByQName(ChoiceNode container, QName name) { for (caze : container.cases) { val ret = caze.childByQName(name) diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java index 4f643fe34d..d6b530039e 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java @@ -212,6 +212,11 @@ public class RestCodec { List predicates = keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument) .getKeyValues()); identityValue.setPredicates(predicates); + } else if (pathArgument instanceof NodeWithValue && identityValue != null) { + List predicates = new ArrayList<>(); + String value = String.valueOf(((NodeWithValue) pathArgument).getValue()); + predicates.add(new Predicate(null, value)); + identityValue.setPredicates(predicates); } identityValuesDTO.add(identityValue); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend index 07fb05aded..cbfc3edf2c 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend @@ -58,12 +58,6 @@ class RestconfImpl implements RestconfService { return INSTANCE } - override readAllData() { - - // return broker.readOperationalData("".toInstanceIdentifier.getInstanceIdentifier); - throw new UnsupportedOperationException("Reading all data is currently not supported.") - } - override getModules() { throw new UnsupportedOperationException("TODO: auto-generated method stub") } @@ -76,7 +70,10 @@ class RestconfImpl implements RestconfService { return callRpc(identifier.rpcDefinition, payload) } - override invokeRpc(String identifier) { + override invokeRpc(String identifier, String noPayload) { + if (!noPayload.nullOrEmpty) { + throw new ResponseException(UNSUPPORTED_MEDIA_TYPE, "Content-Type contains unsupported Media Type."); + } return callRpc(identifier.rpcDefinition, null) } @@ -103,17 +100,6 @@ class RestconfImpl implements RestconfService { return new StructuredData(rpcResult.result, rpc.output, null) } - override readData(String identifier) { - val iiWithData = identifier.toInstanceIdentifier - var CompositeNode data = null; - if (iiWithData.mountPoint !== null) { - data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.instanceIdentifier) - } else { - data = broker.readOperationalData(iiWithData.getInstanceIdentifier); - } - return new StructuredData(data, iiWithData.schemaNode, iiWithData.mountPoint) - } - override readConfigurationData(String identifier) { val iiWithData = identifier.toInstanceIdentifier var CompositeNode data = null; @@ -136,10 +122,6 @@ class RestconfImpl implements RestconfService { return new StructuredData(data, iiWithData.schemaNode, iiWithData.mountPoint) } - override updateConfigurationDataLegacy(String identifier, CompositeNode payload) { - updateConfigurationData(identifier, payload); - } - override updateConfigurationData(String identifier, CompositeNode payload) { val iiWithData = identifier.toInstanceIdentifier val value = normalizeNode(payload, iiWithData.schemaNode, iiWithData.mountPoint) @@ -156,10 +138,6 @@ class RestconfImpl implements RestconfService { } } - override createConfigurationDataLegacy(String identifier, CompositeNode payload) { - createConfigurationData(identifier, payload); - } - override createConfigurationData(String identifier, CompositeNode payload) { if (payload.namespace === null) { throw new ResponseException(BAD_REQUEST, diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java index f3612969b9..874e8b0d1f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java @@ -51,6 +51,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { * Test of json output when as input are specified composite node with empty * data + YANG file */ + @Test public void compositeNodeAndYangWithJsonReaderEmptyDataTest() { CompositeNode compositeNode = prepareCompositeNodeWithEmpties(); @@ -538,49 +539,49 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { TestUtils.buildQName("cont1", "simple:yang:types", "2013-11-5"), null, null, ModifyAction.CREATE, null); // lst11_1 - MutableCompositeNode lst11_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11"), cont1, + MutableCompositeNode lst11_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); cont1.getChildren().add(lst11_1); - MutableSimpleNode lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_1, + MutableSimpleNode lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_1, (short) 1, ModifyAction.CREATE, null); lst11_1.getChildren().add(lf111_1); // lst111_1_1 - MutableCompositeNode lst111_1_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111"), + MutableCompositeNode lst111_1_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); lst11_1.getChildren().add(lst111_1_1); - MutableSimpleNode lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111"), + MutableSimpleNode lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"), lst111_1_1, (int) 34, ModifyAction.CREATE, null); lst111_1_1.getChildren().add(lf1111_1_1); lst111_1_1.init(); // :lst111_1_1 // lst111_1_2 - MutableCompositeNode lst111_1_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111"), + MutableCompositeNode lst111_1_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); lst11_1.getChildren().add(lst111_1_2); - MutableSimpleNode lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111"), + MutableSimpleNode lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"), lst111_1_2, (int) 35, ModifyAction.CREATE, null); lst111_1_2.getChildren().add(lf1111_1_2); lst111_1_2.init(); // :lst111_1_2 // lst111_1_3 - MutableCompositeNode lst111_1_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111"), + MutableCompositeNode lst111_1_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); lst11_1.getChildren().add(lst111_1_3); lst111_1_2.init(); // :lst111_1_3 // lst111_1_4 - MutableCompositeNode lst111_1_4 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111"), + MutableCompositeNode lst111_1_4 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); lst11_1.getChildren().add(lst111_1_4); lst111_1_2.init(); // :lst111_1_4 - MutableCompositeNode cont111_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111"), + MutableCompositeNode cont111_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); lst11_1.getChildren().add(cont111_1); @@ -588,39 +589,39 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { // :lst11_1 // lst11_2 - MutableCompositeNode lst11_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11"), cont1, + MutableCompositeNode lst11_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); cont1.getChildren().add(lst11_2); - MutableSimpleNode lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_2, + MutableSimpleNode lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_2, (short) 2, ModifyAction.CREATE, null); lst11_2.getChildren().add(lf111_2); // cont111_2 - MutableCompositeNode cont111_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111"), + MutableCompositeNode cont111_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_2, null, ModifyAction.CREATE, null); lst11_2.getChildren().add(cont111_2); - MutableSimpleNode lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111"), + MutableSimpleNode lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"), cont111_2, (int) 1024, ModifyAction.CREATE, null); cont111_2.getChildren().add(lflst1111_2_2); - MutableSimpleNode lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111"), + MutableSimpleNode lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"), cont111_2, (int) 4096, ModifyAction.CREATE, null); cont111_2.getChildren().add(lflst1111_2_3); // lst1111_2 - MutableCompositeNode lst1111_2_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"), + MutableCompositeNode lst1111_2_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_2, null, ModifyAction.CREATE, null); cont111_2.getChildren().add(lst1111_2_1); - MutableSimpleNode lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B"), + MutableSimpleNode lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B","simple:yang:types","2013-11-5"), lst1111_2_1, (short) 4, ModifyAction.CREATE, null); lst1111_2_1.getChildren().add(lf1111B_2_1); lst1111_2_1.init(); - MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"), + MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_2, null, ModifyAction.CREATE, null); cont111_2.getChildren().add(lst1111_2_2); - MutableSimpleNode lf1111A_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A"), + MutableSimpleNode lf1111A_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A","simple:yang:types","2013-11-5"), lst1111_2_2, "lf1111A str12", ModifyAction.CREATE, null); lst1111_2_2.getChildren().add(lf1111A_2_2); lst1111_2_2.init(); @@ -629,7 +630,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { cont111_2.init(); // :cont111_2 - MutableCompositeNode lst112_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst112"), lst11_2, + MutableCompositeNode lst112_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst112","simple:yang:types","2013-11-5"), lst11_2, null, ModifyAction.CREATE, null); lst11_2.getChildren().add(lst112_2); lst112_2.init(); @@ -638,25 +639,25 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { // :lst11_2 // lst11_3 - MutableCompositeNode lst11_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11"), cont1, + MutableCompositeNode lst11_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); cont1.getChildren().add(lst11_3); - MutableSimpleNode lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_3, + MutableSimpleNode lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_3, (short) 3, ModifyAction.CREATE, null); lst11_3.getChildren().add(lf111_3); // cont111_3 - MutableCompositeNode cont111_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111"), + MutableCompositeNode cont111_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_3, null, ModifyAction.CREATE, null); lst11_3.getChildren().add(cont111_3); - MutableCompositeNode lst1111_3_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"), + MutableCompositeNode lst1111_3_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_3, null, ModifyAction.CREATE, null); cont111_3.getChildren().add(lst1111_3_1); lst1111_3_1.init(); - MutableCompositeNode lst1111_3_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"), + MutableCompositeNode lst1111_3_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_3, null, ModifyAction.CREATE, null); cont111_3.getChildren().add(lst1111_3_2); lst1111_3_2.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java index d664001d8c..745f11c210 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java @@ -22,7 +22,10 @@ import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { @@ -71,13 +74,13 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { } private CompositeNode prepareCompositeNode(Object value) { - MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont","identityref:module","2013-12-2"), null, null, ModifyAction.CREATE, null); - MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1"), cont, null, + MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1","identityref:module","2013-12-2"), cont, null, ModifyAction.CREATE, null); cont.getChildren().add(cont1); - MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1, value, + MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1","identityref:module","2013-12-2"), cont1, value, ModifyAction.CREATE, null); cont1.getChildren().add(lf1); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java index d1dca95f43..17d7fe6be0 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java @@ -20,8 +20,13 @@ import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; -import org.opendaylight.controller.sal.restconf.impl.test.*; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.controller.sal.restconf.impl.test.DummyType; +import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; +import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; @@ -39,20 +44,13 @@ public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLo dataLoad("/cnsn-to-json/simple-data-types"); } - // FIXME - @Ignore @Test - public void incorrectTopLevelElementTest() { - + public void incorrectTopLevelElementTest() throws WebApplicationException, IOException { String jsonOutput = null; - try { - jsonOutput = TestUtils - .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), - (Set) Collections.EMPTY_SET, prepareDataSchemaNode(), - StructuredDataToJsonProvider.INSTANCE); - } catch (WebApplicationException | IOException e) { - LOG.error("WebApplicationException or IOException was raised"); - } + jsonOutput = TestUtils + .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), + (Set) Collections.EMPTY_SET, prepareDataSchemaNode(), + StructuredDataToJsonProvider.INSTANCE); assertNotNull(jsonOutput); assertTrue(jsonOutput.contains("\"lf1\": \"\"")); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java index baefd93d18..348edbd294 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java @@ -10,7 +10,6 @@ package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test; import static org.junit.Assert.assertTrue; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -20,19 +19,19 @@ import javax.ws.rs.WebApplicationException; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; -import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; -import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; -import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; +import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.SchemaContext; public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialize() { - dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1"); + dataLoad("/xml-to-cnsn/data-of-several-modules/yang", 2, "module1", "cont_m1"); } @Test @@ -41,15 +40,15 @@ public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataS String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext, StructuredDataToJsonProvider.INSTANCE); -// String output = -// String.format("\"data\" : {\n" + -// "\t\"cont_m1\" : {\n" + -// "\t\t\"lf1_m1\" : \"lf1 m1 value\"\n" + -// "\t}\n" + -// "\t\"cont_m2\" : {\n" + -// "\t\t\"lf1_m2\" : \"lf1 m2 value\"\n" + -// "\t}\n" + -// "}"); + // String output = + // String.format("\"data\" : {\n" + + // "\t\"cont_m1\" : {\n" + + // "\t\t\"lf1_m1\" : \"lf1 m1 value\"\n" + + // "\t}\n" + + // "\t\"cont_m2\" : {\n" + + // "\t\t\"lf1_m2\" : \"lf1 m2 value\"\n" + + // "\t}\n" + + // "}"); StringBuilder regex = new StringBuilder(); regex.append("^"); @@ -57,27 +56,27 @@ public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataS regex.append(".*\"data\""); regex.append(".*:"); regex.append(".*\\{"); - - regex.append(".*\"contB_m1\""); + + regex.append(".*\"cont_m1\""); regex.append(".*:"); regex.append(".*\\{"); regex.append(".*\\}"); - - regex.append(".*\"cont_m1\""); + + regex.append(".*\"contB_m1\""); regex.append(".*:"); regex.append(".*\\{"); regex.append(".*\\}"); - regex.append(".*\"contB_m2\""); + regex.append(".*\"cont_m2\""); regex.append(".*:"); regex.append(".*\\{"); regex.append(".*\\}"); - - regex.append(".*\"cont_m2\""); + + regex.append(".*\"contB_m2\""); regex.append(".*:"); regex.append(".*\\{"); regex.append(".*\\}"); - + regex.append(".*\\}"); regex.append(".*"); @@ -91,24 +90,44 @@ public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataS } private CompositeNode prepareCnSn() throws URISyntaxException { - CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data"); - - URI uriModule1 = new URI("module:one"); - CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1"); - SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value"); - cont_m1.addValue(lf1_m1); - CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1"); - - data.addValue(contB_m1); - data.addValue(cont_m1); - - URI uriModule2 = new URI("module:two"); - CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2"); - SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value"); - cont_m2.addValue(lf1_m2); - CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2"); - data.addValue(contB_m2); - data.addValue(cont_m2); + String uri1 = "module:one"; + String rev1 = "2014-01-17"; + + MutableCompositeNode data = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("data", "urn:ietf:params:xml:ns:netconf:base:1.0", "2000-01-01"), null, null, + null, null); + + MutableCompositeNode cont_m1 = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("cont_m1", uri1, rev1), data, null, null, null); + data.getChildren().add(cont_m1); + + MutableSimpleNode lf1_m1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1_m1", uri1, rev1), + cont_m1, "lf1 m1 value", null, null); + cont_m1.getChildren().add(lf1_m1); + cont_m1.init(); + + MutableCompositeNode contB_m1 = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("contB_m1", uri1, rev1), data, null, null, null); + data.getChildren().add(contB_m1); + contB_m1.init(); + + String uri2 = "module:two"; + String rev2 = "2014-01-17"; + MutableCompositeNode cont_m2 = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("cont_m2", uri2, rev2), data, null, null, null); + data.getChildren().add(cont_m2); + + MutableSimpleNode lf1_m2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1_m2", uri2, rev2), + cont_m1, "lf1 m2 value", null, null); + cont_m2.getChildren().add(lf1_m2); + cont_m2.init(); + + MutableCompositeNode contB_m2 = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("contB_m2", uri2, rev2), data, null, null, null); + data.getChildren().add(contB_m2); + contB_m2.init(); + + data.init(); return data; } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnInstanceIdentifierToXmlTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnInstanceIdentifierToXmlTest.java index 5a81b326ab..92de14bba4 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnInstanceIdentifierToXmlTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnInstanceIdentifierToXmlTest.java @@ -35,7 +35,7 @@ public class CnSnInstanceIdentifierToXmlTest extends YangAndXmlAndDataSchemaLoad @BeforeClass public static void initialization() throws URISyntaxException { - dataLoad("/instanceidentifier/yang", 3, "instance-identifier-module", "cont"); + dataLoad("/instanceidentifier/yang", 4, "instance-identifier-module", "cont"); } @Test diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java index 7da572f45c..18b5ce490f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java @@ -28,43 +28,87 @@ import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; -import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; -import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; +import org.opendaylight.yangtools.yang.data.impl.NodeFactory; public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass public static void initialize() { - dataLoad("/instanceidentifier/yang", 3, "instance-identifier-module", "cont"); + dataLoad("/instanceidentifier/yang", 4, "instance-identifier-module", "cont"); } @Test - public void saveCnSnToXml() throws WebApplicationException, IOException, URISyntaxException, XMLStreamException { - CompositeNode cnSn = prepareCnSn(); + public void saveCnSnToXmlTest() throws WebApplicationException, IOException, URISyntaxException, XMLStreamException { + CompositeNode cnSn = prepareCnSn(createInstanceIdentifier()); String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode, StructuredDataToXmlProvider.INSTANCE); + //uncomment for debug + // System.out.println(output); validateXmlOutput(output); + + } + + @Ignore + @Test + public void saveCnSnWithLeafListInstIdentifierToXmlTest() throws WebApplicationException, IOException, + URISyntaxException, XMLStreamException { + CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList()); + String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode, + StructuredDataToXmlProvider.INSTANCE); + //uncomment for debug // System.out.println(output); + validateXmlOutputWithLeafList(output); + } + + @Test + public void saveCnSnToJsonTest() throws WebApplicationException, IOException, URISyntaxException { + CompositeNode cnSn = prepareCnSn(createInstanceIdentifier()); + String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode, + StructuredDataToJsonProvider.INSTANCE); + boolean strInOutput = false; + strInOutput = output + .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module:lst11[augment-module:keyvalue111=\\\"value1\\\"][augment-module:keyvalue112=\\\"value2\\\"]/augment-augment-module:lf112\""); + if (!strInOutput) { + strInOutput = output + .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module:lst11[augment-module:keyvalue111='value1'][augment-module:keyvalue112='value2']/augment-augment-module:lf112\""); + } + //uncomment for debug + // System.out.println(output); + assertTrue(strInOutput); } + @Test - public void saveCnSnToJson() throws WebApplicationException, IOException, URISyntaxException { - CompositeNode cnSn = prepareCnSn(); + public void saveCnSnWithLeafListInstIdentifierToJsonTest() throws WebApplicationException, IOException, + URISyntaxException { + CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList()); String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode, StructuredDataToJsonProvider.INSTANCE); - assertTrue(output - .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module:lst11[augment-module:keyvalue111=\\\"value1\\\"][augment-module:keyvalue112=\\\"value2\\\"]/augment-augment-module:lf112\"")); + //uncomment for debug // System.out.println(output); + boolean strInOutput = false; + strInOutput = output + .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11[.='lflst11_1']\""); + if (!strInOutput) { + strInOutput = output + .contains("\"augment-augment-module:lf111\": \"/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11[.=\\\"lflst11_1\\\"]\""); + } + + assertTrue(strInOutput); } private void validateXmlOutput(String xml) throws XMLStreamException { @@ -104,21 +148,66 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch + ":lst11[" + aModulePrefix + ":keyvalue111='value1'][" + aModulePrefix + ":keyvalue112='value2']/" + aaModulePrefix + ":lf112"; -// System.out.println(xml); assertTrue(xml.contains(instanceIdentifierValue)); } - private CompositeNode prepareCnSn() throws URISyntaxException { - CompositeNodeWrapper cont = new CompositeNodeWrapper(new URI("instance:identifier:module"), "cont"); - CompositeNodeWrapper cont1 = new CompositeNodeWrapper(new URI("instance:identifier:module"), "cont1"); - CompositeNodeWrapper lst11 = new CompositeNodeWrapper(new URI("augment:module"), "lst11"); - InstanceIdentifier instanceIdentifier = createInstanceIdentifier(); - SimpleNodeWrapper lf111 = new SimpleNodeWrapper(new URI("augment:augment:module"), "lf111", instanceIdentifier); + private void validateXmlOutputWithLeafList(String xml) throws XMLStreamException { + XMLInputFactory xmlInFactory = XMLInputFactory.newInstance(); + XMLEventReader eventReader; - lst11.addValue(lf111); - cont1.addValue(lst11); - cont.addValue(cont1); + eventReader = xmlInFactory.createXMLEventReader(new ByteArrayInputStream(xml.getBytes())); + String aModuleLfLstPrefix = null; + String iiModulePrefix = null; + while (eventReader.hasNext()) { + XMLEvent nextEvent = eventReader.nextEvent(); + if (nextEvent.isStartElement()) { + StartElement startElement = (StartElement) nextEvent; + if (startElement.getName().getLocalPart().equals("lf111")) { + Iterator prefixes = startElement.getNamespaceContext().getPrefixes("augment:module:leaf:list"); + + while (prefixes.hasNext() && aModuleLfLstPrefix == null) { + String prefix = (String) prefixes.next(); + if (!prefix.isEmpty()) { + aModuleLfLstPrefix = prefix; + } + } + iiModulePrefix = startElement.getNamespaceContext().getPrefix("instance:identifier:module"); + break; + } + } + } + + assertNotNull(aModuleLfLstPrefix); + assertNotNull(iiModulePrefix); + + String instanceIdentifierValue = "/" + iiModulePrefix + ":cont/" + iiModulePrefix + ":cont1/" + + aModuleLfLstPrefix + ":lflst11[.='lflst11_1']"; + + assertTrue(xml.contains(instanceIdentifierValue)); + + } + + private CompositeNode prepareCnSn(InstanceIdentifier instanceIdentifier) throws URISyntaxException { + MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("cont", "instance:identifier:module", "2014-01-17"), null, null,null,null); + MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("cont1", "instance:identifier:module", "2014-01-17"), cont, null,null,null); + MutableCompositeNode lst11 = NodeFactory.createMutableCompositeNode( + TestUtils.buildQName("lst11", "augment:module", "2014-01-17"), cont1, null,null,null); + + MutableSimpleNode lf111 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111", "augment:augment:module", "2014-01-17"), + lst11, instanceIdentifier,null,null); + + + lst11.getChildren().add(lf111); + lst11.init(); + + cont1.getChildren().add(lst11); + cont1.init(); + + cont.getChildren().add(cont1); + cont.init(); return cont; } @@ -140,4 +229,13 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch return new InstanceIdentifier(pathArguments); } + private InstanceIdentifier createInstanceIdentifierWithLeafList() throws URISyntaxException { + List pathArguments = new ArrayList<>(); + pathArguments.add(new NodeIdentifier(new QName(new URI("instance:identifier:module"), "cont"))); + pathArguments.add(new NodeIdentifier(new QName(new URI("instance:identifier:module"), "cont1"))); + pathArguments.add(new NodeWithValue(new QName(new URI("augment:module:leaf:list"), "lflst11"), "lflst11_1")); + + return new InstanceIdentifier(pathArguments); + } + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java index 2a8ab7a344..e1d7e6a624 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java @@ -72,9 +72,9 @@ public class MediaTypesTest extends JerseyTest { String uriPath = "ietf-interfaces:interfaces"; String uri = createUri(uriPrefix, uriPath); when(restconfService.invokeRpc(eq(uriPath), any(CompositeNode.class))).thenReturn(null); - post(uri, Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+JSON, jsonData); + post(uri, Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+JSON, jsonData); verify(restconfService, times(1)).invokeRpc(eq(uriPath), any(CompositeNode.class)); - post(uri, Draft02.MediaTypes.DATA+XML, Draft02.MediaTypes.DATA+XML, xmlData); + post(uri, Draft02.MediaTypes.OPERATION+XML, Draft02.MediaTypes.OPERATION+XML, xmlData); verify(restconfService, times(2)).invokeRpc(eq(uriPath), any(CompositeNode.class)); post(uri, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, jsonData); verify(restconfService, times(3)).invokeRpc(eq(uriPath), any(CompositeNode.class)); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java index 76ec65c712..be7be9444c 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java @@ -11,7 +11,6 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri; import java.io.FileNotFoundException; @@ -20,21 +19,16 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; -import org.glassfish.jersey.test.TestProperties; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.core.api.mount.MountInstance; import org.opendaylight.controller.sal.core.api.mount.MountService; -import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; @@ -84,24 +78,6 @@ public class RestGetOperationTest extends JerseyTest { return resourceConfig; } - /** - * Tests of status codes for "/datastore/{identifier}". - */ - @Test - public void getDatastoreStatusCodes() throws FileNotFoundException, UnsupportedEncodingException { - mockReadOperationalDataMethod(); - String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0"); - assertEquals(200, get(uri, MediaType.APPLICATION_XML)); - - uri = createUri("/datastore/", "wrong-module:interfaces/interface/eth0"); - assertEquals(400, get(uri, MediaType.APPLICATION_XML)); - - // Test of request for not existing data. Returning status code 404 - uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0"); - when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null); - assertEquals(404, get(uri, MediaType.APPLICATION_XML)); - } - /** * Tests of status codes for "/operational/{identifier}". */ diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java index ab63fbc547..050aa9ab24 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java @@ -14,7 +14,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML; -import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri; import java.io.IOException; import java.io.InputStream; @@ -29,7 +28,6 @@ import java.util.concurrent.Future; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; @@ -43,7 +41,6 @@ import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; -import org.opendaylight.controller.sal.rest.impl.XmlMapper; import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper; @@ -153,20 +150,6 @@ public class RestPostOperationTest extends JerseyTest { assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataInterfaceAbsolutePath)); } - @Test - public void postDatastoreStatusCodes() throws UnsupportedEncodingException { - controllerContext.setSchemas(schemaContextYangsIetf); - mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED); - String uri = createUri("/datastore/", "ietf-interfaces:interfaces"); - assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataInterfaceAbsolutePath)); - - mockCommitConfigurationDataPostMethod(null); - assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataInterfaceAbsolutePath)); - - mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED); - assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataInterfaceAbsolutePath)); - } - @Test public void postDataViaUrlMountPoint() throws UnsupportedEncodingException { controllerContext.setSchemas(schemaContextYangsIetf); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java index 5d7eb20c42..2ba4a38c88 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java @@ -11,7 +11,6 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML; import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri; import java.io.FileNotFoundException; @@ -24,17 +23,14 @@ import java.util.concurrent.Future; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; import org.opendaylight.controller.sal.core.api.mount.MountInstance; import org.opendaylight.controller.sal.core.api.mount.MountService; -import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; @@ -107,19 +103,6 @@ public class RestPutOperationTest extends JerseyTest { assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData)); } - /** - * Tests of status codes for "/datastore/{identifier}". - */ - @Test - public void putDatastoreStatusCodes() throws UnsupportedEncodingException { - String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0"); - mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED); - assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData)); - - mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED); - assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData)); - } - @Test public void testRpcResultCommitedToStatusCodesWithMountPoint() throws UnsupportedEncodingException, FileNotFoundException, URISyntaxException { @@ -131,10 +114,6 @@ public class RestPutOperationTest extends JerseyTest { brokerFacade.commitConfigurationDataPutBehindMountPoint(any(MountInstance.class), any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture); - InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/full-versions/test-data2/data2.xml"); - String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream)); - Entity entity = Entity.entity(xml, Draft02.MediaTypes.DATA + XML); - MountInstance mountInstance = mock(MountInstance.class); when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule); MountService mockMountService = mock(MountService.class); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnInstanceIdentifierTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnInstanceIdentifierTest.java index e8d03fbe39..5476d71320 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnInstanceIdentifierTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnInstanceIdentifierTest.java @@ -26,6 +26,7 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.SimpleNode; @@ -33,7 +34,7 @@ public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSch @BeforeClass public static void initialize() { - dataLoad("/instanceidentifier/yang", 3, "instance-identifier-module", "cont"); + dataLoad("/instanceidentifier/yang", 4, "instance-identifier-module", "cont"); } @Test @@ -41,7 +42,15 @@ public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSch CompositeNode cnSn = TestUtils.readInputToCnSn("/instanceidentifier/xml/xmldata.xml", XmlToCompositeNodeProvider.INSTANCE); TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath); - verify(cnSn); + verifyListPredicate(cnSn); + } + + @Test + public void loadXmlLeafListToCnSn() throws WebApplicationException, IOException, URISyntaxException { + CompositeNode cnSn = TestUtils.readInputToCnSn("/instanceidentifier/xml/xmldata_leaf_list.xml", + XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath); + verifyLeafListPredicate(cnSn); } @Test @@ -49,11 +58,40 @@ public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSch CompositeNode cnSn = TestUtils.readInputToCnSn("/instanceidentifier/json/jsondata.json", JsonToCompositeNodeProvider.INSTANCE); TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath); - verify(cnSn); + verifyListPredicate(cnSn); } - private void verify(CompositeNode cnSn) throws URISyntaxException { - SimpleNode lf111 = getSnWithInstanceIdentifier(cnSn); + @Test + public void loadJsonLeafListToCnSn() throws WebApplicationException, IOException, URISyntaxException { + CompositeNode cnSn = TestUtils.readInputToCnSn("/instanceidentifier/json/jsondata_leaf_list.json", + JsonToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath); + verifyLeafListPredicate(cnSn); + } + + private void verifyLeafListPredicate(CompositeNode cnSn) throws URISyntaxException { + SimpleNode lf11 = getSnWithInstanceIdentifierWhenLeafList(cnSn); + Object value = lf11.getValue(); + assertTrue(value instanceof InstanceIdentifier); + + InstanceIdentifier instanceIdentifier = (InstanceIdentifier) value; + List pathArguments = instanceIdentifier.getPath(); + assertEquals(3, pathArguments.size()); + String revisionDate = "2014-01-17"; + assertEquals(TestUtils.buildQName("cont", "instance:identifier:module", revisionDate), pathArguments.get(0) + .getNodeType()); + assertEquals(TestUtils.buildQName("cont1", "instance:identifier:module", revisionDate), pathArguments.get(1) + .getNodeType()); + assertEquals(TestUtils.buildQName("lflst11", "augment:module:leaf:list", "2014-01-27"), pathArguments.get(2) + .getNodeType()); + + assertTrue(pathArguments.get(2) instanceof NodeWithValue); + assertEquals("lflst11_1", ((NodeWithValue) pathArguments.get(2)).getValue()); + + } + + private void verifyListPredicate(CompositeNode cnSn) throws URISyntaxException { + SimpleNode lf111 = getSnWithInstanceIdentifierWhenList(cnSn); Object value = lf111.getValue(); assertTrue(value instanceof InstanceIdentifier); @@ -76,7 +114,7 @@ public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSch assertEquals("value2", predicates.get(TestUtils.buildQName("keyvalue112", "augment:module", revisionDate))); } - private SimpleNode getSnWithInstanceIdentifier(CompositeNode cnSn) throws URISyntaxException { + private SimpleNode getSnWithInstanceIdentifierWhenList(CompositeNode cnSn) throws URISyntaxException { CompositeNode cont1 = cnSn.getFirstCompositeByName(TestUtils.buildQName("cont1", "instance:identifier:module", "2014-01-17")); assertNotNull(cont1); @@ -89,4 +127,14 @@ public class XmlAndJsonToCnSnInstanceIdentifierTest extends YangAndXmlAndDataSch return lf111; } + private SimpleNode getSnWithInstanceIdentifierWhenLeafList(CompositeNode cnSn) throws URISyntaxException { + CompositeNode cont1 = cnSn.getFirstCompositeByName(TestUtils.buildQName("cont1", "instance:identifier:module", + "2014-01-17")); + assertNotNull(cont1); + SimpleNode lf11 = cont1.getFirstSimpleByName(TestUtils.buildQName("lf11", "augment:module:leaf:list", + "2014-01-27")); + assertNotNull(lf11); + return lf11; + } + } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/json/jsondata_leaf_list.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/json/jsondata_leaf_list.json new file mode 100644 index 0000000000..63be4b9d5d --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/json/jsondata_leaf_list.json @@ -0,0 +1,7 @@ +{ + "instance-identifier-module:cont": { + "cont1": { + "augment-module-leaf-list:lf11" : "/instance-identifier-module:cont/instance-identifier-module:cont1/augment-module-leaf-list:lflst11[.=\"lflst11_1\"]" + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/xml/xmldata_leaf_list.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/xml/xmldata_leaf_list.xml new file mode 100644 index 0000000000..00d58c2cb7 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/xml/xmldata_leaf_list.xml @@ -0,0 +1,8 @@ + + + lflst11_1 + lflst11_2 + lflst11_3 + /a:cont/a:cont1/b:lflst11[.="lflst11_1"] + + diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/yang/augment-module-leaf-list.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/yang/augment-module-leaf-list.yang new file mode 100644 index 0000000000..54c305b208 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/instanceidentifier/yang/augment-module-leaf-list.yang @@ -0,0 +1,20 @@ +module augment-module-leaf-list { + namespace "augment:module:leaf:list"; + + prefix "amodulelflst"; + + import instance-identifier-module {prefix imodule; revision-date 2014-01-17;} + + revision 2014-01-27 { + } + + augment "/imodule:cont/imodule:cont1" { + leaf-list lflst11 { + type string; + } + leaf lf11 { + type instance-identifier; + } + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java index 19f25944b4..5f264abc2c 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java @@ -412,8 +412,6 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList cache.put(notification.getId(), new NodeStatisticsAger(statisticsManager,key)); } NodeStatisticsAger nsa = cache.get(notification.getId()); - FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flowRule); - cache.get(notification.getId()).updateFlowStats(flowStatsEntry); //Augment the data to the flow node @@ -466,6 +464,11 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); sucLogger.debug("Found matching flow in the datastore, augmenting statistics"); foundOriginalFlow = true; + // Update entry with timestamp of latest response + flow.setKey(existingFlow.getKey()); + FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build()); + cache.get(notification.getId()).updateFlowStats(flowStatsEntry); + it.putOperationalData(flowRef, flowBuilder.build()); it.commit(); } @@ -490,6 +493,12 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); sucLogger.debug("Found matching unaccounted flow in the operational datastore, augmenting statistics"); foundOriginalFlow = true; + + // Update entry with timestamp of latest response + flow.setKey(existingFlow.getKey()); + FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build()); + cache.get(notification.getId()).updateFlowStats(flowStatsEntry); + it.putOperationalData(flowRef, flowBuilder.build()); it.commit(); break; @@ -498,9 +507,9 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList } } if(!foundOriginalFlow){ - long flowKey = Long.parseLong(new String("1"+Short.toString(tableId)+"0"+Integer.toString(this.unaccountedFlowsCounter))); + String flowKey = "#UF$TABLE*"+Short.toString(tableId)+"*"+Integer.toString(this.unaccountedFlowsCounter); this.unaccountedFlowsCounter++; - FlowKey newFlowKey = new FlowKey(new FlowId(Long.toString(flowKey))); + FlowKey newFlowKey = new FlowKey(new FlowId(flowKey)); InstanceIdentifier flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key) .augmentation(FlowCapableNode.class) .child(Table.class, new TableKey(tableId)) @@ -508,6 +517,12 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList flowBuilder.setKey(newFlowKey); flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); sucLogger.debug("Flow {} is not present in config data store, augmenting statistics as an unaccounted flow",flowBuilder.build()); + + // Update entry with timestamp of latest response + flow.setKey(newFlowKey); + FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flow.build()); + cache.get(notification.getId()).updateFlowStats(flowStatsEntry); + it.putOperationalData(flowRef, flowBuilder.build()); it.commit(); } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java index 53e14ba5fb..13f8cad968 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java @@ -67,7 +67,7 @@ public class NetconfOperationServiceImplTest { try { NetconfOperationServiceImpl.checkConsistencyBetweenYangStoreAndConfig(mockJmxClient("qname1"), mockYangStoreSnapshot("qname2", "qname1")); - fail("An exception of type " + IllegalArgumentException.class + " was expected"); + fail("An exception of type " + IllegalStateException.class + " was expected"); } catch (IllegalStateException e) { String message = e.getMessage(); Assert.assertThat( diff --git a/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml b/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml index 37db39f8c1..c6111ab395 100644 --- a/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml +++ b/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml @@ -30,53 +30,10 @@ org.opendaylight.yangtools yang-maven-plugin - ${yangtools.version} - - - - generate-sources - - - src/main/yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - - - ${project.build.directory}/generated-sources/monitoring - - - - true - - - - - - org.opendaylight.yangtools - maven-sal-api-gen-plugin - ${yangtools.version} - - org.codehaus.mojo build-helper-maven-plugin - 1.7 - - - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/monitoring - - - - diff --git a/opendaylight/netconf/ietf-netconf-monitoring/pom.xml b/opendaylight/netconf/ietf-netconf-monitoring/pom.xml index a068edf0a9..e6a186c881 100644 --- a/opendaylight/netconf/ietf-netconf-monitoring/pom.xml +++ b/opendaylight/netconf/ietf-netconf-monitoring/pom.xml @@ -37,53 +37,10 @@ org.opendaylight.yangtools yang-maven-plugin - ${yangtools.version} - - - - generate-sources - - - src/main/yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - - - ${project.build.directory}/generated-sources/monitoring - - - - true - - - - - - org.opendaylight.yangtools - maven-sal-api-gen-plugin - ${yangtools.version} - - org.codehaus.mojo build-helper-maven-plugin - 1.7 - - - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/monitoring - - - - diff --git a/opendaylight/netconf/pom.xml b/opendaylight/netconf/pom.xml index 6fef98ff36..2c2ef3b507 100644 --- a/opendaylight/netconf/pom.xml +++ b/opendaylight/netconf/pom.xml @@ -50,6 +50,7 @@ 4.0.10.Final 0.2.4-SNAPSHOT 0.2.4-SNAPSHOT + ${project.build.directory}/generated-sources/sal @@ -225,6 +226,61 @@ + + org.opendaylight.yangtools + yang-maven-plugin + ${yangtools.version} + + + + generate-sources + + + src/main/yang + + + + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + + + ${salGeneratorPath} + + + + org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl + ${project.build.directory}/site/models + + + true + + + + + + org.opendaylight.yangtools + maven-sal-api-gen-plugin + ${yangtools.version} + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + generate-sources + + add-source + + + + ${salGeneratorPath} + + + + + diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SecureMessageReadWriteService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SecureMessageReadWriteService.java index 90b47cf264..d60bcab8b3 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SecureMessageReadWriteService.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SecureMessageReadWriteService.java @@ -407,9 +407,9 @@ public class SecureMessageReadWriteService implements IMessageReadWrite { this.myAppData = ByteBuffer .allocate(session.getApplicationBufferSize()); this.peerAppData = ByteBuffer.allocate(session - .getApplicationBufferSize()); + .getApplicationBufferSize() * 2); this.myNetData = ByteBuffer.allocate(session.getPacketBufferSize()); - this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize()); + this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize() * 2); } @Override diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java index 78a2ea5120..6d1c563aa4 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java @@ -539,7 +539,7 @@ public class FlowConverter { salMatch.setField(new MatchField(MatchType.DL_VLAN, vlan)); } - if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) { + if ((ofMatch.getWildcards() & OFMatch.OFPFW_DL_VLAN_PCP) == 0) { salMatch.setField(MatchType.DL_VLAN_PR, ofMatch .getDataLayerVirtualLanPriorityCodePoint()); } @@ -612,7 +612,7 @@ public class FlowConverter { salMatch.setField(new MatchField(MatchType.DL_VLAN, vlan)); } - if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) { + if ((v6Match.getWildcards() & OFMatch.OFPFW_DL_VLAN_PCP) == 0) { salMatch.setField(MatchType.DL_VLAN_PR, v6Match .getDataLayerVirtualLanPriorityCodePoint()); } diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java index 4daa591ba1..cfe20a1fa2 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java @@ -216,7 +216,7 @@ public class V6Match extends OFMatch implements Cloneable { this.dlVlanIDState = MatchFieldState.MATCH_ABSENT; } - if (match.getDataLayerVirtualLanPriorityCodePoint() != 0) { + if ((match.getWildcards() & OFMatch.OFPFW_DL_VLAN_PCP) == 0) { this.setDataLayerVirtualLanPriorityCodePoint( match.getDataLayerVirtualLanPriorityCodePoint(), (byte) 0); } else { @@ -839,14 +839,12 @@ public class V6Match extends OFMatch implements Cloneable { // extract the vlan id super.setDataLayerVirtualLan(getVlanID(firstByte, secondByte)); - } else { this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match } if ((this.dataLayerVirtualLanTCIMask & 0xe000) != 0) { // else if its a vlan pcp mask // extract the vlan pcp super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte)); - } else { this.wildcards ^= (1 << 20); } this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK; @@ -864,6 +862,8 @@ public class V6Match extends OFMatch implements Cloneable { super.setDataLayerVirtualLan(getVlanID(firstByte, secondByte)); this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY; this.match_len += 6; + this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match + this.wildcards ^= (1 << 20); } } } @@ -1216,8 +1216,6 @@ public class V6Match extends OFMatch implements Cloneable { // ipv4 dest processing this.wildcards ^= (((1 << 5) - 1) << 14); } - } else { - this.wildcards = 0; } } diff --git a/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerServiceTest.java b/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerServiceTest.java index a751948de7..96f0d80022 100644 --- a/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerServiceTest.java +++ b/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerServiceTest.java @@ -18,9 +18,6 @@ import java.util.List; import org.junit.Assert; import org.junit.Test; import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match; -import org.openflow.protocol.OFMatch; -import org.openflow.protocol.action.OFAction; - import org.opendaylight.controller.sal.action.Action; import org.opendaylight.controller.sal.action.Flood; import org.opendaylight.controller.sal.action.FloodAll; @@ -46,6 +43,9 @@ import org.opendaylight.controller.sal.utils.EtherTypes; import org.opendaylight.controller.sal.utils.IPProtocols; import org.opendaylight.controller.sal.utils.NodeConnectorCreator; import org.opendaylight.controller.sal.utils.NodeCreator; +import org.openflow.protocol.OFMatch; +import org.openflow.protocol.action.OFAction; +import org.openflow.util.U32; public class FlowProgrammerServiceTest { @@ -298,6 +298,16 @@ public class FlowProgrammerServiceTest { */ FlowConverter salToOF = new FlowConverter(aFlow); V6Match v6Match = (V6Match) salToOF.getOFMatch(); + // need this hardcoding here to make the test pass. + // this should not be a problem in actual code. + // in the test the sal match is converted to a V6 match. + // we lose the wildcard info as the V6 match is used for nicira extensions + // and nicira deals with wildcards in a different way. + // converting the V6 match back to sal match is not going to preserve the wildcard info. + // and we need the wildcard info for reading the vlan pcp now. + // when creating a V6Match using the readFrom method + // we do convert the nicira extensions format correctly to populate the wildcard info. + v6Match.setWildcards(U32.t(Long.valueOf(~OFMatch.OFPFW_DL_VLAN_PCP))); List ofActions = salToOF.getOFActions(); /* diff --git a/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java b/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java index 7782aa9093..abbc43809d 100644 --- a/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java +++ b/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java @@ -17,6 +17,7 @@ import java.util.Arrays; import org.junit.Assert; import org.junit.Test; import org.openflow.protocol.OFMatch; +import org.openflow.util.U32; public class V6ExtensionTest { @@ -52,20 +53,18 @@ public class V6ExtensionTest { match.fromString("input_port=1"); match.fromString("dl_dst=20:A0:11:10:00:99"); match.fromString("dl_src=00:10:08:22:12:75"); - match.fromString("ip_src=10.1.1.1"); match.fromString("ip_dst=1.2.3.4"); match.fromString("eth_type=0x800"); match.fromString("dl_vlan=10"); - match.fromString("dl_vpcp=1"); match.fromString("nw_proto=6"); match.fromString("nw_tos=100"); match.fromString("tp_dst=8080"); match.fromString("tp_src=60"); + match.fromString("dl_vpcp=1"); Assert.assertTrue(match.getInputPort() == 1); // Assert.assertTrue(match.getIPv6MatchLen()==6); - ofm.setInputPort((short) 1); // V6Match is meant for IPv6, but if using OFMatch, it will be set to // IPv4 values, as OF1.0 doesn't support IPv6. @@ -89,6 +88,13 @@ public class V6ExtensionTest { ofm.setTransportSource((short) 60); ofm.setTransportDestination((short) 8080); + // this v6match ctor now looks at the wildcard field to + // determine if vlan pcp has been set + // so set the wildcards appropriately to reflect that vlan pcp + // has been set. + int wildcards = OFMatch.OFPFW_ALL; + wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP; + ofm.setWildcards(U32.t(Long.valueOf(wildcards))); V6Match match3 = new V6Match(ofm); Assert.assertTrue(match.getInputPort() == match3.getInputPort()); diff --git a/opendaylight/web/root/src/main/resources/js/lib.js b/opendaylight/web/root/src/main/resources/js/lib.js index 00eacdfce6..c265760b97 100644 --- a/opendaylight/web/root/src/main/resources/js/lib.js +++ b/opendaylight/web/root/src/main/resources/js/lib.js @@ -373,11 +373,11 @@ one.lib.nav = { one.lib.helper = { parseInt : function(value) { - return (value !== null && value !== '') ? + return (value != null && value.trim() !== '') ? parseInt(value) : '' }, parseFloat : function(value) { - return (value !== null && value !== '') ? + return (value != null && value.trim() !== '') ? parseFloat(value) : '' } } diff --git a/opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java b/opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java index e46b89ac2a..36b5043dd9 100644 --- a/opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java +++ b/opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java @@ -62,7 +62,7 @@ import org.springframework.web.bind.annotation.ResponseBody; public class Troubleshoot implements IDaylightWeb { private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER; private static final List flowStatsColumnNames = Arrays.asList("Node", "In Port", - "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst", + "DL Src", "DL Dst", "DL Type", "DL Vlan","Vlan Priority", "NW Src", "NW Dst","ToS Bits", "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets", "Time (s)", "Timeout (s)", "Priority"); @@ -229,6 +229,7 @@ public class Troubleshoot implements IDaylightWeb { private Map convertPortsStatistics( NodeConnectorStatistics ncStats, String containerName) { + Map row = new HashMap(); ISwitchManager switchManager = (ISwitchManager) ServiceHelper @@ -313,6 +314,19 @@ public class Troubleshoot implements IDaylightWeb { } else { row.put(MatchType.DL_VLAN.id(), "*"); } + //Vlan Priority + if (match.isPresent(MatchType.DL_VLAN_PR)) { + if (((Byte) flow.getMatch().getField(MatchType.DL_VLAN_PR).getValue()) + .shortValue() < 0) { + row.put(MatchType.DL_VLAN_PR.id(), "0"); + } else { + row.put(MatchType.DL_VLAN_PR.id(), ((Byte) flow.getMatch() + .getField(MatchType.DL_VLAN_PR).getValue()).toString()); + } + } else { + row.put(MatchType.DL_VLAN_PR.id(), "*"); + } + if (match.isPresent(MatchType.NW_SRC)) { row.put(MatchType.NW_SRC.id(), ((InetAddress) flow.getMatch() .getField(MatchType.NW_SRC).getValue()).getHostAddress()); @@ -325,6 +339,12 @@ public class Troubleshoot implements IDaylightWeb { } else { row.put(MatchType.NW_DST.id(), "*"); } + if (match.isPresent(MatchType.NW_TOS)) { + row.put(MatchType.NW_TOS.id(), ((Byte) flow.getMatch() + .getField(MatchType.NW_TOS).getValue()).toString()); + } else { + row.put(MatchType.NW_TOS.id(), "*"); + } if (match.isPresent(MatchType.NW_PROTO)) { row.put(MatchType.NW_PROTO.id(), IPProtocols.getProtocolName(((Byte) flow.getMatch() @@ -400,7 +420,7 @@ public class Troubleshoot implements IDaylightWeb { row.put("durationSeconds", ((Integer) flowOnNode.getDurationSeconds()).toString()); row.put("idleTimeout", ((Short) flow.getIdleTimeout()).toString()); - row.put("priority", String.valueOf(flow.getPriority())); + row.put("priority", String.valueOf(NetUtils.getUnsignedShort(flow.getPriority()))); return row; } diff --git a/opendaylight/web/troubleshoot/src/main/resources/js/page.js b/opendaylight/web/troubleshoot/src/main/resources/js/page.js index a8673b0031..4bc4c76fc4 100644 --- a/opendaylight/web/troubleshoot/src/main/resources/js/page.js +++ b/opendaylight/web/troubleshoot/src/main/resources/js/page.js @@ -363,6 +363,11 @@ one.f.troubleshooting.existingNodes = { label: 'DL Vlan', sortable: true }, + { + property: 'dlVlanPriority', + label: 'Vlan PCP', + sortable: true + }, { property: 'nwSrc', label: 'NW Src', @@ -373,6 +378,11 @@ one.f.troubleshooting.existingNodes = { label: 'NW Dst', sortable: true }, + { + property: 'nwTOS', + label: 'ToS Bits', + sortable: true + }, { property: 'nwProto', label: 'NW Proto', @@ -437,6 +447,7 @@ one.f.troubleshooting.existingNodes = { entry.push(value["dlVlan"]); entry.push(value["nwSrc"]); entry.push(value["nwDst"]); + entry.push(value["nwTOS"]); entry.push(value["nwProto"]); entry.push(value["tpSrc"]); entry.push(value["tpDst"]);