</dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
<scm>
<connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
import javax.annotation.Nullable;
/**
- * Base behavior attached to {@link AbstractClientActor}. Exposes
- * @author user
+ * Base behavior attached to {@link AbstractClientActor}.
*
* @param <C> Type of associated context
*
public abstract class AbstractClientActorBehavior<C extends AbstractClientActorContext> {
private final C context;
- AbstractClientActorBehavior(final @Nonnull C context) {
+ AbstractClientActorBehavior(@Nonnull final C context) {
// Hidden to prevent outside subclasses. Users instantiated this via ClientActorBehavior
this.context = Preconditions.checkNotNull(context);
}
*
* @return A client actor context instance.
*/
- protected final @Nonnull C context() {
+ @Nonnull
+ protected final C context() {
return context;
}
*
* @return Persistence identifier
*/
- protected final @Nonnull String persistenceId() {
+ @Nonnull
+ protected final String persistenceId() {
return context.persistenceId();
}
*
* @return Actor associated with this behavior
*/
- public final @Nonnull ActorRef self() {
+ @Nonnull
+ public final ActorRef self() {
return context.self();
}
* @param command Command message
* @return Behavior which should be used with the next message. Return null if this actor should shut down.
*/
- abstract @Nullable AbstractClientActorBehavior<?> onReceiveCommand(@Nonnull Object command);
+ @Nullable
+ abstract AbstractClientActorBehavior<?> onReceiveCommand(@Nonnull Object command);
/**
* Implementation-internal method for handling an incoming recovery message coming from persistence.
* @param recover Recover message
* @return Behavior which should be used with the next message. Return null if this actor should shut down.
*/
- abstract @Nullable AbstractClientActorBehavior<?> onReceiveRecover(@Nonnull Object recover);
+ @Nullable
+ abstract AbstractClientActorBehavior<?> onReceiveRecover(@Nonnull Object recover);
}
import org.opendaylight.yangtools.concepts.Mutable;
/**
- * Common, externally-invisible superclass of contexts associated with a {@link AbstractClientActor}. End users pass this
- * object via opaque {@link ClientActorContext}.
+ * Common, externally-invisible superclass of contexts associated with a {@link AbstractClientActor}. End users pass
+ * this object via opaque {@link ClientActorContext}.
*
* @author Robert Varga
*/
private final String persistenceId;
private final ActorRef self;
- AbstractClientActorContext(final @Nonnull ActorRef self, final @Nonnull String persistenceId) {
+ AbstractClientActorContext(@Nonnull final ActorRef self, @Nonnull final String persistenceId) {
this.persistenceId = Preconditions.checkNotNull(persistenceId);
this.self = Preconditions.checkNotNull(self);
}
- final @Nonnull String persistenceId() {
+ @Nonnull
+ final String persistenceId() {
return persistenceId;
}
- public final @Nonnull ActorRef self() {
+ @Nonnull
+ public final ActorRef self() {
return self;
}
}
* Basic information about how to talk to the backend. ClientActorBehavior uses this information to dispatch requests
* to the backend.
*
+ * <p>
* This class is not final so concrete actor behavior implementations may subclass it and track more information about
* the backend. The {@link #hashCode()} and {@link #equals(Object)} methods are made final to ensure subclasses compare
* on identity.
* @param cookie Backend cookie
* @param info Previous information to be invalidated
*/
- public final void invalidateBackend(final long cookie, final @Nonnull CompletionStage<? extends BackendInfo> info) {
+ public final void invalidateBackend(final long cookie, @Nonnull final CompletionStage<? extends BackendInfo> info) {
if (backends.remove(cookie, Preconditions.checkNotNull(info))) {
LOG.trace("Invalidated cache %s -> %s", Long.toUnsignedString(cookie), info);
invalidateBackendInfo(info);
* @param cookie Backend cookie
* @return A {@link CompletableFuture} resulting in information about the backend
*/
- protected abstract @Nonnull CompletableFuture<T> resolveBackendInfo(final @Nonnull Long cookie);
+ @Nonnull
+ protected abstract CompletableFuture<T> resolveBackendInfo(@Nonnull final Long cookie);
/**
* Invalidate previously-resolved shard information. This method is invoked when a timeout is detected
implements Identifiable<ClientIdentifier> {
private static final Logger LOG = LoggerFactory.getLogger(ClientActorBehavior.class);
- protected ClientActorBehavior(final @Nonnull ClientActorContext context) {
+ protected ClientActorBehavior(@Nonnull final ClientActorContext context) {
super(context);
}
@Override
- public final @Nonnull ClientIdentifier getIdentifier() {
+ @Nonnull
+ public final ClientIdentifier getIdentifier() {
return context().getIdentifier();
}
needBackend = queue.runTimeout();
} catch (NoProgressException e) {
// Uh-oh, no progress. The queue has already killed itself, now we need to remove it
+ LOG.debug("{}: No progress made - removing queue", persistenceId(), e);
context().removeQueue(queue);
return this;
}
}
/**
- * Halt And Catch Fire.
- *
- * Halt processing on this client. Implementations need to ensure they initiate state flush procedures. No attempt
- * to use this instance should be made after this method returns. Any such use may result in undefined behavior.
+ * Halt And Catch Fire. Halt processing on this client. Implementations need to ensure they initiate state flush
+ * procedures. No attempt to use this instance should be made after this method returns. Any such use may result
+ * in undefined behavior.
*
* @param cause Failure cause
*/
/**
* Override this method to handle any command which is not handled by the base behavior.
*
- * @param command
+ * @param command the command to process
* @return Next behavior to use, null if this actor should shut down.
*/
- protected abstract @Nullable ClientActorBehavior onCommand(@Nonnull Object command);
+ @Nullable
+ protected abstract ClientActorBehavior onCommand(@Nonnull Object command);
/**
* Override this method to provide a backend resolver instance.
*
- * @return
+ * @return a backend resolver instance
*/
- protected abstract @Nonnull BackendInfoResolver<?> resolver();
+ @Nonnull
+ protected abstract BackendInfoResolver<?> resolver();
/**
* Send a request to the backend and invoke a specified callback when it finishes. This method is safe to invoke
/**
* An actor context associated with this {@link AbstractClientActor}.
*
+ * <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()}.
}
@Override
- public @Nonnull ClientIdentifier getIdentifier() {
+ @Nonnull
+ public ClientIdentifier getIdentifier() {
return identifier;
}
*
* @return Client actor time source
*/
- public @Nonnull Ticker ticker() {
+ @Nonnull
+ public Ticker ticker() {
return Ticker.systemTicker();
}
*
* @param command Block of code which needs to be execute
*/
- public void executeInActor(final @Nonnull InternalCommand command) {
+ public void executeInActor(@Nonnull final InternalCommand command) {
self().tell(Preconditions.checkNotNull(command), ActorRef.noSender());
}
- public Cancellable executeInActor(final @Nonnull InternalCommand command, final FiniteDuration delay) {
+ public Cancellable executeInActor(@Nonnull final InternalCommand command, final FiniteDuration delay) {
return scheduler.scheduleOnce(Preconditions.checkNotNull(delay), self(), Preconditions.checkNotNull(command),
executionContext, ActorRef.noSender());
}
}
@Override
- public boolean offer(final E e) {
+ public boolean offer(final E entry) {
return false;
}
import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
/**
+ * The initial context for an actor.
*
* @author Robert Varga
*/
package org.opendaylight.controller.cluster.access.client;
/**
+ * Abstract base class class for a behavior whose actor has recovered from persistence.
+ *
* @param <C> Concrete context type
*
* @author Robert Varga
*/
-abstract class RecoveredClientActorBehavior<C extends AbstractClientActorContext> extends AbstractClientActorBehavior<C> {
+abstract class RecoveredClientActorBehavior<C extends AbstractClientActorContext>
+ extends AbstractClientActorBehavior<C> {
RecoveredClientActorBehavior(final C context) {
super(context);
LOG.debug("{}: got command: {}", persistenceId(), command);
} else if (command instanceof DeleteSnapshotsFailure) {
// Not treating this as a fatal error.
- LOG.warn("{}: failed to delete prior snapshots", persistenceId(), ((DeleteSnapshotsFailure) command).cause());
+ LOG.warn("{}: failed to delete prior snapshots", persistenceId(),
+ ((DeleteSnapshotsFailure) command).cause());
} else {
LOG.debug("{}: stashing command {}", persistenceId(), command);
context().stash();
context().unstash();
return context().createBehavior(myId);
}
-}
\ No newline at end of file
+}
import scala.concurrent.duration.FiniteDuration;
/*
+ * A queue that processes entries in sequence.
+ *
* TODO: make this class and its users thread-safe. This will require some atomic state-keeping so that timeouts,
* retries and enqueues work as expected.
*/
* 2) The request has been enqueued and transmitted, but the caller needs to schedule a new timer
* 3) The request has been enqueued, but the caller needs to request resolution of backend information and that
* process needs to complete before transmission occurs
- *
+ * <p/>
* These options are covered via returning an {@link Optional}. The caller needs to examine it and decode
* the scenarios above according to the following rules:
* - if is null, the first case applies
transmitEntries(pending, toSend);
}
- Optional<FiniteDuration> setBackendInfo(final CompletionStage<? extends BackendInfo> proof, final BackendInfo backend) {
+ Optional<FiniteDuration> setBackendInfo(final CompletionStage<? extends BackendInfo> proof,
+ final BackendInfo backend) {
Preconditions.checkNotNull(backend);
if (!proof.equals(backendProof)) {
LOG.debug("Ignoring resolution {} while waiting for {}", proof, this.backendProof);
package org.opendaylight.controller.cluster.access.client;
import static org.mockito.Mockito.doReturn;
+
import akka.actor.ActorRef;
import org.junit.Before;
import org.mockito.Mock;
package org.opendaylight.controller.cluster.access.client;
import static org.junit.Assert.assertSame;
+
import akka.actor.ActorRef;
import akka.actor.Scheduler;
import akka.dispatch.Dispatcher;
public class ClientActorContextTest {
private static final MemberName MEMBER_NAME = MemberName.forName("member-1");
- private static final FrontendType FRONTEND_TYPE = FrontendType.forName(ClientActorContextTest.class.getSimpleName());
+ private static final FrontendType FRONTEND_TYPE =
+ FrontendType.forName(ClientActorContextTest.class.getSimpleName());
private static final FrontendIdentifier FRONTEND_ID = FrontendIdentifier.create(MEMBER_NAME, FRONTEND_TYPE);
private static final ClientIdentifier CLIENT_ID = ClientIdentifier.create(FRONTEND_ID, 0);
private static final String PERSISTENCE_ID = ClientActorContextTest.class.getSimpleName();
@Test
public void testMockingControl() {
- ClientActorContext ctx = new ClientActorContext(mockSelf, mockScheduler, mockDispatcher, PERSISTENCE_ID, CLIENT_ID);
+ ClientActorContext ctx = new ClientActorContext(mockSelf, mockScheduler, mockDispatcher,
+ PERSISTENCE_ID, CLIENT_ID);
assertSame(CLIENT_ID, ctx.getIdentifier());
assertSame(PERSISTENCE_ID, ctx.persistenceId());
assertSame(mockSelf, ctx.self());
@Test
public void testTicker() {
- ClientActorContext ctx = new ClientActorContext(mockSelf, mockScheduler, mockDispatcher, PERSISTENCE_ID, CLIENT_ID);
+ ClientActorContext ctx = new ClientActorContext(mockSelf, mockScheduler, mockDispatcher,
+ PERSISTENCE_ID, CLIENT_ID);
assertSame(Ticker.systemTicker(), ctx.ticker());
}
}
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
+
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.testkit.TestProbe;
}
@Override
- protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(final ABIVersion version) {
+ protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(
+ final ABIVersion version) {
return null;
}
assertRequestEquals(mockRequest, mockActor.receiveOne(Duration.apply(5, TimeUnit.SECONDS)));
}
- private static void assertRequestEquals(final Request<?, ?> expected, final Object o) {
- assertTrue(o instanceof RequestEnvelope);
+ private static void assertRequestEquals(final Request<?, ?> expected, final Object obj) {
+ assertTrue(obj instanceof RequestEnvelope);
- final RequestEnvelope actual = (RequestEnvelope) o;
- assertEquals(0, actual.getSessionId());
- assertEquals(0, actual.getTxSequence());
- assertEquals(expected.getTarget(), actual.getMessage().getTarget());
+ final RequestEnvelope actual = (RequestEnvelope) obj;
+ assertEquals(0, actual.getSessionId());
+ assertEquals(0, actual.getTxSequence());
+ assertEquals(expected.getTarget(), actual.getMessage().getTarget());
}
}
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.testkit.TestProbe;
}
@Override
- protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(final ABIVersion version) {
+ protected AbstractRequestFailureProxy<WritableIdentifier, MockFailure> externalizableProxy(
+ final ABIVersion version) {
return null;
}
assertTrue(queue.hasCompleted());
}
- @Test(expected=IllegalStateException.class)
+ @Test(expected = IllegalStateException.class)
public void testClosedEnqueueRequest() {
queue.close();
assertSame(mockCause, captor.getValue().getCause());
}
- @Test(expected=IllegalStateException.class)
+ @Test(expected = IllegalStateException.class)
public void testPoisonPerformsClose() {
// Implies close()
queue.poison(mockCause);
assertFalse(queue.expectProof(proof));
}
- @Test(expected=NullPointerException.class)
+ @Test(expected = NullPointerException.class)
public void testSetBackendNull() {
final CompletableFuture<BackendInfo> proof = new CompletableFuture<>();
assertTrue(queue.expectProof(proof));
assertTrue(ret);
}
- @Test(expected=NoProgressException.class)
+ @Test(expected = NoProgressException.class)
public void testRunTimeoutWithoutProgressExact() throws NoProgressException {
queue.enqueueRequest(mockRequest, mockCallback);
queue.runTimeout();
}
- @Test(expected=NoProgressException.class)
+ @Test(expected = NoProgressException.class)
public void testRunTimeoutWithoutProgressMore() throws NoProgressException {
queue.enqueueRequest(mockRequest, mockCallback);
assertRequestEquals(expected, sequence, mockActor.receiveOne(FiniteDuration.apply(5, TimeUnit.SECONDS)));
}
- private static void assertRequestEquals(final Request<?, ?> expected, final long sequence, final Object o) {
- assertTrue(o instanceof RequestEnvelope);
+ private static void assertRequestEquals(final Request<?, ?> expected, final long sequence, final Object obj) {
+ assertTrue(obj instanceof RequestEnvelope);
- final RequestEnvelope actual = (RequestEnvelope) o;
+ final RequestEnvelope actual = (RequestEnvelope) obj;
assertEquals(0, actual.getSessionId());
assertEquals(sequence, actual.getTxSequence());
assertSame(expected, actual.getMessage());