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