8ca8ca36e8962f2a3fa33c8b5ecb65620264047d
[policy/common.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2017-2019, 2021 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.common.endpoints.http.client;
22
23 import java.security.KeyManagementException;
24 import java.security.NoSuchAlgorithmException;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Properties;
29 import java.util.regex.Pattern;
30 import org.apache.commons.lang3.StringUtils;
31 import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
32 import org.onap.policy.common.endpoints.http.client.internal.JerseyClient;
33 import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
34 import org.onap.policy.common.endpoints.utils.PropertyUtils;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * HTTP client factory implementation indexed by name.
40  */
41 class IndexedHttpClientFactory implements HttpClientFactory {
42     private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*");
43
44     /**
45      * Logger.
46      */
47     private static Logger logger = LoggerFactory.getLogger(IndexedHttpClientFactory.class);
48
49     protected HashMap<String, HttpClient> clients = new HashMap<>();
50
51     @Override
52     public synchronized HttpClient build(BusTopicParams busTopicParams) throws HttpClientConfigException {
53         if (clients.containsKey(busTopicParams.getClientName())) {
54             return clients.get(busTopicParams.getClientName());
55         }
56
57         JerseyClient client;
58         try {
59             client = new JerseyClient(busTopicParams);
60         } catch (KeyManagementException | NoSuchAlgorithmException | ClassNotFoundException e) {
61             throw new HttpClientConfigException(e);
62         }
63
64         if (busTopicParams.isManaged()) {
65             clients.put(busTopicParams.getClientName(), client);
66         }
67
68         return client;
69     }
70
71     @Override
72     public synchronized List<HttpClient> build(Properties properties) throws HttpClientConfigException {
73         ArrayList<HttpClient> clientList = new ArrayList<>();
74
75         String clientNames = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES);
76         if (StringUtils.isBlank(clientNames)) {
77             return clientList;
78         }
79
80         for (String clientName : COMMA_SPACE_PAT.split(clientNames)) {
81             addClient(clientList, clientName, properties);
82         }
83
84         return clientList;
85     }
86
87     private void addClient(ArrayList<HttpClient> clientList, String clientName, Properties properties) {
88         String clientPrefix = PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + clientName;
89
90         var props = new PropertyUtils(properties, clientPrefix,
91             (name, value, ex) ->
92                 logger.warn("{}: {} {} is in invalid format for http client {} ", this, name, value, clientName));
93
94         var port = props.getInteger(PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, -1);
95         if (port < 0) {
96             logger.warn("No HTTP port for client in {}", clientName);
97             return;
98         }
99
100         try {
101             HttpClient client = this.build(BusTopicParams.builder()
102                 .clientName(clientName)
103                 .useHttps(props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX, false))
104                 .allowSelfSignedCerts(
105                     props.getBoolean(PolicyEndPointProperties.PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX, false))
106                 .hostname(props.getString(PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, null))
107                 .port(port)
108                 .basePath(props.getString(PolicyEndPointProperties.PROPERTY_HTTP_URL_SUFFIX, null))
109                 .userName(props.getString(PolicyEndPointProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX,
110                                 null))
111                 .password(props.getString(PolicyEndPointProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX,
112                                 null))
113                 .managed(props.getBoolean(PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, true))
114                 .serializationProvider(props.getString(
115                                 PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER, null))
116                 .build());
117             clientList.add(client);
118         } catch (Exception e) {
119             logger.error("http-client-factory: cannot build client {}", clientName, e);
120         }
121     }
122
123     @Override
124     public synchronized HttpClient get(String name) {
125         if (clients.containsKey(name)) {
126             return clients.get(name);
127         }
128
129         throw new IllegalArgumentException("Http Client " + name + " not found");
130     }
131
132     @Override
133     public synchronized List<HttpClient> inventory() {
134         return new ArrayList<>(this.clients.values());
135     }
136
137     @Override
138     public synchronized void destroy(String name) {
139         if (!clients.containsKey(name)) {
140             return;
141         }
142
143         HttpClient client = clients.remove(name);
144         try {
145             client.shutdown();
146         } catch (IllegalStateException e) {
147             logger.error("http-client-factory: cannot shutdown client {}", client, e);
148         }
149     }
150
151     @Override
152     public void destroy() {
153         List<HttpClient> clientsInventory = this.inventory();
154         for (HttpClient client : clientsInventory) {
155             client.shutdown();
156         }
157
158         synchronized (this) {
159             this.clients.clear();
160         }
161     }
162
163 }