Change ConflictingVersionException and ValidationException to be checked instead of
runtime exceptions.
Fix ConfigPusher's ConflictVersionException handling that was introduced when IOException was
used to wrap RuntimeException.
Small fixes in netconf, more refactoring of exception handling will be needed there.
Maros Marsalek: Rebase commit + fix compliation issue in ShutdownTest
Change-Id: Iab89de6ef6ced0de0a267470f860912ae3c56892
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
<arphandler.version>0.5.2-SNAPSHOT</arphandler.version>
<forwarding.staticrouting>0.5.2-SNAPSHOT</forwarding.staticrouting>
<samples.loadbalancer>0.5.2-SNAPSHOT</samples.loadbalancer>
- <config.version>0.2.4-SNAPSHOT</config.version>
- <netconf.version>0.2.4-SNAPSHOT</netconf.version>
+ <config.version>0.2.5-SNAPSHOT</config.version>
+ <netconf.version>0.2.5-SNAPSHOT</netconf.version>
<mdsal.version>1.1-SNAPSHOT</mdsal.version>
<containermanager.version>0.5.2-SNAPSHOT</containermanager.version>
<containermanager.it.version>0.5.2-SNAPSHOT</containermanager.it.version>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>config-api</artifactId>
* transaction was committed after creating this transaction. Clients can create
* new transaction and merge the changes.
*/
-public class ConflictingVersionException extends RuntimeException {
+public class ConflictingVersionException extends Exception {
private static final long serialVersionUID = 1L;
public ConflictingVersionException() {
/**
* This exception is not intended to be used while implementing modules,
- * itaggregates validation exceptions and sends them back to the user.
+ * it aggregates validation exceptions and sends them back to the user.
+ * Use {@link org.opendaylight.controller.config.api.JmxAttributeValidationException} for
+ * validating modules instead.
*/
-public class ValidationException extends RuntimeException {
+public class ValidationException extends Exception {
private static final long serialVersionUID = -6072893219820274247L;
private final Map<String/* module name */, Map<String/* instance name */, ExceptionMessageWithStackTrace>> failedValidations;
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-manager</artifactId>
try {
validate();
} catch (Exception e) {
- throw ValidationException.createForSingleException(
- moduleIdentifier, e);
+
+ throw new MBeanException(ValidationException.createForSingleException(
+ moduleIdentifier, e));
}
return Void.TYPE;
}
package org.opendaylight.controller.config.manager.impl.osgi;
import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
import org.opendaylight.controller.config.spi.ModuleFactory;
synchronized void blankTransaction() {
// race condition check: config-persister might push new configuration while server is starting up.
ConflictingVersionException lastException = null;
- for (int i = 0; i < 10; i++) {
+ int maxAttempts = 10;
+ for (int i = 0; i < maxAttempts; i++) {
try {
// create transaction
boolean blankTransaction = true;
Thread.currentThread().interrupt();
throw new IllegalStateException(interruptedException);
}
+ } catch (ValidationException e) {
+ logger.error("Validation exception while running blank transaction indicates programming error", e);
+ throw new RuntimeException("Validation exception while running blank transaction indicates programming error", e);
}
}
- throw lastException;
+ throw new RuntimeException("Maximal number of attempts reached and still cannot get optimistic lock from " +
+ "config manager",lastException);
}
@Override
import javax.management.MBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
-import javax.management.RuntimeMBeanException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
private void testValidation(ConfigTransactionClient transaction)
throws InstanceAlreadyExistsException, ReflectionException,
- InstanceNotFoundException, MBeanException {
+ InstanceNotFoundException, MBeanException, ConflictingVersionException {
ObjectName fixed1names = transaction.createModule(
TestingFixedThreadPoolModuleFactory.NAME, fixed1);
// call validate on config bean
platformMBeanServer.invoke(fixed1names, "validate", new Object[0],
new String[0]);
fail();
- } catch (RuntimeMBeanException e) {
- RuntimeException targetException = e.getTargetException();
+ } catch (MBeanException e) {
+ Exception targetException = e.getTargetException();
assertNotNull(targetException);
assertEquals(ValidationException.class, targetException.getClass());
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>config-module-archetype</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-api</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-directory-adapter</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-directory-autodetect-adapter</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-directory-xml-adapter</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-file-adapter</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-file-xml-adapter</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>config-plugin-parent</artifactId>
<properties>
<jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
- <config.version>0.2.4-SNAPSHOT</config.version>
</properties>
<build>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-util</artifactId>
*/
package org.opendaylight.controller.config.util;
-import java.util.Map;
-import java.util.Set;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean;
+import org.opendaylight.controller.config.api.jmx.ConfigTransactionControllerMXBean;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import javax.management.Attribute;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.JMX;
+import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
-import javax.management.RuntimeMBeanException;
-
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean;
-import org.opendaylight.controller.config.api.jmx.ConfigTransactionControllerMXBean;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import java.util.Map;
+import java.util.Set;
public class ConfigTransactionJMXClient implements ConfigTransactionClient {
private final ConfigRegistryMXBean configRegistryMXBeanProxy;
throws ValidationException {
try {
configMBeanServer.invoke(configBeanON, "validate", null, null);
+ } catch (MBeanException e) {
+ Exception targetException = e.getTargetException();
+ if (targetException instanceof ValidationException){
+ throw (ValidationException) targetException;
+ } else {
+ throw new RuntimeException(e);
+ }
} catch (JMException e) {
throw new RuntimeException(e);
- } catch (RuntimeMBeanException e) {
- throw e.getTargetException();
}
}
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<artifactId>logback-config</artifactId>
*/
package org.opendaylight.controller.config.yang.logback.config;
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
+import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
+import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.slf4j.LoggerFactory;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
-import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
-import com.google.common.collect.Lists;
+import static org.junit.Assert.assertEquals;
public class LogbackModuleWithInitialConfigurationTest extends AbstractConfigTest {
}
public ObjectName createBeans() throws JoranException, InstanceAlreadyExistsException, IOException,
- MalformedObjectNameException, InstanceNotFoundException {
+ MalformedObjectNameException, InstanceNotFoundException, ValidationException, ConflictingVersionException {
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
*/
package org.opendaylight.controller.config.yang.logback.config;
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.util.List;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
+import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.slf4j.LoggerFactory;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.List;
-import com.google.common.collect.Lists;
+import static org.junit.Assert.assertEquals;
public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
* @throws MalformedObjectNameException
*/
@Test
- public void test() throws InstanceAlreadyExistsException, InstanceNotFoundException, MalformedObjectNameException {
+ public void test() throws InstanceAlreadyExistsException, InstanceNotFoundException, MalformedObjectNameException, ValidationException, ConflictingVersionException {
ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
ObjectName nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), LogbackModuleFactory.INSTANCE_NAME);
*/
@Test
public void testAddNewLogger() throws InstanceAlreadyExistsException, InstanceNotFoundException,
- MalformedObjectNameException {
+ MalformedObjectNameException, ValidationException, ConflictingVersionException {
ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
ObjectName nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), LogbackModuleFactory.INSTANCE_NAME);
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
</parent>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<artifactId>config-subsystem</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<jacoco.version>0.6.2.201302030002</jacoco.version>
<slf4j.version>1.7.2</slf4j.version>
<salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
- <config.version>0.2.4-SNAPSHOT</config.version>
</properties>
<dependencies>
<parent>
<artifactId>config-plugin-parent</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>config-plugin-parent</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
shutdownViaRuntimeJMX(secret);
}
- private void setSecret(String secret) throws InstanceNotFoundException {
+ private void setSecret(String secret) throws InstanceNotFoundException, ValidationException, ConflictingVersionException {
ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
ObjectName on = transaction.lookupConfigBean(NAME, NAME);
ShutdownModuleMXBean proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>yang-jmx-generator-it</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>yang-jmx-generator-plugin</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>yang-jmx-generator</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>yang-store-api</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>yang-store-impl</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-plugin-parent</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../config-plugin-parent</relativePath>
</parent>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-jmx-generator-plugin</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>${config.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-jmx-generator-plugin</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>${config.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>${yangtools.version}</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-jmx-generator-plugin</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>${config.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-jmx-generator-plugin</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>${config.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>sal-parent</artifactId>
<version>1.1-SNAPSHOT</version>
</parent>
- <properties>
- <netconf.version>0.2.4-SNAPSHOT</netconf.version>
- </properties>
+
<artifactId>sal-netconf-connector</artifactId>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-jmx-generator-plugin</artifactId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>${config.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>${yangtools.version}</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>config-netconf-connector</artifactId>
<name>${project.artifactId}</name>
package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-import java.util.HashMap;
-import java.util.Map;
-
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import java.util.HashMap;
+import java.util.Map;
+
public class Commit extends AbstractConfigNetconfOperation {
private static final Logger logger = LoggerFactory.getLogger(Commit.class);
try {
status = this.transactionProvider.commitTransaction();
} catch (final IllegalStateException e) {
+ // FIXME: when can IllegalStateException occur?
logger.warn("Commit failed: ", e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo.put(ErrorTag.operation_failed.name(),
"Operation failed. Use 'get-config' or 'edit-config' before triggering 'commit' operation");
throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
ErrorSeverity.error, errorInfo);
- } catch (final NetconfDocumentedException e) {
- throw new NetconfDocumentedException(
- "Unable to retrieve config snapshot after commit for persister, details: " + e.getMessage(),
- ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error, e.getErrorInfo());
+ } catch (ValidationException e) {
+ throw NetconfDocumentedException.wrap(e);
+ } catch (ConflictingVersionException e) {
+ throw NetconfDocumentedException.wrap(e);
+
}
logger.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-import java.util.HashMap;
-import java.util.Map;
-
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import java.util.HashMap;
+import java.util.Map;
+
public class DiscardChanges extends AbstractConfigNetconfOperation {
public static final String DISCARD = "discard-changes";
try {
fromXml(xml);
} catch (final IllegalArgumentException e) {
+ //FIXME where can IllegalStateException be thrown?
logger.warn("Rpc error: {}", ErrorTag.bad_attribute, e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage());
try {
this.transactionProvider.abortTransaction();
} catch (final IllegalStateException e) {
+ //FIXME where can IllegalStateException be thrown?
logger.warn("Abort failed: ", e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo
try {
checkXml(xml);
} catch (IllegalStateException e) {
+ //FIXME where can IllegalStateException be thrown? I see precondition that guards for programming bugs..
logger.warn("Rpc error: {}", ErrorTag.missing_attribute, e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo.put(ErrorTag.missing_attribute.name(), "Missing value of datastore attribute");
throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.missing_attribute,
ErrorSeverity.error, errorInfo);
} catch (final IllegalArgumentException e) {
+ // FIXME use checked exception if it has domain meaning
logger.warn("Rpc error: {}", ErrorTag.bad_attribute, e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage());
transactionProvider.validateTransaction();
} catch (ValidationException e) {
logger.warn("Validation failed", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.operation_failed.name(), "Validation failed");
- throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
- ErrorSeverity.error, errorInfo);
+ throw NetconfDocumentedException.wrap(e);
} catch (IllegalStateException e) {
logger.warn("Validation failed", e);
final Map<String, String> errorInfo = new HashMap<>();
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.JmxAttributeValidationException;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
try {
set(configRegistryClient, editConfigExecution);
- } catch (IllegalStateException | JmxAttributeValidationException | ValidationException e) {
+
+ } catch (IllegalStateException e) {
+ //FIXME: when can IllegalStateException be thrown?
+ // JmxAttributeValidationException is wrapped in DynamicWritableWrapper with ValidationException
+ // ValidationException is not thrown until validate or commit is issued
logger.warn("Set phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage());
EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
try {
test(configRegistryClient, editConfigExecution, editConfigExecution.getDefaultStrategy());
- } catch (IllegalStateException | JmxAttributeValidationException | ValidationException e) {
+ } catch (IllegalStateException | ValidationException e) {
+ //FIXME: when can IllegalStateException be thrown?
logger.warn("Test phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
final Map<String, String> errorInfo = new HashMap<>();
errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage());
}
private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution,
- EditStrategyType editStrategyType) {
+ EditStrategyType editStrategyType) throws ValidationException {
ObjectName taON = transactionProvider.getTestTransaction();
try {
return identityNameToSchemaNode.containsKey(idName);
}
+ // FIXME method never used
public IdentitySchemaNode getIdentitySchemaNode(String idName) {
Preconditions.checkState(identityNameToSchemaNode.containsKey(idName), "No identity under name %s", idName);
return identityNameToSchemaNode.get(idName);
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Commit and notification send must be atomic
*/
- public synchronized CommitStatus commitTransaction() throws NetconfDocumentedException {
+ public synchronized CommitStatus commitTransaction() throws ValidationException, ConflictingVersionException {
final Optional<ObjectName> maybeTaON = getTransaction();
Preconditions.checkState(maybeTaON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
ObjectName taON = maybeTaON.get();
// no clean up: user can reconfigure and recover this transaction
logger.warn("Transaction {} failed on {}", taON, validationException.toString());
throw validationException;
- } catch (Exception e) {
+ } catch (ConflictingVersionException e) {
logger.error("Exception while commit of {}, aborting transaction", taON, e);
// clean up
abortTransaction();
transactionClient.validateConfig();
}
- public void validateTestTransaction(ObjectName taON) {
+ public void validateTestTransaction(ObjectName taON) throws ValidationException {
ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON);
transactionClient.validateConfig();
}
package org.opendaylight.controller.netconf.confignetconfconnector;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.matchers.JUnitMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
public class NetconfMappingTest extends AbstractConfigTest {
transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID);
}
- private ObjectName createModule(final String instanceName) throws InstanceAlreadyExistsException, InstanceNotFoundException, URISyntaxException {
+ private ObjectName createModule(final String instanceName) throws InstanceAlreadyExistsException, InstanceNotFoundException, URISyntaxException, ValidationException, ConflictingVersionException {
final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
final ObjectName on = transaction.createModule(this.factory.getImplementationName(), instanceName);
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
}
@Test
- public void test() throws NetconfDocumentedException {
+ public void test() throws NetconfDocumentedException, ValidationException {
EditConfig edit = new EditConfig(yangStoreSnapshot, provider, configRegistry,
ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING);
EditConfigStrategy editStrat = mock(EditConfigStrategy.class);
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>config-persister-impl</artifactId>
<name>${project.artifactId}</name>
package org.opendaylight.controller.netconf.persist.impl;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.annotation.concurrent.Immutable;
-
+import com.google.common.base.Preconditions;
+import io.netty.channel.EventLoopGroup;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
-import com.google.common.base.Preconditions;
-import io.netty.channel.EventLoopGroup;
+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.LinkedHashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
@Immutable
public class ConfigPusher {
- private static final Logger logger = LoggerFactory.getLogger(ConfigPusher.class);
+ private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterNotificationHandler.class);
private static final int NETCONF_SEND_ATTEMPT_MS_DELAY = 1000;
private static final int NETCONF_SEND_ATTEMPTS = 20;
}
public ConfigPusher(InetSocketAddress address, EventLoopGroup nettyThreadGroup,
- long maxWaitForCapabilitiesMillis, long connectionTimeoutMillis) {
+ long maxWaitForCapabilitiesMillis, long connectionTimeoutMillis) {
this.address = address;
this.nettyThreadGroup = nettyThreadGroup;
this.maxWaitForCapabilitiesMillis = maxWaitForCapabilitiesMillis;
EditAndCommitResponse editAndCommitResponse = pushLastConfig(configSnapshotHolder, netconfClient);
return new EditAndCommitResponseWithRetries(editAndCommitResponse, retryAttempt);
} catch (ConflictingVersionException e) {
+ logger.debug("Conflicting version detected, will retry after timeout");
lastException = e;
Thread.sleep(1000);
} catch (RuntimeException e) {
logger.trace("Session id received from netconf server: {}", netconfClient.getClientSession());
return netconfClient;
}
- logger.debug("Polling hello from netconf, attempt {}, capabilities {}", attempt, latestCapabilities);
+ Set<String> allNotFound = computeNotFoundCapabilities(expectedCaps, latestCapabilities);
+ logger.debug("Netconf server did not provide required capabilities. Attempt {}. " +
+ "Expected but not found: {}, all expected {}, current {}",
+ attempt, allNotFound, expectedCaps, latestCapabilities);
Util.closeClientAndDispatcher(netconfClient);
Thread.sleep(delayMillis);
}
logger.error("Could not connect to the server in {} ms", maxWaitForCapabilitiesMillis);
throw new RuntimeException("Could not connect to netconf server");
}
- Set<String> allNotFound = new HashSet<>(expectedCaps);
- allNotFound.removeAll(latestCapabilities);
+ Set<String> allNotFound = computeNotFoundCapabilities(expectedCaps, latestCapabilities);
logger.error("Netconf server did not provide required capabilities. Expected but not found: {}, all expected {}, current {}",
allNotFound, expectedCaps, latestCapabilities);
throw new RuntimeException("Netconf server did not provide required capabilities. Expected but not found:" + allNotFound);
}
+ private static Set<String> computeNotFoundCapabilities(Set<String> expectedCaps, Set<String> latestCapabilities) {
+ Set<String> allNotFound = new HashSet<>(expectedCaps);
+ allNotFound.removeAll(latestCapabilities);
+ return allNotFound;
+ }
+
/**
* Sends two RPCs to the netconf server: edit-config and commit.
}
- private static NetconfMessage sendRequestGetResponseCheckIsOK(NetconfMessage request, NetconfClient netconfClient) throws IOException {
+ private static NetconfMessage sendRequestGetResponseCheckIsOK(NetconfMessage request, NetconfClient netconfClient)
+ throws ConflictingVersionException, IOException {
try {
NetconfMessage netconfMessage = netconfClient.sendMessage(request, NETCONF_SEND_ATTEMPTS, NETCONF_SEND_ATTEMPT_MS_DELAY);
NetconfUtil.checkIsMessageOk(netconfMessage);
return netconfMessage;
- } catch (RuntimeException | ExecutionException | InterruptedException | TimeoutException e) {
+ }catch(ConflictingVersionException e) {
+ logger.trace("conflicting version detected: {}", e.toString());
+ throw e;
+ } catch (RuntimeException | ExecutionException | InterruptedException | TimeoutException e) { // TODO: change NetconfClient#sendMessage to throw checked exceptions
logger.debug("Error while executing netconf transaction {} to {}", request, netconfClient, e);
throw new IOException("Failed to execute netconf transaction", e);
}
}
+
// load editConfig.xml template, populate /rpc/edit-config/config with parameter
private static NetconfMessage createEditConfigMessage(Element dataElement) {
String editConfigResourcePath = "/netconfOp/editConfig.xml";
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ietf-netconf-monitoring-extension</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ietf-netconf-monitoring</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>netconf-api</artifactId>
</Private-Package>
<Import-Package>
javax.management,
+ org.opendaylight.controller.config.api,
org.opendaylight.controller.config.api.jmx,
org.opendaylight.protocol.framework,
io.netty.channel,
package org.opendaylight.controller.netconf.api;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
+
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
/**
private static final long serialVersionUID = 1L;
+
+
public enum ErrorType {
transport, rpc, protocol, application;
this.errorInfo = errorInfo;
}
+ public static NetconfDocumentedException wrap(ValidationException e) throws NetconfDocumentedException {
+ final Map<String, String> errorInfo = new HashMap<>();
+ errorInfo.put(ErrorTag.operation_failed.name(), "Validation failed");
+ throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
+ ErrorSeverity.error, errorInfo);
+ }
+
+ public static NetconfDocumentedException wrap(ConflictingVersionException e) throws NetconfDocumentedException {
+ final Map<String, String> errorInfo = new HashMap<>();
+ errorInfo.put(ErrorTag.operation_failed.name(), "Optimistic lock failed");
+ throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
+ ErrorSeverity.error, errorInfo);
+ }
+
public ErrorType getErrorType() {
return this.errorType;
}
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>netconf-client</artifactId>
<name>${project.artifactId}</name>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>netconf-impl</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>netconf-it</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>netconf-mapping-api</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>netconf-monitoring</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
</parent>
<artifactId>netconf-util</artifactId>
<name>${project.artifactId}</name>
<relativePath>../commons/opendaylight</relativePath>
</parent>
- <version>0.2.4-SNAPSHOT</version>
+ <version>0.2.5-SNAPSHOT</version>
<artifactId>netconf-subsystem</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<maven.bundle.version>2.4.0</maven.bundle.version>
<slf4j.version>1.7.2</slf4j.version>
<netconf.netty.version>4.0.10.Final</netconf.netty.version>
- <netconf.version>0.2.4-SNAPSHOT</netconf.version>
- <config.version>0.2.4-SNAPSHOT</config.version>
<salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
</properties>