89ebbe5a8a1ce51c1a5e5122472d41b65709caa8
[portal/sdk.git] /
1 /*
2  * ============LICENSE_START==========================================
3  * ONAP Portal SDK
4  * ===================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * ===================================================================
7  *
8  * Unless otherwise specified, all software contained herein is licensed
9  * under the Apache License, Version 2.0 (the “License”);
10  * you may not use this software except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *             http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * Unless otherwise specified, all documentation contained herein is licensed
22  * under the Creative Commons License, Attribution 4.0 Intl. (the “License”);
23  * you may not use this documentation except in compliance with the License.
24  * You may obtain a copy of the License at
25  *
26  *             https://creativecommons.org/licenses/by/4.0/
27  *
28  * Unless required by applicable law or agreed to in writing, documentation
29  * distributed under the License is distributed on an "AS IS" BASIS,
30  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  * See the License for the specific language governing permissions and
32  * limitations under the License.
33  *
34  * ============LICENSE_END============================================
35  *
36  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
37  */
38 package org.onap.portalsdk.core.restful.client;
39
40 import java.net.URI;
41 import java.util.HashMap;
42 import java.util.List;
43
44 import org.apache.http.client.utils.URIBuilder;
45 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
46 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
47 import org.onap.portalsdk.core.onboarding.util.PortalApiProperties;
48 import org.onap.portalsdk.core.restful.domain.SharedContext;
49 import org.onap.portalsdk.core.util.SystemProperties;
50 import org.springframework.beans.factory.annotation.Autowired;
51 import org.springframework.stereotype.Component;
52
53 import com.fasterxml.jackson.core.JsonParseException;
54 import com.fasterxml.jackson.core.JsonProcessingException;
55 import com.fasterxml.jackson.core.type.TypeReference;
56 import com.fasterxml.jackson.databind.JsonMappingException;
57 import com.fasterxml.jackson.databind.ObjectMapper;
58
59 /**
60  * Provides convenience methods to use the shared-context service at Portal.
61  * This hides all JSON; instead it accepts and returns Java objects. Usage
62  * caveats (repeated from superclass):
63  * <OL>
64  * <LI>Must be auto-wired by Spring, because this in turn auto-wires a data
65  * access service to read application credentials from the FN_APP table.
66  * <LI>If HTTP access is used and the server uses a self-signed certificate, the
67  * local trust store must be extended appropriately. The HTTP client throws
68  * exceptions if the JVM cannot validate the server certificate.
69  * </OL>
70  */
71 @Component
72 public class SharedContextRestClient extends PortalRestClientBase {
73
74         private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SharedContextRestClient.class);
75
76         /**
77          * Reusable JSON (de)serializer
78          */
79         private final ObjectMapper mapper = new ObjectMapper();
80
81         /**
82          * Builds the URl for the shared context service using the portal.properties
83          * value for the AUXAPI endpoint.
84          * 
85          * @throws Exception
86          *             if the ECOMP_REST_URL property is not found 
87          */
88         private String getSharedContextUrl() throws Exception {
89                 String restUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL);
90                 if (restUrl == null || restUrl.length() == 0)
91                         throw new Exception("getSharedContextUrl: no property " + PortalApiConstants.ECOMP_REST_URL);
92                 String contextUrl = restUrl + (restUrl.endsWith("/") ? "" : "/") + "context/";
93                 return contextUrl;
94         }
95
96         /**
97          * Gets the shared-context value for the specified context ID and key.
98          * 
99          * @param contextId
100          *            An Ecomp Portal session ID
101          * @param key
102          *            Key for the shared-context entry; e.g., "lastName"
103          * @return SharedContext object; null if not found.
104          * @throws Exception
105          */
106         public SharedContext getContextValue(String contextId, String key) throws Exception {
107                 HttpStatusAndResponse hsr = getContext("get", contextId, key);
108                 logger.info(EELFLoggerDelegate.debugLogger, "getSharedContext: resp is " + hsr);
109                 if (hsr == null) {
110                         logger.error(EELFLoggerDelegate.applicationLogger, "getContextValue: unexpected null response");
111                         return null;
112                 }
113                 SharedContext jsonObj = null;
114                 try {
115                         jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class);
116                 } catch (JsonMappingException ex) {
117                         logger.error(EELFLoggerDelegate.applicationLogger,
118                                         "getContextValue: failed to map response onto object" + ex.getMessage());
119                 } catch (JsonParseException ex) {
120                         logger.info(EELFLoggerDelegate.applicationLogger,
121                                         "getContextValue: failed to parse response" + ex.getMessage());
122                 }
123                 if (jsonObj != null && jsonObj.getResponse() != null)
124                         return null;
125                 return jsonObj;
126         }
127
128         /**
129          * Gets user information for the specified context ID.
130          * 
131          * @param contextId
132          *            An Ecomp Portal session ID
133          * @return List of SharedContext objects corresponding to the following
134          *         keys: USER_FIRST_NAME, USER_LAST_NAME, USER_EMAIL and
135          *         USER_ORGUSERID; empty if none were found; null if an error
136          *         happens.
137          * @throws Exception
138          */
139         public List<SharedContext> getUserContext(String contextId) throws Exception {
140                 HttpStatusAndResponse hsr = getContext("get_user", contextId, null);
141                 logger.info(EELFLoggerDelegate.debugLogger, "getUserContext: resp is " + hsr);
142                 if (hsr == null) {
143                         logger.error(EELFLoggerDelegate.applicationLogger, "getUserContext: unexpected null response");
144                         return null;
145                 }
146                 List<SharedContext> jsonList = null;
147                 try {
148                         TypeReference<List<SharedContext>> typeRef = new TypeReference<List<SharedContext>>() {
149                         };
150                         jsonList = mapper.readValue(hsr.getResponse(), typeRef);
151                 } catch (JsonMappingException ex) {
152                         logger.error(EELFLoggerDelegate.applicationLogger,
153                                         "getUserContext: failed to map response onto object" + ex.getMessage());
154                 } catch (JsonParseException ex) {
155                         logger.error(EELFLoggerDelegate.applicationLogger,
156                                         "getUserContext: failed to parse response" + ex.getMessage());
157                 }
158                 return jsonList;
159         }
160
161         /**
162          * Checks whether a shared-context entry exists for the specified context ID
163          * and key.
164          * 
165          * @param contextId
166          *            An Ecomp Portal session ID
167          * @param key
168          *            Key for the shared-context entry; e.g., "lastName"
169          * @return True if the object exists, false otherwise; null on error.
170          * @throws Exception
171          */
172         public Boolean checkSharedContext(String contextId, String key) throws Exception {
173                 HttpStatusAndResponse hsr = getContext("check", contextId, key);
174                 logger.info(EELFLoggerDelegate.debugLogger, "checkSharedContext: resp is " + hsr);
175                 if (hsr == null) {
176                         logger.error(EELFLoggerDelegate.applicationLogger, "checkSharedContext: unexpected null response");
177                         return null;
178                 }
179                 String response = null;
180                 try {
181                         SharedContext jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class);
182                         response = jsonObj.getResponse();
183                 } catch (JsonMappingException ex) {
184                         logger.error(EELFLoggerDelegate.applicationLogger,
185                                         "checkSharedContext: failed to map response onto object" + ex.getMessage());
186                 } catch (JsonParseException ex) {
187                         logger.error(EELFLoggerDelegate.applicationLogger,
188                                         "checkSharedContext: failed to parse response" + ex.getMessage());
189                 }
190                 if (response == null)
191                         return null;
192                 return ("exists".equals(response));
193         }
194
195         /**
196          * Removes a shared-context entry with the specified context ID and key.
197          * 
198          * @param contextId
199          *            An Ecomp Portal session ID
200          * @param key
201          *            Key for the shared-context entry; e.g., "lastName"
202          * @return True if the entry was removed, false otherwise; null on error.
203          * @throws Exception
204          */
205         public Boolean removeSharedContext(String contextId, String key) throws Exception {
206                 HttpStatusAndResponse hsr = getContext("remove", contextId, key);
207                 logger.info(EELFLoggerDelegate.debugLogger, "removeSharedContext: resp is " + hsr);
208                 if (hsr == null) {
209                         logger.error(EELFLoggerDelegate.applicationLogger, "removeSharedContext: unexpected null response");
210                         return null;
211                 }
212                 SharedContext jsonObj = null;
213                 try {
214                         jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class);
215                 } catch (JsonMappingException ex) {
216                         logger.error(EELFLoggerDelegate.applicationLogger,
217                                         "removeSharedContext: failed to map response onto object" + ex.getMessage());
218                 } catch (JsonParseException ex) {
219                         logger.error(EELFLoggerDelegate.applicationLogger,
220                                         "removeSharedContext: failed to parse response" + ex.getMessage());
221                 }
222                 if (jsonObj == null)
223                         return null;
224                 String response = jsonObj.getResponse();
225                 return ("removed".equals(response));
226         }
227
228         /**
229          * Clears the shared context for the specified context ID; i.e., removes all
230          * key-value pairs.
231          * 
232          * @param contextId
233          *            An Ecomp Portal session ID
234          * @return Number of key-value pairs removed; -1 if not found or any
235          *         problems occur.
236          * @throws Exception
237          */
238         public int clearSharedContext(String contextId) throws Exception {
239                 HttpStatusAndResponse hsr = getContext("remove", contextId, null);
240                 logger.info(EELFLoggerDelegate.debugLogger, "clearSharedContext: resp is " + hsr);
241                 if (hsr == null) {
242                         logger.error(EELFLoggerDelegate.applicationLogger, "clearSharedContext: unexpected null response");
243                         return -1;
244                 }
245                 SharedContext jsonObj = null;
246                 try {
247                         jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class);
248                 } catch (JsonMappingException ex) {
249                         logger.error(EELFLoggerDelegate.applicationLogger,
250                                         "clearSharedContext: failed to map response onto object" + ex.getMessage());
251                 } catch (JsonParseException ex) {
252                         logger.error(EELFLoggerDelegate.applicationLogger,
253                                         "clearSharedContext: failed to parse response" + ex.getMessage());
254                 }
255                 if (jsonObj == null)
256                         return -1;
257                 String response = jsonObj.getResponse();
258                 if (response == null)
259                         return -1;
260                 return Integer.parseInt(response);
261         }
262
263         /**
264          * Creates a shared-context entry.
265          * 
266          * @param contextId
267          *            An Ecomp Portal session ID
268          * @param key
269          *            Key for the shared-context entry; e.g., "lastName"
270          * @param value
271          *            Value for the entry
272          * @throws Exception
273          * @return True if the object previously existed, false otherwise; null if
274          *         any problem happened.
275          */
276         public Boolean setSharedContext(String contextId, String key, String value) throws Exception {
277                 String body = buildContext(contextId, key, value);
278                 HttpStatusAndResponse hsr = postContext("set", body);
279                 logger.info(EELFLoggerDelegate.debugLogger, "setSharedContext: resp is " + hsr);
280                 if (hsr == null) {
281                         logger.error(EELFLoggerDelegate.applicationLogger, "setSharedContext: unexpected null response");
282                         return null;
283                 }
284                 SharedContext jsonObj = null;
285                 try {
286                         jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class);
287                 } catch (JsonMappingException ex) {
288                         logger.error(EELFLoggerDelegate.applicationLogger,
289                                         "setSharedContext: failed to map response onto object" + ex.getMessage());
290                 } catch (JsonParseException ex) {
291                         logger.error(EELFLoggerDelegate.applicationLogger,
292                                         "setSharedContext: failed to parse response" + ex.getMessage());
293                 }
294                 if (jsonObj == null)
295                         return null;
296                 String response = jsonObj.getResponse();
297                 return ("replaced".equals(response));
298         }
299
300         /**
301          * Builds the full URL with the specified parameters, then calls the method
302          * that adds credentials and GETs.
303          * 
304          * @param requestPath
305          * @param contextId
306          * @param contextKey
307          * @return HttpStatusAndResponse object; may be null.
308          * @throws Exception
309          */
310         private HttpStatusAndResponse getContext(String requestPath, String contextId, String contextKey) throws Exception {
311                 URIBuilder uriBuilder = new URIBuilder(getSharedContextUrl() + requestPath);
312                 uriBuilder.addParameter("context_id", contextId);
313                 if (contextKey != null)
314                         uriBuilder.addParameter("ckey", contextKey);
315                 final URI uri = uriBuilder.build();
316                 return getRestWithCredentials(uri);
317         }
318
319         /**
320          * Builds the full URL, then calls the method that adds credentials and
321          * POSTs.
322          * 
323          * @param requestPath
324          * @param contextId
325          * @param contextKey
326          * @return HttpStatusAndResponse object; may be null.
327          * @throws Exception
328          */
329         private HttpStatusAndResponse postContext(String requestPath, String json) throws Exception {
330                 URIBuilder uriBuilder = new URIBuilder(getSharedContextUrl() + requestPath);
331                 URI uri = uriBuilder.build();
332                 return postRestWithCredentials(uri, json);
333         }
334
335         /**
336          * Builds a JSON block with a single shared-context entry.
337          * 
338          * @param cxid
339          *            Context ID
340          * @param ckey
341          *            Context Key
342          * @param cvalue
343          *            Context value
344          * @return JSON block
345          */
346         private String buildContext(String cxid, String ckey, String cvalue) throws JsonProcessingException {
347                 ObjectMapper mapper = new ObjectMapper();
348                 HashMap<String, String> stringMap = new HashMap<String, String>();
349                 stringMap.put("context_id", cxid);
350                 stringMap.put("ckey", ckey);
351                 stringMap.put("cvalue", cvalue);
352                 String json = mapper.writeValueAsString(stringMap);
353                 return json;
354         }
355
356         // Simple test scaffold
357         public static void main(String[] args) throws Exception {
358                 // ObjectMapper mapper = new ObjectMapper();
359                 // SharedContext cxt = mapper.readValue("{ \"response\":\"foo\" }",
360                 // SharedContext.class);
361                 SharedContextRestClient client = new SharedContextRestClient();
362                 SharedContext get = client.getContextValue("abc", "123");
363                 System.out.println("Get yields " + get.toString());
364         }
365
366 }