File[] sourceFiles = sourceDirectory.listFiles();
for (File sourceFile: sourceFiles) {
- if(sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) {
- File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt"));
- if (stubFile.exists()) {
- try {
- rewrite(sourceFile, FileUtils.readFileToString(stubFile));
- } catch (IOException e) {
- getLog().error("Error while reading/writing to files.", e);
+ if (sourceFile.getName().endsWith(".java")) {
+ String sourceContent;
+ try {
+ sourceContent = FileUtils.readFileToString(sourceFile);
+ } catch (IOException e) {
+ getLog().error("Cannot read " + sourceFile.getAbsolutePath(), e);
+ continue;
+ }
+ if (sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) {
+ File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt"));
+ if (stubFile.exists()) {
+ String stubContent = null;
+ try {
+ stubContent = FileUtils.readFileToString(stubFile);
+ } catch (IOException e) {
+ getLog().error("Cannot read " + stubFile.getAbsolutePath(), e);
+ }
+ if (stubContent != null) {
+ sourceContent = rewriteStub(sourceContent, stubContent);
+ }
}
}
+ // remove copyright headers as they can contain timestamp
+ sourceContent = removeCopyrights(sourceContent);
+
+ // replace the file content
+ try {
+ FileUtils.write(sourceFile, sourceContent);
+ } catch (IOException e) {
+ getLog().error("Cannot write " + sourceFile.getAbsolutePath(), e);
+ }
}
+
}
}
- private static void rewrite(File sourceFile, String replaceTODOWith) throws IOException {
- String source = FileUtils.readFileToString(sourceFile);
- String target = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE).matcher(source).replaceFirst(replaceTODOWith);
- FileUtils.write(sourceFile, target);
+ private static Pattern MULTILINE_COMMENT_PATTERN = Pattern.compile("/\\*.*\\*/", Pattern.MULTILINE | Pattern.DOTALL);
+ private static String removeCopyrights(String source) {
+ String target = MULTILINE_COMMENT_PATTERN.matcher(source).replaceAll("\n");
+ //FileUtils.write(sourceFile, target);
+ return target;
+ }
+
+ private static Pattern UNSUPPORTED_OP_PATTERN = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE);
+
+ private static String rewriteStub(String source, String replaceTODOWith) {
+ String target = UNSUPPORTED_OP_PATTERN.matcher(source).replaceFirst(replaceTODOWith);
+ return target;
}
}
-/*
-* 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.yang.test.impl;
public class DepTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModule {
public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-dep
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 11:50:32 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
package org.opendaylight.controller.config.yang.test.impl;
public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory {
-/*
-* 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.yang.test.impl;
public class IdentityTestModule extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModule {
public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-identity-test
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 11:50:32 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
package org.opendaylight.controller.config.yang.test.impl;
public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory {
-/*
-* 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.yang.test.impl;
public class NetconfTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModule {
public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-netconf
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 11:50:32 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
package org.opendaylight.controller.config.yang.test.impl;
public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory {
-/*
- * 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.yang.test.impl;
import com.google.common.collect.Lists;
-/*
-* 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.yang.test.impl;
public class TestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModule {
public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 11:50:32 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
package org.opendaylight.controller.config.yang.test.impl;
public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory {
netconf.ssh.address=0.0.0.0
netconf.ssh.port=1830
netconf.ssh.pk.path = ./configuration/RSA.pk
+netconf.ssh.default.user = netconf
+netconf.ssh.default.password = netconf
netconf.config.persister.active=1,2
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
<name>yang-schema-service</name>
</module>
- <!-- To enable use of new in-memory datastore and new implementations
- of data brokers, comment out all parts of this
- xml which are marked with DATA-BROKER and uncomment all parts
- of this xml which are marked with NEW-DATA-BROKER
- -->
- <!-- DATA-BROKER start-->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
- <name>hash-map-data-store</name>
- </module>
- <!-- DATA BROKER end -->
- <!-- NEW-DATA-BROKER start -->
- <!--
<module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
- <name>async-data-broker</name>
- <schema-service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
- <name>yang-schema-service</name>
- </schema-service>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+ <name>runtime-mapping-singleton</name>
</module>
- -->
- <!-- NEW-DATA-BROKER end -->
<module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
- <name>dom-broker</name>
- <!-- DATA-BROKER start -->
- <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
- <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
- <name>hash-map-data-store</name>
- <!-- <name>cluster-data-store</name> -->
- </data-store>
- <!-- DATA-BROKER end -->
- <!-- NEW-DATA-BROKER start -->
- <!--
- <async-data-broker>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
- <name>async-data-broker</name>
- </async-data-broker>
- -->
- <!-- NEW-DATA-BROKER end -->
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+ <name>binding-notification-broker</name>
</module>
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
<name>binding-data-broker</name>
</data-broker>
</module>
+
+ <!--
+ Tree-based in-memory data store. This is the data store which is currently
+ recommended for single-node deployments.
+ -->
<module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
- <name>runtime-mapping-singleton</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
- <name>binding-notification-broker</name>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
+ <name>inmemory-data-broker</name>
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
</module>
- <!-- DATA-BROKER start -->
<module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
- <name>binding-data-broker</name>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-broker>
- <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
- <name>runtime-mapping-singleton</name>
- </mapping-service>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+ <name>inmemory-dom-broker</name>
+ <async-data-broker>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+ <name>inmemory-data-broker</name>
+ </async-data-broker>
</module>
- <!-- DATA-BROKER end -->
- <!-- NEW-DATA-BROKER start -->
- <!--
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-compatible-broker</type>
- <name>binding-data-broker</name>
+ <name>inmemory-binding-data-broker</name>
<dom-async-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
<name>dom-broker</name>
<name>runtime-mapping-singleton</name>
</binding-mapping-service>
</module>
- -->
- <!-- NEW-DATA-BROKER end -->
</modules>
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
- <instance>
- <name>yang-schema-service</name>
- <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
- <instance>
- <name>binding-notification-broker</name>
- <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
- </instance>
- </service>
- <!-- DATA-BROKER start -->
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
- <instance>
- <name>hash-map-data-store</name>
- <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
- </instance>
- </service>
- <!-- DATA-BROKER end -->
- <!-- NEW-DATA-BROKER start -->
- <!--
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
- <instance>
- <name>async-data-broker</name>
- <provider>/modules/module[type='dom-inmemory-data-broker'][name='async-data-broker']</provider>
- </instance>
- </service>
- -->
- <!-- NEW-DATA-BROKER end -->
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
- <instance>
- <name>binding-osgi-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
- <instance>
- <name>binding-rpc-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
- <instance>
- <name>runtime-mapping-singleton</name>
- <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
- <instance>
- <name>dom-broker</name>
- <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
- </instance>
- </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <instance>
+ <name>yang-schema-service</name>
+ <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+ <instance>
+ <name>runtime-mapping-singleton</name>
+ <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+ <instance>
+ <name>binding-notification-broker</name>
+ <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+ <instance>
+ <name>binding-osgi-broker</name>
+ <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <instance>
+ <name>binding-rpc-broker</name>
+ <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+ </instance>
+ </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
- <instance>
- <name>binding-data-broker</name>
- <!-- DATA-BROKER start -->
- <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
- <!-- DATA-BROKER end -->
- <!-- NEW-DATA-BROKER start -->
- <!--
- <provider>/modules/module[type='binding-data-compatible-broker'][name='binding-data-broker']</provider>
- -->
- <!-- NEW-DATA-BROKER end -->
- </instance>
- </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+ <instance>
+ <name>dom-broker</name>
+ <provider>/modules/module[type='dom-broker-impl'][name='inmemory-dom-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+ <instance>
+ <name>binding-data-broker</name>
+ <provider>/modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker']</provider>
+ </instance>
+ </service>
+
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+ <instance>
+ <name>inmemory-data-broker</name>
+ <provider>/modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker']</provider>
+ </instance>
+ </service>
</services>
</data>
</configuration>
--- /dev/null
+/*
+ * 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.compatibility.topology;
+
+import static org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.toAdEdge;
+import static org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.toTopoEdgeUpdate;
+
+import java.util.Map.Entry;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService;
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TopologyCommitHandler implements DataChangeListener {
+ private static final Logger LOG = LoggerFactory.getLogger(TopologyCommitHandler.class);
+
+ private IPluginOutTopologyService topologyPublisher;
+
+ private final DataProviderService dataService;
+
+ public TopologyCommitHandler(final DataProviderService dataService, final IPluginOutTopologyService topologyPub) {
+ this.topologyPublisher = topologyPub;
+ this.dataService = dataService;
+ }
+
+ @Override
+ public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> modification) {
+ CopyOnWriteArrayList<TopoEdgeUpdate> msg = new CopyOnWriteArrayList<TopoEdgeUpdate>();
+ try {
+ TypeSafeDataReader reader = TypeSafeDataReader.forReader(dataService);
+ InstanceIdentifier<Topology> topologyPath = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId("flow:1"))).build();
+ Topology topology = reader.readOperationalData(topologyPath);
+
+ for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : modification
+ .getCreatedOperationalData().entrySet()) {
+ if (entry.getValue() instanceof Link
+ && modification.getCreatedOperationalData().containsKey(entry.getKey())) {
+ msg.add(toTopoEdgeUpdate(toAdEdge((Link) entry.getValue(), topology), UpdateType.ADDED, reader));
+ }
+ }
+
+ for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : modification
+ .getUpdatedOperationalData().entrySet()) {
+ if (entry.getValue() instanceof Link) {
+ msg.add(toTopoEdgeUpdate(toAdEdge((Link) entry.getValue(), topology), UpdateType.CHANGED, reader));
+ }
+ }
+ for (InstanceIdentifier<? extends DataObject> path : modification.getRemovedOperationalData()) {
+ if (path.getTargetType() == Link.class) {
+ Link link = (Link) modification.getOriginalOperationalData().get(path);
+ msg.add(toTopoEdgeUpdate(toAdEdge(link, topology), UpdateType.CHANGED, reader));
+ }
+
+ }
+
+ if (topologyPublisher != null && msg != null && !msg.isEmpty()) {
+ topologyPublisher.edgeUpdate(msg);
+ }
+
+ } catch (Exception e) {
+ LOG.error("Exception caught", e);
+ }
+ }
+
+ protected IPluginOutTopologyService getTopologyPublisher() {
+ return topologyPublisher;
+ }
+
+ protected void setTopologyPublisher(final IPluginOutTopologyService topologyPublisher) {
+ this.topologyPublisher = topologyPublisher;
+ }
+
+}
+++ /dev/null
-/*
- * 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.compatibility.topology
-
-import com.google.common.collect.FluentIterable
-import java.util.concurrent.CopyOnWriteArrayList
-import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.controller.sal.core.UpdateType
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
-import org.slf4j.LoggerFactory
-
-class TopologyCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
- static val LOG = LoggerFactory.getLogger(TopologyCommitHandler);
- @Property
- IPluginOutTopologyService topologyPublisher;
-
- @Property
- DataProviderService dataService;
-
- new(DataProviderService dataService) {
- _topologyPublisher = topologyPublisher
- _dataService = dataService
- }
-
- override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
- val msg = new CopyOnWriteArrayList<TopoEdgeUpdate>()
- try {
- val reader = TypeSafeDataReader.forReader(dataService)
- val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, new TopologyKey(new TopologyId("flow:1"))).toInstance
- val topology = reader.readOperationalData(topologyPath)
- val adds = FluentIterable.from(modification.createdOperationalData.entrySet)
- .filter[value instanceof Link]
- .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)]
- .toList
- val updates = FluentIterable.from(modification.updatedOperationalData.entrySet)
- .filter[!modification.createdOperationalData.containsKey(key) && (value instanceof Link)]
- .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] // Evidently the ADSAL does not expect edge 'CHANGED"
- .toList
- val removes = FluentIterable.from(modification.removedOperationalData)
- .transform[reader.readOperationalData(it as InstanceIdentifier<DataObject>)]
- .filter[it instanceof Link]
- .transform[(it as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.REMOVED,reader)]
- .toList
- msg.addAll(adds)
- msg.addAll(updates)
- msg.addAll(removes)
- } catch (Exception e) {
- LOG.error("Exception caught",e)
- }
- return new TopologyTransaction(modification,topologyPublisher,dataService,msg)
- }
-}
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey
import org.opendaylight.yangtools.yang.binding.DataObject
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
import org.slf4j.LoggerFactory
+import org.opendaylight.yangtools.concepts.ListenerRegistration
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener
class TopologyProvider implements AutoCloseable{
static val LOG = LoggerFactory.getLogger(TopologyProvider);
@Property
DataProviderService dataService;
- Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-
+ ListenerRegistration<DataChangeListener> listenerRegistration
+
+
def void start() {
}
LOG.error("dataService not set");
return;
}
- commitHandler = new TopologyCommitHandler(dataService)
- commitHandler.setTopologyPublisher(topologyPublisher)
+ commitHandler = new TopologyCommitHandler(dataService,topologyPublisher);
val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(NetworkTopology)
.child(Topology,new TopologyKey(new TopologyId("flow:1")))
.child(Link)
.toInstance();
- commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
+ listenerRegistration = dataService.registerDataChangeListener(path,commitHandler);
LOG.info("TopologyProvider started")
}
override close() throws Exception {
- commitHandlerRegistration.close
+ listenerRegistration.close
}
def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) {
+++ /dev/null
-/*
- * 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.compatibility.topology
-
-import java.util.Collections
-import java.util.List
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.common.RpcResult
-import org.slf4j.LoggerFactory
-
-class TopologyTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
- static val LOG = LoggerFactory.getLogger(TopologyTransaction);
- @Property
- val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
-
- @Property
- IPluginOutTopologyService topologyPublisher;
-
- @Property
- DataProviderService dataService;
- @Property
- List<TopoEdgeUpdate> edgeUpdates;
-
- new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,IPluginOutTopologyService topologyPublisher,
- DataProviderService dataService,List<TopoEdgeUpdate> edgeUpdates) {
- _modification = modification;
- _topologyPublisher = topologyPublisher
- _dataService = dataService
- _edgeUpdates = edgeUpdates
- }
- override finish() throws IllegalStateException {
-
- if(topologyPublisher != null && _edgeUpdates != null && !edgeUpdates.empty) {
- topologyPublisher.edgeUpdate(edgeUpdates)
- }
-
- return new RpcResultTo()
- }
-
- override getModification() {
- return _modification;
- }
-
- override rollback() throws IllegalStateException {
- // NOOP
- }
-}
-class RpcResultTo implements RpcResult<Void> {
-
- override getErrors() {
- return Collections.emptySet
- }
-
- override getResult() {
- return null;
- }
-
- override isSuccessful() {
- return true;
- }
-
-}
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>xtend-maven-plugin</artifactId>
- </plugin>
</plugins>
</build>
--- /dev/null
+/**
+ * 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.frm;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public abstract class AbstractChangeListener implements DataChangeListener {
+
+ private final AtomicLong txNum = new AtomicLong();
+ private String transactionId;
+
+ @Override
+ public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+ this.transactionId = this.newTransactionIdentifier().toString();
+
+ final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries =
+ changeEvent.getCreatedConfigurationData().entrySet();
+ final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries =
+ new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
+
+ Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updateConfigEntrySet =
+ changeEvent.getUpdatedConfigurationData().entrySet();
+ updatedEntries.addAll(updateConfigEntrySet);
+ updatedEntries.removeAll(createdEntries);
+
+ final Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers =
+ changeEvent.getRemovedConfigurationData();
+
+ for (final Entry<InstanceIdentifier<? extends DataObject>, DataObject> createdEntry : createdEntries) {
+ InstanceIdentifier<? extends DataObject> c_key = createdEntry.getKey();
+ DataObject c_value = createdEntry.getValue();
+ this.add(c_key, c_value);
+ }
+
+ for (final Entry<InstanceIdentifier<?>, DataObject> updatedEntrie : updatedEntries) {
+ Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData =
+ changeEvent.getOriginalConfigurationData();
+
+ InstanceIdentifier<? extends Object> u_key = updatedEntrie.getKey();
+ final DataObject originalFlow = origConfigData.get(u_key);
+ final DataObject updatedFlow = updatedEntrie.getValue();
+ this.update(u_key, originalFlow, updatedFlow);
+ }
+
+ for (final InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
+ Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData =
+ changeEvent.getOriginalConfigurationData();
+
+ final DataObject removeValue = origConfigData.get(instanceId);
+ this.remove(instanceId, removeValue);
+ }
+ }
+
+ public String getTransactionId() {
+ return this.transactionId;
+ }
+
+ private Object newTransactionIdentifier() {
+ return "DOM-" + txNum.getAndIncrement();
+ }
+
+ protected abstract void validate() throws IllegalStateException;
+
+ protected abstract void remove(
+ final InstanceIdentifier<? extends DataObject> identifier,
+ final DataObject remove);
+
+ protected abstract void update(
+ final InstanceIdentifier<? extends DataObject> identifier,
+ final DataObject original, final DataObject update);
+
+ protected abstract void add(
+ final InstanceIdentifier<? extends DataObject> identifier,
+ final DataObject add);
+}
+++ /dev/null
-/*
- * 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.frm
-
-import java.util.Collections
-import java.util.HashSet
-import java.util.Map.Entry
-import java.util.Set
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.controller.sal.common.util.Rpcs
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.common.RpcError
-
-abstract class AbstractTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
-
- @Property
- val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
-
- new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
- _modification = modification;
- }
-
- def void validate() throws IllegalStateException
-
- override finish() throws IllegalStateException {
- validate()
- callRpcs();
- return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
- }
-
- override getModification() {
- return _modification;
- }
-
- override rollback() throws IllegalStateException {
- rollbackRpcs();
- return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
- }
-
- def private callRpcs() {
- val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = _modification.getCreatedConfigurationData().entrySet();
-
- /*
- * This little dance is because updatedEntries contains both created and modified entries
- * The reason I created a new HashSet is because the collections we are returned are immutable.
- */
- val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
- updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet());
- updatedEntries.removeAll(createdEntries);
-
- val Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData();
- for (Entry<InstanceIdentifier<? extends DataObject >, DataObject> entry : createdEntries) {
- add(entry.key,entry.value);
- }
- for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
- val originalFlow = _modification.originalConfigurationData.get(entry.key);
- val updatedFlow = entry.value
- update(entry.key, originalFlow ,updatedFlow);
- }
-
- for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
- val removeValue = _modification.getOriginalConfigurationData.get(instanceId);
- remove(instanceId,removeValue);
- }
- }
-
- def void remove(InstanceIdentifier<?> identifier, DataObject remove)
-
- def void update(InstanceIdentifier<?> identifier, DataObject original, DataObject update)
-
- def void add(InstanceIdentifier<?> identifier, DataObject add)
-
- def private rollbackRpcs() {
- val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = _modification.getCreatedConfigurationData().entrySet();
-
- /*
- * This little dance is because updatedEntries contains both created and modified entries
- * The reason I created a new HashSet is because the collections we are returned are immutable.
- */
- val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
- updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet());
- updatedEntries.removeAll(createdEntries);
-
- val Set<InstanceIdentifier<? >> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData();
- for (Entry<InstanceIdentifier<?>, DataObject> entry : createdEntries) {
- remove(entry.key,entry.value); // because we are rolling back, remove what we would have added.
- }
- for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
- val originalFlow = _modification.originalConfigurationData.get(entry.key);
- val updatedFlow = entry.value
- update(entry.key, updatedFlow ,originalFlow);// because we are rolling back, replace the updated with the original
- }
-
- for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
- val removeValue = _modification.getOriginalConfigurationData.get(instanceId);
- add(instanceId,removeValue);// because we are rolling back, add what we would have removed.
- }
- }
-}
--- /dev/null
+/**
+ * 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.frm;
+
+import org.opendaylight.controller.frm.flow.FlowProvider;
+import org.opendaylight.controller.frm.group.GroupProvider;
+import org.opendaylight.controller.frm.meter.MeterProvider;
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FRMActivator extends AbstractBindingAwareProvider {
+
+ private final static Logger LOG = LoggerFactory.getLogger(FRMActivator.class);
+
+ private static FlowProvider flowProvider = new FlowProvider();
+ private static GroupProvider groupProvider = new GroupProvider();
+ private static MeterProvider meterProvider = new MeterProvider();
+
+ @Override
+ public void onSessionInitiated(final ProviderContext session) {
+ DataProviderService flowSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+ FRMActivator.flowProvider.setDataService(flowSalService);
+ SalFlowService rpcFlowSalService = session.<SalFlowService>getRpcService(SalFlowService.class);
+ FRMActivator.flowProvider.setSalFlowService(rpcFlowSalService);
+ FRMActivator.flowProvider.start();
+ DataProviderService groupSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+ FRMActivator.groupProvider.setDataService(groupSalService);
+ SalGroupService rpcGroupSalService = session.<SalGroupService>getRpcService(SalGroupService.class);
+ FRMActivator.groupProvider.setSalGroupService(rpcGroupSalService);
+ FRMActivator.groupProvider.start();
+ DataProviderService meterSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+ FRMActivator.meterProvider.setDataService(meterSalService);
+ SalMeterService rpcMeterSalService = session.<SalMeterService>getRpcService(SalMeterService.class);
+ FRMActivator.meterProvider.setSalMeterService(rpcMeterSalService);
+ FRMActivator.meterProvider.start();
+ }
+
+ @Override
+ protected void stopImpl(final BundleContext context) {
+ try {
+ FRMActivator.flowProvider.close();
+ FRMActivator.groupProvider.close();
+ FRMActivator.meterProvider.close();
+ } catch (Throwable e) {
+ LOG.error("Unexpected error by stopping FRMActivator", e);
+ throw new RuntimeException(e);
+ }
+ }
+ }
\ No newline at end of file
+++ /dev/null
-/*
- * 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.frm
-
-import org.opendaylight.controller.frm.flow.FlowProvider
-import org.opendaylight.controller.frm.group.GroupProvider
-import org.opendaylight.controller.frm.meter.MeterProvider
-import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.osgi.framework.BundleContext
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-
-class FRMActivator extends AbstractBindingAwareProvider {
-
- static var FlowProvider provider = new FlowProvider();
- static var GroupProvider groupProvider = new GroupProvider();
- static var MeterProvider meterProvider = new MeterProvider();
-
- override onSessionInitiated(ProviderContext session) {
- provider.dataService = session.getSALService(DataProviderService)
- provider.salFlowService = session.getRpcService(SalFlowService);
- provider.start();
-
- groupProvider.dataService = session.getSALService(DataProviderService)
- groupProvider.salGroupService = session.getRpcService(SalGroupService)
- groupProvider.start();
-
- meterProvider.dataService = session.getSALService(DataProviderService)
- meterProvider.salMeterService = session.getRpcService(SalMeterService)
- meterProvider.start();
- }
-
- override protected stopImpl(BundleContext context) {
- provider.close();
- groupProvider.close();
- meterProvider.close();
- }
-
-}
--- /dev/null
+/**
+ * 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.frm.flow;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class FlowChangeListener extends AbstractChangeListener {
+
+ private final static Logger LOG = LoggerFactory.getLogger(FlowChangeListener.class);
+
+ private final SalFlowService salFlowService;
+
+ public SalFlowService getSalFlowService() {
+ return this.salFlowService;
+ }
+
+ public FlowChangeListener(final SalFlowService manager) {
+ this.salFlowService = manager;
+ }
+
+ @Override
+ protected void validate() throws IllegalStateException {
+ FlowTransactionValidator.validate(this);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+ if ((removeDataObj instanceof Flow)) {
+
+ final Flow flow = ((Flow) removeDataObj);
+ final InstanceIdentifier<Table> tableInstanceId = identifier.<Table> firstIdentifierOf(Table.class);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+ final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(flow);
+
+ builder.setFlowRef(new FlowRef(identifier));
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setFlowTable(new FlowTableRef(tableInstanceId));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+ this.salFlowService.removeFlow((RemoveFlowInput) builder.build());
+ LOG.debug("Transaction {} - Removed Flow has removed flow: {}", new Object[]{uri, removeDataObj});
+ }
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+ if (original instanceof Flow && update instanceof Flow) {
+
+ final Flow originalFlow = ((Flow) original);
+ final Flow updatedFlow = ((Flow) update);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node>firstIdentifierOf(Node.class);
+ final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder();
+
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setFlowRef(new FlowRef(identifier));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+
+ builder.setUpdatedFlow((UpdatedFlow) (new UpdatedFlowBuilder(updatedFlow)).build());
+ builder.setOriginalFlow((OriginalFlow) (new OriginalFlowBuilder(originalFlow)).build());
+
+ this.salFlowService.updateFlow((UpdateFlowInput) builder.build());
+ LOG.debug("Transaction {} - Update Flow has updated flow {} with {}", new Object[]{uri, original, update});
+ }
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+ if ((addDataObj instanceof Flow)) {
+
+ final Flow flow = ((Flow) addDataObj);
+ final InstanceIdentifier<Table> tableInstanceId = identifier.<Table> firstIdentifierOf(Table.class);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+ final AddFlowInputBuilder builder = new AddFlowInputBuilder(flow);
+
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setFlowRef(new FlowRef(identifier));
+ builder.setFlowTable(new FlowTableRef(tableInstanceId));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+ this.salFlowService.addFlow((AddFlowInput) builder.build());
+ LOG.debug("Transaction {} - Add Flow has added flow: {}", new Object[]{uri, addDataObj});
+ }
+ }
+}
+++ /dev/null
-/*
- * 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.frm.flow
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-
-class FlowCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-
- @Property
- val SalFlowService salFlowService;
-
- new(SalFlowService manager) {
- _salFlowService = manager;
- }
-
- override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
- return new FlowTransaction(modification,salFlowService);
- }
-
-}
--- /dev/null
+/**
+ * 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.frm.flow;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+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.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlowProvider implements AutoCloseable {
+
+ private final static Logger LOG = LoggerFactory.getLogger(FlowProvider.class);
+
+ private SalFlowService salFlowService;
+ private DataProviderService dataService;
+
+ /* DataChangeListener */
+ private FlowChangeListener flowDataChangeListener;
+ ListenerRegistration<DataChangeListener> flowDataChangeListenerRegistration;
+
+ public void start() {
+ /* Build Path */
+ InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+ InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+ InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+ InstanceIdentifierBuilder<Table> tableChild = augmentFlowCapNode.<Table> child(Table.class);
+ InstanceIdentifierBuilder<Flow> flowChild = tableChild.<Flow> child(Flow.class);
+ final InstanceIdentifier<? extends DataObject> flowDataObjectPath = flowChild.toInstance();
+
+ /* DataChangeListener registration */
+ this.flowDataChangeListener = new FlowChangeListener(this.salFlowService);
+ this.flowDataChangeListenerRegistration = this.dataService.registerDataChangeListener(flowDataObjectPath, flowDataChangeListener);
+ LOG.info("Flow Config Provider started.");
+ }
+
+ protected DataModificationTransaction startChange() {
+ return this.dataService.beginTransaction();
+ }
+
+ @Override
+ public void close() throws Exception {
+ if(flowDataChangeListenerRegistration != null){
+ flowDataChangeListenerRegistration.close();
+ }
+ }
+
+ public void setDataService(final DataProviderService dataService) {
+ this.dataService = dataService;
+ }
+
+ public void setSalFlowService(final SalFlowService salFlowService) {
+ this.salFlowService = salFlowService;
+ }
+}
+++ /dev/null
-/*
- * 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.frm.flow
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class FlowProvider implements AutoCloseable {
-
- @Property
- DataProviderService dataService;
-
- @Property
- SalFlowService salFlowService;
-
- FlowCommitHandler commitHandler
-
- Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-
- static val LOG = LoggerFactory.getLogger(FlowProvider);
-
- def void start() {
- commitHandler = new FlowCommitHandler(salFlowService)
- val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
- .child(Node)
- .augmentation(FlowCapableNode)
- .child(Table)
- .child(Flow)
- .toInstance();
- commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
- LOG.info("Flow Config Provider started.");
- }
-
- protected def startChange() {
- return dataService.beginTransaction;
- }
-
- override close() throws Exception {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
- }
-
-}
+++ /dev/null
-/*
- * 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.frm.flow
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class FlowTransaction extends AbstractTransaction {
-
- @Property
- val SalFlowService salFlowService;
-
-
- new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalFlowService salFlowService) {
- super(modification)
- _salFlowService = salFlowService;
- }
-
- override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
- if(obj instanceof Flow) {
- val flow = (obj as Flow)
- val tableInstanceId = instanceId.firstIdentifierOf(Table);
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new RemoveFlowInputBuilder(flow);
- builder.setFlowRef(new FlowRef(instanceId));
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setFlowTable(new FlowTableRef(tableInstanceId));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- _salFlowService.removeFlow(builder.build());
- }
- }
-
- override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
- if(originalObj instanceof Flow && updatedObj instanceof Flow) {
- val originalFlow = (originalObj as Flow)
- val updatedFlow = (updatedObj as Flow)
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new UpdateFlowInputBuilder();
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setFlowRef(new FlowRef(instanceId));
- val ufb = new UpdatedFlowBuilder(updatedFlow);
- builder.setUpdatedFlow((ufb.build()));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- val ofb = new OriginalFlowBuilder(originalFlow);
- builder.setOriginalFlow(ofb.build());
- _salFlowService.updateFlow(builder.build());
-
- }
- }
-
- override add(InstanceIdentifier<?> instanceId, DataObject obj) {
- if(obj instanceof Flow) {
- val flow = (obj as Flow)
- val tableInstanceId = instanceId.firstIdentifierOf(Table);
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new AddFlowInputBuilder(flow);
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- builder.setFlowRef(new FlowRef(instanceId));
- builder.setFlowTable(new FlowTableRef(tableInstanceId));
- _salFlowService.addFlow(builder.build());
- }
- }
-
- override validate() throws IllegalStateException {
- FlowTransactionValidator.validate(this)
- }
-}
-/*
+/**
* 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
public class FlowTransactionValidator {
- public static void validate(FlowTransaction transaction) throws IllegalStateException {
+ public static void validate(FlowChangeListener transaction) throws IllegalStateException {
// NOOP
}
-
}
--- /dev/null
+/**
+ * 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.frm.group;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class GroupChangeListener extends AbstractChangeListener {
+
+ private final static Logger LOG = LoggerFactory.getLogger(GroupChangeListener.class);
+
+ private final SalGroupService salGroupService;
+
+ public SalGroupService getSalGroupService() {
+ return this.salGroupService;
+ }
+
+ public GroupChangeListener(final SalGroupService manager) {
+ this.salGroupService = manager;
+ }
+
+ @Override
+ protected void validate() throws IllegalStateException {
+ GroupTransactionValidator.validate(this);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+ if ((removeDataObj instanceof Group)) {
+
+ final Group group = ((Group) removeDataObj);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+ final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
+
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setGroupRef(new GroupRef(identifier));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+ this.salGroupService.removeGroup((RemoveGroupInput) builder.build());
+ LOG.debug("Transaction {} - Remove Group has removed group: {}", new Object[]{uri, removeDataObj});
+ }
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+ if (original instanceof Group && update instanceof Group) {
+
+ final Group originalGroup = ((Group) original);
+ final Group updatedGroup = ((Group) update);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+ final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder();
+
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setGroupRef(new GroupRef(identifier));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+
+ builder.setUpdatedGroup((UpdatedGroup) (new UpdatedGroupBuilder(updatedGroup)).build());
+ builder.setOriginalGroup((OriginalGroup) (new OriginalGroupBuilder(originalGroup)).build());
+
+ this.salGroupService.updateGroup((UpdateGroupInput) builder.build());
+ LOG.debug("Transaction {} - Update Group has updated group {} with group {}", new Object[]{uri, original, update});
+ }
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+ if ((addDataObj instanceof Group)) {
+ final Group group = ((Group) addDataObj);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+ final AddGroupInputBuilder builder = new AddGroupInputBuilder(group);
+
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setGroupRef(new GroupRef(identifier));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+ this.salGroupService.addGroup((AddGroupInput) builder.build());
+ LOG.debug("Transaction {} - Add Group has added group: {}", new Object[]{uri, addDataObj});
+ }
+ }
+}
+++ /dev/null
-/*
- * 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.frm.group
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-
-class GroupCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-
- @Property
- val SalGroupService groupService;
-
- new(SalGroupService groupService) {
- _groupService = groupService;
- }
-
- override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
- return new GroupTransaction(modification,groupService);
- }
-
-}
--- /dev/null
+/**
+ * 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.frm.group;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+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.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupProvider implements AutoCloseable {
+
+ private final static Logger LOG = LoggerFactory.getLogger(GroupProvider.class);
+
+ private SalGroupService salGroupService;
+ private DataProviderService dataService;
+
+ /* DataChangeListener */
+ private GroupChangeListener groupDataChangeListener;
+ ListenerRegistration<DataChangeListener> groupDataChangeListenerRegistration;
+
+ public void start() {
+ /* Build Path */
+ InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+ InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+ InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+ InstanceIdentifierBuilder<Group> groupChild = augmentFlowCapNode.<Group> child(Group.class);
+ final InstanceIdentifier<? extends DataObject> groupDataObjectPath = groupChild.toInstance();
+
+ /* DataChangeListener registration */
+ this.groupDataChangeListener = new GroupChangeListener(this.salGroupService);
+ this.groupDataChangeListenerRegistration = this.dataService.registerDataChangeListener(groupDataObjectPath, groupDataChangeListener);
+ LOG.info("Group Config Provider started.");
+ }
+
+ protected DataModificationTransaction startChange() {
+ return this.dataService.beginTransaction();
+ }
+
+ public void close() throws Exception {
+ if(groupDataChangeListenerRegistration != null){
+ groupDataChangeListenerRegistration.close();
+ }
+ }
+
+ public void setDataService(final DataProviderService dataService) {
+ this.dataService = dataService;
+ }
+
+ public void setSalGroupService(final SalGroupService salGroupService) {
+ this.salGroupService = salGroupService;
+ }
+}
+++ /dev/null
-/*
- * 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.frm.group
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class GroupProvider implements AutoCloseable {
-
- @Property
- DataProviderService dataService;
-
- @Property
- SalGroupService salGroupService;
-
- GroupCommitHandler commitHandler
-
- Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-
- static val LOG = LoggerFactory.getLogger(GroupProvider);
-
- def void start() {
- commitHandler = new GroupCommitHandler(salGroupService)
- val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
- .child(Node)
- .augmentation(FlowCapableNode)
- .child(Group)
- .toInstance();
- commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
- LOG.info("Group Config Provider started.");
- }
-
- protected def startChange() {
- return dataService.beginTransaction;
- }
-
- override close() throws Exception {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
- }
-
-}
+++ /dev/null
-/*
- * 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.frm.group
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class GroupTransaction extends AbstractTransaction {
-
- @Property
- val SalGroupService groupService;
-
- new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalGroupService groupService) {
- super(modification)
- _groupService = groupService;
- }
-
- override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
- if(obj instanceof Group) {
- val group = (obj as Group)
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new RemoveGroupInputBuilder(group);
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- builder.setGroupRef(new GroupRef(instanceId));
- _groupService.removeGroup(builder.build());
- }
- }
-
- override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
- if(originalObj instanceof Group && updatedObj instanceof Group) {
- val originalGroup = (originalObj as Group)
- val updatedGroup = (updatedObj as Group)
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new UpdateGroupInputBuilder();
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setGroupRef(new GroupRef(instanceId));
- val ufb = new UpdatedGroupBuilder(updatedGroup);
- builder.setUpdatedGroup((ufb.build()));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- val ofb = new OriginalGroupBuilder(originalGroup);
- builder.setOriginalGroup(ofb.build());
- _groupService.updateGroup(builder.build());
-
- }
- }
-
- override add(InstanceIdentifier<?> instanceId, DataObject obj) {
- if(obj instanceof Group) {
- val group = (obj as Group)
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new AddGroupInputBuilder(group);
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setGroupRef(new GroupRef(instanceId));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- _groupService.addGroup(builder.build());
- }
- }
-
- override validate() throws IllegalStateException {
- GroupTransactionValidator.validate(this)
- }
-}
-/*
+/**
* Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
public class GroupTransactionValidator {
- public static void validate(GroupTransaction transaction) throws IllegalStateException {
+ public static void validate(GroupChangeListener transaction) throws IllegalStateException {
// NOOP
}
-
}
--- /dev/null
+/**
+ * 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.frm.meter;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class MeterChangeListener extends AbstractChangeListener {
+
+ private final static Logger LOG = LoggerFactory.getLogger(MeterChangeListener.class);
+
+ private final SalMeterService salMeterService;
+
+ public SalMeterService getSalMeterService() {
+ return this.salMeterService;
+ }
+
+ public MeterChangeListener(final SalMeterService manager) {
+ this.salMeterService = manager;
+ }
+
+ @Override
+ protected void validate() throws IllegalStateException {
+ MeterTransactionValidator.validate(this);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+ if ((removeDataObj instanceof Meter)) {
+
+ final Meter meter = ((Meter) removeDataObj);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+ final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(meter);
+
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setMeterRef(new MeterRef(identifier));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+ this.salMeterService.removeMeter((RemoveMeterInput) builder.build());
+ LOG.debug("Transaction {} - Remove Meter has removed meter: {}", new Object[]{uri, removeDataObj});
+ }
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+ if (original instanceof Meter && update instanceof Meter) {
+
+ final Meter originalMeter = ((Meter) original);
+ final Meter updatedMeter = ((Meter) update);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+ final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder();
+
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setMeterRef(new MeterRef(identifier));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+
+ builder.setUpdatedMeter((UpdatedMeter) (new UpdatedMeterBuilder(updatedMeter)).build());
+ builder.setOriginalMeter((OriginalMeter) (new OriginalMeterBuilder(originalMeter)).build());
+
+ this.salMeterService.updateMeter((UpdateMeterInput) builder.build());
+ LOG.debug("Transaction {} - Update Meter has updated meter {} with {}", new Object[]{uri, original, update});
+ }
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+ if ((addDataObj instanceof Meter)) {
+
+ final Meter meter = ((Meter) addDataObj);
+ final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+ final AddMeterInputBuilder builder = new AddMeterInputBuilder(meter);
+
+ builder.setNode(new NodeRef(nodeInstanceId));
+ builder.setMeterRef(new MeterRef(identifier));
+
+ Uri uri = new Uri(this.getTransactionId());
+ builder.setTransactionUri(uri);
+ this.salMeterService.addMeter((AddMeterInput) builder.build());
+ LOG.debug("Transaction {} - Add Meter has added meter: {}", new Object[]{uri, addDataObj});
+ }
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.frm.meter
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-
-class FlowCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-
- @Property
- val SalMeterService salMeterService;
-
- new(SalMeterService manager) {
- _salMeterService = manager;
- }
-
- override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
- return new MeterTransaction(modification,salMeterService);
- }
-
-}
--- /dev/null
+/**
+ * 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.frm.meter;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+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.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MeterProvider implements AutoCloseable {
+
+ private final static Logger LOG = LoggerFactory.getLogger(MeterProvider.class);
+
+ private DataProviderService dataService;
+ private SalMeterService salMeterService;
+
+ /* DataChangeListener */
+ private MeterChangeListener meterDataChangeListener;
+ ListenerRegistration<DataChangeListener> meterDataChangeListenerRegistration;
+
+ public void start() {
+ /* Build Path */
+ InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+ InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+ InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+ InstanceIdentifierBuilder<Meter> meterChild = augmentFlowCapNode.<Meter> child(Meter.class);
+ final InstanceIdentifier<? extends DataObject> meterDataObjectPath = meterChild.toInstance();
+
+ /* DataChangeListener registration */
+ this.meterDataChangeListener = new MeterChangeListener(this.salMeterService);
+ this.meterDataChangeListenerRegistration = this.dataService.registerDataChangeListener(meterDataObjectPath, meterDataChangeListener);
+ LOG.info("Meter Config Provider started.");
+ }
+
+ protected DataModificationTransaction startChange() {
+ return this.dataService.beginTransaction();
+ }
+
+ public void close() throws Exception {
+ if(meterDataChangeListenerRegistration != null){
+ meterDataChangeListenerRegistration.close();
+ }
+ }
+
+ public void setDataService(final DataProviderService dataService) {
+ this.dataService = dataService;
+ }
+
+ public void setSalMeterService(final SalMeterService salMeterService) {
+ this.salMeterService = salMeterService;
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.frm.meter
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class MeterProvider implements AutoCloseable {
-
- @Property
- DataProviderService dataService;
-
- @Property
- SalMeterService salMeterService;
-
- FlowCommitHandler commitHandler
-
- Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-
- static val LOG = LoggerFactory.getLogger(MeterProvider);
-
- def void start() {
- commitHandler = new FlowCommitHandler(salMeterService)
- val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
- .child(Node)
- .augmentation(FlowCapableNode)
- .child(Meter)
- .toInstance();
- commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
- LOG.info("Meter Config Provider started.");
- }
-
- protected def startChange() {
- return dataService.beginTransaction;
- }
-
- override close() throws Exception {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
- }
-
-}
+++ /dev/null
-/*
- * 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.frm.meter
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class MeterTransaction extends AbstractTransaction {
-
- @Property
- val SalMeterService salMeterService;
-
- new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalMeterService salMeterService) {
- super(modification)
- _salMeterService = salMeterService;
- }
-
- override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
- if(obj instanceof Meter) {
- val meter = (obj as Meter)
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new RemoveMeterInputBuilder(meter);
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setMeterRef(new MeterRef(instanceId));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- _salMeterService.removeMeter(builder.build());
- }
- }
-
- override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
- if(originalObj instanceof Meter && updatedObj instanceof Meter) {
- val originalMeter = (originalObj as Meter)
- val updatedMeter = (updatedObj as Meter)
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new UpdateMeterInputBuilder();
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setMeterRef(new MeterRef(instanceId));
- val ufb = new UpdatedMeterBuilder(updatedMeter);
- builder.setUpdatedMeter((ufb.build()));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- val ofb = new OriginalMeterBuilder(originalMeter);
- builder.setOriginalMeter(ofb.build());
- _salMeterService.updateMeter(builder.build());
-
- }
- }
-
- override add(InstanceIdentifier<?> instanceId, DataObject obj) {
- if(obj instanceof Meter) {
- val meter = (obj as Meter)
- val nodeInstanceId = instanceId.firstIdentifierOf(Node);
- val builder = new AddMeterInputBuilder(meter);
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setMeterRef(new MeterRef(instanceId));
- builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
- _salMeterService.addMeter(builder.build());
- }
- }
-
- override validate() throws IllegalStateException {
- MeterTransactionValidator.validate(this)
- }
-}
-/*
+/**
* Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
public class MeterTransactionValidator {
- public static void validate(MeterTransaction transaction) throws IllegalStateException {
+ public static void validate(MeterChangeListener transaction) throws IllegalStateException {
// NOOP
}
-
}
try {
final DataObject dataObject = normalizedNode.isPresent() ? codec.toBinding(path,
normalizedNode.get()) : null;
- if(dataObject != null) {
+ if (dataObject != null) {
updateCache(store, path, dataObject);
}
return Optional.fromNullable(dataObject);
.toNormalizedNode(path, data);
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+ ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path);
+ LOG.debug("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
+ writeTransaction.put(store, normalized.getKey(), normalized.getValue());
+ }
+
+ protected void doMergeWithEnsureParents(final DOMDataReadWriteTransaction writeTransaction,
+ final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
+ invalidateCache(store, path);
+ final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
+ .toNormalizedNode(path, data);
+
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+ ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path);
+ LOG.debug("Tx: {} : Merge data {}",getDelegate().getIdentifier(),normalized.getKey());
+ writeTransaction.merge(store, normalized.getKey(), normalized.getValue());
+ }
+
+ private void ensureParentsByMerge(final DOMDataReadWriteTransaction writeTransaction,
+ final LogicalDatastoreType store,
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath,
+ final InstanceIdentifier<?> path) {
List<PathArgument> currentArguments = new ArrayList<>();
DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
writeTransaction.merge(store, currentPath, currentOp.createDefault(currentArg));
}
}
- //LOG .info("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
- writeTransaction.put(store, normalized.getKey(), normalized.getValue());
}
protected void doMerge(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
private class ForwardedBackwardsCompatibleTransacion extends
AbstractForwardedTransaction<DOMDataReadWriteTransaction> implements DataModificationTransaction {
+ private final ListenerRegistry<DataTransactionListener> listeners = ListenerRegistry.create();
private final Map<InstanceIdentifier<? extends DataObject>, DataObject> updated = new HashMap<>();
private final Map<InstanceIdentifier<? extends DataObject>, DataObject> created = new HashMap<>();
private final Set<InstanceIdentifier<? extends DataObject>> removed = new HashSet<>();
@Override
public void putOperationalData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
- posponedRemovedOperational.remove(path);
- doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+ boolean previouslyRemoved = posponedRemovedOperational.remove(path);
+ if(previouslyRemoved) {
+ doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+ } else {
+ doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+ }
}
@Override
public void putConfigurationData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
- posponedRemovedConfiguration.remove(path);
+ boolean previouslyRemoved = posponedRemovedConfiguration.remove(path);
DataObject originalObj = readConfigurationData(path);
if (originalObj != null) {
original.put(path, originalObj);
created.put(path, data);
}
updated.put(path, data);
- doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+ if(previouslyRemoved) {
+ doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+ } else {
+ doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+ }
}
@Override
private void changeStatus(final TransactionStatus status) {
LOG.trace("Transaction {} changed status to {}", getIdentifier(), status);
this.status = status;
+
+ for(ListenerRegistration<DataTransactionListener> listener : listeners) {
+ try {
+ listener.getInstance().onStatusUpdated(this, status);
+ } catch (Exception e) {
+ LOG.error("Error during invoking transaction listener {}",listener.getInstance(),e);
+ }
+ }
}
@Override
doDelete(getDelegate(), LogicalDatastoreType.OPERATIONAL, path);
}
- final ListenableFuture<RpcResult<TransactionStatus>> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this);
-
changeStatus(TransactionStatus.SUBMITED);
+ final ListenableFuture<RpcResult<TransactionStatus>> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this);
+
Futures.addCallback(f, new FutureCallback<RpcResult<TransactionStatus>>() {
@Override
public void onSuccess(final RpcResult<TransactionStatus> result) {
@Override
public ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
- throw new UnsupportedOperationException();
+ return listeners.register(listener);
}
}
public static final int CORE_NOTIFICATION_THREADS = 4;
public static final int MAX_NOTIFICATION_THREADS = 32;
+ // block caller thread after MAX_NOTIFICATION_THREADS + MAX_NOTIFICATION_QUEUE_SIZE pending notifications
+ public static final int MAX_NOTIFICATION_QUEUE_SIZE = 10;
public static final int NOTIFICATION_THREAD_LIFE = 15;
private static ListeningExecutorService NOTIFICATION_EXECUTOR = null;
public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() {
if (NOTIFICATION_EXECUTOR == null) {
- // Overriding the queue since we need an unbounded queue
- // and threadpoolexecutor would not create new threads if the queue is not full
- BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>() {
+ // Overriding the queue:
+ // ThreadPoolExecutor would not create new threads if the queue is not full, thus adding
+ // occurs in RejectedExecutionHandler.
+ // This impl saturates threadpool first, then queue. When both are full caller will get blocked.
+ BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(MAX_NOTIFICATION_QUEUE_SIZE) {
@Override
public boolean offer(Runnable r) {
- if (size() <= 1) {
- // if the queue is empty (or has just 1), no need to rampup the threads
- return super.offer(r);
- } else {
- // if the queue is not empty, force the queue to return false.
- // threadpoolexecutor will spawn a new thread if the queue.offer returns false.
- return false;
- }
+ // ThreadPoolExecutor will spawn a new thread after core size is reached only if the queue.offer returns false.
+ return false;
}
};
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
- e.printStackTrace();
+ Thread.currentThread().interrupt();// set interrupt flag after clearing
+ throw new IllegalStateException(e);
}
}
});
--- /dev/null
+/*
+ * 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.codegen.impl;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import java.lang.reflect.Field;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Ignore
+public class SingletonHolderTest {
+ private static final Logger logger = LoggerFactory.getLogger(SingletonHolderTest.class);
+
+ @Test
+ public void testNotificationExecutor() throws Exception {
+ ListeningExecutorService executor = SingletonHolder.getDefaultNotificationExecutor();
+ ThreadPoolExecutor tpExecutor = (ThreadPoolExecutor) setAccessible(executor.getClass().getDeclaredField("delegate")).get(executor);
+ BlockingQueue<Runnable> queue = tpExecutor.getQueue();
+
+ for (int idx = 0; idx < 100; idx++) {
+ final int idx2 = idx;
+ logger.info("Adding {}\t{}\t{}", idx, queue.size(), tpExecutor.getActiveCount());
+ executor.execute(new Runnable() {
+
+ @Override
+ public void run() {
+ logger.info("in {}", idx2);
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ logger.info("out {}", idx2);
+ }
+ });
+ }
+ executor.shutdown();
+ executor.awaitTermination(10, TimeUnit.SECONDS);
+ }
+
+ private static Field setAccessible(Field field) {
+ field.setAccessible(true);
+ return field;
+ }
+}
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-binding</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-broker-impl</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-management</artifactId>
</dependencies>
<build>
<plugins>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>${salGeneratorPath}</outputBaseDir>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+ <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
<scm>
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
public final class ImmutableDataChangeEvent<P extends Path<P>, D> implements DataChangeEvent<P,D> {
originalOperational.putAll(Maps.filterKeys(data.getOriginalOperationalData(), keyFilter));
createdOperational.putAll(Maps.filterKeys(data.getCreatedOperationalData(), keyFilter));
createdConfiguration.putAll(Maps.filterKeys(data.getCreatedConfigurationData(), keyFilter));
+ removedOperational.addAll(Sets.filter(data.getRemovedOperationalData(), keyFilter));
+ removedConfiguration.addAll(Sets.filter(data.getRemovedConfigurationData(), keyFilter));
return this;
}
Builder eventBuilder = builder(potentialScope) //
.setBefore(beforeCont) //
- .setAfter(afterCont);
+ .setAfter(afterCont)
+ .addUpdated(path, beforeCont, afterCont);
for (DOMImmutableDataChangeEvent childChange : childChanges) {
eventBuilder.merge(childChange);
}
final Collection<Node> listeners, final NormalizedNode<PathArgument, ?> node,
final SimpleEventFactory eventFactory) {
- DOMImmutableDataChangeEvent event = eventFactory.create(path, node);
-
- if (!listeners.isEmpty()) {
+ final DOMImmutableDataChangeEvent event = eventFactory.create(path, node);
+ DOMImmutableDataChangeEvent propagateEvent = event;
// We have listeners for this node or it's children, so we will try
// to do additional processing
- if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
- // Node has children, so we will try to resolve it's children
- // changes.
- @SuppressWarnings("unchecked")
- NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> container = (NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>>) node;
- for (NormalizedNode<PathArgument, ?> child : container.getValue()) {
- PathArgument childId = child.getIdentifier();
- Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
- if (!childListeners.isEmpty()) {
- resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory);
- }
- }
+ if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
+ Builder eventBuilder = builder(DataChangeScope.BASE);
+ eventBuilder.merge(event);
+ eventBuilder.setBefore(event.getOriginalSubtree());
+ eventBuilder.setAfter(event.getUpdatedSubtree());
+
+ // Node has children, so we will try to resolve it's children
+ // changes.
+ @SuppressWarnings("unchecked")
+ NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> container = (NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>>) node;
+ for (NormalizedNode<PathArgument, ?> child : container.getValue()) {
+ PathArgument childId = child.getIdentifier();
+ Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
+ eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory));
}
+ propagateEvent = eventBuilder.build();
+ } else {
+ // We do not dispatch leaf events since Binding Aware components do not support them.
+ propagateEvent = builder(DataChangeScope.BASE).build();
+ }
+ if (!listeners.isEmpty()) {
addPartialTask(listeners, event);
}
- return event;
+ return propagateEvent;
}
private DOMImmutableDataChangeEvent resolveSubtreeChangeEvent(final InstanceIdentifier path,
Builder one = builder(DataChangeScope.ONE).setBefore(before.getData()).setAfter(after.getData());
- Builder subtree = builder(DataChangeScope.SUBTREE);
+ Builder subtree = builder(DataChangeScope.SUBTREE).setBefore(before.getData()).setAfter(after.getData());
for (NodeModification childMod : modification.getModifications()) {
PathArgument childId = childMod.getIdentifier();
import static com.google.common.base.Preconditions.checkArgument;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.AugmentationSchemaProxy;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
} else if (schemaNode instanceof ChoiceNode) {
return new ChoiceModificationStrategy((ChoiceNode) schemaNode);
} else if (schemaNode instanceof LeafListSchemaNode) {
- return new LeafSetEntryModificationStrategy((LeafListSchemaNode) schemaNode);
+ return fromLeafListSchemaNode((LeafListSchemaNode) schemaNode);
} else if (schemaNode instanceof LeafSchemaNode) {
return new LeafModificationStrategy((LeafSchemaNode) schemaNode);
}
return new UnorderedMapModificationStrategy(schemaNode);
}
+ private static SchemaAwareApplyOperation fromLeafListSchemaNode(final LeafListSchemaNode schemaNode) {
+ if(schemaNode.isUserOrdered()) {
+ return new OrderedLeafSetModificationStrategy(schemaNode);
+ } else {
+ return new UnorderedLeafSetModificationStrategy(schemaNode);
+ }
+ }
+
+
public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree,
final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) {
AugmentationSchema augSchema = null;
DataNodeContainerModificationStrategy<AugmentationSchema> {
protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) {
- super(schema, AugmentationNode.class);
+ super(createAugmentProxy(schema,resolved), AugmentationNode.class);
// FIXME: Use resolved children instead of unresolved.
}
}
- public static class LeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+ public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
private final Optional<ModificationApplyOperation> entryStrategy;
@SuppressWarnings({ "unchecked", "rawtypes" })
- protected LeafSetModificationStrategy(final LeafListSchemaNode schema) {
+ protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
super((Class) LeafSetNode.class);
entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
}
}
+ public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+
+ private final Optional<ModificationApplyOperation> entryStrategy;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
+ super((Class) LeafSetNode.class);
+ entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
+ return ImmutableOrderedLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ }
+
+ @Override
+ public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+ if (identifier instanceof NodeWithValue) {
+ return entryStrategy;
+ }
+ return Optional.absent();
+ }
+
+ }
+
public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
private final Optional<ModificationApplyOperation> entryStrategy;
}
+ public static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) {
+ Set<DataSchemaNode> realChildSchemas = new HashSet<>();
+ for(DataSchemaNode augChild : schema.getChildNodes()) {
+ realChildSchemas.add(resolved.getDataChildByName(augChild.getQName()));
+ }
+ return new AugmentationSchemaProxy(schema, realChildSchemas);
+ }
+
}
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
import junit.framework.Assert;
import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
-
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
try {
c = sess.getStdout().read(bytes);
} catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ throw new IllegalStateException("IO exception while reading data on ssh bridge.");
}
logger.info("got data:" + bytes);
if (c == 0) {
*/
package org.opendaylight.controller.netconf.ssh.authentication;
+import java.io.IOException;
import org.opendaylight.controller.sal.authorization.AuthResultEnum;
-import org.opendaylight.controller.sal.authorization.UserLevel;
import org.opendaylight.controller.usermanager.IUserManager;
-import org.opendaylight.controller.usermanager.UserConfig;
-
-import java.util.ArrayList;
-import java.util.List;
-
import static com.google.common.base.Preconditions.checkNotNull;
public class AuthProvider implements AuthProviderInterface {
- private static IUserManager um; //FIXME static mutable state, no locks
- private static final String DEFAULT_USER = "netconf";
- private static final String DEFAULT_PASSWORD = "netconf";
+ private IUserManager um;
private final String pem;
- public AuthProvider(IUserManager ium, String pemCertificate) throws Exception {
+ public AuthProvider(IUserManager ium, String pemCertificate) throws IllegalArgumentException, IOException {
checkNotNull(pemCertificate, "Parameter 'pemCertificate' is null");
- AuthProvider.um = ium;
- if (AuthProvider.um == null) {
- throw new Exception("No usermanager service available.");
- }
-
- List<String> roles = new ArrayList<String>(1);
- roles.add(UserLevel.SYSTEMADMIN.toString());
- AuthProvider.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles)); //FIXME hardcoded auth
+ checkNotNull(ium, "No user manager service available.");
+ this.um = ium;
pem = pemCertificate;
}
@Override
public boolean authenticated(String username, String password) {
- if (AuthProvider.um == null) {
- throw new IllegalStateException("No usermanager service available.");
- }
- AuthResultEnum authResult = AuthProvider.um.authenticate(username, password);
+ AuthResultEnum authResult = this.um.authenticate(username, password);
return authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC);
}
@Override
public void removeUserManagerService() {
- AuthProvider.um = null;
+ this.um = null;
}
@Override
public void addUserManagerService(IUserManager userManagerService) {
- AuthProvider.um = userManagerService;
+ this.um = userManagerService;
}
}
package org.opendaylight.controller.netconf.ssh.osgi;
import com.google.common.base.Optional;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator;
import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
+import org.opendaylight.controller.sal.authorization.UserLevel;
import org.opendaylight.controller.usermanager.IUserManager;
+import org.opendaylight.controller.usermanager.UserConfig;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Activator for netconf SSH bundle which creates SSH bridge between netconf client and netconf server. Activator
* starts SSH Server in its own thread. This thread is closed when activator calls stop() method. Server opens socket
- * and listen for client connections. Each client connection creation is handled in separate
+ * and listens for client connections. Each client connection creation is handled in separate
* {@link org.opendaylight.controller.netconf.ssh.threads.SocketThread} thread.
* This thread creates two additional threads {@link org.opendaylight.controller.netconf.ssh.threads.IOThread}
* forwarding data from/to client.IOThread closes servers session and server connection when it gets -1 on input stream.
private static final String EXCEPTION_MESSAGE = "Netconf ssh bridge is not available.";
private IUserManager iUserManager;
private BundleContext context = null;
+ private Optional<String> defaultPassword;
+ private Optional<String> defaultUser;
private ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
@Override
@Override
public void stop(BundleContext context) throws IOException {
+ if (this.defaultUser.isPresent()){
+ this.iUserManager.removeLocalUser(this.defaultUser.get());
+ }
if (server != null){
server.stop();
logger.trace("Netconf SSH bridge is down ...");
}
}
private void startSSHServer() throws IllegalStateException, IOException {
+ checkNotNull(this.iUserManager, "No user manager service available.");
logger.trace("Starting netconf SSH bridge.");
Optional<InetSocketAddress> sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE);
InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context,
EXCEPTION_MESSAGE, true);
if (sshSocketAddressOptional.isPresent()){
- String path = NetconfConfigUtil.getPrivateKeyPath(context);
- path = path.replace("\\", "/"); // FIXME: shouldn't this convert lines to system dependent path separator?
+ String path = FilenameUtils.separatorsToSystem(NetconfConfigUtil.getPrivateKeyPath(context));
if (path.equals("")){
throw new IllegalStateException("Missing netconf.ssh.pk.path key in configuration file.");
}
File privateKeyFile = new File(path);
String privateKeyPEMString = null;
if (privateKeyFile.exists() == false) {
- // generate & save to file
try {
privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile);
} catch (Exception e) {
- logger.error("Exception occured while generating PEM string {}",e);
+ logger.error("Exception occurred while generating PEM string {}",e);
}
} else {
// read from file
}
AuthProvider authProvider = null;
try {
+ this.defaultPassword = NetconfConfigUtil.getSSHDefaultPassword(context);
+ this.defaultUser = NetconfConfigUtil.getSSHDefaultUser(context);
+ // Since there is no user data store yet (ldap, ...) this adds default user/password to UserManager
+ // if these parameters are set in netconf configuration file.
+ if (defaultUser.isPresent() &&
+ defaultPassword.isPresent()){
+ logger.trace(String.format("Default username and password for netconf ssh bridge found. Adding user %s to user manager.",defaultUser.get()));
+ List<String> roles = new ArrayList<String>(1);
+ roles.add(UserLevel.SYSTEMADMIN.toString());
+ iUserManager.addLocalUser(new UserConfig(defaultUser.get(), defaultPassword.get(), roles));
+ }
authProvider = new AuthProvider(iUserManager, privateKeyPEMString);
} catch (Exception e) {
logger.error("Error instantiating AuthProvider {}",e);
package org.opendaylight.controller.netconf.util.osgi;
import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import java.net.InetSocketAddress;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import java.net.InetSocketAddress;
-
import static com.google.common.base.Preconditions.checkNotNull;
public final class NetconfConfigUtil {
private static final String ADDRESS_SUFFIX_PROP = ".address";
private static final String CLIENT_PROP = ".client";
private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
+ private static final String SSH_DEFAULT_USER = ".default.user";
+ private static final String SSH_DEFAULT_PASSWORD = ".default.password";
private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis";
private static final long DEFAULT_TIMEOUT_MILLIS = 5000;
public static String getPrivateKeyPath(BundleContext context){
return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP);
}
+ public static Optional<String> getSSHDefaultUser(BundleContext context){
+ return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_USER);
+ }
+ public static Optional<String> getSSHDefaultPassword(BundleContext context){
+ return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_PASSWORD);
+ }
+
private static String getPropertyValue(BundleContext context, String propertyName){
String propertyValue = context.getProperty(propertyName);
if (propertyValue == null){
}
return propertyValue;
}
+ private static Optional<String> getOptionalPropertyValue(BundleContext context, String propertyName){
+ String propertyValue = context.getProperty(propertyName);
+ if (Strings.isNullOrEmpty(propertyValue)){
+ return Optional.absent();
+ }
+ return Optional.fromNullable(propertyValue);
+ }
/**
* @param context
* from which properties are being read.