*/
package org.opendaylight.netconf.sal.connect.netconf;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.opendaylight.mdsal.dom.api.DOMNotification;
+import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory;
import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemas;
import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemasResolver;
private static final Logger LOG = LoggerFactory.getLogger(NetconfDevice.class);
protected final RemoteDeviceId id;
- private final boolean reconnectOnSchemasChange;
-
protected final SchemaContextFactory schemaContextFactory;
- private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
- private final ListeningExecutorService processingExecutor;
protected final SchemaSourceRegistry schemaRegistry;
protected final SchemaRepository schemaRepository;
- private final NetconfDeviceSchemasResolver stateSchemasResolver;
- private final NotificationHandler notificationHandler;
+
protected final List<SchemaSourceRegistration<? extends SchemaSourceRepresentation>> sourceRegistrations =
new ArrayList<>();
+
+ private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
+ private final ListeningExecutorService processingExecutor;
+ private final DeviceActionFactory deviceActionFactory;
+ private final NetconfDeviceSchemasResolver stateSchemasResolver;
+ private final NotificationHandler notificationHandler;
+ private final boolean reconnectOnSchemasChange;
+
@GuardedBy("this")
private boolean connected = false;
public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id,
final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
- final ExecutorService globalProcessingExecutor, final boolean reconnectOnSchemasChange) {
+ final ListeningExecutorService globalProcessingExecutor,
+ final boolean reconnectOnSchemasChange) {
+ this(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, reconnectOnSchemasChange, null);
+ }
+
+ public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id,
+ final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+ final ListeningExecutorService globalProcessingExecutor, final boolean reconnectOnSchemasChange,
+ final DeviceActionFactory deviceActionFactory) {
this.id = id;
this.reconnectOnSchemasChange = reconnectOnSchemasChange;
+ this.deviceActionFactory = deviceActionFactory;
this.schemaRegistry = schemaResourcesDTO.getSchemaRegistry();
this.schemaRepository = schemaResourcesDTO.getSchemaRepository();
this.schemaContextFactory = schemaResourcesDTO.getSchemaContextFactory();
this.salFacade = salFacade;
this.stateSchemasResolver = schemaResourcesDTO.getStateSchemasResolver();
- this.processingExecutor = MoreExecutors.listeningDecorator(globalProcessingExecutor);
+ this.processingExecutor = requireNonNull(globalProcessingExecutor);
this.notificationHandler = new NotificationHandler(salFacade, id);
}
final FutureCallback<DeviceSources> resolvedSourceCallback = new FutureCallback<DeviceSources>() {
@Override
- public void onSuccess(@Nonnull final DeviceSources result) {
+ public void onSuccess(final DeviceSources result) {
addProvidedSourcesToSchemaRegistry(result);
setUpSchema(result);
}
@Override
public void onFailure(final Throwable throwable) {
- LOG.warn("{}: Unexpected error resolving device sources: {}", id, throwable);
+ LOG.warn("{}: Unexpected error resolving device sources", id, throwable);
handleSalInitializationFailure(throwable, listener);
}
};
// TODO check whether the model describing create subscription is present in schema
// Perhaps add a default schema context to support create-subscription if the model was not provided
// (same as what we do for base netconf operations in transformer)
- final CheckedFuture<DOMRpcResult, DOMRpcException> rpcResultListenableFuture = deviceRpc.invokeRpc(
+ final FluentFuture<DOMRpcResult> rpcResultListenableFuture = deviceRpc.invokeRpc(
NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_QNAME),
NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_CONTENT);
// Only disconnect is enough,
// the reconnecting nature of the connector will take care of reconnecting
listener.disconnect();
- return Optional.absent();
+ return Optional.empty();
}
return Optional.of(notification);
}
private synchronized void handleSalInitializationSuccess(final SchemaContext result,
final NetconfSessionPreferences remoteSessionCapabilities,
- final DOMRpcService deviceRpc) {
+ final DOMRpcService deviceRpc,
+ final RemoteDeviceCommunicator<NetconfMessage> listener) {
//NetconfDevice.SchemaSetup can complete after NetconfDeviceCommunicator was closed. In that case do nothing,
//since salFacade.onDeviceDisconnected was already called.
if (connected) {
final BaseSchema baseSchema =
remoteSessionCapabilities.isNotificationsSupported()
? BaseSchema.BASE_NETCONF_CTX_WITH_NOTIFICATIONS : BaseSchema.BASE_NETCONF_CTX;
- messageTransformer = new NetconfMessageTransformer(result, true, baseSchema);
+ this.messageTransformer = new NetconfMessageTransformer(result, true, baseSchema);
- updateTransformer(messageTransformer);
+ updateTransformer(this.messageTransformer);
// salFacade.onDeviceConnected has to be called before the notification handler is initialized
- salFacade.onDeviceConnected(result, remoteSessionCapabilities, deviceRpc);
- notificationHandler.onRemoteSchemaUp(messageTransformer);
+ this.salFacade.onDeviceConnected(result, remoteSessionCapabilities, deviceRpc,
+ this.deviceActionFactory == null ? null : this.deviceActionFactory.createDeviceAction(
+ this.messageTransformer, listener, result));
+ this.notificationHandler.onRemoteSchemaUp(this.messageTransformer);
LOG.info("{}: Netconf connector initialized successfully", id);
} else {
final SchemaRepository schemaRepository,
final SchemaContextFactory schemaContextFactory,
final NetconfDeviceSchemasResolver deviceSchemasResolver) {
- this.schemaRegistry = Preconditions.checkNotNull(schemaRegistry);
- this.schemaRepository = Preconditions.checkNotNull(schemaRepository);
- this.schemaContextFactory = Preconditions.checkNotNull(schemaContextFactory);
- this.stateSchemasResolver = Preconditions.checkNotNull(deviceSchemasResolver);
+ this.schemaRegistry = requireNonNull(schemaRegistry);
+ this.schemaRepository = requireNonNull(schemaRepository);
+ this.schemaContextFactory = requireNonNull(schemaContextFactory);
+ this.stateSchemasResolver = requireNonNull(deviceSchemasResolver);
}
public SchemaSourceRegistry getSchemaRegistry() {
/**
* Build schema context, in case of success or final failure notify device.
+ *
+ * @param requiredSources required sources
*/
@SuppressWarnings("checkstyle:IllegalCatch")
private void setUpSchema(Collection<SourceIdentifier> requiredSources) {
remoteSessionCapabilities.getNonModuleBasedCapsOrigin().get(entry)).build())
.collect(Collectors.toList()));
- handleSalInitializationSuccess(result, remoteSessionCapabilities, getDeviceSpecificRpc(result));
+ handleSalInitializationSuccess(result, remoteSessionCapabilities, getDeviceSpecificRpc(result),
+ listener);
return;
} catch (final ExecutionException e) {
// schemaBuilderFuture.checkedGet() throws only SchemaResolutionException
private Collection<SourceIdentifier> stripUnavailableSource(final Collection<SourceIdentifier> requiredSources,
final SourceIdentifier sourceIdToRemove) {
final LinkedList<SourceIdentifier> sourceIdentifiers = Lists.newLinkedList(requiredSources);
- final boolean removed = sourceIdentifiers.remove(sourceIdToRemove);
- Preconditions.checkState(
- removed, "{}: Trying to remove {} from {} failed", id, sourceIdToRemove, requiredSources);
+ checkState(sourceIdentifiers.remove(sourceIdToRemove),
+ "%s: Trying to remove %s from %s failed", id, sourceIdToRemove, requiredSources);
return sourceIdentifiers;
}