import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
import org.opendaylight.controller.md.sal.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;
import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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) {
+ this(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, reconnectOnSchemasChange, null);
+ }
+
+ public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id,
+ final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+ final ExecutorService 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();
@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);
}
};
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 {
}
@Override
- public DeviceSources call() throws Exception {
+ public DeviceSources call() {
final NetconfDeviceSchemas availableSchemas =
stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities, id);
LOG.debug("{}: Schemas exposed by ietf-netconf-monitoring: {}", id,
private Collection<SourceIdentifier> filterMissingSources(final Collection<SourceIdentifier> requiredSources) {
return requiredSources.parallelStream().filter(sourceIdentifier -> {
try {
- schemaRepository.getSchemaSource(sourceIdentifier, ASTSchemaSource.class).get();
+ schemaRepository.getSchemaSource(sourceIdentifier, YangTextSchemaSource.class).get();
return false;
} catch (InterruptedException | ExecutionException e) {
return true;
/**
* 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
final Collection<SourceIdentifier> requiredSources, final MissingSchemaSourceException exception) {
// In case source missing, try without it
final SourceIdentifier missingSource = exception.getSourceId();
- LOG.warn("{}: Unable to build schema context, missing source {}, will reattempt without it", id,
- missingSource);
+ LOG.warn("{}: Unable to build schema context, missing source {}, will reattempt without it",
+ id, missingSource);
LOG.debug("{}: Unable to build schema context, missing source {}, will reattempt without it",
- exception);
+ id, missingSource, exception);
final Collection<QName> qNameOfMissingSource =
- getQNameFromSourceIdentifiers(Sets.newHashSet(missingSource));
+ getQNameFromSourceIdentifiers(Sets.newHashSet(missingSource));
if (!qNameOfMissingSource.isEmpty()) {
capabilities.addUnresolvedCapabilities(
qNameOfMissingSource, UnavailableCapability.FailureReason.MissingSource);
// flawed model - exclude it
final SourceIdentifier failedSourceId = resolutionException.getFailedSource();
LOG.warn("{}: Unable to build schema context, failed to resolve source {}, will reattempt without it",
- id, failedSourceId);
+ id, failedSourceId);
LOG.warn("{}: Unable to build schema context, failed to resolve source {}, will reattempt without it",
- id, resolutionException);
- capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(
- Collections.singleton(failedSourceId)), UnavailableCapability.FailureReason.UnableToResolve);
+ id, failedSourceId, resolutionException);
+ capabilities.addUnresolvedCapabilities(
+ getQNameFromSourceIdentifiers(Collections.singleton(failedSourceId)),
+ UnavailableCapability.FailureReason.UnableToResolve);
return stripUnavailableSource(requiredSources, resolutionException.getFailedSource());
}
// unsatisfied imports
final Set<SourceIdentifier> unresolvedSources = resolutionException.getUnsatisfiedImports().keySet();
- capabilities.addUnresolvedCapabilities(
- getQNameFromSourceIdentifiers(unresolvedSources), UnavailableCapability.FailureReason.UnableToResolve);
+ capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(unresolvedSources),
+ UnavailableCapability.FailureReason.UnableToResolve);
LOG.warn("{}: Unable to build schema context, unsatisfied imports {}, will reattempt with resolved only",
- id, resolutionException.getUnsatisfiedImports());
+ id, resolutionException.getUnsatisfiedImports());
LOG.debug("{}: Unable to build schema context, unsatisfied imports {}, will reattempt with resolved only",
- resolutionException);
+ id, resolutionException.getUnsatisfiedImports(), resolutionException);
return resolutionException.getResolvedSources();
}