008a8fae7e34aa500fcd8b08a302988ee63ceb2e
[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.devicemanager.base.netconf.container;
23
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.lang.reflect.Proxy;
27 import java.text.DateFormat;
28 import java.text.SimpleDateFormat;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Date;
32 import java.util.List;
33 import java.util.Optional;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
35 import org.opendaylight.yangtools.yang.common.QName;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 public class Capabilities {
40
41     private static final Logger LOG = LoggerFactory.getLogger(Capabilities.class);
42     private static final String INTERFACE_AVAILABLECAPABILITY =
43             "org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability";
44
45     private final List<String> capabilities = new ArrayList<>();
46     private final DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
47
48     public Capabilities() {
49
50     }
51
52     public Capabilities(NetconfNode nnode) {
53         LOG.info("Create Capabilities constructor");
54
55         if (nnode != null) {
56             constructor(nnode.getAvailableCapabilities().getAvailableCapability());
57         }
58     }
59
60     /**
61      * Does all construction steps
62      *
63      * @param pcapabilities with a list of capabilities. <br>
64      *        Type could be <br>
65      *        - Boron: List<code><String></code> <br>
66      *        - Carbon: List<AvailableCapability>
67      */
68     private void constructor(List<?> pcapabilities) {
69         for (Object capability : pcapabilities) {
70             if (LOG.isTraceEnabled()) {
71                 LOG.trace("capability class: {} Interfaces: {}", capability.getClass().getName(),
72                         Arrays.toString(capability.getClass().getInterfaces()));
73             }
74             if (capability instanceof String) { // ODL Boron specific
75                 this.capabilities.add((String) capability);
76             } else if (hasInterface(capability, INTERFACE_AVAILABLECAPABILITY)) { // Carbon specific part .. handled via
77                                                                                   // generic
78                 try {
79                     Method method = capability.getClass().getDeclaredMethod("getCapability");
80                     this.capabilities.add(method.invoke(capability).toString());
81                 } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
82                         | InvocationTargetException e) {
83                     LOG.warn("Unknown capability class leads to a problem", e);
84                 }
85             } else {
86                 LOG.warn("Unknown capability class: {}", capability.getClass(),
87                         Arrays.toString(capability.getClass().getInterfaces()));
88             }
89         }
90     }
91
92     /**
93      * check if namespace is supported by given capabilites
94      *
95      * @param theCapability Capability to search
96      * @return true if available
97      */
98     @Deprecated
99     public boolean isSupportingNamespace(QName theCapability) {
100         String theNameSpace = theCapability.getNamespace().toString();
101         for (String capability : capabilities) {
102             if (capability.contains(theNameSpace)) {
103                 LOG.trace("Check {} against {}", capability, theNameSpace);
104                 return true;
105             }
106         }
107         return false;
108     }
109
110     /**
111      * check if the namespace and its revision are supported by the given capabilities
112      *
113      * @param qCapability capability from the model
114      * @return true if supporting the model
115      */
116     public boolean isSupportingNamespaceAndRevision(QName qCapability) {
117         String namespace = qCapability.getNamespace().toString();
118         String revision;
119         Object revisionObject = qCapability.getRevision();
120         if (revisionObject instanceof Optional) {
121             if (((Optional<?>) revisionObject).isPresent()) {
122                 revisionObject = ((Optional<?>) revisionObject).get();
123                 LOG.info("Unwrapp Optional: {}", revisionObject.getClass());
124             }
125         }
126         if (revisionObject instanceof String) {
127             revision = (String) revisionObject;
128         } else if (revisionObject instanceof Date) {
129             revision = formatter.format((Date) revisionObject);
130         } else {
131             revision = revisionObject.toString();
132             LOG.warn("Revision number type not supported. Class:{} String:{}", revisionObject.getClass().getName(),
133                     revisionObject);
134         }
135         for (String capability : capabilities) {
136             if (capability.contains(namespace) && capability.contains(revision)) {
137                 LOG.trace("Model namespace {}?[revision {}]", namespace, revision);
138                 return true;
139             }
140         }
141         return false;
142     }
143
144
145     public void add(String qname) {
146         capabilities.add(qname);
147     }
148
149     @Override
150     public String toString() {
151         return "Capabilities [capabilities=" + capabilities + "]";
152     }
153
154     /**
155      * Check if object is proxy and has specific interface
156      *
157      * @param object Name of the object to verify
158      * @param interfaceName is the name of the interface
159      * @return boolean accordingly
160      */
161     static boolean hasInterface(Object object, String interfaceName) {
162         if (object instanceof Proxy) {
163             Class<?>[] interfaces = object.getClass().getInterfaces();
164             for (Class<?> i : interfaces) {
165                 if (i.getName().equals(interfaceName)) {
166                     return true;
167                 }
168             }
169         }
170         return false;
171     }
172
173 }