133868fcffc525e06436ba544c482cb70cba2ec0
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18 /**
19  * Convert capabilities of netconfnode into internal format. Boron and Carbon are providing
20  * different versions
21  */
22 package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice;
23
24 import java.text.DateFormat;
25 import java.text.SimpleDateFormat;
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.Optional;
30 import javax.annotation.Nullable;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
36 import org.opendaylight.yangtools.yang.common.QName;
37 import org.opendaylight.yangtools.yang.common.Revision;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * Wrapper class for capabilites for Boron and later releases. Uses generics because yang model was changed from Boron
43  * to later version. Interface class:
44  * org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability
45  */
46 public class Capabilities {
47
48     private static final Logger LOG = LoggerFactory.getLogger(Capabilities.class);
49
50     private static final String UNSUPPORTED = "Unsupported";
51     private final List<String> capabilities = new ArrayList<>();
52     private final DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
53
54     private Capabilities() {}
55
56     public static Capabilities getAvailableCapabilities(@Nullable NetconfNode nnode) {
57         LOG.info("GetAvailableCapabilities for node");
58         Capabilities capabilities = new Capabilities();
59         if (nnode != null) {
60             AvailableCapabilities availableCapabilites = nnode.getAvailableCapabilities();
61             if (availableCapabilites != null) {
62                 capabilities.constructor(availableCapabilites.getAvailableCapability());
63             } else {
64                 LOG.debug("empty capabilites");
65             }
66         } else {
67             LOG.debug("No node provided");
68         }
69         return capabilities;
70     }
71
72     public static Capabilities getUnavailableCapabilities(NetconfNode nnode) {
73         LOG.info("GetUnavailableCapabilities for node");
74         Capabilities capabilities = new Capabilities();
75         if (nnode != null) {
76             UnavailableCapabilities availableCapabilites = nnode.getUnavailableCapabilities();
77             if (availableCapabilites != null) {
78                 capabilities.constructor2(availableCapabilites.getUnavailableCapability());
79             } else {
80                 LOG.debug("empty capabilites");
81             }
82         } else {
83             LOG.debug("No node provided");
84         }
85         return capabilities;
86     }
87
88
89     /**
90      * Does all construction steps
91      *
92      * @param pcapabilities with a list of capabilities.
93      */
94     private void constructor(List<AvailableCapability> pcapabilities) {
95         if (pcapabilities != null) {
96             for (AvailableCapability capability : pcapabilities) {
97                 this.capabilities.add(capability.getCapability());
98             }
99         }
100     }
101
102     private void constructor2(List<UnavailableCapability> pcapabilities) {
103         if (pcapabilities != null) {
104             for (UnavailableCapability capability : pcapabilities) {
105                 this.capabilities.add(capability.getCapability());
106             }
107         }
108     }
109
110     /**
111      * Get Capabilites
112      *
113      * @return List<String> with capabilites
114      */
115     public List<String> getCapabilities() {
116         return capabilities;
117     }
118
119     /**
120      * Verify if the namespace is supported
121      *
122      * @param qCapability from model
123      * @return true if namespace is supported
124      */
125     public boolean isSupportingNamespace(QName qCapability) {
126         String namespace = qCapability.getNamespace().toString();
127         return isSupportingNamespaceAndRevision(namespace, null);
128     }
129
130     /**
131      * Verify if the namespace is supported
132      *
133      * @param namespace
134      * @return
135      */
136     public boolean isSupportingNamespace(String namespace) {
137         return isSupportingNamespaceAndRevision(namespace, null);
138     }
139
140     /**
141      * check if the namespace and its revision are supported by the given capabilities
142      *
143      * @param qCapability capability from the model
144      * @return true if supporting the model AND revision<br>
145      *         false if revision not available or both not found.
146      */
147     public boolean isSupportingNamespaceAndRevision(QName qCapability) {
148         String namespace = qCapability.getNamespace().toString();
149         String revision = getRevisionString(qCapability);
150         return revision == null ? false : isSupportingNamespaceAndRevision(namespace, revision);
151     }
152
153     /**
154      *
155      * @param namespace requested
156      * @param revision request or null for any revision
157      * @return true if existing
158      */
159     public boolean isSupportingNamespaceAndRevision(String namespace, @Nullable String revision) {
160         LOG.trace("isSupportingNamespaceAndRevision: Model namespace {}?[revision {}]", namespace, revision);
161
162         final String nsAndRev = String.format("%s?revision=%s", namespace, revision);
163         for (String capability : capabilities) {
164             //if (capability.contains(namespace) && (revision == null || capability.contains(revision))) {
165             if (capability.contains(revision != null ? nsAndRev : namespace)) {
166                 LOG.trace("Verify true with: {}", capability);
167                 return true;
168             } else {
169                 LOG.trace("Verify false with: {}", capability);
170             }
171         }
172         return false;
173     }
174
175     /**
176      * Provide revision as String from QName, considering older formats.
177      *
178      * @param qCapability that specifies the revision
179      * @return String with revisiondate or null
180      */
181     private String getRevisionString(QName qCapability) {
182         Object revisionObject = qCapability.getRevision();
183         String revision = null;
184         if (revisionObject instanceof Optional) {
185             if (((Optional<?>) revisionObject).isPresent()) {
186                 revisionObject = ((Optional<?>) revisionObject).get();
187                 LOG.info("Unwrapp Optional: {}", revisionObject != null ? revisionObject.getClass() : null);
188             }
189         }
190         if (revisionObject == null) {
191             // Cover null case
192         } else if (revisionObject instanceof String) {
193             revision = (String) revisionObject;
194         } else if (revisionObject instanceof Date) {
195             revision = formatter.format((Date) revisionObject);
196         } else {
197             revision = revisionObject.toString();
198             LOG.debug("Revision number type not supported. Use toString().String:{} Class:{} ", revisionObject,
199                     revisionObject.getClass().getName());
200         }
201         return revision;
202     }
203
204     /**
205      * Get revision of first entry of related capability
206      *
207      * @param qCapability that specifies the namespace
208      * @return String with date or
209      */
210     public String getRevisionForNamespace(QName qCapability) {
211         String namespace = qCapability.getNamespace().toString();
212         for (String capability : capabilities) {
213             if (capability.contains(namespace)) {
214                 Optional<Revision> revisionOpt = QName.create(capability).getRevision();
215                 if (revisionOpt.isPresent()) {
216                     return revisionOpt.get().toString();
217                 }
218             }
219         }
220         return UNSUPPORTED;
221     }
222
223     /**
224      * Verify if QName namespace is supported by capabilities
225      *
226      * @param revision result of getRevisionForNamespace()
227      * @return true if namespace is supported.
228      */
229     static public boolean isNamespaceSupported(String revision) {
230         return !UNSUPPORTED.equals(revision);
231     }
232
233     @Override
234     public String toString() {
235         return "Capabilities [capabilities=" + capabilities + "]";
236     }
237
238 }