2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 Ericsson 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.brms.api.nexus;
23 import com.google.gson.Gson;
26 import java.util.HashMap;
29 import javax.ws.rs.client.Client;
30 import javax.ws.rs.client.ClientBuilder;
31 import javax.ws.rs.client.Invocation.Builder;
32 import javax.ws.rs.core.Response;
34 import org.onap.policy.brms.api.nexus.pojo.NexusArtifact;
35 import org.onap.policy.brms.api.nexus.pojo.NexusRepository;
36 import org.onap.policy.brms.api.nexus.pojo.NexusSearchResult;
37 import org.onap.policy.common.logging.flexlogger.FlexLogger;
38 import org.onap.policy.common.logging.flexlogger.Logger;
41 * The Class NexusRestWrapper provides a Java API to a Nexus repository, wrapping the Nexus REST interface.
43 public class NexusRestWrapper {
44 private static final Logger LOGGER = FlexLogger.getLogger(NexusRestWrapper.class.getName());
46 // A web client for issuing REST requests to the Nexus server
47 private final Client client;
49 // The URL of the Nexus server
50 private final String nexusServerUrl;
52 // Credentials for Nexus server logins
53 private String nexusUser;
54 private String nexusPassword;
57 * Instantiates a new Nexus REST agent with credentials.
59 * @param nexusServerUrl the URL of the Nexus server as a string
60 * @param nexusUser the Nexus userid
61 * @param nexusPassword the Nexus password
62 * @throws NexusRestWrapperException on parameter exceptions
64 public NexusRestWrapper(final String nexusServerUrl, final String nexusUser, final String nexusPassword)
65 throws NexusRestWrapperException {
66 LOGGER.trace("new NexusRestWrapper: nexusServerUrl=" + nexusServerUrl);
68 if (isNullOrBlank(nexusServerUrl)) {
69 throw new NexusRestWrapperException("nexusServerUrl must be specified for the Nexus server");
72 if ((isNullOrBlank(nexusUser) && !isNullOrBlank(nexusPassword))
73 || (!isNullOrBlank(nexusUser) && isNullOrBlank(nexusPassword))) {
74 throw new NexusRestWrapperException(
75 "if either nexusUser or nexusPassword are specified, both must be specified");
78 this.nexusServerUrl = nexusServerUrl;
79 this.nexusUser = nexusUser;
80 this.nexusPassword = nexusPassword;
82 // Create a client for RST calls towards the Nexus server
83 client = ClientBuilder.newClient();
85 LOGGER.trace("NexusRestWrapper created: nexusServerUrl=" + nexusServerUrl);
89 * Close the REST client.
92 LOGGER.trace("NexusRestWrapper closing: url=" + nexusServerUrl);
94 // Close the web client
97 LOGGER.trace("NexusRestWrapper closed: url=" + nexusServerUrl);
101 * Find an artifact in the Nexus server.
103 * @param searchParameters
104 * the search parameters to use for the search
105 * @return the list of artifacts found that match the requested artifact
106 * @throws NexusRestWrapperException
107 * Exceptions accessing the Nexus server
109 public NexusSearchResult findArtifact(final NexusRestSearchParameters searchParameters)
110 throws NexusRestWrapperException {
111 LOGGER.trace("new search with search parameters: " + searchParameters);
113 if (null == searchParameters) {
114 throw new NexusRestWrapperException("searchParameters may not be null");
117 // Issue the REST request to perform the search
118 URI searchUri = searchParameters.getSearchUri(nexusServerUrl);
120 LOGGER.debug("search URI is: " + searchUri.toString());
122 // Compose the REST request
123 Builder requestBuilder = client.target(searchUri).request("application/json");
124 getAuthorizationHeader(requestBuilder);
126 // Issue the REST request
127 Response response = null;
129 response = requestBuilder.get();
130 } catch (Exception e) {
131 String message = "search to URI " + searchUri.toString() + " failed with message: " + e.getMessage();
132 LOGGER.warn(message, e);
133 throw new NexusRestWrapperException(message, e);
136 LOGGER.debug("search response is: " + response.toString());
138 // Check the HTTP response code for the search
139 if (Response.Status.OK.getStatusCode() != response.getStatus()) {
140 String message = "search to URI " + searchUri.toString() + " failed, response was: " + response.toString();
141 LOGGER.warn(message);
142 throw new NexusRestWrapperException(message);
146 // Get the JSON string with the the search result
147 String responseString = response.readEntity(String.class);
149 // Parse the returned JSON into result POJOs
150 NexusSearchResult searchResult = new Gson().fromJson(responseString, NexusSearchResult.class);
152 // We now need to expand the release and snapshot URL paths for each artifact
153 expandArtifactUrlPaths(searchResult);
156 } catch (Exception e) {
157 String message = "processing of result from query to Nexus failed with message: " + e.getMessage();
158 LOGGER.warn(message, e);
159 throw new NexusRestWrapperException(message, e);
164 * Get the authorisation header for the user name and password.
165 * @param requestBuilder the request builder to add authorisation to
166 * @return the authorisation header
168 private Builder getAuthorizationHeader(Builder requestBuilder) {
169 if (null != nexusUser && null != nexusPassword) {
170 String userPassString = nexusUser + ":" + nexusPassword;
171 requestBuilder.header("Authorization", "Basic "
172 + java.util.Base64.getEncoder().encodeToString(userPassString.getBytes()));
175 return requestBuilder;
179 * Use the Repository URLs in the search result to create a release and snapshot URL path for each artifact.
180 * @param searchResult the results of a Nexus server search
182 private void expandArtifactUrlPaths(NexusSearchResult searchResult) {
183 // Create a map of repositories for doing lookups
184 Map<String, NexusRepository> repositoryMap = new HashMap<>();
186 for (NexusRepository repository : searchResult.getRepoDetailsList()) {
187 repositoryMap.put(repository.getRepositoryId(), repository);
190 for (NexusArtifact artifact : searchResult.getArtifactList()) {
191 artifact.setUrlPath(composeArtifactUrlPath(repositoryMap, artifact));
196 * Compose an artifact URL path using the repository and artifact details for the artifact.
197 * @param repositoryMap the available repositories
198 * @param artifact the artifact
199 * @return the URL path
201 private String composeArtifactUrlPath(Map<String, NexusRepository> repositoryMap, NexusArtifact artifact) {
202 // We always have one hit
203 NexusRepository repository = repositoryMap.get(artifact.getArtifactHits().get(0).getRepositoryId());
205 return new StringBuilder()
206 .append(repository.getRepositoryUrl())
208 .append(artifact.getGroupId().replace('.', '/'))
210 .append(artifact.getArtifactId())
212 .append(artifact.getVersion())
214 .append(artifact.getArtifactId())
216 .append(artifact.getVersion())
221 * Check if a string is null or all white space.
223 private boolean isNullOrBlank(final String parameter) {
224 return null == parameter || parameter.trim().isEmpty();