2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.sal.connect.netconf.schema;
10 import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
11 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
12 import org.opendaylight.controller.sal.core.api.RpcImplementation;
13 import org.opendaylight.yangtools.yang.common.QName;
14 import org.opendaylight.yangtools.yang.common.RpcResult;
15 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
16 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
17 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
18 import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
19 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
23 import com.google.common.base.Optional;
24 import com.google.common.base.Preconditions;
26 public final class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String> {
28 public static final QName GET_SCHEMA_QNAME = QName.create(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING,
30 public static final QName GET_DATA_QNAME = QName
31 .create(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING, "data");
33 private static final Logger logger = LoggerFactory.getLogger(NetconfRemoteSchemaSourceProvider.class);
35 private final RpcImplementation rpc;
36 private final RemoteDeviceId id;
38 public NetconfRemoteSchemaSourceProvider(final RemoteDeviceId id, final RpcImplementation rpc) {
40 this.rpc = Preconditions.checkNotNull(rpc);
44 public Optional<String> getSchemaSource(final String moduleName, final Optional<String> revision) {
45 final ImmutableCompositeNode getSchemaRequest = createGetSchemaRequest(moduleName, revision);
47 logger.trace("{}: Loading YANG schema source for {}:{}", id, moduleName, revision);
49 final RpcResult<CompositeNode> schemaReply = rpc.invokeRpc(GET_SCHEMA_QNAME, getSchemaRequest).get();
50 if (schemaReply.isSuccessful()) {
51 final Optional<String> schemaBody = getSchemaFromRpc(id, schemaReply.getResult());
52 if (schemaBody.isPresent()) {
53 logger.debug("{}: YANG Schema successfully retrieved for {}:{}", id, moduleName, revision);
57 logger.warn("{}: YANG schema was not successfully retrieved for {}:{}. Errors: {}", id, moduleName,
58 revision, schemaReply.getErrors());
60 return Optional.absent();
61 } catch (final InterruptedException e){
62 Thread.currentThread().interrupt();
63 throw new IllegalStateException(e);
64 } catch (final Exception e) {
65 logger.error("{}: YANG schema was not successfully retrieved for {}:{}", id, moduleName, revision, e);
66 throw new IllegalStateException(e);
70 private ImmutableCompositeNode createGetSchemaRequest(final String moduleName, final Optional<String> revision) {
71 final CompositeNodeBuilder<ImmutableCompositeNode> request = ImmutableCompositeNode.builder();
72 request.setQName(GET_SCHEMA_QNAME).addLeaf("identifier", moduleName);
73 if (revision.isPresent()) {
74 request.addLeaf("version", revision.get());
76 request.addLeaf("format", "yang");
77 return request.toInstance();
80 private static Optional<String> getSchemaFromRpc(final RemoteDeviceId id, final CompositeNode result) {
82 return Optional.absent();
84 final SimpleNode<?> simpleNode = result.getFirstSimpleByName(GET_DATA_QNAME.withoutRevision());
86 Preconditions.checkNotNull(simpleNode,
87 "%s Unexpected response to get-schema, expected response with one child %s, but was %s",
88 id, GET_DATA_QNAME.withoutRevision(), result);
90 final Object potential = simpleNode.getValue();
91 return potential instanceof String ? Optional.of((String) potential) : Optional.<String>absent();