diff --git a/.gitignore b/.gitignore index 01130b25..7ba6f4a1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ target/ .settings/ # Ignore this: autogenerated -core/src/main/java/org/jboss/pnc/causeway/config/constants/BuildInformationConstants.java +src/main/java/org/jboss/pnc/causeway/constants/BuildInformationConstants.java diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index ba73bbaf..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,33 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - - -## [Unreleased] - -### Changed -- [NCL-4236] Allow any authenticated user to do some stuff - -# Template - -## [] - --
-### Added -- Section - -### Changed -- Section - -### Deprecated -- Section - -### Removed -- Section - -### Fixed -- Section - -### Security -- Section - diff --git a/LICENSE-header.txt b/LICENSE-header.txt new file mode 100644 index 00000000..fc2858b1 --- /dev/null +++ b/LICENSE-header.txt @@ -0,0 +1,2 @@ +Copyright 2024 Red Hat, Inc. +SPDX-License-Identifier: Apache-2.0 diff --git a/README.md b/README.md index e5a4eaf3..d0527353 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,56 @@ -## Integration tests -Integration tests are run in phase integration-test. To run them use mvn verify. +# causeway -Tests are using by default url http://pnc-host/pnc-rest/rest to connect to PNC (you can define IP for pnc-host in your hosts file). +This project uses Quarkus, the Supersonic Subatomic Java Framework. -Alternatively you can set the value by setting system property PNC_URL (eg. -DPNC_URL=http://my-pnc-host/pnc-rest/rest) +If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ . -## Disabling integration tests for PNC -Integration tests for PNC can be disabled by setting -Ddisable-pnc-it +## Running the application in dev mode -## Dependencies -To compile causeway you need to compile: - * https://github.com/project-ncl/pnc - * https://github.com/release-engineering/kojiji +You can run your application in dev mode that enables live coding using: +```shell script +mvn compile quarkus:dev +``` -## Metrics support +> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/. -PNC tracks metrics of JVM and its internals via Dropwizard Metrics. The metrics can currently be reported to a Graphite server by specifying as system property or environment variables those properties: -- metrics\_graphite\_server (mandatory) -- metrics\_graphite\_port (mandatory) -- metrics\_graphite\_prefix (mandatory) -- metrics\_graphite\_interval (optional) +## Packaging and running the application -If the `metrics_graphite_interval` variable (interval specified in seconds) is not specified, we'll use the default value of 60 seconds to report data to Graphite. +The application can be packaged using: +```shell script +mvn package +``` +It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory. +Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory. -The graphite reporter is configured to report rates per second and durations in terms of milliseconds. +The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`. -## OIDC Client Support -We need to setup an OIDC Client to send back callback information. This is done by defining in the main.conf the following values: +If you want to build an _über-jar_, execute the following command: +```shell script +mvn package -Dquarkus.package.jar.type=uber-jar +``` -- `oidc-client.url`: Base URL of the Keycloak server -- `oidc-client.realm`: Realm used with Keycloak -- `oidc-client.client-id`: the client id name -- `oidc-client.secret-file`: the location of the file that contains the secret +The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`. -Only client credentials flow is supported for now. +## Creating a native executable + +You can create a native executable using: +```shell script +mvn package -Dnative +``` + +Or, if you don't have GraalVM installed, you can run the native executable build in a container using: +```shell script +mvn package -Dnative -Dquarkus.native.container-build=true +``` + +You can then execute your native executable with: `./target/causeway-1.0.0-SNAPSHOT-runner` + +If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling. + +## Provided Code + +### REST + +Easily start your REST Web Services + +[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources) diff --git a/application/pom.xml b/application/pom.xml deleted file mode 100644 index 5ed5bcf7..00000000 --- a/application/pom.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - 4.0.0 - - - org.jboss.pnc.causeway - causeway - 3.0.3-SNAPSHOT - - - causeway-application - ear - Causeway :: Application - - - - org.jboss.pnc.causeway - causeway-core - ejb - - - org.jboss.pnc.causeway - causeway-web - war - - - org.jboss.pnc.causeway - causeway-rest - ejb - - - - - - - src/main/resources - true - - - src/main/conf - true - ../conf - - - - - org.apache.maven.plugins - maven-ear-plugin - 2.9 - - true - 6 - lib - causeway - no-version - - - - org.jboss.pnc.causeway - causeway-core - - - org.jboss.pnc.causeway - causeway-rest - - - org.jboss.pnc.metrics - pncmetrics - / - - - org.jboss.pnc.causeway - causeway-web - - - - - - ru.concerteza.buildnumber - maven-jgit-buildnumber-plugin - 1.2.10 - - - git-buildnumber - - extract-buildnumber - - initialize - - false - - - - - - org.codehaus.mojo - buildnumber-maven-plugin - 3.2.0 - - - buildnumbers - initialize - - create - - - {0,date,yyyy-MM-dd HH:mm Z} - - - - - - - diff --git a/application/src/main/application/META-INF/application.xml b/application/src/main/application/META-INF/application.xml deleted file mode 100644 index 439f78cc..00000000 --- a/application/src/main/application/META-INF/application.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - Dependency-Analysis - Dependency-Analysis - - - causeway-core.jar - - - causeway-rest.jar - - - pncmetrics.jar - - - - causeway-web.war - causeway - - - - lib - - diff --git a/application/src/main/application/META-INF/jboss-deployment-structure.xml b/application/src/main/application/META-INF/jboss-deployment-structure.xml deleted file mode 100644 index b5b894c7..00000000 --- a/application/src/main/application/META-INF/jboss-deployment-structure.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/application/src/main/conf/main.conf b/application/src/main/conf/main.conf deleted file mode 100644 index 772fd036..00000000 --- a/application/src/main/conf/main.conf +++ /dev/null @@ -1,16 +0,0 @@ -# koji.url=https://koji.myco.com/kojihub -# koji.weburl=https://koji.myco.com/brew/buildinfo?buildID= - -# koji.client.pem.password=testtest - -# pncl.url=http://pnc-host/pnc-rest/rest -# pncl.builds.url=http://pnc-host/pnc-web/#/build-records/ - -# indy.url=http://indy-host/api - -# koji.client.pem.file = ${causeway.config.dir}/ssl/client.pem -# koji.server.pem.file = ${causeway.config.dir}/ssl/server.pem - -# http.timeout.secs = 10 -# koji.timeout.secs = ${http.timeout.secs} -# pncl.timeout.secs = ${http.timeout.secs} diff --git a/core/pom.xml b/core/pom.xml deleted file mode 100644 index 6b7d8ce5..00000000 --- a/core/pom.xml +++ /dev/null @@ -1,216 +0,0 @@ - - - 4.0.0 - - - org.jboss.pnc.causeway - causeway - 3.0.3-SNAPSHOT - - - causeway-core - ejb - Causeway :: Core Implementation - - - - org.jboss.pnc.causeway - causeway-rest - ejb - - - - org.jboss.pnc.metrics - pncmetrics - - - - org.jboss.spec.javax.enterprise.concurrent - jboss-concurrency-api_1.0_spec - jar - - - - org.commonjava.rwx - rwx-bindings - - - org.commonjava.util - configuration-api - - - org.commonjava.util - configuration-dotconf - - - com.github.zafarkhaja - java-semver - - - org.jboss.pnc - rest-client - - - commons-lang - commons-lang - - - commons-io - commons-io - - - org.commonjava.atlas - atlas-npm-identities - - - com.redhat.red.build - kojiji - - - org.commonjava.util - jhttpc - - - org.bouncycastle - bcprov-jdk18on - - - org.bouncycastle - bcpkix-jdk18on - - - org.projectlombok - lombok - - - org.keycloak - keycloak-authz-client - - - - - junit - junit - - - org.mockito - mockito-all - - - com.github.tomakehurst - wiremock - - - org.jboss.resteasy - resteasy-jackson2-provider - test - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - test - - - org.assertj - assertj-core - test - - - org.apache.commons - commons-compress - - - - - - - - org.apache.maven.plugins - maven-ejb-plugin - - - - - org.apache.httpcomponents export meta-inf - - - - - - - - - - pl.project13.maven - git-commit-id-plugin - 4.9.10 - - - - revision - - - - - - ${project.basedir}/.git - - - true - - - - com.google.code.maven-replacer-plugin - maven-replacer-plugin - 1.4.1 - - - process-sources - - replace - - - - - src/main/templates/org/jboss/pnc/causeway/config/constants/BuildInformationConstants.java - src/main/java/org/jboss/pnc/causeway/config/constants/BuildInformationConstants.java - - - @version@ - ${project.version} - - - @commit-id@ - ${git.commit.id.abbrev} - - - @build-time@ - ${maven.build.timestamp} - - - - - - - - diff --git a/core/src/main/java/org/jboss/pnc/causeway/CausewayException.java b/core/src/main/java/org/jboss/pnc/causeway/CausewayException.java deleted file mode 100644 index 87429e54..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/CausewayException.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway; - -import java.io.NotSerializableException; -import java.io.Serializable; -import java.text.MessageFormat; - -/** - * Created by jdcasey on 11/10/15. - */ -public class CausewayException extends Exception { - private static final long serialVersionUID = 1L; - - private Object[] params; - - private transient String formattedMessage; - - public CausewayException(String format, Throwable cause, Object... params) { - super(format, cause); - this.params = params; - } - - public CausewayException(String format, Object... params) { - super(format); - this.params = params; - } - - @Override - public synchronized String getMessage() { - if (formattedMessage == null) { - final String format = super.getMessage(); - if (params == null || params.length < 1) { - formattedMessage = format; - } else { - final String original = super.getMessage(); - try { - formattedMessage = String.format(format.replaceAll("\\{\\}", "%s"), params); - } catch (final Error | Exception e) { - } - - if (formattedMessage == null || original == formattedMessage) { - try { - formattedMessage = MessageFormat.format(format, params); - } catch (final Error | Exception e) { - formattedMessage = format; - throw e; - } - } - } - } - - return formattedMessage; - } - - /** - * Stringify all parameters pre-emptively on serialization, to prevent {@link NotSerializableException}. Since all - * parameters are used in {@link String#format} or {@link MessageFormat#format}, flattening them to strings is an - * acceptable way to provide this functionality without making the use of {@link Serializable} viral. - */ - private Object writeReplace() { - final Object[] newParams = new Object[params.length]; - int i = 0; - for (final Object object : params) { - newParams[i] = String.valueOf(object); - i++; - } - - params = newParams; - return this; - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/CausewayFailure.java b/core/src/main/java/org/jboss/pnc/causeway/CausewayFailure.java deleted file mode 100644 index b6626481..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/CausewayFailure.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.jboss.pnc.causeway; - -/** - * This class indicates just a failure, which can usually be solved by user themselve. - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -public class CausewayFailure extends CausewayException { - - public CausewayFailure(String format, Throwable cause, Object... params) { - super(format, cause, params); - } - - public CausewayFailure(String format, Object... params) { - super(format, params); - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/authentication/KeycloakClient.java b/core/src/main/java/org/jboss/pnc/causeway/authentication/KeycloakClient.java deleted file mode 100644 index bba480ba..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/authentication/KeycloakClient.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.authentication; - -import org.apache.http.impl.client.HttpClients; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.keycloak.authorization.client.AuthzClient; -import org.keycloak.authorization.client.Configuration; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import java.io.IOException; -import java.util.Collections; - -/** - * Helper object to obtain a fresh access token from Keycloak - */ -@ApplicationScoped -public class KeycloakClient { - - @Inject - CausewayConfig config; - - /** - * Get a fresh access token from the OIDC server - * - * @return access token - * @throws KeycloakClientException if there is an issue with the configuration - */ - public String getAccessToken() throws KeycloakClientException { - try { - final Configuration configuration = new Configuration( - config.getOidcClientUrl(), - config.getOidcClientRealm(), - config.getOidcClientClientId(), - Collections.singletonMap("secret", config.getOidcClientSecret()), - HttpClients.createDefault()); - - return AuthzClient.create(configuration).obtainAccessToken().getToken(); - } catch (IOException e) { - throw new KeycloakClientException("Exception trying to obtain an auth token", e); - } - } -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/authentication/KeycloakClientException.java b/core/src/main/java/org/jboss/pnc/causeway/authentication/KeycloakClientException.java deleted file mode 100644 index 003a99a9..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/authentication/KeycloakClientException.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.authentication; - -import org.jboss.pnc.causeway.CausewayException; - -public class KeycloakClientException extends CausewayException { - - public KeycloakClientException(String format, Throwable cause, Object... params) { - super(format, cause, params); - } - - public KeycloakClientException(String format, Object... params) { - super(format, params); - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/bpmclient/BPMClient.java b/core/src/main/java/org/jboss/pnc/causeway/bpmclient/BPMClient.java deleted file mode 100644 index c5dfcfe8..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/bpmclient/BPMClient.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.bpmclient; - -import org.jboss.pnc.api.dto.Request; -import org.jboss.pnc.causeway.rest.pnc.MilestoneReleaseResultRest; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Deprecated -public interface BPMClient { - - void error(Request callback, String callbackId, MilestoneReleaseResultRest result); - - void failure(Request callback, String callbackId, MilestoneReleaseResultRest result); - - void success(Request callback, String callbackId, MilestoneReleaseResultRest result); - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/bpmclient/BPMClientImpl.java b/core/src/main/java/org/jboss/pnc/causeway/bpmclient/BPMClientImpl.java deleted file mode 100644 index 3a8f300b..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/bpmclient/BPMClientImpl.java +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.bpmclient; - -import org.jboss.pnc.api.constants.HttpHeaders; -import org.jboss.pnc.api.constants.MDCHeaderKeys; -import org.jboss.pnc.api.dto.Request; -import org.jboss.pnc.causeway.authentication.KeycloakClient; -import org.jboss.pnc.causeway.authentication.KeycloakClientException; -import org.jboss.pnc.causeway.rest.BrewPushMilestoneResult; -import org.jboss.pnc.causeway.rest.Callback; -import org.jboss.pnc.causeway.rest.pnc.MilestoneReleaseResultRest; -import org.jboss.pnc.common.log.MDCUtils; -import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; -import org.slf4j.MDC; - -import java.util.Map; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import lombok.extern.slf4j.Slf4j; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@ApplicationScoped -@Deprecated -@Slf4j -public class BPMClientImpl implements BPMClient { - private final ResteasyClient client; - - @Inject - private KeycloakClient keycloakClient; - - public BPMClientImpl() { - client = new ResteasyClientBuilder().connectionPoolSize(4).build(); - } - - private synchronized void send(Request callback, BrewPushMilestoneResult result) { - log.info("Will send callback to {} using http method: {}", callback.getUri(), callback.getMethod()); - - ResteasyWebTarget target = client.target(callback.getUri()); - Invocation.Builder requestBuilder = target.request(MediaType.APPLICATION_JSON); - callback.getHeaders().forEach(h -> requestBuilder.header(h.getName(), h.getValue())); - - try { - requestBuilder.header(HttpHeaders.AUTHORIZATION_STRING, "Bearer " + keycloakClient.getAccessToken()); - } catch (KeycloakClientException e) { - log.error("Couldn't obtain the access token from the OIDC server", e); - } - - // Add OTEL headers from MDC context - addOtelMDCHeaders(requestBuilder); - - Response response = requestBuilder - .method(callback.getMethod().toString(), Entity.entity(result, MediaType.APPLICATION_JSON_TYPE)); - log.info( - "Callback sent to {} using http method: {}, received status: {} from location: {}", - callback.getUri(), - callback.getMethod(), - response.getStatus(), - response.getLocation()); - } - - private void addOtelMDCHeaders(Invocation.Builder request) { - headersFromMdc(request, MDCHeaderKeys.SLF4J_TRACE_ID); - headersFromMdc(request, MDCHeaderKeys.SLF4J_SPAN_ID); - Map otelHeaders = MDCUtils.getOtelHeadersFromMDC(); - otelHeaders.forEach((k, v) -> request.header(k, v)); - } - - private void headersFromMdc(Invocation.Builder request, MDCHeaderKeys headerKey) { - String mdcValue = MDC.get(headerKey.getMdcKey()); - if (mdcValue != null && mdcValue.isEmpty()) { - request.header(headerKey.getHeaderName(), mdcValue.trim()); - } - } - - @Override - public void success(Request callbackTarget, String callbackId, MilestoneReleaseResultRest result) { - log.info("Import of milestone {} ended with success.", result.getMilestoneId()); - Callback callback = new Callback(callbackId, 200); - send(callbackTarget, new BrewPushMilestoneResult(result, callback)); - } - - @Override - public void error(Request callbackTarget, String callbackId, MilestoneReleaseResultRest result) { - log.info("Import of milestone {} ended with error.", result.getMilestoneId()); - Callback callback = new Callback(callbackId, 500); - send(callbackTarget, new BrewPushMilestoneResult(result, callback)); - } - - @Override - public void failure(Request callbackTarget, String callbackId, MilestoneReleaseResultRest result) { - log.info("Import of milestone {} ended with failure.", result.getMilestoneId()); - Callback callback = new Callback(callbackId, 418); - send(callbackTarget, new BrewPushMilestoneResult(result, callback)); - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslator.java b/core/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslator.java deleted file mode 100644 index bcd0ad2f..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslator.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.brewclient; - -import com.redhat.red.build.koji.model.json.KojiImport; - -import org.jboss.pnc.api.causeway.dto.push.Build; -import org.jboss.pnc.api.causeway.dto.push.BuiltArtifact; -import org.jboss.pnc.api.causeway.dto.push.MavenBuild; -import org.jboss.pnc.api.causeway.dto.push.MavenBuiltArtifact; -import org.jboss.pnc.api.causeway.dto.push.NpmBuild; -import org.jboss.pnc.api.causeway.dto.push.NpmBuiltArtifact; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.pncclient.BuildArtifacts; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.jboss.pnc.causeway.source.RenamedSources; -import org.jboss.pnc.enums.BuildType; - -import java.io.InputStream; -import java.util.Objects; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -public interface BuildTranslator { - - @Deprecated - ImportFileGenerator getImportFiles(BuildArtifacts artifacts, RenamedSources sources, String log) - throws CausewayException; - - @Deprecated - KojiImport translate( - BrewNVR nvr, - org.jboss.pnc.dto.Build build, - BuildArtifacts artifacts, - RenamedSources sources, - String log, - String username) throws CausewayException; - - RenamedSources getSources(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts, InputStream sourcesStream) - throws CausewayException; - - String getSourcesDeployPath(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts) throws CausewayException; - - RenamedSources getSources(Build build) throws CausewayException; - - SpecialImportFileGenerator getImportFiles(Build build, RenamedSources sources) throws CausewayException; - - KojiImport translate( - BrewNVR nvr, - Build build, - RenamedSources sources, - String username, - SpecialImportFileGenerator importFiles) throws CausewayException; - - public static String guessVersion(Build build) throws CausewayException { - final Predicate filter; - final Function getVersion; - if (build instanceof MavenBuild) { - filter = (artifact -> artifact instanceof MavenBuiltArtifact); - getVersion = (artifact -> ((MavenBuiltArtifact) artifact).getVersion()); - } else if (build instanceof NpmBuild) { - filter = (artifact -> artifact instanceof NpmBuiltArtifact); - getVersion = (artifact -> ((NpmBuiltArtifact) artifact).getVersion()); - } else { - filter = (artifact -> false); - getVersion = (artifact -> null); - } - - return build.getBuiltArtifacts() - .stream() - .filter(filter) - .map(getVersion) - .filter(Objects::nonNull) - .findAny() - .orElseThrow( - () -> new CausewayException( - "Build version or BuildType (MVN,NPM...) not specified and couldn't determine any from artifacts.")); - } - - @Deprecated - public static String guessVersion(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts) - throws CausewayException { - String delim = ":"; - BuildType buildType = build.getBuildConfigRevision().getBuildType(); - - // Maven and Gradle artifacts identifiers have 4 parts (G:A:P:V = org.jboss.pnc.causeway:causeway-web:war:2.0.0) - // and Npm - // 2 (N:V = async:3.1.0) - // Last part for each is the version. - final int parts; - switch (buildType) { - case MVN: - case SBT: - case GRADLE: - parts = 4; - break; - case NPM: - parts = 2; - break; - default: - parts = 0; - break; - } - - return artifacts.buildArtifacts.stream() - .map(artifact -> artifact.identifier.split(delim)) - .filter(i -> i.length >= parts) - .map(i -> i[parts - 1]) - .findAny() - .orElseThrow( - () -> new CausewayException( - "Build version or BuildType (MVN,NPM...) not specified and couldn't determine any from artifacts.")); - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslatorImpl.java b/core/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslatorImpl.java deleted file mode 100644 index 0a960ddc..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslatorImpl.java +++ /dev/null @@ -1,631 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.brewclient; - -import com.github.zafarkhaja.semver.Version; -import com.redhat.red.build.koji.model.json.BuildContainer; -import com.redhat.red.build.koji.model.json.BuildDescription; -import com.redhat.red.build.koji.model.json.BuildOutput; -import com.redhat.red.build.koji.model.json.BuildRoot; -import com.redhat.red.build.koji.model.json.BuildTool; -import com.redhat.red.build.koji.model.json.FileBuildComponent; -import com.redhat.red.build.koji.model.json.KojiImport; -import com.redhat.red.build.koji.model.json.StandardArchitecture; -import com.redhat.red.build.koji.model.json.StandardOutputType; -import com.redhat.red.build.koji.model.json.VerificationException; -import org.commonjava.atlas.maven.ident.ref.ProjectVersionRef; -import org.commonjava.atlas.maven.ident.ref.SimpleArtifactRef; -import org.commonjava.atlas.maven.ident.ref.SimpleProjectVersionRef; -import org.commonjava.atlas.npm.ident.ref.NpmPackageRef; -import org.commonjava.atlas.npm.ident.util.NpmVersionUtils; -import org.jboss.pnc.api.causeway.dto.push.Build; -import org.jboss.pnc.api.causeway.dto.push.BuiltArtifact; -import org.jboss.pnc.api.causeway.dto.push.Dependency; -import org.jboss.pnc.api.causeway.dto.push.Logfile; -import org.jboss.pnc.api.causeway.dto.push.MavenBuild; -import org.jboss.pnc.api.causeway.dto.push.MavenBuiltArtifact; -import org.jboss.pnc.api.causeway.dto.push.NpmBuild; -import org.jboss.pnc.api.causeway.dto.push.NpmBuiltArtifact; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.CausewayFailure; -import org.jboss.pnc.causeway.ErrorMessages; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.jboss.pnc.causeway.pncclient.BuildArtifacts; -import org.jboss.pnc.causeway.pncclient.BuildArtifacts.PncArtifact; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.jboss.pnc.causeway.source.RenamedSources; -import org.jboss.pnc.causeway.source.SourceRenamer; -import org.jboss.pnc.enums.BuildType; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Paths; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import static org.jboss.pnc.constants.Attributes.BUILD_BREW_NAME; -import static org.jboss.pnc.constants.Attributes.BUILD_BREW_VERSION; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@ApplicationScoped -public class BuildTranslatorImpl implements BuildTranslator { - private static final String CONTENT_GENERATOR_NAME = "Project Newcastle"; - public static final String PNC = "PNC"; - private static final String MD5 = "md5"; - - private final CausewayConfig config; - private final SourceRenamer renamer; - - @Inject - public BuildTranslatorImpl(CausewayConfig config, SourceRenamer renamer) { - this.config = config; - this.renamer = renamer; - config.configurationDone(); - } - - @Override - public KojiImport translate( - BrewNVR nvr, - org.jboss.pnc.dto.Build build, - BuildArtifacts artifacts, - RenamedSources sources, - String log, - String username) throws CausewayException { - String externalBuildId = String.valueOf(build.getId()); - String externalBuildUrl = null; - String externalBuildsUrl = config.getPnclBuildsURL(); - if (externalBuildsUrl != null) { - externalBuildUrl = externalBuildsUrl + externalBuildId; - } - KojiImport.Builder builder = new KojiImport.Builder(); - BuildDescription.Builder descriptionBuilder = builder - .withNewBuildDescription(nvr.getKojiName(), nvr.getVersion(), nvr.getRelease()) - .withStartTime(Date.from(build.getStartTime())) - .withEndTime(Date.from(build.getEndTime())) - .withBuildSource(normalizeScmUrl(build.getScmUrl()), build.getScmRevision()) - .withExternalBuildId(externalBuildId) - .withExternalBuildUrl(externalBuildUrl) - .withBuildSystem(PNC); - setBuildType(descriptionBuilder, build, artifacts); - if (build.getScmTag() != null) { - descriptionBuilder.withSCMTag(build.getScmTag()); - } - - int buildRootId = 42; - BuildRoot.Builder buildRootBuilder = builder.withNewBuildRoot(buildRootId) - .withContentGenerator(CONTENT_GENERATOR_NAME, config.getPNCSystemVersion()) - .withContainer(getContainer(build)) - .withHost(build.getEnvironment().getAttributes().get("OS"), StandardArchitecture.noarch); - - Map tools = new HashMap<>(build.getEnvironment().getAttributes()); - addTool(buildRootBuilder, build.getBuildConfigRevision().getBuildType(), tools, build.getEnvironment().getId()); - addTools(buildRootBuilder, tools); - addDependencies(artifacts.dependencies, buildRootBuilder, build.getBuildConfigRevision().getBuildType()); - addBuiltArtifacts( - artifacts.buildArtifacts, - builder, - buildRootId, - build.getBuildConfigRevision().getBuildType()); - addLog(log, builder, buildRootId); - addSources(sources, builder, buildRootId); - - KojiImport translatedBuild = buildTranslatedBuild(builder); - translatedBuild.getBuild().getExtraInfo().setImportInitiator(username); - return translatedBuild; - } - - @Override - public KojiImport translate( - BrewNVR nvr, - Build build, - RenamedSources sources, - String username, - SpecialImportFileGenerator importFiles) throws CausewayException { - KojiImport.Builder builder = new KojiImport.Builder(); - - BuildDescription.Builder descriptionBuilder = builder - .withNewBuildDescription(nvr.getKojiName(), nvr.getVersion(), nvr.getRelease()) - .withStartTime(build.getStartTime()) - .withEndTime(build.getEndTime()) - .withBuildSource(normalizeScmUrl(build.getScmURL()), build.getScmRevision()) - .withExternalBuildId(build.getExternalBuildID()) - .withExternalBuildUrl(build.getExternalBuildURL()) - .withBuildSystem(PNC); - if (build.getScmTag() != null) { - descriptionBuilder.withSCMTag(build.getScmTag()); - } - setBuildType(descriptionBuilder, build); - - int buildRootId = 42; - BuildRoot.Builder buildRootBuilder = builder.withNewBuildRoot(buildRootId) - .withContentGenerator(CONTENT_GENERATOR_NAME, config.getPNCSystemVersion()) - .withContainer(getContainer(build.getBuildRoot())) - .withHost(build.getBuildRoot().getHost(), build.getBuildRoot().getHostArchitecture()); - - Map tools = new HashMap<>(build.getBuildRoot().getTools()); - addTool(buildRootBuilder, guessBuildType(build), tools, "?"); - addTools(buildRootBuilder, tools); - - addDependencies(build.getDependencies(), buildRootBuilder); - addBuiltArtifacts(build.getBuiltArtifacts(), builder, buildRootId); - addLogs(importFiles, builder, buildRootId); - addSources(sources, builder, buildRootId); - - KojiImport translatedBuild = buildTranslatedBuild(builder); - translatedBuild.getBuild().getExtraInfo().setImportInitiator(username); - return translatedBuild; - } - - private BuildType guessBuildType(Build build) { - if (build.getClass().equals(MavenBuild.class)) { - if (build.getBuildRoot().getTools().containsKey("GRADLE")) { - return BuildType.GRADLE; - } else if (build.getBuildRoot().getTools().containsKey("SBT")) { - return BuildType.SBT; - } else { - return BuildType.MVN; - } - } else if (build.getClass().equals(NpmBuild.class)) { - return BuildType.NPM; - } else { - throw new IllegalArgumentException(ErrorMessages.unsupportedBuildClass(build.getClass())); - } - } - - private String normalizeScmUrl(final String url) { - if (url.startsWith("http")) { - return "git+" + url; - } - return url; - } - - private void addLog(String log, KojiImport.Builder builder, int buildRootId) throws CausewayException { - try { - byte[] logBytes = log.getBytes(); - MessageDigest md = MessageDigest.getInstance("MD5"); - BigInteger bi = new BigInteger(1, md.digest(logBytes)); - String logHash = String.format("%032x", bi); - builder.withNewOutput(buildRootId, "build.log") - .withOutputType(StandardOutputType.log) - .withFileSize(logBytes.length) - .withArch(StandardArchitecture.noarch) - .withChecksum(MD5, logHash); - } catch (NoSuchAlgorithmException ex) { - throw new CausewayException(ErrorMessages.failedToComputeBuildLogMD5(ex), ex); - } - } - - private void addSources(RenamedSources sources, KojiImport.Builder builder, int buildRootId) { - if (sources != null) { - BuildOutput.Builder outputBuilder = builder.withNewOutput(buildRootId, sources.getName()) - .withFileSize(sources.getSize()) - .withArch(StandardArchitecture.noarch) - .withChecksum(MD5, sources.getMd5()); - RenamedSources.ArtifactType artifactType = sources.getArtifactType(); - if (artifactType.isMavenType()) { - outputBuilder.withMavenInfoAndType(artifactType.getMavenInfoAndType()); - } else if (artifactType.isNPMType()) { - outputBuilder.withNpmInfoAndType(artifactType.getNpmInfoAndType()); - } else { - throw new IllegalArgumentException(ErrorMessages.unknownArtifactType()); - } - } - } - - private void addLogs(SpecialImportFileGenerator importFiles, KojiImport.Builder builder, int buildRootId) - throws CausewayException { - MessageDigest md; - try { - md = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new CausewayException(ErrorMessages.missingMD5Support(e)); - } - for (SpecialImportFileGenerator.Log log : importFiles.getLogs()) { - byte[] logData = log.getLog(); - byte[] md5Digest = md.digest(logData); - BigInteger bi = new BigInteger(1, md5Digest); - String md5Hash = String.format("%032x", bi); - builder.withNewOutput(buildRootId, log.getFilePath()) - .withOutputType(StandardOutputType.log) - .withFileSize(logData.length) - .withArch(StandardArchitecture.noarch) - .withChecksum(MD5, md5Hash); - } - } - - private void addDependencies( - List dependencies, - BuildRoot.Builder buildRootBuilder, - BuildType buildType) throws CausewayException { - for (PncArtifact artifact : dependencies) { - FileBuildComponent.Builder componentBuilder = buildRootBuilder.withFileComponent(artifact.deployPath); - componentBuilder.withChecksum(MD5, artifact.checksum); - - switch (buildType) { - case GRADLE: - case NPM: - case SBT: - case MVN: { - componentBuilder.withFileSize(artifact.size); - break; - } - default: { - throw new IllegalArgumentException(ErrorMessages.unknownArtifactType()); - } - } - } - } - - private void addDependencies(Set dependencies, BuildRoot.Builder buildRootBuilder) - throws CausewayException { - for (Dependency dependency : dependencies) { - buildRootBuilder.withFileComponent(dependency.getFilename()) - .withChecksum(MD5, dependency.getMd5()) - .withFileSize(dependency.getSize()); - } - } - - private void addBuiltArtifacts( - List buildArtifacts, - KojiImport.Builder builder, - int buildRootId, - BuildType buildType) throws CausewayException { - for (BuildArtifacts.PncArtifact artifact : buildArtifacts) { - BuildOutput.Builder outputBuilder = builder.withNewOutput(buildRootId, artifact.deployPath) - .withArch(StandardArchitecture.noarch) - .withChecksum(MD5, artifact.checksum); - - switch (buildType) { - case GRADLE: - case SBT: - case MVN: { - SimpleArtifactRef ref = SimpleArtifactRef.parse(artifact.identifier); - outputBuilder.withFileSize((int) artifact.size); - outputBuilder.withMavenInfoAndType(ref); - break; - } - case NPM: { - NpmPackageRef ref = NpmPackageRef.parse(artifact.identifier); - outputBuilder.withFileSize((int) artifact.size); - outputBuilder.withNpmInfoAndType(ref); - break; - } - default: { - throw new IllegalArgumentException(ErrorMessages.unknownArtifactType()); - } - } - } - } - - private void addBuiltArtifacts(Set builtArtifacts, KojiImport.Builder builder, int buildRootId) - throws CausewayException { - for (BuiltArtifact artifact : builtArtifacts) { - BuildOutput.Builder outputBuilder = builder - .withNewOutput(buildRootId, stripSlash(artifact.getArtifactPath())) - .withArch(artifact.getArchitecture()) - .withChecksum(MD5, artifact.getMd5()) - .withFileSize(artifact.getSize()); - - if (artifact.getClass().equals(MavenBuiltArtifact.class)) { - outputBuilder.withMavenInfoAndType(mavenArtifactToGAV((MavenBuiltArtifact) artifact)); - } else if (artifact.getClass().equals(NpmBuiltArtifact.class)) { - outputBuilder.withNpmInfoAndType(npmArtifactToNV((NpmBuiltArtifact) artifact)); - } else { - throw new IllegalArgumentException(ErrorMessages.unknownArtifactType()); - } - } - } - - private BuildContainer getContainer(org.jboss.pnc.api.causeway.dto.push.BuildRoot buildRoot) { - return new BuildContainer(buildRoot.getContainer(), buildRoot.getContainerArchitecture()); - } - - private BuildContainer getContainer(org.jboss.pnc.dto.Build buildRecord) { - switch (buildRecord.getEnvironment().getSystemImageType()) { - case DOCKER_IMAGE: - return new BuildContainer("docker", "noarch"); - default: - throw new IllegalArgumentException(ErrorMessages.unknownSystemImageType()); - } - } - - @Override - public ImportFileGenerator getImportFiles(BuildArtifacts artifacts, RenamedSources sources, String log) - throws CausewayException { - try { - StringLogImportFileGenerator ret = new StringLogImportFileGenerator(log, sources); - for (PncArtifact artifact : artifacts.buildArtifacts) { - ret.addUrl(artifact.id, artifact.deployUrl, artifact.deployPath, artifact.size); - } - return ret; - } catch (MalformedURLException ex) { - throw new CausewayException(ErrorMessages.failedToParseArtifactURL(ex), ex); - } - } - - @Override - public SpecialImportFileGenerator getImportFiles(Build build, RenamedSources sources) throws CausewayException { - try { - SpecialImportFileGenerator ret = new SpecialImportFileGenerator(sources); - for (Logfile logfile : build.getLogs()) { - String url = config.getLogStorage() + stripSlash(logfile.getDeployPath()); - ret.addLog(url, logfile.getFilename()); - } - for (BuiltArtifact artifact : build.getBuiltArtifacts()) { - String url = config.getArtifactStorage() - + stripSlash(Paths.get(artifact.getRepositoryPath(), artifact.getArtifactPath()).toString()); - ret.addUrl(artifact.getId(), url, stripSlash(artifact.getArtifactPath()), artifact.getSize()); - } - return ret; - } catch (IOException | InterruptedException ex) { - throw new CausewayException(ErrorMessages.failedToReadLogFile(ex), ex); - } - } - - @Override - public RenamedSources getSources(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts, InputStream sources) - throws CausewayException { - return buildTypeSwitch( - build, - artifacts, - (gav) -> renamer.repackMaven(sources, gav.getGroupId(), gav.getArtifactId(), gav.getVersionString()), - (npmPackage) -> renamer.repackNPM(sources, npmPackage.getName(), npmPackage.getVersionString())); - } - - @Override - public String getSourcesDeployPath(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts) - throws CausewayException { - return buildTypeSwitch( - build, - artifacts, - (gav) -> renamer.getMavenDeployPath(gav.getGroupId(), gav.getArtifactId(), gav.getVersionString()), - (npmPackage) -> renamer.getNPMDeployPath(npmPackage.getName(), npmPackage.getVersionString())); - } - - @Override - public RenamedSources getSources(Build build) throws CausewayException { - String version = build.getBuildVersion(); - if (version == null) { - version = BuildTranslator.guessVersion(build); - } - try { - if (build.getClass().equals(MavenBuild.class)) { - MavenBuild mavenBuild = (MavenBuild) build; - if (mavenBuild.getVersion() != null) { - version = mavenBuild.getVersion(); - } - String deployPath = renamer - .getMavenDeployPath(mavenBuild.getGroupId(), mavenBuild.getArtifactId(), version); - Optional any = mavenBuild.getBuiltArtifacts() - .stream() - .filter(a -> a.getArtifactPath().equals(deployPath)) - .findAny(); - if (!any.isPresent()) { - URL sourcesUrl = new URL(build.getSourcesURL()); - HttpURLConnection urlConnection = (HttpURLConnection) sourcesUrl.openConnection(); - urlConnection.setRequestProperty("Accept", "*/*"); - try (InputStream input = urlConnection.getInputStream()) { - return renamer.repackMaven(input, mavenBuild.getGroupId(), mavenBuild.getArtifactId(), version); - } - } - } else if (build.getClass().equals(NpmBuild.class)) { - NpmBuild npmBuild = (NpmBuild) build; - if (npmBuild.getVersion() != null) { - version = npmBuild.getVersion(); - } - String deployPath = renamer.getNPMDeployPath(npmBuild.getName(), version); - Optional any = npmBuild.getBuiltArtifacts() - .stream() - .filter(a -> a.getArtifactPath().equals(deployPath)) - .findAny(); - if (!any.isPresent()) { - URL sourcesUrl = new URL(build.getSourcesURL()); - HttpURLConnection urlConnection = (HttpURLConnection) sourcesUrl.openConnection(); - urlConnection.setRequestProperty("Accept", "*/*"); - try (InputStream input = urlConnection.getInputStream()) { - return renamer.repackNPM(input, npmBuild.getName(), version); - } - } - } else { - throw new IllegalArgumentException(ErrorMessages.unsupportedBuildClass(build.getClass())); - } - } catch (IOException ex) { - throw new CausewayException(ErrorMessages.failedToDownloadSources(ex), ex); - } - return null; - } - - private KojiImport buildTranslatedBuild(KojiImport.Builder builder) throws CausewayException { - final KojiImport translatedBuild; - try { - translatedBuild = builder.build(); - } catch (VerificationException ex) { - throw new CausewayException(ErrorMessages.failureWhileBuildingKojiImport(ex), ex); - } - return translatedBuild; - } - - private String stripSlash(String url) { - if (url.startsWith("/")) { - return url.substring(1); - } - return url; - } - - private ProjectVersionRef buildRootToGAV(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts) - throws CausewayException { - if (!build.getAttributes().containsKey(BUILD_BREW_NAME)) { - throw new CausewayFailure(ErrorMessages.missingBrewNameAttributeInMavenBuild()); - } - String[] splittedName = build.getAttributes().get(BUILD_BREW_NAME).split(":"); - if (splittedName.length != 2) { - throw new IllegalArgumentException( - ErrorMessages.illegalMavenBrewName(build.getAttributes().get(BUILD_BREW_NAME))); - } - String version = build.getAttributes().get(BUILD_BREW_VERSION); - if (version == null) { - version = BuildTranslator.guessVersion(build, artifacts); - } - return new SimpleProjectVersionRef(splittedName[0], splittedName.length < 2 ? null : splittedName[1], version); - } - - private NpmPackageRef buildRootToNV(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts) - throws CausewayException { - if (!build.getAttributes().containsKey(BUILD_BREW_NAME)) { - throw new CausewayFailure(ErrorMessages.missingBrewNameAttributeInBuild()); - } - String name = build.getAttributes().get(BUILD_BREW_NAME); - String version = build.getAttributes().get(BUILD_BREW_VERSION); - if (version == null) { - version = BuildTranslator.guessVersion(build, artifacts); - } - return new NpmPackageRef(name, Version.valueOf(version)); - } - - private void addTools(BuildRoot.Builder buildRootBuilder, Map tools) { - for (Map.Entry e : tools.entrySet()) { - if (!config.getIgnoredTools().contains(e.getKey())) { - buildRootBuilder.withTool(e.getKey(), e.getValue()); - } - } - } - - private void setBuildType(BuildDescription.Builder buildDescription, Build build) throws CausewayException { - if (build.getClass().equals(MavenBuild.class)) { - buildDescription.withMavenInfoAndType(mavenBuildToGAV((MavenBuild) build)); - } else if (build.getClass().equals(NpmBuild.class)) { - buildDescription.withNpmInfoAndType(npmBuildToNV((NpmBuild) build)); - } else { - throw new IllegalArgumentException(ErrorMessages.unsupportedBuildClass(build.getClass())); - } - } - - private void setBuildType( - BuildDescription.Builder buildDescription, - org.jboss.pnc.dto.Build build, - BuildArtifacts artifacts) throws CausewayException { - buildTypeSwitch(build, artifacts, buildDescription::withMavenInfoAndType, buildDescription::withNpmInfoAndType); - } - - private void addTool( - BuildRoot.Builder buildRootBuilder, - BuildType buildType, - Map tools, - String envID) throws CausewayException { - switch (buildType) { - case MVN: - buildRootBuilder.withTool(getTool("JDK", tools, envID)); - buildRootBuilder.withTool(getTool("MAVEN", tools, envID)); - break; - case SBT: - buildRootBuilder.withTool(getTool("SBT", tools, envID)); - break; - case GRADLE: - buildRootBuilder.withTool(getTool("GRADLE", tools, envID)); - break; - case NPM: - buildRootBuilder.withTool(getTool("NPM", tools, envID)); - break; - default: - throw new IllegalArgumentException(ErrorMessages.unsupportedBuildType(buildType)); - } - } - - private BuildTool getTool(String name, Map tools, String envID) { - String version = tools.remove(name); - if (version == null) { - for (Iterator> it = tools.entrySet().iterator(); it.hasNext();) { - Map.Entry e = it.next(); - if (e.getKey().equalsIgnoreCase(name)) { - if (version != null) { - throw new IllegalArgumentException(ErrorMessages.environmentWithMultipleVersions(envID, name)); - } - version = e.getValue(); - it.remove(); - } - } - if (version == null) { - throw new IllegalArgumentException(ErrorMessages.environmentWithoutVersion(envID, name)); - } - } - return new BuildTool(name, version); - } - - private ProjectVersionRef mavenBuildToGAV(MavenBuild mb) throws CausewayException { - String version = mb.getVersion(); - if (version == null) { - version = BuildTranslator.guessVersion(mb); - } - return new SimpleProjectVersionRef(mb.getGroupId(), mb.getArtifactId(), version); - } - - private NpmPackageRef npmBuildToNV(NpmBuild npmBuild) throws CausewayException { - String version = npmBuild.getVersion(); - if (version == null) { - version = BuildTranslator.guessVersion(npmBuild); - } - return new NpmPackageRef(npmBuild.getName(), NpmVersionUtils.valueOf(version)); - } - - private ProjectVersionRef mavenArtifactToGAV(MavenBuiltArtifact mba) { - return new SimpleProjectVersionRef(mba.getGroupId(), mba.getArtifactId(), mba.getVersion()); - } - - private NpmPackageRef npmArtifactToNV(NpmBuiltArtifact npmBuiltArtifact) { - return new NpmPackageRef(npmBuiltArtifact.getName(), NpmVersionUtils.valueOf(npmBuiltArtifact.getVersion())); - } - - private T buildTypeSwitch( - org.jboss.pnc.dto.Build build, - BuildArtifacts artifacts, - CausewayFunction mavenConsumer, - CausewayFunction npmConsumer) throws CausewayException { - BuildType buildType = build.getBuildConfigRevision().getBuildType(); - switch (buildType) { - case MVN: - case SBT: - case GRADLE: - ProjectVersionRef gav = buildRootToGAV(build, artifacts); - return mavenConsumer.apply(gav); - case NPM: - NpmPackageRef npmPackage = buildRootToNV(build, artifacts); - return npmConsumer.apply(npmPackage); - default: - throw new IllegalArgumentException(ErrorMessages.unsupportedBuildType(buildType)); - } - } - - @FunctionalInterface - private interface CausewayFunction { - R apply(T o) throws CausewayException; - } -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/brewclient/SpecialImportFileGenerator.java b/core/src/main/java/org/jboss/pnc/causeway/brewclient/SpecialImportFileGenerator.java deleted file mode 100644 index ae840006..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/brewclient/SpecialImportFileGenerator.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.brewclient; - -import com.redhat.red.build.koji.model.ImportFile; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.function.Supplier; - -import lombok.Getter; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.jboss.pnc.causeway.source.RenamedSources; - -import lombok.Data; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -public class SpecialImportFileGenerator extends ImportFileGenerator { - @Getter - private final Set logs = new HashSet<>(); - - public SpecialImportFileGenerator(RenamedSources sources) { - super(sources); - } - - /** - * Add log url to the generator. - * - * @param url Url of the log. - * @param filePath Deploy path for the log. - */ - public void addLog(String url, String filePath) throws IOException, InterruptedException { - logs.add(new Log(filePath, doGetRequest(url))); - } - - private byte[] doGetRequest(String url) throws IOException { - // Apache http client should automatically redirect for GETs and also automatically retry (4 times) - try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { - HttpGet get = new HttpGet(url); - CloseableHttpResponse response = httpClient.execute(get); - HttpEntity entity = response.getEntity(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - entity.writeTo(baos); - return baos.toByteArray(); - } - } - - @Override - public Iterator> iterator() { - return new ExternalLogImportFileIterator(artifacts.iterator(), logs.iterator()); - } - - @Data - public static class Log { - private final String filePath; - private final byte[] log; - } - - private class ExternalLogImportFileIterator extends ImportFileIterator { - private final Iterator logIt; - - public ExternalLogImportFileIterator(Iterator it, Iterator logIt) { - super(it); - this.logIt = logIt; - } - - @Override - public boolean hasNext() { - if (logIt.hasNext()) { - return true; - } - return super.hasNext(); - } - - @Override - public Supplier next() { - if (logIt.hasNext()) { - Log next1 = logIt.next(); - return () -> new ImportFile(next1.filePath, new ByteArrayInputStream(next1.log), next1.log.length); - } - return super.next(); - } - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/brewclient/StringLogImportFileGenerator.java b/core/src/main/java/org/jboss/pnc/causeway/brewclient/StringLogImportFileGenerator.java deleted file mode 100644 index 2d3a5209..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/brewclient/StringLogImportFileGenerator.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.brewclient; - -import java.io.ByteArrayInputStream; - -import com.redhat.red.build.koji.model.ImportFile; - -import java.util.Iterator; -import java.util.function.Supplier; - -import org.jboss.pnc.causeway.source.RenamedSources; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Deprecated -public class StringLogImportFileGenerator extends ImportFileGenerator { - private final String log; - - public StringLogImportFileGenerator(String log, RenamedSources sources) { - super(sources); - this.log = log; - } - - @Override - public Iterator> iterator() { - return new ImportFileIterator2(artifacts.iterator()); - } - - private class ImportFileIterator2 extends ImportFileIterator { - private boolean logGiven = false; - - public ImportFileIterator2(Iterator it) { - super(it); - } - - @Override - public boolean hasNext() { - if (!logGiven) { - return true; - } - return super.hasNext(); - } - - @Override - public Supplier next() { - if (log != null && !logGiven) { - logGiven = true; - byte[] bytes = log.getBytes(); - return () -> new ImportFile("build.log", new ByteArrayInputStream(bytes), bytes.length); - } - return super.next(); - } - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/config/CausewayConfig.java b/core/src/main/java/org/jboss/pnc/causeway/config/CausewayConfig.java deleted file mode 100644 index ddd200f3..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/config/CausewayConfig.java +++ /dev/null @@ -1,459 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.config; - -import org.apache.commons.io.FileUtils; -import org.commonjava.util.jhttpc.model.SiteConfig; -import org.commonjava.util.jhttpc.model.SiteConfigBuilder; -import org.commonjava.util.jhttpc.model.SiteTrustType; -import org.commonjava.web.config.annotation.ConfigName; -import org.commonjava.web.config.annotation.SectionName; -import org.commonjava.web.config.section.ConfigurationSectionListener; -import org.jboss.pnc.causeway.ErrorMessages; -import org.jboss.pnc.client.Configuration; - -import javax.enterprise.context.ApplicationScoped; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import static org.apache.commons.lang.StringUtils.isEmpty; - -/** - * Created by jdcasey on 11/10/15. - */ -@ApplicationScoped -@SectionName(ConfigurationSectionListener.DEFAULT_SECTION) -public class CausewayConfig { - public static final String CAUSEWAY_CONFIG_DIR_SYSPROP = "causeway.config.dir"; - - public static final String CLIENT_CERT_PEM_PASSWORD_OPTION = "koji.client.pem.password"; - - public static final String PNCL_URL_OPTION = "pncl.url"; - - public static final String PNCL_BUILDS_URL_OPTION = "pncl.builds.url"; - - public static final String OIDC_CLIENT_URL = "oidc-client.url"; - public static final String OIDC_CLIENT_REALM = "oidc-client.realm"; - public static final String OIDC_CLIENT_CLIENT_ID = "oidc-client.client-id"; - public static final String OIDC_CLIENT_SECRET_FILE = "oidc-client.secret-file"; - - public static final String PNC_SYSTEM_VERSION = "pnc.system.version"; - - public static final String ARTIFACT_STORAGE = "artifact-storage"; - - public static final String LOG_STORAGE = "log-storage"; - - public static final String KOJI_URL_OPTION = "koji.url"; - - public static final String KOJI_WEBURL_OPTION = "koji.weburl"; - - public static final String DEFAULT_CAUSEWAY_CONFIG = "/etc/causeway/main.conf"; - - public static final String DEFAULT_SSL_SERVER_PEM_FILE = "server.pem"; - - public static final String DEFAULT_SSL_CLIENT_PEM_FILE = "client.pem"; - - public static final Boolean DEFAULT_SSL_TRUST_SELF_SIGNED = Boolean.FALSE; - - public static final String KOJI_SITE_ID = "koji"; - - private static final String PNCL_SITE_ID = "pncl"; - - private static final String SSL_SUBDIR = "ssl"; - - private static final Integer DEFAULT_HTTP_TIMEOUT_SECS = Integer.valueOf(10); - - private static final Integer DEFAULT_CONNECTIONS = 10; - - private static final Integer DEFAULT_PAGE_SIZE = 50; - - private boolean configured; - - private String kojiClientKeyCertificateFile; - - private String kojiClientCertificatePassword; - - private String kojiServerCertificateFile; - - private Boolean kojiTrustSelfSigned; - - private String kojiURL; - - private String kojiWebURL; - - private String artifactStorage; - - private String logStorage; - - private String pnclURL; - - private String pnclBuildsURL; - - private String pncSystemVersion; - - private File configDir; - - private Integer httpTimeout; - - private Integer kojiTimeout; - - private Integer kojiConnectionPoolTimeout; - - private Integer kojiConnections; - - private Set ignoredTools; - - private Integer pnclTimeout; - - private String oidcClientUrl; - - private String oidcClientRealm; - - private String oidcClientClientId; - - private String oidcClientSecretFile; - - /** - * Cache the content of the oidcClientSecretFile - */ - private String cachedSecretFileContent; - - private SiteConfig kojiSiteConfig; - - private SiteConfig pnclSiteConfig; - - private Configuration configuration; - - public Boolean getKojiTrustSelfSigned() { - return kojiTrustSelfSigned == null ? false : kojiTrustSelfSigned; - } - - @ConfigName("koji.trust.self-signed") - public void setKojiTrustSelfSigned(Boolean kojiTrustSelfSigned) { - this.kojiTrustSelfSigned = kojiTrustSelfSigned == null ? DEFAULT_SSL_TRUST_SELF_SIGNED : kojiTrustSelfSigned; - } - - public String getKojiClientCertificatePassword() { - return kojiClientCertificatePassword; - } - - @ConfigName(CausewayConfig.CLIENT_CERT_PEM_PASSWORD_OPTION) - public void setKojiClientCertificatePassword(String kojiClientCertificatePassword) { - this.kojiClientCertificatePassword = kojiClientCertificatePassword; - } - - public String getKojiClientKeyCertificateFile() { - checkConfigured(); - return kojiClientKeyCertificateFile == null - ? Paths.get(getConfigDir().getPath(), SSL_SUBDIR, DEFAULT_SSL_CLIENT_PEM_FILE).toString() - : kojiClientKeyCertificateFile; - } - - @ConfigName("koji.client.pem.file") - public void setKojiClientKeyCertificateFile(String kojiClientKeyCertificateFile) { - this.kojiClientKeyCertificateFile = kojiClientKeyCertificateFile; - } - - public String getKojiServerCertificateFile() { - checkConfigured(); - return kojiServerCertificateFile == null - ? Paths.get(getConfigDir().getPath(), SSL_SUBDIR, DEFAULT_SSL_SERVER_PEM_FILE).toString() - : kojiServerCertificateFile; - } - - @ConfigName("koji.server.pem.file") - public void setKojiServerCertificateFile(String kojiServerCertificateFile) { - this.kojiServerCertificateFile = kojiServerCertificateFile; - } - - public String getKojiURL() { - checkConfigured(); - return kojiURL; - } - - @ConfigName(CausewayConfig.KOJI_URL_OPTION) - public void setKojiURL(String kojiURL) { - this.kojiURL = kojiURL; - } - - public String getKojiWebURL() { - checkConfigured(); - return kojiWebURL; - } - - @ConfigName(CausewayConfig.KOJI_WEBURL_OPTION) - public void setKojiWebURL(String kojiWebURL) { - this.kojiWebURL = kojiWebURL; - } - - public String getArtifactStorage() { - checkConfigured(); - return artifactStorage; - } - - @ConfigName(CausewayConfig.ARTIFACT_STORAGE) - public void setArtifactStorage(String artifactStorage) { - this.artifactStorage = artifactStorage; - } - - public String getLogStorage() { - checkConfigured(); - return logStorage; - } - - @ConfigName(CausewayConfig.LOG_STORAGE) - public void setLogStorage(String logStorage) { - this.logStorage = logStorage; - } - - public String getPnclURL() { - checkConfigured(); - return pnclURL; - } - - @ConfigName(CausewayConfig.PNCL_URL_OPTION) - public void setPnclURL(String pnclURL) { - this.pnclURL = pnclURL; - } - - public String getPnclBuildsURL() { - checkConfigured(); - return pnclBuildsURL; - } - - @ConfigName(CausewayConfig.PNCL_BUILDS_URL_OPTION) - public void setPnclBuildsURL(String pnclURL) { - this.pnclBuildsURL = pnclURL; - } - - public String getPNCSystemVersion() { - checkConfigured(); - return pncSystemVersion; - } - - @ConfigName(CausewayConfig.PNC_SYSTEM_VERSION) - public void setPNCSystemVersion(String pncSystemVersion) { - this.pncSystemVersion = pncSystemVersion; - } - - public void configurationDone() { - configured = true; - } - - private void checkConfigured() { - if (!configured) { - throw new IllegalStateException(ErrorMessages.causewayNotConfigured()); - } - } - - public synchronized SiteConfig getKojiSiteConfig() throws IOException { - if (kojiSiteConfig == null) { - SiteConfigBuilder builder = new SiteConfigBuilder(KOJI_SITE_ID, getKojiURL()); - File keyCert = new File(getKojiClientKeyCertificateFile()); - if (keyCert.exists()) { - builder.withKeyCertPem(FileUtils.readFileToString(keyCert)); - } - - File serverCert = new File(getKojiServerCertificateFile()); - if (serverCert.exists()) { - builder.withServerCertPem(FileUtils.readFileToString(serverCert)); - } - - if (getKojiTrustSelfSigned()) { - builder.withTrustType(SiteTrustType.TRUST_SELF_SIGNED); - } - - builder.withRequestTimeoutSeconds(getKojiTimeout()); - - kojiSiteConfig = builder.build(); - } - - return kojiSiteConfig; - } - - public synchronized SiteConfig getPnclSiteConfig() { - if (pnclSiteConfig == null) { - SiteConfigBuilder builder = new SiteConfigBuilder(PNCL_SITE_ID, getPnclURL()); - - // TODO: SSL? - - builder.withRequestTimeoutSeconds(getPnclTimeout()); - - pnclSiteConfig = builder.build(); - } - - return pnclSiteConfig; - } - - public synchronized Configuration getPncClientConfig() { - if (configuration == null) { - Configuration.ConfigurationBuilder builder = Configuration.builder(); - - try { - URL url = new URL(getPnclURL()); - - builder.host(url.getHost()) - .protocol(url.getProtocol()) - .pageSize(DEFAULT_PAGE_SIZE) - .addDefaultMdcToHeadersMappings() - .port((url.getPort() != -1) ? url.getPort() : url.getDefaultPort()); - } catch (MalformedURLException e) { - throw new IllegalStateException(ErrorMessages.configurationValueIsNotURL(PNCL_URL_OPTION), e); - } - - configuration = builder.build(); - } - - return configuration; - } - - public void setConfigDir(File configDir) { - this.configDir = configDir; - } - - public File getConfigDir() { - return configDir; - } - - public Integer getHttpTimeout() { - return httpTimeout == null ? DEFAULT_HTTP_TIMEOUT_SECS : httpTimeout; - } - - @ConfigName("http.timeout.secs") - public void setHttpTimeout(Integer httpTimeout) { - this.httpTimeout = httpTimeout; - } - - @ConfigName("koji.timeout.secs") - public void setKojiTimeout(Integer kojiTimeout) { - this.kojiTimeout = kojiTimeout; - } - - public Integer getKojiTimeout() { - return kojiTimeout == null ? getHttpTimeout() : kojiTimeout; - } - - @ConfigName("koji.connectionPoolTimeout.secs") - public void setKojiConnectionPoolTimeout(Integer kojiConnectionPoolTimeout) { - this.kojiConnectionPoolTimeout = kojiConnectionPoolTimeout; - } - - public Integer getKojiConnectionPoolTimeout() { - return kojiConnectionPoolTimeout == null ? getHttpTimeout() : kojiConnectionPoolTimeout; - } - - @ConfigName("koji.connections") - public void setKojiConnections(Integer kojiConnections) { - this.kojiConnections = kojiConnections; - } - - public Integer getKojiConnections() { - return kojiConnections == null ? DEFAULT_CONNECTIONS : kojiConnections; - } - - public Integer getPnclTimeout() { - return pnclTimeout == null ? getHttpTimeout() : pnclTimeout; - } - - @ConfigName("pncl.timeout.secs") - public void setPnclTimeout(Integer pnclTimeout) { - this.pnclTimeout = pnclTimeout; - } - - public Set getIgnoredTools() { - return ignoredTools == null ? Collections.emptySet() : ignoredTools; - } - - @ConfigName("pnc.tools.ignored") - public void setIgnoredTools(String ignoredTools) { - this.ignoredTools = ignoredTools == null ? null : new HashSet<>(Arrays.asList(ignoredTools.split(","))); - } - - public String getOidcClientUrl() { - return oidcClientUrl; - } - - @ConfigName(CausewayConfig.OIDC_CLIENT_URL) - public void setOidcClientUrl(String clientUrl) { - this.oidcClientUrl = clientUrl; - } - - public String getOidcClientRealm() { - return oidcClientRealm; - } - - @ConfigName(CausewayConfig.OIDC_CLIENT_REALM) - public void setOidcClientRealm(String clientRealm) { - this.oidcClientRealm = clientRealm; - } - - public String getOidcClientClientId() { - return oidcClientClientId; - } - - @ConfigName(CausewayConfig.OIDC_CLIENT_CLIENT_ID) - public void setOidcClientClientId(String clientId) { - this.oidcClientClientId = clientId; - } - - public String getOidcClientSecretFile() { - return oidcClientSecretFile; - } - - @ConfigName(CausewayConfig.OIDC_CLIENT_SECRET_FILE) - public void setOidcClientSecretFile(String secretFile) { - this.oidcClientSecretFile = secretFile; - } - - public String getOidcClientSecret() throws IOException { - if (cachedSecretFileContent == null) { - List lines = Files.readAllLines(Paths.get(oidcClientSecretFile)); - cachedSecretFileContent = String.join("\n", lines).trim(); - } - - return cachedSecretFileContent; - } - - public List getValidationErrors() { - List errors = new ArrayList<>(); - if (isEmpty(getKojiClientCertificatePassword())) { - errors.add(String.format("Koji SSL password '%s' is required.", CLIENT_CERT_PEM_PASSWORD_OPTION)); - } - - if (isEmpty(getPnclURL())) { - errors.add(String.format("Project Newcastle URL '%s' is required.", PNCL_URL_OPTION)); - } - - if (isEmpty(getKojiURL())) { - errors.add(String.format("Koji URL '%s' is required.", KOJI_URL_OPTION)); - } - - if (isEmpty(getKojiWebURL())) { - errors.add(String.format("Koji Web URL '%s' is required.", KOJI_WEBURL_OPTION)); - } - return errors; - } -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/config/CausewayConfigurator.java b/core/src/main/java/org/jboss/pnc/causeway/config/CausewayConfigurator.java deleted file mode 100644 index 821b4598..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/config/CausewayConfigurator.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.config; - -import org.commonjava.web.config.ConfigurationException; -import org.commonjava.web.config.dotconf.DotConfConfigurationReader; -import org.jboss.pnc.causeway.ErrorMessages; - -import javax.inject.Inject; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.ejb.Singleton; -import javax.ejb.Startup; - -/** - * Created by jdcasey on 11/10/15. - */ -@Singleton -@Startup -public class CausewayConfigurator { - @Inject - private CausewayConfig causewayConfig; - - @PostConstruct - public void init() { - try { - load(); - } catch (ConfiguratorException ex) { - throw new RuntimeException(ex); - } - } - - public void load() throws ConfiguratorException { - - String config = System.getProperty(CausewayConfig.CAUSEWAY_CONFIG_DIR_SYSPROP); - if (config == null) { - config = CausewayConfig.DEFAULT_CAUSEWAY_CONFIG; - } - - File configFile = new File(config); - if (configFile.isDirectory()) { - configFile = new File(configFile, "main.conf"); - } - - System.setProperty(CausewayConfig.CAUSEWAY_CONFIG_DIR_SYSPROP, configFile.getParentFile().getAbsolutePath()); - - if (!configFile.exists()) { - // TODO: Make resilient enough to write default configs. - throw new ConfiguratorException("Missing configuration: %s", configFile); - } - - File dir = configFile.getAbsoluteFile().getParentFile(); - causewayConfig.setConfigDir(dir); - - try (InputStream in = new FileInputStream(configFile)) { - new DotConfConfigurationReader(causewayConfig).loadConfiguration(in); - } catch (ConfigurationException | IOException e) { - throw new ConfiguratorException(ErrorMessages.failedToReadConfigFile(configFile, e), e); - } - - causewayConfig.configurationDone(); - - List validationErrors = causewayConfig.getValidationErrors(); - if (!validationErrors.isEmpty()) { - throw new ConfiguratorException(ErrorMessages.configIsNotComplete(validationErrors)); - } - } -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/config/ConfiguratorException.java b/core/src/main/java/org/jboss/pnc/causeway/config/ConfiguratorException.java deleted file mode 100644 index 17f0df34..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/config/ConfiguratorException.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.config; - -import org.jboss.pnc.causeway.CausewayException; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -public class ConfiguratorException extends CausewayException { - - public ConfiguratorException(String format, Throwable cause, Object... params) { - super(format, cause, params); - } - - public ConfiguratorException(String format, Object... params) { - super(format, params); - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/ctl/ImportController.java b/core/src/main/java/org/jboss/pnc/causeway/ctl/ImportController.java deleted file mode 100644 index e3e7b0ff..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/ctl/ImportController.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.jboss.pnc.causeway.ctl; - -import org.jboss.pnc.api.causeway.dto.push.Build; -import org.jboss.pnc.api.causeway.dto.untag.TaggedBuild; -import org.jboss.pnc.api.dto.Request; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -public interface ImportController { - - void importBuild(Build build, Request callback, String username, boolean reimport); - - void untagBuild(TaggedBuild build, Request callback); -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/ctl/ImportControllerImpl.java b/core/src/main/java/org/jboss/pnc/causeway/ctl/ImportControllerImpl.java deleted file mode 100644 index 6fdb4513..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/ctl/ImportControllerImpl.java +++ /dev/null @@ -1,416 +0,0 @@ -package org.jboss.pnc.causeway.ctl; - -import com.codahale.metrics.Histogram; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.Timer; -import com.codahale.metrics.UniformReservoir; -import com.redhat.red.build.koji.model.json.KojiImport; - -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanBuilder; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.context.Scope; -import lombok.Data; - -import org.jboss.pnc.api.causeway.dto.push.Build; -import org.jboss.pnc.api.causeway.dto.push.BuiltArtifact; -import org.jboss.pnc.api.causeway.dto.push.Logfile; -import org.jboss.pnc.api.causeway.dto.untag.TaggedBuild; -import org.jboss.pnc.api.constants.HttpHeaders; -import org.jboss.pnc.api.constants.MDCHeaderKeys; -import org.jboss.pnc.api.constants.MDCKeys; -import org.jboss.pnc.api.dto.Request; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.CausewayFailure; -import org.jboss.pnc.causeway.ErrorMessages; -import org.jboss.pnc.causeway.authentication.KeycloakClient; -import org.jboss.pnc.causeway.authentication.KeycloakClientException; -import org.jboss.pnc.causeway.brewclient.BrewClient; -import org.jboss.pnc.causeway.brewclient.BuildTranslator; -import org.jboss.pnc.causeway.brewclient.ImportFileGenerator; -import org.jboss.pnc.causeway.brewclient.SpecialImportFileGenerator; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.jboss.pnc.causeway.source.RenamedSources; -import org.jboss.pnc.common.log.MDCUtils; -import org.jboss.pnc.common.otel.OtelUtils; -import org.jboss.pnc.pncmetrics.MetricsConfiguration; -import org.jboss.pnc.causeway.rest.BrewBuild; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.jboss.pnc.causeway.rest.model.response.OperationStatus; -import org.jboss.pnc.causeway.rest.model.response.UntagResultRest; -import org.jboss.pnc.causeway.rest.model.response.UntagResultRest.UntagResultRestBuilder; -import org.jboss.pnc.dto.BuildPushResult; -import org.jboss.pnc.enums.BuildPushStatus; -import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; - -import javax.ejb.Asynchronous; -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; -import javax.inject.Inject; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Map; - -import lombok.extern.slf4j.Slf4j; - -import org.slf4j.MDC; -import org.slf4j.Marker; -import org.slf4j.MarkerFactory; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Stateless -@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) -@Slf4j -public class ImportControllerImpl implements ImportController { - - private static final String METRICS_IMPORT_BASE = "causeway.import.build"; - private static final String METRICS_UNTAG_BASE = "causeway.untag.build"; - private static final String METRICS_TIMER = ".timer"; - private static final String METRICS_METER = ".meter"; - private static final String METRICS_ERRORS = ".errors"; - - private static final String METRICS_PUSHED_FILE_TO_BREW_KEY = "pushed-file-to-brew"; - public static final String METRICS_LOGS_NUMBER_KEY = METRICS_PUSHED_FILE_TO_BREW_KEY + ".logs.number"; - public static final String METRICS_LOGS_SIZE_KEY = METRICS_PUSHED_FILE_TO_BREW_KEY + ".logs.size"; - public static final String METRICS_ARTIFACTS_NUMBER_KEY = METRICS_PUSHED_FILE_TO_BREW_KEY + ".artifacts.number"; - public static final String METRICS_ARTIFACTS_SIZE_KEY = METRICS_PUSHED_FILE_TO_BREW_KEY + ".artifacts.size"; - - private static final String BUILD_NOT_TAGGED = " but not previously tagged. Tagged now."; - private static final String BUILD_ALREADY_IMPORTED = "Build was already imported with id "; - - private static final Marker USER_LOG = MarkerFactory.getMarker("USER_LOG"); - - @Inject - private BrewClient brewClient; - @Inject - private BuildTranslator translator; - @Inject - private CausewayConfig config; - private ResteasyClient restClient; - - @Inject - private MetricsConfiguration metricsConfiguration; - - @Inject - private KeycloakClient keycloakClient; - - @Inject - public ImportControllerImpl() { - restClient = new ResteasyClientBuilder().connectionPoolSize(4).build(); - } - - @Override - @Asynchronous - public void importBuild(Build build, Request callback, String username, boolean reimport) { - - // Create a parent child span with values from MDC - SpanBuilder spanBuilder = OtelUtils.buildChildSpan( - GlobalOpenTelemetry.get().getTracer(""), - "ImportControllerImpl.importBuild", - SpanKind.CLIENT, - MDC.get(MDCKeys.SLF4J_TRACE_ID_KEY), - MDC.get(MDCKeys.SLF4J_SPAN_ID_KEY), - MDC.get(MDCKeys.SLF4J_TRACE_FLAGS_KEY), - MDC.get(MDCKeys.SLF4J_TRACE_STATE_KEY), - Span.current().getSpanContext(), - Map.of( - MDCKeys.BUILD_ID_KEY, - String.valueOf(build.getExternalBuildID()), - "tag", - build.getTagPrefix(), - "username", - username, - "reimport", - String.valueOf(reimport))); - Span span = spanBuilder.startSpan(); - log.debug("Started a new span :{}", span); - - MDC.put(MDCKeys.BUILD_ID_KEY, String.valueOf(build.getExternalBuildID())); - log.info(USER_LOG, "Importing external build {} to tag {}.", build.getExternalBuildID(), build.getTagPrefix()); - - MetricRegistry registry = metricsConfiguration.getMetricRegistry(); - Meter meter = registry.meter(METRICS_IMPORT_BASE + METRICS_METER); - meter.mark(); - - Timer timer = registry.timer(METRICS_IMPORT_BASE + METRICS_TIMER); - Timer.Context context = timer.time(); - - Meter errors = registry.meter(METRICS_IMPORT_BASE + METRICS_ERRORS); - - // put the span into the current Context - try (Scope scope = span.makeCurrent()) { - BuildPushResult.Builder response = BuildPushResult.builder(); - response.buildId(String.valueOf(build.getExternalBuildID())); - try { - BuildResult result = importBuild(build, build.getTagPrefix(), username, reimport); - response.brewBuildId(result.getBrewID()); - response.brewBuildUrl(result.getBrewURL()); - response.status(BuildPushStatus.SUCCESS); - response.message(result.getMessage()); - log.info(result.getMessage()); - } catch (CausewayFailure ex) { - log.warn(ErrorMessages.failedToImportBuild(build.getExternalBuildID(), ex), ex); - response.status(BuildPushStatus.FAILED); - response.message(getMessageOrStacktrace(ex)); - errors.mark(); - } catch (CausewayException | RuntimeException ex) { - log.error(ErrorMessages.errorImportingBuild(build.getExternalBuildID(), ex), ex); - response.status(BuildPushStatus.SYSTEM_ERROR); - response.message(getMessageOrStacktrace(ex)); - errors.mark(); - } - respond(callback, response.build()); - - // stop the timer - context.stop(); - } finally { - span.end(); // closing the scope does not end the span, this has to be done manually - } - } - - @Override - @Asynchronous - public void untagBuild(TaggedBuild build, Request callback) { - - // Create a parent child span with values from MDC - SpanBuilder spanBuilder = OtelUtils.buildChildSpan( - GlobalOpenTelemetry.get().getTracer(""), - "ImportControllerImpl.untagBuild", - SpanKind.CLIENT, - MDC.get(MDCKeys.SLF4J_TRACE_ID_KEY), - MDC.get(MDCKeys.SLF4J_SPAN_ID_KEY), - MDC.get(MDCKeys.SLF4J_TRACE_FLAGS_KEY), - MDC.get(MDCKeys.SLF4J_TRACE_STATE_KEY), - Span.current().getSpanContext(), - Map.of("build", String.valueOf(build.getBrewBuildId()), "tag", build.getTagPrefix())); - Span span = spanBuilder.startSpan(); - log.debug("Started a new span :{}", span); - - log.info(USER_LOG, "Untagging build {} from tag {}.", build.getBrewBuildId(), build.getTagPrefix()); - - MetricRegistry registry = metricsConfiguration.getMetricRegistry(); - Meter meter = registry.meter(METRICS_UNTAG_BASE + METRICS_METER); - meter.mark(); - - Timer timer = registry.timer(METRICS_UNTAG_BASE + METRICS_TIMER); - Timer.Context context = timer.time(); - - Meter errors = registry.meter(METRICS_UNTAG_BASE + METRICS_ERRORS); - - // put the span into the current Context - try (Scope scope = span.makeCurrent()) { - UntagResultRestBuilder response = UntagResultRest.builder(); - response.brewBuildId(build.getBrewBuildId()); - try { - untagBuild(build.getBrewBuildId(), build.getTagPrefix()); - response.log("Brew build " + build.getBrewBuildId() + " untagged from tag " + build.getTagPrefix()); - response.status(OperationStatus.SUCCESS); - } catch (CausewayFailure ex) { - log.warn(ErrorMessages.failedToUntagBuild(ex), ex); - response.status(OperationStatus.FAILED); - response.log(getMessageOrStacktrace(ex)); - errors.mark(); - } catch (CausewayException | RuntimeException ex) { - log.error(ErrorMessages.errorUntaggingBuild(ex), ex); - response.status(OperationStatus.SYSTEM_ERROR); - response.log(getMessageOrStacktrace(ex)); - errors.mark(); - } - respond(callback, response.build()); - - // stop the timer - context.stop(); - } finally { - span.end(); // closing the scope does not end the span, this has to be done manually - } - } - - private BuildResult importBuild(Build build, String tagPrefix, String username, boolean reimport) - throws CausewayException { - if (build.getBuiltArtifacts().isEmpty()) { - throw new CausewayFailure(ErrorMessages.buildHasNoArtifacts()); - } - if (!brewClient.tagsExists(tagPrefix)) { - throw new CausewayFailure(ErrorMessages.tagsAreMissingInKoji(tagPrefix, config.getKojiURL())); - } - - BrewNVR nvr = getNVR(build); - boolean buildImported = false; - - BrewBuild brewBuild = brewClient.findBrewBuildOfNVR(nvr); - String message; - if (brewBuild == null) { - brewBuild = translateAndImport(nvr, build, username); - buildImported = true; - message = "Build imported with id " + brewBuild.getId() + "."; - } else { - if (reimport) { - int revision = 1; - while (brewBuild != null && brewClient.isBuildTagged(tagPrefix, brewBuild)) { - nvr = getNVR(build, ++revision); - brewBuild = brewClient.findBrewBuildOfNVR(nvr); - } - if (brewBuild == null) { - brewBuild = translateAndImport(nvr, build, username); - message = "Build was previously imported. Reimported again with revision " + revision - + " and with id " + brewBuild.getId() + "."; - buildImported = true; - } else { - message = BUILD_ALREADY_IMPORTED + brewBuild.getId() + BUILD_NOT_TAGGED; - } - } else { - message = BUILD_ALREADY_IMPORTED + brewBuild.getId(); - if (!brewClient.isBuildTagged(tagPrefix, brewBuild)) { - message += BUILD_NOT_TAGGED; - } - } - } - - if (buildImported) { - long artifactSize = build.getBuiltArtifacts().stream().mapToLong(BuiltArtifact::getSize).sum(); - int artifactNumber = build.getBuiltArtifacts().size(); - long logSize = build.getLogs().stream().mapToLong(Logfile::getSize).sum(); - int logNumber = build.getLogs().size(); - - updateHistogram(metricsConfiguration, METRICS_ARTIFACTS_SIZE_KEY, artifactSize); - updateHistogram(metricsConfiguration, METRICS_ARTIFACTS_NUMBER_KEY, artifactNumber); - updateHistogram(metricsConfiguration, METRICS_LOGS_SIZE_KEY, logSize); - updateHistogram(metricsConfiguration, METRICS_LOGS_NUMBER_KEY, logNumber); - } - - brewClient.tagBuild(tagPrefix, brewBuild); - - return new BuildResult(brewBuild.getId(), brewClient.getBuildUrl(brewBuild.getId()), message); - } - - private BrewBuild translateAndImport(BrewNVR nvr, Build build, String username) throws CausewayException { - RenamedSources sources = translator.getSources(build); - SpecialImportFileGenerator importFiles = translator.getImportFiles(build, sources); - KojiImport kojiImport = translator.translate(nvr, build, sources, username, importFiles); - return brewClient.importBuild(nvr, kojiImport, importFiles); - } - - private void updateHistogram(MetricsConfiguration metricsConfiguration, String name, long value) { - Histogram histogram = null; - if (metricsConfiguration != null) { - MetricRegistry registry = metricsConfiguration.getMetricRegistry(); - try { - histogram = registry.register(name, new Histogram(new UniformReservoir())); - } catch (IllegalArgumentException e) { - histogram = registry.histogram(name); - } - } - if (histogram != null) { - histogram.update(value); - } - } - - BrewNVR getNVR(Build build) throws CausewayException { - String buildVersion = build.getBuildVersion(); - if (buildVersion == null) { - buildVersion = BuildTranslator.guessVersion(build); - } - - return new BrewNVR(build.getBuildName(), buildVersion, "1"); - } - - BrewNVR getNVR(Build build, int revision) throws CausewayException { - if (revision <= 0) - throw new IllegalArgumentException("Revison must be positive, is " + revision); - String buildVersion = build.getBuildVersion(); - if (buildVersion == null) { - buildVersion = BuildTranslator.guessVersion(build); - } - - return new BrewNVR(build.getBuildName(), buildVersion, Integer.toString(revision)); - } - - private void respond(Request callback, T responseEntity) { - if (callback == null) { - log.info(USER_LOG, "Not sending callback."); - return; - } - log.info(USER_LOG, "Sending callback to {}.", callback.getUri()); - ResteasyWebTarget target = restClient.target(callback.getUri()); - Invocation.Builder request = target.request(MediaType.APPLICATION_JSON); - callback.getHeaders().forEach(h -> request.header(h.getName(), h.getValue())); - - try { - request.header(HttpHeaders.AUTHORIZATION_STRING, "Bearer " + keycloakClient.getAccessToken()); - } catch (KeycloakClientException e) { - log.error("Couldn't obtain the access token from the OIDC server", e); - } - - // Add OTEL headers from MDC context - addOtelMDCHeaders(request); - - Response response = request.post(Entity.entity(responseEntity, MediaType.APPLICATION_JSON_TYPE)); - log.debug("Callback response: {} - {}.", response.getStatusInfo(), response.readEntity(String.class)); - } - - private void addOtelMDCHeaders(Invocation.Builder request) { - headersFromMdc(request, MDCHeaderKeys.SLF4J_TRACE_ID); - headersFromMdc(request, MDCHeaderKeys.SLF4J_SPAN_ID); - Map otelHeaders = MDCUtils.getOtelHeadersFromMDC(); - otelHeaders.forEach((k, v) -> request.header(k, v)); - } - - private void headersFromMdc(Invocation.Builder request, MDCHeaderKeys headerKey) { - String mdcValue = MDC.get(headerKey.getMdcKey()); - if (mdcValue != null && mdcValue.isEmpty()) { - request.header(headerKey.getHeaderName(), mdcValue.trim()); - } - } - - private void untagBuild(int brewBuildId, String tagPrefix) throws CausewayException { - BrewBuild build = brewClient.findBrewBuild(brewBuildId); - if (build == null) { - throw new CausewayFailure(ErrorMessages.brewBuildNotFound(brewBuildId)); - } - brewClient.untagBuild(tagPrefix, build); - } - - /** - * If the exception.getMessage() is null, return the stacktrace instead If exception.getMessage() is not-null, just - * return the message - * - * @param e exception - * @return reason for exception - */ - private String getMessageOrStacktrace(Exception e) { - - // get the message - String message = e.getMessage(); - - // it can be null for NullPointerException for example! - if (message != null) { - return message; - } - - // if message is null, return the stacktrace instead - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - - return sw.toString(); - } - - @Data - public static class BuildResult { - - private final int brewID; - private final String brewURL; - private final String message; - } -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/ctl/PncImportController.java b/core/src/main/java/org/jboss/pnc/causeway/ctl/PncImportController.java deleted file mode 100644 index 6d0d4d5a..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/ctl/PncImportController.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.ctl; - -import org.jboss.pnc.api.dto.Request; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Deprecated -public interface PncImportController { - - public void importMilestone(int milestoneId, Request callback, String callbackId, String username); -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/ctl/PncImportControllerImpl.java b/core/src/main/java/org/jboss/pnc/causeway/ctl/PncImportControllerImpl.java deleted file mode 100644 index 12cf079c..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/ctl/PncImportControllerImpl.java +++ /dev/null @@ -1,350 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - *

- * 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. - */ -package org.jboss.pnc.causeway.ctl; - -import static org.jboss.pnc.causeway.ctl.ImportControllerImpl.METRICS_ARTIFACTS_NUMBER_KEY; -import static org.jboss.pnc.causeway.ctl.ImportControllerImpl.METRICS_ARTIFACTS_SIZE_KEY; -import static org.jboss.pnc.causeway.ctl.ImportControllerImpl.METRICS_LOGS_NUMBER_KEY; -import static org.jboss.pnc.causeway.ctl.ImportControllerImpl.METRICS_LOGS_SIZE_KEY; - -import com.codahale.metrics.Histogram; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.Timer; -import com.codahale.metrics.UniformReservoir; -import com.redhat.red.build.koji.model.json.KojiImport; - -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanBuilder; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.context.Scope; - -import org.jboss.pnc.api.constants.MDCKeys; -import org.jboss.pnc.api.dto.Request; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.ErrorMessages; -import org.jboss.pnc.causeway.bpmclient.BPMClient; -import org.jboss.pnc.causeway.brewclient.BrewClient; -import org.jboss.pnc.causeway.brewclient.BuildTranslator; -import org.jboss.pnc.causeway.brewclient.ImportFileGenerator; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.jboss.pnc.causeway.source.RenamedSources; -import org.jboss.pnc.causeway.source.SourceRenamer; -import org.jboss.pnc.common.otel.OtelUtils; -import org.jboss.pnc.enums.BuildType; -import org.jboss.pnc.pncmetrics.MetricsConfiguration; -import org.jboss.pnc.causeway.pncclient.BuildArtifacts; -import org.jboss.pnc.causeway.pncclient.PncClient; -import org.jboss.pnc.causeway.rest.BrewBuild; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.jboss.pnc.causeway.rest.pnc.BuildImportResultRest; -import org.jboss.pnc.causeway.rest.pnc.BuildImportStatus; -import org.jboss.pnc.causeway.rest.pnc.MilestoneReleaseResultRest; -import org.jboss.pnc.causeway.rest.pnc.ReleaseStatus; -import org.jboss.pnc.dto.Build; -import org.jboss.pnc.enums.ArtifactQuality; - -import javax.ejb.Asynchronous; -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; -import javax.inject.Inject; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import lombok.extern.slf4j.Slf4j; - -import org.jboss.pnc.causeway.CausewayFailure; - -import static org.jboss.pnc.constants.Attributes.BUILD_BREW_NAME; -import static org.jboss.pnc.constants.Attributes.BUILD_BREW_VERSION; - -import org.slf4j.MDC; - -@Deprecated -@Stateless -@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) -@Slf4j -public class PncImportControllerImpl implements PncImportController { - - private static final String METRICS_BASE = "causeway.import.milestone"; - private static final String METRICS_TIMER = ".timer"; - private static final String METRICS_METER = ".meter"; - private static final String METRICS_ERRORS = ".errors"; - - private final PncClient pncClient; - private final BrewClient brewClient; - private final BPMClient bpmClient; - private final BuildTranslator translator; - private final CausewayConfig config; - private final SourceRenamer renamer; - - private final MetricsConfiguration metricsConfiguration; - - @Inject - public PncImportControllerImpl( - PncClient pnclClient, - BrewClient brewClient, - BPMClient bpmClient, - BuildTranslator translator, - CausewayConfig config, - SourceRenamer renamer, - MetricsConfiguration metricConfiguration) { - this.pncClient = pnclClient; - this.brewClient = brewClient; - this.bpmClient = bpmClient; - this.translator = translator; - this.config = config; - this.renamer = renamer; - this.metricsConfiguration = metricConfiguration; - } - - @Override - @Asynchronous - public void importMilestone(int milestoneId, Request callback, String callbackId, String username) { - log.info("Importing PNC milestone {}.", milestoneId); - - // Create a parent child span with values from MDC - SpanBuilder spanBuilder = OtelUtils.buildChildSpan( - GlobalOpenTelemetry.get().getTracer(""), - "PncImportControllerImpl.importMilestone", - SpanKind.CLIENT, - MDC.get(MDCKeys.SLF4J_TRACE_ID_KEY), - MDC.get(MDCKeys.SLF4J_SPAN_ID_KEY), - MDC.get(MDCKeys.SLF4J_TRACE_FLAGS_KEY), - MDC.get(MDCKeys.SLF4J_TRACE_STATE_KEY), - Span.current().getSpanContext(), - Map.of("milestoneId", String.valueOf(milestoneId), "callbackId", callbackId, "username", username)); - Span span = spanBuilder.startSpan(); - log.debug("Started a new span :{}", span); - - MetricRegistry registry = metricsConfiguration.getMetricRegistry(); - Meter meter = registry.meter(METRICS_BASE + METRICS_METER); - meter.mark(); - - Timer timer = registry.timer(METRICS_BASE + METRICS_TIMER); - Timer.Context context = timer.time(); - - Meter errors = registry.meter(METRICS_BASE + METRICS_ERRORS); - - // put the span into the current Context - try (Scope scope = span.makeCurrent()) { - MilestoneReleaseResultRest result = new MilestoneReleaseResultRest(); - result.setMilestoneId(milestoneId); - try { - List results = importProductMilestone(milestoneId, username); - result.setBuilds(results); - - if (results.stream().anyMatch(r -> r.getStatus() == BuildImportStatus.ERROR)) { - result.setReleaseStatus(ReleaseStatus.SET_UP_ERROR); - bpmClient.failure(callback, callbackId, result); - errors.mark(); - } else if (results.stream().anyMatch(r -> r.getStatus() == BuildImportStatus.FAILED)) { - result.setReleaseStatus(ReleaseStatus.IMPORT_ERROR); - bpmClient.failure(callback, callbackId, result); - errors.mark(); - } else { - result.setReleaseStatus(ReleaseStatus.SUCCESS); - bpmClient.success(callback, callbackId, result); - } - } catch (CausewayFailure ex) { - log.warn(ErrorMessages.failedToImportMilestone(milestoneId, ex), ex); - result.setErrorMessage(ex.getMessage()); - result.setReleaseStatus(ReleaseStatus.FAILURE); - bpmClient.failure(callback, callbackId, result); - errors.mark(); - } catch (CausewayException | RuntimeException ex) { - log.error(ErrorMessages.errorImportingMilestone(milestoneId, ex), ex); - result.setErrorMessage(ex.getMessage()); - result.setReleaseStatus(ReleaseStatus.SET_UP_ERROR); - bpmClient.error(callback, callbackId, result); - errors.mark(); - } - - // stop the timer - context.stop(); - } finally { - span.end(); // closing the scope does not end the span, this has to be done manually - } - } - - private List importProductMilestone(int milestoneId, String username) - throws CausewayException { - String tagPrefix = pncClient.getTagForMilestone(milestoneId); - if (!brewClient.tagsExists(tagPrefix)) { - throw new CausewayFailure(ErrorMessages.tagsAreMissingInKoji(tagPrefix, config.getKojiURL())); - } - - Collection builds = findAndAssertBuilds(milestoneId); - - List results = new ArrayList<>(); - for (Build build : builds) { - BuildImportResultRest importResult; - try (MDC.MDCCloseable mdcClose = MDC.putCloseable(MDCKeys.BUILD_ID_KEY, build.getId())) { - BuildArtifacts artifacts = pncClient.findBuildArtifacts(build.getId()); - importResult = importBuild(build, username, artifacts); - if (importResult.getStatus() == BuildImportStatus.SUCCESSFUL && importResult.getBrewBuildId() != null) { - brewClient.tagBuild( - tagPrefix, - new BrewBuild(importResult.getBrewBuildId(), getNVR(build, artifacts))); - } - } catch (CausewayException ex) { - importResult = new BuildImportResultRest(); - if (ex instanceof CausewayFailure) { - log.warn(ErrorMessages.failedToImportBuild(build.getId(), (CausewayFailure) ex)); - importResult.setStatus(BuildImportStatus.FAILED); - } else { - log.error(ErrorMessages.errorImportingBuild(build.getId(), ex)); - importResult.setStatus(BuildImportStatus.ERROR); - } - importResult.setBuildRecordId(build.getId()); - importResult.setErrorMessage(ex.getMessage()); - } - results.add(importResult); - } - - return results; - } - - private Collection findAndAssertBuilds(int milestoneId) throws CausewayException { - Collection builds = pncClient.findBuildsOfProductMilestone(milestoneId); - if (builds == null || builds.isEmpty()) { - throw new CausewayFailure(ErrorMessages.messageMilestoneWithoutBuilds(milestoneId)); - } - return builds; - } - - private BuildImportResultRest importBuild(Build build, String username, BuildArtifacts artifacts) - throws CausewayException { - BrewNVR nvr = getNVR(build, artifacts); - log.info("Processing PNC build {} as {}.", build.getId(), nvr.getNVR()); - BrewBuild brewBuild = brewClient.findBrewBuildOfNVR(nvr); - if (brewBuild != null) { - // FIXME clarify behavior - if the build already exists in brew log as successful import ? - BuildImportResultRest ret = new BuildImportResultRest(); - ret.setBrewBuildId(brewBuild.getId()); - ret.setBrewBuildUrl(brewClient.getBuildUrl(brewBuild.getId())); - ret.setBuildRecordId(build.getId()); - ret.setStatus(BuildImportStatus.SUCCESSFUL); // TODO: replace with EXISTING? - - log.info("Build {} was already imported with id {}.", nvr.getNVR(), brewBuild.getId()); - return ret; - } - - List badArtifacts = new ArrayList<>(); - for (Iterator it = artifacts.buildArtifacts.iterator(); it.hasNext();) { - BuildArtifacts.PncArtifact artifact = it.next(); - if (artifact.artifactQuality == ArtifactQuality.BLACKLISTED - || artifact.artifactQuality == ArtifactQuality.DELETED) { - badArtifacts.add(artifact); - it.remove(); - } - } - - final BuildImportResultRest buildResult; - if (artifacts.buildArtifacts.isEmpty()) { - buildResult = new BuildImportResultRest(); - buildResult.setBuildRecordId(build.getId()); - buildResult.setStatus(BuildImportStatus.SUCCESSFUL); - buildResult.setErrorMessage("Build doesn't contain any artifacts to import, skipping."); - log.info("PNC build {} doesn't contain any artifacts to import, skipping.", build.getId()); - } else { - String buildLog = pncClient.getBuildLog(build.getId()); - - BuildType buildType = build.getBuildConfigRevision().getBuildType(); - String sourcesDeployPath = getSourcesDeployPath(build, artifacts); - - Optional any = artifacts.buildArtifacts.stream() - .filter(a -> a.deployPath.equals(sourcesDeployPath)) - .findAny(); - - RenamedSources sources = null; - if (!any.isPresent()) { - log.info("Sources at '{}' not present, generating sources file.", sourcesDeployPath); - try (InputStream sourcesStream = pncClient.getSources(build.getId())) { - sources = translator.getSources(build, artifacts, sourcesStream); - } catch (IOException ex) { - throw new CausewayException(ErrorMessages.failedToDownloadSources(ex), ex); - } - } - KojiImport kojiImport = translator.translate(nvr, build, artifacts, sources, buildLog, username); - ImportFileGenerator importFiles = translator.getImportFiles(artifacts, sources, buildLog); - buildResult = brewClient.importBuild(nvr, build.getId(), kojiImport, importFiles); - - long artifactSize = artifacts.buildArtifacts.stream().mapToLong(pncArtifact -> pncArtifact.size).sum(); - int artifactNumber = artifacts.buildArtifacts.size(); - int logLenght = buildLog.length(); - try { - logLenght = buildLog.getBytes("UTF-8").length; - } catch (UnsupportedEncodingException e) { - } - - updateHistogram(metricsConfiguration, METRICS_ARTIFACTS_SIZE_KEY, artifactSize); - updateHistogram(metricsConfiguration, METRICS_ARTIFACTS_NUMBER_KEY, artifactNumber); - updateHistogram(metricsConfiguration, METRICS_LOGS_SIZE_KEY, logLenght); - updateHistogram(metricsConfiguration, METRICS_LOGS_NUMBER_KEY, 1); - } - - for (BuildArtifacts.PncArtifact artifact : badArtifacts) { - log.warn(ErrorMessages.badArtifactNotImported(artifact.id)); - } - return buildResult; - } - - private String getSourcesDeployPath(Build build, BuildArtifacts artifacts) throws CausewayException { - String sourcesDeployPath = translator.getSourcesDeployPath(build, artifacts); - if (sourcesDeployPath.startsWith("/")) { - sourcesDeployPath = sourcesDeployPath.substring(1); // PncClientImpl.toPncArtifact strips leading "/" - } - return sourcesDeployPath; - } - - private void updateHistogram(MetricsConfiguration metricsConfiguration, String name, long value) { - Histogram histogram = null; - if (metricsConfiguration != null) { - MetricRegistry registry = metricsConfiguration.getMetricRegistry(); - try { - histogram = registry.register(name, new Histogram(new UniformReservoir())); - } catch (IllegalArgumentException e) { - histogram = registry.histogram(name); - } - } - if (histogram != null) { - histogram.update(value); - } - } - - BrewNVR getNVR(Build build, BuildArtifacts artifacts) throws CausewayException { - if (!build.getAttributes().containsKey(BUILD_BREW_NAME)) { - throw new CausewayFailure(ErrorMessages.missingBrewNameAttributeInBuild()); - } - String version = build.getAttributes().get(BUILD_BREW_VERSION); - if (version == null) { - version = BuildTranslator.guessVersion(build, artifacts); - } - return new BrewNVR(build.getAttributes().get(BUILD_BREW_NAME), version, "1"); - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/inject/CausewayProducer.java b/core/src/main/java/org/jboss/pnc/causeway/inject/CausewayProducer.java deleted file mode 100644 index f8f3f749..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/inject/CausewayProducer.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.inject; - -import org.commonjava.util.jhttpc.auth.MemoryPasswordManager; -import org.commonjava.util.jhttpc.auth.PasswordManager; -import org.commonjava.util.jhttpc.auth.PasswordType; -import org.jboss.pnc.causeway.ErrorMessages; -import org.jboss.pnc.causeway.config.CausewayConfig; - -import javax.annotation.PreDestroy; -import javax.annotation.Resource; -import javax.enterprise.concurrent.ManagedExecutorService; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Default; -import javax.enterprise.inject.Produces; -import javax.inject.Inject; - -import java.io.Closeable; - -import com.redhat.red.build.koji.KojiClient; -import com.redhat.red.build.koji.KojiClientException; -import com.redhat.red.build.koji.config.KojiConfig; -import com.redhat.red.build.koji.config.SimpleKojiConfigBuilder; - -/** - * Created by jdcasey on 11/10/15. - */ -@ApplicationScoped -public class CausewayProducer implements Closeable { - - private final CausewayConfig config; - - @Resource - private ManagedExecutorService executorService; - - private KojiClient koji; - - private final PasswordManager passwords = new MemoryPasswordManager(); - - @Inject - public CausewayProducer(CausewayConfig config) { - this.config = config; - passwords.bind(config.getKojiClientCertificatePassword(), CausewayConfig.KOJI_SITE_ID, PasswordType.KEY); - } - - private synchronized void setupKoji(PasswordManager passwords) { - if (koji != null) { - return; - } - - SimpleKojiConfigBuilder builder = new SimpleKojiConfigBuilder(); - builder.withKojiSiteId("koji") - .withKojiURL(config.getKojiURL()) - .withClientKeyCertificateFile(config.getKojiClientKeyCertificateFile()) - .withKojiClientCertificatePassword(config.getKojiClientCertificatePassword()) - .withServerCertificateFile(config.getKojiServerCertificateFile()) - .withTrustSelfSigned(config.getKojiTrustSelfSigned()) - .withTimeout(config.getKojiTimeout()) - .withConnectionPoolTimeout(config.getKojiConnectionPoolTimeout()) - .withMaxConnections(config.getKojiConnections()); - - KojiConfig kc = builder.build(); - - try { - koji = new KojiClient(kc, passwords, executorService); - } catch (KojiClientException ex) { - throw new RuntimeException(ErrorMessages.canNotConnectToKoji(ex), ex); - } - } - - @PreDestroy - public void close() { - if (koji != null) { - koji.close(); - } - } - - @Produces - @Default - public KojiClient getKojiClient() { - if (koji == null) { - setupKoji(passwords); - } - return koji; - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/pncclient/BuildArtifacts.java b/core/src/main/java/org/jboss/pnc/causeway/pncclient/BuildArtifacts.java deleted file mode 100644 index d0f5de42..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/pncclient/BuildArtifacts.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.pncclient; - -import org.jboss.pnc.enums.ArtifactQuality; - -import java.util.ArrayList; -import java.util.List; - -@Deprecated -public final class BuildArtifacts { - - public final List buildArtifacts; - public final List dependencies; - - public BuildArtifacts() { - buildArtifacts = new ArrayList<>(); - dependencies = new ArrayList<>(); - } - - public static class PncArtifact { - public final String id; - public final String identifier; - public final String deployPath; - public final String checksum; - public final String deployUrl; - public final ArtifactQuality artifactQuality; - public final long size; - - public PncArtifact( - String id, - String identifier, - String deployPath, - String checksum, - String deployUrl, - long size, - ArtifactQuality artifactQuality) { - this.id = id; - this.identifier = identifier; - this.deployPath = deployPath; - this.checksum = checksum; - this.deployUrl = deployUrl; - this.size = size; - this.artifactQuality = artifactQuality; - } - } -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClient.java b/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClient.java deleted file mode 100644 index d265b538..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClient.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.pncclient; - -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.dto.Build; - -import java.io.InputStream; -import java.util.Collection; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Deprecated -public interface PncClient { - - BuildArtifacts findBuildArtifacts(String buildId) throws CausewayException; - - public Collection findBuildsOfProductMilestone(int milestoneId) throws CausewayException; - - public String getTagForMilestone(int milestoneId) throws CausewayException; - - public String getBuildLog(String buildId) throws CausewayException; - - public InputStream getSources(String id) throws CausewayException; -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientException.java b/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientException.java deleted file mode 100644 index d73f168e..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientException.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.pncclient; - -import org.jboss.pnc.causeway.CausewayException; - -/** - * Created by jdcasey on 11/10/15. - */ -@Deprecated -public class PncClientException extends CausewayException { - private static final long serialVersionUID = 1L; - - public PncClientException(String format, Throwable cause, Object... params) { - super(format, cause, params); - } - - public PncClientException(String format, Object... params) { - super(format, params); - } - -} diff --git a/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientImpl.java b/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientImpl.java deleted file mode 100644 index 67ce0d50..00000000 --- a/core/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientImpl.java +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - *

- * 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. - */ -package org.jboss.pnc.causeway.pncclient; - -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.CausewayFailure; -import org.jboss.pnc.causeway.ErrorMessages; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.jboss.pnc.causeway.pncclient.BuildArtifacts.PncArtifact; -import org.jboss.pnc.client.BuildClient; -import org.jboss.pnc.client.ClientException; -import org.jboss.pnc.client.ProductMilestoneClient; -import org.jboss.pnc.client.RemoteCollection; -import org.jboss.pnc.client.RemoteResourceException; -import org.jboss.pnc.client.RemoteResourceNotFoundException; -import org.jboss.pnc.constants.Attributes; -import org.jboss.pnc.dto.Artifact; -import org.jboss.pnc.dto.Build; -import org.jboss.pnc.dto.ProductMilestone; -import org.jboss.pnc.enums.BuildStatus; -import org.jboss.pnc.rest.api.parameters.BuildsFilterParameters; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.ws.rs.core.Response; -import java.io.InputStream; -import java.util.Collection; -import java.util.HashSet; -import java.util.Optional; -import java.util.Scanner; - -import lombok.extern.slf4j.Slf4j; - -/** - * Created by jdcasey on 2/9/16. - */ -@ApplicationScoped -@Deprecated -@Slf4j -public class PncClientImpl implements PncClient { - - private final ProductMilestoneClient milestoneClient; - private final BuildClient buildClient; - - @Inject - public PncClientImpl(CausewayConfig config) { - this.milestoneClient = new ProductMilestoneClient(config.getPncClientConfig()); - this.buildClient = new BuildClient(config.getPncClientConfig()); - } - - @Override - public String getTagForMilestone(int milestoneId) throws CausewayException { - ProductMilestone milestone; - try { - log.debug("Getting milestone with id {} from PNC", milestoneId); - milestone = milestoneClient.getSpecific(String.valueOf(milestoneId)); - } catch (RemoteResourceNotFoundException ex) { - throw new CausewayFailure(ErrorMessages.milestoneNotFoundWhenGettingTag(milestoneId, ex), ex); - } catch (RemoteResourceException ex) { - throw new CausewayException(ErrorMessages.errorReadingTagFromMilestone(milestoneId, ex), ex); - } catch (ClientException ex) { - throw new CausewayException(ErrorMessages.errorCommunicatingWhenGettingTag(milestoneId, ex), ex); - } - return milestone.getProductVersion().getAttributes().get(Attributes.BREW_TAG_PREFIX); - } - - @Override - public Collection findBuildsOfProductMilestone(int milestoneId) throws CausewayException { - Collection builds = new HashSet<>(); - try { - log.debug("Getting successful builds of milestone with id {} from PNC", milestoneId); - RemoteCollection buildPages = milestoneClient.getBuilds( - String.valueOf(milestoneId), - new BuildsFilterParameters(), - Optional.empty(), - Optional.of("status==SUCCESS")); - for (Build build : buildPages) { - if (build.getStatus().equals(BuildStatus.SUCCESS)) { - builds.add(build); - } - } - } catch (RemoteResourceException ex) { - throw new CausewayException(ErrorMessages.errorReadingBuildsFromMilestone(milestoneId, ex), ex); - } - return builds; - } - - @Override - public String getBuildLog(String buildId) throws CausewayException { - Optional buildLog; - try { - log.debug("Getting build logs of build with id {} from PNC", buildId); - buildLog = buildClient.getBuildLogs(String.valueOf(buildId)); - InputStream logInput = buildLog - .orElseThrow(() -> new CausewayException(ErrorMessages.buildLogIsEmpty(buildId))); - Scanner s = new Scanner(logInput).useDelimiter("\\A"); - return s.hasNext() ? s.next() : ""; - } catch (RemoteResourceException ex) { - throw new CausewayException(ErrorMessages.errorReadingBuildLog(buildId, ex), ex); - } - } - - @Override - public InputStream getSources(String id) throws CausewayException { - try { - log.debug("Getting sources of build with id {} from PNC", id); - Response response = buildClient.getInternalScmArchiveLink(id); - try { - if (response.getStatus() >= 400) { - throw new CausewayException( - ErrorMessages.errorReadingBuildSources( - id, - response.getStatus(), - response.readEntity(String.class))); - } - return response.readEntity(InputStream.class); - } catch (RuntimeException ex) { - response.close(); - throw new CausewayException(ErrorMessages.errorReadingBuildSources(id, ex), ex); - } - } catch (RemoteResourceException ex) { - throw new CausewayException(ErrorMessages.errorReadingBuildSources(id, ex), ex); - } - } - - @Override - public BuildArtifacts findBuildArtifacts(String buildId) throws CausewayException { - Collection builtArtifacts = getArtifacts(buildId, buildClient::getBuiltArtifacts); - Collection dependantArtifact = getArtifacts(buildId, buildClient::getDependencyArtifacts); - - BuildArtifacts build = new BuildArtifacts(); - - build.buildArtifacts.addAll(builtArtifacts); - build.dependencies.addAll(dependantArtifact); - - return build; - } - - private PncArtifact toPncArtifact(Artifact artifact) { - - String deployPath = artifact.getDeployPath(); - if (deployPath.startsWith("/")) - deployPath = deployPath.substring(1); - return new PncArtifact( - artifact.getId(), - artifact.getIdentifier(), - deployPath, - artifact.getMd5(), - artifact.getDeployUrl(), - artifact.getSize() == null ? 1 : artifact.getSize(), - artifact.getArtifactQuality()); - } - - private Collection getArtifacts( - String buildId, - IntFunctionWithRemoteException> query) throws CausewayException { - Collection pncArtifacts = new HashSet<>(); - try { - RemoteCollection artifacts = query.get(buildId); - for (Artifact artifact : artifacts) { - pncArtifacts.add(toPncArtifact(artifact)); - } - } catch (RemoteResourceException ex) { - throw new CausewayException(ErrorMessages.errorReadingBuildArtifacts(buildId, ex), ex); - } - return pncArtifacts; - } - - /** - * Special IntFunction that throws {@code org.jboss.pnc.client.RemoteResourceException} - * - * It was created so that method {@code getArtifacts} could catch and handle the exception, otherwise it would have - * to be handled in higher level method. - * - * @param Return type of the Function - */ - @FunctionalInterface - public interface IntFunctionWithRemoteException { - T get(String i) throws RemoteResourceException; - } - -} diff --git a/core/src/main/resources/META-INF/beans.xml b/core/src/main/resources/META-INF/beans.xml deleted file mode 100644 index 794b8b5f..00000000 --- a/core/src/main/resources/META-INF/beans.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/core/src/main/templates/org/jboss/pnc/causeway/config/constants/BuildInformationConstants.java b/core/src/main/templates/org/jboss/pnc/causeway/config/constants/BuildInformationConstants.java deleted file mode 100644 index c9686467..00000000 --- a/core/src/main/templates/org/jboss/pnc/causeway/config/constants/BuildInformationConstants.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.config.constants; - -/** - * The values in here are auto-generated from Maven plugin maven-replacer-plugin and the template is found in the - * template folder - * - * @author Dustin Kut Moy Cheung - */ -public final class BuildInformationConstants { - - public static final String VERSION = "@version@"; - public static final String COMMIT_HASH = "@commit-id@"; - public static final String BUILD_TIME = "@build-time@"; -} \ No newline at end of file diff --git a/core/src/main/webapp/WEB-INF/web.xml b/core/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 2a882e9f..00000000 --- a/core/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - diff --git a/core/src/test/java/org/jboss/pnc/causeway/brewclient/TranslatorTest.java b/core/src/test/java/org/jboss/pnc/causeway/brewclient/TranslatorTest.java deleted file mode 100644 index 1f696fb7..00000000 --- a/core/src/test/java/org/jboss/pnc/causeway/brewclient/TranslatorTest.java +++ /dev/null @@ -1,426 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.brewclient; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.redhat.red.build.koji.model.json.BuildOutput; -import com.redhat.red.build.koji.model.json.BuildTool; -import com.redhat.red.build.koji.model.json.KojiImport; -import com.redhat.red.build.koji.model.json.NpmTypeInfoExtraInfo; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.assertj.core.api.Condition; -import org.jboss.pnc.api.causeway.dto.push.Build; -import org.jboss.pnc.api.causeway.dto.push.BuildRoot; -import org.jboss.pnc.api.causeway.dto.push.BuiltArtifact; -import org.jboss.pnc.api.causeway.dto.push.Logfile; -import org.jboss.pnc.api.causeway.dto.push.MavenBuild; -import org.jboss.pnc.api.causeway.dto.push.MavenBuiltArtifact; -import org.jboss.pnc.api.causeway.dto.push.NpmBuild; -import org.jboss.pnc.api.causeway.dto.push.NpmBuiltArtifact; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.brewclient.ImportFileGenerator.Artifact; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.jboss.pnc.causeway.pncclient.BuildArtifacts; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.jboss.pnc.causeway.source.RenamedSources; -import org.jboss.pnc.causeway.source.SourceRenamer; -import org.jboss.pnc.enums.ArtifactQuality; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.assertj.core.api.Assertions.anyOf; -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.Instant; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - -import static org.junit.Assert.assertEquals; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@SuppressWarnings("deprecation") -public class TranslatorTest { - private static final CausewayConfig config = new CausewayConfig(); - private static final SourceRenamer renamer = new SourceRenamer(); - private static final BuildTranslator bt = new BuildTranslatorImpl(config, renamer); - private static final ObjectMapper mapper = new ObjectMapper(); - private static final String SOURCES_PATH = "sources.tar.gz"; - private static final String SOURCES = "Burn this after reading!"; - - @BeforeClass - public static void setUp() { - config.setPnclBuildsURL("http://example.com/build-records/"); - config.setArtifactStorage("http://example.com/storage/"); - mapper.registerSubtypes(MavenBuild.class, MavenBuiltArtifact.class); - mapper.registerModule(new JavaTimeModule()); - } - - @Test - public void testReadBuildArtifacts() throws Exception { - // given - String groupId = "org.jboss.pnc"; - String artifactId = "parent"; - String version = "2.0.0"; - - String json = readResponseBodyFromTemplate("build-dto-1.json"); - org.jboss.pnc.dto.Build build = mapper.readValue(json, org.jboss.pnc.dto.Build.class); - - BuildArtifacts artifacts = new BuildArtifacts(); - artifacts.buildArtifacts.add( - newArtifact( - "2369", - "org.apache.geronimo.specs", - "geronimo-annotation_1.0_spec", - "1.1.1.redhat-1", - "pom")); - artifacts.buildArtifacts.add( - newArtifact( - "2370", - "org.apache.geronimo.specs", - "geronimo-annotation_1.0_spec", - "1.1.1.redhat-1", - "jar")); - artifacts.buildArtifacts.add( - newArtifact( - "2371", - "org.apache.geronimo.specs", - "geronimo-annotation_1.0_spec", - "1.1.1.redhat-1", - "tar.gz", - "project-sources")); - - artifacts.dependencies.add(newArtifact("7", "org.apache.maven", "maven-project", "2.0.6", "pom")); - artifacts.dependencies.add(newArtifact("9", "org.apache.maven.shared", "maven-shared-io", "1.1", "jar")); - artifacts.dependencies.add(newArtifact("10", "xml-apis", "xml-apis", "1.0.b2", "jar")); - - RenamedSources sources = prepareSourcesFile(new RenamedSources.ArtifactType(groupId, artifactId, version)); - - // when - KojiImport out = bt.translate( - new BrewNVR(groupId + ":" + artifactId, version, "1"), - build, - artifacts, - sources, - "foo-bar-logs", - "joe"); - - // Then - Condition buildArtifact = new Condition<>( - bo -> artifacts.buildArtifacts.stream().anyMatch(a -> a.deployPath.equals(bo.getFilename())), - "build artifact"); - Condition buildLog = new Condition<>(bo -> bo.getOutputType().equals("log"), "build log"); - Condition mavenArtifact = new Condition<>( - bo -> bo.getOutputType().equals("maven"), - "maven artifact"); - - assertThat(out.getBuild()).hasFieldOrPropertyWithValue("name", groupId + "-" + artifactId) - .hasFieldOrPropertyWithValue("version", version) - .hasFieldOrPropertyWithValue("release", "1") - .hasFieldOrPropertyWithValue("startTime", Date.from(Instant.parse("2019-02-15T02:02:36.645Z"))); - assertThat(out.getBuild().getSource()) - .hasFieldOrPropertyWithValue("revision", "57ebfa20374d708e232fc8b45f37def055300260"); - assertThat(out.getBuild().getSource().getUrl()).contains("http://github.com/project-ncl/pnc.git"); - assertThat(out.getBuild().getExtraInfo().getMavenExtraInfo()).hasFieldOrPropertyWithValue("groupId", groupId) - .hasFieldOrPropertyWithValue("artifactId", artifactId) - .hasFieldOrPropertyWithValue("version", version); - assertThat(out.getBuildRoots()).hasSize(1); - assertThat(out.getBuildRoots().get(0).getBuildTools()).hasSize(3) - .extracting(BuildTool::getName) - .containsExactly("JDK", "MAVEN", "OS"); - assertThat(out.getOutputs()).hasSize(3 + 2) // 3 artifacts + build log + sources - .areExactly(3, buildArtifact) - .areExactly(4, mavenArtifact) - .areExactly(1, buildLog); - } - - @Test - public void testReadNpmBuildArtifacts() throws Exception { - // given - String scope = "@redhat"; - String packageName = "opossum"; - String version = "0.5.0"; - - String json = readResponseBodyFromTemplate("build-dto-npm.json"); - org.jboss.pnc.dto.Build build = mapper.readValue(json, org.jboss.pnc.dto.Build.class); - - BuildArtifacts artifacts = new BuildArtifacts(); - artifacts.buildArtifacts.add(newNpmArtifact("1800", scope, packageName, version)); - - artifacts.dependencies.add(newNpmArtifact("7777", null, "once", "1.4.0")); - artifacts.dependencies.add(newNpmArtifact("9999", null, "inflight", "1.0.6")); - artifacts.dependencies.add(newNpmArtifact("10101", "@babel", "core", "7.11.0")); - - RenamedSources sources = prepareSourcesFile( - new RenamedSources.ArtifactType(scope + "/" + packageName, version)); - - // when - KojiImport out = bt.translate( - new BrewNVR(scope + ":" + packageName, version, "1"), - build, - artifacts, - sources, - "foo-bar-logs", - "joe"); - - // Then - Condition buildArtifact = new Condition<>( - bo -> artifacts.buildArtifacts.stream().anyMatch(a -> a.deployPath.equals(bo.getFilename())), - "build artifact"); - Condition buildLog = new Condition<>(bo -> bo.getOutputType().equals("log"), "build log"); - Condition npmArtifact = new Condition<>(bo -> bo.getOutputType().equals("npm"), "npm artifact"); - - assertThat(out.getBuild()).hasFieldOrPropertyWithValue("name", scope + "-" + packageName) - .hasFieldOrPropertyWithValue("version", version) - .hasFieldOrPropertyWithValue("release", "1") - .hasFieldOrPropertyWithValue("startTime", Date.from(Instant.parse("2021-07-23T15:54:18.259Z"))); - assertThat(out.getBuild().getSource()) - .hasFieldOrPropertyWithValue("revision", "647daeb088cd49354f8831d3e3dab440e039b11a"); - assertThat(out.getBuild().getSource().getUrl()).contains("http://github.com/nodeshift/opossum.git"); - assertThat(out.getBuild().getExtraInfo().getNpmExtraInfo()) - .hasFieldOrPropertyWithValue("name", scope + "-" + packageName) - .hasFieldOrPropertyWithValue("version", version); - assertThat(out.getBuild().getExtraInfo().getTypeInfo()) - .hasFieldOrPropertyWithValue("npmTypeInfoExtraInfo", NpmTypeInfoExtraInfo.getInstance()); - assertThat(out.getBuildRoots()).hasSize(1); - assertThat(out.getBuildRoots().get(0).getBuildTools()).hasSize(3) - .extracting(BuildTool::getName) - .containsExactly("NPM", "OS", "Nodejs"); - assertThat(out.getOutputs()).hasSize(3) // 1 artifact + build log + sources - .areExactly(1, buildArtifact) - .areExactly(2, npmArtifact) - .areExactly(1, buildLog); - - // System.out.println(mapper.writeValueAsString(out)); - } - - @Test(expected = IllegalArgumentException.class) - public void testTranslateBuildWithMissingTool() throws Exception { - // given - String groupId = "org.jboss.pnc"; - String artifactId = "parent"; - String version = "2.0.0"; - - String json = readResponseBodyFromTemplate("build-dto-missing-tool-version.json"); - org.jboss.pnc.dto.Build build = mapper.readValue(json, org.jboss.pnc.dto.Build.class); - - BuildArtifacts artifacts = new BuildArtifacts(); - artifacts.buildArtifacts.add( - newArtifact( - "2369", - "org.apache.geronimo.specs", - "geronimo-annotation_1.0_spec", - "1.1.1.redhat-1", - "pom")); - RenamedSources sources = prepareSourcesFile(new RenamedSources.ArtifactType(groupId, artifactId, version)); - - // throw exception when - KojiImport out = bt.translate( - new BrewNVR(groupId + ":" + artifactId, version, "1"), - build, - artifacts, - sources, - "foo-bar-logs", - "joe"); - } - - @Test - public void testReadBuild() throws Exception { - // given - String groupId = "org.apache.geronimo.specs"; - String artifactId = "geronimo-annotation_1.0_spec"; - String version = "1.1.1"; - String json = readResponseBodyFromTemplate("build.json"); - - Build build = mapper.readValue(json, Build.class); - RenamedSources sources = prepareSourcesFile(new RenamedSources.ArtifactType(groupId, artifactId, version)); - - SpecialImportFileGenerator importFiles = new SpecialImportFileGenerator(sources); - for (Logfile log : build.getLogs()) { - importFiles.getLogs().add(new SpecialImportFileGenerator.Log(log.getFilename(), new byte[1])); - } - - // when - KojiImport out = bt - .translate(new BrewNVR(groupId + ":" + artifactId, version, "1"), build, sources, "joe", importFiles); - - // Then - Condition buildArtifact = new Condition<>( - bo -> bo.getOutputType().equals("maven"), - "maven artifact"); - Condition logFile = new Condition<>(bo -> bo.getOutputType().equals("log"), "log file"); - Condition sourceFile = new Condition<>( - bo -> bo.getOutputType().equals("remote-source-file"), - "source file"); - - assertThat(out.getBuild()).hasFieldOrPropertyWithValue("name", groupId + "-" + artifactId) - .hasFieldOrPropertyWithValue("version", version) - .hasFieldOrPropertyWithValue("release", "1") - .hasFieldOrPropertyWithValue("startTime", new Date(1470309691844l)); - assertThat(out.getBuild().getSource()) - .hasFieldOrPropertyWithValue("revision", "repour-57ebfa20374d708e232fc8b45f37def055300260"); - assertThat(out.getBuild().getSource().getUrl()) - .contains("http://internal.maven.repo.com/productization-test3/geronimo-specs"); - assertThat(out.getBuild().getExtraInfo().getMavenExtraInfo()).hasFieldOrPropertyWithValue("groupId", groupId) - .hasFieldOrPropertyWithValue("artifactId", artifactId) - .hasFieldOrPropertyWithValue("version", version); - assertThat(out.getBuildRoots()).hasSize(1); - assertThat(out.getBuildRoots().get(0).getBuildTools()).hasSize(3) - .extracting(BuildTool::getName) - .containsExactly("JDK", "MAVEN", "OS"); - assertThat(out.getOutputs()).hasSize(3 + 2 + 1) // 3 artifacts + 2 logs + sources - .areExactly(4, buildArtifact) - .areExactly(2, logFile) - .areExactly(0, sourceFile); - - mapper.enable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS); - String jsonOut = mapper.writeValueAsString(out); - System.out.println("RESULTA:\n" + jsonOut); - } - - @Test - public void testNpmImportPathsComposition() throws CausewayException { - Set artifacts = new HashSet<>(); - artifacts.add( - NpmBuiltArtifact.builder() - .repositoryPath("/api/content/npm/hosted/pnc-builds/") - .artifactPath("/thepackage/-/thepackage-1.0.0.tgz") - .architecture("") - .filename("thepackage-1.0.0.tgz") - .md5("") - .name("thepackage_1.0.0") - .version("1.0.0") - .build()); - BuildRoot buildRoot = BuildRoot.builder() - .container("") - .containerArchitecture("") - .host("") - .hostArchitecture("") - .tools(Collections.emptyMap()) - .build(); - Build build = NpmBuild.builder() - .buildName("") - .builtArtifacts(artifacts) - .externalBuildSystem("") - .externalBuildURL("") - .startTime(new Date()) - .endTime(new Date()) - .scmURL("") - .scmRevision("") - .buildRoot(buildRoot) - .logs(Collections.emptySet()) - .sourcesURL("") - .dependencies(Collections.emptySet()) - .tagPrefix("") - .name("") - .build(); - ImportFileGenerator importFiles = bt.getImportFiles(build, null); - - Set importArtifacts = importFiles.artifacts; - assertEquals(1, importArtifacts.size()); - assertEquals( - "http://example.com/storage/api/content/npm/hosted/pnc-builds/thepackage/-/thepackage-1.0.0.tgz", - importArtifacts.iterator().next().getUrl().toString()); - } - - private RenamedSources prepareSourcesFile(RenamedSources.ArtifactType artifactType) throws IOException { - Path tempFile = Files.createTempFile("burn", "me"); - Files.write(tempFile, Collections.singleton(SOURCES)); - return new RenamedSources(tempFile, SOURCES_PATH, "01234", artifactType); - } - - private static org.jboss.pnc.causeway.pncclient.BuildArtifacts.PncArtifact newArtifact( - String id, - String groupId, - String artifactId, - String version, - String type) { - return newArtifact(id, groupId, artifactId, version, type, null); - } - - private static BuildArtifacts.PncArtifact newArtifact( - String id, - String groupId, - String artifactId, - String version, - String type, - String specifier) { - final String filename; - final String identifier; - if (specifier == null) { - filename = artifactId + "-" + version + "." + type; - identifier = groupId + ":" + artifactId + ":" + type + ":" + version; - } else { - filename = artifactId + "-" + version + "-" + specifier + "." + type; - identifier = groupId + ":" + artifactId + ":" + type + ":" + version + ":" + specifier; - } - final String path = groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + filename; - return new BuildArtifacts.PncArtifact( - id, - identifier, - filename, - "bedf8af1b107b36c72f52009e6fcc768", - "http://ulozto.cz/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721/" + path, - 13245, - ArtifactQuality.NEW); - } - - private static BuildArtifacts.PncArtifact newNpmArtifact( - String id, - String scope, - String packageName, - String version) { - final String identifier; - if (scope == null) { - identifier = packageName + ":" + version; - } else { - identifier = scope + "/" + packageName + ":" + version; - } - final String path = (scope == null ? "" : scope + "/") + packageName + "/-/" + packageName + "-" + version - + ".tgz"; - return new BuildArtifacts.PncArtifact( - id, - identifier, - path, - "bedf8af1b107b36c72f52009e6fcc768", - "http://repository.com/build-repo/" + path, - 13245, - ArtifactQuality.NEW); - } - - private String readResponseBodyFromTemplate(String name) throws IOException { - String folderName = getClass().getPackage().getName().replace(".", "/"); - try (InputStream inputStream = getContextClassLoader().getResourceAsStream(folderName + "/" + name)) { - return StringUtils.join(IOUtils.readLines(inputStream, Charset.forName("utf-8")), "\n"); - } - } - - private ClassLoader getContextClassLoader() { - return Thread.currentThread().getContextClassLoader(); - } -} diff --git a/core/src/test/java/org/jboss/pnc/causeway/ctl/ImportControllerTest.java b/core/src/test/java/org/jboss/pnc/causeway/ctl/ImportControllerTest.java deleted file mode 100644 index f33a96ec..00000000 --- a/core/src/test/java/org/jboss/pnc/causeway/ctl/ImportControllerTest.java +++ /dev/null @@ -1,403 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.ctl; - -import com.codahale.metrics.Histogram; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.Timer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.tomakehurst.wiremock.client.WireMock; -import com.github.tomakehurst.wiremock.junit.WireMockRule; -import com.redhat.red.build.koji.model.json.KojiImport; -import com.redhat.red.build.koji.model.json.util.KojiObjectMapper; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.jboss.pnc.api.causeway.dto.push.Build; -import org.jboss.pnc.api.causeway.dto.push.MavenBuild; -import org.jboss.pnc.api.causeway.dto.push.MavenBuiltArtifact; -import org.jboss.pnc.api.causeway.dto.push.NpmBuild; -import org.jboss.pnc.api.causeway.dto.push.NpmBuiltArtifact; -import org.jboss.pnc.api.dto.Request; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.CausewayFailure; -import org.jboss.pnc.causeway.authentication.KeycloakClient; -import org.jboss.pnc.causeway.brewclient.BrewClient; -import org.jboss.pnc.causeway.brewclient.BuildTranslatorImpl; -import org.jboss.pnc.causeway.brewclient.SpecialImportFileGenerator; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.jboss.pnc.pncmetrics.MetricsConfiguration; -import org.jboss.pnc.causeway.rest.BrewBuild; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.InjectMocks; -import static org.junit.Assert.assertEquals; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.net.URI; -import java.nio.charset.Charset; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static org.jboss.pnc.causeway.ErrorMessages.tagsAreMissingInKoji; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.same; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT; - -public class ImportControllerTest { - - @Rule - public WireMockRule wireMockRule = (new WireMockRule(8081)); - - private static final String USERNAME = "joe"; - private static final String TAG_PREFIX = "pnc-foo-0.1"; - private static final String BUILD_VERSION = "1.1.1"; - private static final String ARTIFACTS_VERSION = "1.1.1.redhat_1"; - private static final String BUILD_NAME = "org.apache.geronimo.specs:geronimo-annotation_1.0_spec"; - private static final URI CALLBACK_URL = URI.create("http://localhost:8081/callback"); - private static final Request CALLBACK_TARGET = new Request(Request.Method.POST, CALLBACK_URL); - private static final String KOJI_URL = "http://koji.example.com/koji"; - private static final String KOJI_BUILD_URL = KOJI_URL + "/build?id="; - - private static final String BUILD_NPM_NAME = "npm_async_3.1.0-npm"; - private static final String ARTIFACT_NPM_VERSION = "3.1.0.redhat_1"; - - private static final BrewNVR NVR = new BrewNVR(BUILD_NAME, BUILD_VERSION, "1"); - private static final BrewNVR NVR2 = new BrewNVR(BUILD_NAME, BUILD_VERSION, "2"); - - private static final SpecialImportFileGenerator IMPORT_FILE_GENERATOR = mock(SpecialImportFileGenerator.class); - private static final KojiImport KOJI_IMPORT = mock(KojiImport.class); - - private static final ObjectMapper mapper = new KojiObjectMapper(); - - @Mock - private BrewClient brewClient; - @Mock - private CausewayConfig causewayConfig; - - @Mock - public BuildTranslatorImpl translator; - - @Mock - public MetricsConfiguration metricsConfiguration; - - @Mock - public MetricRegistry metricRegistry; - - @Mock - public KeycloakClient keycloakClient; - - @InjectMocks - private ImportControllerImpl importController; - - @Before - public void before() throws Exception { - MockitoAnnotations.initMocks(this); - when(causewayConfig.getKojiURL()).thenReturn(KOJI_URL); - when(causewayConfig.getKojiWebURL()).thenReturn(KOJI_BUILD_URL); - when(metricsConfiguration.getMetricRegistry()).thenReturn(metricRegistry); - when(metricRegistry.meter(anyString())).thenReturn(mock(Meter.class)); - Timer timer = mock(Timer.class); - when(metricRegistry.timer(anyString())).thenReturn(timer); - when(timer.time()).thenReturn(mock(Timer.Context.class)); - - Histogram histogram = mock(Histogram.class); - when(metricRegistry.register(anyString(), any(Histogram.class))).thenReturn(histogram); - when(metricRegistry.histogram(anyString())).thenReturn(histogram); - - when(keycloakClient.getAccessToken()).thenReturn("hahaha"); - - mapper.registerSubtypes(MavenBuild.class, NpmBuild.class, MavenBuiltArtifact.class, NpmBuiltArtifact.class); - - stubFor(post(urlEqualTo("/callback")).willReturn(aResponse().withStatus(200))); - } - - private Build getMavenBuild() throws IOException { - return getBuild("build.json"); - } - - private Build getNpmBuild() throws IOException { - return getBuild("npmbuild.json"); - } - - private Build getBuild(String buildFileName) throws IOException { - String json = readResponseBodyFromTemplate(buildFileName); - return mapper.readValue(json, Build.class); - } - - private void mockBrew() throws CausewayException { - doReturn(true).when(brewClient).tagsExists(eq(TAG_PREFIX)); - when(brewClient.getBuildUrl(anyInt())).then(inv -> KOJI_BUILD_URL + inv.getArguments()[0]); - doNothing().when(brewClient).tagBuild(eq(TAG_PREFIX), any()); - } - - private void mockTranslator() throws CausewayException { - doReturn(KOJI_IMPORT).when(translator).translate(eq(NVR), any(), any(), any(), any()); - doReturn(IMPORT_FILE_GENERATOR).when(translator).getImportFiles(any(), any()); - } - - private BrewBuild mockExistingBuild(int id, BrewNVR nvr, boolean tagged) throws Exception { - BrewBuild brewBuild = new BrewBuild(id, nvr); - when(brewClient.findBrewBuildOfNVR(eq(nvr))).thenReturn(brewBuild); - when(brewClient.findBrewBuild(eq(id))).thenReturn(brewBuild); - when(brewClient.isBuildTagged(eq(TAG_PREFIX), same(brewBuild))).thenReturn(tagged); - return brewBuild; - } - - @Test - public void testReImportBuildWhenPreviousUntagedImportExists() throws Exception { - // Test setup - mockBrew(); - - // Mock existing Brew build - BrewBuild brewBuild = mockExistingBuild(11, NVR, false); - - // Run import - importController.importBuild(getMavenBuild(), CALLBACK_TARGET, USERNAME, true); - - // Verify - verify(brewClient).tagBuild(eq(TAG_PREFIX), same(brewBuild)); - verifySuccess("Build was already imported with id 11 but not previously tagged. Tagged now."); - } - - @Test - public void testReImportBuildWhenPreviousTaggedImportExists() throws Exception { - // Test setup - mockBrew(); - mockTranslator(); - - // Mock existing Brew build - mockExistingBuild(11, NVR, true); - // Mock Brew import - KojiImport kojiImport = mock(KojiImport.class); - doReturn(kojiImport).when(translator).translate(eq(NVR2), any(), any(), any(), any()); - BrewBuild brewBuild = new BrewBuild(12, NVR2); - doReturn(brewBuild).when(brewClient).importBuild(eq(NVR2), same(kojiImport), same(IMPORT_FILE_GENERATOR)); - - // Run import - importController.importBuild(getMavenBuild(), CALLBACK_TARGET, USERNAME, true); - - // Verify - verify(brewClient).tagBuild(eq(TAG_PREFIX), same(brewBuild)); - verifySuccess("Build was previously imported. Reimported again with revision 2 and with id 12.", "12"); - } - - @Test - public void testImportBuildWhenPreviousTaggedImportExists() throws Exception { - // Test setup - mockBrew(); - mockTranslator(); - - // Mock existing Brew build - mockExistingBuild(11, NVR, true); - - // Run import - importController.importBuild(getMavenBuild(), CALLBACK_TARGET, USERNAME, false); - - // Verify - verifySuccess("Build was already imported with id 11"); - } - - @Test - public void testImportBuildWhenConflictingBrewBuildExists() throws Exception { - // Test setup - mockBrew(); - - // Mock existing Brew build - doThrow(new CausewayException("Conflicting brew build exists.")).when(brewClient).findBrewBuildOfNVR(eq(NVR)); - - // Run import - importController.importBuild(getMavenBuild(), CALLBACK_TARGET, USERNAME, true); - - // Verify - verifyError("Conflicting brew build exists."); - } - - @Test - public void testImportBuild() throws Exception { - // Test setup - mockBrew(); - mockTranslator(); - - // Mock Brew import - BrewBuild brewBuild = new BrewBuild(11, NVR); - doReturn(brewBuild).when(brewClient).importBuild(eq(NVR), same(KOJI_IMPORT), same(IMPORT_FILE_GENERATOR)); - - // Run import - importController.importBuild(getMavenBuild(), CALLBACK_TARGET, USERNAME, true); - - // Verify - verify(brewClient).tagBuild(eq(TAG_PREFIX), same(brewBuild)); - verifySuccess("Build imported with id 11."); - } - - @Test - public void testImportBuildWithEmptyArtifacts() throws Exception { - // Test setup - mockBrew(); - - // Mock no builds in milestone - Build build = getMavenBuild(); - build.getBuiltArtifacts().clear(); - - // Run import - importController.importBuild(build, CALLBACK_TARGET, USERNAME, false); - - // Verify - verifyFailure("Build doesn't contain any artifacts."); - } - - @Test - public void testImportBuildWhereImportBuildThrowsException() throws Exception { - String exceptionMessage = "Import build failed"; - - // Test setup - mockBrew(); - - // Mock exception from Brew Client - doThrow(new CausewayException(exceptionMessage)).when(brewClient).findBrewBuildOfNVR(eq(NVR)); - - // Run import - importController.importBuild(getMavenBuild(), CALLBACK_TARGET, USERNAME, true); - - // Verify - verifyError(exceptionMessage); - } - - @Test - public void testImportBuildWithArtifactImportErrors() throws Exception { - final String exceptionMessage = "Failure while importing artifacts"; - - // Test setup - mockBrew(); - mockTranslator(); - - doThrow(new CausewayFailure(exceptionMessage)).when(brewClient) - .importBuild(eq(NVR), same(KOJI_IMPORT), same(IMPORT_FILE_GENERATOR)); - - // Run import - importController.importBuild(getMavenBuild(), CALLBACK_TARGET, USERNAME, true); - - // Verify - verifyFailure(exceptionMessage); - } - - @Test - public void testImportBuildWhenTagDoesNotExistInBrew() throws Exception { - - // Test setup - mockBrew(); - doReturn(false).when(brewClient).tagsExists(TAG_PREFIX); - - // Run import - importController.importBuild(getMavenBuild(), CALLBACK_TARGET, USERNAME, true); - - // Verify - verifyFailure(tagsAreMissingInKoji(TAG_PREFIX, KOJI_URL).replace("\n", "\\n")); - } - - @Test - public void testGetNVR() throws IOException, CausewayException, ReflectiveOperationException { - Build build = getMavenBuild(); - BrewNVR nvr = importController.getNVR(build); - assertEquals(BUILD_NAME, nvr.getName()); - assertEquals(BUILD_VERSION, nvr.getVersion()); - - setFinalField(build, Build.class.getDeclaredField("buildVersion"), null); - nvr = importController.getNVR(build); - assertEquals(BUILD_NAME, nvr.getName()); - assertEquals(ARTIFACTS_VERSION, nvr.getVersion()); - } - - @Test - public void testAutomaticVersionNpm() throws IOException, CausewayException, ReflectiveOperationException { - Build build = getNpmBuild(); - setFinalField(build, Build.class.getDeclaredField("buildVersion"), null); - BrewNVR nvr = importController.getNVR(build); - assertEquals(BUILD_NPM_NAME, nvr.getName()); - assertEquals(ARTIFACT_NPM_VERSION, nvr.getVersion()); - } - - static void setFinalField(Object obj, Field field, Object newValue) throws ReflectiveOperationException { - field.setAccessible(true); - - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - - field.set(obj, newValue); - } - - private void verifySuccess(String log) { - verifySuccess(log, "11"); - } - - private void verifySuccess(String log, String id) { - String result = "{" + "\"id\":null," + "\"buildId\":\"61\"," + "\"status\":\"SUCCESS\"," + "\"message\":\"" - + log + "\"," + "\"brewBuildId\":" + id + "," + "\"brewBuildUrl\":\"" + KOJI_BUILD_URL + id + "\"" - + "}"; - - WireMock.verify( - postRequestedFor(urlEqualTo("/callback")).withRequestBody(WireMock.equalToJson(result, LENIENT))); - } - - private void verifyFailure(String message) { - String result = "{" + "\"id\":null," + "\"buildId\":\"61\"," + "\"status\":\"FAILED\"," + "\"message\":\"" - + message + "\"," + "\"brewBuildId\":null," + "\"brewBuildUrl\":null" + "}"; - - WireMock.verify( - postRequestedFor(urlEqualTo("/callback")).withRequestBody(WireMock.equalToJson(result, LENIENT))); - } - - private void verifyError(String message) { - String result = "{" + "\"id\":null," + "\"buildId\":\"61\"," + "\"status\":\"SYSTEM_ERROR\"," + "\"message\":\"" - + message + "\"," + "\"brewBuildId\":null," + "\"brewBuildUrl\":null" + "}"; - - WireMock.verify( - postRequestedFor(urlEqualTo("/callback")).withRequestBody(WireMock.equalToJson(result, LENIENT))); - } - - private String readResponseBodyFromTemplate(String name) throws IOException { - String folderName = getClass().getPackage().getName().replace(".", "/"); - try (InputStream inputStream = getContextClassLoader().getResourceAsStream(folderName + "/" + name)) { - return StringUtils.join(IOUtils.readLines(inputStream, Charset.forName("utf-8")), "\n"); - } - } - - private ClassLoader getContextClassLoader() { - return Thread.currentThread().getContextClassLoader(); - } -} diff --git a/core/src/test/java/org/jboss/pnc/causeway/ctl/PncImportControllerTest.java b/core/src/test/java/org/jboss/pnc/causeway/ctl/PncImportControllerTest.java deleted file mode 100644 index fe4e176c..00000000 --- a/core/src/test/java/org/jboss/pnc/causeway/ctl/PncImportControllerTest.java +++ /dev/null @@ -1,509 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.ctl; - -import com.codahale.metrics.Histogram; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.Timer; -import com.redhat.red.build.koji.model.json.KojiImport; - -import org.jboss.pnc.api.dto.Request; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.bpmclient.BPMClient; -import org.jboss.pnc.causeway.brewclient.BrewClient; -import org.jboss.pnc.causeway.brewclient.BuildTranslatorImpl; -import org.jboss.pnc.causeway.brewclient.StringLogImportFileGenerator; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.jboss.pnc.pncmetrics.MetricsConfiguration; -import org.jboss.pnc.causeway.pncclient.BuildArtifacts; -import org.jboss.pnc.causeway.pncclient.PncClient; -import org.jboss.pnc.causeway.rest.BrewBuild; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.jboss.pnc.causeway.rest.pnc.BuildImportResultRest; -import org.jboss.pnc.causeway.rest.pnc.BuildImportStatus; -import org.jboss.pnc.causeway.rest.pnc.MilestoneReleaseResultRest; -import org.jboss.pnc.causeway.rest.pnc.ReleaseStatus; -import org.jboss.pnc.dto.Build; -import org.jboss.pnc.dto.BuildConfigurationRevision; -import org.jboss.pnc.dto.Environment; -import org.jboss.pnc.dto.SCMRepository; -import org.jboss.pnc.dto.User; -import org.jboss.pnc.enums.ArtifactQuality; -import org.jboss.pnc.enums.BuildStatus; -import org.jboss.pnc.enums.BuildType; -import org.jboss.pnc.enums.SystemImageType; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import static org.jboss.pnc.constants.Attributes.BUILD_BREW_NAME; -import static org.jboss.pnc.constants.Attributes.BUILD_BREW_VERSION; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.same; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class PncImportControllerTest { - - private static final String USERNAME = "joe"; - private static final String TAG_PREFIX = "pnc-foo-0.1"; - private static final String BREW_BUILD_VERSION = "1.1.1"; - private static final String BREW_BUILD_NAME = "test:artifact"; - private static final String CALLBACK_ID = "callbackId"; - private static final URI CALLBACK_URL = URI.create("http://dummy.org"); - private static final List CALLBACK_HEADERS = Arrays - .asList(new Request.Header("header1", "value1"), new Request.Header("header2", "value2")); - private static final Request.Method CALLBACK_METHOD = Request.Method.PUT; - private static final Request CALLBACK_TARGET = new Request(CALLBACK_METHOD, CALLBACK_URL, CALLBACK_HEADERS); - - private static final BrewNVR NVR = new BrewNVR(BREW_BUILD_NAME, BREW_BUILD_VERSION, "1"); - - private static final StringLogImportFileGenerator IMPORT_FILE_GENERATOR = mock(StringLogImportFileGenerator.class); - private static final KojiImport KOJI_IMPORT = mock(KojiImport.class); - - private static final Random generator = new Random(); - @Mock - private PncClient pncClient; - @Mock - private BrewClient brewClient; - @Mock - private BPMClient bpmClient; - @Mock - private CausewayConfig causewayConfig; - - @Mock - public MetricsConfiguration metricsConfiguration; - - @Mock - public MetricRegistry metricRegistry; - - @Mock - public BuildTranslatorImpl translator; - - @InjectMocks - private PncImportControllerImpl importController; - - @Before - public void before() throws Exception { - MockitoAnnotations.initMocks(this); - when(metricsConfiguration.getMetricRegistry()).thenReturn(metricRegistry); - when(metricRegistry.meter(anyString())).thenReturn(mock(Meter.class)); - Timer timer = mock(Timer.class); - when(metricRegistry.timer(anyString())).thenReturn(timer); - when(timer.time()).thenReturn(mock(Timer.Context.class)); - Histogram histogram = mock(Histogram.class); - when(metricRegistry.register(anyString(), any(Histogram.class))).thenReturn(histogram); - when(metricRegistry.histogram(anyString())).thenReturn(histogram); - // importController = new PncImportControllerImpl(pncClient, brewClient, bpmClient, translator, causewayConfig); - } - - private void mockPNC(Integer milestoneId, BuildType buildType) throws CausewayException { - mockPNC(milestoneId, String.valueOf(generator.nextInt()), buildType); - } - - private void mockPNC(Integer milestoneId, String buildId, BuildType buildType) throws CausewayException { - Integer id = generator.nextInt(); - - Environment env = createEnvironment(buildType); - - // Mock BuildConfigurationAudited - BuildConfigurationRevision bcar = createBuildConfiguration(id, env, buildType); - - // Mock BuildRecord - Build buildRecord = createBuildRecord(buildId, bcar, BREW_BUILD_NAME, BREW_BUILD_VERSION); - - Collection buildRecords = new HashSet<>(); - buildRecords.add(buildRecord); - - // Mock BuildArtifacts - BuildArtifacts buildArtifacts = new BuildArtifacts(); - buildArtifacts.buildArtifacts.add(createArtifact(buildId)); - - doReturn(buildRecords).when(pncClient).findBuildsOfProductMilestone(eq(milestoneId)); - doReturn(TAG_PREFIX).when(pncClient).getTagForMilestone(eq(milestoneId)); - doReturn(buildArtifacts).when(pncClient).findBuildArtifacts(eq(buildId)); - doAnswer(i -> "Log of build " + i.getArguments()[0]).when(pncClient).getBuildLog(anyString()); - } - - private Environment createEnvironment(BuildType buildType) { - // Mock BuildEnvironment - Map attrs = new HashMap(); - attrs.put("OS", "Fedora25"); - switch (buildType) { - case MVN: - case GRADLE: - attrs.put("JDK", "1.8"); - break; - case NPM: - attrs.put("NPM", "5"); - } - - return Environment.builder().attributes(attrs).systemImageType(SystemImageType.DOCKER_IMAGE).build(); - } - - private BuildConfigurationRevision createBuildConfiguration(Integer id, Environment env, BuildType buildType) { - - SCMRepository scm = SCMRepository.builder().id(String.valueOf(1)).internalUrl("http://repo.url").build(); - - return BuildConfigurationRevision.builder() - .id(String.valueOf(id)) - .rev(1) - .scmRepository(scm) - .buildType(buildType) - .scmRevision("r21345") - .environment(env) - .build(); - } - - private void mockBrew() throws CausewayException { - doReturn(true).when(brewClient).tagsExists(eq(TAG_PREFIX)); - doNothing().when(brewClient).tagBuild(eq(TAG_PREFIX), any()); - } - - private void mockTranslator() throws CausewayException { - doReturn(KOJI_IMPORT).when(translator).translate(eq(NVR), any(), any(), any(), anyString(), any()); - doReturn(IMPORT_FILE_GENERATOR).when(translator).getImportFiles(any(), any(), anyString()); - doReturn("/path/to/sources.tar.gz").when(translator).getSourcesDeployPath(any(), any()); - } - - @Test - public void testImportProductMilestoneWithExistingBrewBuildIsImported() throws Exception { - Integer milestoneId = generator.nextInt(); - - // Test setup - mockPNC(milestoneId, BuildType.MVN); - mockBrew(); - - // Mock existing Brew build - doReturn(new BrewBuild(11, NVR)).when(brewClient).findBrewBuildOfNVR(eq(NVR)); - - // Run import - importController.importMilestone(milestoneId, CALLBACK_TARGET, CALLBACK_ID, USERNAME); - - // Verify - verifySuccess(); - } - - @Test - public void testImportProductMilestoneWithNonExistingBrewBuildIsImported() throws Exception { - Integer milestoneId = generator.nextInt(); - String buildId = String.valueOf(generator.nextInt()); - - // Test setup - mockPNC(milestoneId, buildId, BuildType.MVN); - mockBrew(); - mockTranslator(); - - // Mock Brew import - BuildImportResultRest buildImportResultRest = new BuildImportResultRest( - buildId, - 11, - "https://koji.myco.com/brew/buildinfo?buildID=11", - BuildImportStatus.SUCCESSFUL, - null); - doReturn(buildImportResultRest).when(brewClient) - .importBuild(eq(NVR), eq(buildId), same(KOJI_IMPORT), same(IMPORT_FILE_GENERATOR)); - - // Run import - importController.importMilestone(milestoneId, CALLBACK_TARGET, CALLBACK_ID, USERNAME); - - // Verify - verifySuccess(); - } - - @Test - public void testImportProductReleaseWithPncReleaseNotFound() throws Exception { - Integer milestoneId = generator.nextInt(); - - // Test setup - mockPNC(milestoneId, BuildType.MVN); - mockBrew(); - - // Mock exception from PNC client - final String exceptionMessage = "Test Exception"; - doThrow(new RuntimeException(exceptionMessage)).when(pncClient).findBuildsOfProductMilestone(eq(milestoneId)); - - // Run import - importController.importMilestone(milestoneId, CALLBACK_TARGET, CALLBACK_ID, USERNAME); - - // Verify - MilestoneReleaseResultRest result = verifyError(true); - // that user gets the exception message - assertNotNull(result.getErrorMessage()); - assertTrue("Error message doesn't contain expected data", result.getErrorMessage().contains(exceptionMessage)); - } - - @Test - public void testImportProductReleaseWithEmptyBuildConfigurations() throws Exception { - Integer milestoneId = generator.nextInt(); - - // Test setup - mockPNC(milestoneId, BuildType.MVN); - mockBrew(); - - // Mock no builds in milestone - Collection buildRecords = new HashSet<>(); - - doReturn(buildRecords).when(pncClient).findBuildsOfProductMilestone(eq(milestoneId)); - - // Run import - importController.importMilestone(milestoneId, CALLBACK_TARGET, CALLBACK_ID, USERNAME); - - // Verify - verifyFailure(); - // TODO verify the error message somehow? - } - - @Test - public void testImportProductReleaseWhereImportBuildThrowsException() throws Exception { - Integer milestoneId = generator.nextInt(); - String buildId = String.valueOf(generator.nextInt()); - String exceptionMessage = "Import build failed"; - - // Test setup - mockPNC(milestoneId, buildId, BuildType.MVN); - mockBrew(); - - // Mock exception from Brew Client - doThrow(new CausewayException(exceptionMessage)).when(brewClient).findBrewBuildOfNVR(eq(NVR)); - - // Run import - importController.importMilestone(milestoneId, CALLBACK_TARGET, CALLBACK_ID, USERNAME); - - // Verify - MilestoneReleaseResultRest result = verifyError(false); - // that the build is in the result with error - assertNotNull(result.getBuilds()); - assertEquals(1, result.getBuilds().size()); - BuildImportResultRest buildImportResultRest = result.getBuilds().get(0); - assertEquals(buildId, buildImportResultRest.getBuildRecordId()); - assertEquals(BuildImportStatus.ERROR, buildImportResultRest.getStatus()); - // that user gets the exception message - assertNotNull(buildImportResultRest.getErrorMessage()); - assertTrue( - "Build error message doesn't contain expected data", - buildImportResultRest.getErrorMessage().contains(exceptionMessage)); - } - - @Test - public void testImportProductReleaseWithArtifactImportErrors() throws Exception { - Integer milestoneId = generator.nextInt(); - String buildId = String.valueOf(generator.nextInt()); - // Test setup - mockPNC(milestoneId, buildId, BuildType.MVN); - mockBrew(); - mockTranslator(); - - BuildImportResultRest buildImportResultRest = new BuildImportResultRest( - buildId, - 11, - "https://koji.myco.com/brew/buildinfo?buildID=11", - BuildImportStatus.FAILED, - null); - - doReturn(buildImportResultRest).when(brewClient) - .importBuild(eq(NVR), eq(buildId), same(KOJI_IMPORT), same(IMPORT_FILE_GENERATOR)); - - // Run import - importController.importMilestone(milestoneId, CALLBACK_TARGET, CALLBACK_ID, USERNAME); - - // Verify - MilestoneReleaseResultRest result = verifyCallback(ReleaseStatus.IMPORT_ERROR, true); - // that the build is in the result with error - assertNotNull(result.getBuilds()); - assertEquals(1, result.getBuilds().size()); - BuildImportResultRest buildResult = result.getBuilds().get(0); - assertEquals(buildId, buildResult.getBuildRecordId()); - assertEquals(BuildImportStatus.FAILED, buildResult.getStatus()); - } - - @Test - public void testImportProductWhenTagDoesNotExistInBrew() throws Exception { - Integer milestoneId = generator.nextInt(); - - // Test setup - mockPNC(milestoneId, BuildType.MVN); - mockBrew(); - doReturn(false).when(brewClient).tagsExists(TAG_PREFIX); - - // Run import - importController.importMilestone(milestoneId, CALLBACK_TARGET, CALLBACK_ID, USERNAME); - - // Verify - MilestoneReleaseResultRest result = verifyFailure(); - assertNotNull(result.getErrorMessage()); - assertTrue(result.getErrorMessage().contains(TAG_PREFIX)); // We inform user about missing tag - } - - @Test - public void testGetNVR() throws IOException, CausewayException, ReflectiveOperationException { - Environment env = createEnvironment(BuildType.MVN); - BuildConfigurationRevision bcar = createBuildConfiguration(1, env, BuildType.MVN); - Build buildRecordRest = createBuildRecord("1", bcar, BREW_BUILD_NAME, BREW_BUILD_VERSION); - BuildArtifacts buildArtifacts = new BuildArtifacts(); - buildArtifacts.buildArtifacts.add(createArtifact("1")); - - BrewNVR nvr = importController.getNVR(buildRecordRest, buildArtifacts); - assertEquals(BREW_BUILD_NAME, nvr.getName()); - assertEquals(BREW_BUILD_VERSION, nvr.getVersion()); - - buildRecordRest = createBuildRecord("1", bcar, BREW_BUILD_NAME, null); - nvr = importController.getNVR(buildRecordRest, buildArtifacts); - assertEquals(BREW_BUILD_NAME, nvr.getName()); - assertEquals("1.1.1.redhat_1", nvr.getVersion()); - - buildRecordRest = createBuildRecord("1", bcar, null, null); - try { - importController.getNVR(buildRecordRest, buildArtifacts); - fail("Expected CausewayException to be thrown."); - } catch (CausewayException ex) { - // ok - } - } - - @Test - public void testAutomaticVersionNPM() throws CausewayException { - Environment env = createEnvironment(BuildType.NPM); - BuildConfigurationRevision bcar = createBuildConfiguration(1, env, BuildType.NPM); - Build build = createBuildRecord("1", bcar, BREW_BUILD_NAME, null); - BuildArtifacts buildArtifacts = new BuildArtifacts(); - buildArtifacts.buildArtifacts.add(createNpmArtifact("1")); - - BrewNVR nvr = importController.getNVR(build, buildArtifacts); - - assertEquals(BREW_BUILD_NAME, nvr.getName()); - assertEquals("0.1.18.redhat_1", nvr.getVersion()); - } - - private void verifySuccess() { - ArgumentCaptor resultArgument = ArgumentCaptor - .forClass(MilestoneReleaseResultRest.class); - verify(bpmClient).success(eq(CALLBACK_TARGET), eq(CALLBACK_ID), resultArgument.capture()); - MilestoneReleaseResultRest milestoneReleaseResultRest = resultArgument.getValue(); - assertEquals(ReleaseStatus.SUCCESS, milestoneReleaseResultRest.getReleaseStatus()); - assertTrue(milestoneReleaseResultRest.isSuccessful()); - assertNull(milestoneReleaseResultRest.getErrorMessage()); - } - - private MilestoneReleaseResultRest verifyFailure() { - return verifyCallback(ReleaseStatus.FAILURE, true); - } - - private MilestoneReleaseResultRest verifyError(boolean importError) { - return verifyCallback(ReleaseStatus.SET_UP_ERROR, !importError); - } - - private MilestoneReleaseResultRest verifyCallback(ReleaseStatus expectedStatus, boolean failure) { - ArgumentCaptor resultArgument = ArgumentCaptor - .forClass(MilestoneReleaseResultRest.class); - if (failure) { - verify(bpmClient).failure(eq(CALLBACK_TARGET), eq(CALLBACK_ID), resultArgument.capture()); - } else { - verify(bpmClient).error(eq(CALLBACK_TARGET), eq(CALLBACK_ID), resultArgument.capture()); - } - MilestoneReleaseResultRest milestoneReleaseResultRest = resultArgument.getValue(); - assertEquals(expectedStatus, milestoneReleaseResultRest.getReleaseStatus()); - assertFalse(milestoneReleaseResultRest.isSuccessful()); - return milestoneReleaseResultRest; - } - - private static BuildArtifacts.PncArtifact createArtifact(String buildId) { - return new BuildArtifacts.PncArtifact( - buildId, - "org.apache.geronimo.specs:geronimo-annotation_1.0_spec:pom:1.1.1.redhat-1", - "geronimo-annotation_1.0_spec-1.1.1.redhat-1.pom", - "bedf8af1b107b36c72f52009e6fcc768", - "http://ulozto.cz/api/hosted/" - + "build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1.pom", - 13245, - ArtifactQuality.NEW); - } - - private static BuildArtifacts.PncArtifact createNpmArtifact(String buildId) { - return new BuildArtifacts.PncArtifact( - buildId, - "async:0.1.18.redhat-1", - "async-0.1.18.redhat-1-wow-much-good.tar-gz", - "dsdfs1dfs6ads588few98ncv98465ew2", - "http://ulozto.cz/path/to/deploy/" + "async/async-0.1.18.redhat-1-wow-much-good.tar-gz", - 1337, - ArtifactQuality.NEW); - } - - private Build createBuildRecord( - String buildId, - BuildConfigurationRevision bcar, - String brewBuildName, - String brewBuildVersion) { - User user = User.builder().id(String.valueOf(1)).build(); - - Date submit = new Date(); - Date start = new Date(submit.getTime() + 1000L); - Date end = new Date(start.getTime() + 100000L); - Map attributes = new HashMap<>(); - if (brewBuildName != null) { - attributes.put(BUILD_BREW_NAME, brewBuildName); - } - if (brewBuildVersion != null) { - attributes.put(BUILD_BREW_VERSION, brewBuildVersion); - } - Build buildRecord = Build.builder() - .id(String.valueOf(buildId)) - .status(BuildStatus.SUCCESS) - .submitTime(submit.toInstant()) - .startTime(start.toInstant()) - .endTime(end.toInstant()) - .user(user) - .attributes(attributes) - .buildConfigRevision(bcar) - .build(); - return buildRecord; - } - - public static String createRandomString() { - return "" + generator.nextLong(); - } -} diff --git a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-records-61-1.json b/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-records-61-1.json deleted file mode 100644 index 0db3dd27..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-records-61-1.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "id": 61, - "submitTime": 1470309689231, - "startTime": 1470309691844, - "endTime": 1470309936668, - "status": "DONE", - "buildConfigurationId": 351, - "buildConfigurationName": "geronimo-annotation_1.0_spec-1.1.1", - "buildConfigurationRev": 404, - "userId": 17, - "username": "user", - "scmUrl": "http://ulozto.cz/productization-test3/geronimo-specs", - "scmRevision": "57ebfa20374d708e232fc8b45f37def055300260", - "scmTag": "repour-57ebfa20374d708e232fc8b45f37def055300260", - "buildEnvironmentId": null, - "attributes": {}, - "liveLogsUri": null, - "buildConfigSetRecordId": 56, - "buildContentId": "build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721", - "productMilestoneId": 3, - "executionRootName": "org.apache.geronimo.specs:geronimo-annotation_1.0_spec", - "executionRootVersion": "1.1.1", - "user": { - "id": 17, - "email": "user@redhat.com", - "firstName": "User", - "lastName": "Name", - "username": "nickname" - }, - "buildConfigurationAudited": { - "id": 351, - "rev": 404, - "idRev": { - "id": 351, - "rev": 404, - "fieldHandler": null - }, - "name": "geronimo-annotation_1.0_spec-1.1.1", - "description": null, - "buildScript": "mvn clean deploy", - "repositoryConfiguration": { - "internalURL": "git://internal.maven.repo.com/apache/geronimo-specs.git" - }, - "scmRevision": "geronimo-annotation_1.0_spec-1.1.1", - "scmMirrorRepoURL": null, - "scmMirrorRevision": null, - "creationTime": null, - "lastModificationTime": null, - "repositories": null, - "projectId": 23, - "environmentId": 1, - "project": { - "id": 23, - "name": "apache/geronimo-specs", - "description": null, - "issueTrackerUrl": null, - "projectUrl": "https://github.com/apache/geronimo-specs", - "configurationIds": [ - 327, - 328, - 329, - 345, - 331, - 348, - 332, - 333, - 334, - 350, - 351 - ], - "licenseId": null - }, - "environment": { - "id": 1, - "name": "Demo Environment 1", - "description": "Basic Java and Maven Environment", - "systemImageRepositoryUrl": "my.registry/newcastle", - "systemImageId": "12345678", - "attributes": { - "JDK": "1.7.0", - "OS": "Linux" - }, - "systemImageType": "DOCKER_IMAGE", - "imageRepositoryUrl": "my.registry/newcastle" - } - } -} \ No newline at end of file diff --git a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build.json b/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build.json deleted file mode 100644 index dfda107f..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "@buildType": "maven", - "buildName": "org.apache.geronimo.specs:geronimo-annotation_1.0_spec", - "buildVersion": "1.1.1", - "externalBuildSystem": "PNC", - "externalBuildID": 61, - "externalBuildURL": "/pnc-rest/rest/build-records/61", - "startTime": 1470309691844, - "endTime": 1470309936668, - "scmURL": "http://internal.maven.repo.com/productization-test3/geronimo-specs", - "scmRevision": "repour-57ebfa20374d708e232fc8b45f37def055300260", - "buildRoot": { - "container": "DOCKER_IMAGE", - "containerArchitecture": "x86_64", - "host": "rhel", - "hostArchitecture": "x86_64", - "tools": { - "JDK": "1.8.0", - "MAVEN": "3.3.9", - "OS": "Linux" - } - }, - "logs": [ - { - "filename": "repour.log", - "deployPath": "/pnc-rest/rest/build-records/62/repour-log", - "size": 10, - "md5": "bedf8af1b107b36c72f52009e6fcc768" - }, - { - "filename": "build.log", - "deployPath": "/pnc-rest/rest/build-records/62/log", - "size": 10, - "md5": "bedf8af1b107b36c72f52009e6fcc768" - } - ], - "sourcesURL": "http://internal.maven.repo.com/productization-test3/geronimo-specs.tar.gz", - "dependencies": [ - { - "filename": "maven-project-2.0.6.pom", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - }, - { - "filename": "maven-shared-io-1.1.jar", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - }, - { - "filename": "xml-apis-1.0.b2.jar", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - } - ], - "builtArtifacts": [ - { - "@artifactType": "maven", - "id": 2369, - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1.pom", - "architecture": "noarch", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "repositoryPath": "api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721", - "artifactPath": "/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1.pom", - "size": 13245, - "groupId": "org.apache.geronimo.specs", - "artifactId": "geronimo-annotation_1.0_spec", - "version": "1.1.1.redhat-1" - }, - { - "@artifactType": "maven", - "id": 2369, - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1.jar", - "architecture": "noarch", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "repositoryPath": "/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721", - "artifactPath": "/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1.jar", - "size": 13245, - "groupId": "org.apache.geronimo.specs", - "artifactId": "geronimo-annotation_1.0_spec", - "version": "1.1.1.redhat-1" - }, - { - "@artifactType": "maven", - "id": 2369, - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1-project-sources.jar", - "architecture": "noarch", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "repositoryPath": "/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721", - "artifactPath": "/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1-project-sources.jar", - "size": 13245, - "groupId": "org.apache.geronimo.specs", - "artifactId": "geronimo-annotation_1.0_spec", - "version": "1.1.1.redhat-1" - } - ], - "tagPrefix": "pnc-foo-0.1", - "groupId": "org.apache.geronimo.specs", - "artifactId": "geronimo-annotation_1.0_spec", - "version": "1.1.1" -} \ No newline at end of file diff --git a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/cg-import-schema.json b/core/src/test/resources/org/jboss/pnc/causeway/brewclient/cg-import-schema.json deleted file mode 100644 index 64a94c9e..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/cg-import-schema.json +++ /dev/null @@ -1,234 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$description": "Koji content generator metadata", - "type": "object", - "definitions": { - "components": { - "type": "array", - "items": { - "type": "object", - "oneOf": [ - { - "properties": { - "type": {"const": "rpm"}, - "name": {"type": "string"}, - "version": {"type": "string"}, - "release": {"type": "string"}, - "epoch": { - "oneOf": [ - {"type": "integer"}, - {"const": null} - ] - }, - "arch": {"type": "string"}, - "sigmd5": {"type": "string"}, - "signature": { - "anyOf": [ - {"type": "string"}, - {"const": null} - ] - } - }, - "additionalProperties": false - }, - { - "properties": { - "type": {"const": "file"}, - "filename": {"type": "string"}, - "filesize": { - "type": "integer", - "minimum": 0 - }, - "checksum": {"type": "string"}, - "checksum_type": {"type": "string"} - }, - "additionalProperties": false - }, - { - "properties": { - "type": {"const": "kojifile"}, - "filename": {"type": "string"}, - "filesize": { - "type": "integer", - "minimum": 0 - }, - "checksum": {"type": "string"}, - "checksum_type": {"type": "string"}, - "nvr": {"type": "string"}, - "archive_id": {"type": "integer"} - }, - "additionalProperties": false - } - ] - } - } - }, - "properties": { - "metadata_version": { - "type": "integer", - "const": 0 - }, - "build": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "version": {"type": "string"}, - "release": {"type": "string"}, - "source": {"type": "string"}, - "start_time": { - "type": "integer", - "minimum": 0 - }, - "end_time": { - "type": "integer", - "minimum": 0 - }, - "owner": { - "type": "string", - "description": "optional user name" - }, - "extra": { - "type": "object", - "oneOf": [ - { - "properties": {"typeinfo": {"type": "object"}}, - "required": ["typeinfo"], - "additionalProperties": false - }, - { - "properties": {"maven": {"type": "object"}}, - "required": ["maven"], - "additionalProperties": false - }, - { - "properties": {"win": {"type": "object"}}, - "required": ["win"], - "additionalProperties": false - }, - { - "properties": {"image": {"type": "object"}}, - "required": ["image"], - "additionalProperties": false - }, - { - "properties": {}, - "additionalProperties": false - } - ] - } - }, - "required": [ - "name", - "version", - "release", - "source", - "start_time", - "end_time" - ] - }, - "buildroots": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "minimum": 1 - }, - "host": { - "type": "object", - "properties": { - "os": {"type": "string"}, - "arch": {"type": "string"} - }, - "required": ["os", "arch"], - "additionalProperties": false - }, - "content_generator": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "version": {"type": "string"} - }, - "required": ["name", "version"], - "additionalProperties": false - }, - "container": { - "type": "object", - "properties": { - "type": {"type": "string"}, - "arch": {"type": "string"} - }, - "required": ["type", "arch"], - "additionalProperties": false - }, - "tools": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": {"type": "string"}, - "version": {"type": "string"} - }, - "required": ["name", "version"], - "additionalProperties": false - } - }, - "components": { "$ref": "#/definitions/components" }, - "extra": { - "type": "object", - "properties": { - "osbs": { - "type": "object", - "description": "OSBS has predefined extra", - "properties": { - "build_id": {"type": "integer"}, - "builder_image_id": {"type": "integer"} - }, - "required": ["build_id", "builder_image_id"] - } - } - }, - "additionalProperties": false - }, - "required": [ - "id", - "host", - "content_generator", - "container", - "tools", - "components", - "extra" - ] - } - }, - "output": { - "type": "array", - "items": { - "type": "object", - "properties": { - "buildroot_id": {"type": "integer"}, - "filename": {"type": "string"}, - "filesize": {"type": "integer"}, - "arch": {"type": "string"}, - "checksum": {"type": "string"}, - "checksum_type": {"type": "string"}, - "type": {"type": "string"}, - "components": { "$ref": "#/definitions/components" }, - "extra": {"type": "object"} - }, - "required": [ - "buildroot_id", - "filename", - "filesize", - "arch", - "checksum", - "checksum_type", - "type" - ], - "additionalProperties": false - } - }, - "additionalProperties": false - } -} \ No newline at end of file diff --git a/core/src/test/resources/org/jboss/pnc/causeway/ctl/build.json b/core/src/test/resources/org/jboss/pnc/causeway/ctl/build.json deleted file mode 100644 index cf4d2370..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/ctl/build.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "@buildType": "maven", - "buildName": "org.apache.geronimo.specs:geronimo-annotation_1.0_spec", - "buildVersion": "1.1.1", - "externalBuildSystem": "PNC", - "externalBuildID": 61, - "externalBuildURL": "/pnc-rest/rest/build-records/61", - "startTime": 1470309691844, - "endTime": 1470309936668, - "scmURL": "http://internal.maven.repo.com/productization-test3/geronimo-specs", - "scmRevision": "repour-57ebfa20374d708e232fc8b45f37def055300260", - "buildRoot": { - "container": "DOCKER_IMAGE", - "containerArchitecture": "x86_64", - "host": "rhel", - "hostArchitecture": "x86_64", - "tools": { - "JDK": "1.8.0", - "MAVEN": "3.3.9", - "OS": "Linux" - } - }, - "logs": [ - { - "filename": "repour.log", - "deployPath": "/pnc-rest/rest/build-records/62/repour-log", - "size": 10, - "md5": "bedf8af1b107b36c72f52009e6fcc768" - }, - { - "filename": "build.log", - "deployPath": "/pnc-rest/rest/build-records/62/log", - "size": 10, - "md5": "bedf8af1b107b36c72f52009e6fcc768" - } - ], - "sourcesURL": "http://internal.maven.repo.com/productization-test3/geronimo-specs.tar.gz", - "dependencies": [ - { - "filename": "maven-project-2.0.6.pom", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - }, - { - "filename": "maven-shared-io-1.1.jar", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - }, - { - "filename": "xml-apis-1.0.b2.jar", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - } - ], - "builtArtifacts": [ - { - "@artifactType": "maven", - "id": 2369, - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1.pom", - "architecture": "noarch", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "repositoryPath": "api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721", - "artifactPath": "/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1.pom", - "size": 13245, - "groupId": "org.apache.geronimo.specs", - "artifactId": "geronimo-annotation_1.0_spec", - "version": "1.1.1.redhat-1" - }, - { - "@artifactType": "maven", - "id": 2369, - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1.jar", - "architecture": "noarch", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "repositoryPath": "/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721", - "artifactPath": "/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1.jar", - "size": 13245, - "groupId": "org.apache.geronimo.specs", - "artifactId": "geronimo-annotation_1.0_spec", - "version": "1.1.1.redhat-1" - }, - { - "@artifactType": "maven", - "id": 2369, - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1-project-sources.jar", - "architecture": "noarch", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "repositoryPath": "/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721", - "artifactPath": "/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1-project-sources.jar", - "size": 13245, - "groupId": "org.apache.geronimo.specs", - "artifactId": "geronimo-annotation_1.0_spec", - "version": "1.1.1.redhat-1" - } - ], - "tagPrefix": "pnc-foo-0.1", - "groupId": "org.apache.geronimo.specs", - "artifactId": "geronimo-annotation_1.0_spec", - "version": "1.1.1" -} diff --git a/core/src/test/resources/org/jboss/pnc/causeway/ctl/npmbuild.json b/core/src/test/resources/org/jboss/pnc/causeway/ctl/npmbuild.json deleted file mode 100644 index b53632c4..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/ctl/npmbuild.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "@buildType": "npm", - "buildName": "npm_async_3.1.0-npm", - "buildVersion": "3.1.0", - "externalBuildSystem": "PNC", - "externalBuildID": 99, - "externalBuildURL": "/pnc-rest/rest/build-records/99", - "startTime": 1470309691844, - "endTime": 1470309996668, - "scmURL": "http://ulozto.cz/productization-test3/async/3.1.0", - "scmRevision": "repour-tag-version-3.1.0", - "buildRoot": { - "container": "DOCKER_IMAGE", - "containerArchitecture": "x86_64", - "host": "rhel", - "hostArchitecture": "x86_64", - "tools": { - "JDK": "1.8.0", - "MAVEN": "3.5.4", - "NPM": "5", - "OS": "Linux" - } - }, - "logs": [ - { - "filename": "repour.log", - "deployPath": "/pnc-rest/rest/build-records/99/repour-log", - "size": 10, - "md5": "bedf8af1b107b36c72f52009e6fcc768" - }, - { - "filename": "build.log", - "deployPath": "/pnc-rest/rest/build-records/62/log", - "size": 10, - "md5": "bedf8af1b107b36c72f52009e6fcc768" - } - ], - "sourcesURL": "http://internal.maven.repo.com/productization-test3/geronimo-specs.tar.gz", - "dependencies": [ - { - "filename": "file.tar.gz", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - }, - { - "filename": "file2.tar.gz", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - }, - { - "filename": "file3.tar.gz", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "size": 13245 - } - ], - "builtArtifacts": [ - { - "@artifactType": "npm", - "id": 5645, - "filename": "npm-archive.tar.gz", - "architecture": "noarch", - "md5": "bedf8af1b107b36c72f52009e6fcc768", - "repositoryPath": "api/npm", - "artifactPath": "/async/3.1.0.redhat-1/async-archive.tar.gz", - "size": 13245, - "name": "async", - "version": "3.1.0.redhat-1" - } - ], - "tagPrefix": "pnc-foo-0.1", - "name": "async", - "version": "3.1.0" -} \ No newline at end of file diff --git a/core/src/test/resources/org/jboss/pnc/causeway/pncclient/build-records-61-built-artifacts-1.json b/core/src/test/resources/org/jboss/pnc/causeway/pncclient/build-records-61-built-artifacts-1.json deleted file mode 100644 index 3959cc35..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/pncclient/build-records-61-built-artifacts-1.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "pageIndex": 0, - "pageSize": 1000, - "totalPages": 1, - "content": [ - { - "id": 2369, - "identifier": "org.apache.geronimo.specs:geronimo-annotation_1.0_spec:pom:1.1.1.redhat-1", - "artifactQuality": "NEW", - "repoType": "MAVEN", - "checksum": "bedf8af1b107b36c72f52009e6fcc768", - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1.pom", - "deployUrl": "http://maven.repo.com/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1.pom", - "buildRecordIds": [ - 61 - ], - "dependantBuildRecordIds": [], - "importDate": null, - "originUrl": null, - "built": true, - "imported": false, - "status": "BINARY_BUILT" - }, - { - "id": 2370, - "identifier": "org.apache.geronimo.specs:geronimo-annotation_1.0_spec:jar:1.1.1.redhat-1", - "artifactQuality": "NEW", - "repoType": "MAVEN", - "checksum": "445fd69dce3c1cb8b0945d0b02aff79c", - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1.jar", - "deployUrl": "http://maven.repo.com/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1.jar", - "buildRecordIds": [ - 61 - ], - "dependantBuildRecordIds": [], - "importDate": null, - "originUrl": null, - "built": true, - "imported": false, - "status": "BINARY_BUILT" - }, - { - "id": 2371, - "identifier": "org.apache.geronimo.specs:geronimo-annotation_1.0_spec:tar.gz:1.1.1.redhat-1:project-sources", - "artifactQuality": "NEW", - "repoType": "MAVEN", - "checksum": "e58845340c278024bd1d6165caf109d7", - "filename": "geronimo-annotation_1.0_spec-1.1.1.redhat-1-project-sources.tar.gz", - "deployUrl": "http://maven.repo.com/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721/org/apache/geronimo/specs/geronimo-annotation_1.0_spec/1.1.1.redhat-1/geronimo-annotation_1.0_spec-1.1.1.redhat-1-project-sources.tar.gz", - "buildRecordIds": [ - 61 - ], - "dependantBuildRecordIds": [], - "importDate": null, - "originUrl": null, - "built": true, - "imported": false, - "status": "BINARY_BUILT" - } - ] -} \ No newline at end of file diff --git a/core/src/test/resources/org/jboss/pnc/causeway/pncclient/build-records-61-dependency-artifacts-1.json b/core/src/test/resources/org/jboss/pnc/causeway/pncclient/build-records-61-dependency-artifacts-1.json deleted file mode 100644 index 88e46c6e..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/pncclient/build-records-61-dependency-artifacts-1.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "pageIndex": 0, - "pageSize": 1000, - "totalPages": 206, - "content": [ - { - "id": 7, - "identifier": "org.apache.maven:maven-project:pom:2.0.6", - "artifactQuality": "NEW", - "repoType": "MAVEN", - "checksum": "a4f25c31860ab157e6a28f71950914e8", - "filename": "maven-project-2.0.6.pom", - "deployUrl": "http://localhost:8089/api/remote/EAP7_MEAD/org/apache/maven/maven-project/2.0.6/maven-project-2.0.6.pom", - "buildRecordIds": [], - "dependantBuildRecordIds": [ - 192, - 193, - 194, - 195, - 196, - 197, - 133, - 134, - 198, - 135, - 199, - 136, - 137, - 202, - 138, - 144, - 156, - 222, - 223, - 159, - 224, - 225, - 226, - 227, - 229, - 230, - 231, - 168, - 232, - 169, - 233, - 234, - 170, - 61, - 172, - 112, - 184, - 185, - 187, - 189, - 190 - ], - "importDate": 1468310993023, - "originUrl": "http://ulozto.cz/brewroot/repos/jb-eap-7.0-rhel-7-maven-build/latest/maven/org/apache/maven/maven-project/2.0.6/maven-project-2.0.6.pom", - "built": false, - "imported": true, - "status": "BINARY_IMPORTED" - }, - { - "id": 9, - "identifier": "org.apache.maven.shared:maven-shared-io:jar:1.1", - "artifactQuality": "NEW", - "repoType": "MAVEN", - "checksum": "fe668f50b2c0edc8707609f792ca4036", - "filename": "maven-shared-io-1.1.jar", - "deployUrl": "http://localhost:8089/api/remote/EAP7_MEAD/org/apache/maven/shared/maven-shared-io/1.1/maven-shared-io-1.1.jar", - "buildRecordIds": [], - "dependantBuildRecordIds": [ - 192, - 193, - 194, - 195, - 196, - 197, - 133, - 134, - 198, - 135, - 199, - 136, - 137, - 202, - 138, - 144, - 156, - 222, - 223, - 159, - 224, - 225, - 226, - 227, - 229, - 230, - 231, - 168, - 232, - 169, - 233, - 234, - 170, - 61, - 172, - 112, - 184, - 185, - 187, - 189, - 190 - ], - "importDate": 1468310992928, - "originUrl": "http://ulozto.cz/brewroot/repos/jb-eap-7.0-rhel-7-maven-build/latest/maven/org/apache/maven/shared/maven-shared-io/1.1/maven-shared-io-1.1.jar", - "built": false, - "imported": true, - "status": "BINARY_IMPORTED" - }, - { - "id": 10, - "identifier": "xml-apis:xml-apis:jar:1.0.b2", - "artifactQuality": "NEW", - "repoType": "MAVEN", - "checksum": "458715c0f7646a56b1c6ad3138098beb", - "filename": "xml-apis-1.0.b2.jar", - "deployUrl": "http://localhost:8089/api/remote/EAP7_MEAD/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2.jar", - "buildRecordIds": [], - "dependantBuildRecordIds": [ - 192, - 193, - 194, - 195, - 196, - 197, - 133, - 134, - 198, - 135, - 199, - 136, - 137, - 202, - 138, - 144, - 156, - 222, - 223, - 159, - 224, - 225, - 226, - 227, - 229, - 230, - 231, - 168, - 232, - 169, - 233, - 234, - 170, - 61, - 172, - 112, - 184, - 185, - 187, - 189, - 190 - ], - "importDate": 1468310992553, - "originUrl": "http://ulozto.cz/brewroot/repos/jb-eap-7.0-rhel-7-maven-build/latest/maven/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2.jar", - "built": false, - "imported": true, - "status": "BINARY_IMPORTED" - } - ] -} \ No newline at end of file diff --git a/core/src/test/resources/org/jboss/pnc/causeway/pncclient/product-release-distributed-build-records-ids-1.json b/core/src/test/resources/org/jboss/pnc/causeway/pncclient/product-release-distributed-build-records-ids-1.json deleted file mode 100644 index ca9951f4..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/pncclient/product-release-distributed-build-records-ids-1.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "pageIndex": 0, - "pageSize": 50, - "totalPages": 1, - "content": [ - { - "id": 1, - "submitTime": 1460570783943, - "startTime": 1460570963945, - "endTime": 1460571263945, - "status": "DONE", - "buildConfigurationId": 1, - "buildConfigurationName": "pnc-1.0.0.DR1", - "buildConfigurationRev": 1, - "userId": 1, - "username": "demo-user", - "scmRepoURL": null, - "scmRevision": null, - "buildEnvironmentId": null, - "liveLogsUri": null, - "buildConfigSetRecordId": null, - "buildContentId": null, - "productMilestoneId": 1, - "user": { - "id": 1, - "email": "demo-user@pnc.com", - "firstName": "Demo First Name", - "lastName": "Demo Last Name", - "username": "demo-user" - }, - "buildConfigurationAudited": { - "id": 1, - "rev": 1, - "idRev": { - "id": 1, - "rev": 1, - "fieldHandler": null - }, - "name": "pnc-1.0.0.DR1", - "description": "Test build config for project newcastle", - "buildScript": "mvn clean deploy -DskipTests=true", - "scmRepoURL": "https://github.com/project-ncl/pnc.git", - "scmRevision": "*/v0.2", - "scmMirrorRepoURL": null, - "scmMirrorRevision": null, - "creationTime": null, - "lastModificationTime": null, - "repositories": null, - "projectId": 1, - "environmentId": 1, - "project": { - "id": 1, - "name": "Project Newcastle Demo Project 1", - "description": "Example Project for Newcastle Demo", - "issueTrackerUrl": null, - "projectUrl": "https://github.com/project-ncl/pnc", - "configurationIds": [ - 1 - ], - "licenseId": null - }, - "environment": { - "id": 1, - "name": "Demo Environment 1", - "description": "Basic Java and Maven Environment", - "systemImageRepositoryUrl": "my.registry/newcastle", - "attributes": { - "JDK": "1.7.0", - "OS": "Linux" - }, - "systemImageType": "DOCKER_IMAGE", - "systemImageId": "12345678", - "imageRepositoryUrl": "my.registry/newcastle" - } - } - }, - { - "id": 2, - "submitTime": 1460570784087, - "startTime": 1460570964087, - "endTime": 1460571264087, - "status": "DONE", - "buildConfigurationId": 2, - "buildConfigurationName": "jboss-modules-1.5.0", - "buildConfigurationRev": 1, - "userId": 1, - "username": "demo-user", - "scmRepoURL": null, - "scmRevision": null, - "buildEnvironmentId": null, - "liveLogsUri": null, - "buildConfigSetRecordId": null, - "buildContentId": null, - "productMilestoneId": null, - "user": { - "id": 1, - "email": "demo-user@pnc.com", - "firstName": "Demo First Name", - "lastName": "Demo Last Name", - "username": "demo-user" - }, - "buildConfigurationAudited": { - "id": 2, - "rev": 1, - "idRev": { - "id": 2, - "rev": 1, - "fieldHandler": null - }, - "name": "jboss-modules-1.5.0", - "description": "Test config for JBoss modules build master branch.", - "buildScript": "mvn clean deploy -DskipTests=true", - "scmRepoURL": "https://github.com/jboss-modules/jboss-modules.git", - "scmRevision": "9e7115771a791feaa5be23b1255416197f2cda38", - "scmMirrorRepoURL": null, - "scmMirrorRevision": null, - "creationTime": null, - "lastModificationTime": null, - "repositories": null, - "projectId": 2, - "environmentId": 1, - "project": { - "id": 2, - "name": "JBoss Modules", - "description": "JBoss Modules Project", - "issueTrackerUrl": "https://issues.jboss.org/browse/MODULES", - "projectUrl": "https://github.com/jboss-modules/jboss-modules", - "configurationIds": [ - 2, - 6 - ], - "licenseId": null - }, - "environment": { - "id": 1, - "name": "Demo Environment 1", - "description": "Basic Java and Maven Environment", - "systemImageRepositoryUrl": "my.registry/newcastle", - "attributes": { - "JDK": "1.7.0", - "OS": "Linux" - }, - "systemImageType": "DOCKER_IMAGE", - "systemImageId": "12345678", - "imageRepositoryUrl": "my.registry/newcastle" - } - } - } - ] -} diff --git a/core/src/test/resources/org/jboss/pnc/causeway/pncclient/product-releases-1.json b/core/src/test/resources/org/jboss/pnc/causeway/pncclient/product-releases-1.json deleted file mode 100644 index 5991fdb4..00000000 --- a/core/src/test/resources/org/jboss/pnc/causeway/pncclient/product-releases-1.json +++ /dev/null @@ -1 +0,0 @@ -{"content":{"id":1,"version":"1.0.0.GA","releaseDate":null,"downloadUrl":null,"issueTrackerUrl":null,"productVersionId":1,"productMilestoneId":1,"supportLevel":"EARLYACCESS"}} \ No newline at end of file diff --git a/eclipse-codeStyle.xml b/eclipse-codeStyle.xml index 7f1af4ce..900073c5 100644 --- a/eclipse-codeStyle.xml +++ b/eclipse-codeStyle.xml @@ -27,7 +27,7 @@ - + @@ -36,7 +36,6 @@ - diff --git a/pom.xml b/pom.xml index 59b78c27..5056dac1 100644 --- a/pom.xml +++ b/pom.xml @@ -1,432 +1,436 @@ + - - 4.0.0 - - - org.jboss - jboss-parent - 39 - - + + 4.0.0 + org.jboss.pnc.causeway + causeway + 4.0.0-SNAPSHOT - org.jboss.pnc.causeway - causeway - 3.0.3-SNAPSHOT - pom + Causeway + PNC-to-Koji Bridge + http://github.com/project-ncl/causeway + 2015 - Causeway PNCL-to-Koji Bridge - 2015 - http://github.com/project-ncl/causeway + + Red Hat, Inc. + http://www.redhat.com/ + - - - Apache License, Version 2.0 - repo - http://www.apache.org/licenses/LICENSE-2.0.html - - + + + Apache License, Version 2.0 + repo + http://www.apache.org/licenses/LICENSE-2.0.html + + - - scm:git:http://github.com/project-ncl/causeway.git - scm:git:git@github.com:project-ncl/causeway.git - http://github.com/project-ncl/causeway - HEAD - + + scm:git:http://github.com/project-ncl/causeway.git + scm:git:git@github.com:project-ncl/causeway.git + http://github.com/project-ncl/causeway + HEAD + - - Red Hat, Inc. - jbrazdil@redhat.com - 11 - 0.8 - 1.10.19 - 2.20 - 1.1.12 - 0.10.2 - 1.1.4 - 2.7.6 - 3.0.4 - - 1.22.0 - 1.3.0 - 3.0.1 - 1.78.1 - 1.13 - - + + + RedHat + http://www.redhat.com + + - - core - rest - web - application - + + 3.13.0 + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.12.0 + true + 3.2.5 + 1.1.0 + 1.69 + + - - - mrrc-ga - https://maven.repository.redhat.com/ga - - true - - - - jboss-snapshots - https://repository.jboss.org/nexus/content/repositories/snapshots - - true - - - false - - + + + mrrc-ga + https://maven.repository.redhat.com/ga + + true + + - - Nexus Staging - https://oss.sonatype.org/content/groups/staging - - false - - - + + jboss-snapshots + https://repository.jboss.org/nexus/content/repositories/snapshots + + true + + + false + + - - - - - org.jboss.bom - jboss-eap-jakartaee8-with-tools - 7.4.5.GA - pom - import - - - org.jboss.bom - eap-runtime-artifacts - 7.4.16.GA - pom - import - + + Nexus Staging + https://oss.sonatype.org/content/groups/staging + + false + + + - - - org.projectlombok - lombok - 1.18.22 - provided - - - org.keycloak - keycloak-core - 18.0.9.redhat-00001 - provided - + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + org.commonjava.atlas + atlas-identities + ${atlas.version} + + + org.commonjava.atlas + atlas-npm-identities + ${atlas.version} + + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + + + org.bouncycastle + bcpkix-jdk15on + ${bouncycastle.version} + + + - - - org.jboss.pnc.causeway - causeway-core - ejb - ${project.version} - - - org.jboss.pnc.causeway - causeway-rest - ejb - ${project.version} - - - org.jboss.pnc.causeway - causeway-web - war - ${project.version} - + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + - - - org.jboss.pnc - rest-client - ${pncVersion} - - - com.fasterxml.jackson.core - * - - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - org.jboss.resteasy - resteasy-jackson2-provider - - - org.apache.httpcomponents - * - - - - - org.jboss.pnc.metrics - pncmetrics - ${pncmetrics.version} - - - org.jboss.pnc - pnc-api - ${pncApiVersion} - - - org.jboss.pnc - pnc-common - ${version.pnc-common} - - - - - com.github.zafarkhaja - java-semver - ${semverVersion} - - - org.commonjava.util - configuration-api - ${configVersion} - - - org.commonjava.util - configuration-dotconf - ${configVersion} - - - org.commonjava.atlas - atlas-npm-identities - ${atlasVersion} - - - org.commonjava.rwx - rwx-bindings - 1.1 - - - org.apache.commons - commons-compress - 1.21 - - - com.redhat.red.build - kojiji - ${kojijiVersion} - - - com.fasterxml.jackson.core - * - - - org.apache.httpcomponents - * - - - org.commonjava.util - jhttpc - - - - - org.commonjava.util - jhttpc - ${version.org.commonjava.util.jhttpc} - - - org.bouncycastle - bcpkix-jdk18on - - - org.bouncycastle - bcprov-jdk18on - - - org.bouncycastle - bcutil-jdk18on - - - org.apache.httpcomponents - * - - - - - - org.bouncycastle - bcprov-jdk18on - ${version.org.bouncycastle} - - - org.bouncycastle - bcpkix-jdk18on - ${version.org.bouncycastle} - - - org.bouncycastle - bcutil-jdk18on - ${version.org.bouncycastle} - - + - - - - io.opentelemetry.instrumentation - opentelemetry-instrumentation-annotations - ${version.io.opentelemetry.instrumentation} - - - io.opentelemetry - opentelemetry-api - - - + + com.redhat.red.build + kojiji + 2.21-SNAPSHOT + + + org.jboss.pnc + rest-client-jakarta + 3.0.1-SNAPSHOT + + + org.apache.commons + commons-compress + 1.26.2 + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-rest + + + io.quarkus + quarkus-scheduler + + + io.quarkus + quarkus-oidc-client + + + io.quarkus + quarkus-micrometer-registry-prometheus + + + io.quarkus + quarkus-micrometer + + + io.quarkiverse.wiremock + quarkus-wiremock + 1.3.3 + provided + + + io.quarkus + quarkus-smallrye-openapi + + + io.quarkus + quarkus-rest-jackson + + + io.quarkus + quarkus-hibernate-validator + + + io.quarkiverse.wiremock + quarkus-wiremock-test + 1.3.3 + test + + + io.quarkus + quarkus-config-yaml + + + + io.quarkus + quarkus-junit5 + test + + + io.quarkus + quarkus-junit5-mockito + test + + + org.assertj + assertj-core + 3.26.3 + test + + + org.jboss.pnc + pnc-api + 2.5.2-SNAPSHOT + jakarta + + + org.projectlombok + lombok + 1.18.32 + + + org.jboss.pnc + pnc-common + 3.0.2-SNAPSHOT + jakarta + + + org.jboss.pnc + pnc-api + + + + - - com.redhat.resilience.otel - opentelemetry-ext-cli-java - ${version.com.redhat.resilience.otel} - + + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + + causeway + + true + + true + + + + build + generate-code + generate-code-tests + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + + + ${project.build.directory}/${project.build.finalName}-runner + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + net.revelc.code.formatter + formatter-maven-plugin + 2.23.0 + + eclipse-codeStyle.xml + + + + java-format + + format + + + + + + com.mycila + license-maven-plugin + 4.5 + + + +

LICENSE-header.txt
+ + LICENSE.txt + eclipse-codeStyle.xml + + + + + + + org.apache.maven.plugins + maven-release-plugin + + @{project.version}${tagSuffix} + true + false + release + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + deploy + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + ossrh + https://oss.sonatype.org/ + false + + + + pl.project13.maven + git-commit-id-plugin + 4.9.10 + + + + revision + + + - - org.keycloak - keycloak-authz-client - 19.0.1 - provided - - - org.apache.httpcomponents - 4.5.13.redhat-00001 - httpclient - provided - + + + ${project.basedir}/.git - - - org.mockito - mockito-all - ${mockitoVersion} - test - - - org.assertj - assertj-core - 3.25.3 - test - - - com.github.tomakehurst - wiremock - 1.58 - test - + + true - - + + + + com.google.code.maven-replacer-plugin + maven-replacer-plugin + 1.4.1 + + + process-sources + + replace + + + + + src/main/templates/org/jboss/pnc/causeway/constants/BuildInformationConstants.java + src/main/java/org/jboss/pnc/causeway/constants/BuildInformationConstants.java + + + @version@ + ${project.version} + + + @commit-id@ + ${git.commit.id.abbrev} + + + @build-time@ + ${maven.build.timestamp} + + + + + + - - - org.slf4j - slf4j-api - provided - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - - integration-test - verify - - - - - - **/*IT.java - - - - - net.revelc.code.formatter - formatter-maven-plugin - 2.11.0 - - ../eclipse-codeStyle.xml - - - - java-format - - format - - - - - - com.mycila - license-maven-plugin - - - none - - - - - org.apache.maven.plugins - maven-release-plugin - - @{project.version}${tagSuffix} - true - release - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.13 - true - - ossrh - https://oss.sonatype.org/ - false - - - - - + + + native + + + native + + + + false + true + + release @@ -465,7 +469,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.1.0 + 3.2.1 sign-artifacts diff --git a/release.sh b/release.sh deleted file mode 100755 index dbf78524..00000000 --- a/release.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash - -set -e - -repository="project-ncl/causeway" -tagprefix="" -testparams="" -releaseparams="" - -####### - - -if [ $# -lt 1 ]; then - echo "You have to enter new version" >&2 - exit 1 -fi - -version=$1 -if ! echo $version | grep -q "^[1-9][0-9]*\.[0-9]\+\.[0-9]\+$"; then - echo "The version has to be in format X.Y.Z" - exit 1 -fi - -changes=`git status --porcelain | grep -v "^??" | wc -l` -if [ $changes -gt 0 ]; then - echo "You have uncommited changes." - exit 1 -fi - -upstream=`git remote -v | grep "$repository" | cut -f1 | head -n1` -tag="$tagprefix$version" -majmin=`echo $version | cut -f1,2 -d.` -micro=`echo $version | cut -f3 -d.` -nextversion="$majmin.$(( micro + 1 ))-SNAPSHOT" -branch="version-$majmin.x" - -echo "Checking out to branch $branch" -git checkout $branch - -echo "Making sure we are up-to-date with upstream ($upstream remote)" -git fetch $upstream -git merge $upstream/$branch --ff-only - -echo "Testing build" -mvn clean install $testparams - -echo "Seting up new version" -mvn versions:set -DnewVersion=$version -mvn versions:commit -sed -i "s/HEAD<\/tag>/$tag<\/tag>/" pom.xml - -echo "Commiting changed pom files" -git add pom.xml */pom.xml -git commit -m "Release version $version" - -echo "Deploing artifacts" -GPG_TTY=$(tty) -export GPG_TTY -mvn clean deploy -DskipTests -Prelease $releaseparams - -echo "Tagging release" -git tag $tag - -echo "Preparing for next development" -mvn versions:set -DnewVersion=$nextversion -mvn versions:commit -sed -i "s/$tag<\/tag>/HEAD<\/tag>/" pom.xml -git add pom.xml */pom.xml -git commit -m "Preparing for next development" - -echo -echo -echo "Release prepared. Check everything!" -echo "Then go to https://oss.sonatype.org/ and release the staging repository." -echo "When everything is done, don't forget to push:" -echo " git push $upstream $branch && git push $upstream $tag" - diff --git a/rest/pom.xml b/rest/pom.xml deleted file mode 100644 index 4f96ae0b..00000000 --- a/rest/pom.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - 4.0.0 - - - org.jboss.pnc.causeway - causeway - 3.0.3-SNAPSHOT - - - causeway-rest - ejb - Causeway :: REST Bindings - - - - org.jboss.pnc - pnc-api - - - com.fasterxml.jackson.core - jackson-databind - provided - - - org.jboss.spec.javax.ws.rs - jboss-jaxrs-api_2.1_spec - provided - - - com.fasterxml.jackson.core - jackson-annotations - provided - - - junit - junit - - - org.projectlombok - lombok - - - diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewBuild.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewBuild.java deleted file mode 100644 index da52863b..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewBuild.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class BrewBuild extends BrewNVR { - - private final Integer id; - - @JsonCreator - public BrewBuild( - @JsonProperty("id") Integer id, - @JsonProperty("name") String name, - @JsonProperty("version") String version, - @JsonProperty("release") String release) { - super(name, version, release); - this.id = id; - } - - public BrewBuild(Integer id, BrewNVR nvr) { - this(id, nvr.getName(), nvr.getVersion(), nvr.getRelease()); - } - - public Integer getId() { - return id; - } -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewNVR.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewNVR.java deleted file mode 100644 index 37d69ef6..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewNVR.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -import lombok.EqualsAndHashCode; - -@EqualsAndHashCode -public class BrewNVR { - - private final String name; - private final String version; - private final String release; - - public BrewNVR(String name, String version, String release) { - this.name = name; - this.version = version.replace('-', '_'); - this.release = release.replace('-', '_'); - } - - public String getName() { - return name; - } - - public String getKojiName() { - return name.replaceAll(":", "-"); - } - - public String getVersion() { - return version; - } - - public String getRelease() { - return release; - } - - @JsonIgnore - public String getNVR() { - return getKojiName() + "-" + version + "-" + release; - } -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestone.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestone.java deleted file mode 100644 index 58e9550f..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestone.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import org.jboss.pnc.api.dto.Request; -import org.jboss.pnc.causeway.rest.pnc.MilestoneReleaseRest; - -import com.fasterxml.jackson.annotation.JsonUnwrapped; - -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Data -@NoArgsConstructor -@Deprecated -public class BrewPushMilestone { - @JsonUnwrapped - @NonNull - private MilestoneReleaseRest content; - @NonNull - private Request callback; -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestoneResponse.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestoneResponse.java deleted file mode 100644 index d93ff0a7..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestoneResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import lombok.Data; -import lombok.NonNull; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Data -@Deprecated -public class BrewPushMilestoneResponse { - @NonNull - private final Callback callback; -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestoneResult.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestoneResult.java deleted file mode 100644 index d6475b12..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/BrewPushMilestoneResult.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import org.jboss.pnc.causeway.rest.pnc.MilestoneReleaseResultRest; - -import lombok.Data; -import lombok.NonNull; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Data -@Deprecated -public class BrewPushMilestoneResult { - @NonNull - private final MilestoneReleaseResultRest content; - @NonNull - private final Callback callback; -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/Callback.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/Callback.java deleted file mode 100644 index 9635fbf5..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/Callback.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import com.fasterxml.jackson.annotation.JsonInclude; - -import lombok.Data; -import lombok.NonNull; - -/** - * - * @author Honza Brázdil <janinko.g@gmail.com> - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -@Data -@Deprecated -public class Callback { - @NonNull - private final String id; - - private final Integer status; - - public Callback(String id) { - this.id = id; - this.status = null; - } - - public Callback(String id, int status) { - this.id = id; - this.status = status; - } -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/PncImportResource.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/PncImportResource.java deleted file mode 100644 index 01ebe763..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/PncImportResource.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -@Path("/import/product") -@Deprecated -public interface PncImportResource { - - @POST - @Path("/milestone") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Deprecated - public BrewPushMilestoneResponse importProductMilestone(BrewPushMilestone request); - -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/model/response/OperationStatus.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/model/response/OperationStatus.java deleted file mode 100644 index 6a67636b..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/model/response/OperationStatus.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest.model.response; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -public enum OperationStatus { - - SUCCESS, FAILED, SYSTEM_ERROR - -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/model/response/UntagResultRest.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/model/response/UntagResultRest.java deleted file mode 100644 index b18b41be..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/model/response/UntagResultRest.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * JBoss, Home of Professional Open Source. - * Copyright 2014 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. - * - * 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. - */ -package org.jboss.pnc.causeway.rest.model.response; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; - -import lombok.Builder; - -import lombok.Data; -import lombok.NonNull; - -/** - * @author Matej Lazar - */ -@Data -@Builder -@JsonDeserialize(builder = UntagResultRest.BuildRecordPushResultRestBuilder.class) -public class UntagResultRest { - - @NonNull - private final OperationStatus status; - - @NonNull - private final String log; - - private final int brewBuildId; - - @JsonPOJOBuilder(withPrefix = "") - public static final class BuildRecordPushResultRestBuilder { - } - -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/BuildImportResultRest.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/BuildImportResultRest.java deleted file mode 100644 index 258c6d22..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/BuildImportResultRest.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * JBoss, Home of Professional Open Source. - * Copyright 2014 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. - * - * 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. - */ -package org.jboss.pnc.causeway.rest.pnc; - -import com.fasterxml.jackson.annotation.JsonInclude; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Author: Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com Date: 8/25/16 Time: 2:48 PM - */ -@Data -@JsonInclude(JsonInclude.Include.NON_NULL) -@NoArgsConstructor -@AllArgsConstructor -@Deprecated -public class BuildImportResultRest { - - /** - * id of pnc build record - */ - private String buildRecordId; - - /** - * build id assigned by brew - */ - private Integer brewBuildId; - /** - * link to brew - */ - private String brewBuildUrl; - - private BuildImportStatus status; - /** - * global errors - */ - private String errorMessage; -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/BuildImportStatus.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/BuildImportStatus.java deleted file mode 100644 index 73a5251d..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/BuildImportStatus.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * JBoss, Home of Professional Open Source. - * Copyright 2014 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. - * - * 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. - */ -package org.jboss.pnc.causeway.rest.pnc; - -/** - * Author: Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com Date: 8/25/16 Time: 2:22 PM - */ -@Deprecated -public enum BuildImportStatus { - - /** - * setting up the import process failed - */ - ERROR, - /** - * some of the artifacts failed to import - */ - FAILED, - SUCCESSFUL -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/MilestoneReleaseRest.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/MilestoneReleaseRest.java deleted file mode 100644 index dc51a1a2..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/MilestoneReleaseRest.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * JBoss, Home of Professional Open Source. - * Copyright 2014 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. - * - * 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. - */ -package org.jboss.pnc.causeway.rest.pnc; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import lombok.Data; - -/** - * Author: Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com Date: 8/24/16 Time: 3:42 PM - */ -@Data -@Deprecated -public class MilestoneReleaseRest { - - private final int milestoneId; - - @JsonCreator - public MilestoneReleaseRest(@JsonProperty("milestoneId") int milestoneId) { - this.milestoneId = milestoneId; - } -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/MilestoneReleaseResultRest.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/MilestoneReleaseResultRest.java deleted file mode 100644 index 5a9cf035..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/MilestoneReleaseResultRest.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * JBoss, Home of Professional Open Source. - * Copyright 2014 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. - * - * 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. - */ -package org.jboss.pnc.causeway.rest.pnc; - -import lombok.Data; - -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -/** - * Author: Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com Date: 8/25/16 Time: 7:34 AM - */ -@Data -@Deprecated -public class MilestoneReleaseResultRest { - - private static final String EVENT_TYPE = "BREW_IMPORT"; - - private Integer milestoneId; - - private ReleaseStatus releaseStatus; - private String errorMessage; - - private List builds = new ArrayList<>(); - - public String getEventType() { - return EVENT_TYPE; - } - - @JsonIgnore - public boolean isSuccessful() { - return !builds.isEmpty() && allBuildsSuccessful(); - } - - private boolean allBuildsSuccessful() { - return builds.stream().allMatch(r -> r.getStatus() == BuildImportStatus.SUCCESSFUL); - } -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/ReleaseStatus.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/ReleaseStatus.java deleted file mode 100644 index 58b566f3..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/pnc/ReleaseStatus.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * JBoss, Home of Professional Open Source. - * Copyright 2014 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. - * - * 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. - */ -package org.jboss.pnc.causeway.rest.pnc; - -/** - * Author: Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com Date: 8/26/16 Time: 2:39 PM - */ -@Deprecated -public enum ReleaseStatus { - - SUCCESS, FAILURE, IMPORT_ERROR, SET_UP_ERROR; - -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/spi/Import.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/spi/Import.java deleted file mode 100644 index 67017ada..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/spi/Import.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest.spi; - -import org.jboss.pnc.api.causeway.dto.push.BuildImportRequest; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -/** - * - * @author Honza Brázdil <janinko.g@gmail.com> - */ - -@Path("/import") -public interface Import { - - @POST - @Path("/build") - @Consumes(MediaType.APPLICATION_JSON) - public Response importBuild(BuildImportRequest request); - - @GET - @Path("/test/{variable}") - public Response testResponse(@PathParam("variable") String var); -} diff --git a/rest/src/main/java/org/jboss/pnc/causeway/rest/spi/Untag.java b/rest/src/main/java/org/jboss/pnc/causeway/rest/spi/Untag.java deleted file mode 100644 index e6241f72..00000000 --- a/rest/src/main/java/org/jboss/pnc/causeway/rest/spi/Untag.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest.spi; - -import org.jboss.pnc.api.causeway.dto.untag.UntagRequest; - -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -@Path("/untag") -public interface Untag { - - @POST - @Path("/build") - @Consumes(MediaType.APPLICATION_JSON) - public Response untagBuild(UntagRequest request); - -} diff --git a/rest/src/main/resources/META-INF/beans.xml b/rest/src/main/resources/META-INF/beans.xml deleted file mode 100644 index 794b8b5f..00000000 --- a/rest/src/main/resources/META-INF/beans.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/rest/src/test/java/org/jboss/pnc/causeway/rest/CallbackTargetTest.java b/rest/src/test/java/org/jboss/pnc/causeway/rest/CallbackTargetTest.java deleted file mode 100644 index 0d45c226..00000000 --- a/rest/src/test/java/org/jboss/pnc/causeway/rest/CallbackTargetTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import static org.junit.Assert.assertFalse; - -import org.jboss.pnc.api.dto.Request; -import org.junit.Test; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -public class CallbackTargetTest { - - @Test - public void testSecurityCensoring() throws URISyntaxException { - Request ct = Request.builder() - .method(Request.Method.POST) - .uri(new URI("http://foo.bar/")) - .header("foo", "bar") - .header("Authorization", "top-secret-token") - .build(); - String toString = ct.toString(); - assertFalse("Secret token should be censored", toString.contains("top-secret-token")); - } -} diff --git a/src/main/docker/Dockerfile.jvm b/src/main/docker/Dockerfile.jvm new file mode 100644 index 00000000..13f413a3 --- /dev/null +++ b/src/main/docker/Dockerfile.jvm @@ -0,0 +1,97 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# mvn package +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/causeway-jvm . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/causeway-jvm +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/causeway-jvm +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.19 + +ENV LANGUAGE='en_US:en' + + +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/ +COPY --chown=185 target/quarkus-app/*.jar /deployments/ +COPY --chown=185 target/quarkus-app/app/ /deployments/app/ +COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] + diff --git a/src/main/docker/Dockerfile.legacy-jar b/src/main/docker/Dockerfile.legacy-jar new file mode 100644 index 00000000..49289a7a --- /dev/null +++ b/src/main/docker/Dockerfile.legacy-jar @@ -0,0 +1,93 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# mvn package -Dquarkus.package.jar.type=legacy-jar +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/causeway-legacy-jar . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/causeway-legacy-jar +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/causeway-legacy-jar +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.19 + +ENV LANGUAGE='en_US:en' + + +COPY target/lib/* /deployments/lib/ +COPY target/*-runner.jar /deployments/quarkus-run.jar + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] diff --git a/src/main/docker/Dockerfile.native b/src/main/docker/Dockerfile.native new file mode 100644 index 00000000..a03e0e45 --- /dev/null +++ b/src/main/docker/Dockerfile.native @@ -0,0 +1,27 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# +# Before building the container image run: +# +# mvn package -Dnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native -t quarkus/causeway . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/causeway +# +### +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root target/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/src/main/docker/Dockerfile.native-micro b/src/main/docker/Dockerfile.native-micro new file mode 100644 index 00000000..1be7f43d --- /dev/null +++ b/src/main/docker/Dockerfile.native-micro @@ -0,0 +1,30 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# It uses a micro base image, tuned for Quarkus native executables. +# It reduces the size of the resulting container image. +# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. +# +# Before building the container image run: +# +# mvn package -Dnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/causeway . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/causeway +# +### +FROM quay.io/quarkus/quarkus-micro-image:2.0 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root target/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/src/main/java/org/jboss/pnc/causeway/CausewayConfig.java b/src/main/java/org/jboss/pnc/causeway/CausewayConfig.java new file mode 100644 index 00000000..d72ea2d7 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/CausewayConfig.java @@ -0,0 +1,62 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway; + +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; +import org.jboss.pnc.common.http.PNCHttpClientConfig; + +import java.net.URL; +import java.util.Set; + +@ConfigMapping(prefix = "causeway") +public interface CausewayConfig { + + Koji koji(); + + PNC pnc(); + + PNCHttpClientConfig httpClientConfig(); + + interface Koji { + + String url(); + + String clientKeyCertificateFile(); // was koji.client.pem.file + + String clientCertificatePassword(); // was koji.client.pem.password + + // String serverCertificateFile(); // was koji.server.pem.file + + @WithDefault("false") + Boolean trustSelfSigned(); // was koji.trust.self-signed + + @WithDefault("900") + Integer timeout(); // was koji.timeout.secs + + @WithDefault("1200") + Integer connectionPoolTimeout(); // was koji.connectionPoolTimeout.secs + + @WithDefault("10") + Integer connections(); // was koji.connections + + String webURL(); // was koji.weburl + } + + interface PNC { + String buildsURL(); // was pncl.url + + String systemVersion(); // was pnc.system.version + + @WithDefault("[]") + Set ignoredTools(); // pnc.tools.ignored + + URL url(); + + @WithDefault("200") + int pageSize(); + } + +} diff --git a/src/main/java/org/jboss/pnc/causeway/CausewayException.java b/src/main/java/org/jboss/pnc/causeway/CausewayException.java new file mode 100644 index 00000000..ae6a24b1 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/CausewayException.java @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway; + +/** + * This class indicates an error, which signifies problem in this or related services. + * + * @author Honza Brázdil <jbrazdil@redhat.com> + */ +public class CausewayException extends RuntimeException { + + public CausewayException(String message, Throwable cause) { + super(message, cause); + } + + public CausewayException(String message) { + super(message); + } + +} diff --git a/src/main/java/org/jboss/pnc/causeway/CausewayFailure.java b/src/main/java/org/jboss/pnc/causeway/CausewayFailure.java new file mode 100644 index 00000000..0c7732b7 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/CausewayFailure.java @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway; + +/** + * This class indicates a failure, which can usually be solved by user. + * + * @author Honza Brázdil <jbrazdil@redhat.com> + */ +public class CausewayFailure extends CausewayException { + + public CausewayFailure(String format, Throwable cause) { + super(format, cause); + } + + public CausewayFailure(String message) { + super(message); + } + +} diff --git a/src/main/java/org/jboss/pnc/causeway/CausewayResource.java b/src/main/java/org/jboss/pnc/causeway/CausewayResource.java new file mode 100644 index 00000000..cf5d40b2 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/CausewayResource.java @@ -0,0 +1,122 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.eclipse.microprofile.context.ManagedExecutor; +import org.jboss.pnc.api.causeway.dto.push.BuildPushRequest; +import org.jboss.pnc.api.causeway.dto.push.PushResult; +import org.jboss.pnc.api.causeway.dto.untag.UntagRequest; +import org.jboss.pnc.api.causeway.rest.Causeway; +import org.jboss.pnc.api.dto.ComponentVersion; +import org.jboss.pnc.api.dto.HeartbeatConfig; +import org.jboss.pnc.api.dto.Request; +import org.jboss.pnc.api.enums.ResultStatus; +import org.jboss.pnc.causeway.constants.BuildInformationConstants; +import org.jboss.pnc.causeway.ctl.ImportController; +import org.jboss.pnc.common.concurrent.HeartbeatScheduler; +import org.jboss.pnc.common.http.PNCHttpClient; + +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; +import java.time.ZonedDateTime; +import java.util.concurrent.CompletionException; +import java.util.function.Consumer; + +@ApplicationScoped +@Slf4j +public class CausewayResource implements Causeway { + + @Inject + ImportController controller; + + @Inject + ManagedExecutor executor; + + @Inject + HeartbeatScheduler heartbeat; + + @Inject + PNCHttpClient httpClient; + + @ConfigProperty(name = "quarkus.application.name") + String name; + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public void importBuild(@Valid BuildPushRequest buildPushRequest) { + HeartbeatConfig heartbeatConf = buildPushRequest.getHeartbeat(); + if (heartbeatConf != null) { + heartbeat.subscribeRequest(buildPushRequest.getId(), heartbeatConf); + } + + executor.supplyAsync( + () -> controller.importBuild( + buildPushRequest.getBuildId(), + buildPushRequest.getTagPrefix(), + buildPushRequest.isReimport(), + buildPushRequest.getUsername())) + .exceptionally(e -> handleError(e, buildPushRequest.getBuildId())) + .thenAccept(sendCallback(buildPushRequest.getCallback())) + .whenComplete((_r, e) -> { + heartbeat.unsubscribeRequest(buildPushRequest.getId()); + }); + throw new WebApplicationException(Response.Status.ACCEPTED); // return 202 status, quarkus/issues/30170 + } + + private Consumer sendCallback(Request callback) { + if (callback == null) { + return (pushResult -> {}); + } else { + return (pushResult -> { + try { + httpClient.sendRequest(callback, pushResult); + } catch (RuntimeException ex) { + log.error("Error when sending callback " + callback + " with " + pushResult + "."); + } + }); + } + } + + private static PushResult handleError(Throwable e, String buildId) { + PushResult.PushResultBuilder resultBuilder = PushResult.builder().buildId(buildId); + if (e instanceof CompletionException) { + e = e.getCause(); + } + if (e instanceof CausewayFailure) { + log.info("Failure: " + e.getMessage()); + resultBuilder.result(ResultStatus.FAILED); + } else if (e instanceof CausewayException) { + log.error(e.getMessage(), e); + resultBuilder.result(ResultStatus.SYSTEM_ERROR); + } else { + log.error("Unexpected error while pushing to Brew.", e); + resultBuilder.result(ResultStatus.SYSTEM_ERROR); + } + + return resultBuilder.build(); + } + + @Override + public void untagBuild(@Valid UntagRequest request) { + controller.untagBuild(request.getBuild().getBrewBuildId(), request.getBuild().getTagPrefix()); + } + + @Override + public ComponentVersion getVersion() { + return ComponentVersion.builder() + .name(name) + .version(BuildInformationConstants.VERSION) + .commit(BuildInformationConstants.COMMIT_HASH) + .builtOn(ZonedDateTime.parse(BuildInformationConstants.BUILD_TIME)) + .build(); + } +} diff --git a/core/src/main/java/org/jboss/pnc/causeway/ErrorMessages.java b/src/main/java/org/jboss/pnc/causeway/ErrorMessages.java similarity index 64% rename from core/src/main/java/org/jboss/pnc/causeway/ErrorMessages.java rename to src/main/java/org/jboss/pnc/causeway/ErrorMessages.java index c64a4606..a0c90b3e 100644 --- a/core/src/main/java/org/jboss/pnc/causeway/ErrorMessages.java +++ b/src/main/java/org/jboss/pnc/causeway/ErrorMessages.java @@ -1,23 +1,22 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ package org.jboss.pnc.causeway; import com.redhat.red.build.koji.KojiClientException; import com.redhat.red.build.koji.KojijiErrorInfo; import com.redhat.red.build.koji.model.json.KojiJsonConstants; import com.redhat.red.build.koji.model.json.VerificationException; -import org.jboss.pnc.api.causeway.dto.push.Build; import org.jboss.pnc.causeway.brewclient.BrewClientImpl; import org.jboss.pnc.causeway.brewclient.BuildTranslatorImpl; -import org.jboss.pnc.client.ClientException; import org.jboss.pnc.client.RemoteResourceException; -import org.jboss.pnc.client.RemoteResourceNotFoundException; import org.jboss.pnc.enums.BuildType; -import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.security.NoSuchAlgorithmException; import java.text.MessageFormat; -import java.util.List; import static org.jboss.pnc.api.constants.Attributes.BUILD_BREW_NAME; @@ -27,7 +26,7 @@ public class ErrorMessages { private static final String FAILURE_IMPORTING_BUILDS = "Failure while importing builds to Koji: {0}"; private static final String FAILURE_LOGGING_TO_KOJI = "Failure while logging to Koji: {0}"; private static final String MISSING_TAG_PERMISSIONS = "Failure while communicating with Koji: This is most probably because of missing permissions. Ask RCM to add permissions for user ''{0}}'' to add packages to tag ''{1}'' and to tag builds into tag ''{2}''. Cause: {3}"; - private static final String FOUND_CONFLICTING_BREW_BUILD = "Found conflicting brew build {0} (build doesn''t have " + private static final String FOUND_CONFLICTING_BREW_BUILD = "Found conflicting brew build {0} (build doesn't have " + KojiJsonConstants.BUILD_SYSTEM + " set to " + BuildTranslatorImpl.PNC + ")."; private static final String FAILURE_IMPORTING_ARTIFACTS = "Failure while importing artifacts."; private static final String NO_BUILD_INFO = "Import to koji failed for unknown reason. No build data."; @@ -37,7 +36,6 @@ public class ErrorMessages { private static final String UNKNOWN_SYSTEM_IMAGE_TYPE = "Unknown system image type."; private static final String FAILED_TO_PARSE_ARTIFACT_URL = "Failed to parse artifact URL: {0}"; private static final String FAILED_TO_READ_LOG_FILE = "Failed to read log file: {0}"; - private static final String UNSUPPORTED_BUILD_CLASS = "Unsupported type of build ''{0}''"; private static final String UNSUPPORTED_BUILD_TYPE = "Unsupported build type ''{0}''."; private static final String FAILED_TO_DOWNLOAD_SOURCES = "Failed to download sources: {0}"; private static final String FAILURE_WHILE_BUILDING_KOJI_IMPORT = "Failure while building metadata for the import to Koji : {0}"; @@ -50,40 +48,39 @@ public class ErrorMessages { private static final String BUILD_ENVIRONMENT_HAS_MULTIPLE_VERSIONS = "Build environment ({0}) has multiple versions for tool ''{1}''"; private static final String BUILD_ENVIRONMENT_HAS_NO_VERSION = "Build environment ({0}) has no version for tool {1}"; private static final String FAILED_TO_OBTAIN_ARTIFACT = "Failed to obtain artifact (status {0} {1})"; - private static final String CAUSEWAY_HAS_NOT_BEEN_CONFIGURED = "The Causeway system has not been configured. This is a sign that something is in the wrong order in the boot sequence."; - private static final String CONFIG_VALUE_IS_NOT_URL = "Value of the ''{0}'' field in Causeway configuration is not parsable URL"; - private static final String FAILED_TO_READ_CONFIG_FILE = "Failed to read configuration: {0}. Reason: {1}"; - private static final String CONFIG_IS_NOT_COMPLETE = "Causeway configuration is not complete. Validation errors:\n{0}"; - public static final String FAILED_TO_IMPORT_BUILD = "Failed to import build {0}: {1}"; - public static final String ERROR_WHILE_IMPORTING_BUILD = "Error while importing build {0}: {1}"; - public static final String FAILED_TO_IMPORT_MILESTONE = "Failed to import milestone {0}: {1}"; - public static final String ERROR_WHILE_IMPORTING_MILESTONE = "Error while importing milestone {0}: {1}"; - public static final String FAILED_TO_UNTAG_BUILD = "Failed to untag build: {0}"; - public static final String ERROR_WHILE_UNTAGGING_BUILD = "Error while untagging build: {0}"; - public static final String BUILD_DOESN_T_CONTAIN_ANY_ARTIFACTS = "Build doesn't contain any artifacts."; - public static final String MISSING_TAG_MESSAGE = "Proper brew tags don''t exist. Create them before importing builds.\n" - + "Tag prefix: {0}\n" + "You should ask RCM to create at least following tags:\n" + " * {1}\n" - + " * {2}\n" + "in {3}\n" + "(Note that tag {1} should inherit from tag {2})"; - public static final String BREW_BUILD_WAS_NOT_FOUND = "Brew build with id {0} was not found."; - public static final String MILESTONE_DOES_NOT_CONTAIN_ANY_BUILD = "Milestone {0} does not contain any build."; - public static final String BAD_ARTIFACT_NOT_IMPORTED = "Failed to import artifact {0}: This artifact is blacklisted or deleted, so it was not imported."; - public static final String COULD_NOT_CONNECT_TO_KOJI = "Couldn''t connect to Koji: {0}"; - public static final String MILESTONE_NOT_FOUND_WHEN_GETTING_TAG = "Can not read tag because the product milestone {0} was not found in PNC: {1}"; - public static final String ERROR_READING_TAG_FROM_MILESTONE = "Can not read tag from product milestone {0} because PNC responded with an {0} error: {2}"; - public static final String ERROR_COMMUNICATING_WHEN_GETTING_TAG = "Can not read tag because there was a problem communicating with PNC when getting product milestone {1}: {2}"; - public static final String ERROR_READING_BUILDS_FROM_MILESTONE = "Can not read builds for product milestone {0} because PNC responded with an {1} error: {2}"; - public static final String ERROR_READING_BUILD_LOG = "Can not read build log of build {0} because PNC responded with an {1} error: {2}"; - public static final String ERROR_READING_BUILD_SOURCES = "Can not read sources of build {0} because PNC responded with an {1} error: {2}"; - public static final String ERROR_READING_BUILD_SOURCES_NO_STATUS = "Can not read sources of build {0} because PNC responded with an error: {1}"; - public static final String ERROR_READING_BUILD_ARTIFACTS = "Can not read artifacts of build {0} because PNC responded with an {1} error: {2}"; - public static final String BUILD_LOG_IS_EMPTY = "Build log for build {0} is empty."; - public static final String SOURCES_ARCHIVE_FILE_WAS_ALREADY_READ = "Sources archive file was already read."; - public static final String THIS_IS_NOT_A_MAVEN_TYPE = "This is not a Maven type."; - public static final String THIS_IS_NOT_AN_NPM_TYPE = "This is not an NPM type."; - public static final String ERROR_REPACKING_ARCHIVE = "Error while repacking archive with changed root directory name: {0}"; - public static final String MISSING_MD5_SUPPORT = "The JVM does not support MD5 digest"; - public static final String NON_DIRECTORY_FILE_IN_ROOT_OF_THE_ARCHIVE = "There is a non-directory file in root of the archive."; - public static final String MULTIPLE_DIRECTORIES_IN_ROOT_OF_THE_ARCHIVE = "There are multiple directories in root of the archive."; + private static final String FAILED_TO_IMPORT_BUILD = "Failed to import build {0}: {1}"; + private static final String ERROR_WHILE_IMPORTING_BUILD = "Error while importing build {0}: {1}"; + private static final String FAILED_TO_UNTAG_BUILD = "Failed to untag build: {0}"; + private static final String ERROR_WHILE_UNTAGGING_BUILD = "Error while untagging build: {0}"; + private static final String BUILD_DOESN_T_CONTAIN_ANY_ARTIFACTS = "Build doesn't contain any artifacts."; + private static final String MISSING_TAG_MESSAGE = """ + Proper brew tags don''t exist. Create them before importing builds. + Tag prefix: {0} + You should ask RCM to create at least following tags: + * {1} + * {2} + in {3} + (Note that tag {1} should inherit from tag {2})"""; + private static final String BREW_BUILD_WAS_NOT_FOUND = "Brew build with id {0} was not found."; + private static final String PNC_BUILD_WAS_NOT_FOUND = "PNC build with id {0} was not found."; + private static final String BAD_ARTIFACT_NOT_IMPORTED = "Failed to import artifact {0}: This artifact is blacklisted or deleted, so it was not imported."; + private static final String COULD_NOT_CONNECT_TO_KOJI = "Couldn''t connect to Koji: {0}"; + private static final String ERROR_READING_BUILD = "Can not read build metadata of build {0} because PNC responded with an {1} error: {2}"; + private static final String ERROR_READING_BUILD_LOG = "Can not read build log of build {0} because PNC responded with an {1} error: {2}"; + private static final String ERROR_STORING_BUILD_LOG = "Can not temporarily store build log of build {0} because of an error: {1}"; + private static final String ERROR_READING_ALIGN_LOG = "Can not read alignment log of build {0} because PNC responded with an {1} error: {2}"; + private static final String ERROR_STORING_ALIGN_LOG = "Can not temporarily store alignment log of build {0} because of an error: {1}"; + private static final String ERROR_READING_BUILD_SOURCES = "Can not read sources of build {0} because PNC responded with an {1} error: {2}"; + private static final String ERROR_READING_BUILD_SOURCES_NO_STATUS = "Can not read sources of build {0} because PNC responded with an error: {1}"; + private static final String ERROR_READING_BUILD_ARTIFACTS = "Can not read artifacts of build {0} because PNC responded with an {1} error: {2}"; + private static final String BUILD_LOG_IS_EMPTY = "Build log for build {0} is empty."; + private static final String SOURCES_ARCHIVE_FILE_WAS_ALREADY_READ = "Sources archive file was already read."; + private static final String THIS_IS_NOT_A_MAVEN_TYPE = "This is not a Maven type."; + private static final String THIS_IS_NOT_AN_NPM_TYPE = "This is not an NPM type."; + private static final String ERROR_REPACKING_ARCHIVE = "Error while repacking archive with changed root directory name: {0}"; + private static final String MISSING_MD5_SUPPORT = "The JVM does not support MD5 digest"; + private static final String NON_DIRECTORY_FILE_IN_ROOT_OF_THE_ARCHIVE = "There is a non-directory file in root of the archive."; + private static final String MULTIPLE_DIRECTORIES_IN_ROOT_OF_THE_ARCHIVE = "There are multiple directories in root of the archive."; /** * {@value KOJI_COMMUNICATION_FAILURE} @@ -198,13 +195,6 @@ public static String unknownSystemImageType() { return UNKNOWN_SYSTEM_IMAGE_TYPE; } - /** - * {@value UNSUPPORTED_BUILD_CLASS} - */ - public static String unsupportedBuildClass(Class buildClass) { - return MessageFormat.format(UNSUPPORTED_BUILD_CLASS, buildClass); - } - /** * {@value UNSUPPORTED_BUILD_TYPE} */ @@ -254,35 +244,6 @@ public static String failedToObtainArtifact(int responseCode, String responseMes return MessageFormat.format(FAILED_TO_OBTAIN_ARTIFACT, responseCode, responseMessage); } - /** - * {@value CAUSEWAY_HAS_NOT_BEEN_CONFIGURED} - */ - public static String causewayNotConfigured() { - return CAUSEWAY_HAS_NOT_BEEN_CONFIGURED; - } - - /** - * {@value CONFIG_VALUE_IS_NOT_URL} - */ - public static String configurationValueIsNotURL(String valueName) { - return MessageFormat.format(CONFIG_VALUE_IS_NOT_URL, valueName); - } - - /** - * {@value FAILED_TO_READ_CONFIG_FILE} - */ - public static String failedToReadConfigFile(File configFile, Exception ex) { - return MessageFormat.format(FAILED_TO_READ_CONFIG_FILE, configFile, ex); - } - - /** - * {@value CONFIG_IS_NOT_COMPLETE} - */ - public static String configIsNotComplete(List validationErrors) { - String formattedValidationErrors = String.join("\n", validationErrors); - return MessageFormat.format(CONFIG_IS_NOT_COMPLETE, formattedValidationErrors); - } - /** * {@value FAILED_TO_IMPORT_BUILD} */ @@ -297,20 +258,6 @@ public static String errorImportingBuild(String buildId, Exception ex) { return MessageFormat.format(ERROR_WHILE_IMPORTING_BUILD, buildId, ex); } - /** - * {@value FAILED_TO_IMPORT_MILESTONE} - */ - public static String failedToImportMilestone(int milestoneId, CausewayFailure ex) { - return MessageFormat.format(FAILED_TO_IMPORT_MILESTONE, milestoneId, ex); - } - - /** - * {@value ERROR_WHILE_IMPORTING_MILESTONE} - */ - public static String errorImportingMilestone(int milestoneId, Exception ex) { - return MessageFormat.format(ERROR_WHILE_IMPORTING_MILESTONE, milestoneId, ex); - } - /** * {@value FAILED_TO_UNTAG_BUILD} */ @@ -349,10 +296,10 @@ public static String brewBuildNotFound(int kojiBuildId) { } /** - * {@value MILESTONE_DOES_NOT_CONTAIN_ANY_BUILD} + * {@value BREW_BUILD_WAS_NOT_FOUND} */ - public static String messageMilestoneWithoutBuilds(long milestoneId) { - return MessageFormat.format(MILESTONE_DOES_NOT_CONTAIN_ANY_BUILD, milestoneId); + public static String pncBuildNotFound(String pncBuildId) { + return MessageFormat.format(PNC_BUILD_WAS_NOT_FOUND, pncBuildId); } /** @@ -370,45 +317,45 @@ public static String canNotConnectToKoji(KojiClientException ex) { } /** - * {@value MILESTONE_NOT_FOUND_WHEN_GETTING_TAG} + * {@value BUILD_LOG_IS_EMPTY} */ - public static String milestoneNotFoundWhenGettingTag(int milestoneId, RemoteResourceNotFoundException ex) { - return MessageFormat.format(MILESTONE_NOT_FOUND_WHEN_GETTING_TAG, milestoneId, ex); + public static String buildLogIsEmpty(String buildId) { + return MessageFormat.format(BUILD_LOG_IS_EMPTY, buildId); } /** - * {@value ERROR_READING_TAG_FROM_MILESTONE} + * {@value ERROR_READING_BUILD} */ - public static String errorReadingTagFromMilestone(int milestoneId, RemoteResourceException ex) { - return MessageFormat.format(ERROR_READING_TAG_FROM_MILESTONE, milestoneId, ex.getStatus(), ex); + public static String errorReadingBuild(String buildId, RemoteResourceException ex) { + return MessageFormat.format(ERROR_READING_BUILD, buildId, ex.getStatus(), ex); } /** - * {@value ERROR_COMMUNICATING_WHEN_GETTING_TAG} + * {@value ERROR_READING_BUILD_LOG} */ - public static String errorCommunicatingWhenGettingTag(int milestoneId, ClientException ex) { - return MessageFormat.format(ERROR_COMMUNICATING_WHEN_GETTING_TAG, milestoneId, ex); + public static String errorReadingBuildLog(String buildId, RemoteResourceException ex) { + return MessageFormat.format(ERROR_READING_BUILD_LOG, buildId, ex.getStatus(), ex); } /** - * {@value ERROR_READING_BUILDS_FROM_MILESTONE} + * {@value ERROR_STORING_BUILD_LOG} */ - public static String errorReadingBuildsFromMilestone(int milestoneId, RemoteResourceException ex) { - return MessageFormat.format(ERROR_READING_BUILDS_FROM_MILESTONE, milestoneId, ex.getStatus(), ex); + public static String errorStoringBuildLog(String buildId, Exception ex) { + return MessageFormat.format(ERROR_STORING_BUILD_LOG, buildId, ex); } /** - * {@value BUILD_LOG_IS_EMPTY} + * {@value ERROR_READING_ALIGN_LOG} */ - public static String buildLogIsEmpty(String buildId) { - return MessageFormat.format(BUILD_LOG_IS_EMPTY, buildId); + public static String errorReadingAlignLog(String buildId, RemoteResourceException ex) { + return MessageFormat.format(ERROR_READING_ALIGN_LOG, buildId, ex.getStatus(), ex); } /** - * {@value ERROR_READING_BUILD_LOG} + * {@value ERROR_STORING_ALIGN_LOG} */ - public static String errorReadingBuildLog(String buildId, RemoteResourceException ex) { - return MessageFormat.format(ERROR_READING_BUILD_LOG, buildId, ex.getStatus(), ex); + public static String errorStoringAlignLog(String buildId, Exception ex) { + return MessageFormat.format(ERROR_STORING_ALIGN_LOG, buildId, ex); } /** @@ -484,7 +431,7 @@ public static String nonDirectoryInArchiveRoot() { /** * {@value MULTIPLE_DIRECTORIES_IN_ROOT_OF_THE_ARCHIVE} */ - public static String multipleDirectoriseInArchiveRoot() { + public static String multipleDirectoriesInArchiveRoot() { return MULTIPLE_DIRECTORIES_IN_ROOT_OF_THE_ARCHIVE; } } diff --git a/src/main/java/org/jboss/pnc/causeway/brewclient/BrewBuild.java b/src/main/java/org/jboss/pnc/causeway/brewclient/BrewBuild.java new file mode 100644 index 00000000..c6a992f7 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/brewclient/BrewBuild.java @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.brewclient; + +import lombok.Getter; + +@Getter +public class BrewBuild extends BrewNVR { + + private final Integer id; + + public BrewBuild(Integer id, String name, String version, String release) { + super(name, version, release); + this.id = id; + } + + public BrewBuild(Integer id, BrewNVR nvr) { + this(id, nvr.getName(), nvr.getVersion(), nvr.getRelease()); + } + +} diff --git a/core/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClient.java b/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClient.java similarity index 66% rename from core/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClient.java rename to src/main/java/org/jboss/pnc/causeway/brewclient/BrewClient.java index 1a686405..f3b577eb 100644 --- a/core/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClient.java +++ b/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClient.java @@ -1,26 +1,12 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 */ package org.jboss.pnc.causeway.brewclient; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.rest.BrewBuild; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.jboss.pnc.causeway.rest.pnc.BuildImportResultRest; - import com.redhat.red.build.koji.model.json.KojiImport; +import org.jboss.pnc.api.causeway.dto.push.PushResult; +import org.jboss.pnc.causeway.CausewayException; /** * @@ -32,7 +18,7 @@ public interface BrewClient { * Find Brew build with given name:version:release that was imported by Causeway. If there isn't any such build, * returns null. If there is build with the NVR but it wasn't imported by causeway, CausewayFailure exception is * thrown. - * + * * @throws CausewayException when build with given NVR exists but wasn't imported by Causeway. */ BrewBuild findBrewBuildOfNVR(BrewNVR nvr) throws CausewayException; @@ -40,18 +26,11 @@ public interface BrewClient { /** * Find Brew build with given id that was imported by Causeway. If there isn't such build, returns null. If there is * build with the id but it wasn't imported by causeway, CausewayFailure exception is thrown. - * + * * @throws CausewayException when build with given id exists but wasn't imported by Causeway. */ BrewBuild findBrewBuild(int id) throws CausewayException; - @Deprecated - BuildImportResultRest importBuild( - BrewNVR nvr, - String buildRecordId, - KojiImport kojiImport, - ImportFileGenerator importFiles) throws CausewayException; - BrewBuild importBuild(BrewNVR nvr, KojiImport kojiImport, ImportFileGenerator importFiles) throws CausewayException; public String getBuildUrl(int id); @@ -60,7 +39,7 @@ BuildImportResultRest importBuild( /** * Check if build is tagged in given tag. - * + * * @param tag Tag name to be checked. * @param build Brew build to get tag information. * @return True if the build is tagged in the given tag. @@ -70,7 +49,7 @@ BuildImportResultRest importBuild( /** * Tag build into given tag. - * + * * @param tag Tag name. * @param build Build to be tagegd. * @throws CausewayException when there was problem communicating with Brew or problems with permisions. diff --git a/core/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClientImpl.java b/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClientImpl.java similarity index 76% rename from core/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClientImpl.java rename to src/main/java/org/jboss/pnc/causeway/brewclient/BrewClientImpl.java index 768852f1..460e7dd6 100644 --- a/core/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClientImpl.java +++ b/src/main/java/org/jboss/pnc/causeway/brewclient/BrewClientImpl.java @@ -1,17 +1,6 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 */ package org.jboss.pnc.causeway.brewclient; @@ -24,25 +13,24 @@ import com.redhat.red.build.koji.model.xmlrpc.KojiBuildInfo; import com.redhat.red.build.koji.model.xmlrpc.KojiNVR; import com.redhat.red.build.koji.model.xmlrpc.KojiSessionInfo; +import com.redhat.red.build.koji.model.xmlrpc.KojiTagInfo; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.jboss.pnc.causeway.CausewayConfig; import org.jboss.pnc.causeway.CausewayException; import org.jboss.pnc.causeway.CausewayFailure; import org.jboss.pnc.causeway.ErrorMessages; -import org.jboss.pnc.causeway.config.CausewayConfig; -import org.jboss.pnc.causeway.rest.BrewBuild; -import org.jboss.pnc.causeway.rest.BrewNVR; -import org.jboss.pnc.causeway.rest.pnc.BuildImportResultRest; -import org.jboss.pnc.causeway.rest.pnc.BuildImportStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; import java.util.List; import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import com.redhat.red.build.koji.model.xmlrpc.KojiTagInfo; @ApplicationScoped @Slf4j public class BrewClientImpl implements BrewClient { + private static final Logger userLog = LoggerFactory.getLogger("org.jboss.pnc._userlog_.brew-push"); public static final String BUILD_TAG_SUFIX = "-candidate"; @@ -53,7 +41,7 @@ public class BrewClientImpl implements BrewClient { @Inject public BrewClientImpl(KojiClient koji, CausewayConfig config) { this.koji = koji; - brewUrl = config.getKojiWebURL(); + brewUrl = config.koji().webURL(); } @Override @@ -104,7 +92,7 @@ public BrewBuild findBrewBuild(int id) throws CausewayException { private void checkPNCImportedBuild(KojiBuildInfo bi) throws CausewayException { final Map extra = bi.getExtra(); Object buildSystem = extra == null ? null : extra.get(KojiJsonConstants.BUILD_SYSTEM); - if (buildSystem == null || !BuildTranslatorImpl.PNC.equals(buildSystem)) { + if (!BuildTranslatorImpl.PNC.equals(buildSystem)) { throw new CausewayFailure(ErrorMessages.conflictingBrewBuild(bi.getId())); } } @@ -149,7 +137,7 @@ public boolean isBuildTagged(String tag, BrewBuild build) throws CausewayExcepti try { log.info("Listing tags of build id {} from user '{}'.", build.getId(), session.getUserInfo().getUserName()); List tags = koji.listTags(build.getId(), session); - return tags.stream().map(KojiTagInfo::getName).anyMatch(n -> tagName.equals(n)); + return tags.stream().map(KojiTagInfo::getName).anyMatch(tagName::equals); } catch (KojiClientException ex) { throw new CausewayException(ErrorMessages.failureWhileGettingTagInformation(ex), ex); } finally { @@ -174,45 +162,6 @@ public void untagBuild(String tag, BrewNVR nvr) throws CausewayException { logout(session); } - @Override - public BuildImportResultRest importBuild( - BrewNVR nvr, - String buildRecordId, - KojiImport kojiImport, - ImportFileGenerator importFiles) throws CausewayException { - BuildImportResultRest ret = new BuildImportResultRest(); - ret.setBuildRecordId(buildRecordId); - ret.setStatus(BuildImportStatus.SUCCESSFUL); - try { - KojiSessionInfo session = login(); - log.info( - "Importing build {} from user '{}'.", - kojiImport.getBuildNVR(), - session.getUserInfo().getUserName()); - KojiImportResult result = koji.importBuild(kojiImport, importFiles, session); - logout(session); - - if (checkImportErrors(result, importFiles)) { - ret.setStatus(BuildImportStatus.FAILED); - } - - KojiBuildInfo bi = result.getBuildInfo(); - - if (bi == null) { - ret.setErrorMessage("Import to koji failed"); - ret.setStatus(BuildImportStatus.ERROR); - } else { - ret.setBrewBuildId(bi.getId()); - ret.setBrewBuildUrl(getBuildUrl(bi.getId())); - } - - log.info("Build {} import status: {}.", nvr.getNVR(), ret.getStatus()); - return ret; - } catch (KojiClientException ex) { - throw new CausewayException(ErrorMessages.kojiCommunicationFailure(ex), ex); - } - } - @Override public BrewBuild importBuild(BrewNVR nvr, KojiImport kojiImport, ImportFileGenerator importFiles) throws CausewayException { @@ -247,10 +196,10 @@ private boolean checkImportErrors(KojiImportResult result, ImportFileGenerator i if (kojiErrors != null) { for (Map.Entry e : kojiErrors.entrySet()) { String artifactId = importFiles.getId(e.getKey()); - if (log.isWarnEnabled()) { + if (userLog.isWarnEnabled()) { KojijiErrorInfo errorInfo = e.getValue(); String message = ErrorMessages.failedToImportArtifact(artifactId, e.getKey(), errorInfo); - log.warn(message, errorInfo.getError()); + userLog.warn(message, errorInfo.getError()); } errorsPresent = true; } diff --git a/src/main/java/org/jboss/pnc/causeway/brewclient/BrewNVR.java b/src/main/java/org/jboss/pnc/causeway/brewclient/BrewNVR.java new file mode 100644 index 00000000..ea2a1a26 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/brewclient/BrewNVR.java @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.brewclient; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode +public class BrewNVR { + + private final String name; + private final String version; + private final String release; + + public BrewNVR(String name, String version, String release) { + this.name = name; + this.version = version.replace('-', '_'); + this.release = release.replace('-', '_'); + } + + public String getKojiName() { + return name.replace(':', '-'); + } + + @JsonIgnore + public String getNVR() { + return getKojiName() + "-" + version + "-" + release; + } +} diff --git a/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslator.java b/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslator.java new file mode 100644 index 00000000..717a0b45 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslator.java @@ -0,0 +1,64 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.brewclient; + +import com.redhat.red.build.koji.model.json.KojiImport; +import org.jboss.pnc.causeway.CausewayException; +import org.jboss.pnc.causeway.pncclient.BuildArtifacts; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; +import org.jboss.pnc.causeway.source.RenamedSources; +import org.jboss.pnc.dto.ArtifactRef; +import org.jboss.pnc.dto.Build; +import org.jboss.pnc.enums.BuildType; +import org.jboss.pnc.restclient.util.ArtifactUtil; + +import java.io.InputStream; + +/** + * + * @author Honza Brázdil <jbrazdil@redhat.com> + */ +public interface BuildTranslator { + + ImportFileGenerator getImportFiles( + BuildArtifacts artifacts, + BurnAfterReadingFile sources, + BurnAfterReadingFile buildLog, + BurnAfterReadingFile alignLog) throws CausewayException; + + KojiImport translate( + BrewNVR nvr, + Build build, + BuildArtifacts artifacts, + RenamedSources sources, + BurnAfterReadingFile buildLog, + BurnAfterReadingFile alignLog, + String username) throws CausewayException; + + RenamedSources getSources(Build build, BuildArtifacts artifacts, InputStream sourcesStream) + throws CausewayException; + + String getSourcesDeployPath(Build build, BuildArtifacts artifacts) throws CausewayException; + + static String guessVersion(Build build, BuildArtifacts artifacts) throws CausewayException { + BuildType buildType = build.getBuildConfigRevision().getBuildType(); + + return artifacts.getBuildArtifacts() + .stream() + .map(artifact -> extractVersion(buildType, artifact)) + .findAny() + .orElseThrow( + () -> new CausewayException( + "Build version or BuildType (MVN,NPM...) not specified and couldn't determine any from artifacts.")); + } + + private static String extractVersion(BuildType buildType, ArtifactRef artifact) { + return switch (buildType) { + case MVN, SBT, GRADLE -> ArtifactUtil.parseMavenCoordinates(artifact).getVersionString(); + case NPM -> ArtifactUtil.parseNPMCoordinates(artifact).getVersion().toString(); + }; + } + +} diff --git a/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslatorImpl.java b/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslatorImpl.java new file mode 100644 index 00000000..94921c03 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/brewclient/BuildTranslatorImpl.java @@ -0,0 +1,382 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.brewclient; + +import com.github.zafarkhaja.semver.Version; +import com.redhat.red.build.koji.model.json.BuildContainer; +import com.redhat.red.build.koji.model.json.BuildDescription; +import com.redhat.red.build.koji.model.json.BuildOutput; +import com.redhat.red.build.koji.model.json.BuildRoot; +import com.redhat.red.build.koji.model.json.BuildTool; +import com.redhat.red.build.koji.model.json.FileBuildComponent; +import com.redhat.red.build.koji.model.json.KojiImport; +import com.redhat.red.build.koji.model.json.StandardArchitecture; +import com.redhat.red.build.koji.model.json.StandardOutputType; +import com.redhat.red.build.koji.model.json.VerificationException; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import org.commonjava.atlas.maven.ident.ref.ProjectVersionRef; +import org.commonjava.atlas.maven.ident.ref.SimpleArtifactRef; +import org.commonjava.atlas.maven.ident.ref.SimpleProjectVersionRef; +import org.commonjava.atlas.npm.ident.ref.NpmPackageRef; +import org.jboss.pnc.causeway.CausewayConfig; +import org.jboss.pnc.causeway.CausewayException; +import org.jboss.pnc.causeway.CausewayFailure; +import org.jboss.pnc.causeway.ErrorMessages; +import org.jboss.pnc.causeway.pncclient.BuildArtifacts; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; +import org.jboss.pnc.causeway.source.RenamedSources; +import org.jboss.pnc.causeway.source.SourceRenamer; +import org.jboss.pnc.dto.ArtifactRef; +import org.jboss.pnc.enums.BuildType; +import org.jboss.pnc.restclient.util.ArtifactUtil; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import static org.jboss.pnc.api.constants.Attributes.BUILD_BREW_NAME; +import static org.jboss.pnc.api.constants.Attributes.BUILD_BREW_VERSION; + +/** + * + * @author Honza Brázdil <jbrazdil@redhat.com> + */ +@ApplicationScoped +public class BuildTranslatorImpl implements BuildTranslator { + private static final String CONTENT_GENERATOR_NAME = "Project Newcastle"; + public static final String PNC = "PNC"; + private static final String MD5 = "md5"; + + @Inject + CausewayConfig config; + + @Inject + SourceRenamer renamer; + + @Override + public KojiImport translate( + BrewNVR nvr, + org.jboss.pnc.dto.Build build, + BuildArtifacts artifacts, + RenamedSources sources, + BurnAfterReadingFile buildLog, + BurnAfterReadingFile alignLlog, + String username) throws CausewayException { + String externalBuildId = String.valueOf(build.getId()); + String externalBuildUrl = null; + String externalBuildsUrl = config.pnc().buildsURL(); + if (externalBuildsUrl != null) { + externalBuildUrl = externalBuildsUrl + externalBuildId; + } + KojiImport.Builder builder = new KojiImport.Builder(); + BuildDescription.Builder descriptionBuilder = builder + .withNewBuildDescription(nvr.getKojiName(), nvr.getVersion(), nvr.getRelease()) + .withStartTime(Date.from(build.getStartTime())) + .withEndTime(Date.from(build.getEndTime())) + .withBuildSource(normalizeScmUrl(build.getScmUrl()), build.getScmRevision()) + .withExternalBuildId(externalBuildId) + .withExternalBuildUrl(externalBuildUrl) + .withBuildSystem(PNC); + setBuildType(descriptionBuilder, build, artifacts); + if (build.getScmTag() != null) { + descriptionBuilder.withSCMTag(build.getScmTag()); + } + + int buildRootId = 42; + BuildRoot.Builder buildRootBuilder = builder.withNewBuildRoot(buildRootId) + .withContentGenerator(CONTENT_GENERATOR_NAME, config.pnc().systemVersion()) + .withContainer(getContainer(build)) + .withHost(build.getEnvironment().getAttributes().get("OS"), StandardArchitecture.noarch); + + Map tools = new HashMap<>(build.getEnvironment().getAttributes()); + addTool(buildRootBuilder, build.getBuildConfigRevision().getBuildType(), tools, build.getEnvironment().getId()); + addTools(buildRootBuilder, tools); + addDependencies(artifacts.getDependencies(), buildRootBuilder, build.getBuildConfigRevision().getBuildType()); + addBuiltArtifacts( + artifacts.getBuildArtifacts(), + builder, + buildRootId, + build.getBuildConfigRevision().getBuildType()); + addLog(buildLog, builder, buildRootId); + addLog(alignLlog, builder, buildRootId); + addSources(sources, builder, buildRootId); + + KojiImport translatedBuild = buildTranslatedBuild(builder); + translatedBuild.getBuild().getExtraInfo().setImportInitiator(username); + return translatedBuild; + } + + private String normalizeScmUrl(final String url) { + if (url.startsWith("http")) { + return "git+" + url; + } + return url; + } + + private void addLog(BurnAfterReadingFile log, KojiImport.Builder builder, int buildRootId) { + builder.withNewOutput(buildRootId, log.getName()) + .withOutputType(StandardOutputType.log) + .withFileSize(log.getSize()) + .withArch(StandardArchitecture.noarch) + .withChecksum(MD5, log.getMd5()); + } + + private void addSources(RenamedSources sources, KojiImport.Builder builder, int buildRootId) { + if (sources != null) { + BuildOutput.Builder outputBuilder = builder.withNewOutput(buildRootId, sources.getName()) + .withFileSize(sources.getSize()) + .withArch(StandardArchitecture.noarch) + .withChecksum(MD5, sources.getMd5()); + RenamedSources.ArtifactType artifactType = sources.getArtifactType(); + if (artifactType.isMavenType()) { + outputBuilder.withMavenInfoAndType(artifactType.getMavenInfoAndType()); + } else if (artifactType.isNPMType()) { + outputBuilder.withNpmInfoAndType(artifactType.getNpmInfoAndType()); + } else { + throw new IllegalArgumentException(ErrorMessages.unknownArtifactType()); + } + } + } + + private void addDependencies( + List dependencies, + BuildRoot.Builder buildRootBuilder, + BuildType buildType) throws CausewayException { + for (ArtifactRef artifact : dependencies) { + FileBuildComponent.Builder componentBuilder = buildRootBuilder + .withFileComponent(stripLeadingSlash(artifact.getDeployPath())); + componentBuilder.withChecksum(MD5, artifact.getMd5()); + + switch (buildType) { + case GRADLE: + case NPM: + case SBT: + case MVN: { + componentBuilder.withFileSize(artifact.getSize()); + break; + } + default: { + throw new IllegalArgumentException(ErrorMessages.unknownArtifactType()); + } + } + } + } + + public static String stripLeadingSlash(String deployPath) { + if (deployPath.startsWith("/")) + return deployPath.substring(1); + return deployPath; + } + + private void addBuiltArtifacts( + List buildArtifacts, + KojiImport.Builder builder, + int buildRootId, + BuildType buildType) throws CausewayException { + for (ArtifactRef artifact : buildArtifacts) { + BuildOutput.Builder outputBuilder = builder + .withNewOutput(buildRootId, stripLeadingSlash(artifact.getDeployPath())) + .withArch(StandardArchitecture.noarch) + .withChecksum(MD5, artifact.getMd5()); + + switch (buildType) { + case GRADLE: + case SBT: + case MVN: { + SimpleArtifactRef ref = ArtifactUtil.parseMavenCoordinates(artifact); + outputBuilder.withFileSize(artifact.getSize()); + outputBuilder.withMavenInfoAndType(ref); + break; + } + case NPM: { + NpmPackageRef ref = ArtifactUtil.parseNPMCoordinates(artifact); + outputBuilder.withFileSize(artifact.getSize()); + outputBuilder.withNpmInfoAndType(ref); + break; + } + default: { + throw new IllegalArgumentException(ErrorMessages.unknownArtifactType()); + } + } + } + } + + private BuildContainer getContainer(org.jboss.pnc.dto.Build buildRecord) { + return switch (buildRecord.getEnvironment().getSystemImageType()) { + case DOCKER_IMAGE -> new BuildContainer("docker", "noarch"); + default -> throw new IllegalArgumentException(ErrorMessages.unknownSystemImageType()); + }; + } + + @Override + public ImportFileGenerator getImportFiles( + BuildArtifacts artifacts, + BurnAfterReadingFile sources, + BurnAfterReadingFile buildLog, + BurnAfterReadingFile alignLog) throws CausewayException { + try { + ImportFileGenerator ret = new ImportFileGenerator(sources, buildLog, alignLog); + for (ArtifactRef artifact : artifacts.getBuildArtifacts()) { + ret.addUrl( + artifact.getId(), + artifact.getDeployUrl(), + stripLeadingSlash(artifact.getDeployPath()), + artifact.getSize()); + } + return ret; + } catch (MalformedURLException ex) { + throw new CausewayException(ErrorMessages.failedToParseArtifactURL(ex), ex); + } + } + + @Override + public RenamedSources getSources(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts, InputStream sources) + throws CausewayException { + return buildTypeSwitch( + build, + artifacts, + (gav) -> renamer.repackMaven(sources, gav.getGroupId(), gav.getArtifactId(), gav.getVersionString()), + (npmPackage) -> renamer + .repackNPM(sources, npmPackage.getName(), npmPackage.getVersion().getNormalVersion())); + } + + @Override + public String getSourcesDeployPath(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts) + throws CausewayException { + return buildTypeSwitch( + build, + artifacts, + (gav) -> renamer.getMavenDeployPath(gav.getGroupId(), gav.getArtifactId(), gav.getVersionString()), + (npmPackage) -> renamer + .getNPMDeployPath(npmPackage.getName(), npmPackage.getVersion().getNormalVersion())); + } + + private KojiImport buildTranslatedBuild(KojiImport.Builder builder) throws CausewayException { + final KojiImport translatedBuild; + try { + translatedBuild = builder.build(); + } catch (VerificationException ex) { + throw new CausewayException(ErrorMessages.failureWhileBuildingKojiImport(ex), ex); + } + return translatedBuild; + } + + private ProjectVersionRef buildRootToGAV(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts) + throws CausewayException { + String brewName = build.getAttributes().get(BUILD_BREW_NAME); + if (brewName == null) { + throw new CausewayFailure(ErrorMessages.missingBrewNameAttributeInMavenBuild()); + } + String[] splittedName = brewName.split(":"); + if (splittedName.length != 2) { + throw new IllegalArgumentException(ErrorMessages.illegalMavenBrewName(brewName)); + } + String version = build.getAttributes().get(BUILD_BREW_VERSION); + if (version == null) { + version = BuildTranslator.guessVersion(build, artifacts); + } + return new SimpleProjectVersionRef(splittedName[0], splittedName[1], version); + } + + private NpmPackageRef buildRootToNV(org.jboss.pnc.dto.Build build, BuildArtifacts artifacts) + throws CausewayException { + if (!build.getAttributes().containsKey(BUILD_BREW_NAME)) { + throw new CausewayFailure(ErrorMessages.missingBrewNameAttributeInBuild()); + } + String name = build.getAttributes().get(BUILD_BREW_NAME); + String version = build.getAttributes().get(BUILD_BREW_VERSION); + if (version == null) { + version = BuildTranslator.guessVersion(build, artifacts); + } + return new NpmPackageRef(name, Version.valueOf(version)); + } + + private void addTools(BuildRoot.Builder buildRootBuilder, Map tools) { + for (Map.Entry e : tools.entrySet()) { + if (!config.pnc().ignoredTools().contains(e.getKey())) { + buildRootBuilder.withTool(e.getKey(), e.getValue()); + } + } + } + + private void setBuildType( + BuildDescription.Builder buildDescription, + org.jboss.pnc.dto.Build build, + BuildArtifacts artifacts) throws CausewayException { + buildTypeSwitch(build, artifacts, buildDescription::withMavenInfoAndType, buildDescription::withNpmInfoAndType); + } + + private void addTool( + BuildRoot.Builder buildRootBuilder, + BuildType buildType, + Map tools, + String envID) throws CausewayException { + switch (buildType) { + case MVN: + buildRootBuilder.withTool(getTool("JDK", tools, envID)); + buildRootBuilder.withTool(getTool("MAVEN", tools, envID)); + break; + case SBT: + buildRootBuilder.withTool(getTool("SBT", tools, envID)); + break; + case GRADLE: + buildRootBuilder.withTool(getTool("GRADLE", tools, envID)); + break; + case NPM: + buildRootBuilder.withTool(getTool("NPM", tools, envID)); + break; + default: + throw new IllegalArgumentException(ErrorMessages.unsupportedBuildType(buildType)); + } + } + + private BuildTool getTool(String name, Map tools, String envID) { + String version = tools.remove(name); + if (version == null) { + for (Iterator> it = tools.entrySet().iterator(); it.hasNext();) { + Map.Entry e = it.next(); + if (e.getKey().equalsIgnoreCase(name)) { + if (version != null) { + throw new IllegalArgumentException(ErrorMessages.environmentWithMultipleVersions(envID, name)); + } + version = e.getValue(); + it.remove(); + } + } + if (version == null) { + throw new IllegalArgumentException(ErrorMessages.environmentWithoutVersion(envID, name)); + } + } + return new BuildTool(name, version); + } + + private T buildTypeSwitch( + org.jboss.pnc.dto.Build build, + BuildArtifacts artifacts, + CausewayFunction mavenConsumer, + CausewayFunction npmConsumer) throws CausewayException { + BuildType buildType = build.getBuildConfigRevision().getBuildType(); + return switch (buildType) { + case MVN, SBT, GRADLE -> { + ProjectVersionRef gav = buildRootToGAV(build, artifacts); + yield mavenConsumer.apply(gav); + } + case NPM -> { + NpmPackageRef npmPackage = buildRootToNV(build, artifacts); + yield npmConsumer.apply(npmPackage); + } + }; + } + + @FunctionalInterface + private interface CausewayFunction { + R apply(T o) throws CausewayException; + } +} diff --git a/core/src/main/java/org/jboss/pnc/causeway/brewclient/ImportFileGenerator.java b/src/main/java/org/jboss/pnc/causeway/brewclient/ImportFileGenerator.java similarity index 63% rename from core/src/main/java/org/jboss/pnc/causeway/brewclient/ImportFileGenerator.java rename to src/main/java/org/jboss/pnc/causeway/brewclient/ImportFileGenerator.java index 2a75c731..45d4e41a 100644 --- a/core/src/main/java/org/jboss/pnc/causeway/brewclient/ImportFileGenerator.java +++ b/src/main/java/org/jboss/pnc/causeway/brewclient/ImportFileGenerator.java @@ -1,53 +1,44 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - *

- * 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. +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 */ package org.jboss.pnc.causeway.brewclient; import com.redhat.red.build.koji.model.ImportFile; - -import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.jboss.pnc.causeway.ErrorMessages; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; +import org.jboss.pnc.common.log.MDCUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Supplier; -import lombok.extern.slf4j.Slf4j; - -import org.jboss.pnc.causeway.ErrorMessages; -import org.jboss.pnc.causeway.source.RenamedSources; -import org.jboss.pnc.common.log.MDCUtils; - /** * @author Honza Brázdil <jbrazdil@redhat.com> */ @Slf4j -public abstract class ImportFileGenerator implements Iterable> { +public class ImportFileGenerator implements Iterable> { + private static final Logger userLog = LoggerFactory.getLogger("org.jboss.pnc._userlog_.brew-push"); protected final Set artifacts = new HashSet<>(); - protected final RenamedSources sources; + protected final List files = new ArrayList<>(); protected final Map paths = new HashMap<>(); - public ImportFileGenerator(RenamedSources sources) { - this.sources = sources; + public ImportFileGenerator(BurnAfterReadingFile... files) { + this.files.addAll(Arrays.asList(files)); } /** @@ -74,33 +65,32 @@ public String getId(String path) { return paths.get(path); } - @Data - protected static class Artifact { - private final String id; - private final URL url; - private final String filePath; - private final long size; + @Override + public Iterator> iterator() { + return new ImportFileIterator(); + } + + private record Artifact(String id, URL url, String filePath, long size) { } - protected abstract class ImportFileIterator implements Iterator> { + private class ImportFileIterator implements Iterator> { - private Iterator it; - private boolean sourcesGiven; + private final Iterator it; + private int nextFile = 0; - protected ImportFileIterator(Iterator it) { - this.it = it; - this.sourcesGiven = sources == null; + protected ImportFileIterator() { + this.it = artifacts.iterator(); } private ImportFileSupplier getNext() { Artifact artifact = it.next(); - log.info("Reading file {} from {}", artifact.getFilePath(), artifact.getUrl()); + userLog.info("Reading file {} from {}", artifact.filePath(), artifact.url()); return new ImportFileSupplier(artifact); } @Override public boolean hasNext() { - if (!sourcesGiven) { + if (nextFile < files.size()) { return true; } return it.hasNext(); @@ -108,11 +98,11 @@ public boolean hasNext() { @Override public Supplier next() { - if (!sourcesGiven) { - sourcesGiven = true; + if (nextFile < files.size()) { + BurnAfterReadingFile file = files.get(nextFile++); return () -> { try { - return new ImportFile(sources.getName(), sources.read(), sources.getSize()); + return new ImportFile(file.getName(), file.read(), file.getSize()); } catch (IOException ex) { throw new RuntimeException(ex); } @@ -122,7 +112,7 @@ public Supplier next() { } } - protected static class ImportFileSupplier implements Supplier { + private static class ImportFileSupplier implements Supplier { private final Artifact artifact; @@ -133,7 +123,7 @@ public ImportFileSupplier(Artifact artifact) { @Override public ImportFile get() { try { - HttpURLConnection connection = (HttpURLConnection) artifact.getUrl().openConnection(); + HttpURLConnection connection = (HttpURLConnection) artifact.url().openConnection(); try { MDCUtils.getHeadersFromMDC().forEach(connection::addRequestProperty); connection.setRequestMethod("GET"); @@ -144,7 +134,7 @@ public ImportFile get() { throw new RuntimeException(ErrorMessages.failedToObtainArtifact(responseCode, responseMessage)); } InputStream stream = connection.getInputStream(); - return new ImportFile(artifact.getFilePath(), stream, artifact.getSize()); + return new ImportFile(artifact.filePath(), stream, artifact.size()); } catch (RuntimeException ex) { connection.disconnect(); throw ex; diff --git a/src/main/java/org/jboss/pnc/causeway/brewclient/KojiProducer.java b/src/main/java/org/jboss/pnc/causeway/brewclient/KojiProducer.java new file mode 100644 index 00000000..1e1009eb --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/brewclient/KojiProducer.java @@ -0,0 +1,82 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.brewclient; + +import com.redhat.red.build.koji.KojiClient; +import com.redhat.red.build.koji.KojiClientException; +import com.redhat.red.build.koji.config.KojiConfig; +import com.redhat.red.build.koji.config.SimpleKojiConfigBuilder; +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Produces; +import jakarta.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.commonjava.util.jhttpc.auth.MemoryPasswordManager; +import org.commonjava.util.jhttpc.auth.PasswordManager; +import org.commonjava.util.jhttpc.auth.PasswordType; +import org.eclipse.microprofile.context.ManagedExecutor; +import org.jboss.pnc.causeway.CausewayConfig; +import org.jboss.pnc.causeway.ErrorMessages; +import java.io.Closeable; + +@ApplicationScoped +@Slf4j +public class KojiProducer implements Closeable { + + private static final String KOJI_SITE_ID = "koji"; + + @Inject + CausewayConfig config; + + @Inject + ManagedExecutor executorService; + + private KojiClient koji; + + private final PasswordManager passwords = new MemoryPasswordManager(); + + private synchronized void setupKoji() { + if (koji != null) { + return; + } + passwords.bind(config.koji().clientCertificatePassword(), KOJI_SITE_ID, PasswordType.KEY); + + log.warn("config.koji().clientKeyCertificateFile(): " + config.koji().clientKeyCertificateFile()); + + SimpleKojiConfigBuilder builder = new SimpleKojiConfigBuilder(); + builder.withKojiSiteId(KOJI_SITE_ID) + .withKojiURL(config.koji().url()) + .withClientKeyCertificateFile(config.koji().clientKeyCertificateFile()) + .withKojiClientCertificatePassword(config.koji().clientCertificatePassword()) + .withServerCertificateFile("conf/ssl/server.pem")// config.koji().serverCertificateFile()) + .withTrustSelfSigned(config.koji().trustSelfSigned()) + .withTimeout(config.koji().timeout()) + .withConnectionPoolTimeout(config.koji().connectionPoolTimeout()) + .withMaxConnections(config.koji().connections()); + KojiConfig kc = builder.build(); + + try { + koji = new KojiClient(kc, passwords, executorService); + } catch (KojiClientException ex) { + throw new RuntimeException(ErrorMessages.canNotConnectToKoji(ex), ex); + } + } + + @PreDestroy + public void close() { + if (koji != null) { + koji.close(); + } + } + + @Produces + public KojiClient getKojiClient() { + if (koji == null) { + setupKoji(); + } + return koji; + } + +} diff --git a/src/main/java/org/jboss/pnc/causeway/ctl/ImportController.java b/src/main/java/org/jboss/pnc/causeway/ctl/ImportController.java new file mode 100644 index 00000000..5aee8060 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/ctl/ImportController.java @@ -0,0 +1,18 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.ctl; + +import org.jboss.pnc.api.causeway.dto.push.PushResult; + +/** + * + * @author Honza Brázdil <jbrazdil@redhat.com> + */ +public interface ImportController { + + PushResult importBuild(String buildId, String tagPrefix, boolean reimport, String username); + + void untagBuild(int brewBuildId, String tagPrefix); +} diff --git a/src/main/java/org/jboss/pnc/causeway/ctl/ImportControllerImpl.java b/src/main/java/org/jboss/pnc/causeway/ctl/ImportControllerImpl.java new file mode 100644 index 00000000..33605890 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/ctl/ImportControllerImpl.java @@ -0,0 +1,211 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.ctl; + +import com.redhat.red.build.koji.model.json.KojiImport; +import io.micrometer.core.annotation.Timed; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.instrumentation.annotations.SpanAttribute; +import io.opentelemetry.instrumentation.annotations.WithSpan; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.jboss.pnc.api.causeway.dto.push.PushResult; +import org.jboss.pnc.api.constants.MDCKeys; +import org.jboss.pnc.api.enums.ResultStatus; +import org.jboss.pnc.causeway.CausewayConfig; +import org.jboss.pnc.causeway.CausewayException; +import org.jboss.pnc.causeway.CausewayFailure; +import org.jboss.pnc.causeway.ErrorMessages; +import org.jboss.pnc.causeway.brewclient.BrewBuild; +import org.jboss.pnc.causeway.brewclient.BrewClient; +import org.jboss.pnc.causeway.brewclient.BrewNVR; +import org.jboss.pnc.causeway.brewclient.BuildTranslator; +import org.jboss.pnc.causeway.brewclient.ImportFileGenerator; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; +import org.jboss.pnc.causeway.impl.Meters; +import org.jboss.pnc.causeway.pncclient.BuildArtifacts; +import org.jboss.pnc.causeway.pncclient.PncClient; +import org.jboss.pnc.causeway.source.RenamedSources; +import org.jboss.pnc.dto.ArtifactRef; +import org.jboss.pnc.dto.Build; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.Optional; + +import static org.jboss.pnc.api.constants.Attributes.BUILD_BREW_NAME; +import static org.jboss.pnc.api.constants.Attributes.BUILD_BREW_VERSION; +import static org.jboss.pnc.causeway.impl.Meters.METRICS_IMPORT; +import static org.jboss.pnc.causeway.impl.Meters.METRICS_UNTAG; +import static org.jboss.pnc.enums.ArtifactQuality.BLACKLISTED; +import static org.jboss.pnc.enums.ArtifactQuality.DELETED; + +@Slf4j +@ApplicationScoped +public class ImportControllerImpl implements ImportController { + private static final Logger userLog = LoggerFactory.getLogger("org.jboss.pnc._userlog_.brew-push"); + private static final String BUILD_NOT_TAGGED = " but not previously tagged. Tagging now."; + private static final String BUILD_ALREADY_IMPORTED = "Build was already imported with id "; + @Inject + BrewClient brewClient; + + @Inject + PncClient pncClient; + + @Inject + CausewayConfig config; + + @Inject + BuildTranslator translator; + + @Inject + Meters meters; + + @Timed(value = METRICS_IMPORT) + @WithSpan(kind = SpanKind.CLIENT) + public PushResult importBuild( + @SpanAttribute(value = MDCKeys.BUILD_ID_KEY) String buildId, + @SpanAttribute(value = "tag") String tagPrefix, + @SpanAttribute(value = "reimport") boolean reimport, + @SpanAttribute(value = "username") String username) throws CausewayException { + + Build build = pncClient.findBuild(buildId); + BuildArtifacts artifacts = filterArtifacts(pncClient.findBuildArtifacts(buildId)); + if (artifacts.getBuildArtifacts().isEmpty()) { + userLog.info("PNC build {} doesn't contain any artifacts to import, skipping.", build.getId()); + return PushResult.builder().buildId(build.getId()).result(ResultStatus.SUCCESS).build(); + } + + if (!brewClient.tagsExists(tagPrefix)) { + throw new CausewayFailure(ErrorMessages.tagsAreMissingInKoji(tagPrefix, config.koji().url())); + } + + BrewBuild brewBuild = checkAndImport(tagPrefix, reimport, username, build, artifacts); + brewClient.tagBuild(tagPrefix, brewBuild); + + log.debug(brewClient.getBuildUrl(brewBuild.getId())); + return PushResult.builder() + .buildId(buildId) + .brewBuildId(brewBuild.getId()) + .brewBuildUrl(brewClient.getBuildUrl(brewBuild.getId())) + .result(ResultStatus.SUCCESS) + .build(); + } + + private BrewBuild checkAndImport( + String tagPrefix, + boolean reimport, + String username, + Build build, + BuildArtifacts artifacts) { + BrewNVR nvr = getNVR(build, artifacts); + userLog.info("Processing PNC build {} as {}.", build.getId(), nvr.getNVR()); + BrewBuild brewBuild = brewClient.findBrewBuildOfNVR(nvr); + + if (brewBuild == null) { + brewBuild = translateAndImport(build, artifacts, nvr, username); + userLog.info("Build imported with id " + brewBuild.getId() + "."); + } else { + if (reimport) { + int revision = 1; + while (brewBuild != null && brewClient.isBuildTagged(tagPrefix, brewBuild)) { + nvr = getNVR(nvr, ++revision); + brewBuild = brewClient.findBrewBuildOfNVR(nvr); + } + if (brewBuild == null) { + brewBuild = translateAndImport(build, artifacts, nvr, username); + userLog.info( + "Build was previously imported. Re-imported again with revision " + revision + + " and with id " + brewBuild.getId() + "."); + } else { + userLog.info(BUILD_ALREADY_IMPORTED + brewBuild.getId() + BUILD_NOT_TAGGED); + } + } else { + String message = BUILD_ALREADY_IMPORTED + brewBuild.getId(); + if (!brewClient.isBuildTagged(tagPrefix, brewBuild)) { + message += BUILD_NOT_TAGGED; + } + userLog.info(message); + } + } + return brewBuild; + } + + private BuildArtifacts filterArtifacts(BuildArtifacts artifacts) { + for (Iterator it = artifacts.getBuildArtifacts().iterator(); it.hasNext();) { + ArtifactRef artifact = it.next(); + if (artifact.getArtifactQuality() == BLACKLISTED || artifact.getArtifactQuality() == DELETED) { + it.remove(); + userLog.warn(ErrorMessages.badArtifactNotImported(artifact.getId())); + } + } + return artifacts; + } + + private BrewBuild translateAndImport(Build build, BuildArtifacts artifacts, BrewNVR nvr, String username) { + BurnAfterReadingFile buildLog = pncClient.getBuildLog(build.getId()); + BurnAfterReadingFile alignLog = pncClient.getAlignLog(build.getId()); + + RenamedSources sources = getSources(build, artifacts); + KojiImport kojiImport = translator.translate(nvr, build, artifacts, sources, buildLog, alignLog, username); + ImportFileGenerator importFiles = translator.getImportFiles(artifacts, sources, buildLog, alignLog); + BrewBuild brewBuild = brewClient.importBuild(nvr, kojiImport, importFiles); + + long artifactSize = artifacts.getBuildArtifacts().stream().mapToLong(ArtifactRef::getSize).sum(); + meters.recordArtifactsSize(artifactSize); + meters.recordArtifactsNumber(artifacts.getBuildArtifacts().size()); + meters.recordLogsSize(buildLog.getSize() + alignLog.getSize()); + meters.recordLogsNumber(2); + + return brewBuild; + } + + private RenamedSources getSources(Build build, BuildArtifacts artifacts) { + String sourcesDeployPath = translator.getSourcesDeployPath(build, artifacts); + Optional sourceJar = artifacts.getBuildArtifacts() + .stream() + .filter(a -> a.getDeployPath().equals(sourcesDeployPath)) + .findAny(); + if (sourceJar.isEmpty()) { + userLog.info("Sources at '{}' not present, generating sources file.", sourcesDeployPath); + try (InputStream sourcesStream = pncClient.getSources(build.getId())) { + return translator.getSources(build, artifacts, sourcesStream); + } catch (IOException ex) { + throw new CausewayException(ErrorMessages.failedToDownloadSources(ex), ex); + } + } + return null; + } + + @Override + @Timed(value = METRICS_UNTAG) + @WithSpan(kind = SpanKind.CLIENT) + public void untagBuild(@SpanAttribute("build") int brewBuildId, @SpanAttribute("tag") String tagPrefix) { + BrewBuild build = brewClient.findBrewBuild(brewBuildId); + if (build == null) { + throw new CausewayFailure(ErrorMessages.brewBuildNotFound(brewBuildId)); + } + brewClient.untagBuild(tagPrefix, build); + } + + BrewNVR getNVR(Build build, BuildArtifacts artifacts) throws CausewayException { + if (!build.getAttributes().containsKey(BUILD_BREW_NAME)) { + throw new CausewayFailure(ErrorMessages.missingBrewNameAttributeInBuild()); + } + String version = build.getAttributes().get(BUILD_BREW_VERSION); + if (version == null) { + version = BuildTranslator.guessVersion(build, artifacts); + } + return new BrewNVR(build.getAttributes().get(BUILD_BREW_NAME), version, "1"); + } + + BrewNVR getNVR(BrewNVR nvr, int revision) { + return new BrewNVR(nvr.getName(), nvr.getVersion(), Integer.toString(revision)); + } +} diff --git a/src/main/java/org/jboss/pnc/causeway/exceptionmappers/AllOtherExceptionsMapper.java b/src/main/java/org/jboss/pnc/causeway/exceptionmappers/AllOtherExceptionsMapper.java new file mode 100644 index 00000000..93e0dfce --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/exceptionmappers/AllOtherExceptionsMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.exceptionmappers; + +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.ext.ExceptionMapper; +import jakarta.ws.rs.ext.Provider; +import lombok.extern.slf4j.Slf4j; +import org.jboss.pnc.api.dto.ErrorResponse; + +@Provider +@Slf4j +public class AllOtherExceptionsMapper implements ExceptionMapper { + + @Override + public Response toResponse(Throwable exception) { + log.error("Unexpected error occurred: ", exception); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(new ErrorResponse(exception)) + .type(MediaType.APPLICATION_JSON_TYPE) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/pnc/causeway/exceptionmappers/ValidationExceptionMapper.java b/src/main/java/org/jboss/pnc/causeway/exceptionmappers/ValidationExceptionMapper.java new file mode 100644 index 00000000..012e2819 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/exceptionmappers/ValidationExceptionMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.exceptionmappers; + +import jakarta.validation.ValidationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.ext.ExceptionMapper; +import jakarta.ws.rs.ext.Provider; +import lombok.extern.slf4j.Slf4j; +import org.jboss.pnc.api.dto.ErrorResponse; + +@Provider +@Slf4j +public class ValidationExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(ValidationException exception) { + log.debug("Bad format of the request: {}", exception.getMessage()); + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse(exception)) + .type(MediaType.APPLICATION_JSON_TYPE) + .build(); + } +} diff --git a/src/main/java/org/jboss/pnc/causeway/exceptionmappers/WebApplicationExceptionMapper.java b/src/main/java/org/jboss/pnc/causeway/exceptionmappers/WebApplicationExceptionMapper.java new file mode 100644 index 00000000..38cb2716 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/exceptionmappers/WebApplicationExceptionMapper.java @@ -0,0 +1,34 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.exceptionmappers; + +import com.fasterxml.jackson.databind.JsonMappingException; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.ext.ExceptionMapper; +import jakarta.ws.rs.ext.Provider; +import lombok.extern.slf4j.Slf4j; +import org.jboss.pnc.api.dto.ErrorResponse; + +@Provider +@Slf4j +public class WebApplicationExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(WebApplicationException exception) { + if (exception.getResponse().getStatus() == 400) { + Throwable cause = exception.getCause(); + if (cause instanceof JsonMappingException) { + log.debug("Bad format of the request: {}", cause.getMessage()); + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse(cause)) + .type(MediaType.APPLICATION_JSON_TYPE) + .build(); + } + } + return exception.getResponse(); + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/pnc/causeway/impl/BurnAfterReadingFile.java b/src/main/java/org/jboss/pnc/causeway/impl/BurnAfterReadingFile.java new file mode 100644 index 00000000..b4e0c62e --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/impl/BurnAfterReadingFile.java @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.impl; + +import lombok.Getter; +import org.jboss.pnc.causeway.ErrorMessages; + +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class BurnAfterReadingFile { + protected final Path file; + @Getter + protected final int size; + @Getter + protected final String name; + @Getter + protected final String md5; + private boolean read = false; + + public BurnAfterReadingFile(Path file, String name, String md5) throws IOException { + this.file = file; + this.size = (int) Files.size(file); + this.name = name; + this.md5 = md5; + } + + public static BurnAfterReadingFile fromInputStream(String name, InputStream is) + throws IOException, NoSuchAlgorithmException { + Path tempFile = Files.createTempFile("barf-", name); + + MessageDigest md5Digest = MessageDigest.getInstance("MD5"); + try (is; DigestOutputStream outputStream = new DigestOutputStream(Files.newOutputStream(tempFile), md5Digest)) { + is.transferTo(outputStream); + } + + BigInteger bi = new BigInteger(1, md5Digest.digest()); + String md5Hash = String.format("%032x", bi); + + return new BurnAfterReadingFile(tempFile, name, md5Hash); + } + + public InputStream read() throws IOException { + if (read) { + throw new IllegalStateException(ErrorMessages.sourcesFileWasAlreadyRead()); + } + read = true; + return Files.newInputStream(file, StandardOpenOption.DELETE_ON_CLOSE); + } +} diff --git a/src/main/java/org/jboss/pnc/causeway/impl/Meters.java b/src/main/java/org/jboss/pnc/causeway/impl/Meters.java new file mode 100644 index 00000000..c3f2b859 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/impl/Meters.java @@ -0,0 +1,66 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.impl; + +import io.micrometer.core.instrument.DistributionSummary; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.BaseUnits; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class Meters { + + public static final String METRICS_IMPORT = "causeway.import.build"; + public static final String METRICS_UNTAG = "causeway.untag.build"; + + private static final String METRICS_PUSHED_FILE_TO_BREW_KEY = "pushed-file-to-brew"; + private static final String METRICS_LOGS_NUMBER_KEY = METRICS_PUSHED_FILE_TO_BREW_KEY + ".logs.number"; + private static final String METRICS_LOGS_SIZE_KEY = METRICS_PUSHED_FILE_TO_BREW_KEY + ".logs.size"; + private static final String METRICS_ARTIFACTS_NUMBER_KEY = METRICS_PUSHED_FILE_TO_BREW_KEY + ".artifacts.number"; + private static final String METRICS_ARTIFACTS_SIZE_KEY = METRICS_PUSHED_FILE_TO_BREW_KEY + ".artifacts.size"; + + private final DistributionSummary artifactsSize; + private final DistributionSummary artifactsNumber; + private final DistributionSummary logsSize; + private final DistributionSummary logsNumber; + + @Inject + public Meters(MeterRegistry registry) { + artifactsSize = DistributionSummary.builder(METRICS_ARTIFACTS_SIZE_KEY) + .baseUnit(BaseUnits.BYTES) + .description("Size of uploaded artifacts") + .register(registry); + artifactsNumber = DistributionSummary.builder(METRICS_ARTIFACTS_NUMBER_KEY) + .baseUnit(BaseUnits.FILES) + .description("Number of uploaded artifacts") + .register(registry); + + logsSize = DistributionSummary.builder(METRICS_LOGS_SIZE_KEY) + .baseUnit(BaseUnits.BYTES) + .description("Size of uploaded logs") + .register(registry); + logsNumber = DistributionSummary.builder(METRICS_LOGS_NUMBER_KEY) + .baseUnit(BaseUnits.FILES) + .description("Number of uploaded logs") + .register(registry); + } + + public void recordLogsNumber(long number) { + logsNumber.record(number); + } + + public void recordLogsSize(long size) { + logsSize.record(size); + } + + public void recordArtifactsNumber(long number) { + artifactsNumber.record(number); + } + + public void recordArtifactsSize(long size) { + artifactsSize.record(size); + } +} diff --git a/src/main/java/org/jboss/pnc/causeway/impl/Producers.java b/src/main/java/org/jboss/pnc/causeway/impl/Producers.java new file mode 100644 index 00000000..27bf4c0f --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/impl/Producers.java @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.impl; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.quarkus.oidc.client.OidcClient; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Produces; +import jakarta.inject.Inject; +import org.jboss.pnc.causeway.CausewayConfig; +import org.jboss.pnc.common.concurrent.HeartbeatScheduler; +import org.jboss.pnc.common.http.PNCHttpClient; + +import java.time.Duration; +import java.util.concurrent.ScheduledExecutorService; + +@ApplicationScoped +public class Producers { + private final HeartbeatScheduler heartbeatScheduler; + private final PNCHttpClient httpClient; + + @Inject + public Producers( + ScheduledExecutorService executorService, + OidcClient oidcClient, + CausewayConfig causewayConfig, + ObjectMapper objectMapper) { + httpClient = new PNCHttpClient(objectMapper, causewayConfig.httpClientConfig()); + httpClient + .setTokenSupplier(() -> oidcClient.getTokens().await().atMost(Duration.ofMinutes(1)).getAccessToken()); + heartbeatScheduler = new HeartbeatScheduler(executorService, httpClient); + } + + @Produces + public HeartbeatScheduler heartbeatScheduler() { + return heartbeatScheduler; + } + + @Produces + public PNCHttpClient pncHttpClient() { + return httpClient; + } +} diff --git a/src/main/java/org/jboss/pnc/causeway/logging/LoggingFilter.java b/src/main/java/org/jboss/pnc/causeway/logging/LoggingFilter.java new file mode 100644 index 00000000..280b703f --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/logging/LoggingFilter.java @@ -0,0 +1,60 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.logging; + +import io.opentelemetry.api.trace.Span; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerRequestFilter; +import jakarta.ws.rs.container.ContainerResponseContext; +import jakarta.ws.rs.container.ContainerResponseFilter; +import jakarta.ws.rs.core.Request; +import jakarta.ws.rs.core.UriInfo; +import jakarta.ws.rs.ext.Provider; +import org.jboss.pnc.api.constants.MDCKeys; +import org.jboss.pnc.common.log.MDCUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +/** + * @author Matej Lazar + */ +@Provider +public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { + + private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class); + private static final String REQUEST_EXECUTION_START = "request-execution-start"; + + @Override + public void filter(ContainerRequestContext requestContext) { + + requestContext.setProperty(REQUEST_EXECUTION_START, System.currentTimeMillis()); + MDCUtils.setMDCFromRequestContext(requestContext); + MDCUtils.addMDCFromOtelHeadersWithFallback(requestContext, Span.current().getSpanContext(), false); + + UriInfo uriInfo = requestContext.getUriInfo(); + Request request = requestContext.getRequest(); + logger.info("Requested {} {}.", request.getMethod(), uriInfo.getRequestUri()); + } + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { + Long startTime = (Long) requestContext.getProperty(REQUEST_EXECUTION_START); + + String took; + if (startTime == null) { + took = "-1"; + } else { + took = Long.toString(System.currentTimeMillis() - startTime); + } + + try (MDC.MDCCloseable ignored = MDC.putCloseable(MDCKeys.REQUEST_TOOK, took); + MDC.MDCCloseable ignored2 = MDC + .putCloseable(MDCKeys.RESPONSE_STATUS, Integer.toString(responseContext.getStatus()));) { + logger.info("Completed {}, took: {}ms.", requestContext.getUriInfo().getPath(), took); + } + } + +} diff --git a/src/main/java/org/jboss/pnc/causeway/pncclient/BuildArtifacts.java b/src/main/java/org/jboss/pnc/causeway/pncclient/BuildArtifacts.java new file mode 100644 index 00000000..cc124813 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/pncclient/BuildArtifacts.java @@ -0,0 +1,24 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.pncclient; + +import lombok.Getter; +import org.jboss.pnc.dto.ArtifactRef; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public final class BuildArtifacts { + + private final List buildArtifacts; + private final List dependencies; + + public BuildArtifacts() { + buildArtifacts = new ArrayList<>(); + dependencies = new ArrayList<>(); + } + +} diff --git a/src/main/java/org/jboss/pnc/causeway/pncclient/PncClient.java b/src/main/java/org/jboss/pnc/causeway/pncclient/PncClient.java new file mode 100644 index 00000000..a1a7b5a7 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/pncclient/PncClient.java @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.pncclient; + +import org.jboss.pnc.causeway.CausewayException; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; +import org.jboss.pnc.dto.Build; + +import java.io.InputStream; + +/** + * + * @author Honza Brázdil <jbrazdil@redhat.com> + */ +public interface PncClient { + + BuildArtifacts findBuildArtifacts(String buildId) throws CausewayException; + + BurnAfterReadingFile getBuildLog(String buildId) throws CausewayException; + + BurnAfterReadingFile getAlignLog(String buildId) throws CausewayException; + + InputStream getSources(String id) throws CausewayException; + + Build findBuild(String buildId); + +} diff --git a/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientImpl.java b/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientImpl.java new file mode 100644 index 00000000..b9719b09 --- /dev/null +++ b/src/main/java/org/jboss/pnc/causeway/pncclient/PncClientImpl.java @@ -0,0 +1,140 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.pncclient; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.Response; +import lombok.extern.slf4j.Slf4j; +import org.jboss.pnc.causeway.CausewayConfig; +import org.jboss.pnc.causeway.CausewayException; +import org.jboss.pnc.causeway.ErrorMessages; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; +import org.jboss.pnc.client.BuildClient; +import org.jboss.pnc.client.Configuration; +import org.jboss.pnc.client.RemoteCollection; +import org.jboss.pnc.client.RemoteResourceException; +import org.jboss.pnc.dto.Artifact; +import org.jboss.pnc.dto.Build; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.NoSuchAlgorithmException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Optional; +import java.util.Scanner; + +/** + * Created by jdcasey on 2/9/16. + */ +@ApplicationScoped +@Slf4j +public class PncClientImpl implements PncClient { + + private final BuildClient buildClient; + + @Inject + public PncClientImpl(CausewayConfig config) { + URL url = config.pnc().url(); + Configuration clientConfig = Configuration.builder() + .host(url.getHost()) + .protocol(url.getProtocol()) + .pageSize(config.pnc().pageSize()) + .addDefaultMdcToHeadersMappings() + .port((url.getPort() != -1) ? url.getPort() : url.getDefaultPort()) + .build(); + + log.debug("Client config: " + clientConfig); + this.buildClient = new BuildClient(clientConfig); + } + + @Override + public Build findBuild(String buildId) throws CausewayException { + try { + log.debug("Getting build with id {} from PNC", buildId); + Build build = buildClient.getSpecific(buildId); + if (build == null) { + throw new CausewayException(ErrorMessages.pncBuildNotFound(buildId)); + } + return build; + } catch (RemoteResourceException ex) { + throw new CausewayException(ErrorMessages.errorReadingBuild(buildId, ex), ex); + } + } + + @Override + public BurnAfterReadingFile getBuildLog(String buildId) throws CausewayException { + Optional buildLog; + try { + log.debug("Getting build logs of build with id {} from PNC", buildId); + buildLog = buildClient.getBuildLogs(String.valueOf(buildId)); + InputStream logInput = buildLog + .orElseThrow(() -> new CausewayException(ErrorMessages.buildLogIsEmpty(buildId))); + return BurnAfterReadingFile.fromInputStream("build.log", logInput); + } catch (RemoteResourceException ex) { + throw new CausewayException(ErrorMessages.errorReadingBuildLog(buildId, ex), ex); + } catch (IOException | NoSuchAlgorithmException ex) { + throw new CausewayException(ErrorMessages.errorStoringBuildLog(buildId, ex), ex); + } + } + + @Override + public BurnAfterReadingFile getAlignLog(String buildId) throws CausewayException { + Optional buildLog; + try { + log.debug("Getting align logs of build with id {} from PNC", buildId); + buildLog = buildClient.getAlignLogs(String.valueOf(buildId)); + InputStream logInput = buildLog + .orElseThrow(() -> new CausewayException(ErrorMessages.buildLogIsEmpty(buildId))); + return BurnAfterReadingFile.fromInputStream("align.log", logInput); + } catch (RemoteResourceException ex) { + throw new CausewayException(ErrorMessages.errorReadingAlignLog(buildId, ex), ex); + } catch (IOException | NoSuchAlgorithmException ex) { + throw new CausewayException(ErrorMessages.errorStoringAlignLog(buildId, ex), ex); + } + } + + @Override + public InputStream getSources(String id) throws CausewayException { + try { + log.debug("Getting sources of build with id {} from PNC", id); + Response response = buildClient.getInternalScmArchiveLink(id); + try { + if (response.getStatus() >= 400) { + throw new CausewayException( + ErrorMessages.errorReadingBuildSources( + id, + response.getStatus(), + response.readEntity(String.class))); + } + return response.readEntity(InputStream.class); + } catch (RuntimeException ex) { + response.close(); + throw new CausewayException(ErrorMessages.errorReadingBuildSources(id, ex), ex); + } + } catch (RemoteResourceException ex) { + throw new CausewayException(ErrorMessages.errorReadingBuildSources(id, ex), ex); + } + } + + @Override + public BuildArtifacts findBuildArtifacts(String buildId) throws CausewayException { + try { + Collection builtArtifacts = buildClient.getBuiltArtifacts(buildId).getAll(); + Collection dependantArtifact = buildClient.getDependencyArtifacts(buildId).getAll(); + BuildArtifacts build = new BuildArtifacts(); + + build.getBuildArtifacts().addAll(builtArtifacts); + build.getDependencies().addAll(dependantArtifact); + + return build; + } catch (RemoteResourceException ex) { + throw new CausewayException(ErrorMessages.errorReadingBuildArtifacts(buildId, ex), ex); + } + } + +} diff --git a/core/src/main/java/org/jboss/pnc/causeway/source/RenamedSources.java b/src/main/java/org/jboss/pnc/causeway/source/RenamedSources.java similarity index 72% rename from core/src/main/java/org/jboss/pnc/causeway/source/RenamedSources.java rename to src/main/java/org/jboss/pnc/causeway/source/RenamedSources.java index 11331019..948b3cd0 100644 --- a/core/src/main/java/org/jboss/pnc/causeway/source/RenamedSources.java +++ b/src/main/java/org/jboss/pnc/causeway/source/RenamedSources.java @@ -1,47 +1,31 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ package org.jboss.pnc.causeway.source; +import com.github.zafarkhaja.semver.Version; import lombok.Getter; import org.commonjava.atlas.maven.ident.ref.SimpleArtifactRef; import org.commonjava.atlas.npm.ident.ref.NpmPackageRef; import org.jboss.pnc.causeway.ErrorMessages; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardOpenOption; import static org.jboss.pnc.causeway.source.SourceRenamer.ARTIFACT_CLASSIFIER; import static org.jboss.pnc.causeway.source.SourceRenamer.ARTIFACT_TYPE; -public class RenamedSources { - private final Path file; - @Getter - private final int size; - @Getter - private final String name; - @Getter - private final String md5; - private boolean read = false; +public class RenamedSources extends BurnAfterReadingFile { @Getter private final ArtifactType artifactType; public RenamedSources(Path file, String name, String md5, ArtifactType artifactType) throws IOException { - this.file = file; - this.name = name; - this.md5 = md5; - this.size = (int) Files.size(file); + super(file, name, md5); this.artifactType = artifactType; } - public InputStream read() throws IOException { - if (read) { - throw new IllegalStateException(ErrorMessages.sourcesFileWasAlreadyRead()); - } - read = true; - return Files.newInputStream(file, StandardOpenOption.DELETE_ON_CLOSE); - } - public static class ArtifactType { private final SimpleArtifactRef mavenInfoAndType; @@ -59,7 +43,7 @@ public ArtifactType(String groupId, String artifactId, String version) { public ArtifactType(String name, String version) { this.mavenInfoAndType = null; - this.npmInfoAndType = new NpmPackageRef(name + "-" + ARTIFACT_CLASSIFIER, version); + this.npmInfoAndType = new NpmPackageRef(name + "-" + ARTIFACT_CLASSIFIER, Version.valueOf(version)); } public boolean isMavenType() { diff --git a/core/src/main/java/org/jboss/pnc/causeway/source/SourceRenamer.java b/src/main/java/org/jboss/pnc/causeway/source/SourceRenamer.java similarity index 97% rename from core/src/main/java/org/jboss/pnc/causeway/source/SourceRenamer.java rename to src/main/java/org/jboss/pnc/causeway/source/SourceRenamer.java index e4b09278..fcea65ae 100644 --- a/core/src/main/java/org/jboss/pnc/causeway/source/SourceRenamer.java +++ b/src/main/java/org/jboss/pnc/causeway/source/SourceRenamer.java @@ -1,5 +1,20 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ package org.jboss.pnc.causeway.source; +import jakarta.enterprise.context.ApplicationScoped; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.compress.compressors.CompressorStreamFactory; +import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; +import org.apache.commons.io.IOUtils; +import org.jboss.pnc.causeway.CausewayException; +import org.jboss.pnc.causeway.ErrorMessages; + import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; @@ -11,17 +26,6 @@ import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import javax.enterprise.context.ApplicationScoped; - -import org.apache.commons.compress.archivers.tar.TarArchiveEntry; -import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; -import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; -import org.apache.commons.compress.compressors.CompressorException; -import org.apache.commons.compress.compressors.CompressorStreamFactory; -import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; -import org.apache.commons.io.IOUtils; -import org.jboss.pnc.causeway.CausewayException; -import org.jboss.pnc.causeway.ErrorMessages; @ApplicationScoped public class SourceRenamer { @@ -121,7 +125,7 @@ private void rewrite(InputStream input, OutputStream output, String name) throws throw new IllegalArgumentException(ErrorMessages.nonDirectoryInArchiveRoot()); } if (rootFound) { - throw new IllegalArgumentException(ErrorMessages.multipleDirectoriseInArchiveRoot()); + throw new IllegalArgumentException(ErrorMessages.multipleDirectoriesInArchiveRoot()); } rootFound = true; } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 00000000..66d2cab4 --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,41 @@ +# +# Copyright 2024 Red Hat, Inc. +# SPDX-License-Identifier: Apache-2.0 +# + +causeway: + koji: + + pnc: + builds-url: ${causeway.pnc.url}/../pnc-web/builds/ + system-version: 3 + +"%dev": + quarkus: + log: + category: + "org.jboss.pnc": + level: DEBUG + "org.commonjava.util.jhttpc.INTERNAL.conn": + level: WARN + causeway: + koji: + url: "http://localhost:${quarkus.wiremock.devservices.port}/kojihub" + web-url: "http://localhost:${quarkus.wiremock.devservices.port}/koji/buildinfo?buildID=" + client-key-certificate-file: src/test/resources/cert/snakeoil.pem + client-certificate-password: password +# server-certificate-file: src/test/resources/cert/snakeoil.pem + pnc: + url: "http://localhost:${quarkus.wiremock.devservices.port}/pnc-rest/rest" + + +"%test": + causeway: + koji: + url: "http://localhost:${quarkus.wiremock.devservices.port}/kojihub" + web-url: "http://localhost:${quarkus.wiremock.devservices.port}/koji/buildinfo?buildID=" + client-key-certificate-file: src/test/resources/cert/snakeoil.pem + client-certificate-password: password + # server-certificate-file: src/test/resources/cert/snakeoil.pem + pnc: + url: "http://localhost:${quarkus.wiremock.devservices.port}/pnc-rest/rest" diff --git a/src/main/templates/org/jboss/pnc/causeway/constants/BuildInformationConstants.java b/src/main/templates/org/jboss/pnc/causeway/constants/BuildInformationConstants.java new file mode 100644 index 00000000..7bc890be --- /dev/null +++ b/src/main/templates/org/jboss/pnc/causeway/constants/BuildInformationConstants.java @@ -0,0 +1,18 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.constants; + +/** + * The values in here are auto-generated from Maven plugin maven-replacer-plugin and the template is found in the + * template folder + * + * @author Dustin Kut Moy Cheung + */ +public final class BuildInformationConstants { + + public static final String VERSION = "@version@"; + public static final String COMMIT_HASH = "@commit-id@"; + public static final String BUILD_TIME = "@build-time@"; +} diff --git a/core/src/test/java/org/jboss/pnc/causeway/brewclient/ImportFileGeneratorTest.java b/src/test/java/org/jboss/pnc/causeway/brewclient/ImportFileGeneratorTest.java similarity index 64% rename from core/src/test/java/org/jboss/pnc/causeway/brewclient/ImportFileGeneratorTest.java rename to src/test/java/org/jboss/pnc/causeway/brewclient/ImportFileGeneratorTest.java index 4f8a3934..6cd244a0 100644 --- a/core/src/test/java/org/jboss/pnc/causeway/brewclient/ImportFileGeneratorTest.java +++ b/src/test/java/org/jboss/pnc/causeway/brewclient/ImportFileGeneratorTest.java @@ -1,20 +1,23 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ package org.jboss.pnc.causeway.brewclient; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - +import com.github.tomakehurst.wiremock.client.WireMock; +import com.redhat.red.build.koji.model.ImportFile; +import io.quarkiverse.wiremock.devservice.ConnectWireMock; +import io.quarkiverse.wiremock.devservice.WireMockConfigKey; +import io.quarkus.test.junit.QuarkusTest; +import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.pnc.causeway.source.RenamedSources; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.MalformedURLException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; @@ -24,20 +27,24 @@ import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.head; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import com.github.tomakehurst.wiremock.junit.WireMockRule; -import com.redhat.red.build.koji.model.ImportFile; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.fail; /** * * @author Honza Brázdil <jbrazdil@redhat.com> */ +@QuarkusTest +@ConnectWireMock public class ImportFileGeneratorTest { + WireMock wiremock; - @Rule - public WireMockRule wireMockRule = (new WireMockRule(8081)); - private static final String HOST = "http://localhost:8081"; + @ConfigProperty(name = WireMockConfigKey.PORT) + Integer port; + + private static final String HOST = "http://localhost:"; private static final String FIRST_PATH = "path/to/artifact.jar"; private static final String FIRST_LOCATION = "/api/" + FIRST_PATH; @@ -46,60 +53,55 @@ public class ImportFileGeneratorTest { private static final String NONEXISTING_PATH = "path/to/non-existing/artifact.jar"; private static final String NONEXISTING_LOCATION = "/api/" + NONEXISTING_PATH; private static final String LOG_PATH = "build.log"; - private static final String LOG_LOCATION = "/other-api/" + LOG_PATH; private static final String SOURCES_PATH = "sources.tar.gz"; private static final String FIRST_ARTIFACT = "First artifact"; private static final String SECOND_ARTIFACT = "This is second artifact"; private static final String BUILD_LOG = "foobar"; private static final String SOURCES = "Burn this after reading!"; - @Before + private String host() { + return HOST + port; + } + + @BeforeEach public void stubArtifacts() { - stubFor( + wiremock.register( get(urlEqualTo(FIRST_LOCATION)).willReturn( aResponse().withStatus(200) .withHeader("Content-Type", "text/plain") .withHeader("Content-Length", "14") .withBody(FIRST_ARTIFACT))); - stubFor( + wiremock.register( head(urlEqualTo(FIRST_LOCATION)) .willReturn(aResponse().withStatus(200).withHeader("Content-Type", "text/plain"))); - stubFor( + wiremock.register( get(urlEqualTo(SECOND_LOCATION)).willReturn( aResponse().withStatus(200) .withHeader("Content-Type", "text/plain") .withHeader("Content-Length", "23") .withBody(SECOND_ARTIFACT))); - stubFor( + wiremock.register( head(urlEqualTo(SECOND_LOCATION)) .willReturn(aResponse().withStatus(200).withHeader("Content-Type", "text/plain"))); - stubFor( - get(urlEqualTo(LOG_LOCATION)).willReturn( - aResponse().withStatus(200).withHeader("Content-Type", "text/plain").withBody(BUILD_LOG))); } - private RenamedSources prepareSourcesFile() throws IOException { + private RenamedSources prepareBurningFile(String text, String path) throws IOException { Path tempFile = Files.createTempFile("burn", "me"); - Files.write(tempFile, Collections.singleton(SOURCES)); - return new RenamedSources(tempFile, SOURCES_PATH, "01234", null); + Files.write(tempFile, Collections.singleton(text)); + return new RenamedSources(tempFile, path, "01234", null); } @Test - public void testStringLogImportFileGenerator() throws MalformedURLException, IOException { - final StringLogImportFileGenerator ifg = new StringLogImportFileGenerator(BUILD_LOG, prepareSourcesFile()); + public void testLogImportFileGenerator() throws IOException { + final ImportFileGenerator ifg = new ImportFileGenerator( + prepareBurningFile(BUILD_LOG, LOG_PATH), + prepareBurningFile(SOURCES, SOURCES_PATH)); doTestImportFileGenerator(ifg); } - @Test - public void testExternalLongImportFileGenerator() throws IOException, InterruptedException { - final SpecialImportFileGenerator ifg = new SpecialImportFileGenerator(prepareSourcesFile()); - ifg.addLog(HOST + LOG_LOCATION, LOG_PATH); - doTestImportFileGenerator(ifg); - } - - private void doTestImportFileGenerator(ImportFileGenerator ifg) throws MalformedURLException, IOException { - ifg.addUrl("1", HOST + FIRST_LOCATION, FIRST_PATH, FIRST_ARTIFACT.length()); - ifg.addUrl("2", HOST + SECOND_LOCATION, SECOND_PATH, SECOND_ARTIFACT.length()); + private void doTestImportFileGenerator(ImportFileGenerator ifg) throws IOException { + ifg.addUrl("1", host() + FIRST_LOCATION, FIRST_PATH, FIRST_ARTIFACT.length()); + ifg.addUrl("2", host() + SECOND_LOCATION, SECOND_PATH, SECOND_ARTIFACT.length()); assertEquals("1", ifg.getId(FIRST_PATH)); assertEquals("2", ifg.getId(SECOND_PATH)); @@ -118,7 +120,7 @@ private void doTestImportFileGenerator(ImportFileGenerator ifg) throws Malformed assertEquals(SECOND_ARTIFACT, toString(file.getStream())); break; case LOG_PATH: - assertEquals(6, file.getSize()); + assertEquals(7, file.getSize()); assertEquals(BUILD_LOG, toString(file.getStream())); break; case SOURCES_PATH: @@ -134,21 +136,16 @@ private void doTestImportFileGenerator(ImportFileGenerator ifg) throws Malformed } @Test - public void testStringLogImportFileGeneratorFail() throws MalformedURLException, IOException { - final StringLogImportFileGenerator ifg = new StringLogImportFileGenerator(BUILD_LOG, prepareSourcesFile()); - doTestImportFileGeneratorFail(ifg); - } - - @Test - public void testExternalLongImportFileGeneratorFail() throws IOException, InterruptedException { - final SpecialImportFileGenerator ifg = new SpecialImportFileGenerator(prepareSourcesFile()); - ifg.addLog(HOST + LOG_LOCATION, LOG_PATH); + public void testImportFileGeneratorFail() throws IOException { + final ImportFileGenerator ifg = new ImportFileGenerator( + prepareBurningFile(BUILD_LOG, SOURCES_PATH), + prepareBurningFile(SOURCES, SOURCES_PATH)); doTestImportFileGeneratorFail(ifg); } - private void doTestImportFileGeneratorFail(ImportFileGenerator ifg) throws MalformedURLException, IOException { - ifg.addUrl("1", HOST + FIRST_LOCATION, FIRST_PATH, FIRST_ARTIFACT.length()); - ifg.addUrl("2", HOST + NONEXISTING_LOCATION, NONEXISTING_PATH, 42); + private void doTestImportFileGeneratorFail(ImportFileGenerator ifg) throws IOException { + ifg.addUrl("1", host() + FIRST_LOCATION, FIRST_PATH, FIRST_ARTIFACT.length()); + ifg.addUrl("2", host() + NONEXISTING_LOCATION, NONEXISTING_PATH, 42); try { for (Supplier supp : ifg) { diff --git a/src/test/java/org/jboss/pnc/causeway/brewclient/TranslatorTest.java b/src/test/java/org/jboss/pnc/causeway/brewclient/TranslatorTest.java new file mode 100644 index 00000000..313619f1 --- /dev/null +++ b/src/test/java/org/jboss/pnc/causeway/brewclient/TranslatorTest.java @@ -0,0 +1,321 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.brewclient; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.redhat.red.build.koji.model.json.BuildOutput; +import com.redhat.red.build.koji.model.json.BuildTool; +import com.redhat.red.build.koji.model.json.KojiImport; +import com.redhat.red.build.koji.model.json.NpmTypeInfoExtraInfo; +import io.quarkus.test.junit.QuarkusTest; +import jakarta.inject.Inject; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.assertj.core.api.Condition; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; +import org.jboss.pnc.causeway.pncclient.BuildArtifacts; +import org.jboss.pnc.causeway.source.RenamedSources; +import org.jboss.pnc.dto.ArtifactRef; +import org.jboss.pnc.dto.Build; +import org.jboss.pnc.enums.ArtifactQuality; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.Collections; +import java.util.Date; +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * + * @author Honza Brázdil <jbrazdil@redhat.com> + */ +@QuarkusTest +public class TranslatorTest { + + @Inject + BuildTranslator bt; + + private static final ObjectMapper mapper = new ObjectMapper(); + private static final String SOURCES_PATH = "sources.tar.gz"; + private static final String SOURCES = "Burn this after reading!"; + + @BeforeAll + public static void setUp() { + mapper.registerModule(new JavaTimeModule()); + } + + private BurnAfterReadingFile mockBARF(String content) throws IOException { + BurnAfterReadingFile file = Mockito.mock(BurnAfterReadingFile.class); + Mockito.when(file.read()).then(invocationOnMock -> new ByteArrayInputStream(content.getBytes())); + Mockito.when(file.getName()).thenReturn("some-file"); + Mockito.when(file.getSize()).thenReturn(content.getBytes().length); + Mockito.when(file.getMd5()).thenReturn("a4c0d35c95a63a805915367dcfe6b751"); + return file; + } + + @Test + public void testReadBuildArtifacts() throws Exception { + // given + String groupId = "org.jboss.pnc"; + String artifactId = "parent"; + String version = "2.0.0"; + + String json = readResponseBodyFromTemplate("build-dto-1.json"); + Build build = mapper.readValue(json, Build.class); + + BuildArtifacts artifacts = new BuildArtifacts(); + artifacts.getBuildArtifacts() + .add( + newArtifact( + "2369", + "org.apache.geronimo.specs", + "geronimo-annotation_1.0_spec", + "1.1.1.redhat-1", + "pom")); + artifacts.getBuildArtifacts() + .add( + newArtifact( + "2370", + "org.apache.geronimo.specs", + "geronimo-annotation_1.0_spec", + "1.1.1.redhat-1", + "jar")); + artifacts.getBuildArtifacts() + .add( + newArtifact( + "2371", + "org.apache.geronimo.specs", + "geronimo-annotation_1.0_spec", + "1.1.1.redhat-1", + "tar.gz", + "project-sources")); + + artifacts.getDependencies().add(newArtifact("7", "org.apache.maven", "maven-project", "2.0.6", "pom")); + artifacts.getDependencies().add(newArtifact("9", "org.apache.maven.shared", "maven-shared-io", "1.1", "jar")); + artifacts.getDependencies().add(newArtifact("10", "xml-apis", "xml-apis", "1.0.b2", "jar")); + + RenamedSources sources = prepareSourcesFile(new RenamedSources.ArtifactType(groupId, artifactId, version)); + + // when + KojiImport out = bt.translate( + new BrewNVR(groupId + ":" + artifactId, version, "1"), + build, + artifacts, + sources, + mockBARF("foo-bar-logs"), + mockBARF("foo-bar-align-logs"), + "joe"); + + // Then + + Condition buildArtifact = new Condition<>( + bo -> artifacts.getBuildArtifacts().stream().anyMatch(a -> a.getDeployPath().equals(bo.getFilename())), + "build artifact"); + Condition buildLog = new Condition<>(bo -> bo.getOutputType().equals("log"), "log"); + Condition mavenArtifact = new Condition<>( + bo -> bo.getOutputType().equals("maven"), + "maven artifact"); + + assertThat(out.getBuild()).hasFieldOrPropertyWithValue("name", groupId + "-" + artifactId) + .hasFieldOrPropertyWithValue("version", version) + .hasFieldOrPropertyWithValue("release", "1") + .hasFieldOrPropertyWithValue("startTime", Date.from(Instant.parse("2019-02-15T02:02:36.645Z"))); + assertThat(out.getBuild().getSource()) + .hasFieldOrPropertyWithValue("revision", "57ebfa20374d708e232fc8b45f37def055300260"); + assertThat(out.getBuild().getSource().getUrl()).contains("https://github.com/project-ncl/pnc.git"); + assertThat(out.getBuild().getExtraInfo().getMavenExtraInfo()).hasFieldOrPropertyWithValue("groupId", groupId) + .hasFieldOrPropertyWithValue("artifactId", artifactId) + .hasFieldOrPropertyWithValue("version", version); + assertThat(out.getBuildRoots()).hasSize(1); + assertThat(out.getBuildRoots().get(0).getBuildTools()).hasSize(3) + .extracting(BuildTool::getName) + .containsExactly("JDK", "MAVEN", "OS"); + assertThat(out.getOutputs()).hasSize(3 + 3) // 3 artifacts + build log + align log + sources + .areExactly(3, buildArtifact) + .areExactly(4, mavenArtifact) + .areExactly(2, buildLog); + } + + @Test + public void testReadNpmBuildArtifacts() throws Exception { + // given + String scope = "@redhat"; + String packageName = "opossum"; + String version = "0.5.0"; + + String json = readResponseBodyFromTemplate("build-dto-npm.json"); + Build build = mapper.readValue(json, Build.class); + + BuildArtifacts artifacts = new BuildArtifacts(); + artifacts.getBuildArtifacts().add(newNpmArtifact("1800", scope, packageName, version)); + + artifacts.getDependencies().add(newNpmArtifact("7777", null, "once", "1.4.0")); + artifacts.getDependencies().add(newNpmArtifact("9999", null, "inflight", "1.0.6")); + artifacts.getDependencies().add(newNpmArtifact("10101", "@babel", "core", "7.11.0")); + + RenamedSources sources = prepareSourcesFile( + new RenamedSources.ArtifactType(scope + "/" + packageName, version)); + + // when + KojiImport out = bt.translate( + new BrewNVR(scope + ":" + packageName, version, "1"), + build, + artifacts, + sources, + mockBARF("foo-bar-logs"), + mockBARF("foo-bar-align-logs"), + "joe"); + + // Then + Condition buildArtifact = new Condition<>( + bo -> artifacts.getBuildArtifacts().stream().anyMatch(a -> a.getDeployPath().equals(bo.getFilename())), + "build artifact"); + Condition log = new Condition<>(bo -> bo.getOutputType().equals("log"), "log"); + Condition npmArtifact = new Condition<>(bo -> bo.getOutputType().equals("npm"), "npm artifact"); + + assertThat(out.getBuild()).hasFieldOrPropertyWithValue("name", scope + "-" + packageName) + .hasFieldOrPropertyWithValue("version", version) + .hasFieldOrPropertyWithValue("release", "1") + .hasFieldOrPropertyWithValue("startTime", Date.from(Instant.parse("2021-07-23T15:54:18.259Z"))); + assertThat(out.getBuild().getSource()) + .hasFieldOrPropertyWithValue("revision", "647daeb088cd49354f8831d3e3dab440e039b11a"); + assertThat(out.getBuild().getSource().getUrl()).contains("http://github.com/nodeshift/opossum.git"); + assertThat(out.getBuild().getExtraInfo().getNpmExtraInfo()) + .hasFieldOrPropertyWithValue("name", scope + "-" + packageName) + .hasFieldOrPropertyWithValue("version", version); + assertThat(out.getBuild().getExtraInfo().getTypeInfo()) + .hasFieldOrPropertyWithValue("npmTypeInfoExtraInfo", NpmTypeInfoExtraInfo.getInstance()); + assertThat(out.getBuildRoots()).hasSize(1); + assertThat(out.getBuildRoots().get(0).getBuildTools()).hasSize(3) + .extracting(BuildTool::getName) + .containsExactly("NPM", "OS", "Nodejs"); + assertThat(out.getOutputs()).hasSize(4) // 1 artifact + build log + align log + sources + .areExactly(1, buildArtifact) + .areExactly(2, npmArtifact) + .areExactly(2, log); + + // System.out.println(mapper.writeValueAsString(out)); + } + + @Test + public void testTranslateBuildWithMissingTool() throws Exception { + // given + String groupId = "org.jboss.pnc"; + String artifactId = "parent"; + String version = "2.0.0"; + + String json = readResponseBodyFromTemplate("build-dto-missing-tool-version.json"); + Build build = mapper.readValue(json, Build.class); + + BuildArtifacts artifacts = new BuildArtifacts(); + artifacts.getBuildArtifacts() + .add( + newArtifact( + "2369", + "org.apache.geronimo.specs", + "geronimo-annotation_1.0_spec", + "1.1.1.redhat-1", + "pom")); + RenamedSources sources = prepareSourcesFile(new RenamedSources.ArtifactType(groupId, artifactId, version)); + + assertThatThrownBy( + () -> bt.translate( + new BrewNVR(groupId + ":" + artifactId, version, "1"), + build, + artifacts, + sources, + mockBARF("foo-bar-logs"), + mockBARF("foo-bar-align-logs"), + "joe")) + .isInstanceOf(IllegalArgumentException.class); + } + + private RenamedSources prepareSourcesFile(RenamedSources.ArtifactType artifactType) throws IOException { + Path tempFile = Files.createTempFile("burn", "me"); + Files.write(tempFile, Collections.singleton(SOURCES)); + return new RenamedSources(tempFile, SOURCES_PATH, "01234", artifactType); + } + + private static ArtifactRef newArtifact(String id, String groupId, String artifactId, String version, String type) { + return newArtifact(id, groupId, artifactId, version, type, null); + } + + private static ArtifactRef newArtifact( + String id, + String groupId, + String artifactId, + String version, + String type, + String specifier) { + final String filename; + final String identifier; + if (specifier == null) { + filename = artifactId + "-" + version + "." + type; + identifier = groupId + ":" + artifactId + ":" + type + ":" + version; + } else { + filename = artifactId + "-" + version + "-" + specifier + "." + type; + identifier = groupId + ":" + artifactId + ":" + type + ":" + version + ":" + specifier; + } + final String path = groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + filename; + + return ArtifactRef.refBuilder() + .id(id) + .identifier(identifier) + .filename(filename) + .md5("bedf8af1b107b36c72f52009e6fcc768") + .deployUrl( + "http://example.com/api/hosted/build_geronimo-annotation_1-0_spec-1-1-1_20160804.0721/" + path) + .deployPath("/" + path) + .size(13245L) + .artifactQuality(ArtifactQuality.NEW) + .build(); + } + + private static ArtifactRef newNpmArtifact(String id, String scope, String packageName, String version) { + final String identifier; + if (scope == null) { + identifier = packageName + ":" + version; + } else { + identifier = scope + "/" + packageName + ":" + version; + } + final String path = (scope == null ? "" : scope + "/") + packageName + "/-/" + packageName + "-" + version + + ".tgz"; + + return ArtifactRef.refBuilder() + .id(id) + .identifier(identifier) + .filename(path) + .md5("bedf8af1b107b36c72f52009e6fcc768") + .deployUrl("http://example.com/build-repo/" + path) + .deployPath("/" + path) + .size(13245L) + .artifactQuality(ArtifactQuality.NEW) + .build(); + } + + private String readResponseBodyFromTemplate(String name) throws IOException { + String folderName = getClass().getPackage().getName().replace(".", "/"); + try (InputStream inputStream = getContextClassLoader().getResourceAsStream(folderName + "/" + name)) { + return StringUtils + .join(IOUtils.readLines(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8), "\n"); + } + } + + private ClassLoader getContextClassLoader() { + return Thread.currentThread().getContextClassLoader(); + } +} diff --git a/src/test/java/org/jboss/pnc/causeway/ctl/ImportControllerTest.java b/src/test/java/org/jboss/pnc/causeway/ctl/ImportControllerTest.java new file mode 100644 index 00000000..3b51af52 --- /dev/null +++ b/src/test/java/org/jboss/pnc/causeway/ctl/ImportControllerTest.java @@ -0,0 +1,463 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.pnc.causeway.ctl; + +import com.redhat.red.build.koji.model.json.KojiImport; +import io.quarkus.test.InjectMock; +import io.quarkus.test.junit.QuarkusTest; +import jakarta.inject.Inject; +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.jboss.pnc.api.causeway.dto.push.PushResult; +import org.jboss.pnc.api.constants.Attributes; +import org.jboss.pnc.api.enums.ResultStatus; +import org.jboss.pnc.causeway.CausewayException; +import org.jboss.pnc.causeway.CausewayFailure; +import org.jboss.pnc.causeway.brewclient.BrewBuild; +import org.jboss.pnc.causeway.brewclient.BrewClient; +import org.jboss.pnc.causeway.brewclient.BrewNVR; +import org.jboss.pnc.causeway.brewclient.BuildTranslatorImpl; +import org.jboss.pnc.causeway.brewclient.ImportFileGenerator; +import org.jboss.pnc.causeway.impl.BurnAfterReadingFile; +import org.jboss.pnc.causeway.pncclient.BuildArtifacts; +import org.jboss.pnc.causeway.pncclient.PncClient; +import org.jboss.pnc.dto.ArtifactRef; +import org.jboss.pnc.dto.Build; +import org.jboss.pnc.dto.BuildConfigurationRevision; +import org.jboss.pnc.dto.Environment; +import org.jboss.pnc.dto.SCMRepository; +import org.jboss.pnc.dto.User; +import org.jboss.pnc.enums.ArtifactQuality; +import org.jboss.pnc.enums.BuildStatus; +import org.jboss.pnc.enums.BuildType; +import org.jboss.pnc.enums.SystemImageType; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.jboss.pnc.causeway.ErrorMessages.tagsAreMissingInKoji; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.same; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@QuarkusTest +public class ImportControllerTest { + + @ConfigProperty(name = "causeway.koji.url") + String kojiUrl; + @ConfigProperty(name = "causeway.koji.web-url") + String kojiBuildUrl; + + @InjectMock + PncClient pncClient; + @InjectMock + BrewClient brewClient; + + @InjectMock + BuildTranslatorImpl translator; + + @Inject + ImportControllerImpl importController; + + private static final ImportFileGenerator IMPORT_FILE_GENERATOR = mock(ImportFileGenerator.class); + private static final KojiImport KOJI_IMPORT = mock(KojiImport.class); + + private static final Random generator = new Random(); + private static final String MVN_GROUP_ID = "my.test-artifact"; + private static final String MVN_ARTIFACT_ID = "artifact-test"; + private static final String MVN_BUILD_NAME = MVN_GROUP_ID + ":" + MVN_ARTIFACT_ID; + private static final String MVN_VERSION = "1.1.1.redhat-00001"; + private static final String MVN_VERSION_KOJI_STYLE = "1.1.1.redhat_00001"; + private static final String NPM_ARTIFACT_SCOPE = "foo-bar"; + private static final String NPM_ARTIFACT_NAME = "baz"; + private static final String NPM_VERSION = "1.1.1-redhat-00001"; + private static final String NPM_VERSION_KOJI_STYLE = "1.1.1_redhat_00001"; + private static final String NPM_BUILD_NAME = NPM_ARTIFACT_SCOPE + "-" + NPM_ARTIFACT_NAME + "-npm"; + private static final BrewNVR MVN_NVR = new BrewNVR(MVN_BUILD_NAME, MVN_VERSION_KOJI_STYLE, "1"); + private static final BrewNVR MVN_NVR2 = new BrewNVR(MVN_BUILD_NAME, MVN_VERSION_KOJI_STYLE, "2"); + private static final String USERNAME = "joe"; + private static final String TAG_PREFIX = "pnc-foo-0.1"; + + @Test + public void testReImportBuildWhenPreviousUntaggedImportExists() throws Exception { + // Test setup + mockBrew(); + mockTranslator(); + + // Mock existing Brew build + int existingKojiBuildID = 11; + BrewBuild brewBuild = mockExistingBuild(existingKojiBuildID, MVN_NVR, false); + String buildId = mockMVNBuild().getId(); + + // Run import + PushResult pushResult = importController.importBuild(buildId, TAG_PREFIX, true, USERNAME); + + // Verify + verify(brewClient).tagBuild(eq(TAG_PREFIX), same(brewBuild)); + assertThat(pushResult).extracting(PushResult::getResult).isEqualTo(ResultStatus.SUCCESS); + assertThat(pushResult).extracting(PushResult::getBrewBuildId).isEqualTo(existingKojiBuildID); + } + + @Test + public void testReImportBuildWhenPreviousTaggedImportExists() throws Exception { + // Test setup + mockBrew(); + mockTranslator(); + + // Mock existing Brew build + String buildId = mockMVNBuild().getId(); + mockExistingBuild(11, MVN_NVR, true); + + // Mock Brew import + KojiImport kojiImport = mock(KojiImport.class); + doReturn(kojiImport).when(translator).translate(eq(MVN_NVR2), any(), any(), any(), any(), any(), any()); + int newKojiBuildID = 12; + BrewBuild brewBuild = new BrewBuild(newKojiBuildID, MVN_NVR2); + doReturn(brewBuild).when(brewClient).importBuild(eq(MVN_NVR2), same(kojiImport), same(IMPORT_FILE_GENERATOR)); + + // Run import + PushResult pushResult = importController.importBuild(buildId, TAG_PREFIX, true, USERNAME); + + // Verify + verify(brewClient).tagBuild(eq(TAG_PREFIX), same(brewBuild)); + assertThat(pushResult).extracting(PushResult::getResult).isEqualTo(ResultStatus.SUCCESS); + assertThat(pushResult).extracting(PushResult::getBrewBuildId).isEqualTo(newKojiBuildID); + assertThat(pushResult).extracting(PushResult::getBrewBuildUrl).isEqualTo(kojiBuildUrl + newKojiBuildID); + assertThat(pushResult).extracting(PushResult::getBuildId).isEqualTo(buildId); + } + + @Test + public void testImportBuildWhenPreviousTaggedImportExists() throws Exception { + // Test setup + mockBrew(); + mockTranslator(); + + // Mock existing Brew build + int existingKojiBuildID = 11; + mockExistingBuild(existingKojiBuildID, MVN_NVR, true); + String buildId = mockMVNBuild().getId(); + + // Run import + PushResult pushResult = importController.importBuild(buildId, TAG_PREFIX, false, USERNAME); + + // Verify + assertThat(pushResult).extracting(PushResult::getResult).isEqualTo(ResultStatus.SUCCESS); + assertThat(pushResult).extracting(PushResult::getBrewBuildId).isEqualTo(existingKojiBuildID); + } + + @Test + public void testImportBuildWhenConflictingBrewBuildExists() throws Exception { + // Test setup + mockBrew(); + mockTranslator(); + + // Mock existing Brew build + String buildId = mockMVNBuild().getId(); + doThrow(new CausewayException("Conflicting brew build exists.")).when(brewClient) + .findBrewBuildOfNVR(eq(MVN_NVR)); + + // Run import + assertThatThrownBy(() -> importController.importBuild(buildId, TAG_PREFIX, true, USERNAME)) + .isInstanceOf(CausewayException.class) + .hasMessageContaining("Conflicting brew build exists."); + } + + @Test + public void testImportBuild() throws Exception { + // Test setup + mockBrew(); + mockTranslator(); + + // Mock Brew import + int kojiBuildID = 11; + BrewBuild brewBuild = new BrewBuild(kojiBuildID, MVN_NVR); + String buildId = mockMVNBuild().getId(); + doReturn(brewBuild).when(brewClient).importBuild(eq(MVN_NVR), same(KOJI_IMPORT), same(IMPORT_FILE_GENERATOR)); + + // Run import + PushResult pushResult = importController.importBuild(buildId, TAG_PREFIX, true, USERNAME); + + // Verify + verify(brewClient).tagBuild(eq(TAG_PREFIX), same(brewBuild)); + assertThat(pushResult).extracting(PushResult::getResult).isEqualTo(ResultStatus.SUCCESS); + assertThat(pushResult).extracting(PushResult::getBrewBuildId).isEqualTo(kojiBuildID); + assertThat(pushResult).extracting(PushResult::getBrewBuildUrl).isEqualTo(kojiBuildUrl + kojiBuildID); + assertThat(pushResult).extracting(PushResult::getBuildId).isEqualTo(buildId); + } + + @Test + public void testImportBuildWithEmptyArtifacts() throws Exception { + // Test setup + mockBrew(); + + // Mock no builds in milestone + String buildId = mockMVNBuild().getId(); + doReturn(new BuildArtifacts()).when(pncClient).findBuildArtifacts(eq(buildId)); + + // Run import + PushResult pushResult = importController.importBuild(buildId, TAG_PREFIX, true, USERNAME); + + // verify + assertThat(pushResult).extracting(PushResult::getResult).isEqualTo(ResultStatus.SUCCESS); + assertThat(pushResult).extracting(PushResult::getBrewBuildId).isNull(); + assertThat(pushResult).extracting(PushResult::getBrewBuildUrl).isNull(); + assertThat(pushResult).extracting(PushResult::getBuildId).isEqualTo(buildId); + } + + @Test + public void testImportBuildWhereImportBuildThrowsException() throws Exception { + String exceptionMessage = "Import build failed"; + + // Test setup + mockBrew(); + mockTranslator(); + + // Mock exception from Brew Client + String buildId = mockMVNBuild().getId(); + doThrow(new CausewayException(exceptionMessage)).when(brewClient).findBrewBuildOfNVR(eq(MVN_NVR)); + + // Run import + assertThatThrownBy(() -> importController.importBuild(buildId, TAG_PREFIX, true, USERNAME)) + .isInstanceOf(CausewayException.class) + .hasMessageContaining(exceptionMessage); + } + + @Test + public void testImportBuildWithArtifactImportErrors() throws Exception { + final String exceptionMessage = "Failure while importing artifacts"; + + // Test setup + mockBrew(); + mockTranslator(); + + String buildId = mockMVNBuild().getId(); + doThrow(new CausewayFailure(exceptionMessage)).when(brewClient) + .importBuild(eq(MVN_NVR), same(KOJI_IMPORT), same(IMPORT_FILE_GENERATOR)); + + // Run import + assertThatThrownBy(() -> importController.importBuild(buildId, TAG_PREFIX, true, USERNAME)) + .isInstanceOf(CausewayFailure.class) + .hasMessageContaining(exceptionMessage); + } + + @Test + public void testImportBuildWhenTagDoesNotExistInBrew() throws Exception { + // Test setup + mockBrew(); + doReturn(false).when(brewClient).tagsExists(TAG_PREFIX); + String buildId = mockMVNBuild().getId(); + + // Run import + assertThatThrownBy(() -> importController.importBuild(buildId, TAG_PREFIX, true, USERNAME)) + .isInstanceOf(CausewayFailure.class) + .hasMessageContaining(tagsAreMissingInKoji(TAG_PREFIX, kojiUrl)); + } + + @Test + public void testGetNVR() throws CausewayException { + BuildArtifacts buildArtifacts = new BuildArtifacts(); + ArtifactRef artifact = createArtifact("32"); + buildArtifacts.getBuildArtifacts().add(artifact); + Build build = mockMVNBuild(); + Build build2 = build.toBuilder().attributes(Map.of(Attributes.BUILD_BREW_NAME, MVN_BUILD_NAME)).build(); + + BrewNVR nvr = importController.getNVR(build, new BuildArtifacts()); + assertEquals(MVN_BUILD_NAME, nvr.getName()); + assertEquals(MVN_VERSION_KOJI_STYLE, nvr.getVersion()); + + BrewNVR nvr2 = importController.getNVR(build2, buildArtifacts); + assertEquals(MVN_BUILD_NAME, nvr2.getName()); + assertEquals(MVN_VERSION_KOJI_STYLE, nvr2.getVersion()); + } + + @Test + public void testAutomaticVersionNpm() throws CausewayException { + Build build = mockNPMBuild().toBuilder().attributes(Map.of(Attributes.BUILD_BREW_NAME, NPM_BUILD_NAME)).build(); + BuildArtifacts buildArtifacts = new BuildArtifacts(); + ArtifactRef artifact = createNPMArtifact("32"); + buildArtifacts.getBuildArtifacts().add(artifact); + + BrewNVR nvr = importController.getNVR(build, buildArtifacts); + assertEquals(NPM_BUILD_NAME, nvr.getName()); + assertEquals(NPM_VERSION_KOJI_STYLE, nvr.getVersion()); + } + + private Build mockMVNBuild() throws CausewayException { + String buildId = String.valueOf(generator.nextInt()); + Integer id = generator.nextInt(); + + Environment env = createEnvironment(BuildType.MVN); + + // Mock BuildConfigurationAudited + BuildConfigurationRevision bcar = createBuildConfiguration(id, env, BuildType.MVN); + + // Mock BuildRecord + Build buildRecord = createBuildRecord(buildId, bcar, MVN_BUILD_NAME, MVN_VERSION); + + // Mock BuildArtifacts + BuildArtifacts buildArtifacts = new BuildArtifacts(); + buildArtifacts.getBuildArtifacts().add(createArtifact(buildId)); + + doReturn(buildRecord).when(pncClient).findBuild(eq(buildId)); + doReturn(buildArtifacts).when(pncClient).findBuildArtifacts(eq(buildId)); + doAnswer(i -> mockBARF("Log of build " + i.getArguments()[0])).when(pncClient).getBuildLog(anyString()); + doAnswer(i -> mockBARF("Log of alignment " + i.getArguments()[0])).when(pncClient).getAlignLog(anyString()); + return buildRecord; + } + + private Build mockNPMBuild() throws CausewayException { + String buildId = String.valueOf(generator.nextInt()); + Integer id = generator.nextInt(); + + Environment env = createEnvironment(BuildType.NPM); + + // Mock BuildConfigurationAudited + BuildConfigurationRevision bcar = createBuildConfiguration(id, env, BuildType.NPM); + + // Mock BuildRecord + Build buildRecord = createBuildRecord(buildId, bcar, NPM_BUILD_NAME, NPM_VERSION); + + // Mock BuildArtifacts + BuildArtifacts buildArtifacts = new BuildArtifacts(); + buildArtifacts.getBuildArtifacts().add(createArtifact(buildId)); + + doReturn(buildRecord).when(pncClient).findBuild(eq(buildId)); + doReturn(buildArtifacts).when(pncClient).findBuildArtifacts(eq(buildId)); + doAnswer(i -> mockBARF("Log of build " + i.getArguments()[0])).when(pncClient).getBuildLog(anyString()); + doAnswer(i -> mockBARF("Log of alignment " + i.getArguments()[0])).when(pncClient).getAlignLog(anyString()); + return buildRecord; + } + + private Environment createEnvironment(BuildType buildType) { + // Mock BuildEnvironment + Map attrs = new HashMap<>(); + attrs.put("OS", "Fedora25"); + switch (buildType) { + case MVN: + case GRADLE: + attrs.put("JDK", "1.8"); + break; + case NPM: + attrs.put("NPM", "5"); + } + + return Environment.builder().attributes(attrs).systemImageType(SystemImageType.DOCKER_IMAGE).build(); + } + + private BuildConfigurationRevision createBuildConfiguration(Integer id, Environment env, BuildType buildType) { + SCMRepository scm = SCMRepository.builder().id(String.valueOf(1)).internalUrl("http://repo.url").build(); + + return BuildConfigurationRevision.builder() + .id(String.valueOf(id)) + .rev(1) + .scmRepository(scm) + .buildType(buildType) + .scmRevision("r21345") + .environment(env) + .build(); + } + + private Build createBuildRecord( + String buildId, + BuildConfigurationRevision bcar, + String brewBuildName, + String brewBuildVersion) { + User user = User.builder().id(String.valueOf(1)).build(); + + Date submit = new Date(); + Date start = new Date(submit.getTime() + 1000L); + Date end = new Date(start.getTime() + 100000L); + Map attributes = new HashMap<>(); + if (brewBuildName != null) { + attributes.put(Attributes.BUILD_BREW_NAME, brewBuildName); + } + if (brewBuildVersion != null) { + attributes.put(Attributes.BUILD_BREW_VERSION, brewBuildVersion); + } + return Build.builder() + .id(String.valueOf(buildId)) + .status(BuildStatus.SUCCESS) + .submitTime(submit.toInstant()) + .startTime(start.toInstant()) + .endTime(end.toInstant()) + .user(user) + .attributes(attributes) + .buildConfigRevision(bcar) + .build(); + } + + private static ArtifactRef createArtifact(String id) { + String filename = MVN_ARTIFACT_ID + "-" + MVN_VERSION + ".pom"; + String path = MVN_GROUP_ID.replace('.', '/') + "/" + MVN_ARTIFACT_ID + "/" + MVN_VERSION + "/" + filename; + return ArtifactRef.refBuilder() + .id(id) + .identifier(MVN_GROUP_ID + ":" + MVN_ARTIFACT_ID + ":pom:" + MVN_VERSION) + .filename(filename) + .md5("bedf8af1b107b36c72f52009e6fcc768") + .deployUrl("https://example.com/api/content/mvn/hosted/shared-imports/" + path) + .deployPath("/" + path) + .size(13245L) + .artifactQuality(ArtifactQuality.NEW) + .build(); + } + + private static ArtifactRef createNPMArtifact(String id) { + String filename = NPM_ARTIFACT_NAME + "-" + NPM_VERSION + ".tgz"; + String path = "@" + NPM_ARTIFACT_SCOPE + "/" + NPM_ARTIFACT_NAME + "/-/" + filename; + return ArtifactRef.refBuilder() + .id(id) + .identifier("@" + NPM_ARTIFACT_SCOPE + "/" + NPM_ARTIFACT_NAME + ":" + NPM_VERSION) + .filename(filename) + .md5("bedf8af1b107b36c72f52009e6fcc768") + .deployUrl("https://example.com/api/content/npm/hosted/shared-imports/" + path) + .deployPath("/" + path) + .size(13245L) + .artifactQuality(ArtifactQuality.NEW) + .build(); + } + + private BurnAfterReadingFile mockBARF(String content) throws IOException { + BurnAfterReadingFile file = Mockito.mock(BurnAfterReadingFile.class); + Mockito.when(file.read()).then(invocationOnMock -> new ByteArrayInputStream(content.getBytes())); + return file; + } + + private void mockBrew() throws CausewayException { + doReturn(true).when(brewClient).tagsExists(eq(TAG_PREFIX)); + when(brewClient.getBuildUrl(anyInt())).then(inv -> kojiBuildUrl + inv.getArguments()[0]); + doNothing().when(brewClient).tagBuild(eq(TAG_PREFIX), any()); + } + + private void mockTranslator() throws CausewayException { + doReturn(KOJI_IMPORT).when(translator).translate(eq(MVN_NVR), any(), any(), any(), any(), any(), any()); + doReturn(IMPORT_FILE_GENERATOR).when(translator).getImportFiles(any(), any(), any(), any()); + doReturn("/path/to/sources.tar.gz").when(translator).getSourcesDeployPath(any(), any()); + } + + private BrewBuild mockExistingBuild(int id, BrewNVR nvr, boolean tagged) throws Exception { + BrewBuild brewBuild = new BrewBuild(id, nvr); + when(brewClient.findBrewBuildOfNVR(eq(nvr))).thenReturn(brewBuild); + when(brewClient.findBrewBuild(eq(id))).thenReturn(brewBuild); + when(brewClient.isBuildTagged(eq(TAG_PREFIX), same(brewBuild))).thenReturn(tagged); + return brewBuild; + } +} diff --git a/core/src/test/java/org/jboss/pnc/causeway/source/SourceRenamerTest.java b/src/test/java/org/jboss/pnc/causeway/source/SourceRenamerTest.java similarity index 89% rename from core/src/test/java/org/jboss/pnc/causeway/source/SourceRenamerTest.java rename to src/test/java/org/jboss/pnc/causeway/source/SourceRenamerTest.java index c78c473d..124a395f 100644 --- a/core/src/test/java/org/jboss/pnc/causeway/source/SourceRenamerTest.java +++ b/src/test/java/org/jboss/pnc/causeway/source/SourceRenamerTest.java @@ -1,29 +1,39 @@ +/* + * Copyright 2024 Red Hat, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ package org.jboss.pnc.causeway.source; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - +import io.quarkus.test.junit.QuarkusTest; +import jakarta.inject.Inject; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; import org.jboss.pnc.causeway.CausewayException; import org.jboss.pnc.causeway.brewclient.BuildTranslatorImpl; -import org.jboss.pnc.causeway.config.CausewayConfig; import org.jboss.pnc.causeway.pncclient.BuildArtifacts; import org.jboss.pnc.dto.Build; import org.jboss.pnc.dto.BuildConfigurationRevision; import org.jboss.pnc.enums.BuildType; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; import static org.jboss.pnc.causeway.source.SourceRenamer.ARCHIVE_SUFFIX; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +@QuarkusTest public class SourceRenamerTest { - private SourceRenamer renamer = new SourceRenamer(); + @Inject + BuildTranslatorImpl buildTranslator; + + @Inject + SourceRenamer renamer; @Test public void shouldRenameRootDirectory() throws CausewayException, IOException { @@ -65,7 +75,6 @@ public void shouldGetMavenDeployPath() { @Test public void shouldGetMavenDeployPath2() throws CausewayException { - BuildTranslatorImpl buildTranslator = new BuildTranslatorImpl(new CausewayConfig(), renamer); Map attributes = new HashMap<>(); attributes.put("BREW_BUILD_VERSION", "1.8.2.fuse-790037-redhat-00001"); attributes.put("BREW_BUILD_NAME", "org.arquillian.cube:arquillian-cube-parent"); diff --git a/src/test/resources/cert/snakeoil.csr b/src/test/resources/cert/snakeoil.csr new file mode 100644 index 00000000..edbd61f0 --- /dev/null +++ b/src/test/resources/cert/snakeoil.csr @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEoDCCAogCAQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0 +eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKR92Nbk9IL3pWCC7Cpwb+1RpDLjrS+ojbX2SnAQpQXL +maYs+zlxr2/AyV55q+s+12l9sF7K8MckMo20oWXqLI0pV1l3i2BsNfw6bKZWvPhX +NMOHz37FuseJiJ1CIwkOIjvtZ11D0OHC5SMepj2499n02dwblhlaOxkzu1JmLnAU +cXvDPOo9A6ZLVvV8WQWGsHNQdphEzOxEoN00UDztgs67oMFdkV8g0QjqDIrvSDk+ +bdW5N05Mn8llIc+W0H3sFtl0DrLi2zUsYfAxvsPehE1xcCmb93C17Im7wqY3k8fn ++6JSg+9h3G5UH5vEvYLaGOpeT5QZS0RLbOkom2iuOlZNCk+x8tGqY5aLp9cDK4af +2soNemEuf/snmOKb9zKNPYN7nE23P2Z8Ev+4Sp40KeO29BLnzIkS8G9MZ6CoKvTk +w+ikg1EzxvLRKKG2CMqAvHPWLoAqcKS+Je2EdGoIWAstOmRGOzT+yMfdaOLkW50u +u5HNb1si/TewEXCqs9j9/NQ7qk0s7ZEYEb3UVOqERGIyxYD38h9BtnVZCOarsBsQ +DxeR/xq92UmDjakNdquOHTRlyO+x1JEJIkhykpxm42NzS3V1d4mzdA+a7lTxRfTO +o2RteDtLXsOQocQ0M4h1gfqdifhph81BasHPxBQYdvqUJlykfByr5Ow3LLOkemvB +AgMBAAGgGTAXBgkqhkiG9w0BCQcxCgwIcGFzc3dvcmQwDQYJKoZIhvcNAQELBQAD +ggIBAIsIn7DD0+8RSSK26NPOL6CK0UAj6KX8rjBhkpz3boZHmDa3H3ko7si1Sd9O +OH90Le6f50E6Or6E7iDXS/9NvmzO+FiUu8gIXjZWLlmq5A7CDzJioDO1skxYpBoW +7vmFUFcAFNJo/k4hQfZj+wLuLudmaaOChszLlawH4IxCjiPnO+0qZMXPzUCAnTWg +DKWjj6CPYVYJ44qPCnGoEvOB7xNxnh/7juaExT1uL44t2NYCHhXcPplNHl7rJqGQ +XeE8JT8k2Q/uDJI2YPuHRyFRxiqxNbOGyZvsW+uB4GXVcDeJGbHnaoPP6G/0kdRU +8LZdAguzuDxI1bvfgh0qRdP+gcaEesOy74lodN73/vyslvG0GlNnTeQHNzzIc96y +ccga+i275fDr4hyyyzVJSPWV3CDkEFQoVpPUV7wxWdxf4WyigSWMLypGmZThB2YO +WYh49rNKxxUbA0i2lEyXOizVi5xEGINK4AUkVPXixz/+sn8CNCCS2100lwpIjqfY +Xvu5YY0eu1qfgKUVHCwS4QHcYz/8OnjcxLwzv5bOJV/Ykb3r/KMntvb6jR+6bvMq +H3poimC7cYTZuhUU0TTU37MYOdKvO3jyfhParb0egPggZnXGk34/hvwEJahTmboE +yvrMoe32AcyUWiFpj9O8V5aC4wGSh5+zLtQYGtrRKKtz9Fdn +-----END CERTIFICATE REQUEST----- diff --git a/src/test/resources/cert/snakeoil.key b/src/test/resources/cert/snakeoil.key new file mode 100644 index 00000000..486d6599 --- /dev/null +++ b/src/test/resources/cert/snakeoil.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQAIBADANBgkqhkiG9w0BAQEFAASCCSowggkmAgEAAoICAQCkfdjW5PSC96Vg +guwqcG/tUaQy460vqI219kpwEKUFy5mmLPs5ca9vwMleeavrPtdpfbBeyvDHJDKN +tKFl6iyNKVdZd4tgbDX8OmymVrz4VzTDh89+xbrHiYidQiMJDiI77WddQ9DhwuUj +HqY9uPfZ9NncG5YZWjsZM7tSZi5wFHF7wzzqPQOmS1b1fFkFhrBzUHaYRMzsRKDd +NFA87YLOu6DBXZFfINEI6gyK70g5Pm3VuTdOTJ/JZSHPltB97BbZdA6y4ts1LGHw +Mb7D3oRNcXApm/dwteyJu8KmN5PH5/uiUoPvYdxuVB+bxL2C2hjqXk+UGUtES2zp +KJtorjpWTQpPsfLRqmOWi6fXAyuGn9rKDXphLn/7J5jim/cyjT2De5xNtz9mfBL/ +uEqeNCnjtvQS58yJEvBvTGegqCr05MPopINRM8by0SihtgjKgLxz1i6AKnCkviXt +hHRqCFgLLTpkRjs0/sjH3Wji5FudLruRzW9bIv03sBFwqrPY/fzUO6pNLO2RGBG9 +1FTqhERiMsWA9/IfQbZ1WQjmq7AbEA8Xkf8avdlJg42pDXarjh00ZcjvsdSRCSJI +cpKcZuNjc0t1dXeJs3QPmu5U8UX0zqNkbXg7S17DkKHENDOIdYH6nYn4aYfNQWrB +z8QUGHb6lCZcpHwcq+TsNyyzpHprwQIDAQABAoICAD1kvSSDwuEI5kAtzVCPs67L +XHIj+RVDH1Utbh4CkF0n3xqfSkrn7BdVSLNKzUhZpZO5djUDILfrAjVSmDTOIL+1 +EOWTEUG1Ubbo5Xl2AUTdY5OhImhKC4sDAarULvhnvo5Ibt5n+9PvZo9jlp+N5HAE +i7Wz1CN1Qn6HCODZw3ZQowSS267/g9ey4etw9Fb0LPJ1MzZk42lBuhqltlbvPPXF +INxa/HGZcXuWw4Sth3LaIqt03DgMsEy+Qs7Uls+Q6PxTbVMGCdQAUzOPlYhMimvP +LZJSJJn8RKMpoZ5hOvaPVqOAkb6sc1X4bu24EhV/KnJ7Lc90W1vLnQQvBEYfVSUc +mn0prJuVNtd5I8OqfiU3opvyGU6eU4DVddbbIIbC0qTMIi/usUZw575ejbAaqPd/ +WPZI7fe5zCxN6fblGkUyZRVW17M5RLv1m5CWCSZv95U5hJpJeGT4kFlsCfI/56vE +EhmjF4GTHA72lDLboL92r39IXHUxR4E4NPFVsOeBqfq5E32gBx5NcTM5u1ANGYPG +xBJvPcQWdrrOOiQk0rU3PhdR2GTY/LUGFJQ69veLO/vB7Gy0oGkLpJuODCpJY8fe +zmqtvHpAdTMPj61eQS+yf5YzZXKhFfGG3mCM4WOg4aasPjEKB+Ncp5Ehb7CPpJcw +WJAX+XhvWjJC07RnsoKbAoIBAQDQ0P2A9zzIiZUbIU0W3U+DBilesve/ncnsfz/P +59YY+YFO5FCV9DH/t4UyRo+3r2OdlywNPMjJCgMLWrqrUWj0u7Akkp16vz7hz3bA +B/RADTuKG45hhSdv8J20cpj1HEOMQa/BcSSUa0PpDT9JNGTEsxZYVv2adzBUmHxW +BPfiIcOQDA0qo+OMPtyHdFELAg9vmMdOQ4uCtWQCfWEnm2DzydHe5UkFUmIGPkFs +9YXGTU2f3R+osRs5iJVjXbBgZE/r7mDMyukGAt1z7SLPxilaid8mnwHG049Dr0Jq +yu+pluE/nn/A9t0mWemELJzbrFxPbwzxAmawSA85Hxu6wzdzAoIBAQDJqOJfWU+h +rP7JYiVSlcX6op2hN8FZovi95osmXahJPH4lIZFP5WL2deQ8aK3LN7X9XKeJVrCO +Q5wZDA162gkPdp9ekcgC203pBX3FXbC0h+Bzcsbv1ypX1rYIn54pCjo43SQikNcf +y3FZm7DWM1ANUQmAXp9ASpkxCCB5b8tZfphiwK462RPcF3IDKnrwwetF6m1dDIKM +XfcNtAaXeHNR5k9IIeLphwuhW9XA4j6Txo43oCCh+Fwp707c6Sf6extkl9CygAhj +ufhTZ0/YGKuCghk7ke0AZVp2Btp7bvG+NdyA+gK7bSgCNcv+HWW20l1ezgcxeSGG +zqXru6SysTr7AoIBAQDLQNGwKXdZv0mKedSej9ZoM6QrEErEkeLNN2M2jHRCJQJv +dx7VhzbvsIOO103mvmpZJ59yVxsdTIiAEdUnEnv104b1Yly08NhVVepBqrxdaEPu +/zmMxN4JQI1Q6kbmNpetOvbHdMjlSq90djeGmuAG8kaqwCnjo2ZAwZgs5nMeAj1n +xcM/IP1JMprXoimMbHn35x8AmBCAruzk24Oo2L37LhQBQO7dpj3R0+E9HJMU3YPU +OpkpSxKz4rV+XeBjQuDkRkikrlE5T6qcv1KmKT1xakfyQM2q6ZxGhp5Acr3rNfiU +Q0QY4HGMdfItfHtF+7RygSZ4pRytM8bVk+ka1g/vAoIBAA92TI0lCu8JlauZQ+VW +KIz0JQP0g3W9AjeFUswJSFr9MWrlbP/kRbdCCNL8775yMhkQHqRwKi9uTay5+Nqf +lyxBWyzkHqLhb9LbIe6dJWxiMrqHZWuEYvHDO8fjfTwGVbqAckHYOzZr4fAN+Pwj +iRLMUN8v4iQK1D4nMl49TSk6hLKltXY7qMMqZQqLGkwVglWlCOemiuf6WHQLhqnc +iXMRJqkQOBbRzPl9UiFs94FbKxJmy7m/kkmA2NolYnRZNht7bHwTRxFmc/zpIf0e +vx/Nm+OuZ66tFseP9Pab5htAg/y7rrPyRawNtetxE5h1/sTDJVgMwp5Uf/JYO+Ob +pTsCgf8dOKvV0/+iHbXpP+hbmBdsw6Umm1gY8k+jtr7M37azJ0P327ITf3qlUuEh +6m+GBZdRhIesDaACmeDFSgikzCpNpZIv0t1Bl2AmZjwW0jzPl3ro6AM/hJXtBOv5 +j0lgk3z+nVaG8w9YcOWX32iiaaYhJ+6kVInZPjRZVP/9kQanHrnuTagSuQ7+V+YV +v7rwkKGnGz7N6kx/1zGdJFkXE6gpJeanlpHCf8K838+BnaXVRr7ybE7JCCW9aAnH +ste/CxR35NRE39l2YYfDaywGk/9a5kI//xw2R39kW9nuDJiRNPE41eflvPsgq0g8 +pIE5OZ8C1iBFHldg/C7i0nPRZdc= +-----END PRIVATE KEY----- diff --git a/src/test/resources/cert/snakeoil.pem b/src/test/resources/cert/snakeoil.pem new file mode 100644 index 00000000..383e3f10 --- /dev/null +++ b/src/test/resources/cert/snakeoil.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFMzCCAxugAwIBAgIUYbvFAndTuJgW7CtZA2dt4jN8h1owDQYJKoZIhvcNAQEL +BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE +CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yNDA4MDcxODA4MTNaFw0yNTA4MDcx +ODA4MTNaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa +BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCkfdjW5PSC96VgguwqcG/tUaQy460vqI219kpwEKUFy5mmLPs5 +ca9vwMleeavrPtdpfbBeyvDHJDKNtKFl6iyNKVdZd4tgbDX8OmymVrz4VzTDh89+ +xbrHiYidQiMJDiI77WddQ9DhwuUjHqY9uPfZ9NncG5YZWjsZM7tSZi5wFHF7wzzq +PQOmS1b1fFkFhrBzUHaYRMzsRKDdNFA87YLOu6DBXZFfINEI6gyK70g5Pm3VuTdO +TJ/JZSHPltB97BbZdA6y4ts1LGHwMb7D3oRNcXApm/dwteyJu8KmN5PH5/uiUoPv +YdxuVB+bxL2C2hjqXk+UGUtES2zpKJtorjpWTQpPsfLRqmOWi6fXAyuGn9rKDXph +Ln/7J5jim/cyjT2De5xNtz9mfBL/uEqeNCnjtvQS58yJEvBvTGegqCr05MPopINR +M8by0SihtgjKgLxz1i6AKnCkviXthHRqCFgLLTpkRjs0/sjH3Wji5FudLruRzW9b +Iv03sBFwqrPY/fzUO6pNLO2RGBG91FTqhERiMsWA9/IfQbZ1WQjmq7AbEA8Xkf8a +vdlJg42pDXarjh00ZcjvsdSRCSJIcpKcZuNjc0t1dXeJs3QPmu5U8UX0zqNkbXg7 +S17DkKHENDOIdYH6nYn4aYfNQWrBz8QUGHb6lCZcpHwcq+TsNyyzpHprwQIDAQAB +oyEwHzAdBgNVHQ4EFgQUyWqhx221xSvVFJby74bybHAOQ4QwDQYJKoZIhvcNAQEL +BQADggIBADe/TWh6XZ4KrQLSOUuDz744K8aXcFOoKG0Lqq/F2hmeYu+HD6fS2L1A +Jvhiuf7E7qciAaI5pS0GzOFsQbRd0qO48QZ6SBf8V7zlhojzkukCn/oh25Sr14vQ +lVZmemnAI6SOaT0n7seitCpH/5j2H30Q8QSF2nZJVcQOMtleMLi/4/6r/aZjDq7o +Ced7WO+pcP+8Eda5FxLk+X6B6KmM/snob8yxt5bUiv25udjNq2Loci9BylaoZnYb +EYWN6j53bIRjlUoxzMw3u7ytJSyw4jSQ7ZdgOlPTdI96fG1JrKh4s0Kyt39NW4An +szTkvILHaLOn0Lc8CXRjuGKyBNZwIVjvg5e9Nn3y9oBUq27VGt/GXYmLBxevrYLo +/LZeBdJ/xgOMPArSUnecMJe0hP6P+Cz9BvM10ML5SvfK2MqIN/QZnWRng++/oTk1 +3UeiKpGZwOeYH9kzDnYlrUpRiUvziKIt1VVOm5lcD/ti6UKLa7WgQC5EEhugUwWm +Z0cM0VxizXCkNda9Jhkg2OtwVrNuF5ZqvI3KVGtk69MdyH3N6J3nbqWQUisKy0BD +jTuXAzYVwVd3/UQIQsiK8/1DIlXp6871dqN+wKwi7t10ZaWJ9W183l8vnJz/tZ41 +TRD7n0VcDwJceK1IlwcvWYNR/fkkzRC2H9PSHZeCWuxMK/iJBQ6a +-----END CERTIFICATE----- diff --git a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-1.json b/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-1.json similarity index 96% rename from core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-1.json rename to src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-1.json index 7c120543..96d6a400 100644 --- a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-1.json +++ b/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-1.json @@ -6,7 +6,7 @@ "status": "SUCCESS", "buildContentId": null, "temporaryBuild": false, - "scmUrl": "http://github.com/project-ncl/pnc.git", + "scmUrl": "https://github.com/project-ncl/pnc.git", "scmRevision": "57ebfa20374d708e232fc8b45f37def055300260", "scmTag": "repour-57ebfa20374d708e232fc8b45f37def055300260", "project": { diff --git a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-missing-tool-version.json b/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-missing-tool-version.json similarity index 100% rename from core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-missing-tool-version.json rename to src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-missing-tool-version.json diff --git a/core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-npm.json b/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-npm.json similarity index 100% rename from core/src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-npm.json rename to src/test/resources/org/jboss/pnc/causeway/brewclient/build-dto-npm.json diff --git a/core/src/test/resources/org/jboss/pnc/causeway/source/foobar.tar.gz b/src/test/resources/org/jboss/pnc/causeway/source/foobar.tar.gz similarity index 100% rename from core/src/test/resources/org/jboss/pnc/causeway/source/foobar.tar.gz rename to src/test/resources/org/jboss/pnc/causeway/source/foobar.tar.gz diff --git a/web/README.md b/web/README.md deleted file mode 100644 index 7e870ac0..00000000 --- a/web/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# reports-rest - -The `reports-rest` module is used to provide REST endpoints to: - -- obtain listings of white and black artifacts -- get dependency information of a project or GAV. - -## Documentation -The REST endpoints are documented using [Swagger](http://swagger.io/) - -## Adding a new JAX-RS class -Swagger imposes some restrictions on automatic scanning of JAX-RS classes. As -such, for now we'll have to specify the JAX-RS classes we want to activate in -the `ReportsRestActivator` class, method `addProjectResources`. diff --git a/web/pom.xml b/web/pom.xml deleted file mode 100644 index d022d270..00000000 --- a/web/pom.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - 4.0.0 - - - org.jboss.pnc.causeway - causeway - 3.0.3-SNAPSHOT - - - causeway-web - war - Causeway :: Web - - - - - org.jboss.pnc.causeway - causeway-core - provided - ejb - - - org.jboss.pnc.causeway - causeway-rest - provided - ejb - - - org.jboss.spec.javax.ws.rs - jboss-jaxrs-api_2.1_spec - provided - - - org.keycloak - keycloak-core - - - org.jboss.spec.javax.servlet - jboss-servlet-api_4.0_spec - - - com.fasterxml.jackson.core - jackson-annotations - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - - io.opentelemetry.instrumentation - opentelemetry-instrumentation-annotations - - - - - - - org.apache.maven.plugins - maven-war-plugin - - true - - - src/main/webapp - true - - **/*.html - - - - - - - - diff --git a/web/src/main/java/org/jboss/pnc/causeway/rest/ImportEndpoint.java b/web/src/main/java/org/jboss/pnc/causeway/rest/ImportEndpoint.java deleted file mode 100644 index b1614f12..00000000 --- a/web/src/main/java/org/jboss/pnc/causeway/rest/ImportEndpoint.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import org.jboss.pnc.api.causeway.dto.push.BuildImportRequest; -import org.jboss.pnc.causeway.ctl.ImportController; -import org.jboss.pnc.causeway.rest.spi.Import; - -import io.opentelemetry.instrumentation.annotations.SpanAttribute; -import io.opentelemetry.instrumentation.annotations.WithSpan; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.ws.rs.core.Response; - -@RequestScoped -public class ImportEndpoint implements Import { - - @Inject - private ImportController controller; - - @Inject - private UserService userSerivce; - - @Override - public Response testResponse(String var) { - return Response.ok(var).build(); - } - - @Override - @WithSpan - public Response importBuild(@SpanAttribute(value = "request") BuildImportRequest request) { - controller.importBuild( - request.getBuild(), - request.getCallback(), - userSerivce.getUsername(), - request.isReimport()); - return Response.accepted().build(); - } - -} diff --git a/web/src/main/java/org/jboss/pnc/causeway/rest/JacksonProvider.java b/web/src/main/java/org/jboss/pnc/causeway/rest/JacksonProvider.java deleted file mode 100644 index a2daa01b..00000000 --- a/web/src/main/java/org/jboss/pnc/causeway/rest/JacksonProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.jboss.pnc.causeway.rest; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; - -import javax.ws.rs.Consumes; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; - -/** - * Jackson Provider just to properly serialize the timestamp - */ -@Provider -@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_PATCH_JSON }) -@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_PATCH_JSON }) -public class JacksonProvider implements ContextResolver { - private final ObjectMapper objectMapper; - - public JacksonProvider() { - objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - - // write dates in ISO8601 format - objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); - } - - public ObjectMapper getMapper() { - return objectMapper; - } - - @Override - public ObjectMapper getContext(Class objectType) { - return objectMapper; - } -} diff --git a/web/src/main/java/org/jboss/pnc/causeway/rest/PncImportResourceEndpoint.java b/web/src/main/java/org/jboss/pnc/causeway/rest/PncImportResourceEndpoint.java deleted file mode 100644 index 4720033f..00000000 --- a/web/src/main/java/org/jboss/pnc/causeway/rest/PncImportResourceEndpoint.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import org.jboss.pnc.causeway.ctl.PncImportController; - -import io.opentelemetry.instrumentation.annotations.SpanAttribute; -import io.opentelemetry.instrumentation.annotations.WithSpan; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; - -import java.util.UUID; - -@RequestScoped -@Deprecated -public class PncImportResourceEndpoint implements PncImportResource { - - @Inject - private PncImportController pncController; - - @Inject - private UserService userSerivce; - - @Override - @WithSpan - public BrewPushMilestoneResponse importProductMilestone( - @SpanAttribute(value = "request") BrewPushMilestone request) { - String id = UUID.randomUUID().toString(); - - pncController.importMilestone( - request.getContent().getMilestoneId(), - request.getCallback(), - id, - userSerivce.getUsername()); - - return new BrewPushMilestoneResponse(new Callback(id)); - } - -} diff --git a/web/src/main/java/org/jboss/pnc/causeway/rest/ReportsRestActivator.java b/web/src/main/java/org/jboss/pnc/causeway/rest/ReportsRestActivator.java deleted file mode 100644 index 51de3978..00000000 --- a/web/src/main/java/org/jboss/pnc/causeway/rest/ReportsRestActivator.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import javax.ws.rs.ApplicationPath; -import javax.ws.rs.core.Application; - -import java.util.HashSet; -import java.util.Set; -import org.jboss.pnc.causeway.rest.filter.MDCLoggingFilter; - -/** - * - * @author Jozef Mrazek <jmrazek@redhat.com> - * - */ -@ApplicationPath("/rest") -public class ReportsRestActivator extends Application { - - @Override - public Set> getClasses() { - Set> resources = new HashSet<>(); - addProjectResources(resources); - return resources; - } - - /** - * Add all JAX-RS classes here to get activated! - * - * @param resources - */ - public void addProjectResources(Set> resources) { - resources.add(Root.class); - resources.add(PncImportResourceEndpoint.class); - resources.add(ImportEndpoint.class); - resources.add(UntagEndpoint.class); - resources.add(MDCLoggingFilter.class); - resources.add(JacksonProvider.class); - } -} diff --git a/web/src/main/java/org/jboss/pnc/causeway/rest/Root.java b/web/src/main/java/org/jboss/pnc/causeway/rest/Root.java deleted file mode 100644 index 06cb7252..00000000 --- a/web/src/main/java/org/jboss/pnc/causeway/rest/Root.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import org.jboss.pnc.api.dto.ComponentVersion; -import org.jboss.pnc.causeway.config.constants.BuildInformationConstants; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import java.time.ZonedDateTime; - -/** - * - * @author Jozef Mrazek <jmrazek@redhat.com> - * - */ -@Path("/") -public class Root { - - @GET - @Produces(MediaType.TEXT_HTML) - public String getDescription() { - return "

Causeway REST API

" + "\n"; - } - - @GET - @Path("/version") - @Produces(MediaType.APPLICATION_JSON) - public ComponentVersion getVersion() { - return ComponentVersion.builder() - .name("Causeway") - .version(BuildInformationConstants.VERSION) - .commit(BuildInformationConstants.COMMIT_HASH) - .builtOn(ZonedDateTime.parse(BuildInformationConstants.BUILD_TIME)) - .build(); - } - -} diff --git a/web/src/main/java/org/jboss/pnc/causeway/rest/UntagEndpoint.java b/web/src/main/java/org/jboss/pnc/causeway/rest/UntagEndpoint.java deleted file mode 100644 index c25dd40b..00000000 --- a/web/src/main/java/org/jboss/pnc/causeway/rest/UntagEndpoint.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. (jbrazdil@redhat.com) - * - * 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. - */ -package org.jboss.pnc.causeway.rest; - -import org.jboss.pnc.api.causeway.dto.untag.UntagRequest; -import org.jboss.pnc.causeway.ctl.ImportController; -import org.jboss.pnc.causeway.rest.spi.Untag; - -import io.opentelemetry.instrumentation.annotations.SpanAttribute; -import io.opentelemetry.instrumentation.annotations.WithSpan; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.ws.rs.core.Response; - -@RequestScoped -public class UntagEndpoint implements Untag { - - @Inject - private ImportController controller; - - @Override - @WithSpan - public Response untagBuild(@SpanAttribute(value = "request") UntagRequest request) { - controller.untagBuild(request.getBuild(), request.getCallback()); - return Response.accepted().build(); - } - -} diff --git a/web/src/main/java/org/jboss/pnc/causeway/rest/UserService.java b/web/src/main/java/org/jboss/pnc/causeway/rest/UserService.java deleted file mode 100644 index a960c3c0..00000000 --- a/web/src/main/java/org/jboss/pnc/causeway/rest/UserService.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.jboss.pnc.causeway.rest; - -import org.keycloak.KeycloakSecurityContext; - -import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; - -/** - * - * @author Honza Brázdil <jbrazdil@redhat.com> - */ -class UserService { - - @Inject - private HttpServletRequest sr; - - public String getUsername() { - KeycloakSecurityContext ksc = (KeycloakSecurityContext) sr - .getAttribute(KeycloakSecurityContext.class.getName()); - - if (ksc == null) { - throw new IllegalStateException("No user information. Is user logged in?"); - } - - return ksc.getToken().getPreferredUsername(); - } -} diff --git a/web/src/main/java/org/jboss/pnc/causeway/rest/filter/MDCLoggingFilter.java b/web/src/main/java/org/jboss/pnc/causeway/rest/filter/MDCLoggingFilter.java deleted file mode 100644 index c9d5173c..00000000 --- a/web/src/main/java/org/jboss/pnc/causeway/rest/filter/MDCLoggingFilter.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * JBoss, Home of Professional Open Source. - * Copyright 2014-2019 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. - * - * 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. - */ -package org.jboss.pnc.causeway.rest.filter; - -import org.jboss.pnc.common.log.MDCUtils; -import org.slf4j.MDC; - -import io.opentelemetry.api.trace.Span; - -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerRequestFilter; -import java.io.IOException; - -/** - * @author Matej Lazar - */ -public class MDCLoggingFilter implements ContainerRequestFilter { - - @Override - public void filter(ContainerRequestContext containerRequestContext) throws IOException { - MDC.clear(); - MDCUtils.setMDCFromRequestContext(containerRequestContext); - MDCUtils.addMDCFromOtelHeadersWithFallback(containerRequestContext, Span.current().getSpanContext(), true); - - } -} diff --git a/web/src/main/webapp/WEB-INF/beans.xml b/web/src/main/webapp/WEB-INF/beans.xml deleted file mode 100644 index 13bbf4fd..00000000 --- a/web/src/main/webapp/WEB-INF/beans.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - diff --git a/web/src/main/webapp/WEB-INF/jboss-web.xml b/web/src/main/webapp/WEB-INF/jboss-web.xml deleted file mode 100644 index 5aae075b..00000000 --- a/web/src/main/webapp/WEB-INF/jboss-web.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - true - \ No newline at end of file diff --git a/web/src/main/webapp/WEB-INF/web.xml b/web/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 58107dd9..00000000 --- a/web/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - causeway-web - - - - - - All Access for users on GET - /rest/* - GET - OPTIONS - - - - - - - Authorized users Access - /rest/* - POST - DELETE - PUT - TRACE - POST - - - pnc-app-causeway-user - - - - - pnc-app-causeway-user - - - -