<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<groupId>org.opendaylight.controller</groupId>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-clustering-commons</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-clustering-config</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-distributed-datastore</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
- <!-- FIXME: remove override once odlparent ships 3.1.0+ -->
- <version>3.0.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>feature-repo-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<groupId>org.opendaylight.controller</groupId>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>feature-repo-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
-->
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="odl-config-netty">
<feature name="odl-config-netty">
- <feature version="[4,5)">odl-guava</feature>
- <feature version="[4,5)">odl-netty-4</feature>
+ <feature version="[5,6)">odl-guava</feature>
+ <feature version="[5,6)">odl-netty-4</feature>
</feature>
</features>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>feature-repo-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>feature-repo-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<properties>
<blueprint.version>0.11.0-SNAPSHOT</blueprint.version>
+ <!-- CONTROLLER-1584 -->
+ <skip.karaf.featureTest>true</skip.karaf.featureTest>
</properties>
<dependencyManagement>
-->
<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="odl-mdsal-${project.version}">
<feature name="odl-mdsal-broker-local" version="${project.version}">
- <feature version="[4,5)">odl-lmax-3</feature>
+ <feature version="[5,6)">odl-lmax-3</feature>
<feature version="[2.1,3)">odl-yangtools-codec</feature>
<bundle start-level="40">mvn:org.opendaylight.controller/blueprint/${blueprint.version}</bundle>
</feature>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<version>1.10.0-SNAPSHOT</version>
<packaging>feature</packaging>
+ <properties>
+ <!-- CONTROLLER-1584 -->
+ <skip.karaf.featureTest>true</skip.karaf.featureTest>
+ </properties>
+
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
-->
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="odl-controller-${project.version}">
<feature name="odl-mdsal-clustering-commons" version="${project.version}">
- <feature version="[4,5)">odl-akka-system-2.5</feature>
- <feature version="[4,5)">odl-akka-persistence-2.5</feature>
- <feature version="[4,5)">odl-akka-clustering-2.5</feature>
- <feature version="[4,5)">odl-apache-commons-lang3</feature>
- <feature version="[4.0.8,5)">odl-dropwizard-metrics</feature>
- <feature version="[4,5)">odl-servlet-api</feature>
+ <feature version="[5,6)">odl-akka-system-2.5</feature>
+ <feature version="[5,6)">odl-akka-persistence-2.5</feature>
+ <feature version="[5,6)">odl-akka-clustering-2.5</feature>
+ <feature version="[5,6)">odl-apache-commons-lang3</feature>
+ <feature version="[5,6)">odl-dropwizard-metrics</feature>
+ <feature version="[5,6)">odl-servlet-api</feature>
</feature>
</features>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<version>1.10.0-SNAPSHOT</version>
<packaging>feature</packaging>
+ <properties>
+ <!-- CONTROLLER-1584 -->
+ <skip.karaf.featureTest>true</skip.karaf.featureTest>
+ </properties>
+
<dependencyManagement>
<dependencies>
<dependency>
-->
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="odl-controller-${project.version}">
<feature name="odl-mdsal-distributed-datastore" version="${project.version}">
- <feature version="[4,5)">odl-apache-commons-text</feature>
+ <feature version="[5,6)">odl-apache-commons-text</feature>
</feature>
</features>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<version>1.10.0-SNAPSHOT</version>
<packaging>feature</packaging>
+ <properties>
+ <!-- CONTROLLER-1584 -->
+ <skip.karaf.featureTest>true</skip.karaf.featureTest>
+ </properties>
+
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<dependency>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odl-akka-leveldb-0.10</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<type>xml</type>
<classifier>features</classifier>
</dependency>
-->
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="odl-controller-${project.version}">
<feature name="odl-mdsal-remoterpc-connector" version="${project.version}">
- <feature version="[4,5)">odl-akka-leveldb-0.10</feature>
+ <feature version="[5,6)">odl-akka-leveldb-0.10</feature>
</feature>
</features>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>karaf4-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>bundle-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
-import javax.annotation.concurrent.GuardedBy;
import org.apache.aries.blueprint.di.AbstractRecipe;
import org.apache.aries.blueprint.di.ExecutionContext;
import org.apache.aries.blueprint.di.Recipe;
import org.apache.aries.blueprint.ext.DependentComponentFactoryMetadata;
import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.blueprint.BlueprintContainerRestartService;
import org.osgi.framework.ServiceReference;
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.controller.config.threadpool.util;
-import com.google.common.base.Preconditions;
+import static java.util.Objects.requireNonNull;
+
import java.io.Closeable;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;
-import javax.annotation.concurrent.ThreadSafe;
/**
- * Implementation of {@link ThreadFactory}.
+ * Implementation of {@link ThreadFactory}. This class is thread-safe.
*/
-@ThreadSafe
public class NamingThreadPoolFactory implements ThreadFactory, Closeable {
private final ThreadGroup group;
private final String namePrefix;
private final AtomicLong threadName = new AtomicLong();
- public NamingThreadPoolFactory(String namePrefix) {
- Preconditions.checkNotNull(namePrefix);
+ public NamingThreadPoolFactory(final String namePrefix) {
+ this.namePrefix = requireNonNull(namePrefix);
this.group = new ThreadGroup(namePrefix);
- this.namePrefix = namePrefix;
}
@Override
- public Thread newThread(Runnable r) {
+ public Thread newThread(final Runnable r) {
return new Thread(group, r, String.format("%s-%d", group.getName(), threadName.incrementAndGet()));
}
public String getNamePrefix() {
return namePrefix;
}
-
}
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.List;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.concepts.Identifiable;
/**
* A reusable {@link Builder} for creating {@link ModifyTransactionRequest} message instances. Its internal state is
- * reset when {@link #build()} is invoked, hence it can be used to create a sequence of messages.
+ * reset when {@link #build()} is invoked, hence it can be used to create a sequence of messages. This class is NOT
+ * thread-safe.
*
* @author Robert Varga
*/
@Beta
-@NotThreadSafe
public final class ModifyTransactionRequestBuilder implements Builder<ModifyTransactionRequest>,
Identifiable<TransactionIdentifier> {
private final List<TransactionModification> modifications = new ArrayList<>(1);
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.NotThreadSafe;
+import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.checkerframework.checker.lock.qual.Holding;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.controller.cluster.access.concepts.Request;
import org.opendaylight.controller.cluster.access.concepts.RequestException;
/**
* Base class for a connection to the backend. Responsible to queueing and dispatch of requests toward the backend.
* Can be in three conceptual states: Connecting, Connected and Reconnecting, which are represented by public final
- * classes exposed from this package.
+ * classes exposed from this package. This class NOT thread-safe, not are its subclasses expected to be thread-safe.
*
* @author Robert Varga
*/
-@NotThreadSafe
public abstract class AbstractClientConnection<T extends BackendInfo> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractClientConnection.class);
}
}
- @GuardedBy("lock")
+ @Holding("lock")
private void commonEnqueue(final ConnectionEntry entry, final long now) {
final RequestException maybePoison = poisoned;
if (maybePoison != null) {
return queue.drain();
}
- @GuardedBy("lock")
+ @Holding("lock")
final void finishReplay(final ReconnectForwarder forwarder) {
setForwarder(forwarder);
lock.unlock();
}
- @GuardedBy("lock")
+ @Holding("lock")
final void setForwarder(final ReconnectForwarder forwarder) {
queue.setForwarder(forwarder, currentTime());
}
- @GuardedBy("lock")
+ @Holding("lock")
abstract ClientActorBehavior<T> lockedReconnect(ClientActorBehavior<T> current,
RequestException runtimeRequestException);
*
* @param delay Delay, in nanoseconds
*/
- @GuardedBy("lock")
+ @Holding("lock")
private void scheduleTimer(final long delay) {
if (haveTimer) {
LOG.debug("{}: timer already scheduled on {}", context.persistenceId(), this);
}
}
- @GuardedBy("lock")
+ @Holding("lock")
private void lockedPoison(final RequestException cause) {
poisoned = enrichPoison(cause);
queue.poison(cause);
package org.opendaylight.controller.cluster.access.client;
import java.util.concurrent.TimeUnit;
-import javax.annotation.concurrent.NotThreadSafe;
/**
* A ProgressTracker subclass which uses {@code ticksWorkedPerClosedTask} to compute delays.
* <p>On the other hand, there is no delay when number of open tasks is half the limit or less,
* in order to prevent backend from running out of tasks while there may be waiting frontend threads.
*
+ * <p>
+ * This class is NOT thread-safe.
+ *
* @author Vratko Polak
*/
-@NotThreadSafe
final class AveragingProgressTracker extends ProgressTracker {
private static final long DEFAULT_TICKS_PER_TASK = TimeUnit.MILLISECONDS.toNanos(500);
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.Holding;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.commands.NotLeaderException;
* @param newConn New connection
* @return ConnectionConnectCohort which will be used to complete the process of bringing the connection up.
*/
- @GuardedBy("connectionsLock")
+ @Holding("connectionsLock")
protected abstract @NonNull ConnectionConnectCohort connectionUp(@NonNull ConnectedClientConnection<T> newConn);
private void backendConnectFinished(final Long shard, final AbstractClientConnection<T> oldConn,
import com.google.common.annotations.Beta;
import com.google.common.base.Ticker;
import java.util.concurrent.TimeUnit;
-import javax.annotation.concurrent.ThreadSafe;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
import org.opendaylight.controller.cluster.common.actor.Dispatchers;
* <p>
* Time-keeping in a client actor is based on monotonic time. The precision of this time can be expected to be the
* same as {@link System#nanoTime()}, but it is not tied to that particular clock. Actor clock is exposed as
- * a {@link Ticker}, which can be obtained via {@link #ticker()}.
+ * a {@link Ticker}, which can be obtained via {@link #ticker()}. This class is thread-safe.
*
* @author Robert Varga
*/
@Beta
-@ThreadSafe
public class ClientActorContext extends AbstractClientActorContext implements Identifiable<ClientIdentifier> {
private final ExecutionContext executionContext;
private final ClientIdentifier identifier;
package org.opendaylight.controller.cluster.access.client;
import com.google.common.annotations.Beta;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.access.concepts.RequestException;
@Beta
-@NotThreadSafe
public final class ConnectedClientConnection<T extends BackendInfo> extends AbstractReceivingClientConnection<T> {
ConnectedClientConnection(final AbstractClientConnection<T> oldConnection, final T newBackend) {
package org.opendaylight.controller.cluster.access.client;
import com.google.common.base.Preconditions;
-import javax.annotation.concurrent.NotThreadSafe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* @author Vratko Polak
*/
// TODO: Would bulk methods be less taxing than a loop of single task calls?
-@NotThreadSafe
abstract class ProgressTracker {
private static final Logger LOG = LoggerFactory.getLogger(ProgressTracker.class);
import java.util.Iterator;
import java.util.Optional;
import java.util.Queue;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.access.concepts.Request;
import org.opendaylight.controller.cluster.access.concepts.RequestEnvelope;
import org.opendaylight.controller.cluster.access.concepts.RequestException;
*
* @author Robert Varga
*/
-@NotThreadSafe
abstract class TransmitQueue {
static final class Halted extends TransmitQueue {
// For ConnectingClientConnection.
}
@Override
- void preComplete(ResponseEnvelope<?> envelope) {
+ void preComplete(final ResponseEnvelope<?> envelope) {
}
}
}
@Override
- void preComplete(ResponseEnvelope<?> envelope) {
+ void preComplete(final ResponseEnvelope<?> envelope) {
if (envelope.getTxSequence() == currentSlicedEnvSequenceId) {
// Slicing completed for the prior request - clear the cached sequence id field to enable subsequent
// requests to be transmitted.
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>bundle-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>bundle-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
-import javax.annotation.concurrent.ThreadSafe;
/**
- * Registry of {@link CloseTracked} instances.
+ * Registry of {@link CloseTracked} instances. This class is thread-safe.
*
* @author Michael Vorburger.ch
*/
-@ThreadSafe
public class CloseTrackedRegistry<T extends CloseTracked<T>> {
private final Object anchor;
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>feature-repo-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>single-feature-parent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
import com.google.common.collect.ImmutableList;
import java.util.LinkedList;
import java.util.List;
-import javax.annotation.concurrent.NotThreadSafe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* }
*
* </pre>
+ *
+ * <p>
+ * This class is NOT thread-safe.
*/
@Beta
-@NotThreadSafe
public final class MessageTracker {
public abstract static class Context implements AutoCloseable {
Context() {
import com.google.common.annotations.Beta;
import java.util.Optional;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
/**
* Abstract {@link DataTreeModificationCursor} which tracks the current path. Subclasses can get the current path
- * via {@link #current()}.
+ * via {@link #current()}. This class is NOT thread-safe.
*
* @author Thomas Pantelis
*/
@Beta
-@NotThreadSafe
public abstract class AbstractDataTreeModificationCursor implements DataTreeModificationCursor {
private YangInstanceIdentifier current = YangInstanceIdentifier.EMPTY;
import java.nio.file.Files;
import java.util.Iterator;
import java.util.Set;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
+import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.checkerframework.checker.lock.qual.Holding;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.slf4j.Logger;
*
* @author Thomas Pantelis
*/
-@ThreadSafe
public class FileBackedOutputStream extends OutputStream {
private static final Logger LOG = LoggerFactory.getLogger(FileBackedOutputStream.class);
* @param fileDirectory the directory in which to create the file if needed. If null, the default temp file
* location is used.
*/
- public FileBackedOutputStream(int fileThreshold, @Nullable String fileDirectory) {
+ public FileBackedOutputStream(final int fileThreshold, @Nullable final String fileDirectory) {
this.fileThreshold = fileThreshold;
this.fileDirectory = fileDirectory;
}
@Override
@SuppressFBWarnings(value = "VO_VOLATILE_INCREMENT", justification = "Findbugs erroneously complains that the "
+ "increment of count needs to be atomic even though it is inside a synchronized block.")
- public synchronized void write(int value) throws IOException {
+ public synchronized void write(final int value) throws IOException {
possiblySwitchToFile(1);
out.write(value);
count++;
}
@Override
- public synchronized void write(byte[] bytes) throws IOException {
+ public synchronized void write(final byte[] bytes) throws IOException {
write(bytes, 0, bytes.length);
}
@Override
- public synchronized void write(byte[] bytes, int off, int len) throws IOException {
+ public synchronized void write(final byte[] bytes, final int off, final int len) throws IOException {
possiblySwitchToFile(len);
out.write(bytes, off, len);
count += len;
}
}
- @GuardedBy("this")
+ @Holding("this")
private void closeQuietly() {
try {
close();
/**
* Checks if writing {@code len} bytes would go over threshold, and switches to file buffering if so.
*/
- @GuardedBy("this")
- private void possiblySwitchToFile(int len) throws IOException {
+ @Holding("this")
+ private void possiblySwitchToFile(final int len) throws IOException {
if (out == null) {
throw new IOException("Stream already closed");
}
}
}
- private static void deleteFile(File file) {
+ private static void deleteFile(final File file) {
if (!file.delete()) {
LOG.warn("Could not delete temp file {}", file);
}
private static class Cleanup extends FinalizablePhantomReference<FileBackedOutputStream> {
private final File file;
- Cleanup(FileBackedOutputStream referent, File file) {
+ Cleanup(final FileBackedOutputStream referent, final File file) {
super(referent, REFERENCE_QUEUE);
this.file = file;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.util.Arrays;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.io.FileBackedOutputStream;
import org.opendaylight.controller.cluster.io.FileBackedOutputStreamFactory;
import org.opendaylight.yangtools.concepts.Identifier;
import org.slf4j.LoggerFactory;
/**
- * Maintains the state of an assembled message.
+ * Maintains the state of an assembled message. This class is NOT thread-safe.
*
* @author Thomas Pantelis
*/
-@NotThreadSafe
public class AssembledMessageState implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(AssembledMessageState.class);
import java.io.InputStream;
import java.util.Arrays;
import java.util.function.Consumer;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.io.FileBackedOutputStream;
import org.opendaylight.yangtools.concepts.Identifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Maintains the state of a sliced message.
+ * Maintains the state of a sliced message. This class is NOT thread-safe.
*
* @author Thomas Pantelis
* @see MessageSlicer
*/
-@NotThreadSafe
public class SlicedMessageState<T> implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(SlicedMessageState.class);
* @param index the slice index to test
* @return true if the index is the last slice, false otherwise
*/
- public boolean isLastSlice(int index) {
+ public boolean isLastSlice(final int index) {
return totalSlices == index;
}
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<dependencies>
<!-- Java -->
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
*/
package org.opendaylight.controller.cluster.databroker;
-import com.google.common.base.Preconditions;
+import static java.util.Objects.requireNonNull;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
import org.opendaylight.controller.cluster.databroker.actors.dds.AbstractClientHandle;
import org.opendaylight.controller.cluster.databroker.actors.dds.ClientLocalHistory;
private final boolean debugAllocation;
ClientBackedTransactionChain(final ClientLocalHistory history, final boolean debugAllocation) {
- this.history = Preconditions.checkNotNull(history);
+ this.history = requireNonNull(history);
this.debugAllocation = debugAllocation;
}
*/
package org.opendaylight.controller.cluster.databroker.actors.dds;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.concurrent.locks.StampedLock;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.access.client.AbstractClientConnection;
import org.opendaylight.controller.cluster.access.client.ConnectedClientConnection;
import org.opendaylight.controller.cluster.access.client.ConnectionEntry;
private volatile State state = State.IDLE;
AbstractClientHistory(final AbstractDataStoreClientBehavior client, final LocalHistoryIdentifier identifier) {
- this.client = Preconditions.checkNotNull(client);
- this.identifier = Preconditions.checkNotNull(identifier);
- Preconditions.checkArgument(identifier.getCookie() == 0);
+ this.client = requireNonNull(client);
+ this.identifier = requireNonNull(identifier);
+ checkArgument(identifier.getCookie() == 0);
}
final State state() {
final void updateState(final State expected, final State next) {
final boolean success = STATE_UPDATER.compareAndSet(this, expected, next);
- Preconditions.checkState(success, "Race condition detected, state changed from %s to %s", expected, state);
+ checkState(success, "Race condition detected, state changed from %s to %s", expected, state);
LOG.debug("Client history {} changed state from {} to {}", this, expected, next);
}
final synchronized void doClose() {
final State local = state;
if (local != State.CLOSED) {
- Preconditions.checkState(local == State.IDLE, "Local history %s has an open transaction", this);
+ checkState(local == State.IDLE, "Local history %s has an open transaction", this);
histories.values().forEach(ProxyHistory::close);
updateState(local, State.CLOSED);
}
}
final AbstractTransactionCommitCohort previous = readyTransactions.putIfAbsent(txId, cohort);
- Preconditions.checkState(previous == null, "Duplicate cohort %s for transaction %s, already have %s",
- cohort, txId, previous);
+ checkState(previous == null, "Duplicate cohort %s for transaction %s, already have %s", cohort, txId, previous);
LOG.debug("Local history {} readied transaction {}", this, txId);
return cohort;
return null;
}
- final ProxyReconnectCohort proxy = Verify.verifyNotNull(oldProxy.startReconnect(newConn));
+ final ProxyReconnectCohort proxy = verifyNotNull(oldProxy.startReconnect(newConn));
return new HistoryReconnectCohort() {
@Override
ProxyReconnectCohort getProxy() {
*/
package org.opendaylight.controller.cluster.databroker.actors.dds;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Verify.verify;
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
import akka.actor.ActorRef;
import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.function.Consumer;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.NotThreadSafe;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.client.ConnectionEntry;
abstract class AbstractProxyTransaction implements Identifiable<TransactionIdentifier> {
/**
* Marker object used instead of read-type of requests, which are satisfied only once. This has a lower footprint
- * and allows compressing multiple requests into a single entry.
+ * and allows compressing multiple requests into a single entry. This class is not thread-safe.
*/
- @NotThreadSafe
private static final class IncrementSequence {
private final long sequence;
private long delta = 0;
private final String string;
State(final String string) {
- this.string = Preconditions.checkNotNull(string);
+ this.string = requireNonNull(string);
}
@Override
}
State getPrevState() {
- return Verify.verifyNotNull(prevState, "Attempted to access previous state, which was not set");
+ return verifyNotNull(prevState, "Attempted to access previous state, which was not set");
}
void setPrevState(final State prevState) {
- Verify.verify(this.prevState == null, "Attempted to set previous state to %s when we already have %s",
- prevState, this.prevState);
- this.prevState = Preconditions.checkNotNull(prevState);
+ verify(this.prevState == null, "Attempted to set previous state to %s when we already have %s", prevState,
+ this.prevState);
+ this.prevState = requireNonNull(prevState);
// We cannot have duplicate successor states, so this check is sufficient
this.done = DONE.equals(prevState);
}
// To be called from safe contexts, where successor is known to be completed
AbstractProxyTransaction getSuccessor() {
- return Verify.verifyNotNull(successor);
+ return verifyNotNull(successor);
}
void setSuccessor(final AbstractProxyTransaction successor) {
- Verify.verify(this.successor == null, "Attempted to set successor to %s when we already have %s",
- successor, this.successor);
- this.successor = Preconditions.checkNotNull(successor);
+ verify(this.successor == null, "Attempted to set successor to %s when we already have %s", successor,
+ this.successor);
+ this.successor = requireNonNull(successor);
}
boolean isDone() {
private volatile State state;
AbstractProxyTransaction(final ProxyHistory parent, final boolean isDone) {
- this.parent = Preconditions.checkNotNull(parent);
+ this.parent = requireNonNull(parent);
if (isDone) {
state = DONE;
// DONE implies previous seal operation completed
final void seal() {
// Transition user-visible state first
final boolean success = markSealed();
- Preconditions.checkState(success, "Proxy %s was already sealed", getIdentifier());
+ checkState(success, "Proxy %s was already sealed", getIdentifier());
if (!sealAndSend(Optional.empty())) {
sealSuccessor();
}
private void checkNotSealed() {
- Preconditions.checkState(sealed == 0, "Transaction %s has already been sealed", getIdentifier());
+ checkState(sealed == 0, "Transaction %s has already been sealed", getIdentifier());
}
private void checkSealed() {
- Preconditions.checkState(sealed != 0, "Transaction %s has not been sealed yet", getIdentifier());
+ checkState(sealed != 0, "Transaction %s has not been sealed yet", getIdentifier());
}
private SuccessorState getSuccessorState() {
final State local = state;
- Verify.verify(local instanceof SuccessorState, "State %s has unexpected class", local);
+ verify(local instanceof SuccessorState, "State %s has unexpected class", local);
return (SuccessorState) local;
}
}
final void recordSuccessfulRequest(final @NonNull TransactionRequest<?> req) {
- successfulRequests.add(Verify.verifyNotNull(req));
+ successfulRequests.add(verifyNotNull(req));
}
final void recordFinishedRequest(final Response<?, ?> response) {
synchronized (this) {
if (STATE_UPDATER.compareAndSet(this, SEALED, FLUSHED)) {
final SettableFuture<Boolean> ret = SettableFuture.create();
- sendRequest(Verify.verifyNotNull(commitRequest(false)), t -> {
+ sendRequest(verifyNotNull(commitRequest(false)), t -> {
if (t instanceof TransactionCommitSuccess) {
ret.set(Boolean.TRUE);
} else if (t instanceof RequestFailure) {
// Precludes startReconnect() from interfering with the fast path
synchronized (this) {
if (STATE_UPDATER.compareAndSet(this, SEALED, FLUSHED)) {
- final TransactionRequest<?> req = Verify.verifyNotNull(commitRequest(true));
+ final TransactionRequest<?> req = verifyNotNull(commitRequest(true));
sendRequest(req, t -> {
if (t instanceof TransactionCanCommitSuccess) {
final State prevState = STATE_UPDATER.getAndSet(this, nextState);
LOG.debug("Start reconnect of proxy {} previous state {}", this, prevState);
- Verify.verify(!(prevState instanceof SuccessorState), "Proxy %s duplicate reconnect attempt after %s", this,
+ verify(!(prevState instanceof SuccessorState), "Proxy %s duplicate reconnect attempt after %s", this,
prevState);
// We have asserted a slow-path state, seal(), canCommit(), directCommit() are forced to slow paths, which will
LOG.debug("Forwarding successful request {} to successor {}", obj, successor);
successor.doReplayRequest((TransactionRequest<?>) obj, resp -> { /*NOOP*/ }, now);
} else {
- Verify.verify(obj instanceof IncrementSequence);
+ verify(obj instanceof IncrementSequence);
final IncrementSequence increment = (IncrementSequence) obj;
successor.doReplayRequest(new IncrementTransactionSequenceRequest(getIdentifier(),
increment.getSequence(), localActor(), isSnapshotOnly(),
final Request<?, ?> req = e.getRequest();
if (getIdentifier().equals(req.getTarget())) {
- Verify.verify(req instanceof TransactionRequest, "Unhandled request %s", req);
+ verify(req instanceof TransactionRequest, "Unhandled request %s", req);
LOG.debug("Replaying queued request {} to successor {}", req, successor);
successor.doReplayRequest((TransactionRequest<?>) req, e.getCallback(), e.getEnqueuedTicks());
it.remove();
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.ABIVersion;
* shard is assigned a single cookie and this mapping is stored in a bidirectional map. Information about corresponding
* shard leader is resolved via {@link ActorUtils}. The product of resolution is {@link ShardBackendInfo}.
*
+ * <p>
+ * This class is thread-safe.
+ *
* @author Robert Varga
*/
-@ThreadSafe
abstract class AbstractShardBackendResolver extends BackendInfoResolver<ShardBackendInfo> {
static final class ShardState {
private final CompletionStage<ShardBackendInfo> stage;
import com.google.common.util.concurrent.FluentFuture;
import java.util.Optional;
import java.util.function.Consumer;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.commands.AbortLocalTransactionRequest;
/**
* An {@link AbstractProxyTransaction} for dispatching a transaction towards a shard leader which is co-located with
- * the client instance.
+ * the client instance. This class is NOT thread-safe.
*
* <p>
* It requires a {@link DataTreeSnapshot}, which is used to instantiated a new {@link DataTreeModification}. Operations
*
* @author Robert Varga
*/
-@NotThreadSafe
abstract class LocalProxyTransaction extends AbstractProxyTransaction {
private static final Logger LOG = LoggerFactory.getLogger(LocalProxyTransaction.class);
*/
package org.opendaylight.controller.cluster.databroker.actors.dds;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Verify.verify;
+import static java.util.Objects.requireNonNull;
+
import java.util.Optional;
import java.util.function.Consumer;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.access.commands.CommitLocalTransactionRequest;
import org.opendaylight.controller.cluster.access.commands.ModifyTransactionRequest;
import org.opendaylight.controller.cluster.access.commands.PersistenceProtocol;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
/**
- * A read-only specialization of {@link LocalProxyTransaction}.
+ * A read-only specialization of {@link LocalProxyTransaction}. This class is NOT thread-safe.
*
* @author Robert Varga
*/
-@NotThreadSafe
final class LocalReadOnlyProxyTransaction extends LocalProxyTransaction {
private final DataTreeSnapshot snapshot;
LocalReadOnlyProxyTransaction(final ProxyHistory parent, final TransactionIdentifier identifier,
final DataTreeSnapshot snapshot) {
super(parent, identifier, false);
- this.snapshot = Preconditions.checkNotNull(snapshot);
+ this.snapshot = requireNonNull(snapshot);
}
LocalReadOnlyProxyTransaction(final ProxyHistory parent, final TransactionIdentifier identifier) {
@Override
DataTreeSnapshot readOnlyView() {
- return Preconditions.checkNotNull(snapshot, "Transaction %s is DONE", getIdentifier());
+ return checkNotNull(snapshot, "Transaction %s is DONE", getIdentifier());
}
@Override
}
private static void commonModifyTransactionRequest(final ModifyTransactionRequest request) {
- Verify.verify(request.getModifications().isEmpty());
+ verify(request.getModifications().isEmpty());
final PersistenceProtocol protocol = request.getPersistenceProtocol().get();
- Verify.verify(protocol == PersistenceProtocol.ABORT);
+ verify(protocol == PersistenceProtocol.ABORT);
}
}
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.commands.AbortLocalTransactionRequest;
/**
* An {@link AbstractProxyTransaction} for dispatching a transaction towards a shard leader which is co-located with
- * the client instance.
+ * the client instance. This class is NOT thread-safe.
*
* <p>
* It requires a {@link DataTreeSnapshot}, which is used to instantiated a new {@link DataTreeModification}. Operations
*
* @author Robert Varga
*/
-@NotThreadSafe
final class LocalReadWriteProxyTransaction extends LocalProxyTransaction {
private static final Logger LOG = LoggerFactory.getLogger(LocalReadWriteProxyTransaction.class);
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.access.client.BackendInfoResolver;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
import org.opendaylight.controller.cluster.datastore.shardmanager.RegisterForShardAvailabilityChanges;
* shard is assigned a single cookie and this mapping is stored in a bidirectional map. Information about corresponding
* shard leader is resolved via {@link ActorUtils}. The product of resolution is {@link ShardBackendInfo}.
*
+ * <p>
+ * This class is thread-safe.
+ *
* @author Robert Varga
*/
-@ThreadSafe
final class ModuleShardBackendResolver extends AbstractShardBackendResolver {
private static final Logger LOG = LoggerFactory.getLogger(ModuleShardBackendResolver.class);
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.checkerframework.checker.lock.qual.Holding;
import org.opendaylight.controller.cluster.access.client.AbstractClientConnection;
import org.opendaylight.controller.cluster.access.client.ClientActorContext;
import org.opendaylight.controller.cluster.access.client.ConnectedClientConnection;
return identifier;
}
- @GuardedBy("lock")
+ @Holding("lock")
@Override
void replayRequests(final Collection<ConnectionEntry> previousEntries) {
// First look for our Create message
LOG.debug("Proxy {} purge completed with {}", this, response);
}
- @GuardedBy("lock")
+ @Holding("lock")
void onTransactionAborted(final AbstractProxyTransaction tx) {
// No-op for most implementations
}
- @GuardedBy("lock")
+ @Holding("lock")
void onTransactionCompleted(final AbstractProxyTransaction tx) {
// No-op for most implementations
}
import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedLong;
import java.util.Optional;
-import javax.annotation.concurrent.ThreadSafe;
import org.opendaylight.controller.cluster.access.ABIVersion;
import org.opendaylight.controller.cluster.access.client.BackendInfo;
import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
/**
* Combined backend tracking. Aside from usual {@link BackendInfo}, this object also tracks the cookie assigned
- * to the shard. This assignment remains constant for as long as the client is not restarted.
+ * to the shard. This assignment remains constant for as long as the client is not restarted. This class is thread-safe.
*
* @author Robert Varga
*/
-@ThreadSafe
final class ShardBackendInfo extends BackendInfo {
private final Optional<DataTree> dataTree;
private final UnsignedLong cookie;
import static java.util.Objects.requireNonNull;
import java.util.concurrent.CompletionStage;
-import javax.annotation.concurrent.ThreadSafe;
import org.opendaylight.controller.cluster.access.client.BackendInfoResolver;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
/**
* {@link BackendInfoResolver} implementation for static shard configuration based on ShardManager. Unlike the full
* {@link ModuleShardBackendResolver}, this resolver is used in situations where the client corresponds exactly to one
- * backend shard, e.g. there is only one fixed cookie assigned and the operation path is not consulted at all.
+ * backend shard, e.g. there is only one fixed cookie assigned and the operation path is not consulted at all. This
+ * class is thread-safe.
*
* @author Robert Varga
*/
-@ThreadSafe
final class SimpleShardBackendResolver extends AbstractShardBackendResolver {
private static final Logger LOG = LoggerFactory.getLogger(SimpleShardBackendResolver.class);
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.checkerframework.checker.lock.qual.Holding;
/**
* An {@link AbstractFuture} implementation which requires a certain number of votes before it completes. If all votes
return votes == 0;
}
- @GuardedBy("failures")
+ @Holding("failures")
private void resolveResult() {
final Iterator<Throwable> it = failures.iterator();
if (!it.hasNext()) {
import akka.actor.ActorRef;
import akka.actor.Props;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.common.actor.Dispatchers;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.slf4j.Logger;
/**
* Abstract base class for a ShardDataTreeNotificationPublisher that offloads the generation and publication
- * of data tree notifications to an actor.
+ * of data tree notifications to an actor. This class is NOT thread-safe.
*
* @author Thomas Pantelis
*/
-@NotThreadSafe
abstract class AbstractShardDataTreeNotificationPublisherActorProxy implements ShardDataTreeNotificationPublisher {
@SuppressFBWarnings("SLF4J_LOGGER_SHOULD_BE_PRIVATE")
protected final Logger log = LoggerFactory.getLogger(getClass());
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
import org.opendaylight.controller.cluster.datastore.persisted.AbortTransactionPayload;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
/**
- * Abstract base for transactions running on SharrdDataTree.
+ * Abstract base for transactions running on SharrdDataTree. This class is NOT thread-safe.
*
* @param <T> Backing transaction type.
*/
-@NotThreadSafe
abstract class AbstractShardDataTreeTransaction<T extends DataTreeSnapshot>
implements Identifiable<TransactionIdentifier> {
private final ShardDataTreeTransactionParent parent;
import akka.actor.PoisonPill;
import akka.dispatch.OnComplete;
import com.google.common.annotations.VisibleForTesting;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.datastore.exceptions.LocalShardNotFoundException;
import org.opendaylight.controller.cluster.datastore.messages.CloseDataTreeNotificationListenerRegistration;
import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCandidate;
/**
* Registry of user commit cohorts, which is responsible for handling registration and calculation
- * of affected cohorts based on {@link DataTreeCandidate}.
+ * of affected cohorts based on {@link DataTreeCandidate}. This class is NOT thread-safe.
*
*/
-@NotThreadSafe
class DataTreeCohortActorRegistry extends AbstractRegistrationTree<ActorRef> {
private static final Logger LOG = LoggerFactory.getLogger(DataTreeCohortActorRegistry.class);
import akka.pattern.Patterns;
import akka.util.Timeout;
import java.util.concurrent.TimeUnit;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.datastore.exceptions.LocalShardNotFoundException;
import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
*/
package org.opendaylight.controller.cluster.datastore;
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Primitives;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import javax.annotation.concurrent.GuardedBy;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.WordUtils;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.datastore.DatastoreContext.Builder;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
@SuppressWarnings("checkstyle:IllegalCatch")
private static void processDataStoreProperty(final String name, final Class<?> propertyType,
final Method readMethod) {
- Preconditions.checkArgument(BUILDER_SETTERS.containsKey(name), String.format(
+ checkArgument(BUILDER_SETTERS.containsKey(name),
"DataStoreProperties property \"%s\" does not have corresponding setter in DatastoreContext.Builder",
- name));
+ name);
try {
processPropertyType(propertyType);
DATA_STORE_PROP_INFO.put(name, new SimpleImmutableEntry<>(propertyType, readMethod));
import com.google.common.base.Optional;
import java.util.Collection;
import java.util.function.Consumer;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
import org.opendaylight.mdsal.dom.spi.AbstractDOMDataTreeChangeListenerRegistration;
import org.opendaylight.mdsal.dom.spi.store.AbstractDOMStoreTreeChangePublisher;
/**
* Default implementation of ShardDataTreeChangeListenerPublisher that directly generates and publishes
- * notifications for DataTreeChangeListeners.
+ * notifications for DataTreeChangeListeners. This class is NOT thread-safe.
*
* @author Thomas Pantelis
*/
-@NotThreadSafe
final class DefaultShardDataTreeChangeListenerPublisher extends AbstractDOMStoreTreeChangePublisher
implements ShardDataTreeChangeListenerPublisher {
private static final Logger LOG = LoggerFactory.getLogger(DefaultShardDataTreeChangeListenerPublisher.class);
import akka.actor.ActorRef;
import java.util.EventListener;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import com.google.common.collect.Collections2;
import java.util.HashMap;
import java.util.Map;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-@NotThreadSafe
+/**
+ * This class is NOT thread-safe.
+ */
final class FrontendClientMetadataBuilder implements Builder<FrontendClientMetadata>, Identifiable<ClientIdentifier> {
private static final Logger LOG = LoggerFactory.getLogger(FrontendClientMetadataBuilder.class);
import com.google.common.collect.Maps;
import java.util.HashMap;
import java.util.Map;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
import org.opendaylight.controller.cluster.access.concepts.FrontendIdentifier;
/**
* Frontend state as observed by a shard follower. This class is responsible for maintaining metadata state
* so that this can be used to seed {@link LeaderFrontendState} with proper state so that the frontend/backend
- * conversation can continue where it left off.
+ * conversation can continue where it left off. This class is NOT thread-safe.
*
* @author Robert Varga
*/
-@NotThreadSafe
final class FrontendMetadata extends ShardDataTreeMetadata<FrontendShardDataTreeSnapshotMetadata> {
private static final Logger LOG = LoggerFactory.getLogger(FrontendMetadata.class);
import static java.util.Objects.requireNonNull;
import java.util.Optional;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.access.commands.ExistsTransactionRequest;
import org.opendaylight.controller.cluster.access.commands.ExistsTransactionSuccess;
import org.opendaylight.controller.cluster.access.commands.ModifyTransactionRequest;
import org.slf4j.LoggerFactory;
/**
- * Read-only frontend transaction state as observed by the shard leader.
+ * Read-only frontend transaction state as observed by the shard leader. This class is NOT thread-safe.
*
* @author Robert Varga
*/
-@NotThreadSafe
final class FrontendReadOnlyTransaction extends FrontendTransaction {
private static final Logger LOG = LoggerFactory.getLogger(FrontendReadOnlyTransaction.class);
import com.google.common.util.concurrent.FutureCallback;
import java.util.Collection;
import java.util.Optional;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.commands.AbortLocalTransactionRequest;
import org.opendaylight.controller.cluster.access.commands.CommitLocalTransactionRequest;
import org.slf4j.LoggerFactory;
/**
- * Frontend read-write transaction state as observed by the shard leader.
+ * Frontend read-write transaction state as observed by the shard leader. This class is NOT thread-safe.
*
* @author Robert Varga
*/
-@NotThreadSafe
final class FrontendReadWriteTransaction extends FrontendTransaction {
private enum CommitStage {
READY,
import java.util.ArrayDeque;
import java.util.Optional;
import java.util.Queue;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.commands.IncrementTransactionSequenceRequest;
import org.opendaylight.controller.cluster.access.commands.IncrementTransactionSequenceSuccess;
import org.slf4j.LoggerFactory;
/**
- * Frontend common transaction state as observed by the shard leader.
+ * Frontend common transaction state as observed by the shard leader. This class is NOT thread-safe.
*
* @author Robert Varga
*/
-@NotThreadSafe
abstract class FrontendTransaction implements Identifiable<TransactionIdentifier> {
private static final Logger LOG = LoggerFactory.getLogger(FrontendTransaction.class);
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.commands.CreateLocalHistoryRequest;
import org.opendaylight.controller.cluster.access.commands.DeadHistoryException;
/**
* Frontend state as observed by the shard leader. This class is responsible for tracking generations and sequencing
- * in the frontend/backend conversation.
+ * in the frontend/backend conversation. This class is NOT thread-safe.
*
* @author Robert Varga
*/
-@NotThreadSafe
final class LeaderFrontendState implements Identifiable<ClientIdentifier> {
private static final Logger LOG = LoggerFactory.getLogger(LeaderFrontendState.class);
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.UnaryOperator;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
import scala.concurrent.duration.FiniteDuration;
/**
- * Internal shard state, similar to a DOMStore, but optimized for use in the actor system,
- * e.g. it does not expose public interfaces and assumes it is only ever called from a
- * single thread.
+ * Internal shard state, similar to a DOMStore, but optimized for use in the actor system, e.g. it does not expose
+ * public interfaces and assumes it is only ever called from a single thread.
*
* <p>
- * This class is not part of the API contract and is subject to change at any time.
+ * This class is not part of the API contract and is subject to change at any time. It is NOT thread-safe.
*/
-@NotThreadSafe
public class ShardDataTree extends ShardDataTreeTransactionParent {
private static final class CommitEntry {
final SimpleShardDataTreeCohort cohort;
import akka.actor.Props;
import com.google.common.base.Optional;
import java.util.function.Consumer;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
/**
- * Implementation of ShardDataTreeChangeListenerPublisher that offloads the generation and publication
- * of data tree change notifications to an actor.
+ * Implementation of ShardDataTreeChangeListenerPublisher that offloads the generation and publication of data tree
+ * change notifications to an actor. This class is NOT thread-safe.
*
* @author Thomas Pantelis
*/
-@NotThreadSafe
class ShardDataTreeChangeListenerPublisherActorProxy extends AbstractShardDataTreeNotificationPublisherActorProxy
implements ShardDataTreeChangeListenerPublisher {
import com.google.common.base.Preconditions;
import java.util.Optional;
import java.util.SortedSet;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.slf4j.LoggerFactory;
/**
- * A transaction chain attached to a Shard.
+ * A transaction chain attached to a Shard. This class is NOT thread-safe.
*/
-@NotThreadSafe
final class ShardDataTreeTransactionChain extends ShardDataTreeTransactionParent
implements Identifiable<LocalHistoryIdentifier> {
import java.util.Optional;
import java.util.SortedSet;
import java.util.concurrent.TimeUnit;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
import org.slf4j.Logger;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
+import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.checkerframework.checker.lock.qual.Holding;
import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
import org.slf4j.LoggerFactory;
/**
- * Manages EntityOwnershipListener registrations and notifications for the EntityOwnershipShard.
+ * Manages EntityOwnershipListener registrations and notifications for the EntityOwnershipShard. This class is
+ * thread-safe.
*
* @author Thomas Pantelis
*/
-@ThreadSafe
class EntityOwnershipListenerSupport extends EntityOwnershipChangePublisher {
private static final Logger LOG = LoggerFactory.getLogger(EntityOwnershipListenerSupport.class);
}
}
- @GuardedBy("listenerLock")
+ @Holding("listenerLock")
private void notifyListeners(final DOMEntity entity, final boolean wasOwner, final boolean isOwner,
final boolean hasOwner, final Collection<ListenerActorRefEntry> listenerEntries) {
DOMEntityOwnershipChange changed = new DOMEntityOwnershipChange(entity,
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.datastore.Shard;
import org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot;
*/
package org.opendaylight.controller.cluster.datastore.messages;
-import com.google.common.base.Preconditions;
+import static java.util.Objects.requireNonNull;
+
import java.util.Optional;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.notifications.LeaderStateChanged;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
private final DataTree localShardDataTree;
- public ShardLeaderStateChanged(@Nonnull String memberId, @Nullable String leaderId,
- @Nonnull DataTree localShardDataTree, short leaderPayloadVersion) {
+ public ShardLeaderStateChanged(@NonNull String memberId, @Nullable String leaderId,
+ @NonNull DataTree localShardDataTree, short leaderPayloadVersion) {
super(memberId, leaderId, leaderPayloadVersion);
- this.localShardDataTree = Preconditions.checkNotNull(localShardDataTree);
+ this.localShardDataTree = requireNonNull(localShardDataTree);
}
- public ShardLeaderStateChanged(@Nonnull String memberId, @Nullable String leaderId,
+ public ShardLeaderStateChanged(@NonNull String memberId, @Nullable String leaderId,
short leaderPayloadVersion) {
super(memberId, leaderId, leaderPayloadVersion);
this.localShardDataTree = null;
}
- @Nonnull
- public Optional<DataTree> getLocalShardDataTree() {
+ public @NonNull Optional<DataTree> getLocalShardDataTree() {
return Optional.ofNullable(localShardDataTree);
}
}
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.databroker.actors.dds.DataStoreClient;
import org.opendaylight.controller.cluster.datastore.AbstractDataStore;
import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.databroker.actors.dds.DataStoreClient;
import org.opendaylight.controller.cluster.datastore.AbstractDataStore;
import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
import org.opendaylight.controller.cluster.ActorSystemProvider;
import org.opendaylight.controller.cluster.access.concepts.MemberName;
import org.opendaylight.controller.cluster.databroker.actors.dds.DataStoreClient;
import akka.actor.ActorRef;
import akka.actor.Status;
-import javax.annotation.concurrent.NotThreadSafe;
import org.eclipse.jdt.annotation.Nullable;
/**
- * Base class for lookup tasks. Lookup tasks are supposed to run repeatedly
- * until successful lookup or maximum retries are hit.
+ * Base class for lookup tasks. Lookup tasks are supposed to run repeatedly until successful lookup or maximum retries
+ * are hit. This class is NOT thread-safe.
*/
-@NotThreadSafe
abstract class LookupTask implements Runnable {
private final int maxRetries;
private final ActorRef replyTo;
*/
package org.opendaylight.controller.cluster.databroker.actors.dds;
-import static org.hamcrest.CoreMatchers.both;
+import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.core.Is.isA;
import static org.mockito.Mockito.mock;
protected void checkModifications(final ModifyTransactionRequest modifyRequest) {
final List<TransactionModification> modifications = modifyRequest.getModifications();
Assert.assertEquals(3, modifications.size());
- Assert.assertThat(modifications, hasItem(both(isA(TransactionWrite.class)).and(hasPath(PATH_1))));
- Assert.assertThat(modifications, hasItem(both(isA(TransactionMerge.class)).and(hasPath(PATH_2))));
- Assert.assertThat(modifications, hasItem(both(isA(TransactionDelete.class)).and(hasPath(PATH_3))));
+ Assert.assertThat(modifications, hasItem(allOf(isA(TransactionWrite.class), hasPath(PATH_1))));
+ Assert.assertThat(modifications, hasItem(allOf(isA(TransactionMerge.class), hasPath(PATH_2))));
+ Assert.assertThat(modifications, hasItem(allOf(isA(TransactionDelete.class), hasPath(PATH_3))));
}
@SuppressWarnings("checkstyle:hiddenField")
import java.util.Map.Entry;
import java.util.concurrent.CancellationException;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import javax.annotation.concurrent.GuardedBy;
+import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.checkerframework.checker.lock.qual.Holding;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
* this method has completed executing. Also inflightTx may be updated outside
* the lock, hence we need to re-check.
*/
- @GuardedBy("this")
+ @Holding("this")
private void processIfReady() {
if (inflightTx == null) {
final PingPongTransaction tx = READY_UPDATER.getAndSet(this, null);
*
* @param tx Transaction which needs processing.
*/
- @GuardedBy("this")
+ @Holding("this")
private void processTransaction(final @NonNull PingPongTransaction tx) {
if (failed) {
LOG.debug("Cancelling transaction {}", tx);
import com.google.common.util.concurrent.SettableFuture;
import java.util.Map;
import java.util.Queue;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
* subtree in conceptual data tree. We define this subtree by first write
* operation performed on transaction. All next read and write operations
* should be performed just in this initial subtree.
+ *
*/
// FIXME explicitly enforce just one subtree requirement
-@NotThreadSafe
class ShardedDOMDataBrokerDelegatingReadWriteTransaction implements DOMDataReadWriteTransaction {
private final DOMDataReadOnlyTransaction readTxDelegate;
private final DOMDataWriteTransaction writeTxDelegate;
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent-lite</artifactId>
- <version>4.0.9</version>
+ <version>5.0.0</version>
<relativePath/>
</parent>
<groupId>org.opendaylight.controller</groupId>