import com.google.common.util.concurrent.Futures;
import java.io.IOException;
import java.util.List;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.controller.cluster.schema.provider.RemoteYangTextSourceProvider;
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.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private DOMDataBroker deviceDataBroker;
//readTxActor can be shared
private ActorRef readTxActor;
+ private List<SchemaSourceRegistration<YangTextSchemaSource>> registeredSchemas;
public static Props props(final NetconfTopologySetup setup,
final RemoteDeviceId id, final SchemaSourceRegistry schemaRegistry,
}
}
+ @Override
+ public void postStop() throws Exception {
+ super.postStop();
+ closeSchemaSourceRegistrations();
+ }
private void sendYangTextSchemaSourceProxy(final SourceIdentifier sourceIdentifier, final ActorRef sender) {
final CheckedFuture<YangTextSchemaSource, SchemaSourceException> yangTextSchemaSource =
if (this.slaveSalManager != null) {
slaveSalManager.close();
}
+ closeSchemaSourceRegistrations();
slaveSalManager = new SlaveSalFacade(id, setup.getDomBroker(), setup.getActorSystem(), actorResponseWaitTime);
final CheckedFuture<SchemaContext, SchemaResolutionException> remoteSchemaContext =
final RemoteSchemaProvider remoteProvider = new RemoteSchemaProvider(remoteYangTextSourceProvider,
getContext().dispatcher());
- sourceIdentifiers.forEach(sourceId ->
- schemaRegistry.registerSchemaSource(remoteProvider, PotentialSchemaSource.create(sourceId,
- YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
+ registeredSchemas = sourceIdentifiers.stream()
+ .map(sourceId ->
+ schemaRegistry.registerSchemaSource(remoteProvider, PotentialSchemaSource.create(sourceId,
+ YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())))
+ .collect(Collectors.toList());
final SchemaContextFactory schemaContextFactory
= schemaRepository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
return schemaContextFactory.createSchemaContext(sourceIdentifiers);
}
+ private void closeSchemaSourceRegistrations() {
+ if (registeredSchemas != null) {
+ registeredSchemas.forEach(SchemaSourceRegistration::close);
+ registeredSchemas = null;
+ }
+ }
+
}
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY;
import akka.util.Timeout;
import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.SettableFuture;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.opendaylight.controller.cluster.schema.provider.impl.YangTextSchemaSourceSerializationProxy;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.controller.sal.core.api.Broker;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
import org.opendaylight.netconf.topology.singleton.impl.utils.ClusteringRpcException;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
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.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
}
+ @Test
+ public void testReceiveRegisterMountpoint() throws Exception {
+ final NetconfTopologySetup setup = mock(NetconfTopologySetup.class);
+ doReturn(mock(Broker.class)).when(setup).getDomBroker();
+ final RevisionSourceIdentifier yang1 = RevisionSourceIdentifier.create("yang1");
+ final RevisionSourceIdentifier yang2 = RevisionSourceIdentifier.create("yang2");
+ final SchemaSourceRegistry registry = mock(SchemaSourceRegistry.class);
+ final SchemaRepository schemaRepository = mock(SchemaRepository.class);
+ final SchemaSourceRegistration regYang1 = mock(SchemaSourceRegistration.class);
+ final SchemaSourceRegistration regYang2 = mock(SchemaSourceRegistration.class);
+ doReturn(regYang1).when(registry).registerSchemaSource(any(), withSourceId(yang1));
+ doReturn(regYang2).when(registry).registerSchemaSource(any(), withSourceId(yang2));
+ final SchemaContextFactory schemaContextFactory = mock(SchemaContextFactory.class);
+ doReturn(schemaContextFactory).when(schemaRepository).createSchemaContextFactory(any());
+ final SettableFuture<SchemaContext> schemaContextFuture = SettableFuture.create();
+ final CheckedFuture<SchemaContext, SchemaResolutionException> checkedFuture =
+ Futures.makeChecked(schemaContextFuture, e -> new SchemaResolutionException("fail", e));
+ doReturn(checkedFuture).when(schemaContextFactory).createSchemaContext(any());
+ final ActorRef slaveRef =
+ system.actorOf(NetconfNodeActor.props(setup, remoteDeviceId, registry, schemaRepository, TIMEOUT));
+ final List<SourceIdentifier> sources = ImmutableList.of(yang1, yang2);
+ slaveRef.tell(new RegisterMountPoint(sources), masterRef);
+
+ verify(registry, timeout(1000)).registerSchemaSource(any(), withSourceId(yang1));
+ verify(registry, timeout(1000)).registerSchemaSource(any(), withSourceId(yang2));
+ //stop actor
+ final Future<Boolean> stopFuture = Patterns.gracefulStop(slaveRef, TIMEOUT.duration());
+ Await.result(stopFuture, TIMEOUT.duration());
+ //provider should be deregistered
+ verify(regYang1).close();
+ verify(regYang2).close();
+ }
+
@Test
public void testYangTextSchemaSourceRequestMessage() throws Exception {
final SchemaRepository schemaRepository = mock(SchemaRepository.class);
}
+ private PotentialSchemaSource<?> withSourceId(final SourceIdentifier identifier) {
+ return argThat(new ArgumentMatcher<PotentialSchemaSource>() {
+ @Override
+ public boolean matches(final Object argument) {
+ final PotentialSchemaSource potentialSchemaSource = (PotentialSchemaSource) argument;
+ return identifier.equals(potentialSchemaSource.getSourceIdentifier());
+ }
+ });
+ }
+
private String convertStreamToString(final java.io.InputStream is) {
final java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";