141ba8471d20cf103706c6ae3bc404e7a3d2356f
[vfc/nfvo/driver/vnfm/svnfm.git] / nokiav2 / driver / src / main / java / org / onap / vfc / nfvo / driver / vnfm / svnfm / nokia / onap / direct / AAIRestApiProvider.java
1 /*
2  * Copyright 2016-2017, Nokia Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct;
17
18 import com.google.common.annotations.VisibleForTesting;
19 import org.onap.aai.restclient.client.Headers;
20 import org.onap.aai.restclient.client.OperationResult;
21 import org.onap.aai.restclient.client.RestClient;
22 import org.onap.aai.restclient.enums.RestAuthenticationMode;
23 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.MsbApiProvider;
24 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions;
25 import org.slf4j.Logger;
26 import org.springframework.beans.factory.annotation.Autowired;
27 import org.springframework.beans.factory.annotation.Value;
28 import org.springframework.context.annotation.Conditional;
29 import org.springframework.http.MediaType;
30 import org.springframework.stereotype.Component;
31
32 import javax.xml.bind.JAXBContext;
33 import java.io.ByteArrayOutputStream;
34 import java.io.StringReader;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.NoSuchElementException;
39
40 import static com.google.common.collect.Lists.newArrayList;
41 import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE;
42 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.SelfRegistrationManager.SERVICE_NAME;
43 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
44 import static org.slf4j.LoggerFactory.getLogger;
45
46 /**
47  * Responsible for providing access to AAI APIs.
48  * Handles authentication and mandatory parameters.
49  */
50 @Component
51 @Conditional(value = Conditions.UseForDirect.class)
52 public class AAIRestApiProvider {
53     private static final String AAI_VERSION = "v11";
54     private static Logger logger = getLogger(AAIRestApiProvider.class);
55     private final MsbApiProvider msbApiProvider;
56     @Value("${aaiUsername}")
57     private String aaiUsername;
58     @Value("${aaiPassword}")
59     private String aaiPassword;
60
61     @Autowired
62     AAIRestApiProvider(MsbApiProvider msbApiProvider) {
63         this.msbApiProvider = msbApiProvider;
64     }
65
66     /**
67      * @param logger  the logger of the class that requests unmarshalling
68      * @param service the AAI service of the request
69      * @param url     the URL of the request after the base URL (ex. /cloud-infrastructure/...)
70      * @param clazz   the class of the result
71      * @param <T>     the type of the result
72      * @return the result of the GET request
73      */
74     public <T> T get(Logger logger, AAIService service, String url, Class<T> clazz) {
75         return expectSuccess(logger, buildClient().get(getBaseUrl(service.getServiceName()) + url, buildCommonHeaders(), APPLICATION_XML_TYPE), clazz, url);
76     }
77
78     /**
79      * @param logger  the logger of the class that requests unmarshalling
80      * @param service the AAI service of the request
81      * @param url     the URL of the request after the base URL (ex. /cloud-infrastructure/...)
82      * @param payload the payload of the request (non serialized)
83      * @param clazz   the class of the result
84      * @param <T>     the type of the result
85      * @return the result of the PUT request
86      */
87     public <T, S> T put(Logger logger, AAIService service, String url, S payload, Class<T> clazz) {
88         String marshalledContent = marshall(payload);
89         OperationResult result = buildClient().put(getBaseUrl(service.getServiceName()) + url, marshalledContent, buildCommonHeaders(), APPLICATION_XML_TYPE, APPLICATION_XML_TYPE);
90         return expectSuccess(logger, result, clazz, url);
91     }
92
93     /**
94      * Execute a delete request on the given URL
95      *
96      * @param logger  the logger of the class that requests unmarshalling
97      * @param service the AAI service of the request
98      * @param url     the URL of the request after the base URL (ex. /cloud-infrastructure/...)
99      */
100     public void delete(Logger logger, AAIService service, String url) {
101         buildClient().delete(getBaseUrl(service.getServiceName()) + url, buildCommonHeaders(), APPLICATION_XML_TYPE);
102     }
103
104     /**
105      * @param serviceName the name of the AAI service on MSB
106      * @return the base URL of the service
107      */
108     private String getBaseUrl(String serviceName) {
109         return msbApiProvider.getMicroServiceUrl(serviceName, AAI_VERSION);
110     }
111
112     private <T> T expectSuccess(Logger logger, OperationResult result, Class<T> clazz, String url) {
113         if (!result.wasSuccessful()) {
114             if (result.getResultCode() == 404) {
115                 logger.debug("The resource at " + url + " does not exists");
116                 throw new NoSuchElementException("The resource at " + url + " does not exists");
117             }
118             throw buildFatalFailure(logger, "Bad response. Code: " + result.getResultCode() + " cause: " + result.getFailureCause());
119         }
120         if (clazz.isAssignableFrom(Void.class)) {
121             return null;
122         }
123         return unmarshal(result.getResult(), clazz);
124     }
125
126     private <T> T unmarshal(String content, Class<T> clazz) {
127         try {
128             return (T) JAXBContext.newInstance(clazz).createUnmarshaller().unmarshal(new StringReader(content));
129         } catch (Exception e) {
130             throw buildFatalFailure(logger, "Unable to unmarshal content", e);
131         }
132     }
133
134     private String marshall(Object object) {
135         try {
136             ByteArrayOutputStream bos = new ByteArrayOutputStream();
137             JAXBContext.newInstance(object.getClass()).createMarshaller().marshal(object, bos);
138             return bos.toString();
139         } catch (Exception e) {
140             throw buildFatalFailure(logger, "Unable to marshal content", e);
141         }
142     }
143
144     /**
145      * @return the common mandatory headers for AAI requests
146      */
147     private Map<String, List<String>> buildCommonHeaders() {
148         Map<String, List<String>> headers = new HashMap<>();
149         headers.put(Headers.ACCEPT, newArrayList(MediaType.APPLICATION_XML_VALUE));
150         headers.put(Headers.FROM_APP_ID, newArrayList(SERVICE_NAME));
151         return headers;
152     }
153
154
155     private RestClient buildClient() {
156         return buildRawClient().basicAuthUsername(aaiUsername).basicAuthPassword(aaiPassword).authenticationMode(RestAuthenticationMode.SSL_BASIC);
157     }
158
159     @VisibleForTesting
160     RestClient buildRawClient() {
161         return new RestClient();
162     }
163
164     public enum AAIService {
165         NETWORK {
166             String getServiceName() {
167                 return "aai-network";
168             }
169         },
170         ESR {
171             String getServiceName() {
172                 return "aai-externalSystem";
173             }
174         },
175         CLOUD {
176             String getServiceName() {
177                 return "aai-cloudInfrastructure";
178             }
179         };
180
181         abstract String getServiceName();
182     }
183 }