Remove Rfc8040.Capabilities
[netconf.git] / restconf / restconf-nb-rfc8040 / src / main / java / org / opendaylight / restconf / nb / rfc8040 / utils / mapping / RestconfMappingNodeUtil.java
1 /*
2  * Copyright (c) 2016 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.restconf.nb.rfc8040.utils.mapping;
9
10 import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.$YangModuleInfoImpl.qnameOf;
11
12 import com.google.common.annotations.VisibleForTesting;
13 import java.net.URI;
14 import java.time.Instant;
15 import java.time.OffsetDateTime;
16 import java.time.ZoneId;
17 import java.time.format.DateTimeFormatter;
18 import java.util.Collection;
19 import java.util.Optional;
20 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
21 import org.opendaylight.restconf.nb.rfc8040.AbstractReplayParameter;
22 import org.opendaylight.restconf.nb.rfc8040.DepthParameter;
23 import org.opendaylight.restconf.nb.rfc8040.FieldsParameter;
24 import org.opendaylight.restconf.nb.rfc8040.FilterParameter;
25 import org.opendaylight.restconf.nb.rfc8040.WithDefaultsParameter;
26 import org.opendaylight.restconf.nb.rfc8040.utils.parser.IdentifierCodec;
27 import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.RestconfState;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.Capabilities;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.streams.Stream;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.streams.stream.Access;
32 import org.opendaylight.yangtools.yang.common.QName;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
36 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
40 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
41 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
42 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
43 import org.opendaylight.yangtools.yang.model.api.Module;
44 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
45 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
46
47 /**
48  * Util class for mapping nodes.
49  */
50 public final class RestconfMappingNodeUtil {
51     private static final QName CAPABILITY_QNAME = qnameOf("capability");
52     @VisibleForTesting
53     static final QName DESCRIPTION_QNAME = qnameOf("description");
54     @VisibleForTesting
55     static final QName ENCODING_QNAME = qnameOf("encoding");
56     @VisibleForTesting
57     static final QName LOCATION_QNAME = qnameOf("location");
58     @VisibleForTesting
59     static final QName NAME_QNAME = qnameOf("name");
60     @VisibleForTesting
61     static final QName REPLAY_SUPPORT_QNAME = qnameOf("replay-support");
62     @VisibleForTesting
63     static final QName REPLAY_LOG_CREATION_TIME = qnameOf("replay-log-creation-time");
64
65     private RestconfMappingNodeUtil() {
66         // Hidden on purpose
67     }
68
69     /**
70      * Map capabilites by ietf-restconf-monitoring.
71      *
72      * @param monitoringModule ietf-restconf-monitoring module
73      * @return mapped capabilites
74      */
75     public static ContainerNode mapCapabilites(final Module monitoringModule) {
76         return Builders.containerBuilder()
77             .withNodeIdentifier(new NodeIdentifier(RestconfState.QNAME))
78             .withChild(Builders.containerBuilder()
79                 .withNodeIdentifier(new NodeIdentifier(Capabilities.QNAME))
80                 .withChild(Builders.<String>orderedLeafSetBuilder()
81                     .withNodeIdentifier(new NodeIdentifier(CAPABILITY_QNAME))
82                     .withChildValue(DepthParameter.capabilityUri().toString())
83                     .withChildValue(FieldsParameter.capabilityUri().toString())
84                     .withChildValue(FilterParameter.capabilityUri().toString())
85                     .withChildValue(AbstractReplayParameter.capabilityUri().toString())
86                     .withChildValue(WithDefaultsParameter.capabilityUri().toString())
87                     .build())
88                 .build())
89             .build();
90     }
91
92     /**
93      * Map data of yang notification to normalized node according to ietf-restconf-monitoring.
94      *
95      * @param notifiQName qname of notification from listener
96      * @param notifications list of notifications for find schema of notification by notifiQName
97      * @param start start-time query parameter of notification
98      * @param outputType output type of notification
99      * @param uri location of registered listener for sending data of notification
100      * @return mapped data of notification - map entry node if parent exists,
101      *         container streams with list and map entry node if not
102      */
103     public static MapEntryNode mapYangNotificationStreamByIetfRestconfMonitoring(final QName notifiQName,
104             final Collection<? extends NotificationDefinition> notifications, final Instant start,
105             final String outputType, final URI uri) {
106         for (final NotificationDefinition notificationDefinition : notifications) {
107             if (notificationDefinition.getQName().equals(notifiQName)) {
108                 final String streamName = notifiQName.getLocalName();
109                 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
110                     Builders.mapEntryBuilder()
111                         .withNodeIdentifier(NodeIdentifierWithPredicates.of(Stream.QNAME, NAME_QNAME, streamName))
112                         .withChild(ImmutableNodes.leafNode(NAME_QNAME, streamName));
113
114                 notificationDefinition.getDescription().ifPresent(
115                     desc -> streamEntry.withChild(ImmutableNodes.leafNode(DESCRIPTION_QNAME, desc)));
116                 streamEntry.withChild(ImmutableNodes.leafNode(REPLAY_SUPPORT_QNAME, Boolean.TRUE));
117                 if (start != null) {
118                     streamEntry.withChild(ImmutableNodes.leafNode(REPLAY_LOG_CREATION_TIME,
119                         DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start,
120                             ZoneId.systemDefault()))));
121                 }
122
123                 return streamEntry
124                     .withChild(createAccessList(outputType, uri))
125                     .build();
126             }
127         }
128
129         throw new RestconfDocumentedException(notifiQName + " doesn't exist in any modul");
130     }
131
132     private static MapNode createAccessList(final String outputType, final URI uriToWebsocketServer) {
133         return Builders.mapBuilder()
134             .withNodeIdentifier(new NodeIdentifier(Access.QNAME))
135             .withChild(Builders.mapEntryBuilder()
136                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(Access.QNAME, ENCODING_QNAME, outputType))
137                 .withChild(ImmutableNodes.leafNode(ENCODING_QNAME, outputType))
138                 .withChild(ImmutableNodes.leafNode(LOCATION_QNAME, uriToWebsocketServer.toString()))
139                 .build())
140             .build();
141     }
142
143     /**
144      * Map data of data change notification to normalized node according to ietf-restconf-monitoring.
145      *
146      * @param path path of data to listen on
147      * @param start start-time query parameter of notification
148      * @param outputType output type of notification
149      * @param uri location of registered listener for sending data of notification
150      * @param schemaContext schemaContext for parsing instance identifier to get schema node of data
151      * @return mapped data of notification - map entry node if parent exists,
152      *         container streams with list and map entry node if not
153      */
154     public static MapEntryNode mapDataChangeNotificationStreamByIetfRestconfMonitoring(
155             final YangInstanceIdentifier path, final Instant start, final String outputType, final URI uri,
156             final EffectiveModelContext schemaContext, final String streamName) {
157         final SchemaNode schemaNode = ParserIdentifier.toInstanceIdentifier(
158             IdentifierCodec.serialize(path, schemaContext), schemaContext, Optional.empty()).getSchemaNode();
159         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
160             Builders.mapEntryBuilder()
161                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(Stream.QNAME, NAME_QNAME, streamName))
162                 .withChild(ImmutableNodes.leafNode(NAME_QNAME, streamName));
163
164         schemaNode.getDescription().ifPresent(desc ->
165             streamEntry.withChild(ImmutableNodes.leafNode(DESCRIPTION_QNAME, desc)));
166
167         return streamEntry
168             .withChild(ImmutableNodes.leafNode(REPLAY_SUPPORT_QNAME, Boolean.TRUE))
169             .withChild(ImmutableNodes.leafNode(REPLAY_LOG_CREATION_TIME,
170                 DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(start, ZoneId.systemDefault()))))
171             .withChild(createAccessList(outputType, uri))
172             .build();
173     }
174 }