aboutsummaryrefslogtreecommitdiffstats
path: root/BRMSGateway/src/main/java/org/onap/policy/brms/api/nexus/NexusRestWrapper.java
diff options
context:
space:
mode:
authorliamfallon <liam.fallon@ericsson.com>2018-04-24 15:29:41 +0100
committerliamfallon <liam.fallon@ericsson.com>2018-04-24 15:32:06 +0100
commit30b44d3e752d44f8f870594a05464c9e1c5158b6 (patch)
treef6f1f1f76650dbde5c8416594d3ee36ab7734155 /BRMSGateway/src/main/java/org/onap/policy/brms/api/nexus/NexusRestWrapper.java
parentab8bc20cabdbdd104a69da321d69d49662e53b92 (diff)
Implement Sonar Nexus REST interface directly
The BRMS gateway used the obsolete nexus-rest-client-java library to query the Nexus repository. This change removes that dependency and implements an interface directly to Nexus servers using the Nexus REST interface. This change is being submitted to ensure that the security issues with the plugin are resolved. The unit test for the new code will be implemented in a later submission. Issue-ID: POLICY-700 Change-Id: Ia1044e432d370034fe13f42cf7ed55d75e21187a Signed-off-by: liamfallon <liam.fallon@ericsson.com>
Diffstat (limited to 'BRMSGateway/src/main/java/org/onap/policy/brms/api/nexus/NexusRestWrapper.java')
-rw-r--r--BRMSGateway/src/main/java/org/onap/policy/brms/api/nexus/NexusRestWrapper.java233
1 files changed, 233 insertions, 0 deletions
diff --git a/BRMSGateway/src/main/java/org/onap/policy/brms/api/nexus/NexusRestWrapper.java b/BRMSGateway/src/main/java/org/onap/policy/brms/api/nexus/NexusRestWrapper.java
new file mode 100644
index 000000000..afa3e3794
--- /dev/null
+++ b/BRMSGateway/src/main/java/org/onap/policy/brms/api/nexus/NexusRestWrapper.java
@@ -0,0 +1,233 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 Ericsson Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.brms.api.nexus;
+
+import com.google.gson.Gson;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation.Builder;
+import javax.ws.rs.core.Response;
+
+import org.onap.policy.brms.api.nexus.pojo.NexusArtifact;
+import org.onap.policy.brms.api.nexus.pojo.NexusRepository;
+import org.onap.policy.brms.api.nexus.pojo.NexusSearchResult;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+
+/**
+ * The Class NexusRestWrapper provides a Java API to a Nexus repository, wrapping the Nexus REST interface.
+ */
+public class NexusRestWrapper {
+ private static final Logger LOGGER = FlexLogger.getLogger(NexusRestWrapper.class.getName());
+
+ // A web client for issuing REST requests to the Nexus server
+ private final Client client;
+
+ // The URL of the Nexus server
+ private final String nexusServerUrl;
+
+ // Credentials for Nexus server logins
+ private String nexusUser;
+ private String nexusPassword;
+
+ /**
+ * Instantiates a new Nexus REST agent.
+ *
+ * @param nexusServerUrl the URL of the Nexus server as a string
+ * @throws NexusRestWrapperException on errors on the Nexus server URL
+ */
+ public NexusRestWrapper(final String nexusServerUrl) throws NexusRestWrapperException {
+ LOGGER.trace("new NexusRestWrapper: nexusServerUrl=" + nexusServerUrl);
+
+ if (isNullOrBlank(nexusServerUrl)) {
+ throw new NexusRestWrapperException("nexusServerUrl must be specified for the Nexus server");
+ }
+
+ this.nexusServerUrl = nexusServerUrl;
+
+ // Create a client for RST calls towards the Nexus server
+ client = ClientBuilder.newClient();
+ }
+
+ /**
+ * Instantiates a new Nexus REST agent with credentials.
+ *
+ * @param nexusServerUrl the URL of the Nexus server as a string
+ * @param nexusUser the Nexus userid
+ * @param nexusPassword the Nexus password
+ * @throws NexusRestWrapperException on parameter exceptions
+ */
+ public NexusRestWrapper(final String nexusServerUrl, final String nexusUser, final String nexusPassword)
+ throws NexusRestWrapperException {
+ LOGGER.trace("new NexusRestWrapper: nexusServerUrl=" + nexusServerUrl);
+
+ if (isNullOrBlank(nexusServerUrl)) {
+ throw new NexusRestWrapperException("nexusServerUrl must be specified for the Nexus server");
+ }
+
+ if (isNullOrBlank(nexusUser) || isNullOrBlank(nexusPassword)) {
+ throw new NexusRestWrapperException("nexuusUser and nexusPassword must both be specified");
+ }
+
+ this.nexusServerUrl = nexusServerUrl;
+ this.nexusUser = nexusUser;
+ this.nexusPassword = nexusPassword;
+
+ // Create a client for RST calls towards the Nexus server
+ client = ClientBuilder.newClient();
+
+ LOGGER.trace("NexusRestWrapper created: nexusServerUrl=" + nexusServerUrl);
+ }
+
+ /**
+ * Close the REST client.
+ */
+ public void close() {
+ LOGGER.trace("NexusRestWrapper closing: url=" + nexusServerUrl);
+
+ // Close the web client
+ client.close();
+
+ LOGGER.trace("NexusRestWrapper closed: url=" + nexusServerUrl);
+ }
+
+ /**
+ * Find an artifact in the Nexus server.
+ *
+ * @param searchParameters
+ * the search parameters to use for the search
+ * @return the list of artifacts found that match the requested artifact
+ * @throws NexusRestWrapperException
+ * Exceptions accessing the Nexus server
+ */
+ public NexusSearchResult findArtifact(final NexusRestSearchParameters searchParameters)
+ throws NexusRestWrapperException {
+
+ LOGGER.trace("new search with search parameters: " + searchParameters);
+
+ // Issue the REST request to perform the search
+ URI searchUri = searchParameters.getSearchUri(nexusServerUrl);
+
+ LOGGER.debug("search URI is: " + searchUri.toString());
+
+ // Compose the REST request
+ Builder requestBuilder = client.target(searchUri).request("application/json");
+ getAuthorizationHeader(requestBuilder);
+
+ // Issue the REST request
+ Response response = requestBuilder.get();
+
+ LOGGER.debug("search response is: " + response.toString());
+
+ // Check the HTTP response code for the search
+ if (Response.Status.OK.getStatusCode() != response.getStatus()) {
+ LOGGER.warn("search to URI " + searchUri.toString() + "failed, response was: " + response.toString());
+ throw new NexusRestWrapperException("query to Nexus failed with message: " + response.toString());
+ }
+
+ try {
+ // Get the JSON string with the the search result
+ String responseString = response.readEntity(String.class);
+
+ // Parse the returned JSON into result POJOs
+ NexusSearchResult searchResult = new Gson().fromJson(responseString, NexusSearchResult.class);
+
+ // We now need to expand the release and snapshot URL paths for each artifact
+ expandArtifactUrlPaths(searchResult);
+
+ return searchResult;
+ } catch (Exception e) {
+ LOGGER.warn("processing of result from search to URI " + searchUri
+ + " failed with message " + e.getMessage());
+ throw new NexusRestWrapperException(
+ "processing of result from query to Nexus failed with message: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Get the authorisation header for the user name and password.
+ * @param requestBuilder the request builder to add authorization to
+ * @return the authorisation header
+ */
+ private Builder getAuthorizationHeader(Builder requestBuilder) {
+ if (null != nexusUser && null != nexusPassword) {
+ String userPassString = nexusUser + ":" + nexusPassword;
+ requestBuilder.header("Authorization", "Basic "
+ + java.util.Base64.getEncoder().encodeToString(userPassString.getBytes()));
+ }
+
+ return requestBuilder;
+ }
+
+ /**
+ * Use the Repository URLs in the search result to create a release and snapshot URL path for each artifact.
+ * @param searchResult the results of a Nexus server search
+ */
+ private void expandArtifactUrlPaths(NexusSearchResult searchResult) {
+ // Create a map of repositories for doing lookups
+ Map<String, NexusRepository> repositoryMap = new HashMap<>();
+
+ for (NexusRepository repository : searchResult.getRepoDetailsList()) {
+ repositoryMap.put(repository.getRepositoryId(), repository);
+ }
+
+ for (NexusArtifact artifact : searchResult.getArtifactList()) {
+ artifact.setUrlPath(composeArtifactUrlPath(repositoryMap, artifact));
+ }
+ }
+
+ /**
+ * Compose an artifact URL path using the repository and artifact details for the artifact.
+ * @param repositoryMap the available repositories
+ * @param artifact the artifact
+ * @return the URL path
+ */
+ private String composeArtifactUrlPath(Map<String, NexusRepository> repositoryMap, NexusArtifact artifact) {
+ // We always have one hit
+ NexusRepository repository = repositoryMap.get(artifact.getArtifactHits().get(0).getRepositoryId());
+
+ return new StringBuilder()
+ .append(repository.getRepositoryUrl())
+ .append("/content/")
+ .append(artifact.getGroupId().replace('.', '/'))
+ .append('/')
+ .append(artifact.getArtifactId())
+ .append('/')
+ .append(artifact.getVersion())
+ .append('/')
+ .append(artifact.getArtifactId())
+ .append('-')
+ .append(artifact.getVersion())
+ .toString();
+ }
+
+ /**
+ * Check if a string is null or all white space.
+ */
+ private boolean isNullOrBlank(final String parameter) {
+ return null == parameter || parameter.trim().isEmpty();
+ }
+}