package org.opendaylight.controller.arphandler.internal;\r
\r
\r
-import junit.framework.TestCase;\r
-\r
import org.junit.Assert;\r
import org.junit.Test;\r
\r
-public class ArphandlerTest extends TestCase {\r
+public class ArphandlerTest {\r
\r
@Test\r
public void testArphandlerCreation() {\r
private ViewChangedListener cacheManagerListener;
private static String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress();
-
+ private static final int gossipRouterPortDefault = 12001;
// defaultTransactionTimeout is 60 seconds
private static int DEFAULT_TRANSACTION_TIMEOUT = 60;
*/
private GossipRouter startGossiper() {
boolean amIGossipRouter = false;
- Integer gossipRouterPortDefault = 12001;
Integer gossipRouterPort = gossipRouterPortDefault;
InetAddress gossipRouterAddress = null;
String supernodes_list = System.getProperty("supernodes",
loopbackAddress);
- StringBuffer sanitized_supernodes_list = new StringBuffer();
+ StringBuilder sanitized_supernodes_list = new StringBuilder();
List<InetAddress> myAddresses = new ArrayList<InetAddress>();
StringTokenizer supernodes = new StringTokenizer(supernodes_list, ":");
try {
hostAddr = InetAddress.getByName(host);
} catch (UnknownHostException ue) {
- logger.error("Host not known");
+ logger.error("Host {} is not known", host);
continue;
}
if (host_port.hasMoreTokens()) {
try {
port_num = Integer.valueOf(port);
} catch (NumberFormatException ne) {
- logger
- .error("Supplied supernode gossiepr port is not recognized, using standard gossipport");
+ logger.error("Supplied supernode gossip port is not recognized, using default gossip port {}",
+ gossipRouterPortDefault);
port_num = gossipRouterPortDefault;
}
if ((port_num > 65535) || (port_num < 0)) {
- logger
- .error("Supplied supernode gossip port is outside a valid TCP port range");
+ logger.error("Supplied supernode gossip port is outside a valid TCP port range");
port_num = gossipRouterPortDefault;
}
}
if (!sanitized_supernodes_list.toString().equals("")) {
sanitized_supernodes_list.append(",");
}
- sanitized_supernodes_list.append(hostAddr.getHostAddress() + "["
- + port_num + "]");
+ sanitized_supernodes_list.append(hostAddr.getHostAddress()).append("[").append(port_num).append("]");
}
if (amIGossipRouter) {
import org.junit.Assert;\r
import org.junit.Test;\r
\r
-import junit.framework.TestCase;\r
-\r
-public class TestClusteringTest extends TestCase {\r
+public class TestClusteringTest {\r
\r
@Test\r
public void testComplexClass() {\r
<ietf-inet-types.version>2010.09.24.2-SNAPSHOT</ietf-inet-types.version>
<ietf-yang-types.version>2010.09.24.2-SNAPSHOT</ietf-yang-types.version>
<ietf-topology.version>2013.10.21.0-SNAPSHOT</ietf-topology.version>
- <opendaylight-l2-types.version>2013.08.27.1</opendaylight-l2-types.version>
- <yang-ext.version>2013.09.07.1</yang-ext.version>
+ <opendaylight-l2-types.version>2013.08.27.2-SNAPSHOT</opendaylight-l2-types.version>
+ <yang-ext.version>2013.09.07.2-SNAPSHOT</yang-ext.version>
<javassist.version>3.17.1-GA</javassist.version>
<sample-toaster.version>1.0-SNAPSHOT</sample-toaster.version>
<releaseplugin.version>2.3.2</releaseplugin.version>
try {
startNegotiation();
} catch (Exception e) {
- logger.info("Unexpected negotiation failure", e);
+ logger.warn("Unexpected negotiation failure", e);
negotiationFailed(e);
}
}
try {
handleMessage((M)msg);
} catch (Exception e) {
- logger.debug("Unexpected exception during negotiation", e);
+ logger.debug("Unexpected error while handling negotiation message {}", msg, e);
negotiationFailed(e);
}
}
+
+ @Override
+ public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
+ logger.info("Unexpected error during negotiation", cause);
+ negotiationFailed(cause);
+ }
}
}
if (!cf.isSuccess()) {
- LOG.info("Attempt to connect to connect to {} failed", ProtocolSessionPromise.this.address, cf.cause());
+ LOG.warn("Attempt to connect to connect to {} failed", ProtocolSessionPromise.this.address, cf.cause());
final Future<Void> rf = ProtocolSessionPromise.this.strategy.scheduleReconnect(cf.cause());
rf.addListener(new FutureListener<Void>() {
@Override
throws ConflictingVersionException, ValidationException {
final String transactionName = ObjectNameUtil
.getTransactionName(transactionControllerON);
- logger.info("About to commit {}. Current parentVersion: {}, versionCounter {}", transactionName, version, versionCounter);
+ logger.trace("About to commit {}. Current parentVersion: {}, versionCounter {}", transactionName, version, versionCounter);
// find ConfigTransactionController
Map<String, ConfigTransactionControllerInternal> transactions = transactionsHolder.getCurrentTransactions();
private void validate_noLocks() throws ValidationException {
transactionStatus.checkNotAborted();
- logger.info("Validating transaction {}", getTransactionIdentifier());
+ logger.trace("Validating transaction {}", getTransactionIdentifier());
// call validate()
List<ValidationException> collectedExceptions = new ArrayList<>();
for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
throw ValidationException
.createFromCollectedValidationExceptions(collectedExceptions);
}
- logger.info("Validated transaction {}", getTransactionIdentifier());
+ logger.trace("Validated transaction {}", getTransactionIdentifier());
}
/**
try {
validate_noLocks();
} catch (ValidationException e) {
- logger.info("Commit failed on validation");
+ logger.trace("Commit failed on validation");
configBeanModificationDisabled.set(false); // recoverable error
throw e;
}
+ "to obtain a lock");
}
- logger.info("Committing transaction {}", getTransactionIdentifier());
+ logger.trace("Committing transaction {}", getTransactionIdentifier());
// call getInstance()
for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
// count dependency order
- logger.info("Committed configuration {}", getTransactionIdentifier());
+ logger.trace("Committed configuration {}", getTransactionIdentifier());
transactionStatus.setCommitted();
// unregister this and all modules from jmx
close();
@Override
public void close() {
- logger.info("Destroying {}", identifier);
+ logger.trace("Destroying {}", identifier);
try {
instance.close();
} catch (Exception e) {
logger.warn("Thread dump:{}", sb);
System.exit(1);
} catch (InterruptedException e) {
- logger.info("Interrupted, not going to call System.exit(1)");
+ logger.warn("Interrupted, not going to call System.exit(1)");
}
}
}
pathToFile.mkdirs();
}
if (targetFile.exists() && overwrite == false) {
- logger.info("Skipping {} since it already exists", targetFile);
+ logger.trace("Skipping {} since it already exists", targetFile);
} else {
try (Writer fileWriter = new FileWriter(targetFile)) {
fileWriter.write(entry.getValue());
}
- logger.info("{}: File {} generated successfully",
+ logger.trace("{}: File {} generated successfully",
JMXGenerator.class.getCanonicalName(), targetFile);
result.add(targetFile);
}
updateCache(snapshot);
cache.setInconsistentURLsForReporting(Collections.<URL> emptySet());
- logger.info("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size());
+ logger.trace("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size());
logger.debug("Yang store updated to new consistent state containing {}", consistentBundlesToYangURLs);
}
Status status = configurationAware.saveConfiguration();
if (!status.isSuccess()) {
success = false;
- logger.info("Failed to save config for {}",
+ logger.warn("Failed to save config for {}",
configurationAware.getClass().getName());
}
}
public Status saveConfiguration() {
boolean success = true;
for (IConfigurationContainerAware configurationAware : configurationAwareList) {
- logger.info("Save Config triggered for {}", configurationAware.getClass().getSimpleName());
+ logger.trace("Save Config triggered for {}", configurationAware.getClass().getSimpleName());
Status status = configurationAware.saveConfiguration();
if (!status.isSuccess()) {
success = false;
- logger.info("Failed to save config for {}", configurationAware.getClass().getSimpleName());
+ logger.warn("Failed to save config for {}", configurationAware.getClass().getSimpleName());
}
}
if (success) {
*/
private void notifyContainerModeChange(boolean lastActionDelete, boolean notifyLocal) {
if (lastActionDelete == false && containerConfigs.size() == 1) {
- logger.info("First container Creation. Inform listeners");
+ logger.trace("First container Creation. Inform listeners");
synchronized (this.iContainerListener) {
for (IContainerListener i : this.iContainerListener) {
i.containerModeUpdated(UpdateType.ADDED);
}
}
} else if (lastActionDelete == true && containerConfigs.isEmpty()) {
- logger.info("Last container Deletion. Inform listeners");
+ logger.trace("Last container Deletion. Inform listeners");
synchronized (this.iContainerListener) {
for (IContainerListener i : this.iContainerListener) {
i.containerModeUpdated(UpdateType.REMOVED);
@SuppressWarnings("deprecation")
private void allocateCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't create cache");
+ log.trace("un-initialized clusterContainerService, can't create cache");
return;
}
@SuppressWarnings({ "unchecked", "deprecation" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't retrieve cache");
+ log.warn("un-initialized clusterContainerService, can't retrieve cache");
return;
}
private void notifyStaticRouteUpdate(StaticRoute s, boolean update) {
if (this.staticRoutingAware != null) {
- log.info("Invoking StaticRoutingAware listeners");
+ log.trace("Invoking StaticRoutingAware listeners");
synchronized (this.staticRoutingAware) {
for (IStaticRoutingAware ra : this.staticRoutingAware) {
try {
Status succeeded = null;
boolean decouple = false;
if (installedList.size() != toInstallList.size()) {
- log.info("Modify: New flow entry does not satisfy the same "
+ log.trace("Modify: New flow entry does not satisfy the same "
+ "number of container flows as the original entry does");
decouple = true;
}
*/
FlowEntryInstall sameMatchEntry = installedSwView.get(installEntry);
if (sameMatchEntry != null && !sameMatchEntry.getOriginal().equals(currentFlowEntry)) {
- log.info("Modify: new container flow merged flow entry clashes with existing flow");
+ log.trace("Modify: new container flow merged flow entry clashes with existing flow");
decouple = true;
} else {
toInstallSafe.add(installEntry);
}
Status error = modifyEntry(currentFlowEntry, newFlowEntry, false);
if (error.isSuccess()) {
- log.info("Ports {} added to FlowEntry {}", portList, flowName);
+ log.trace("Ports {} added to FlowEntry {}", portList, flowName);
} else {
log.warn("Failed to add ports {} to Flow entry {}. The failure is: {}", portList,
currentFlowEntry.toString(), error.getDescription());
}
Status status = modifyEntry(currentFlowEntry, newFlowEntry, false);
if (status.isSuccess()) {
- log.info("Ports {} removed from FlowEntry {}", portList, flowName);
+ log.trace("Ports {} removed from FlowEntry {}", portList, flowName);
} else {
log.warn("Failed to remove ports {} from Flow entry {}. The failure is: {}", portList,
currentFlowEntry.toString(), status.getDescription());
Status status = modifyEntry(currentFlowEntry, newFlowEntry, false);
if (status.isSuccess()) {
- log.info("Output port replaced with {} for flow {} on node {}", outPort, flowName, node);
+ log.trace("Output port replaced with {} for flow {} on node {}", outPort, flowName, node);
} else {
log.warn("Failed to replace output port for flow {} on node {}. The failure is: {}", flowName, node,
status.getDescription());
// Do not attempt to reinstall the flow, warn user
if (newFlowConfig.equals(oldFlowConfig)) {
String msg = "No modification detected";
- log.info("Static flow modification skipped. New flow and old flow are the same: {}", newFlowConfig);
+ log.trace("Static flow modification skipped. New flow and old flow are the same: {}", newFlowConfig);
return new Status(StatusCode.SUCCESS, msg);
}
* inactive list
*/
private void uninstallAllFlowEntries(boolean preserveFlowEntries) {
- log.info("Uninstalling all non-internal flows");
+ log.trace("Uninstalling all non-internal flows");
List<FlowEntryInstall> toRemove = new ArrayList<FlowEntryInstall>();
* default container instance of FRM only when the last container is deleted
*/
private void reinstallAllFlowEntries() {
- log.info("Reinstalling all inactive flows");
+ log.trace("Reinstalling all inactive flows");
for (FlowEntry flowEntry : this.inactiveFlows.keySet()) {
this.addEntry(flowEntry, false);
dropAllConfig.setActions(dropAction);
defaultConfigs.add(dropAllConfig);
- log.info("Forwarding mode for node {} set to {}", node, (proactive ? "proactive" : "reactive"));
+ log.trace("Forwarding mode for node {} set to {}", node, (proactive ? "proactive" : "reactive"));
for (FlowConfig fc : defaultConfigs) {
Status status = (proactive) ? addStaticFlowInternal(fc, false) : removeStaticFlow(fc);
if (status.isSuccess()) {
- log.info("{} Proactive Static flow: {}", (proactive ? "Installed" : "Removed"), fc.getName());
+ log.trace("{} Proactive Static flow: {}", (proactive ? "Installed" : "Removed"), fc.getName());
} else {
log.warn("Failed to {} Proactive Static flow: {}", (proactive ? "install" : "remove"),
fc.getName());
* @param node
*/
private void cleanDatabaseForNode(Node node) {
- log.info("Cleaning Flow database for Node {}", node);
+ log.trace("Cleaning Flow database for Node {}", node);
if (nodeFlows.containsKey(node)) {
List<FlowEntryInstall> toRemove = new ArrayList<FlowEntryInstall>(nodeFlows.get(node));
@Override
public void portGroupChanged(PortGroupConfig config, Map<Node, PortGroup> data, boolean add) {
- log.info("PortGroup Changed for: {} Data: {}", config, portGroupData);
+ log.trace("PortGroup Changed for: {} Data: {}", config, portGroupData);
Map<Node, PortGroup> existingData = portGroupData.get(config);
if (existingData != null) {
for (Map.Entry<Node, PortGroup> entry : data.entrySet()) {
\r
import org.junit.Assert;\r
import org.junit.Test;\r
-\r
import org.opendaylight.controller.sal.core.ConstructionException;\r
import org.opendaylight.controller.sal.core.Node;\r
-\r
-import junit.framework.TestCase;\r
-\r
+import org.opendaylight.controller.sal.core.NodeConnector;\r
import org.opendaylight.controller.sal.packet.address.EthernetAddress;\r
-\r
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;\r
-import org.opendaylight.controller.sal.core.NodeConnector;\r
import org.opendaylight.controller.sal.utils.NodeCreator;\r
\r
-public class HostNodeConnectorTest extends TestCase {\r
+public class HostNodeConnectorTest {\r
\r
@Test\r
public void testHostNodeConnector() throws UnknownHostException {\r
import java.net.InetAddress;\r
import java.net.UnknownHostException;\r
\r
-import junit.framework.TestCase;\r
-\r
import org.junit.Assert;\r
import org.junit.Test;\r
import org.opendaylight.controller.hosttracker.IHostId;\r
import org.opendaylight.controller.hosttracker.IPHostId;\r
\r
-public class HostTrackerTest extends TestCase {\r
+public class HostTrackerTest {\r
\r
@Test\r
public void testHostTrackerCallable() throws UnknownHostException {\r
\r
import org.junit.Assert;\r
import org.junit.Test;\r
-\r
import org.opendaylight.controller.sal.core.ConstructionException;\r
import org.opendaylight.controller.sal.core.Node;\r
-\r
-import junit.framework.TestCase;\r
-\r
+import org.opendaylight.controller.sal.core.NodeConnector;\r
import org.opendaylight.controller.sal.packet.address.EthernetAddress;\r
-\r
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;\r
-import org.opendaylight.controller.sal.core.NodeConnector;\r
import org.opendaylight.controller.sal.utils.NodeCreator;\r
\r
-public class HostNodeConnectorTest extends TestCase {\r
+public class HostNodeConnectorTest {\r
\r
@Test\r
public void testHostNodeConnector() throws UnknownHostException {\r
if (reader == null) {
this.log.error("Cannot register the LogListener because "
+ "cannot retrieve LogReaderService");
- }
- reader.addLogListener(this.listener);
- // Now lets walk all the exiting messages
- Enumeration<LogEntry> entries = reader.getLog();
- if (entries != null) {
- while (entries.hasMoreElements()) {
- LogEntry entry = (LogEntry) entries.nextElement();
- this.listener.logged(entry);
+ } else {
+ reader.addLogListener(this.listener);
+ // Now lets walk all the exiting messages
+ Enumeration<LogEntry> entries = reader.getLog();
+ if (entries != null) {
+ while (entries.hasMoreElements()) {
+ LogEntry entry = entries.nextElement();
+ this.listener.logged(entry);
+ }
}
}
log.warn("Invalid policy name \"{}\", defaulting to {}", policy, handler);
}
}
- log.info("Setting uncaught exception policy to {}", handler);
+ log.trace("Setting uncaught exception policy to {}", handler);
Thread.setDefaultUncaughtExceptionHandler(handler);
/*
@Override
public void stop(BundleContext context) {
- ServiceReference service = null;
- service = context.getServiceReference(LogReaderService.class.getName());
- if (service != null) {
- LogReaderService reader = (LogReaderService) service;
+ ServiceReference serviceRef = context.getServiceReference(
+ LogReaderService.class.getName());
+ if (serviceRef != null) {
+ LogReaderService reader = (LogReaderService) context.getService(serviceRef);
reader.removeLogListener(this.listener);
}
if (this.shutdownHandler != null) {
private Logger logger = LoggerFactory.getLogger(ClusteredDataStoreImpl.class);
public ClusteredDataStoreImpl(IClusterGlobalServices clusterGlobalServices) throws CacheConfigException {
- logger.info("Constructing clustered data store");
+ logger.trace("Constructing clustered data store");
Preconditions.checkNotNull(clusterGlobalServices, "clusterGlobalServices cannot be null");
operationalDataCache = getOrCreateCache(clusterGlobalServices, OPERATIONAL_DATA_CACHE);
public boolean containsConfigurationPath(InstanceIdentifier path) {
return configurationDataCache.containsKey(path);
}
-
+
@Override
public boolean containsOperationalPath(InstanceIdentifier path) {
return operationalDataCache.containsKey(path);
}
-
+
@Override
public Iterable<InstanceIdentifier> getStoredConfigurationPaths() {
return configurationDataCache.keySet();
}
-
+
@Override
public Iterable<InstanceIdentifier> getStoredOperationalPaths() {
return operationalDataCache.keySet();
}
-
-
-
+
+
+
@Override
public CompositeNode readConfigurationData(InstanceIdentifier path) {
Preconditions.checkNotNull(path, "path cannot be null");
val table= it.readConfigurationData(tableRef) as Table;
if(table != null){
- LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+ LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
for(flow : table.flow){
val table= it.readConfigurationData(tableRef) as Table;
if(table != null){
- LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+ LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
for(mdsalFlow : table.flow){
if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1-SNAPSHOT</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>yang-ext</artifactId>
- <version>2013.09.07.1-SNAPSHOT</version>
+ <version>2013.09.07.2-SNAPSHOT</version>
</dependency>
</dependencies>
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-broker-impl</artifactId>
<version>1.0-SNAPSHOT</version>
- <scope>runtime</scope>
+ <scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.codegen.impl;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
+import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@Override
public RpcRegistration<T> registerDefaultService(T service) {
// TODO Auto-generated method stub
+ RuntimeCodeHelper.setDelegate(invocationProxy, service);
return null;
}
baArgs.add(baArg)
}
val ret = new InstanceIdentifier(baArgs,baType as Class<? extends DataObject>);
+ LOG.debug("DOM Instance Identifier {} deserialized to {}",input,ret);
return ret;
}
previousAugmentation = baArg.type;
}
}
- return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(components);
+ val ret = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(components);
+ LOG.debug("Binding Instance Identifier {} serialized to DOM InstanceIdentifier {}",input,ret);
+ return ret;
}
def updateAugmentationInjection(Class<? extends DataObject> class1, ImmutableList<QName> list, Class<?> augmentation) {
if (typeDef !== null) {
return typeDef;
}
- LOG.info("Thread blocked waiting for schema for: {}",type.fullyQualifiedName)
+ LOG.trace("Thread blocked waiting for schema for: {}",type.fullyQualifiedName)
return type.getSchemaInFuture.get();
}
}
private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
- log.info("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
+ log.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
return createClass(typeSpec.codecClassName) [
if (object.isYangBindingAvailable) {
implementsType(BINDING_CODEC)
if(log.isDebugEnabled){\r
log.debug("Delivering notification {} to {}",notification,listener);\r
} else {\r
- log.info("Delivering notification {} to {}",notification.class.name,listener);\r
+ log.trace("Delivering notification {} to {}",notification.class.name,listener);\r
}\r
listener.onNotification(notification);\r
if(log.isDebugEnabled){\r
log.debug("Notification delivered {} to {}",notification,listener);\r
} else {\r
- log.info("Notification delivered {} to {}",notification.class.name,listener);\r
+ log.trace("Notification delivered {} to {}",notification.class.name,listener);\r
}\r
} catch (Exception e) {\r
log.error("Unhandled exception thrown by listener: {}", listener, e);\r
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.impl;
+import java.util.EventListener;
import java.util.Map;
import java.util.Map.Entry;
import java.util.HashMap;
private final Map<Class<? extends RpcService>, RpcRouter<?>> rpcRouters = new WeakHashMap<>();
private final ListenerRegistry<RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> routeChangeListeners = ListenerRegistry
.create();
+ private final ListenerRegistry<RouterInstantiationListener> routerInstantiationListener = ListenerRegistry.create();
private final static Logger LOG = LoggerFactory.getLogger(RpcProviderRegistryImpl.class);
-
+
private final String name;
+ private ListenerRegistry<GlobalRpcRegistrationListener> globalRpcListeners = ListenerRegistry.create();
+
public String getName() {
return name;
}
T publicProxy = getRpcService(type);
RpcService currentDelegate = RuntimeCodeHelper.getDelegate(publicProxy);
checkState(currentDelegate == null, "Rpc service is already registered");
- LOG.debug("Registering {} as global implementation of {} in {}",implementation,type.getSimpleName(),this);
+ LOG.debug("Registering {} as global implementation of {} in {}", implementation, type.getSimpleName(), this);
RuntimeCodeHelper.setDelegate(publicProxy, implementation);
+ notifyGlobalRpcAdded(type);
return new RpcProxyRegistration<T>(type, implementation, this);
}
if (potentialProxy != null) {
return potentialProxy;
}
- synchronized(this) {
+ synchronized (this) {
/**
- * Potential proxy could be instantiated by other thread while we were
- * waiting for the lock.
+ * Potential proxy could be instantiated by other thread while we
+ * were waiting for the lock.
*/
-
+
potentialProxy = (T) publicProxies.get(type);
if (potentialProxy != null) {
return (T) potentialProxy;
}
T proxy = rpcFactory.getDirectProxyFor(type);
- LOG.debug("Created {} as public proxy for {} in {}",proxy,type.getSimpleName(),this);
+ LOG.debug("Created {} as public proxy for {} in {}", proxy, type.getSimpleName(), this);
publicProxies.put(type, proxy);
return proxy;
}
}
- private <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
+ @SuppressWarnings("unchecked")
+ public <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
RpcRouter<?> potentialRouter = rpcRouters.get(type);
if (potentialRouter != null) {
return (RpcRouter<T>) potentialRouter;
}
- synchronized(this) {
+ synchronized (this) {
/**
- * Potential Router could be instantiated by other thread while we were
- * waiting for the lock.
+ * Potential Router could be instantiated by other thread while we
+ * were waiting for the lock.
*/
- potentialRouter = rpcRouters.get(type);
+ potentialRouter = rpcRouters.get(type);
if (potentialRouter != null) {
return (RpcRouter<T>) potentialRouter;
}
- RpcRouter<T> router = rpcFactory.getRouterFor(type,name);
+ RpcRouter<T> router = rpcFactory.getRouterFor(type, name);
router.registerRouteChangeListener(new RouteChangeForwarder(type));
- LOG.debug("Registering router {} as global implementation of {} in {}",router,type.getSimpleName(),this);
+ LOG.debug("Registering router {} as global implementation of {} in {}", router, type.getSimpleName(), this);
RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy());
rpcRouters.put(type, router);
+ notifyListenersRoutedCreated(router);
return router;
}
}
+ private void notifyGlobalRpcAdded(Class<? extends RpcService> type) {
+ for(ListenerRegistration<GlobalRpcRegistrationListener> listener : globalRpcListeners) {
+ try {
+ listener.getInstance().onGlobalRpcRegistered(type);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ }
+
+ }
+
+ private void notifyListenersRoutedCreated(RpcRouter router) {
+
+ for (ListenerRegistration<RouterInstantiationListener> listener : routerInstantiationListener) {
+ try {
+ listener.getInstance().onRpcRouterCreated(router);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ }
+
+ }
+
+ public ListenerRegistration<RouterInstantiationListener> registerRouterInstantiationListener(
+ RouterInstantiationListener listener) {
+ ListenerRegistration<RouterInstantiationListener> reg = routerInstantiationListener.register(listener);
+ try {
+ for (RpcRouter<?> router : rpcRouters.values()) {
+ listener.onRpcRouterCreated(router);
+ }
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ return reg;
+ }
+
@Override
public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
L listener) {
this.rpcFactory = rpcFactory;
}
+ public interface RouterInstantiationListener extends EventListener {
+ void onRpcRouterCreated(RpcRouter<?> router);
+ }
+
+ public ListenerRegistration<GlobalRpcRegistrationListener> registerGlobalRpcRegistrationListener(GlobalRpcRegistrationListener listener) {
+ return globalRpcListeners.register(listener);
+ }
+
+ public interface GlobalRpcRegistrationListener extends EventListener {
+ void onGlobalRpcRegistered(Class<? extends RpcService> cls);
+ void onGlobalRpcUnregistered(Class<? extends RpcService> cls);
+
+ }
+
private class RouteChangeForwarder<T extends RpcService> implements
RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>> {
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.impl.connect.dom;
import static com.google.common.base.Preconditions.checkNotNull;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.impl.connect.dom;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
-import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.GlobalRpcRegistrationListener;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.RouterInstantiationListener;
import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-
-import static com.google.common.base.Preconditions.*;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.util.concurrent.Futures;
public class BindingIndependentConnector implements //
RuntimeDataProvider, //
private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
+ @SuppressWarnings( "deprecation")
private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
.builder().toInstance();
+ private final static Method EQUALS_METHOD;
+
+
private BindingIndependentMappingService mappingService;
private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
private boolean notificationForwarding = false;
+ private RpcProviderRegistryImpl baRpcRegistryImpl;
+
+ private org.opendaylight.controller.sal.dom.broker.spi.RpcRouter biRouter;
+
+
+ static {
+ try {
+ EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
@Override
public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
try {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
CompositeNode result = biDataService.readOperationalData(biPath);
- return potentialAugmentationRead(path,biPath,result);
+ return potentialAugmentationRead(path, biPath, result);
} catch (DeserializationException e) {
throw new IllegalStateException(e);
}
}
- private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException {
+ private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path,
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result)
+ throws DeserializationException {
Class<? extends DataObject> targetType = path.getTargetType();
if (Augmentation.class.isAssignableFrom(targetType)) {
path = mappingService.fromDataDom(biPath);
try {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
CompositeNode result = biDataService.readConfigurationData(biPath);
- return potentialAugmentationRead(path,biPath,result);
+ return potentialAugmentationRead(path, biPath, result);
} catch (DeserializationException e) {
throw new IllegalStateException(e);
}
private DataModificationTransaction createBindingToDomTransaction(
DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
DataModificationTransaction target = biDataService.beginTransaction();
+ LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(),source.getIdentifier());
for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
.entrySet()) {
Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
.toDataDom(entry);
target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
+ LOG.debug("Update of Binding Configuration Data {} is translated to {}",entry,biEntry);
}
for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
.entrySet()) {
Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
.toDataDom(entry);
target.putOperationalData(biEntry.getKey(), biEntry.getValue());
+ LOG.debug("Update of Binding Operational Data {} is translated to {}",entry,biEntry);
}
for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
target.removeConfigurationData(biEntry);
+ LOG.debug("Delete of Binding Configuration Data {} is translated to {}",entry,biEntry);
}
for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
target.removeOperationalData(biEntry);
+ LOG.debug("Delete of Binding Operational Data {} is translated to {}",entry,biEntry);
}
return target;
}
baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
dataForwarding = true;
}
-
+
public void startRpcForwarding() {
if (baRpcRegistry != null && biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher<?, ?>) {
- checkState(!rpcForwarding,"Connector is already forwarding RPCs");
+ checkState(!rpcForwarding, "Connector is already forwarding RPCs");
domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager());
+ if (baRpcRegistry instanceof RpcProviderRegistryImpl) {
+ baRpcRegistryImpl = (RpcProviderRegistryImpl) baRpcRegistry;
+ baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance());
+ baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance());
+ }
+ if(biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) {
+ biRouter = (org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) biRpcRegistry;
+ }
rpcForwarding = true;
}
}
-
+
public void startNotificationForwarding() {
checkState(!notificationForwarding, "Connector is already forwarding notifications.");
notificationForwarding = true;
public void onSessionInitiated(ProviderSession session) {
setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
setDomRpcRegistry(session.getService(RpcProvisionRegistry.class));
-
+
}
public <T extends RpcService> void onRpcRouterCreated(Class<T> serviceType, RpcRouter<T> router) {
}
DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
- LOG.info("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
+ LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
domTransaction.getIdentifier());
return wrapped;
}
org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction);
- LOG.info("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
+ LOG.trace("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
baTransaction.getIdentifier());
return forwardedTransaction;
}
}
+ /**
+ * Manager responsible for instantiating forwarders responsible for
+ * forwarding of RPC invocations from DOM Broker to Binding Aware Broker
+ *
+ */
private class DomToBindingRpcForwardingManager implements
- RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>> {
+ RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>,
+ RouterInstantiationListener,
+ GlobalRpcRegistrationListener {
private final Map<Class<? extends RpcService>, DomToBindingRpcForwarder> forwarders = new WeakHashMap<>();
+ private RpcProviderRegistryImpl registryImpl;
+
+ public RpcProviderRegistryImpl getRegistryImpl() {
+ return registryImpl;
+ }
+
+ public void setRegistryImpl(RpcProviderRegistryImpl registryImpl) {
+ this.registryImpl = registryImpl;
+ }
+
+ @Override
+ public void onGlobalRpcRegistered(Class<? extends RpcService> cls) {
+ getRpcForwarder(cls, null);
+ }
+
+ @Override
+ public void onGlobalRpcUnregistered(Class<? extends RpcService> cls) {
+ // NOOP
+ }
+
+ @Override
+ public void onRpcRouterCreated(RpcRouter<?> router) {
+ Class<? extends BaseIdentity> ctx = router.getContexts().iterator().next();
+ getRpcForwarder(router.getServiceType(), ctx);
+ }
@Override
public void onRouteChange(RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
} else {
potential = new DomToBindingRpcForwarder(service, context);
}
+
forwarders.put(service, potential);
return potential;
}
}
- private class DomToBindingRpcForwarder implements RpcImplementation {
+ private class DomToBindingRpcForwarder implements RpcImplementation, InvocationHandler {
private final Set<QName> supportedRpcs;
private final WeakReference<Class<? extends RpcService>> rpcServiceType;
private Set<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> registrations;
+ private Map<QName, RpcInvocationStrategy> strategiesByQName = new HashMap<>();
+ private WeakHashMap<Method, RpcInvocationStrategy> strategiesByMethod = new WeakHashMap<>();
public DomToBindingRpcForwarder(Class<? extends RpcService> service) {
this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
this.supportedRpcs = mappingService.getRpcQNamesFor(service);
- for (QName rpc : supportedRpcs) {
- biRpcRegistry.addRpcImplementation(rpc, this);
+ try {
+ for (QName rpc : supportedRpcs) {
+ RpcInvocationStrategy strategy = createInvocationStrategy(rpc, service);
+ strategiesByMethod.put(strategy.targetMethod, strategy);
+ strategiesByQName.put(rpc, strategy);
+ biRpcRegistry.addRpcImplementation(rpc, this);
+ }
+
+ } catch (Exception e) {
+ LOG.error("Could not forward Rpcs of type {}", service.getName());
}
registrations = ImmutableSet.of();
}
+ /**
+ * Constructor for Routed RPC Forwareder.
+ *
+ * @param service
+ * @param context
+ */
public DomToBindingRpcForwarder(Class<? extends RpcService> service, Class<? extends BaseIdentity> context) {
this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
this.supportedRpcs = mappingService.getRpcQNamesFor(service);
- registrations = new HashSet<>();
- for (QName rpc : supportedRpcs) {
- registrations.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this));
+ Builder<RoutedRpcRegistration> registrationsBuilder = ImmutableSet
+ .<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> builder();
+ try {
+ for (QName rpc : supportedRpcs) {
+ RpcInvocationStrategy strategy = createInvocationStrategy(rpc, service);
+ strategiesByMethod.put(strategy.targetMethod, strategy);
+ strategiesByQName.put(rpc, strategy);
+ registrationsBuilder.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this));
+ }
+ createDefaultDomForwarder();
+ } catch (Exception e) {
+ LOG.error("Could not forward Rpcs of type {}", service.getName(),e);
}
- registrations = ImmutableSet.copyOf(registrations);
+ registrations = registrationsBuilder.build();
}
public void registerPaths(Class<? extends BaseIdentity> context, Class<? extends RpcService> service,
}
}
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if(EQUALS_METHOD.equals(method)) {
+ return false;
+ }
+ RpcInvocationStrategy strategy = strategiesByMethod.get(method);
+ checkState(strategy != null);
+ checkArgument(args.length <= 2);
+ if(args.length == 1) {
+ checkArgument(args[0] instanceof DataObject);
+ return strategy.forwardToDomBroker((DataObject) args[0]);
+ }
+ return strategy.forwardToDomBroker(null);
+ }
+
public void removePaths(Class<? extends BaseIdentity> context, Class<? extends RpcService> service,
Set<InstanceIdentifier<?>> set) {
QName ctx = BindingReflections.findQName(context);
return supportedRpcs;
}
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public void createDefaultDomForwarder() {
+ if (baRpcRegistryImpl != null) {
+ Class<?> cls = rpcServiceType.get();
+ ClassLoader clsLoader = cls.getClassLoader();
+ RpcService proxy = (RpcService) Proxy.newProxyInstance(clsLoader, new Class<?>[] { cls }, this);
+
+ RpcRouter rpcRouter = baRpcRegistryImpl.getRpcRouter(rpcServiceType.get());
+ rpcRouter.registerDefaultService(proxy);
+ }
+ }
+
@Override
public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode domInput) {
checkArgument(rpc != null);
checkState(rpcService != null);
CompositeNode domUnwrappedInput = domInput.getFirstCompositeByName(QName.create(rpc, "input"));
try {
- return resolveInvocationStrategy(rpc, rpcType).invokeOn(rpcService, domUnwrappedInput);
+ return resolveInvocationStrategy(rpc).invokeOn(rpcService, domUnwrappedInput);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
- private RpcInvocationStrategy resolveInvocationStrategy(final QName rpc,
+ private RpcInvocationStrategy resolveInvocationStrategy(QName rpc) {
+ return strategiesByQName.get(rpc);
+ }
+
+ private RpcInvocationStrategy createInvocationStrategy(final QName rpc,
final Class<? extends RpcService> rpcType) throws Exception {
return ClassLoaderUtils.withClassLoader(rpcType.getClassLoader(), new Callable<RpcInvocationStrategy>() {
@Override
RpcInvocationStrategy strategy = null;
if (outputClass.isPresent()) {
if (inputClass.isPresent()) {
- strategy = new DefaultInvocationStrategy(targetMethod, outputClass.get(), inputClass.get());
+ strategy = new DefaultInvocationStrategy(rpc,targetMethod, outputClass.get(), inputClass.get());
} else {
- strategy = new NoInputNoOutputInvocationStrategy(targetMethod);
+ strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod);
}
} else {
strategy = null;
private abstract class RpcInvocationStrategy {
protected final Method targetMethod;
+ protected final QName rpc;
- public RpcInvocationStrategy(Method targetMethod) {
+ public RpcInvocationStrategy(QName rpc,Method targetMethod) {
this.targetMethod = targetMethod;
+ this.rpc = rpc;
}
+ public abstract Future<RpcResult<?>> forwardToDomBroker(DataObject input);
+
public abstract RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput)
throws Exception;
private WeakReference<Class> outputClass;
@SuppressWarnings({ "rawtypes", "unchecked" })
- public DefaultInvocationStrategy(Method targetMethod, Class<?> outputClass,
+ public DefaultInvocationStrategy(QName rpc, Method targetMethod, Class<?> outputClass,
Class<? extends DataContainer> inputClass) {
- super(targetMethod);
+ super(rpc,targetMethod);
this.outputClass = new WeakReference(outputClass);
this.inputClass = new WeakReference(inputClass);
}
RpcResult<?> bindingResult = result.get();
return Rpcs.getRpcResult(true);
}
+
+ @Override
+ public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
+ if(biRouter != null) {
+ CompositeNode xml = mappingService.toDataDom(input);
+ CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
+ RpcResult<CompositeNode> result = biRouter.invokeRpc(rpc, wrappedXml);
+ Object baResultValue = null;
+ if(result.getResult() != null) {
+ baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), result.getResult());
+ }
+ RpcResult<?> baResult = Rpcs.getRpcResult(result.isSuccessful(), baResultValue, result.getErrors());
+ return Futures.<RpcResult<?>>immediateFuture(baResult);
+ }
+ return Futures.<RpcResult<?>>immediateFuture(Rpcs.getRpcResult(false));
+ }
}
private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy {
- public NoInputNoOutputInvocationStrategy(Method targetMethod) {
- super(targetMethod);
+ public NoInputNoOutputInvocationStrategy(QName rpc, Method targetMethod) {
+ super(rpc,targetMethod);
}
public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
RpcResult<Void> bindingResult = result.get();
return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors());
}
+
+ @Override
+ public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
+ return Futures.immediateFuture(null);
+ }
}
public boolean isRpcForwarding() {
import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
-import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl;
import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import static com.google.common.base.Preconditions.*;
-public class BindingTestContext implements AutoCloseable {
+public class BindingTestContext implements AutoCloseable, SchemaContextProvider {
public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
.builder().toInstance();
private MountPointManagerImpl biMountImpl;
+ private SchemaContext schemaContext;
+
+ public SchemaContext getSchemaContext() {
+ return schemaContext;
+ }
+
protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) {
this.executor = executor;
this.classPool = classPool;
}
public void updateYangSchema(String[] files) {
- SchemaContext context = getContext(files);
+ schemaContext = getContext(files);
if (schemaAwareDataStore != null) {
- schemaAwareDataStore.onGlobalContextUpdated(context);
+ schemaAwareDataStore.onGlobalContextUpdated(schemaContext);
}
if (mappingServiceImpl != null) {
- mappingServiceImpl.onGlobalContextUpdated(context);
+ mappingServiceImpl.onGlobalContextUpdated(schemaContext);
}
}
checkState(executor != null);
biBrokerImpl = new BrokerImpl();
biBrokerImpl.setExecutor(executor);
- biBrokerImpl.setRouter(new RpcRouterImpl("test"));
+ biBrokerImpl.setRouter(new SchemaAwareRpcBroker("/", this));
}
public void startBindingNotificationBroker() {
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.test.connect.dom;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNotSame;
+import static junit.framework.Assert.assertTrue;
+
import java.math.BigInteger;
import java.util.Collections;
+import java.util.Set;
import java.util.concurrent.Future;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
import org.opendaylight.controller.sal.binding.test.util.BindingTestContext;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
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.UpdateFlowOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import static junit.framework.Assert.*;
-
-import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Multimap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
public static final NodeId NODE_B = new NodeId("b");
public static final NodeId NODE_C = new NodeId("c");
public static final NodeId NODE_D = new NodeId("d");
+
+ private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+ private static final QName ADD_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "add-flow");
public static final InstanceIdentifier<Node> BA_NODE_A_ID = createBANodeIdentifier(NODE_A);
public static final InstanceIdentifier<Node> BA_NODE_B_ID = createBANodeIdentifier(NODE_B);
public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_C_ID = createBINodeIdentifier(NODE_C);
public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_D_ID = createBINodeIdentifier(NODE_D);
- private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
- private static final QName ADD_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "add-flow");
- private static final QName REMOVE_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "remove-flow");
- private static final QName UPDATE_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "update-flow");
+
@Before
public void setup() {
assertEquals(addFlowA, flowService.getReceivedAddFlows().get(BA_NODE_A_ID).iterator().next());
}
- public void bindingRpcInvoker_DomRoutedProviderTest() {
-
+ @Test
+ public void bindingRpcInvoker_DomRoutedProviderTest() throws Exception {
+ AddFlowOutputBuilder builder = new AddFlowOutputBuilder();
+ builder.setTransactionId(new TransactionId(BigInteger.valueOf(10)));
+ final AddFlowOutput output = builder.build();
+ org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration registration = biRpcRegistry.addRoutedRpcImplementation(ADD_FLOW_QNAME, new RpcImplementation() {
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ CompositeNode result = testContext.getBindingToDomMappingService().toDataDom(output);
+ return Rpcs.getRpcResult(true, result, ImmutableList.<RpcError>of());
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return ImmutableSet.of(ADD_FLOW_QNAME);
+ }
+ });
+ registration.registerPath(NodeContext.QNAME, BI_NODE_C_ID);
+
+ SalFlowService baFlowInvoker = baRpcRegistry.getRpcService(SalFlowService.class);
+ Future<RpcResult<AddFlowOutput>> baResult = baFlowInvoker.addFlow(addFlow(BA_NODE_C_ID).setPriority(500).build());
+ assertNotNull(baResult);
+ assertEquals(output,baResult.get().getResult());
}
private CompositeNode toDomRpcInput(DataObject addFlowA) {
override final registerCommitHandler(P path, DataCommitHandler<P, D> commitHandler) {\r
val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this);\r
commitHandlers.put(path, registration)\r
- LOG.info("Registering Commit Handler {} for path: {}",commitHandler,path);\r
+ LOG.trace("Registering Commit Handler {} for path: {}",commitHandler,path);\r
for(listener : commitHandlerRegistrationListeners) {\r
try {\r
listener.instance.onRegister(registration);\r
protected final def removeCommitHandler(DataCommitHandlerRegistrationImpl<P, D> registration) {\r
commitHandlers.remove(registration.path, registration);\r
\r
- LOG.info("Removing Commit Handler {} for path: {}",registration.instance,registration.path);\r
+ LOG.trace("Removing Commit Handler {} for path: {}",registration.instance,registration.path);\r
for(listener : commitHandlerRegistrationListeners) {\r
try {\r
listener.instance.onUnregister(registration);\r
\r
val transactionId = transaction.identifier;\r
\r
- log.info("Transaction: {} Started.",transactionId);\r
+ log.trace("Transaction: {} Started.",transactionId);\r
// requesting commits\r
val Iterable<DataCommitHandler<P, D>> commitHandlers = dataBroker.affectedCommitHandlers(affectedPaths);\r
val List<DataCommitTransaction<P, D>> handlerTransactions = new ArrayList();\r
dataBroker.failedTransactionsCount.andIncrement\r
return rollback(handlerTransactions, e);\r
}\r
- log.info("Transaction: {} Finished successfully.",transactionId);\r
+ log.trace("Transaction: {} Finished successfully.",transactionId);\r
dataBroker.finishedTransactionsCount.andIncrement;\r
return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());\r
\r
\r
public abstract class AbstractDataTransaction<P extends Path<P>, D> extends AbstractDataModification<P, D> {\r
\r
+ private static val LOG = LoggerFactory.getLogger(AbstractDataTransaction);
+
@Property\r
private val Object identifier;\r
\r
_identifier = identifier;\r
broker = dataBroker;\r
status = TransactionStatus.NEW;\r
+ LOG.debug("Transaction {} Allocated.", identifier);
\r
//listeners = new ListenerRegistry<>();\r
}\r
protected abstract def void onStatusChange(TransactionStatus status);\r
\r
public def changeStatus(TransactionStatus status) {\r
+ LOG.debug("Transaction {} transitioned from {} to {}", identifier, this.status, status);
this.status = status;\r
onStatusChange(status);\r
}\r
package org.opendaylight.controller.sal.core.api;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-public interface RpcProvisionRegistry extends BrokerService {
+public interface RpcProvisionRegistry extends BrokerService, RouteChangePublisher<RpcRoutingContext, InstanceIdentifier> {
/**
* Registers an implementation of the rpc.
*/
RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
throws IllegalArgumentException;
+
+ ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener);
RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation);
}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.core.api;
import java.util.EventListener;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.controller.sal.core.api;
+import java.io.Serializable;
+
+import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.common.QName;
-public interface RpcRoutingContext {
+public class RpcRoutingContext implements Immutable, Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9079324728075883325L;
+
+ private final QName context;
+ private final QName rpc;
+
+
+ private RpcRoutingContext(QName context, QName rpc) {
+ super();
+ this.context = context;
+ this.rpc = rpc;
+ }
+
+ public static final RpcRoutingContext create(QName context, QName rpc) {
+ return new RpcRoutingContext(context, rpc);
+ }
+
+ public QName getContext() {
+ return context;
+ }
+
+ public QName getRpc() {
+ return rpc;
+ }
+
+ @Override
+ public String toString() {
+ return "RpcRoutingContext [context=" + context + ", rpc=" + rpc + "]";
+ }
- public QName getContext();
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((context == null) ? 0 : context.hashCode());
+ result = prime * result + ((rpc == null) ? 0 : rpc.hashCode());
+ return result;
+ }
- public QName getRpcType();
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RpcRoutingContext other = (RpcRoutingContext) obj;
+ if (context == null) {
+ if (other.context != null)
+ return false;
+ } else if (!context.equals(other.context))
+ return false;
+ if (rpc == null) {
+ if (other.rpc != null)
+ return false;
+ } else if (!rpc.equals(other.rpc))
+ return false;
+ return true;
+ }
}
<configuration>
<instructions>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ <Export-Package>
+ org.opendaylight.controller.sal.dom.broker.spi
+ </Export-Package>
<Private-Package>
- org.opendaylight.controller.sal.dom.broker.*,
- org.opendaylight.controller.config.yang.md.sal.dom.impl
+ org.opendaylight.controller.sal.dom.broker,
+ org.opendaylight.controller.sal.dom.broker.impl,
+ org.opendaylight.controller.sal.dom.broker.osgi,
+ org.opendaylight.controller.config.yang.md.sal.dom.impl,
+ org.opendaylight.controller.config.yang.md.sal.dom.statistics,
+ org.opendaylight.yangtools.yang.util
</Private-Package>
<Import-Package>
*
public java.lang.AutoCloseable createInstance() {
SchemaServiceImpl newInstance = new SchemaServiceImpl();
newInstance.setContext(getBundleContext());
- newInstance.setParser(new YangParserImpl());
newInstance.start();
return newInstance;
}
+++ /dev/null
-package org.opendaylight.controller.sal.dom.broker;
-
-public class $ModuleInfo {
-
-
-}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.dom.broker
-import org.osgi.framework.ServiceRegistration
-import org.opendaylight.controller.sal.core.api.model.SchemaService
+import java.util.Hashtable
import org.opendaylight.controller.sal.core.api.data.DataBrokerService
import org.opendaylight.controller.sal.core.api.data.DataProviderService
-import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore
+import org.opendaylight.controller.sal.core.api.data.DataStore
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
import org.opendaylight.controller.sal.core.api.mount.MountService
-import org.osgi.framework.BundleContext
-import java.util.Hashtable
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.sal.core.api.data.DataStore
import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter
-import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
-import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.osgi.framework.BundleContext
+import org.osgi.framework.ServiceRegistration
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders
class BrokerConfigActivator implements AutoCloseable {
-
-
+
private static val ROOT = InstanceIdentifier.builder().toInstance();
@Property
private var DataBrokerImpl dataService;
-
+
private var ServiceRegistration<SchemaService> schemaReg;
private var ServiceRegistration<DataBrokerService> dataReg;
private var ServiceRegistration<DataProviderService> dataProviderReg;
private var ServiceRegistration<MountService> mountReg;
private var ServiceRegistration<MountProvisionService> mountProviderReg;
- private var SchemaServiceImpl schemaService;
+ private var SchemaService schemaService;
private var MountPointManagerImpl mountService;
-
+
SchemaAwareDataStoreAdapter wrappedStore
- public def void start(BrokerImpl broker,DataStore store,BundleContext context) {
+ public def void start(BrokerImpl broker, DataStore store, BundleContext context) {
val emptyProperties = new Hashtable<String, String>();
broker.setBundleContext(context);
-
- broker.setRouter(new RpcRouterImpl("Rpc router"))
- schemaService = new SchemaServiceImpl();
- schemaService.setContext(context);
- schemaService.setParser(new YangParserImpl());
- schemaService.start();
+
+ val serviceRef = context.getServiceReference(SchemaService);
+ schemaService = context.getService(serviceRef);
schemaReg = context.registerService(SchemaService, schemaService, emptyProperties);
-
+
+ broker.setRouter(new SchemaAwareRpcBroker("/", SchemaContextProviders.fromSchemaService(schemaService)));
+
dataService = new DataBrokerImpl();
dataService.setExecutor(broker.getExecutor());
-
+
dataReg = context.registerService(DataBrokerService, dataService, emptyProperties);
dataProviderReg = context.registerService(DataProviderService, dataService, emptyProperties);
wrappedStore = new SchemaAwareDataStoreAdapter();
wrappedStore.changeDelegate(store);
wrappedStore.setValidationEnabled(false);
-
- context.registerService(SchemaServiceListener,wrappedStore,emptyProperties)
-
+
+ context.registerService(SchemaServiceListener, wrappedStore, emptyProperties)
+
dataService.registerConfigurationReader(ROOT, wrappedStore);
dataService.registerCommitHandler(ROOT, wrappedStore);
dataService.registerOperationalReader(ROOT, wrappedStore);
-
+
mountService = new MountPointManagerImpl();
mountService.setDataBroker(dataService);
-
+
mountReg = context.registerService(MountService, mountService, emptyProperties);
- mountProviderReg = context.registerService(MountProvisionService, mountService, emptyProperties);
+ mountProviderReg = context.registerService(MountProvisionService, mountService, emptyProperties);
}
override def close() {
mountReg?.unregister();
mountProviderReg?.unregister();
}
-
-}
\ No newline at end of file
+
+}
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry
import org.opendaylight.controller.sal.core.api.RpcImplementation
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
private static val log = LoggerFactory.getLogger(BrokerImpl);
override registerConsumer(Consumer consumer, BundleContext ctx) {
checkPredicates(consumer);
- log.info("Registering consumer " + consumer);
+ log.trace("Registering consumer " + consumer);
val session = newSessionFor(consumer, ctx);
consumer.onSessionInitiated(session);
sessions.add(session);
router.addRoutedRpcImplementation(rpcType,implementation);
}
+ override addRpcRegistrationListener(RpcRegistrationListener listener) {
+ return router.addRpcRegistrationListener(listener);
+ }
+
+ override <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> registerRouteChangeListener(L listener) {
+ return router.registerRouteChangeListener(listener);
+ }
+
}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.dom.broker;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
import org.opendaylight.controller.sal.common.DataStoreIdentifier;
import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
import org.opendaylight.controller.sal.core.api.data.DataValidator;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
-import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
import org.opendaylight.controller.sal.dom.broker.impl.NotificationRouterImpl;
-import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
-import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public class MountPointImpl implements MountProvisionInstance {
+public class MountPointImpl implements MountProvisionInstance, SchemaContextProvider {
- private final RpcRouter rpcs;
+ private final SchemaAwareRpcBroker rpcs;
private final DataBrokerImpl dataReader;
private final NotificationRouter notificationRouter;
private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
public MountPointImpl(InstanceIdentifier path) {
this.mountPath = path;
- rpcs = new RpcRouterImpl("");
+ rpcs = new SchemaAwareRpcBroker(path.toString(),this);
dataReader = new DataBrokerImpl();
notificationRouter = new NotificationRouterImpl();
readWrapper = new ReadWrapper();
@Override
public Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
- // TODO Auto-generated method stub
return null;
}
RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
return dataReader.registerCommitHandlerListener(commitHandlerListener);
}
+
+ @Override
+ public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+ L listener) {
+ return rpcs.registerRouteChangeListener(listener);
+ }
}
}
def registerMountPoint(MountPointImpl impl) {
- dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
- dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
+ //dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
+ //dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
}
private void sendNotification(CompositeNode notification) {
QName type = notification.getNodeType();
Collection<NotificationListener> toNotify = listeners.get(type);
- log.info("Publishing notification " + type);
+ log.trace("Publishing notification " + type);
if (toNotify == null) {
// No listeners were registered - returns.
.create();
private boolean closed = false;
-
+
public Registration<NotificationListener> addNotificationListener(QName notification,
NotificationListener listener) {
checkSessionState();
consumerListeners.put(notification, listener);
listeners.put(notification, listener);
- log.info("Registered listener for notification: " + notification);
+ log.trace("Registered listener for notification: " + notification);
return null; // Return registration Object.
}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.dom.broker;
-import java.io.IOException;
-import java.io.InputStream;
+import static com.google.common.base.Preconditions.checkState;
+
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.Enumeration;
-import java.util.List;
-import java.util.Set;
-import java.util.zip.Checksum;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.osgi.util.tracker.BundleTracker;
-import org.osgi.util.tracker.BundleTrackerCustomizer;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.util.URLSchemaContextResolver;
import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceReference;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Function;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-
-import static com.google.common.base.Preconditions.*;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
public class SchemaServiceImpl implements //
+ SchemaContextProvider, //
SchemaService, //
ServiceTrackerCustomizer<SchemaServiceListener, SchemaServiceListener>, //
AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(SchemaServiceImpl.class);
private ListenerRegistry<SchemaServiceListener> listeners;
- private YangModelParser parser;
-
+
private BundleContext context;
private BundleScanner scanner = new BundleScanner();
- /**
- * Map of currently problematic yang files that should get fixed eventually
- * after all events are received.
- */
- private final Multimap<Bundle, URL> inconsistentBundlesToYangURLs = HashMultimap.create();
- private final Multimap<Bundle, URL> consistentBundlesToYangURLs = HashMultimap.create();
- private BundleTracker<Object> bundleTracker;
- private final YangStoreCache cache = new YangStoreCache();
+ private BundleTracker<ImmutableSet<Registration<URL>>> bundleTracker;
+
+ private final URLSchemaContextResolver contextResolver = new URLSchemaContextResolver();
private ServiceTracker<SchemaServiceListener, SchemaServiceListener> listenerTracker;
+ private boolean starting = true;
+
public ListenerRegistry<SchemaServiceListener> getListeners() {
return listeners;
}
this.listeners = listeners;
}
- public YangModelParser getParser() {
- return parser;
- }
-
- public void setParser(YangModelParser parser) {
- this.parser = parser;
- }
-
public BundleContext getContext() {
return context;
}
}
public void start() {
- checkState(parser != null);
checkState(context != null);
if (listeners == null) {
listeners = new ListenerRegistry<>();
}
- listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, this);
- bundleTracker = new BundleTracker<Object>(context, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, scanner);
+ listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, SchemaServiceImpl.this);
+ bundleTracker = new BundleTracker<ImmutableSet<Registration<URL>>>(context, BundleEvent.RESOLVED
+ | BundleEvent.UNRESOLVED, scanner);
bundleTracker.open();
listenerTracker.open();
+ starting = false;
+ tryToUpdateSchemaContext();
}
- public SchemaContext getGlobalContext() {
- return getSchemaContextSnapshot();
+ @Override
+ public SchemaContext getSchemaContext() {
+ return getGlobalContext();
}
- public synchronized SchemaContext getSchemaContextSnapshot() {
- Optional<SchemaContext> yangStoreOpt = cache.getCachedSchemaContext(consistentBundlesToYangURLs);
- if (yangStoreOpt.isPresent()) {
- return yangStoreOpt.get();
- }
- SchemaContext snapshot = createSnapshot(parser, consistentBundlesToYangURLs);
- updateCache(snapshot);
- return snapshot;
+ public SchemaContext getGlobalContext() {
+ return contextResolver.getSchemaContext().orNull();
}
@Override
public void addModule(Module module) {
- // TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public SchemaContext getSessionContext() {
- // TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public void removeModule(Module module) {
- // TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public void close() throws Exception {
- bundleTracker.close();
- // FIXME: Add listeners.close();
-
- }
-
- private synchronized boolean tryToUpdateState(Collection<URL> changedURLs, Multimap<Bundle, URL> proposedNewState,
- boolean adding) {
- Preconditions.checkArgument(!changedURLs.isEmpty(), "No change can occur when no URLs are changed");
-
- try {
- // consistent state
- // merge into
- SchemaContext snapshot = createSnapshot(parser, proposedNewState);
- consistentBundlesToYangURLs.clear();
- consistentBundlesToYangURLs.putAll(proposedNewState);
- inconsistentBundlesToYangURLs.clear();
- // update cache
- updateCache(snapshot);
- logger.info("SchemaService updated to new consistent state");
- logger.trace("SchemaService updated to new consistent state containing {}", consistentBundlesToYangURLs);
-
- // notifyListeners(changedURLs, adding);
- return true;
- } catch (Exception e) {
- // inconsistent state
- logger.debug(
- "SchemaService is falling back on last consistent state containing {}, inconsistent yang files {}",
- consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, e);
- return false;
+ if (bundleTracker != null) {
+ bundleTracker.close();
}
+ if (listenerTracker != null) {
+ listenerTracker.close();
+ }
+ // FIXME: Add listeners.close();
}
- private static Collection<InputStream> fromUrlsToInputStreams(Multimap<Bundle, URL> multimap) {
- return Collections2.transform(multimap.values(), new Function<URL, InputStream>() {
-
- @Override
- public InputStream apply(URL url) {
- try {
- return url.openStream();
- } catch (IOException e) {
- logger.warn("Unable to open stream from {}", url);
- throw new IllegalStateException("Unable to open stream from " + url, e);
- }
- }
- });
- }
-
- private static SchemaContext createSnapshot(YangModelParser parser, Multimap<Bundle, URL> multimap) {
- List<InputStream> models = new ArrayList<>(fromUrlsToInputStreams(multimap));
- Set<Module> modules = parser.parseYangModelsFromStreams(models);
- SchemaContext yangStoreSnapshot = parser.resolveSchemaContext(modules);
- return yangStoreSnapshot;
- }
-
- private void updateCache(SchemaContext snapshot) {
- cache.cacheYangStore(consistentBundlesToYangURLs, snapshot);
+ private void updateContext(SchemaContext snapshot) {
Object[] services = listenerTracker.getServices();
if (services != null) {
for (Object rawListener : services) {
}
}
- private class BundleScanner implements BundleTrackerCustomizer<Object> {
+ private class BundleScanner implements BundleTrackerCustomizer<ImmutableSet<Registration<URL>>> {
@Override
- public Object addingBundle(Bundle bundle, BundleEvent event) {
+ public ImmutableSet<Registration<URL>> addingBundle(Bundle bundle, BundleEvent event) {
- // Ignore system bundle:
- // system bundle might have config-api on classpath &&
- // config-api contains yang files =>
- // system bundle might contain yang files from that bundle
if (bundle.getBundleId() == 0) {
- return bundle;
+ return ImmutableSet.of();
}
Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
- if (enumeration != null && enumeration.hasMoreElements()) {
- synchronized (this) {
- List<URL> addedURLs = new ArrayList<>();
- while (enumeration.hasMoreElements()) {
- URL url = enumeration.nextElement();
- addedURLs.add(url);
- }
- logger.trace("Bundle {} has event {}, bundle state {}, URLs {}", bundle, event, bundle.getState(),
- addedURLs);
- // test that yang store is consistent
- Multimap<Bundle, URL> proposedNewState = HashMultimap.create(consistentBundlesToYangURLs);
- proposedNewState.putAll(inconsistentBundlesToYangURLs);
- proposedNewState.putAll(bundle, addedURLs);
- boolean adding = true;
-
- if (tryToUpdateState(addedURLs, proposedNewState, adding) == false) {
- inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
- }
- }
+ Builder<Registration<URL>> builder = ImmutableSet.<Registration<URL>> builder();
+ while (enumeration != null && enumeration.hasMoreElements()) {
+ Registration<URL> reg = contextResolver.registerSource(enumeration.nextElement());
+ builder.add(reg);
+ }
+ ImmutableSet<Registration<URL>> urls = builder.build();
+ if(urls.isEmpty()) {
+ return urls;
}
- return bundle;
+ tryToUpdateSchemaContext();
+ return urls;
}
@Override
- public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+ public void modifiedBundle(Bundle bundle, BundleEvent event, ImmutableSet<Registration<URL>> object) {
logger.debug("Modified bundle {} {} {}", bundle, event, object);
}
*/
@Override
- public synchronized void removedBundle(Bundle bundle, BundleEvent event, Object object) {
- inconsistentBundlesToYangURLs.removeAll(bundle);
- Collection<URL> consistentURLsToBeRemoved = consistentBundlesToYangURLs.removeAll(bundle);
-
- if (consistentURLsToBeRemoved.isEmpty()) {
- return; // no change
- }
- boolean adding = false;
- // notifyListeners(consistentURLsToBeRemoved, adding);
- }
- }
-
- private static final class YangStoreCache {
-
- Set<URL> cachedUrls;
- SchemaContext cachedContextSnapshot;
-
- Optional<SchemaContext> getCachedSchemaContext(Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = setFromMultimapValues(bundlesToYangURLs);
- if (cachedUrls != null && cachedUrls.equals(urls)) {
- Preconditions.checkState(cachedContextSnapshot != null);
- return Optional.of(cachedContextSnapshot);
+ public synchronized void removedBundle(Bundle bundle, BundleEvent event, ImmutableSet<Registration<URL>> urls) {
+ for (Registration<URL> url : urls) {
+ try {
+ url.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
- return Optional.absent();
- }
-
- private static Set<URL> setFromMultimapValues(Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = Sets.newHashSet(bundlesToYangURLs.values());
- Preconditions.checkState(bundlesToYangURLs.size() == urls.size());
- return urls;
- }
-
- void cacheYangStore(Multimap<Bundle, URL> urls, SchemaContext ctx) {
- this.cachedUrls = setFromMultimapValues(urls);
- this.cachedContextSnapshot = ctx;
+ tryToUpdateSchemaContext();
}
}
return listener;
}
+ public synchronized void tryToUpdateSchemaContext() {
+ if(starting ) {
+ return;
+ }
+ Optional<SchemaContext> schema = contextResolver.tryToUpdateSchemaContext();
+ if(schema.isPresent()) {
+ updateContext(schema.get());
+ }
+ }
+
@Override
public void modifiedService(ServiceReference<SchemaServiceListener> reference, SchemaServiceListener service) {
// NOOP
private void sendNotification(CompositeNode notification) {
QName type = notification.getNodeType();
Collection<Registration<NotificationListener>> toNotify = listeners.get(type);
- log.info("Publishing notification " + type);
+ log.trace("Publishing notification " + type);
if (toNotify == null) {
// No listeners were registered - returns.
+++ /dev/null
-package org.opendaylight.controller.sal.dom.broker.impl
-
-import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter
-import org.opendaylight.yangtools.concepts.Identifiable
-import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.controller.sal.core.api.RpcImplementation
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import static com.google.common.base.Preconditions.*;
-import java.util.Map
-import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration
-import java.util.concurrent.ConcurrentHashMap
-import java.util.Set
-import java.util.Collections
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
-import org.slf4j.LoggerFactory
-import org.opendaylight.yangtools.concepts.util.ListenerRegistry
-import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-
-class RpcRouterImpl implements RpcRouter, Identifiable<String> {
-
- static val log = LoggerFactory.getLogger(RpcRouterImpl)
-
- Map<QName, RpcRegistration> implementations = new ConcurrentHashMap();
-
- @Property
- val Set<QName> supportedRpcs = Collections.unmodifiableSet(implementations.keySet);
-
- private val rpcRegistrationListeners = new ListenerRegistry<RpcRegistrationListener>();
-
- @Property
- val String identifier;
-
- new(String name) {
- _identifier = name;
- }
-
- override addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
- checkNotNull(rpcType, "Rpc Type should not be null");
- checkNotNull(implementation, "Implementation should not be null.");
- val reg = new RoutedRpcRegistrationImpl(rpcType, implementation, this);
- implementations.put(rpcType, reg)
-
- for (listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationAdded(rpcType);
- } catch (Exception e) {
- log.error("Unhandled exception during invoking listener", e);
- }
- }
-
- return reg;
- }
-
- override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException {
- checkNotNull(rpcType, "Rpc Type should not be null");
- checkNotNull(implementation, "Implementation should not be null.");
- checkState(!implementations.containsKey(rpcType), "Provider for supplied rpc is already registered.");
- val reg = new RpcRegistrationImpl(rpcType, implementation, this);
- implementations.put(rpcType, reg)
-
- for (listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationAdded(rpcType);
- } catch (Exception e) {
- log.error("Unhandled exception during invoking listener", e);
- }
- }
-
- return reg;
-
- }
-
- override invokeRpc(QName rpc, CompositeNode input) {
- checkNotNull(rpc, "Rpc Type should not be null");
-
- val impl = implementations.get(rpc);
- checkState(impl !== null, "Provider for supplied rpc is not registered.");
-
- return impl.instance.invokeRpc(rpc, input);
- }
-
- def remove(RpcRegistrationImpl impl) {
- val existing = implementations.get(impl.type);
- if (existing == impl) {
- implementations.remove(impl.type);
- }
- for (listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationRemoved(impl.type);
- } catch (Exception e) {
- log.error("Unhandled exception during invoking listener", e);
- }
- }
- }
-
- override addRpcRegistrationListener(RpcRegistrationListener listener) {
- rpcRegistrationListeners.register(listener);
- }
-
-}
-
-class RpcRegistrationImpl extends AbstractObjectRegistration<RpcImplementation> implements RpcRegistration {
-
- @Property
- val QName type;
-
- @Property
- var RpcRouterImpl router;
-
- new(QName type, RpcImplementation instance, RpcRouterImpl router) {
- super(instance)
- _type = type
- _router = router
- }
-
- override protected removeRegistration() {
- router.remove(this);
- }
-}
-class RoutedRpcRegistrationImpl extends RpcRegistrationImpl implements RoutedRpcRegistration {
-
-
- new(QName type, RpcImplementation instance, RpcRouterImpl router) {
- super(type,instance,router)
- }
-
- override protected removeRegistration() {
- router.remove(this);
- }
- override registerPath(QName context, InstanceIdentifier path) {
- //
-
- }
-
- override unregisterPath(QName context, InstanceIdentifier path) {
- //
- }
-}
}
if (schema == null) {
- LOG.info("Validation not performed for {}. Reason: YANG Schema not present.", modification.getIdentifier());
+ LOG.warn("Validation not performed for {}. Reason: YANG Schema not present.", modification.getIdentifier());
return;
}
}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.md.sal.common.impl.routing.RoutingUtils;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+
+public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareRpcBroker.class);
+
+ private static final QName CONTEXT_REFERENCE = QName.create("urn:opendaylight:yang:extension:yang-ext",
+ "2013-07-09", "context-reference");
+ private final ListenerRegistry<RpcRegistrationListener> rpcRegistrationListeners = new ListenerRegistry<>();
+ private final ListenerRegistry<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeChangeListeners = new ListenerRegistry<>();
+
+
+ private final String identifier;
+ private final ConcurrentMap<QName, RpcImplementation> implementations = new ConcurrentHashMap<>();
+ private RpcImplementation defaultImplementation;
+ private SchemaContextProvider schemaProvider;
+
+ public SchemaAwareRpcBroker(String identifier, SchemaContextProvider schemaProvider) {
+ super();
+ this.identifier = identifier;
+ this.schemaProvider = schemaProvider;
+ }
+
+ public RpcImplementation getDefaultImplementation() {
+ return defaultImplementation;
+ }
+
+ public void setDefaultImplementation(RpcImplementation defaultImplementation) {
+ this.defaultImplementation = defaultImplementation;
+ }
+
+ public SchemaContextProvider getSchemaProvider() {
+ return schemaProvider;
+ }
+
+ public void setSchemaProvider(SchemaContextProvider schemaProvider) {
+ this.schemaProvider = schemaProvider;
+ }
+
+ @Override
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ checkArgument(rpcType != null, "RPC Type should not be null");
+ checkArgument(implementation != null, "RPC Implementatoin should not be null");
+ return getOrCreateRoutedRpcRouter(rpcType).addRoutedRpcImplementation(rpcType, implementation);
+ }
+
+ private RoutedRpcSelector getOrCreateRoutedRpcRouter(QName rpcType) {
+ RoutedRpcSelector potential = getRoutedRpcRouter(rpcType);
+ if (potential != null) {
+ return potential;
+ }
+ synchronized (implementations) {
+ potential = getRoutedRpcRouter(rpcType);
+ if (potential != null) {
+ return potential;
+ }
+ RpcDefinition definition = findRpcDefinition(rpcType);
+ RoutingStrategy strategy = getRoutingStrategy(definition);
+ checkState(strategy instanceof RoutedRpcStrategy, "Rpc %s is not routed.", rpcType);
+ potential = new RoutedRpcSelector((RoutedRpcStrategy) strategy, this);
+ implementations.put(rpcType, potential);
+ return potential;
+ }
+ }
+
+ private RoutedRpcSelector getRoutedRpcRouter(QName rpcType) {
+ RpcImplementation potential = implementations.get(rpcType);
+ if (potential != null) {
+ checkState(potential instanceof RoutedRpcSelector, "Rpc %s is not routed.", rpcType);
+ return (RoutedRpcSelector) potential;
+ }
+ return null;
+
+ }
+
+ @Override
+ public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException {
+ checkArgument(rpcType != null, "RPC Type should not be null");
+ checkArgument(implementation != null, "RPC Implementatoin should not be null");
+ checkState(!hasRpcImplementation(rpcType), "Implementation already registered");
+ RpcDefinition definition = findRpcDefinition(rpcType);
+ checkArgument(!isRoutedRpc(definition), "RPC Type must not be routed.");
+ GlobalRpcRegistration reg = new GlobalRpcRegistration(rpcType, implementation, this);
+ return reg;
+ }
+
+ private boolean isRoutedRpc(RpcDefinition definition) {
+ return getRoutingStrategy(definition) instanceof RoutedRpcStrategy;
+ }
+
+ @Override
+ public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
+ return rpcRegistrationListeners.register(listener);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return ImmutableSet.copyOf(implementations.keySet());
+ }
+
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ return findRpcImplemention(rpc).invokeRpc(rpc, input);
+ }
+
+ private RpcImplementation findRpcImplemention(QName rpc) {
+ checkArgument(rpc != null, "Rpc name should not be null");
+ RpcImplementation potentialImpl = implementations.get(rpc);
+ if (potentialImpl != null) {
+ return potentialImpl;
+ }
+ potentialImpl = defaultImplementation;
+ checkState(potentialImpl != null, "Implementation is not available.");
+ return potentialImpl;
+ }
+
+ private boolean hasRpcImplementation(QName rpc) {
+ return implementations.containsKey(rpc);
+ }
+
+ private RpcDefinition findRpcDefinition(QName rpcType) {
+ checkArgument(rpcType != null, "Rpc name must be supplied.");
+ checkState(schemaProvider != null, "Schema Provider is not available.");
+ SchemaContext ctx = schemaProvider.getSchemaContext();
+ checkState(ctx != null, "YANG Schema Context is not available.");
+ Module module = ctx.findModuleByNamespaceAndRevision(rpcType.getNamespace(), rpcType.getRevision());
+ checkState(module != null, "YANG Module is not available.");
+ return findRpcDefinition(rpcType, module.getRpcs());
+ }
+
+ static private RpcDefinition findRpcDefinition(QName rpcType, Set<RpcDefinition> rpcs) {
+ checkState(rpcs != null, "Rpc schema is not available.");
+ for (RpcDefinition rpc : rpcs) {
+ if (rpcType.equals(rpc.getQName())) {
+ return rpc;
+ }
+ }
+ throw new IllegalArgumentException("Supplied Rpc Type is not defined.");
+ }
+
+ private RoutingStrategy getRoutingStrategy(RpcDefinition rpc) {
+ ContainerSchemaNode input = rpc.getInput();
+ if (input != null) {
+ for (DataSchemaNode schemaNode : input.getChildNodes()) {
+ Optional<QName> context = getRoutingContext(schemaNode);
+ if (context.isPresent()) {
+ return createRoutedStrategy(rpc, context.get(), schemaNode.getQName());
+ }
+ }
+ }
+ return createGlobalStrategy(rpc);
+ }
+
+ private static RoutingStrategy createRoutedStrategy(RpcDefinition rpc, QName context, QName leafNode) {
+ return new RoutedRpcStrategy(rpc.getQName(), context, leafNode);
+ }
+
+ private Optional<QName> getRoutingContext(DataSchemaNode schemaNode) {
+ for (UnknownSchemaNode extension : schemaNode.getUnknownSchemaNodes()) {
+ if (CONTEXT_REFERENCE.equals(extension.getNodeType())) {
+ return Optional.fromNullable(extension.getQName());
+ }
+ ;
+ }
+ return Optional.absent();
+ }
+
+ private static RoutingStrategy createGlobalStrategy(RpcDefinition rpc) {
+ GlobalRpcStrategy ret = new GlobalRpcStrategy(rpc.getQName());
+ return ret;
+ }
+
+ private static abstract class RoutingStrategy implements Identifiable<QName> {
+
+ private final QName identifier;
+
+ public RoutingStrategy(QName identifier) {
+ super();
+ this.identifier = identifier;
+ }
+
+ @Override
+ public QName getIdentifier() {
+ return identifier;
+ }
+ }
+
+ private static class GlobalRpcStrategy extends RoutingStrategy {
+
+ public GlobalRpcStrategy(QName identifier) {
+ super(identifier);
+ }
+ }
+
+ private static class RoutedRpcStrategy extends RoutingStrategy {
+
+ private final QName context;
+ private final QName leaf;
+
+ public RoutedRpcStrategy(QName identifier, QName ctx, QName leaf) {
+ super(identifier);
+ this.context = ctx;
+ this.leaf = leaf;
+ }
+
+ public QName getContext() {
+ return context;
+ }
+
+ public QName getLeaf() {
+ return leaf;
+ }
+ }
+
+ private static class RoutedRpcSelector implements RpcImplementation, AutoCloseable, Identifiable<QName> {
+
+ private final RoutedRpcStrategy strategy;
+ private final Set<QName> supportedRpcs;
+ private RpcImplementation defaultDelegate;
+ private final ConcurrentMap<InstanceIdentifier, RoutedRpcRegImpl> implementations = new ConcurrentHashMap<>();
+ private SchemaAwareRpcBroker router;
+
+ public RoutedRpcSelector(RoutedRpcStrategy strategy, SchemaAwareRpcBroker router) {
+ super();
+ this.strategy = strategy;
+ supportedRpcs = ImmutableSet.of(strategy.getIdentifier());
+ this.router = router;
+ }
+
+ @Override
+ public QName getIdentifier() {
+ return strategy.getIdentifier();
+ }
+
+ @Override
+ public void close() throws Exception {
+
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return supportedRpcs;
+ }
+
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ return new RoutedRpcRegImpl(rpcType, implementation, this);
+ }
+
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ CompositeNode inputContainer = input.getFirstCompositeByName(QName.create(rpc,"input"));
+ checkArgument(inputContainer != null, "Rpc payload must contain input element");
+ SimpleNode<?> routeContainer = inputContainer.getFirstSimpleByName(strategy.getLeaf());
+ checkArgument(routeContainer != null, "Leaf %s must be set with value", strategy.getLeaf());
+ Object route = routeContainer.getValue();
+ RpcImplementation potential = null;
+ if (route != null) {
+ RoutedRpcRegImpl potentialReg = implementations.get(route);
+ if (potentialReg != null) {
+ potential = potentialReg.getInstance();
+ }
+ }
+ if (potential == null) {
+ potential = defaultDelegate;
+ }
+ checkState(potential != null, "No implementation is available for rpc:%s path:%s", rpc, route);
+ return potential.invokeRpc(rpc, input);
+ }
+
+ public void addPath(QName context, InstanceIdentifier path, RoutedRpcRegImpl routedRpcRegImpl) {
+ //checkArgument(strategy.getContext().equals(context),"Supplied context is not supported.");
+ RoutedRpcRegImpl previous = implementations.put(path, routedRpcRegImpl);
+ if (previous == null) {
+ router.notifyPathAnnouncement(context,strategy.getIdentifier(), path);
+ }
+
+ }
+
+ public void removePath(QName context, InstanceIdentifier path, RoutedRpcRegImpl routedRpcRegImpl) {
+ boolean removed = implementations.remove(path, routedRpcRegImpl);
+ if (removed) {
+ router.notifyPathWithdrawal(context, strategy.getIdentifier(), path);
+ }
+ }
+ }
+
+ private static class GlobalRpcRegistration extends AbstractObjectRegistration<RpcImplementation> implements
+ RpcRegistration {
+ private final QName type;
+ private SchemaAwareRpcBroker router;
+
+ public GlobalRpcRegistration(QName type, RpcImplementation instance, SchemaAwareRpcBroker router) {
+ super(instance);
+ this.type = type;
+ this.router = router;
+ }
+
+ @Override
+ public QName getType() {
+ return type;
+ }
+
+ @Override
+ protected void removeRegistration() {
+ if (router != null) {
+ router.remove(this);
+ router = null;
+ }
+ }
+ }
+
+ private static class RoutedRpcRegImpl extends AbstractObjectRegistration<RpcImplementation> implements
+ RoutedRpcRegistration {
+
+ private final QName type;
+ private RoutedRpcSelector router;
+
+ public RoutedRpcRegImpl(QName rpcType, RpcImplementation implementation, RoutedRpcSelector routedRpcSelector) {
+ super(implementation);
+ this.type = rpcType;
+ router = routedRpcSelector;
+ }
+
+ @Override
+ public void registerPath(QName context, InstanceIdentifier path) {
+ router.addPath(context, path, this);
+ }
+
+ @Override
+ public void unregisterPath(QName context, InstanceIdentifier path) {
+ router.removePath(context, path, this);
+ }
+
+ @Override
+ protected void removeRegistration() {
+
+ }
+
+ @Override
+ public QName getType() {
+ return type;
+ }
+
+ }
+
+ private void remove(GlobalRpcRegistration registration) {
+ implementations.remove(registration.getType(), registration);
+ }
+
+ private void notifyPathAnnouncement(QName context, QName identifier, InstanceIdentifier path) {
+ RpcRoutingContext contextWrapped = RpcRoutingContext.create(context, identifier);
+ RouteChange<RpcRoutingContext, InstanceIdentifier> change = RoutingUtils.announcementChange(contextWrapped , path);
+ for(ListenerRegistration<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeListener : routeChangeListeners) {
+ try {
+ routeListener.getInstance().onRouteChange(change);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking onRouteChange for {}",routeListener.getInstance(),e);
+
+ }
+ }
+
+ }
+
+
+
+ private void notifyPathWithdrawal(QName context,QName identifier, InstanceIdentifier path) {
+ RpcRoutingContext contextWrapped = RpcRoutingContext.create(context, identifier);
+ RouteChange<RpcRoutingContext, InstanceIdentifier> change = RoutingUtils.removalChange(contextWrapped , path);
+ for(ListenerRegistration<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeListener : routeChangeListeners) {
+ try {
+ routeListener.getInstance().onRouteChange(change);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking onRouteChange for {}",routeListener.getInstance(),e);
+ }
+ }
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+ L listener) {
+ return routeChangeListeners.registerWithType(listener);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public interface SchemaContextProvider {
+
+ SchemaContext getSchemaContext();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class SchemaContextProviders {
+
+ public static final SchemaContextProvider fromSchemaService(SchemaService schemaService) {
+ if (schemaService instanceof SchemaContextProvider) {
+ return (SchemaContextProvider) schemaService;
+ }
+ return new SchemaServiceAdapter(schemaService);
+ }
+
+ private final static class SchemaServiceAdapter implements SchemaContextProvider, Delegator<SchemaService> {
+
+ private final SchemaService service;
+
+ public SchemaServiceAdapter(SchemaService service) {
+ super();
+ this.service = service;
+ }
+
+ @Override
+ public SchemaContext getSchemaContext() {
+ return service.getGlobalContext();
+ }
+
+ @Override
+ public SchemaService getDelegate() {
+ return service;
+ }
+
+ @Override
+ public String toString() {
+ return "SchemaServiceAdapter [service=" + service + "]";
+ }
+ }
+}
@Override
public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
-
- ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener);
}
request.addLeaf("version", revision.get());
}
- device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision);
+ device.logger.trace("Loading YANG schema source for {}:{}", moduleName, revision);
RpcResult<CompositeNode> schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance());
if (schemaReply.isSuccessful()) {
String schemaBody = getSchemaFromRpc(schemaReply.getResult());
if (schemaBody != null) {
- device.logger.info("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision);
+ device.logger.trace("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision);
return Optional.of(schemaBody);
}
}
- device.logger.info("YANG shcema was not successfully retrieved.");
+ device.logger.warn("YANG shcema was not successfully retrieved.");
return Optional.absent();
}
}
return null;
}
-
+
public static final boolean isSupportedFor(Set<QName> capabilities) {
return capabilities.contains(IETF_NETCONF_MONITORING);
}
ZMQ.Context context;
ExecutorService serverThread;
- final String SERVER_ADDRESS = "localhost:5554";
+ final String SERVER_ADDRESS = "localhost:5553";
ClientRequestHandler handler;
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>yang-ext</artifactId>
- <version>2013.09.07.1</version>
+ <version>2013.09.07.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
override readConfigurationData(InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Configuration via Restconf: {}", path)
+ LOG.trace("Read Configuration via Restconf: {}", path)
return dataService.readConfigurationData(path);
}
def readConfigurationDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Configuration via Restconf: {}", path)
+ LOG.trace("Read Configuration via Restconf: {}", path)
return mountPoint.readConfigurationData(path);
}
override readOperationalData(InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Operational via Restconf: {}", path)
+ LOG.trace("Read Operational via Restconf: {}", path)
return dataService.readOperationalData(path);
}
def readOperationalDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Operational via Restconf: {}", path)
+ LOG.trace("Read Operational via Restconf: {}", path)
return mountPoint.readOperationalData(path);
}
def commitConfigurationDataPut(InstanceIdentifier path, CompositeNode payload) {
checkPreconditions
val transaction = dataService.beginTransaction;
- LOG.info("Put Configuration via Restconf: {}", path)
+ LOG.trace("Put Configuration via Restconf: {}", path)
transaction.putConfigurationData(path, payload);
return transaction.commit
}
def commitConfigurationDataPutBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
checkPreconditions
val transaction = mountPoint.beginTransaction;
- LOG.info("Put Configuration via Restconf: {}", path)
+ LOG.trace("Put Configuration via Restconf: {}", path)
transaction.putConfigurationData(path, payload);
return transaction.commit
}
val transaction = dataService.beginTransaction;
transaction.putConfigurationData(path, payload);
if (payload == transaction.createdConfigurationData.get(path)) {
- LOG.info("Post Configuration via Restconf: {}", path)
+ LOG.trace("Post Configuration via Restconf: {}", path)
return transaction.commit
}
- LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+ LOG.trace("Post Configuration via Restconf was not executed because data already exists: {}", path)
return null;
}
val transaction = mountPoint.beginTransaction;
transaction.putConfigurationData(path, payload);
if (payload == transaction.createdConfigurationData.get(path)) {
- LOG.info("Post Configuration via Restconf: {}", path)
+ LOG.trace("Post Configuration via Restconf: {}", path)
return transaction.commit
}
- LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+ LOG.trace("Post Configuration via Restconf was not executed because data already exists: {}", path)
return null;
}
RpcResult<Void> result = getToastService().makeToast(toastInput.build()).get();
if (result.isSuccessful()) {
- log.info("Toast was successfuly finished");
+ log.trace("Toast was successfuly finished");
} else {
- log.info("Toast was not successfuly finished");
+ log.warn("Toast was not successfuly finished");
}
return result.isSuccessful();
} catch (InterruptedException | ExecutionException e) {
- log.info("Error occured during toast creation");
+ log.warn("Error occured during toast creation");
}
return false;
}
-
+
@Override
@Deprecated
protected void startImpl(BundleContext context) {
@Override
public void onNotification(ToastDone notification) {
- log.info("ToastDone Notification Received: {} ",notification.getToastStatus());
+ log.trace("ToastDone Notification Received: {} ",notification.getToastStatus());
}
@Override
public Future<RpcResult<Void>> makeToast(MakeToastInput input) {
// TODO Auto-generated method stub
- log.info("makeToast - Received input for toast");
+ log.trace("makeToast - Received input for toast");
logToastInput(input);
if (currentTask != null) {
return inProgressError();
private void logToastInput(MakeToastInput input) {
String toastType = input.getToasterToastType().getName();
String toastDoneness = input.getToasterDoneness().toString();
- log.info("Toast: {} doneness: {}", toastType, toastDoneness);
+ log.trace("Toast: {} doneness: {}", toastType, toastDoneness);
}
private class MakeToastTask implements Callable<RpcResult<Void>> {
ToastDoneBuilder notifyBuilder = new ToastDoneBuilder();
notifyBuilder.setToastStatus(ToastStatus.Done);
notificationProvider.notify(notifyBuilder.build());
- log.info("Toast Done");
+ log.trace("Toast Done");
logToastInput(toastRequest);
currentTask = null;
return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
public class StatisticsProvider implements AutoCloseable {
public final static Logger spLogger = LoggerFactory.getLogger(StatisticsProvider.class);
-
+
private DataProviderService dps;
private NotificationProviderService nps;
-
+
private OpendaylightGroupStatisticsService groupStatsService;
-
+
private OpendaylightMeterStatisticsService meterStatsService;
-
+
private OpendaylightFlowStatisticsService flowStatsService;
-
+
private OpendaylightPortStatisticsService portStatsService;
private OpendaylightFlowTableStatisticsService flowTableStatsService;
private OpendaylightQueueStatisticsService queueStatsService;
private final MultipartMessageManager multipartMessageManager = new MultipartMessageManager();
-
+
private Thread statisticsRequesterThread;
-
+
private final InstanceIdentifier<Nodes> nodesIdentifier = InstanceIdentifier.builder(Nodes.class).toInstance();
-
+
private final int STATS_THREAD_EXECUTION_TIME= 50000;
//Local caching of stats
-
- private final ConcurrentMap<NodeId,NodeStatistics> statisticsCache =
+
+ private final ConcurrentMap<NodeId,NodeStatistics> statisticsCache =
new ConcurrentHashMap<NodeId,NodeStatistics>();
-
+
public DataProviderService getDataService() {
return this.dps;
}
-
+
public void setDataService(final DataProviderService dataService) {
this.dps = dataService;
}
-
+
public NotificationProviderService getNotificationService() {
return this.nps;
}
-
+
public void setNotificationService(final NotificationProviderService notificationService) {
this.nps = notificationService;
}
}
private final StatisticsUpdateCommiter updateCommiter = new StatisticsUpdateCommiter(StatisticsProvider.this);
-
+
private Registration<NotificationListener> listenerRegistration;
-
+
public void start() {
-
+
NotificationProviderService nps = this.getNotificationService();
Registration<NotificationListener> registerNotificationListener = nps.registerNotificationListener(this.updateCommiter);
this.listenerRegistration = registerNotificationListener;
-
+
// Get Group/Meter statistics service instance
groupStatsService = StatisticsManagerActivator.getProviderContext().
getRpcService(OpendaylightGroupStatisticsService.class);
-
+
meterStatsService = StatisticsManagerActivator.getProviderContext().
getRpcService(OpendaylightMeterStatisticsService.class);
-
+
flowStatsService = StatisticsManagerActivator.getProviderContext().
getRpcService(OpendaylightFlowStatisticsService.class);
flowTableStatsService = StatisticsManagerActivator.getProviderContext().
getRpcService(OpendaylightFlowTableStatisticsService.class);
-
+
queueStatsService = StatisticsManagerActivator.getProviderContext().
getRpcService(OpendaylightQueueStatisticsService.class);
-
+
statisticsRequesterThread = new Thread( new Runnable(){
@Override
while(true){
try {
statsRequestSender();
-
+
Thread.sleep(STATS_THREAD_EXECUTION_TIME);
}catch (Exception e){
spLogger.error("Exception occurred while sending stats request : {}",e);
}
}
});
-
+
spLogger.debug("Statistics requester thread started with timer interval : {}",STATS_THREAD_EXECUTION_TIME);
-
+
statisticsRequesterThread.start();
-
+
spLogger.info("Statistics Provider started.");
}
-
+
protected DataModificationTransaction startChange() {
-
+
DataProviderService dps = this.getDataService();
return dps.beginTransaction();
}
-
+
private void statsRequestSender(){
-
+
List<Node> targetNodes = getAllConnectedNodes();
-
+
if(targetNodes == null)
return;
-
+
for (Node targetNode : targetNodes){
-
+
if(targetNode.getAugmentation(FlowCapableNode.class) != null){
- spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
-
+ spLogger.trace("Send request for stats collection to node : {})",targetNode.getId());
+
InstanceIdentifier<Node> targetInstanceId = InstanceIdentifier.builder(Nodes.class).child(Node.class,targetNode.getKey()).toInstance();
-
+
NodeRef targetNodeRef = new NodeRef(targetInstanceId);
-
+
try{
sendAggregateFlowsStatsFromAllTablesRequest(targetNode.getKey());
-
+
sendAllFlowsStatsFromAllTablesRequest(targetNodeRef);
sendAllNodeConnectorsStatisticsRequest(targetNodeRef);
-
+
sendAllFlowTablesStatisticsRequest(targetNodeRef);
-
+
sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
sendAllGroupStatisticsRequest(targetNodeRef);
-
+
sendAllMeterStatisticsRequest(targetNodeRef);
-
+
sendGroupDescriptionRequest(targetNodeRef);
-
+
sendMeterConfigStatisticsRequest(targetNodeRef);
}catch(Exception e){
spLogger.error("Exception occured while sending statistics requests : {}", e);
}
private void sendAllFlowTablesStatisticsRequest(NodeRef targetNodeRef) throws InterruptedException, ExecutionException {
- final GetFlowTablesStatisticsInputBuilder input =
+ final GetFlowTablesStatisticsInputBuilder input =
new GetFlowTablesStatisticsInputBuilder();
-
+
input.setNode(targetNodeRef);
- Future<RpcResult<GetFlowTablesStatisticsOutput>> response =
+ Future<RpcResult<GetFlowTablesStatisticsOutput>> response =
flowTableStatsService.getFlowTablesStatistics(input.build());
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
private void sendAllFlowsStatsFromAllTablesRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input =
new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
-
+
input.setNode(targetNode);
-
- Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> response =
+
+ Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> response =
flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build());
-
+
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.ALL_FLOW);
-
+
}
-
+
private void sendAggregateFlowsStatsFromAllTablesRequest(NodeKey targetNodeKey) throws InterruptedException, ExecutionException{
-
+
List<Short> tablesId = getTablesFromNode(targetNodeKey);
-
+
if(tablesId.size() != 0){
for(Short id : tablesId){
-
- spLogger.info("Send aggregate stats request for flow table {} to node {}",id,targetNodeKey);
- GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
+
+ spLogger.trace("Send aggregate stats request for flow table {} to node {}",id,targetNodeKey);
+ GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
-
+
input.setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).toInstance()));
input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(id));
- Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> response =
+ Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> response =
flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build());
-
+
multipartMessageManager.setTxIdAndTableIdMapEntry(response.get().getResult().getTransactionId(), id);
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.AGGR_FLOW);
}
private void sendAllNodeConnectorsStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
-
+
final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
-
+
input.setNode(targetNode);
- Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> response =
+ Future<RpcResult<GetAllNodeConnectorsStatisticsOutput>> response =
portStatsService.getAllNodeConnectorsStatistics(input.build());
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.ALL_PORT);
}
private void sendAllGroupStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
-
+
final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
-
+
input.setNode(targetNode);
- Future<RpcResult<GetAllGroupStatisticsOutput>> response =
+ Future<RpcResult<GetAllGroupStatisticsOutput>> response =
groupStatsService.getAllGroupStatistics(input.build());
-
+
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.ALL_GROUP);
}
-
+
private void sendGroupDescriptionRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
-
+
input.setNode(targetNode);
- Future<RpcResult<GetGroupDescriptionOutput>> response =
+ Future<RpcResult<GetGroupDescriptionOutput>> response =
groupStatsService.getGroupDescription(input.build());
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.GROUP_DESC);
}
-
+
private void sendAllMeterStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
-
+
GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
-
+
input.setNode(targetNode);
- Future<RpcResult<GetAllMeterStatisticsOutput>> response =
+ Future<RpcResult<GetAllMeterStatisticsOutput>> response =
meterStatsService.getAllMeterStatistics(input.build());
-
+
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.ALL_METER);;
}
-
+
private void sendMeterConfigStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
-
+
GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
-
+
input.setNode(targetNode);
- Future<RpcResult<GetAllMeterConfigStatisticsOutput>> response =
+ Future<RpcResult<GetAllMeterConfigStatisticsOutput>> response =
meterStatsService.getAllMeterConfigStatistics(input.build());
-
+
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.METER_CONFIG);;
}
-
+
private void sendAllQueueStatsFromAllNodeConnector(NodeRef targetNode) throws InterruptedException, ExecutionException {
GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
-
+
input.setNode(targetNode);
-
- Future<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> response =
+
+ Future<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> response =
queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build());
-
+
this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
, StatsRequestType.ALL_QUEUE_STATS);;
public ConcurrentMap<NodeId, NodeStatistics> getStatisticsCache() {
return statisticsCache;
}
-
+
private List<Node> getAllConnectedNodes(){
-
+
Nodes nodes = (Nodes) dps.readOperationalData(nodesIdentifier);
if(nodes == null)
return null;
-
- spLogger.info("Number of connected nodes : {}",nodes.getNode().size());
+
+ spLogger.trace("Number of connected nodes : {}",nodes.getNode().size());
return nodes.getNode();
}
-
+
private List<Short> getTablesFromNode(NodeKey nodeKey){
InstanceIdentifier<FlowCapableNode> nodesIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class,nodeKey).augmentation(FlowCapableNode.class).toInstance();
-
+
FlowCapableNode node = (FlowCapableNode)dps.readOperationalData(nodesIdentifier);
List<Short> tablesId = new ArrayList<Short>();
if(node != null && node.getTable()!=null){
- spLogger.info("Number of tables {} supported by node {}",node.getTable().size(),nodeKey);
+ spLogger.trace("Number of tables {} supported by node {}",node.getTable().size(),nodeKey);
for(Table table: node.getTable()){
tablesId.add(table.getId());
}
@SuppressWarnings("deprecation")
@Override
public void close(){
-
+
try {
- spLogger.info("Statistics Provider stopped.");
+ spLogger.trace("Statistics Provider stopped.");
if (this.listenerRegistration != null) {
-
+
this.listenerRegistration.close();
-
+
this.statisticsRequesterThread.destroy();
-
+
}
} catch (Throwable e) {
throw Exceptions.sneakyThrow(e);
import org.slf4j.LoggerFactory;
/**
- * Class implement statistics manager related listener interface and augment all the
+ * Class implement statistics manager related listener interface and augment all the
* received statistics data to data stores.
- * TODO: Need to add error message listener and clean-up the associated tx id
+ * TODO: Need to add error message listener and clean-up the associated tx id
* if it exists in the tx-id cache.
* @author vishnoianil
*
*/
public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsListener,
- OpendaylightMeterStatisticsListener,
+ OpendaylightMeterStatisticsListener,
OpendaylightFlowStatisticsListener,
OpendaylightPortStatisticsListener,
OpendaylightFlowTableStatisticsListener,
OpendaylightQueueStatisticsListener{
-
+
public final static Logger sucLogger = LoggerFactory.getLogger(StatisticsUpdateCommiter.class);
private final StatisticsProvider statisticsManager;
-
+
private final int unaccountedFlowsCounter = 1;
public StatisticsUpdateCommiter(final StatisticsProvider manager){
this.statisticsManager = manager;
}
-
+
public StatisticsProvider getStatisticsManager(){
return statisticsManager;
}
-
+
@Override
public void onMeterConfigStatsUpdated(MeterConfigStatsUpdated notification) {
//Check if response is for the request statistics-manager sent.
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
-
+
//Add statistics to local cache
ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
cache.put(notification.getId(), new NodeStatistics());
}
cache.get(notification.getId()).setMeterConfigStats(notification.getMeterConfigStats());
-
+
//Publish data to configuration data store
NodeKey key = new NodeKey(notification.getId());
-
+
List<MeterConfigStats> eterConfigStatsList = notification.getMeterConfigStats();
-
+
for(MeterConfigStats meterConfigStats : eterConfigStatsList){
DataModificationTransaction it = this.statisticsManager.startChange();
MeterBuilder meterBuilder = new MeterBuilder();
MeterKey meterKey = new MeterKey(meterConfigStats.getMeterId());
meterBuilder.setKey(meterKey);
-
+
InstanceIdentifier<Meter> meterRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
.augmentation(FlowCapableNode.class)
.child(Meter.class,meterKey).toInstance();
-
+
NodeMeterConfigStatsBuilder meterConfig= new NodeMeterConfigStatsBuilder();
MeterConfigStatsBuilder stats = new MeterConfigStatsBuilder();
stats.fieldsFrom(meterConfigStats);
meterConfig.setMeterConfigStats(stats.build());
-
+
//Update augmented data
meterBuilder.addAugmentation(NodeMeterConfigStats.class, meterConfig.build());
it.putOperationalData(meterRef, meterBuilder.build());
@Override
public void onMeterStatisticsUpdated(MeterStatisticsUpdated notification) {
-
+
//Check if response is for the request statistics-manager sent.
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
cache.put(notification.getId(), new NodeStatistics());
}
cache.get(notification.getId()).setMeterStatistics(notification.getMeterStats());
-
+
NodeKey key = new NodeKey(notification.getId());
-
+
List<MeterStats> meterStatsList = notification.getMeterStats();
-
+
for(MeterStats meterStats : meterStatsList){
//Publish data to configuration data store
MeterBuilder meterBuilder = new MeterBuilder();
MeterKey meterKey = new MeterKey(meterStats.getMeterId());
meterBuilder.setKey(meterKey);
-
+
InstanceIdentifier<Meter> meterRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
.augmentation(FlowCapableNode.class)
.child(Meter.class,meterKey).toInstance();
-
+
NodeMeterStatisticsBuilder meterStatsBuilder= new NodeMeterStatisticsBuilder();
MeterStatisticsBuilder stats = new MeterStatisticsBuilder();
stats.fieldsFrom(meterStats);
@Override
public void onGroupDescStatsUpdated(GroupDescStatsUpdated notification) {
-
+
//Check if response is for the request statistics-manager sent.
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
cache.put(notification.getId(), new NodeStatistics());
}
cache.get(notification.getId()).setGroupDescStats(notification.getGroupDescStats());
-
+
//Publish data to configuration data store
NodeKey key = new NodeKey(notification.getId());
List<GroupDescStats> groupDescStatsList = notification.getGroupDescStats();
for(GroupDescStats groupDescStats : groupDescStatsList){
DataModificationTransaction it = this.statisticsManager.startChange();
-
+
GroupBuilder groupBuilder = new GroupBuilder();
GroupKey groupKey = new GroupKey(groupDescStats.getGroupId());
groupBuilder.setKey(groupKey);
-
+
InstanceIdentifier<Group> groupRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
.augmentation(FlowCapableNode.class)
.child(Group.class,groupKey).toInstance();
GroupDescBuilder stats = new GroupDescBuilder();
stats.fieldsFrom(groupDescStats);
groupDesc.setGroupDesc(stats.build());
-
+
//Update augmented data
groupBuilder.addAugmentation(NodeGroupDescStats.class, groupDesc.build());
@Override
public void onGroupStatisticsUpdated(GroupStatisticsUpdated notification) {
-
+
//Check if response is for the request statistics-manager sent.
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
cache.put(notification.getId(), new NodeStatistics());
}
cache.get(notification.getId()).setGroupStatistics(notification.getGroupStats());
-
+
//Publish data to configuration data store
NodeKey key = new NodeKey(notification.getId());
List<GroupStats> groupStatsList = notification.getGroupStats();
for(GroupStats groupStats : groupStatsList){
DataModificationTransaction it = this.statisticsManager.startChange();
-
+
GroupBuilder groupBuilder = new GroupBuilder();
GroupKey groupKey = new GroupKey(groupStats.getGroupId());
groupBuilder.setKey(groupKey);
-
+
InstanceIdentifier<Group> groupRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
.augmentation(FlowCapableNode.class)
.child(Group.class,groupKey).toInstance();
GroupStatisticsBuilder stats = new GroupStatisticsBuilder();
stats.fieldsFrom(groupStats);
groupStatisticsBuilder.setGroupStatistics(stats.build());
-
+
//Update augmented data
groupBuilder.addAugmentation(NodeGroupStatistics.class, groupStatisticsBuilder.build());
it.putOperationalData(groupRef, groupBuilder.build());
it.commit();
}
}
-
+
@Override
public void onMeterFeaturesUpdated(MeterFeaturesUpdated notification) {
meterFeature.setMaxBands(notification.getMaxBands());
meterFeature.setMaxColor(notification.getMaxColor());
meterFeature.setMaxMeter(notification.getMaxMeter());
-
+
cache.get(notification.getId()).setMeterFeatures(meterFeature.build());
-
+
//Publish data to configuration data store
DataModificationTransaction it = this.statisticsManager.startChange();
NodeKey key = new NodeKey(notification.getId());
NodeRef ref = getNodeRef(key);
-
- final NodeBuilder nodeData = new NodeBuilder();
+
+ final NodeBuilder nodeData = new NodeBuilder();
nodeData.setKey(key);
-
+
NodeMeterFeaturesBuilder nodeMeterFeatures= new NodeMeterFeaturesBuilder();
nodeMeterFeatures.setMeterFeatures(meterFeature.build());
-
+
//Update augmented data
nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
-
+
InstanceIdentifier<? extends Object> refValue = ref.getValue();
it.putOperationalData(refValue, nodeData.build());
it.commit();
}
-
+
@Override
public void onGroupFeaturesUpdated(GroupFeaturesUpdated notification) {
if(!cache.containsKey(notification.getId())){
cache.put(notification.getId(), new NodeStatistics());
}
-
+
GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder();
groupFeatures.setActions(notification.getActions());
groupFeatures.setGroupCapabilitiesSupported(notification.getGroupCapabilitiesSupported());
groupFeatures.setGroupTypesSupported(notification.getGroupTypesSupported());
groupFeatures.setMaxGroups(notification.getMaxGroups());
cache.get(notification.getId()).setGroupFeatures(groupFeatures.build());
-
+
//Publish data to configuration data store
DataModificationTransaction it = this.statisticsManager.startChange();
NodeKey key = new NodeKey(notification.getId());
NodeRef ref = getNodeRef(key);
-
- final NodeBuilder nodeData = new NodeBuilder();
+
+ final NodeBuilder nodeData = new NodeBuilder();
nodeData.setKey(key);
-
+
NodeGroupFeaturesBuilder nodeGroupFeatures= new NodeGroupFeaturesBuilder();
nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
-
+
//Update augmented data
nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
-
+
InstanceIdentifier<? extends Object> refValue = ref.getValue();
it.putOperationalData(refValue, nodeData.build());
it.commit();
@Override
public void onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
-
+
//Check if response is for the request statistics-manager sent.
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
NodeKey key = new NodeKey(notification.getId());
sucLogger.debug("Received flow stats update : {}",notification.toString());
-
+
for(FlowAndStatisticsMapList map: notification.getFlowAndStatisticsMapList()){
short tableId = map.getTableId();
-
+
DataModificationTransaction it = this.statisticsManager.startChange();
boolean foundOriginalFlow = false;
flow.setPriority(map.getPriority());
flow.setStrict(map.isStrict());
flow.setTableId(tableId);
-
+
Flow flowRule = flow.build();
-
+
FlowAndStatisticsMapListBuilder stats = new FlowAndStatisticsMapListBuilder();
stats.setByteCount(map.getByteCount());
stats.setPacketCount(map.getPacketCount());
stats.setDuration(map.getDuration());
-
+
GenericStatistics flowStats = stats.build();
-
+
//Add statistics to local cache
ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
cache.get(notification.getId()).getFlowAndStatsMap().put(tableId, new HashMap<Flow,GenericStatistics>());
}
cache.get(notification.getId()).getFlowAndStatsMap().get(tableId).put(flowRule,flowStats);
-
+
//Augment the data to the flow node
FlowStatisticsBuilder flowStatistics = new FlowStatisticsBuilder();
flowStatistics.setTableId(tableId);
flowStatisticsData.setFlowStatistics(flowStatistics.build());
-
+
sucLogger.debug("Flow : {}",flowRule.toString());
sucLogger.debug("Statistics to augment : {}",flowStatistics.build().toString());
InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
.augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
-
+
Table table= (Table)it.readConfigurationData(tableRef);
//TODO: Not a good way to do it, need to figure out better way.
- //TODO: major issue in any alternate approach is that flow key is incrementally assigned
+ //TODO: major issue in any alternate approach is that flow key is incrementally assigned
//to the flows stored in data store.
if(table != null){
.child(Flow.class,existingFlow.getKey()).toInstance();
flowBuilder.setKey(existingFlow.getKey());
flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
- sucLogger.info("Found matching flow in the datastore, augmenting statistics");
+ sucLogger.trace("Found matching flow in the datastore, augmenting statistics");
foundOriginalFlow = true;
it.putOperationalData(flowRef, flowBuilder.build());
it.commit();
}
}
}
-
+
if(!foundOriginalFlow){
sucLogger.debug("Associated original flow is not found in data store. Augmenting flow in operational data store");
//TODO: Temporary fix: format [ 1+tableid+1+unaccounted flow counter]
.child(Flow.class,newFlowKey).toInstance();
flowBuilder.setKey(newFlowKey);
flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
- sucLogger.info("Flow was no present in data store, augmenting statistics as an unaccounted flow");
+ sucLogger.trace("Flow was no present in data store, augmenting statistics as an unaccounted flow");
it.putOperationalData(flowRef, flowBuilder.build());
it.commit();
}
NodeKey key = new NodeKey(notification.getId());
sucLogger.debug("Received aggregate flow statistics update : {}",notification.toString());
-
+
Short tableId = this.statisticsManager.getMultipartMessageManager().getTableIdForTxId(notification.getTransactionId());
if(tableId != null){
-
+
DataModificationTransaction it = this.statisticsManager.startChange();
InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
aggregateFlowStatisticsBuilder.setFlowCount(notification.getFlowCount());
aggregateFlowStatisticsBuilder.setPacketCount(notification.getPacketCount());
aggregateFlowStatisticsDataBuilder.setAggregateFlowStatistics(aggregateFlowStatisticsBuilder.build());
-
+
ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
cache.put(notification.getId(), new NodeStatistics());
}
cache.get(notification.getId()).getTableAndAggregateFlowStatsMap().put(tableId,aggregateFlowStatisticsBuilder.build());
-
+
sucLogger.debug("Augment aggregate statistics: {} for table {} on Node {}",aggregateFlowStatisticsBuilder.build().toString(),tableId,key);
TableBuilder tableBuilder = new TableBuilder();
NodeKey key = new NodeKey(notification.getId());
sucLogger.debug("Received port stats update : {}",notification.toString());
-
+
//Add statistics to local cache
ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
List<NodeConnectorStatisticsAndPortNumberMap> portsStats = notification.getNodeConnectorStatisticsAndPortNumberMap();
for(NodeConnectorStatisticsAndPortNumberMap portStats : portsStats){
-
+
DataModificationTransaction it = this.statisticsManager.startChange();
- FlowCapableNodeConnectorStatisticsBuilder statisticsBuilder
+ FlowCapableNodeConnectorStatisticsBuilder statisticsBuilder
= new FlowCapableNodeConnectorStatisticsBuilder();
statisticsBuilder.setBytes(portStats.getBytes());
statisticsBuilder.setCollisionCount(portStats.getCollisionCount());
statisticsBuilder.setReceiveOverRunError(portStats.getReceiveOverRunError());
statisticsBuilder.setTransmitDrops(portStats.getTransmitDrops());
statisticsBuilder.setTransmitErrors(portStats.getTransmitErrors());
-
+
//Update data in the cache
cache.get(notification.getId()).getNodeConnectorStats().put(portStats.getNodeConnectorId(), statisticsBuilder.build());
-
+
//Augment data to the node-connector
- FlowCapableNodeConnectorStatisticsDataBuilder statisticsDataBuilder =
+ FlowCapableNodeConnectorStatisticsDataBuilder statisticsDataBuilder =
new FlowCapableNodeConnectorStatisticsDataBuilder();
-
+
statisticsDataBuilder.setFlowCapableNodeConnectorStatistics(statisticsBuilder.build());
-
+
InstanceIdentifier<NodeConnector> nodeConnectorRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key).child(NodeConnector.class, new NodeConnectorKey(portStats.getNodeConnectorId())).toInstance();
-
+
NodeConnector nodeConnector = (NodeConnector)it.readOperationalData(nodeConnectorRef);
-
+
if(nodeConnector != null){
sucLogger.debug("Augmenting port statistics {} to port {}",statisticsDataBuilder.build().toString(),nodeConnectorRef.toString());
NodeConnectorBuilder nodeConnectorBuilder = new NodeConnectorBuilder();
NodeKey key = new NodeKey(notification.getId());
sucLogger.debug("Received flow table statistics update : {}",notification.toString());
-
+
List<FlowTableAndStatisticsMap> flowTablesStatsList = notification.getFlowTableAndStatisticsMap();
for (FlowTableAndStatisticsMap ftStats : flowTablesStatsList){
-
+
DataModificationTransaction it = this.statisticsManager.startChange();
InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
.augmentation(FlowCapableNode.class).child(Table.class, new TableKey(ftStats.getTableId().getValue())).toInstance();
-
+
FlowTableStatisticsDataBuilder statisticsDataBuilder = new FlowTableStatisticsDataBuilder();
-
+
FlowTableStatisticsBuilder statisticsBuilder = new FlowTableStatisticsBuilder();
statisticsBuilder.setActiveFlows(ftStats.getActiveFlows());
statisticsBuilder.setPacketsLookedUp(ftStats.getPacketsLookedUp());
statisticsBuilder.setPacketsMatched(ftStats.getPacketsMatched());
-
+
statisticsDataBuilder.setFlowTableStatistics(statisticsBuilder.build());
-
+
ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
cache.put(notification.getId(), new NodeStatistics());
}
cache.get(notification.getId()).getFlowTableAndStatisticsMap().put(ftStats.getTableId().getValue(),statisticsBuilder.build());
-
+
sucLogger.debug("Augment flow table statistics: {} for table {} on Node {}",statisticsBuilder.build().toString(),ftStats.getTableId(),key);
-
+
TableBuilder tableBuilder = new TableBuilder();
tableBuilder.setKey(new TableKey(ftStats.getTableId().getValue()));
tableBuilder.addAugmentation(FlowTableStatisticsData.class, statisticsDataBuilder.build());
@Override
public void onQueueStatisticsUpdate(QueueStatisticsUpdate notification) {
-
+
//Check if response is for the request statistics-manager sent.
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
NodeKey key = new NodeKey(notification.getId());
sucLogger.debug("Received queue stats update : {}",notification.toString());
-
+
//Add statistics to local cache
ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
cache.put(notification.getId(), new NodeStatistics());
}
-
+
List<QueueIdAndStatisticsMap> queuesStats = notification.getQueueIdAndStatisticsMap();
for(QueueIdAndStatisticsMap swQueueStats : queuesStats){
-
+
if(!cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap().containsKey(swQueueStats.getNodeConnectorId())){
cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap().put(swQueueStats.getNodeConnectorId(), new HashMap<QueueId,GenericQueueStatistics>());
}
-
+
FlowCapableNodeConnectorQueueStatisticsDataBuilder queueStatisticsDataBuilder = new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
-
+
FlowCapableNodeConnectorQueueStatisticsBuilder queueStatisticsBuilder = new FlowCapableNodeConnectorQueueStatisticsBuilder();
-
+
queueStatisticsBuilder.fieldsFrom(swQueueStats);
-
+
queueStatisticsDataBuilder.setFlowCapableNodeConnectorQueueStatistics(queueStatisticsBuilder.build());
-
+
cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap()
.get(swQueueStats.getNodeConnectorId())
.put(swQueueStats.getQueueId(), queueStatisticsBuilder.build());
-
-
+
+
DataModificationTransaction it = this.statisticsManager.startChange();
- InstanceIdentifier<Queue> queueRef
+ InstanceIdentifier<Queue> queueRef
= InstanceIdentifier.builder(Nodes.class)
.child(Node.class, key)
.child(NodeConnector.class, new NodeConnectorKey(swQueueStats.getNodeConnectorId()))
.augmentation(FlowCapableNodeConnector.class)
.child(Queue.class, new QueueKey(swQueueStats.getQueueId())).toInstance();
-
+
QueueBuilder queueBuilder = new QueueBuilder();
queueBuilder.addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, queueStatisticsDataBuilder.build());
queueBuilder.setKey(new QueueKey(swQueueStats.getQueueId()));
- sucLogger.info("Augmenting queue statistics {} of queue {} to port {}"
+ sucLogger.trace("Augmenting queue statistics {} of queue {} to port {}"
,queueStatisticsDataBuilder.build().toString(),
swQueueStats.getQueueId(),
swQueueStats.getNodeConnectorId());
-
+
it.putOperationalData(queueRef, queueBuilder.build());
it.commit();
-
+
}
-
+
}
private NodeRef getNodeRef(NodeKey nodeKey){
InstanceIdentifierBuilder<?> builder = InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeKey);
return new NodeRef(builder.toInstance());
}
-
+
public boolean flowEquals(Flow statsFlow, Flow storedFlow) {
if (statsFlow.getClass() != storedFlow.getClass()) {
return false;
}
return true;
}
-
+
/**
* Explicit equals method to compare the 'match' for flows stored in the data-stores and flow fetched from the switch.
- * Usecase: e.g If user don't set any ethernet source and destination address for match,data store will store null for
+ * Usecase: e.g If user don't set any ethernet source and destination address for match,data store will store null for
* these address.
* e.g [_ethernetMatch=EthernetMatch [_ethernetDestination=null, _ethernetSource=null, _ethernetType=
* EthernetType [_type=EtherType [_value=2048], _mask=null, augmentation=[]]
- *
- * But when you fetch the flows from switch, openflow driver library converts all zero bytes of mac address in the
- * message stream to 00:00:00:00:00:00. Following string shows how library interpret the zero mac address bytes and
- * eventually when translator convert it to MD-SAL match, this is how it looks
- * [_ethernetDestination=EthernetDestination [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]],
- * _ethernetSource=EthernetSource [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]],
+ *
+ * But when you fetch the flows from switch, openflow driver library converts all zero bytes of mac address in the
+ * message stream to 00:00:00:00:00:00. Following string shows how library interpret the zero mac address bytes and
+ * eventually when translator convert it to MD-SAL match, this is how it looks
+ * [_ethernetDestination=EthernetDestination [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]],
+ * _ethernetSource=EthernetSource [_address=MacAddress [_value=00:00:00:00:00:00], _mask=null, augmentation=[]],
* _ethernetType=EthernetType [_type=EtherType [_value=2048], _mask=null, augmentation=[]]
- *
- * Similarly for inPort, if user/application don't set any value for it, FRM will store null value for it in data store.
+ *
+ * Similarly for inPort, if user/application don't set any value for it, FRM will store null value for it in data store.
* When we fetch the same flow (with its statistics) from switch, plugin converts its value to openflow:X:0.
- * e.g _inPort=Uri [_value=openflow:1:0]
- *
+ * e.g _inPort=Uri [_value=openflow:1:0]
+ *
* So this custom equals method add additional check to take care of these scenario, in case any match element is null in data-store-flow, but not
* in the flow fetched from switch.
- *
+ *
* @param statsFlow
* @param storedFlow
* @return
"Unable to retrieve config snapshot after commit for persister, details: " + e.getMessage(),
ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error, e.getErrorInfo());
}
- logger.info("Datastore {} committed successfully: {}", Datastore.candidate, status);
+ logger.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
return document.createElement(XmlNetconfConstants.OK);
}
throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
ErrorSeverity.error, errorInfo);
}
- logger.info("Changes discarded successfully from datastore {}", Datastore.candidate);
+ logger.trace("Changes discarded successfully from datastore {}", Datastore.candidate);
return document.createElement(XmlNetconfConstants.OK);
}
}
- logger.info("Datastore {} validated successfully", Datastore.candidate);
+ logger.trace("Datastore {} validated successfully", Datastore.candidate);
return document.createElement(XmlNetconfConstants.OK);
}
executeSet(configRegistryClient, editConfigExecution);
}
- logger.info("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
+ logger.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
return document.createElement(XmlNetconfConstants.OK);
}
ObjectName on = null;
try {
on = ta.createModule(module, instance);
- logger.info("New instance for {} {} created under name {}", module, instance, on);
+ logger.trace("New instance for {} {} created under name {}", module, instance, on);
} catch (InstanceAlreadyExistsException e1) {
throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
}
ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn);
final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta));
- logger.info("{} operation successful", XmlNetconfConstants.GET);
+ logger.trace("{} operation successful", XmlNetconfConstants.GET);
return element;
}
ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta);
dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
- logger.info("{} operation successful", GET_CONFIG);
+ logger.trace("{} operation successful", GET_CONFIG);
return dataElement;
}
final Object result = executeOperation(configRegistryClient, execution.on, execution.operationName,
execution.attributes);
- logger.info("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName,
+ logger.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName,
execution.on, execution.attributes, result);
if (execution.isVoid()) {
org.xml.sax,
javax.xml.namespace,
javax.xml.xpath,
- org.opendaylight.controller.config.api
+ org.opendaylight.controller.config.api,
+ org.opendaylight.controller.netconf.util
</Import-Package>
<Export-Package>
</Export-Package>
// Socket should not be closed at this point
// Activator unregisters this as JMX listener before close is called
- logger.info("Received notification {}", notification);
+ logger.trace("Received notification {}", notification);
if (notification instanceof CommitJMXNotification) {
try {
handleAfterCommitNotification((CommitJMXNotification) notification);
try {
persisterAggregator.persistConfig(new CapabilityStrippingConfigSnapshotHolder(notification.getConfigSnapshot(),
notification.getCapabilities(), ignoredMissingCapabilityRegex));
- logger.info("Configuration persisted successfully");
+ logger.trace("Configuration persisted successfully");
} catch (IOException e) {
throw new RuntimeException("Unable to persist configuration snapshot", e);
}
package org.opendaylight.controller.netconf.persist.impl;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import io.netty.channel.EventLoopGroup;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.concurrent.Immutable;
-
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClient;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.util.NetconfUtil;
import org.opendaylight.controller.netconf.util.messages.NetconfMessageAdditionalHeader;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+import javax.annotation.concurrent.Immutable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
@Immutable
public class ConfigPusher {
int maxAttempts = 30;
for(int i = 0 ; i < maxAttempts; i++) {
NetconfClient netconfClient = makeNetconfConnection(configSnapshotHolder.getCapabilities(), oldClientForPossibleReuse);
- final String configSnapshot = configSnapshotHolder.getConfigSnapshot();
- logger.trace("Pushing following xml to netconf {}", configSnapshot);
+ logger.trace("Pushing following xml to netconf {}", configSnapshotHolder);
try {
pushLastConfig(configSnapshotHolder, netconfClient);
return netconfClient;
latestCapabilities = netconfClient.getCapabilities();
if (Util.isSubset(netconfClient, expectedCaps)) {
logger.debug("Hello from netconf stable with {} capabilities", latestCapabilities);
- logger.info("Session id received from netconf server: {}", netconfClient.getClientSession());
+ logger.trace("Session id received from netconf server: {}", netconfClient.getClientSession());
return netconfClient;
}
logger.debug("Polling hello from netconf, attempt {}, capabilities {}", attempt, latestCapabilities);
throws ConflictingVersionException, IOException, SAXException {
Element xmlToBePersisted = XmlUtil.readXmlToElement(configSnapshotHolder.getConfigSnapshot());
- logger.info("Pushing last configuration to netconf: {}", configSnapshotHolder);
+ logger.trace("Pushing last configuration to netconf: {}", configSnapshotHolder);
StringBuilder response = new StringBuilder("editConfig response = {");
-
NetconfMessage message = createEditConfigMessage(xmlToBePersisted, "/netconfOp/editConfig.xml");
// sending message to netconf
NetconfMessage responseMessage = getResponse(message, netconfClient);
- XmlElement element = XmlElement.fromDomDocument(responseMessage.getDocument());
- Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
- element = element.getOnlyChildElement();
-
- Util.checkIsOk(element, responseMessage);
+ NetconfUtil.checkIsMessageOk(responseMessage);
response.append(XmlUtil.toString(responseMessage.getDocument()));
response.append("}");
responseMessage = getResponse(getNetconfMessageFromResource("/netconfOp/commit.xml"), netconfClient);
- element = XmlElement.fromDomDocument(responseMessage.getDocument());
- Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
- element = element.getOnlyChildElement();
- Util.checkIsOk(element, responseMessage);
+
+ NetconfUtil.checkIsMessageOk(responseMessage);
response.append("commit response = {");
response.append(XmlUtil.toString(responseMessage.getDocument()));
response.append("}");
- logger.info("Last configuration loaded successfully");
+ logger.trace("Last configuration loaded successfully");
logger.trace("Detailed message {}", response);
}
package org.opendaylight.controller.netconf.persist.impl;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClient;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
import java.util.Set;
public final class Util {
}
}
}
-
-
- public static void checkIsOk(XmlElement element, NetconfMessage responseMessage) throws ConflictingVersionException {
- if (element.getName().equals(XmlNetconfConstants.OK)) {
- return;
- }
-
- if (element.getName().equals(XmlNetconfConstants.RPC_ERROR)) {
- logger.warn("Can not load last configuration, operation failed");
- // is it ConflictingVersionException ?
- XPathExpression xPathExpression = XMLNetconfUtil.compileXPath("/netconf:rpc-reply/netconf:rpc-error/netconf:error-info/netconf:error");
- String error = (String) XmlUtil.evaluateXPath(xPathExpression, element.getDomElement(), XPathConstants.STRING);
- if (error!=null && error.contains(ConflictingVersionException.class.getCanonicalName())) {
- throw new ConflictingVersionException(error);
- }
- throw new IllegalStateException("Can not load last configuration, operation failed: "
- + XmlUtil.toString(responseMessage.getDocument()));
- }
-
- logger.warn("Can not load last configuration. Operation failed.");
- throw new IllegalStateException("Can not load last configuration. Operation failed: "
- + XmlUtil.toString(responseMessage.getDocument()));
- }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.client;
+
+import io.netty.channel.nio.NioEventLoopGroup;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.NetconfUtil;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.LoginPassword;
+
+import java.net.InetSocketAddress;
+
+@Ignore
+public class SSHNetconfClientLiveTest {
+
+ NioEventLoopGroup nettyThreadgroup;
+ NetconfSshClientDispatcher netconfClientDispatcher;
+
+ @Before
+ public void setUp() {
+ nettyThreadgroup = new NioEventLoopGroup();
+ netconfClientDispatcher = new NetconfSshClientDispatcher(new LoginPassword(
+ System.getProperty("username"), System.getProperty("password")),
+ nettyThreadgroup, nettyThreadgroup);
+ }
+
+ @Test
+ public void test() throws Exception {
+ InetSocketAddress address = new InetSocketAddress(System.getProperty("host"), 830);
+ int connectionAttempts = 10, attemptMsTimeout = 1000;
+
+ NetconfClient netconfClient = new NetconfClient("client", address, connectionAttempts,
+ attemptMsTimeout, netconfClientDispatcher);
+
+ netconfClient.getCapabilities();
+
+ NetconfMessage netconfMessage = NetconfUtil.createMessage(getClass().getResourceAsStream("/get_schema.xml"));
+ NetconfMessage response = netconfClient.sendMessage(netconfMessage);
+ NetconfUtil.checkIsMessageOk(response);
+ }
+}
--- /dev/null
+<rpc message-id="2"
+ xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <get-schema xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
+ <identifier>ietf-netconf-monitoring</identifier>
+ <format
+ xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">ncm:yang
+ </format>
+ </get-schema>
+</rpc>
\ No newline at end of file
import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
-import org.opendaylight.controller.netconf.impl.util.NetconfUtil;
+import org.opendaylight.controller.netconf.util.NetconfUtil;
import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
XmlUtil.addNamespaceAttr(getSchemaResult,
XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING);
- logger.info("{} operation successful", GET_SCHEMA);
+ logger.trace("{} operation successful", GET_SCHEMA);
return getSchemaResult;
}
.createElement(XmlNetconfConstants.RPC_ERROR);\r
}\r
\r
- logger.info("{} operation successful", START_EXI);\r
+ logger.trace("{} operation successful", START_EXI);\r
logger.debug("received start-exi message {} ", XmlUtil.toString(document));\r
return getSchemaResult;\r
\r
Element getSchemaResult = document.createElement(XmlNetconfConstants.OK);\r
XmlUtil.addNamespaceAttr(getSchemaResult,\r
XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);\r
- logger.info("{} operation successful", STOP_EXI);\r
+ logger.trace("{} operation successful", STOP_EXI);\r
logger.debug("received stop-exi message {} ", XmlUtil.toString(document));\r
return getSchemaResult;\r
}\r
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl.util;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class NetconfUtil {
-
- private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class);
-
- public static NetconfMessage createMessage(final File f) {
- Preconditions.checkNotNull(f, "File parameter was null");
- try {
- return createMessage(new FileInputStream(f));
- } catch (final FileNotFoundException e) {
- logger.warn("File {} not found.", f, e);
- }
- return null;
- }
-
- public static NetconfMessage createMessage(final InputStream is) {
- Preconditions.checkNotNull(is, "InputStream parameter was null");
- Document doc = null;
- try {
- doc = XmlUtil.readXmlToDocument(is);
- } catch (final IOException e) {
- logger.warn("Error ocurred while parsing stream.", e);
- } catch (final SAXException e) {
- logger.warn("Error ocurred while final parsing stream.", e);
- }
- return (doc == null) ? null : new NetconfMessage(doc);
- }
-}
ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
@Override
public IUserManager addingService(ServiceReference<IUserManager> reference) {
- logger.info("Service {} added, let there be SSH bridge.", reference);
+ logger.trace("Service {} added, let there be SSH bridge.", reference);
iUserManager = context.getService(reference);
try {
onUserManagerFound(iUserManager);
}
@Override
public void modifiedService(ServiceReference<IUserManager> reference, IUserManager service) {
- logger.info("Replacing modified service {} in netconf SSH.", reference);
+ logger.trace("Replacing modified service {} in netconf SSH.", reference);
server.addUserManagerService(service);
}
@Override
public void removedService(ServiceReference<IUserManager> reference, IUserManager service) {
- logger.info("Removing service {} from netconf SSH. " +
+ logger.trace("Removing service {} from netconf SSH. " +
"SSH won't authenticate users until IUserManeger service will be started.", reference);
removeUserManagerService();
}
return AuthenticationResult.SUCCESS;
}
} catch (Exception e){
- logger.info("Authentication failed due to :" + e.getLocalizedMessage());
+ logger.warn("Authentication failed due to :" + e.getLocalizedMessage());
}
return AuthenticationResult.FAILURE;
}
com.siemens.ct.exi.exceptions,
com.siemens.ct.exi.api.dom,
org.xml.sax.helpers,
+ org.opendaylight.controller.config.api,
</Import-Package>
</instructions>
</configuration>
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.util;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class NetconfUtil {
+
+ private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class);
+
+ public static NetconfMessage createMessage(final File f) {
+ Preconditions.checkNotNull(f, "File parameter was null");
+ try {
+ return createMessage(new FileInputStream(f));
+ } catch (final FileNotFoundException e) {
+ logger.warn("File {} not found.", f, e);
+ }
+ return null;
+ }
+
+ public static NetconfMessage createMessage(final InputStream is) {
+ Preconditions.checkNotNull(is, "InputStream parameter was null");
+ Document doc = null;
+ try {
+ doc = XmlUtil.readXmlToDocument(is);
+ } catch (final IOException e) {
+ logger.warn("Error ocurred while parsing stream.", e);
+ } catch (final SAXException e) {
+ logger.warn("Error ocurred while final parsing stream.", e);
+ }
+ return (doc == null) ? null : new NetconfMessage(doc);
+ }
+
+ public static void checkIsMessageOk(NetconfMessage responseMessage) throws ConflictingVersionException {
+ XmlElement element = XmlElement.fromDomDocument(responseMessage.getDocument());
+ Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
+ element = element.getOnlyChildElement();
+
+ if (element.getName().equals(XmlNetconfConstants.OK)) {
+ return;
+ }
+
+ if (element.getName().equals(XmlNetconfConstants.RPC_ERROR)) {
+ logger.warn("Can not load last configuration, operation failed");
+ // is it ConflictingVersionException ?
+ XPathExpression xPathExpression = XMLNetconfUtil.compileXPath("/netconf:rpc-reply/netconf:rpc-error/netconf:error-info/netconf:error");
+ String error = (String) XmlUtil.evaluateXPath(xPathExpression, element.getDomElement(), XPathConstants.STRING);
+ if (error!=null && error.contains(ConflictingVersionException.class.getCanonicalName())) {
+ throw new ConflictingVersionException(error);
+ }
+ throw new IllegalStateException("Can not load last configuration, operation failed: "
+ + XmlUtil.toString(responseMessage.getDocument()));
+ }
+
+ logger.warn("Can not load last configuration. Operation failed.");
+ throw new IllegalStateException("Can not load last configuration. Operation failed: "
+ + XmlUtil.toString(responseMessage.getDocument()));
+ }
+}
public static void sendErrorMessage(final NetconfSession session,
final NetconfDocumentedException sendErrorException) {
- logger.info("Sending error {}", sendErrorException.getMessage(), sendErrorException);
+ logger.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
final Document errorDocument = createDocument(sendErrorException);
session.sendMessage(new NetconfMessage(errorDocument));
}
public static void sendErrorMessage(Channel channel, NetconfDocumentedException sendErrorException) {
- logger.info("Sending error {}", sendErrorException.getMessage(), sendErrorException);
+ logger.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
final Document errorDocument = createDocument(sendErrorException);
channel.writeAndFlush(new NetconfMessage(errorDocument));
}
public static void sendErrorMessage(NetconfSession session, NetconfDocumentedException sendErrorException,
NetconfMessage incommingMessage) {
final Document errorDocument = createDocument(sendErrorException);
- logger.info("Sending error {}", XmlUtil.toString(errorDocument));
+ logger.trace("Sending error {}", XmlUtil.toString(errorDocument));
tryToCopyAttributes(incommingMessage.getDocument(), errorDocument, sendErrorException);
session.sendMessage(new NetconfMessage(errorDocument));
}
* 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.netconf.persist.impl;
+package org.opendaylight.controller.netconf.util;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
import static org.junit.Assert.fail;
import static org.junit.matchers.JUnitMatchers.containsString;
-public class ConfigPersisterNotificationHandlerTest {
+public class NetconfUtilTest {
@Test
public void testConflictingVersionDetection() throws Exception {
- Document document = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/conflictingVersionResponse.xml"));
+ Document document = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconfMessages/conflictingversion/conflictingVersionResponse.xml"));
try{
- Util.checkIsOk(XmlElement.fromDomDocument(document).getOnlyChildElement(), new NetconfMessage(document));
+ NetconfUtil.checkIsMessageOk(new NetconfMessage(document));
fail();
}catch(ConflictingVersionException e){
assertThat(e.getMessage(), containsString("Optimistic lock failed. Expected parent version 21, was 18"));
}
}
-
}
}
}
if (conflictsMsg.length() > 0) {
- LOGGER.info("JAXB type conflicts detected : {}", conflictsMsg.toString());
+ LOGGER.warn("JAXB type conflicts detected : {}", conflictsMsg.toString());
}
}
} else {
auditMsg = "Mode: " + mode + " User " + user + " " + action + " " + moduleName + " " + resource;
}
- logger.info(auditMsg);
+ logger.trace(auditMsg);
}
public static void auditlog(String moduleName, String user, String action, String resource) {
import org.junit.Assert;
import org.junit.Test;
-import junit.framework.TestCase;
-
-public class CommonsNorthboundTest extends TestCase {
+public class CommonsNorthboundTest {
@Test
public void testRestMessages() {
import org.junit.Assert;
import org.junit.Test;
-import junit.framework.TestCase;
-
-public class CommonsNorthboundExceptionTest extends TestCase {
+public class CommonsNorthboundExceptionTest {
@Test
public void testMethodNotAllowed() {
import java.util.HashSet;
import java.util.Set;
-import junit.framework.TestCase;
-
import org.junit.Assert;
import org.junit.Test;
import org.opendaylight.controller.sal.core.Property;
-public class ControllerManagerNorthboundTest extends TestCase {
+public class ControllerManagerNorthboundTest {
@Test
public void testControllerProperties() {
import org.junit.Assert;
import org.junit.Test;
-import junit.framework.TestCase;
-
-public class StaticRoutingNorthboundTest extends TestCase {
+public class StaticRoutingNorthboundTest {
@Test
public void testStaticRoute() {
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
-
import org.junit.Assert;
import org.junit.Test;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.reader.NodeTableStatistics;
import org.opendaylight.controller.sal.utils.NodeCreator;
-public class StatisticsNorthboundTest extends TestCase {
+public class StatisticsNorthboundTest {
@Test
public void testFlowStatistics() {
package org.opendaylight.controller.switchmanager.northbound;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.ArrayList;
import org.junit.Assert;
import org.junit.Test;
-import junit.framework.TestCase;
-
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
import org.opendaylight.controller.sal.utils.NodeCreator;
-public class SwitchManagerNorthboundTest extends TestCase {
+public class SwitchManagerNorthboundTest {
@Test
public void testNodes() {
} else {
if (!currentlyUp) {
// only generate log if the interface changes from down to up
- logger.info("Interface {} with address {} is UP!",
+ logger.trace("Interface {} with address {} is UP!",
netInt.getDisplayName(),
controllerIP.getHostAddress());
}
List<LLDPTLV> optionalTLVList = lldp.getOptionalTLVList();
if (optionalTLVList == null) {
- logger.info("The discovery packet with null custom option from {}", dstNodeConnector);
+ logger.warn("The discovery packet with null custom option from {}", dstNodeConnector);
return false;
}
continue;
}
if (action.getType() == ActionType.SET_NEXT_HOP) {
- logger.info("Unsupported action: {}", action);
+ logger.warn("Unsupported action: {}", action);
continue;
}
}
}
private void printInfoMessage(String type, StatsRequest request) {
- log.info("{} stats request not inserted for switch: {}. Queue size: {}. Collector state: {}.",
+ log.trace("{} stats request not inserted for switch: {}. Queue size: {}. Collector state: {}.",
new Object[] {type, HexString.toHexString(request.switchId), pendingStatsRequests.size(),
statisticsCollector.getState().toString() });
}
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.TreeMap;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
if (this.fields == null) {
result = prime * result;
} else {
- int sum = 0;
- for (MatchType field : this.fields.keySet()) {
- MatchField f = this.fields.get(field);
- sum = sum + ((field==null ? 0 : field.calculateConsistentHashCode()) ^
- (f==null ? 0 : f.hashCode()));
+ // use a tree map as the order of hashMap is not guaranteed.
+ // 2 Match objects with fields in different order are still equal.
+ // Hence the hashCode should be the same too.
+ TreeMap<MatchType, MatchField> tm = new TreeMap<MatchType, MatchField>(this.fields);
+ for (MatchType field : tm.keySet()) {
+ MatchField f = tm.get(field);
+ int fieldHashCode = (field==null ? 0 : field.calculateConsistentHashCode()) ^
+ (f==null ? 0 : f.hashCode());
+ result = prime * result + fieldHashCode;
}
- result = prime * result + sum;
}
result = prime * result + matches;
return result;
Assert.assertTrue(match1.equals(match2));
}
+ @Test
+ public void testHashCodeWithReverseMatch() throws Exception {
+ InetAddress srcIP1 = InetAddress.getByName("1.1.1.1");
+ InetAddress ipMask1 = InetAddress.getByName("255.255.255.255");
+ InetAddress srcIP2 = InetAddress.getByName("2.2.2.2");
+ InetAddress ipMask2 = InetAddress.getByName("255.255.255.255");
+ MatchField field1 = new MatchField(MatchType.NW_SRC, srcIP1, ipMask1);
+ MatchField field2 = new MatchField(MatchType.NW_DST, srcIP2, ipMask2);
+ Match match1 = new Match();
+ match1.setField(field1);
+ match1.setField(field2);
+ Match match2 = match1.reverse();
+ Assert.assertFalse(match1.hashCode() == match2.hashCode());
+ }
+
@Test
public void testHashCode() throws Exception {
byte srcMac1[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9a, (byte) 0xbc };
}
public VIP getVIPWithPoolName(VIP vip){
- cmLogger.info("Search a VIP with name:{}",vip);
+ cmLogger.trace("Search a VIP with name:{}",vip);
for(VIP vipTemp: this.vips.values()){
if(vipTemp.equals(vip)){
- cmLogger.info("Found VIP with pool detail : {}",vipTemp);
+ cmLogger.trace("Found VIP with pool detail : {}",vipTemp);
return vipTemp;
}
}
- cmLogger.info("VIP with pool detail not found ");
+ cmLogger.trace("VIP with pool detail not found ");
return null;
}
@Override
public VIP createVIP(String name,String ip,String protocol,short protocolPort,String poolName){
- cmLogger.info("Create VIP with the following details :[ name : "+name
+ cmLogger.trace("Create VIP with the following details :[ name : "+name
+" ip : "+ip
+" protocol : "+protocol
+" protocol_port : "+protocolPort
vip.setStatus(LBConst.STATUS_ACTIVE);
this.vips.put(name, vip);
- cmLogger.info("New VIP created : "+vip.toString());
+ cmLogger.trace("New VIP created : "+vip.toString());
return vip;
}
@Override
public VIP updateVIP(String name, String poolName){
- cmLogger.info("Updating VIP : "+name+" pool name to "+poolName);
+ cmLogger.trace("Updating VIP : "+name+" pool name to "+poolName);
if(vips.containsKey(name)){
VIP vip = vips.get(name);
@Override
public VIP deleteVIP(String name){
- cmLogger.info("Deleting VIP : "+name);
+ cmLogger.trace("Deleting VIP : "+name);
VIP vip = vips.get(name);
}
}
- cmLogger.info("VIP removed : "+vip.toString());
+ cmLogger.trace("VIP removed : "+vip.toString());
vips.remove(vip.getName());
PoolMember pm = new PoolMember(name,memberIP,poolName);
- cmLogger.info("Adding pool member : "+pm.toString());
+ cmLogger.trace("Adding pool member : "+pm.toString());
pools.get(poolName).addMember(pm);
@Override
public PoolMember removePoolMember(String name, String poolName){
- cmLogger.info("Removing pool member : {} from pool {}",name, poolName);
+ cmLogger.trace("Removing pool member : {} from pool {}",name, poolName);
Pool pool = pools.get(poolName);
pool.removeMember(name);
- cmLogger.info("Pool member {} removed from {} ",name,poolName);
+ cmLogger.trace("Pool member {} removed from {} ",name,poolName);
return pm;
}
Pool newPool = new Pool(name,lbMethod);
- cmLogger.info("New pool created : " + newPool.toString());
+ cmLogger.trace("New pool created : " + newPool.toString());
pools.put(name, newPool);
}
- cmLogger.info("Pool removed : "+pool.toString());
+ cmLogger.trace("Pool removed : "+pool.toString());
pools.remove(poolName);
* @return Details of the source machine in Client object.
*/
public Client getClientFromPacket(IPv4 inPkt){
- lbuLogger.info("Find client information from packet : {}",inPkt.toString());
+ lbuLogger.trace("Find client information from packet : {}",inPkt.toString());
String ip = NetUtils.getInetAddress(inPkt.getSourceAddress()).getHostAddress();
String protocol = IPProtocols.getProtocolName(inPkt.getProtocol());
- lbuLogger.info("client ip {} and protocl {}",ip,protocol);
+ lbuLogger.trace("client ip {} and protocl {}",ip,protocol);
Packet tpFrame= inPkt.getPayload();
- lbuLogger.info("Get protocol layer {}",tpFrame.toString());
+ lbuLogger.trace("Get protocol layer {}",tpFrame.toString());
short port = 0;
port = udpFrame.getSourcePort();
}
- lbuLogger.info("Found port {}",port);
+ lbuLogger.trace("Found port {}",port);
Client source = new Client(ip, protocol,port);
- lbuLogger.info("Client information : {}",source.toString());
+ lbuLogger.trace("Client information : {}",source.toString());
return source;
}
*/
public VIP getVIPFromPacket(IPv4 inPkt){
- lbuLogger.info("Find VIP information from packet : {}",inPkt.toString());
+ lbuLogger.trace("Find VIP information from packet : {}",inPkt.toString());
String ip = NetUtils.getInetAddress(inPkt.getDestinationAddress()).getHostAddress();
VIP dest = new VIP(null,ip, protocol,port,null);
- lbuLogger.info("VIP information : {}",dest.toString());
+ lbuLogger.trace("VIP information : {}",dest.toString());
return dest;
}
forwardPort = hnConnector.getnodeConnector();
lbsLogger
- .info("Both source (client) and destination pool machine is connected to same switch nodes. Respective ports are - {},{}",
+ .trace("Both source (client) and destination pool machine is connected to same switch nodes. Respective ports are - {},{}",
forwardPort, inPkt.getIncomingNodeConnector());
} else {
Path route = this.routing.getRoute(clientNode, destNode);
- lbsLogger.info("Path between source (client) and destination switch nodes : {}",
+ lbsLogger.trace("Path between source (client) and destination switch nodes : {}",
route.toString());
forwardPort = route.getEdges().get(0).getTailNodeConnector();
if (installLoadBalancerFlow(client, vip, clientNode, poolMemberIp,
hnConnector.getDataLayerAddressBytes(), forwardPort,
LBConst.FORWARD_DIRECTION_LB_FLOW)) {
- lbsLogger.info("Traffic from client : {} will be routed " + "to pool machine : {}",
+ lbsLogger.trace("Traffic from client : {} will be routed " + "to pool machine : {}",
client, poolMemberIp);
} else {
lbsLogger.error("Not able to route traffic from client : {}", client);
if (installLoadBalancerFlow(client, vip, clientNode, poolMemberIp, vipMacAddr,
inPkt.getIncomingNodeConnector(), LBConst.REVERSE_DIRECTION_LB_FLOW)) {
- lbsLogger.info("Flow rule installed to change the source ip/mac from "
+ lbsLogger.trace("Flow rule installed to change the source ip/mac from "
+ "pool machine ip {} to VIP {} for traffic coming pool machine", poolMemberIp,
vip);
} else {
FlowEntry fEntry = new FlowEntry(policyName, flowName, flow, sourceSwitch);
- lbsLogger.info("Install flow entry {} on node {}", fEntry.toString(), sourceSwitch.toString());
+ lbsLogger.trace("Install flow entry {} on node {}", fEntry.toString(), sourceSwitch.toString());
if (!this.ruleManager.checkFlowEntryConflict(fEntry)) {
if (this.ruleManager.installFlowEntry(fEntry).isSuccess()) {
if (props != null) {
this.containerName = (String) props.get("containerName");
- lbsLogger.info("Running container name:" + this.containerName);
+ lbsLogger.trace("Running container name:" + this.containerName);
} else {
// In the Global instance case the containerName is empty
this.containerName = "";
}
- lbsLogger.info(configManager.toString());
+ lbsLogger.trace(configManager.toString());
}
@Override
public String getPoolMemberForClient(Client source, VIP dest){
- rLogger.info("Received traffic from client : {} for VIP : {} ",source, dest);
+ rLogger.trace("Received traffic from client : {} for VIP : {} ",source, dest);
syncWithLoadBalancerData();
if(this.clientMemberMap.containsKey(source)){
pm= this.clientMemberMap.get(source);
- rLogger.info("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
+ rLogger.trace("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
}else{
Pool pool = null;
pool = this.cmgr.getPool(dest.getPoolName());
int memberNum = this.randomGenerator.nextInt(pool.getAllMembers().size()-1);
pm = pool.getAllMembers().get(memberNum);
this.clientMemberMap.put(source, pm );
- rLogger.info("Network traffic from client {} will be directed to pool member {}",pm);
+ rLogger.trace("Network traffic from client {} will be directed to pool member {}",pm);
}
return pm.getIp();
}
@Override
public String getPoolMemberForClient(Client source, VIP dest){
- rrLogger.info("Received traffic from client : {} for VIP : {} ",source, dest);
+ rrLogger.trace("Received traffic from client : {} for VIP : {} ",source, dest);
syncWithLoadBalancerData();
if(this.clientMemberMap.containsKey(source)){
pm= this.clientMemberMap.get(source);
- rrLogger.info("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
+ rrLogger.trace("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
}else{
Pool pool = null;
pool = this.cmgr.getPool(dest.getPoolName());
pm = pool.getAllMembers().get(memberNum);
this.clientMemberMap.put(source, pm );
- rrLogger.info("New client's packet will be directed to pool member {}",pm);
+ rrLogger.trace("New client's packet will be directed to pool member {}",pm);
memberNum++;
if(memberNum > pool.getAllMembers().size()-1){
pm = pool.getAllMembers().get(0);
this.clientMemberMap.put(source, pm);
- rrLogger.info("Network traffic from client {} will be directed to pool member {}",pm);
+ rrLogger.trace("Network traffic from client {} will be directed to pool member {}",pm);
this.nextItemFromPool.put(dest, 1);
rrLogger.debug("Next pool member for new client of VIP is set to {}",pool.getAllMembers().get(1));
}
import org.opendaylight.controller.samples.loadbalancer.entities.VIP;\r
import org.opendaylight.controller.samples.loadbalancer.policies.RoundRobinLBPolicy;\r
\r
-import junit.framework.TestCase;\r
-\r
/**\r
*\r
* Class to unit test the load balancing policies.\r
*\r
*/\r
-public class LoadBalancerTest extends TestCase {\r
+public class LoadBalancerTest {\r
@Test\r
public void testRoundRobinPolicy() {\r
ConfigManager cm = null;\r
c1 = new Client("10.0.0.1","TCP",(short)5003);\r
Assert.assertTrue(rrp.getPoolMemberForClient(c1, vip).equals(host4.getIp()));\r
}\r
-}
\ No newline at end of file
+}
private void allocateCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't create cache");
+ log.trace("un-initialized clusterContainerService, can't create cache");
return;
}
@SuppressWarnings({ "unchecked" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't retrieve cache");
+ log.trace("un-initialized clusterContainerService, can't retrieve cache");
return;
}
private void destroyCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't destroy cache");
+ log.trace("un-initialized clusterContainerService, can't destroy cache");
return;
}
private static final long serialVersionUID = 1L;
// Key fields
private InetAddress networkAddress;
+ private transient InetAddress subnetPrefix;
private short subnetMaskLength;
// Property fields
private short vlan;
*/
public Subnet setNetworkAddress(InetAddress networkAddress) {
this.networkAddress = networkAddress;
+ this.subnetPrefix = null;
return this;
}
if (ip == null) {
return false;
}
- InetAddress thisPrefix = getPrefixForAddress(this.networkAddress);
+ if(subnetPrefix == null) {
+ subnetPrefix = getPrefixForAddress(this.networkAddress);
+ }
InetAddress otherPrefix = getPrefixForAddress(ip);
boolean isSubnetOf = true;
- if (((thisPrefix == null) || (otherPrefix == null)) || (!thisPrefix.equals(otherPrefix)) ) {
+ if (((subnetPrefix == null) || (otherPrefix == null)) || (!subnetPrefix.equals(otherPrefix)) ) {
isSubnetOf = false;
}
return isSubnetOf;
@SuppressWarnings({ "unchecked" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't create cache");
+ log.warn("un-initialized clusterContainerService, can't create cache");
return;
}
return;
}
- log.info("Set Node {}'s Mode to {}", nodeId, cfgObject.getMode());
+ log.trace("Set Node {}'s Mode to {}", nodeId, cfgObject.getMode());
if (modeChange) {
notifyModeChange(node, cfgObject.isProactive());
private TopoEdgeUpdate edgeUpdate(Edge e, UpdateType type, Set<Property> props) {
switch (type) {
case ADDED:
- // Avoid redundant update as notifications trigger expensive tasks
- if (edgesDB.containsKey(e)) {
- log.trace("Skipping redundant edge addition: {}", e);
- return null;
- }
-
- // Ensure that head node connector exists
- if (!headNodeConnectorExist(e)) {
- log.warn("Ignore edge that contains invalid node connector: {}", e);
- return null;
- }
-
- // Check if nodeConnectors of the edge were correctly categorized
- // by OF plugin
- crossCheckNodeConnectors(e);
- // Make sure the props are non-null
+ // Make sure the props are non-null or create a copy
if (props == null) {
props = new HashSet<Property>();
} else {
props = new HashSet<Property>(props);
}
- //in case of node switch-over to a different cluster controller,
- //let's retain edge props
Set<Property> currentProps = this.edgesDB.get(e);
- if (currentProps != null){
+ if (currentProps != null) {
+
+ if (currentProps.equals(props)) {
+ // Avoid redundant updates as notifications trigger expensive tasks
+ log.trace("Skipping redundant edge addition: {}", e);
+ return null;
+ }
+
+ // In case of node switch-over to a different cluster controller,
+ // let's retain edge props (e.g. creation time)
props.addAll(currentProps);
}
+ // Ensure that head node connector exists
+ if (!headNodeConnectorExist(e)) {
+ log.warn("Ignore edge that contains invalid node connector: {}", e);
+ return null;
+ }
+
+ // Check if nodeConnectors of the edge were correctly categorized
+ // by protocol plugin
+ crossCheckNodeConnectors(e);
+
// Now make sure there is the creation timestamp for the
// edge, if not there, stamp with the first update
boolean found_create = false;
rcResponse = aaaClient.authService(userName, password,
aaaServer.getAddress(), aaaServer.getSecret());
if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
- logger.info(
+ logger.trace(
"Remote Authentication Succeeded for User: \"{}\", by Server: {}",
userName, aaaServer.getAddress());
remotelyAuthenticated = true;
break;
} else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
- logger.info(
+ logger.trace(
"Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
new Object[] { userName, aaaServer.getAddress(),
rcResponse.getStatus().toString() });
} else {
- logger.info(
+ logger.trace(
"Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
new Object[] { userName, aaaServer.getAddress(),
rcResponse.getStatus().toString() });
// Trigger cluster update
localUserConfigList.put(user, targetConfigEntry);
- logger.info("Password changed for User \"{}\"", user);
+ logger.trace("Password changed for User \"{}\"", user);
return status;
}
// TODO: if user was authenticated through AAA server, send
// Acct-Status-Type=stop message to server with logout as reason
removeUserFromActiveList(userName);
- logger.info("User \"{}\" logged out", userName);
+ logger.trace("User \"{}\" logged out", userName);
}
/*
// TODO: if user was authenticated through AAA server, send
// Acct-Status-Type=stop message to server with timeout as reason
removeUserFromActiveList(userName);
- logger.info("User \"{}\" timed out", userName);
+ logger.trace("User \"{}\" timed out", userName);
}
@Override
} else {
auditMsg = "Mode: " + mode + " User " + user + " " + action + " " + moduleName + " " + resource;
}
- logger.info(auditMsg);
+ logger.trace(auditMsg);
}
public static void auditlog(String moduleName, String user, String action, String resource) {