Merge "TCP_Flag extension model additions for OFPXMC_NXM_1 class"
[controller.git] / opendaylight / md-sal / sal-netconf-connector / src / main / java / org / opendaylight / controller / sal / connect / netconf / schema / NetconfRemoteSchemaSourceProvider.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.sal.connect.netconf.schema;
9
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;
22
23 import com.google.common.base.Optional;
24 import com.google.common.base.Preconditions;
25
26 public final class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String> {
27
28     public static final QName GET_SCHEMA_QNAME = QName.create(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING,
29             "get-schema");
30     public static final QName GET_DATA_QNAME = QName
31             .create(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING, "data");
32
33     private static final Logger logger = LoggerFactory.getLogger(NetconfRemoteSchemaSourceProvider.class);
34
35     private final RpcImplementation rpc;
36     private final RemoteDeviceId id;
37
38     public NetconfRemoteSchemaSourceProvider(final RemoteDeviceId id, final RpcImplementation rpc) {
39         this.id = id;
40         this.rpc = Preconditions.checkNotNull(rpc);
41     }
42
43     @Override
44     public Optional<String> getSchemaSource(final String moduleName, final Optional<String> revision) {
45         final ImmutableCompositeNode getSchemaRequest = createGetSchemaRequest(moduleName, revision);
46
47         logger.trace("{}: Loading YANG schema source for {}:{}", id, moduleName, revision);
48         try {
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);
54                     return schemaBody;
55                 }
56             } else {
57                 logger.warn("{}: YANG schema was not successfully retrieved for {}:{}. Errors: {}", id, moduleName,
58                         revision, schemaReply.getErrors());
59             }
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);
67         }
68     }
69
70     private ImmutableCompositeNode createGetSchemaRequest(final String moduleName, final Optional<String> revision) {
71         final CompositeNodeBuilder<ImmutableCompositeNode> request = ImmutableCompositeNode.builder();
72         request.setQName(GET_SCHEMA_QNAME)
73                 .addLeaf("format", "yang")
74                 .addLeaf("identifier", moduleName);
75
76         if (revision.isPresent()) {
77             request.addLeaf("version", revision.get());
78         }
79         return request.toInstance();
80     }
81
82     private static Optional<String> getSchemaFromRpc(final RemoteDeviceId id, final CompositeNode result) {
83         if (result == null) {
84             return Optional.absent();
85         }
86         final SimpleNode<?> simpleNode = result.getFirstSimpleByName(GET_DATA_QNAME.withoutRevision());
87
88         Preconditions.checkNotNull(simpleNode,
89                 "%s Unexpected response to get-schema, expected response with one child %s, but was %s",
90                 id, GET_DATA_QNAME.withoutRevision(), result);
91
92         final Object potential = simpleNode.getValue();
93         return potential instanceof String ? Optional.of((String) potential) : Optional.<String>absent();
94     }
95 }