import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.net.URI;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
import org.opendaylight.mdsal.dom.api.DOMRpcService;
import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService.YangTextSourceExtension;
import org.opendaylight.restconf.api.ApiPath;
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.common.errors.RestconfFuture;
-import org.opendaylight.restconf.common.patch.PatchStatusContext;
import org.opendaylight.restconf.nb.rfc8040.databind.ChildBody;
import org.opendaylight.restconf.nb.rfc8040.databind.DataPostBody;
import org.opendaylight.restconf.nb.rfc8040.databind.OperationInputBody;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy.StrategyAndTail;
import org.opendaylight.restconf.server.api.DataGetParams;
import org.opendaylight.restconf.server.api.DataGetResult;
+import org.opendaylight.restconf.server.api.DataPatchResult;
import org.opendaylight.restconf.server.api.DataPostResult;
import org.opendaylight.restconf.server.api.DataPostResult.CreateResource;
import org.opendaylight.restconf.server.api.DataPutResult;
+import org.opendaylight.restconf.server.api.DataYangPatchResult;
import org.opendaylight.restconf.server.api.DatabindContext;
import org.opendaylight.restconf.server.api.ModulesGetResult;
import org.opendaylight.restconf.server.api.OperationsGetResult;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.common.YangNames;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextListener;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.api.YinTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.source.SourceRepresentation;
+import org.opendaylight.yangtools.yang.model.api.source.YangTextSource;
+import org.opendaylight.yangtools.yang.model.api.source.YinTextSource;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A RESTCONF server implemented on top of MD-SAL.
*/
@Singleton
@Component(service = { RestconfServer.class, DatabindProvider.class })
-public final class MdsalRestconfServer
- implements RestconfServer, DatabindProvider, EffectiveModelContextListener, AutoCloseable {
- private static final Logger LOG = LoggerFactory.getLogger(MdsalRestconfServer.class);
+public final class MdsalRestconfServer implements RestconfServer, DatabindProvider, AutoCloseable {
private static final QName YANG_LIBRARY_VERSION = QName.create(Restconf.QNAME, "yang-library-version").intern();
private static final VarHandle LOCAL_STRATEGY;
private final @NonNull DOMDataBroker dataBroker;
private final @Nullable DOMRpcService rpcService;
private final @Nullable DOMActionService actionService;
- private final @Nullable DOMYangTextSourceProvider sourceProvider;
+ private final @Nullable YangTextSourceExtension sourceProvider;
private final Registration reg;
@SuppressWarnings("unused")
+ @SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
private volatile MdsalRestconfStrategy localStrategy;
@Inject
this.actionService = requireNonNull(actionService);
this.mountPointService = requireNonNull(mountPointService);
this.localRpcs = Maps.uniqueIndex(localRpcs, RpcImplementation::qname);
- sourceProvider = schemaService.getExtensions().getInstance(DOMYangTextSourceProvider.class);
+ sourceProvider = schemaService.extension(YangTextSourceExtension.class);
localStrategy = createLocalStrategy(schemaService.getGlobalContext());
- reg = schemaService.registerSchemaContextListener(this);
+ reg = schemaService.registerSchemaContextListener(this::onModelContextUpdated);
}
public MdsalRestconfServer(final DOMSchemaService schemaService, final DOMDataBroker dataBroker,
return localStrategy().databind();
}
- @Override
- public void onModelContextUpdated(final EffectiveModelContext newModelContext) {
+ private void onModelContextUpdated(final EffectiveModelContext newModelContext) {
final var local = localStrategy();
if (!newModelContext.equals(local.modelContext())) {
LOCAL_STRATEGY.setRelease(this, createLocalStrategy(newModelContext));
}
@Override
- public RestconfFuture<Empty> dataPATCH(final ResourceBody body) {
+ public RestconfFuture<DataPatchResult> dataPATCH(final ResourceBody body) {
return localStrategy().dataPATCH(ApiPath.empty(), body);
}
@Override
- public RestconfFuture<Empty> dataPATCH(final ApiPath identifier, final ResourceBody body) {
+ public RestconfFuture<DataPatchResult> dataPATCH(final ApiPath identifier, final ResourceBody body) {
final StrategyAndTail strategyAndTail;
try {
strategyAndTail = localStrategy().resolveStrategy(identifier);
}
@Override
- public RestconfFuture<PatchStatusContext> dataPATCH(final PatchBody body) {
+ public RestconfFuture<DataYangPatchResult> dataPATCH(final PatchBody body) {
return localStrategy().dataPATCH(ApiPath.empty(), body);
}
@Override
- public RestconfFuture<PatchStatusContext> dataPATCH(final ApiPath identifier, final PatchBody body) {
+ public RestconfFuture<DataYangPatchResult> dataPATCH(final ApiPath identifier, final PatchBody body) {
final StrategyAndTail strategyAndTail;
try {
strategyAndTail = localStrategy().resolveStrategy(identifier);
@Override
public RestconfFuture<ModulesGetResult> modulesYangGET(final String fileName, final String revision) {
- return modulesGET(fileName, revision, YangTextSchemaSource.class);
+ return modulesGET(fileName, revision, YangTextSource.class);
}
@Override
public RestconfFuture<ModulesGetResult> modulesYangGET(final ApiPath mountPath, final String fileName,
final String revision) {
- return modulesGET(mountPath, fileName, revision, YangTextSchemaSource.class);
+ return modulesGET(mountPath, fileName, revision, YangTextSource.class);
}
@Override
public RestconfFuture<ModulesGetResult> modulesYinGET(final String fileName, final String revision) {
- return modulesGET(fileName, revision, YinTextSchemaSource.class);
+ return modulesGET(fileName, revision, YinTextSource.class);
}
@Override
public RestconfFuture<ModulesGetResult> modulesYinGET(final ApiPath mountPath, final String fileName,
final String revision) {
- return modulesGET(mountPath, fileName, revision, YinTextSchemaSource.class);
+ return modulesGET(mountPath, fileName, revision, YinTextSource.class);
}
private @NonNull RestconfFuture<ModulesGetResult> modulesGET(final String fileName, final String revision,
- final Class<? extends SchemaSourceRepresentation> representation) {
+ final Class<? extends SourceRepresentation> representation) {
return modulesGET(localStrategy(), fileName, revision, representation);
}
private @NonNull RestconfFuture<ModulesGetResult> modulesGET(final ApiPath mountPath, final String fileName,
- final String revision, final Class<? extends SchemaSourceRepresentation> representation) {
+ final String revision, final Class<? extends SourceRepresentation> representation) {
final var mountOffset = mountPath.indexOf("yang-ext", "mount");
if (mountOffset != mountPath.steps().size() - 1) {
return RestconfFuture.failed(new RestconfDocumentedException("Mount path has to end with yang-ext:mount"));
private static @NonNull RestconfFuture<ModulesGetResult> modulesGET(final RestconfStrategy strategy,
final String moduleName, final String revisionStr,
- final Class<? extends SchemaSourceRepresentation> representation) {
+ final Class<? extends SourceRepresentation> representation) {
if (moduleName == null) {
return RestconfFuture.failed(new RestconfDocumentedException("Module name must be supplied",
ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE));
return RestconfFuture.failed(new RestconfDocumentedException("RESTCONF is not available"));
}
return RestconfFuture.of(new NormalizedNodePayload(stack.toInference(),
- ImmutableNodes.leafNode(YANG_LIBRARY_VERSION, stack.getEffectiveModelContext()
+ ImmutableNodes.leafNode(YANG_LIBRARY_VERSION, stack.modelContext()
.findModuleStatements("ietf-yang-library").iterator().next().localQNameModule().getRevision()
.map(Revision::toString).orElse(""))));
}