From: Tony Tkacik Date: Thu, 1 May 2014 11:22:17 +0000 (+0000) Subject: Merge "Bug 930 - Add bound to queue in SingletonHandler#NOTIFICATION_EXECUTOR ." X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~153 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=9d269c372a5d565101629cea6dad14a35a9e0591;hp=8e654401ca264098b4bcfb25fe1411caed10ebe2 Merge "Bug 930 - Add bound to queue in SingletonHandler#NOTIFICATION_EXECUTOR ." --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index f30d4b005a..e0891662ea 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -247,11 +247,6 @@ jersey-core ${jersey.version} - - javax.ws.rs - jsr311-api - ${jsr311.api.version} - com.sun.jersey jersey-server @@ -429,6 +424,11 @@ netty-transport ${netty.version} + + javax.ws.rs + jsr311-api + ${jsr311.api.version} + orbit javax.activation diff --git a/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java b/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java index f2a56f2b1b..7a20f22440 100644 --- a/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java +++ b/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java @@ -44,22 +44,53 @@ public class ProcessSources extends AbstractMojo{ 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; } } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java index 07d7438a00..78ac362e59 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java @@ -1,10 +1,5 @@ -/* -* 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) { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java index ae6ae67584..026dd9aca2 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java @@ -1,19 +1,5 @@ -/* -* 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 { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java index a5b7f55df3..ddf72f39b4 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java @@ -1,10 +1,5 @@ -/* -* 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) { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java index 07012263e1..3a4348d376 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java @@ -1,19 +1,5 @@ -/* -* 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 { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java index ecbf4aba33..943fe3b0d7 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java @@ -1,10 +1,5 @@ -/* -* 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) { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java index 3baee6c132..587089b10f 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java @@ -1,19 +1,5 @@ -/* -* 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 { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java index 4de9804337..1d5cda036f 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java @@ -1,10 +1,5 @@ -/* - * 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; diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java index 9132407356..7b049e7b57 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java @@ -1,10 +1,5 @@ -/* -* 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) { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java index 6f9118bf92..de9ac2fef3 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java @@ -1,19 +1,5 @@ -/* -* 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 { diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini index 9d0d6c1888..234e0feb45 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini @@ -22,6 +22,8 @@ netconf.tcp.client.port=8383 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 diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml index 619ab06d8d..d872bfd47b 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml @@ -15,48 +15,13 @@ prefix:schema-service-singleton yang-schema-service - - - - prefix:hash-map-data-store - hash-map-data-store - - - - - - prefix:dom-broker-impl - dom-broker - - - dom:dom-data-store - - hash-map-data-store - - - - - - + prefix:binding-notification-broker + binding-notification-broker prefix:binding-broker-impl @@ -70,33 +35,30 @@ binding-data-broker + + - prefix:runtime-generated-mapping - runtime-mapping-singleton - - - prefix:binding-notification-broker - binding-notification-broker + prefix:dom-inmemory-data-broker + inmemory-data-broker + + dom:schema-service + yang-schema-service + - - prefix:binding-data-broker - binding-data-broker - - dom:dom-broker-osgi-registry - dom-broker - - - binding:binding-dom-mapping-service - runtime-mapping-singleton - + prefix:dom-broker-impl + inmemory-dom-broker + + dom:dom-async-data-broker + inmemory-data-broker + - - - - - - dom:schema-service - - yang-schema-service - /modules/module[type='schema-service-singleton'][name='yang-schema-service'] - - - - binding:binding-notification-service - - binding-notification-broker - /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] - - - - - dom:dom-data-store - - hash-map-data-store - /modules/module[type='hash-map-data-store'][name='hash-map-data-store'] - - - - - - - - binding:binding-broker-osgi-registry - - binding-osgi-broker - /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] - - - - binding:binding-rpc-registry - - binding-rpc-broker - /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] - - - - binding-impl:binding-dom-mapping-service - - runtime-mapping-singleton - /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] - - - - dom:dom-broker-osgi-registry - - dom-broker - /modules/module[type='dom-broker-impl'][name='dom-broker'] - - + + dom:schema-service + + yang-schema-service + /modules/module[type='schema-service-singleton'][name='yang-schema-service'] + + + + binding-impl:binding-dom-mapping-service + + runtime-mapping-singleton + /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] + + + + binding:binding-notification-service + + binding-notification-broker + /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] + + + + binding:binding-broker-osgi-registry + + binding-osgi-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + binding:binding-rpc-registry + + binding-rpc-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + - - binding:binding-data-broker - - binding-data-broker - - /modules/module[type='binding-data-broker'][name='binding-data-broker'] - - - - - - + + dom:dom-broker-osgi-registry + + dom-broker + /modules/module[type='dom-broker-impl'][name='inmemory-dom-broker'] + + + + binding:binding-data-broker + + binding-data-broker + /modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker'] + + + + + dom:dom-async-data-broker + + inmemory-data-broker + /modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker'] + + diff --git a/opendaylight/md-sal/forwardingrules-manager/pom.xml b/opendaylight/md-sal/forwardingrules-manager/pom.xml index 919a53c364..9bd63d3c3b 100644 --- a/opendaylight/md-sal/forwardingrules-manager/pom.xml +++ b/opendaylight/md-sal/forwardingrules-manager/pom.xml @@ -54,10 +54,6 @@ - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java new file mode 100644 index 0000000000..426f4ba2d5 --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java @@ -0,0 +1,94 @@ +/** + * 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 Vaclav Demcak + * + */ +public abstract class AbstractChangeListener implements DataChangeListener { + + private final AtomicLong txNum = new AtomicLong(); + private String transactionId; + + @Override + public void onDataChanged(DataChangeEvent, DataObject> changeEvent) { + this.transactionId = this.newTransactionIdentifier().toString(); + + final Set, DataObject>> createdEntries = + changeEvent.getCreatedConfigurationData().entrySet(); + final Set, DataObject>> updatedEntries = + new HashSet, DataObject>>(); + + Set, DataObject>> updateConfigEntrySet = + changeEvent.getUpdatedConfigurationData().entrySet(); + updatedEntries.addAll(updateConfigEntrySet); + updatedEntries.removeAll(createdEntries); + + final Set> removeEntriesInstanceIdentifiers = + changeEvent.getRemovedConfigurationData(); + + for (final Entry, DataObject> createdEntry : createdEntries) { + InstanceIdentifier c_key = createdEntry.getKey(); + DataObject c_value = createdEntry.getValue(); + this.add(c_key, c_value); + } + + for (final Entry, DataObject> updatedEntrie : updatedEntries) { + Map, DataObject> origConfigData = + changeEvent.getOriginalConfigurationData(); + + InstanceIdentifier 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, 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 identifier, + final DataObject remove); + + protected abstract void update( + final InstanceIdentifier identifier, + final DataObject original, final DataObject update); + + protected abstract void add( + final InstanceIdentifier identifier, + final DataObject add); +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend deleted file mode 100644 index cb1e90d6ba..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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, DataObject> { - - @Property - val DataModification, DataObject> modification; - - new(DataModification, DataObject> modification) { - _modification = modification; - } - - def void validate() throws IllegalStateException - - override finish() throws IllegalStateException { - validate() - callRpcs(); - return Rpcs.getRpcResult(true, null, Collections.emptySet()); - } - - override getModification() { - return _modification; - } - - override rollback() throws IllegalStateException { - rollbackRpcs(); - return Rpcs.getRpcResult(true, null, Collections.emptySet()); - } - - def private callRpcs() { - val Set, 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, DataObject>> updatedEntries = new HashSet, DataObject>>(); - updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet()); - updatedEntries.removeAll(createdEntries); - - val Set> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData(); - for (Entry, DataObject> entry : createdEntries) { - add(entry.key,entry.value); - } - for (Entry, 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, 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, DataObject>> updatedEntries = new HashSet, DataObject>>(); - updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet()); - updatedEntries.removeAll(createdEntries); - - val Set> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData(); - for (Entry, DataObject> entry : createdEntries) { - remove(entry.key,entry.value); // because we are rolling back, remove what we would have added. - } - for (Entry, 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. - } - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java new file mode 100644 index 0000000000..929c489eaf --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java @@ -0,0 +1,61 @@ +/** + * 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.getSALService(DataProviderService.class); + FRMActivator.flowProvider.setDataService(flowSalService); + SalFlowService rpcFlowSalService = session.getRpcService(SalFlowService.class); + FRMActivator.flowProvider.setSalFlowService(rpcFlowSalService); + FRMActivator.flowProvider.start(); + DataProviderService groupSalService = session.getSALService(DataProviderService.class); + FRMActivator.groupProvider.setDataService(groupSalService); + SalGroupService rpcGroupSalService = session.getRpcService(SalGroupService.class); + FRMActivator.groupProvider.setSalGroupService(rpcGroupSalService); + FRMActivator.groupProvider.start(); + DataProviderService meterSalService = session.getSALService(DataProviderService.class); + FRMActivator.meterProvider.setDataService(meterSalService); + SalMeterService rpcMeterSalService = session.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 diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend deleted file mode 100644 index 8ec9d79bfc..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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(); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java new file mode 100644 index 0000000000..df086c7acc --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java @@ -0,0 +1,120 @@ +/** + * 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 Vaclav Demcak + * + */ +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 identifier, DataObject removeDataObj) { + if ((removeDataObj instanceof Flow)) { + + final Flow flow = ((Flow) removeDataObj); + final InstanceIdentifier tableInstanceId = identifier.
firstIdentifierOf(Table.class); + final InstanceIdentifier nodeInstanceId = identifier. 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 identifier, DataObject original, DataObject update) { + if (original instanceof Flow && update instanceof Flow) { + + final Flow originalFlow = ((Flow) original); + final Flow updatedFlow = ((Flow) update); + final InstanceIdentifier nodeInstanceId = identifier.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 identifier, DataObject addDataObj) { + if ((addDataObj instanceof Flow)) { + + final Flow flow = ((Flow) addDataObj); + final InstanceIdentifier
tableInstanceId = identifier.
firstIdentifierOf(Table.class); + final InstanceIdentifier nodeInstanceId = identifier. 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}); + } + } +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend deleted file mode 100644 index 188bfcd3ef..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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, DataObject> { - - @Property - val SalFlowService salFlowService; - - new(SalFlowService manager) { - _salFlowService = manager; - } - - override requestCommit(DataModification, DataObject> modification) { - return new FlowTransaction(modification,salFlowService); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java new file mode 100644 index 0000000000..afdd628bbb --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java @@ -0,0 +1,70 @@ +/** + * 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 flowDataChangeListenerRegistration; + + public void start() { + /* Build Path */ + InstanceIdentifierBuilder nodesBuilder = InstanceIdentifier. builder(Nodes.class); + InstanceIdentifierBuilder nodeChild = nodesBuilder. child(Node.class); + InstanceIdentifierBuilder augmentFlowCapNode = nodeChild. augmentation(FlowCapableNode.class); + InstanceIdentifierBuilder
tableChild = augmentFlowCapNode.
child(Table.class); + InstanceIdentifierBuilder flowChild = tableChild. child(Flow.class); + final InstanceIdentifier 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; + } +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend deleted file mode 100644 index d2ed5410ed..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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,DataObject>> commitHandlerRegistration; - - static val LOG = LoggerFactory.getLogger(FlowProvider); - - def void start() { - commitHandler = new FlowCommitHandler(salFlowService) - val InstanceIdentifier 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") - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend deleted file mode 100644 index 26846ad493..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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, 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) - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java index 7c6f1ff1cb..4ef93a55e9 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java @@ -1,6 +1,6 @@ -/* +/** * 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 @@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.flow; public class FlowTransactionValidator { - public static void validate(FlowTransaction transaction) throws IllegalStateException { + public static void validate(FlowChangeListener transaction) throws IllegalStateException { // NOOP } - } diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java new file mode 100644 index 0000000000..1260f0ec53 --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java @@ -0,0 +1,113 @@ +/** + * 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 Vaclav Demcak + * + */ +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 identifier, DataObject removeDataObj) { + if ((removeDataObj instanceof Group)) { + + final Group group = ((Group) removeDataObj); + final InstanceIdentifier nodeInstanceId = identifier. 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 identifier, DataObject original, DataObject update) { + if (original instanceof Group && update instanceof Group) { + + final Group originalGroup = ((Group) original); + final Group updatedGroup = ((Group) update); + final InstanceIdentifier nodeInstanceId = identifier. 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 identifier, DataObject addDataObj) { + if ((addDataObj instanceof Group)) { + final Group group = ((Group) addDataObj); + final InstanceIdentifier nodeInstanceId = identifier. 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}); + } + } +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend deleted file mode 100644 index b6d385126f..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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, DataObject> { - - @Property - val SalGroupService groupService; - - new(SalGroupService groupService) { - _groupService = groupService; - } - - override requestCommit(DataModification, DataObject> modification) { - return new GroupTransaction(modification,groupService); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java new file mode 100644 index 0000000000..14b1b6f2fd --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java @@ -0,0 +1,67 @@ +/** + * 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 groupDataChangeListenerRegistration; + + public void start() { + /* Build Path */ + InstanceIdentifierBuilder nodesBuilder = InstanceIdentifier. builder(Nodes.class); + InstanceIdentifierBuilder nodeChild = nodesBuilder. child(Node.class); + InstanceIdentifierBuilder augmentFlowCapNode = nodeChild. augmentation(FlowCapableNode.class); + InstanceIdentifierBuilder groupChild = augmentFlowCapNode. child(Group.class); + final InstanceIdentifier 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; + } +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend deleted file mode 100644 index 4ded8b6151..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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,DataObject>> commitHandlerRegistration; - - static val LOG = LoggerFactory.getLogger(GroupProvider); - - def void start() { - commitHandler = new GroupCommitHandler(salGroupService) - val InstanceIdentifier 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") - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend deleted file mode 100644 index e8d9982bdc..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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, 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) - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java index 92baf7bdf0..88eea0db34 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.group; public class GroupTransactionValidator { - public static void validate(GroupTransaction transaction) throws IllegalStateException { + public static void validate(GroupChangeListener transaction) throws IllegalStateException { // NOOP } - } diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java new file mode 100644 index 0000000000..839e556fbc --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java @@ -0,0 +1,114 @@ +/** + * 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 Vaclav Demcak + * + */ +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 identifier, DataObject removeDataObj) { + if ((removeDataObj instanceof Meter)) { + + final Meter meter = ((Meter) removeDataObj); + final InstanceIdentifier nodeInstanceId = identifier. 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 identifier, DataObject original, DataObject update) { + if (original instanceof Meter && update instanceof Meter) { + + final Meter originalMeter = ((Meter) original); + final Meter updatedMeter = ((Meter) update); + final InstanceIdentifier nodeInstanceId = identifier. 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 identifier, DataObject addDataObj) { + if ((addDataObj instanceof Meter)) { + + final Meter meter = ((Meter) addDataObj); + final InstanceIdentifier nodeInstanceId = identifier. 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 diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend deleted file mode 100644 index d5292f0f8b..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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, DataObject> { - - @Property - val SalMeterService salMeterService; - - new(SalMeterService manager) { - _salMeterService = manager; - } - - override requestCommit(DataModification, DataObject> modification) { - return new MeterTransaction(modification,salMeterService); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java new file mode 100644 index 0000000000..620801fba5 --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java @@ -0,0 +1,67 @@ +/** + * 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 meterDataChangeListenerRegistration; + + public void start() { + /* Build Path */ + InstanceIdentifierBuilder nodesBuilder = InstanceIdentifier. builder(Nodes.class); + InstanceIdentifierBuilder nodeChild = nodesBuilder. child(Node.class); + InstanceIdentifierBuilder augmentFlowCapNode = nodeChild. augmentation(FlowCapableNode.class); + InstanceIdentifierBuilder meterChild = augmentFlowCapNode. child(Meter.class); + final InstanceIdentifier 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 diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend deleted file mode 100644 index 323da57075..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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,DataObject>> commitHandlerRegistration; - - static val LOG = LoggerFactory.getLogger(MeterProvider); - - def void start() { - commitHandler = new FlowCommitHandler(salMeterService) - val InstanceIdentifier 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") - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend deleted file mode 100644 index 491fa082a2..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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, 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) - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java index b16739cc5b..c8fba23b93 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.meter; public class MeterTransactionValidator { - public static void validate(MeterTransaction transaction) throws IllegalStateException { + public static void validate(MeterChangeListener transaction) throws IllegalStateException { // NOOP } - } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java index 6bd6e6aaf5..cc9c6ebaa6 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java @@ -82,7 +82,7 @@ public class AbstractForwardedTransaction path, final DataObject data) { + invalidateCache(store, path); + final Entry> 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 currentArguments = new ArrayList<>(); DataNormalizationOperation currentOp = codec.getDataNormalizer().getRootOperation(); Iterator iterator = normalizedPath.getPath().iterator(); @@ -135,8 +156,6 @@ public class AbstractForwardedTransaction implements DataModificationTransaction { + private final ListenerRegistry listeners = ListenerRegistry.create(); private final Map, DataObject> updated = new HashMap<>(); private final Map, DataObject> created = new HashMap<>(); private final Set> removed = new HashSet<>(); @@ -218,13 +219,17 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat @Override public void putOperationalData(final InstanceIdentifier 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 path, final DataObject data) { - posponedRemovedConfiguration.remove(path); + boolean previouslyRemoved = posponedRemovedConfiguration.remove(path); DataObject originalObj = readConfigurationData(path); if (originalObj != null) { original.put(path, originalObj); @@ -233,7 +238,11 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat 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 @@ -314,6 +323,14 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat private void changeStatus(final TransactionStatus status) { LOG.trace("Transaction {} changed status to {}", getIdentifier(), status); this.status = status; + + for(ListenerRegistration listener : listeners) { + try { + listener.getInstance().onStatusUpdated(this, status); + } catch (Exception e) { + LOG.error("Error during invoking transaction listener {}",listener.getInstance(),e); + } + } } @Override @@ -327,10 +344,10 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat doDelete(getDelegate(), LogicalDatastoreType.OPERATIONAL, path); } - final ListenableFuture> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this); - changeStatus(TransactionStatus.SUBMITED); + final ListenableFuture> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this); + Futures.addCallback(f, new FutureCallback>() { @Override public void onSuccess(final RpcResult result) { @@ -349,7 +366,7 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat @Override public ListenerRegistration registerListener(final DataTransactionListener listener) { - throw new UnsupportedOperationException(); + return listeners.register(listener); } } diff --git a/opendaylight/md-sal/sal-binding-dom-it/pom.xml b/opendaylight/md-sal/sal-binding-dom-it/pom.xml index 21fa207d78..d1354f897f 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/pom.xml +++ b/opendaylight/md-sal/sal-binding-dom-it/pom.xml @@ -14,6 +14,10 @@ junit junit + + org.opendaylight.yangtools + yang-binding + org.opendaylight.controller sal-binding-broker-impl @@ -25,10 +29,6 @@ test-jar test - - org.opendaylight.yangtools - yang-binding - org.opendaylight.controller.model model-flow-management @@ -54,26 +54,6 @@ - - org.opendaylight.yangtools - yang-maven-plugin - - - - generate-sources - - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - org.jacoco jacoco-maven-plugin @@ -98,6 +78,26 @@ + + org.opendaylight.yangtools + yang-maven-plugin + + + + generate-sources + + + + + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + ${salGeneratorPath} + + + true + + + + diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java index a91799d458..19235d2ddf 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java @@ -11,6 +11,7 @@ import com.google.common.base.Predicate; 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

, D> implements DataChangeEvent { @@ -127,6 +128,8 @@ public final class ImmutableDataChangeEvent

, D> implements Dat 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; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java index c62c27dea8..e74ba95891 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java @@ -394,7 +394,8 @@ public class ResolveDataChangeEventsTask implements Callable listeners, final NormalizedNode 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> container = (NormalizedNodeContainer>) node; - for (NormalizedNode child : container.getValue()) { - PathArgument childId = child.getIdentifier(); - Collection 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> container = (NormalizedNodeContainer>) node; + for (NormalizedNode child : container.getValue()) { + PathArgument childId = child.getIdentifier(); + Collection 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, @@ -476,7 +484,7 @@ public class ResolveDataChangeEventsTask implements Callable entryStrategy; @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafSetModificationStrategy(final LeafListSchemaNode schema) { + protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { super((Class) LeafSetNode.class); entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); } @@ -589,6 +599,32 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } + public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final Optional entryStrategy; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { + super((Class) LeafSetNode.class); + entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) { + return ImmutableOrderedLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier); + } + + @Override + public Optional getChild(final PathArgument identifier) { + if (identifier instanceof NodeWithValue) { + return entryStrategy; + } + return Optional.absent(); + } + + } + public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation { private final Optional entryStrategy; diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java index 4a58579b13..167fb21ffd 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java @@ -20,8 +20,8 @@ abstract class AbstractListeningStatsTracker extends AbstractStatsTracker< private static final Logger logger = LoggerFactory.getLogger(AbstractListeningStatsTracker.class); private ListenerRegistration reg; - protected AbstractListeningStatsTracker(FlowCapableContext context, long lifetimeNanos) { - super(context, lifetimeNanos); + protected AbstractListeningStatsTracker(FlowCapableContext context) { + super(context); } protected abstract InstanceIdentifier listenPath(); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java index c29b6a7730..e922656d91 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java @@ -32,6 +32,9 @@ import com.google.common.util.concurrent.JdkFutureAdapters; abstract class AbstractStatsTracker { private static final Logger logger = LoggerFactory.getLogger(AbstractStatsTracker.class); + + private static final int WAIT_FOR_REQUEST_CYCLE = 2; + private final FutureCallback> callback = new FutureCallback>() { @Override @@ -62,11 +65,11 @@ abstract class AbstractStatsTracker { private final Map trackedItems = new HashMap<>(); private final FlowCapableContext context; - private final long lifetimeNanos; + private long requestCounter; - protected AbstractStatsTracker(final FlowCapableContext context, final long lifetimeNanos) { + protected AbstractStatsTracker(final FlowCapableContext context) { this.context = Preconditions.checkNotNull(context); - this.lifetimeNanos = lifetimeNanos; + this.requestCounter = 0; } protected final InstanceIdentifierBuilder getNodeIdentifierBuilder() { @@ -89,24 +92,32 @@ abstract class AbstractStatsTracker { return context.startDataModification(); } + public final synchronized void increaseRequestCounter(){ + this.requestCounter++; + } protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item); protected abstract K updateSingleStat(DataModificationTransaction trans, I item); + public abstract void request(); public final synchronized void updateStats(List list) { - final Long expiryTime = System.nanoTime() + lifetimeNanos; + final DataModificationTransaction trans = startTransaction(); for (final I item : list) { - trackedItems.put(updateSingleStat(trans, item), expiryTime); + trackedItems.put(updateSingleStat(trans, item), requestCounter); } trans.commit(); } - public final synchronized void cleanup(final DataModificationTransaction trans, long now) { + /** + * Statistics will be cleaned up if not update in last two request cycles. + * @param trans + */ + public final synchronized void cleanup(final DataModificationTransaction trans) { for (Iterator> it = trackedItems.entrySet().iterator();it.hasNext();){ Entry e = it.next(); - if (now > e.getValue()) { + if (requestCounter >= e.getValue()+WAIT_FOR_REQUEST_CYCLE) { cleanupSingleStat(trans, e.getKey()); it.remove(); } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java index 90ddc28acd..06d6e82112 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.md.statistics.manager; +import java.util.Collection; import java.util.Map.Entry; import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; @@ -37,12 +38,17 @@ import org.slf4j.LoggerFactory; final class FlowStatsTracker extends AbstractListeningStatsTracker { private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class); private final OpendaylightFlowStatisticsService flowStatsService; + private FlowTableStatsTracker flowTableStats; private int unaccountedFlowsCounter = 1; - FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) { - super(context, lifetimeNanos); + FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context) { + super(context); this.flowStatsService = flowStatsService; } + FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, FlowTableStatsTracker flowTableStats) { + this(flowStatsService, context); + this.flowTableStats = flowTableStats; + } @Override protected void cleanupSingleStat(DataModificationTransaction trans, FlowStatsEntry item) { @@ -203,6 +209,20 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker tables = flowTableStats.getTables(); + logger.debug("Node {} supports {} table(s)", this.getNodeRef(), tables.size()); + for (final TableKey key : tables) { + logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), this.getNodeRef()); + this.requestAggregateFlows(key); + } + + this.requestAllFlowsAllTables(); + + } public void requestAllFlowsAllTables() { if (flowStatsService != null) { final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder(); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java index 3fe68c111a..a160f6d467 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java @@ -30,8 +30,8 @@ final class FlowTableStatsTracker extends AbstractStatsTracker tables = Collections.unmodifiableSet(privateTables); private final OpendaylightFlowTableStatisticsService flowTableStatsService; - FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context, long lifetimeNanos) { - super(context, lifetimeNanos); + FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context) { + super(context); this.flowTableStatsService = flowTableStatsService; } @@ -61,6 +61,7 @@ final class FlowTableStatsTracker extends AbstractStatsTracker targetNodeIdentifier; private final FlowStatsTracker flowStats; private final FlowTableStatsTracker flowTableStats; @@ -103,23 +103,25 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo final OpendaylightGroupStatisticsService groupStatsService, final OpendaylightMeterStatisticsService meterStatsService, final OpendaylightPortStatisticsService portStatsService, - final OpendaylightQueueStatisticsService queueStatsService) { + final OpendaylightQueueStatisticsService queueStatsService, + final StatisticsRequestScheduler srScheduler) { this.dps = Preconditions.checkNotNull(dps); this.targetNodeKey = Preconditions.checkNotNull(nodeKey); + this.srScheduler = Preconditions.checkNotNull(srScheduler); this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build(); this.targetNodeRef = new NodeRef(targetNodeIdentifier); final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES); msgManager = new MultipartMessageManager(lifetimeNanos); - flowStats = new FlowStatsTracker(flowStatsService, this, lifetimeNanos); - flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this, lifetimeNanos); - groupDescStats = new GroupDescStatsTracker(groupStatsService, this, lifetimeNanos); - groupStats = new GroupStatsTracker(groupStatsService, this, lifetimeNanos); - meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this, lifetimeNanos); - meterStats = new MeterStatsTracker(meterStatsService, this, lifetimeNanos); - nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this, lifetimeNanos); - queueStats = new QueueStatsTracker(queueStatsService, this, lifetimeNanos); + flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this); + flowStats = new FlowStatsTracker(flowStatsService, this, flowTableStats); + groupDescStats = new GroupDescStatsTracker(groupStatsService, this); + groupStats = new GroupStatsTracker(groupStatsService, this); + meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this); + meterStats = new MeterStatsTracker(meterStatsService, this); + nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this); + queueStats = new QueueStatsTracker(queueStatsService, this); } public NodeKey getTargetNodeKey() { @@ -138,7 +140,9 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo @Override public DataModificationTransaction startDataModification() { - return dps.beginTransaction(); + DataModificationTransaction dmt = dps.beginTransaction(); + dmt.registerListener(this.srScheduler); + return dmt; } public synchronized void updateGroupDescStats(TransactionAware transaction, List list) { @@ -186,7 +190,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo public synchronized void updateAggregateFlowStats(TransactionAware transaction, AggregateFlowStatistics flowStats) { final Short tableId = msgManager.isExpectedTableTransaction(transaction); if (tableId != null) { - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = this.startDataModification(); InstanceIdentifier

tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey) .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance(); @@ -214,7 +218,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo } public synchronized void updateGroupFeatures(GroupFeatures notification) { - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = this.startDataModification(); final NodeBuilder nodeData = new NodeBuilder(); nodeData.setKey(targetNodeKey); @@ -232,7 +236,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo } public synchronized void updateMeterFeatures(MeterFeatures features) { - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = this.startDataModification(); final NodeBuilder nodeData = new NodeBuilder(); nodeData.setKey(targetNodeKey); @@ -250,16 +254,15 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo } public synchronized void cleanStaleStatistics() { - final DataModificationTransaction trans = dps.beginTransaction(); - final long now = System.nanoTime(); - - flowStats.cleanup(trans, now); - groupDescStats.cleanup(trans, now); - groupStats.cleanup(trans, now); - meterConfigStats.cleanup(trans, now); - meterStats.cleanup(trans, now); - nodeConnectorStats.cleanup(trans, now); - queueStats.cleanup(trans, now); + final DataModificationTransaction trans = this.startDataModification(); + + flowStats.cleanup(trans); + groupDescStats.cleanup(trans); + groupStats.cleanup(trans); + meterConfigStats.cleanup(trans); + meterStats.cleanup(trans); + nodeConnectorStats.cleanup(trans); + queueStats.cleanup(trans); msgManager.cleanStaleTransactionIds(); trans.commit(); @@ -268,26 +271,23 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo public synchronized void requestPeriodicStatistics() { logger.debug("Send requests for statistics collection to node : {}", targetNodeKey); - flowTableStats.request(); - - // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest() - // comes back -- we do not have any tables anyway. - final Collection tables = flowTableStats.getTables(); - logger.debug("Node {} supports {} table(s)", targetNodeKey, tables.size()); - for (final TableKey key : tables) { - logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), targetNodeKey); - flowStats.requestAggregateFlows(key); - } - - flowStats.requestAllFlowsAllTables(); - nodeConnectorStats.request(); - groupStats.request(); - groupDescStats.request(); - meterStats.request(); - meterConfigStats.request(); - queueStats.request(); + this.srScheduler.addRequestToSchedulerQueue(flowTableStats); + + this.srScheduler.addRequestToSchedulerQueue(flowStats); + + this.srScheduler.addRequestToSchedulerQueue(nodeConnectorStats); + + this.srScheduler.addRequestToSchedulerQueue(groupStats); + + this.srScheduler.addRequestToSchedulerQueue(groupDescStats); + + this.srScheduler.addRequestToSchedulerQueue(meterStats); + + this.srScheduler.addRequestToSchedulerQueue(meterConfigStats); + + this.srScheduler.addRequestToSchedulerQueue(queueStats); } - + public synchronized void start(final Timer timer) { flowStats.start(dps); groupDescStats.start(dps); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java index f187c7082e..6f93eeb617 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java @@ -36,8 +36,8 @@ final class QueueStatsTracker extends AbstractListeningStatsTracker requestQueue = + Collections.synchronizedMap(new LinkedHashMap()); + + private Long PendingTransactions; + + private long lastRequestTime = System.nanoTime(); + + private static final long REQUEST_MONITOR_INTERVAL = 1000; + + private final TimerTask task = new TimerTask() { + @Override + public void run() { + long now = System.nanoTime(); + if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){ + requestStatistics(); + } + } + }; + + public StatisticsRequestScheduler(){ + PendingTransactions = (long) 0; + } + + public void addRequestToSchedulerQueue(AbstractStatsTracker statsRequest){ + requestQueue.put(statsRequest, null); + } + + public AbstractStatsTracker getNextRequestFromSchedulerQueue(){ + //Remove first element + AbstractStatsTracker stats = null; + synchronized(requestQueue){ + Iterator> nodesItr = requestQueue.entrySet().iterator(); + if(nodesItr.hasNext()){ + stats = nodesItr.next().getKey(); + srsLogger.debug("{} chosen up for execution",stats.getNodeRef()); + nodesItr.remove(); + return stats; + } + } + return stats; + } + + private void requestStatistics(){ + AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue(); + if(stats != null) { + stats.request(); + stats.increaseRequestCounter(); + } + } + @Override + public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) { + + AbstractStatsTracker stats = null; + synchronized(PendingTransactions){ + switch(status){ + case SUBMITED: + this.PendingTransactions++; + break; + case COMMITED: + case FAILED: + this.PendingTransactions--; + if(PendingTransactions == 0){ + lastRequestTime = System.nanoTime(); + stats = this.getNextRequestFromSchedulerQueue(); + } + srsLogger.debug("Pending MD-SAL transactions : {} & Scheduler queue size : {}",this.PendingTransactions,this.requestQueue.size()); + break; + default: + break; + } + } + if(stats != null){ + stats.request(); + stats.increaseRequestCounter(); + } + } + + public void start(){ + timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL); + } +} diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index 857cc3e2e5..b77d92e7cb 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -13,6 +13,20 @@ import ch.ethz.ssh2.Session; 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; @@ -52,22 +66,6 @@ import org.w3c.dom.Element; 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; @@ -411,7 +409,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { 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) { diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java index 6ddc8ebb55..2e9a0b9d8b 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java @@ -7,42 +7,26 @@ */ 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 roles = new ArrayList(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); } @@ -53,11 +37,11 @@ public class AuthProvider implements AuthProviderInterface { @Override public void removeUserManagerService() { - AuthProvider.um = null; + this.um = null; } @Override public void addUserManagerService(IUserManager userManagerService) { - AuthProvider.um = userManagerService; + this.um = userManagerService; } } diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java index 5b8803001c..ca0c9454d4 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java @@ -8,12 +8,21 @@ 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; @@ -21,16 +30,12 @@ import org.osgi.util.tracker.ServiceTracker; 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. @@ -44,6 +49,8 @@ public class NetconfSSHActivator implements BundleActivator{ private static final String EXCEPTION_MESSAGE = "Netconf ssh bridge is not available."; private IUserManager iUserManager; private BundleContext context = null; + private Optional defaultPassword; + private Optional defaultUser; private ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer(){ @Override @@ -79,20 +86,23 @@ public class NetconfSSHActivator implements BundleActivator{ @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 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."); } @@ -100,11 +110,10 @@ public class NetconfSSHActivator implements BundleActivator{ 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 @@ -117,6 +126,17 @@ public class NetconfSSHActivator implements BundleActivator{ } 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 roles = new ArrayList(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); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java index b23a2d6697..f89df2ac7c 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java @@ -9,12 +9,11 @@ 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 { @@ -32,6 +31,8 @@ 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; @@ -72,6 +73,13 @@ public final class NetconfConfigUtil { public static String getPrivateKeyPath(BundleContext context){ return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP); } + public static Optional getSSHDefaultUser(BundleContext context){ + return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_USER); + } + public static Optional 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){ @@ -79,6 +87,13 @@ public final class NetconfConfigUtil { } return propertyValue; } + private static Optional 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.