Skip to content

Commit

Permalink
RHCLOUD-24930
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenneg committed Feb 2, 2024
1 parent 2909da0 commit 0683f98
Show file tree
Hide file tree
Showing 15 changed files with 301 additions and 22 deletions.
21 changes: 16 additions & 5 deletions .rhcicd/clowdapp-connector-servicenow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ objects:
envName: ${ENV_NAME}
testing:
iqePlugin: eventing
dependencies:
- sources-api
optionalDependencies:
- drift
- notifications-backend
Expand Down Expand Up @@ -65,6 +67,8 @@ objects:
value: ${NOTIFICATIONS_CONNECTOR_ENDPOINT_CACHE_MAX_SIZE}
- name: NOTIFICATIONS_CONNECTOR_HTTP_CONNECT_TIMEOUT_MS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_CONNECT_TIMEOUT_MS}
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS}
- name: NOTIFICATIONS_CONNECTOR_HTTP_SOCKET_TIMEOUT_MS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_SOCKET_TIMEOUT_MS}
- name: NOTIFICATIONS_CONNECTOR_KAFKA_INCOMING_MAX_POLL_INTERVAL_MS
Expand All @@ -83,8 +87,13 @@ objects:
value: ${NOTIFICATIONS_CONNECTOR_SEDA_CONCURRENT_CONSUMERS}
- name: NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE
value: ${NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE}
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS}
- name: NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED
value: ${NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED}
- name: NOTIFICATIONS_CONNECTOR_SOURCES_PSK
valueFrom:
secretKeyRef:
name: sources-api-psk
key: psk
- name: QUARKUS_HTTP_PORT
value: ${QUARKUS_HTTP_PORT}
- name: QUARKUS_LOG_CATEGORY__COM_REDHAT_CLOUD_NOTIFICATIONS__LEVEL
Expand Down Expand Up @@ -152,6 +161,9 @@ parameters:
- name: NOTIFICATIONS_CONNECTOR_HTTP_CONNECT_TIMEOUT_MS
description: Maximum time in milliseconds allowed to establish an HTTP connection
value: "2500"
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
description: Add flags on connector response to let engine disable endpoint regarding HTTP error type
value: "true"
- name: NOTIFICATIONS_CONNECTOR_HTTP_SOCKET_TIMEOUT_MS
description: Maximum time in milliseconds allowed to wait for HTTP data
value: "2500"
Expand All @@ -170,12 +182,11 @@ parameters:
- name: NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE
description: Maximum capacity of the SEDA queue
value: "20"
- name: NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED
value: "false"
- name: NOTIFICATIONS_LOG_LEVEL
description: Log level of Notifications
value: INFO
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
description: Add flags on connector response to let engine disable endpoint regarding HTTP error type
value: "true"
- name: QUARKUS_HTTP_PORT
description: Quarkus HTTP server port, defaulting to the default Clowder private port
value: "9000"
Expand Down
21 changes: 16 additions & 5 deletions .rhcicd/clowdapp-connector-splunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ objects:
envName: ${ENV_NAME}
testing:
iqePlugin: eventing
dependencies:
- sources-api
optionalDependencies:
- drift
- notifications-backend
Expand Down Expand Up @@ -65,6 +67,8 @@ objects:
value: ${NOTIFICATIONS_CONNECTOR_ENDPOINT_CACHE_MAX_SIZE}
- name: NOTIFICATIONS_CONNECTOR_HTTP_CONNECT_TIMEOUT_MS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_CONNECT_TIMEOUT_MS}
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS}
- name: NOTIFICATIONS_CONNECTOR_HTTP_SOCKET_TIMEOUT_MS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_SOCKET_TIMEOUT_MS}
- name: NOTIFICATIONS_CONNECTOR_KAFKA_INCOMING_MAX_POLL_INTERVAL_MS
Expand All @@ -83,8 +87,13 @@ objects:
value: ${NOTIFICATIONS_CONNECTOR_SEDA_CONCURRENT_CONSUMERS}
- name: NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE
value: ${NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE}
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS}
- name: NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED
value: ${NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED}
- name: NOTIFICATIONS_CONNECTOR_SOURCES_PSK
valueFrom:
secretKeyRef:
name: sources-api-psk
key: psk
- name: QUARKUS_HTTP_PORT
value: ${QUARKUS_HTTP_PORT}
- name: QUARKUS_LOG_CATEGORY__COM_REDHAT_CLOUD_NOTIFICATIONS__LEVEL
Expand Down Expand Up @@ -152,6 +161,9 @@ parameters:
- name: NOTIFICATIONS_CONNECTOR_HTTP_CONNECT_TIMEOUT_MS
description: Maximum time in milliseconds allowed to establish an HTTP connection
value: "2500"
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
description: Add flags on connector response to let engine disable endpoint regarding HTTP error type
value: "true"
- name: NOTIFICATIONS_CONNECTOR_HTTP_SOCKET_TIMEOUT_MS
description: Maximum time in milliseconds allowed to wait for HTTP data
value: "2500"
Expand All @@ -170,12 +182,11 @@ parameters:
- name: NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE
description: Maximum capacity of the SEDA queue
value: "20"
- name: NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED
value: "false"
- name: NOTIFICATIONS_LOG_LEVEL
description: Log level of Notifications
value: INFO
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
description: Add flags on connector response to let engine disable endpoint regarding HTTP error type
value: "true"
- name: QUARKUS_HTTP_PORT
description: Quarkus HTTP server port, defaulting to the default Clowder private port
value: "9000"
Expand Down
21 changes: 16 additions & 5 deletions .rhcicd/clowdapp-connector-webhook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ objects:
envName: ${ENV_NAME}
testing:
iqePlugin: notifications
dependencies:
- sources-api
optionalDependencies:
- notifications-backend
kafkaTopics:
Expand Down Expand Up @@ -65,6 +67,8 @@ objects:
value: ${NOTIFICATIONS_CONNECTOR_HTTP_CONNECT_TIMEOUT_MS}
- name: NOTIFICATIONS_CONNECTOR_HTTP_CONNECTIONS_PER_ROUTE
value: ${NOTIFICATIONS_CONNECTOR_HTTP_CONNECTIONS_PER_ROUTE}
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS}
- name: NOTIFICATIONS_CONNECTOR_HTTP_MAX_TOTAL_CONNECTIONS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_MAX_TOTAL_CONNECTIONS}
- name: NOTIFICATIONS_CONNECTOR_HTTP_SOCKET_TIMEOUT_MS
Expand All @@ -85,8 +89,13 @@ objects:
value: ${NOTIFICATIONS_CONNECTOR_SEDA_CONCURRENT_CONSUMERS}
- name: NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE
value: ${NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE}
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
value: ${NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS}
- name: NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED
value: ${NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED}
- name: NOTIFICATIONS_CONNECTOR_SOURCES_PSK
valueFrom:
secretKeyRef:
name: sources-api-psk
key: psk
- name: QUARKUS_HTTP_PORT
value: ${QUARKUS_HTTP_PORT}
- name: QUARKUS_LOG_CATEGORY__COM_REDHAT_CLOUD_NOTIFICATIONS__LEVEL
Expand Down Expand Up @@ -157,6 +166,9 @@ parameters:
- name: NOTIFICATIONS_CONNECTOR_HTTP_CONNECTIONS_PER_ROUTE
description: Maximum number of HTTP connections per route
value: "20"
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
description: Add flags on connector response to let engine disable endpoint regarding HTTP error type
value: "true"
- name: NOTIFICATIONS_CONNECTOR_HTTP_MAX_TOTAL_CONNECTIONS
description: Maximum number of HTTP connections
value: "200"
Expand All @@ -178,12 +190,11 @@ parameters:
- name: NOTIFICATIONS_CONNECTOR_SEDA_QUEUE_SIZE
description: Maximum capacity of the SEDA queue
value: "20"
- name: NOTIFICATIONS_CONNECTOR_SOURCES_ENABLED
value: "false"
- name: NOTIFICATIONS_LOG_LEVEL
description: Log level of Notifications
value: INFO
- name: NOTIFICATIONS_CONNECTOR_HTTP_DISABLE_FAULTY_ENDPOINTS
description: Add flags on connector response to let engine disable endpoint regarding HTTP error type
value: "true"
- name: QUARKUS_HTTP_PORT
description: Quarkus HTTP server port, defaulting to the default Clowder private port
value: "9000"
Expand Down
75 changes: 75 additions & 0 deletions connector-common-sources/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<artifactId>notifications-connector-common-sources</artifactId>

<parent>
<groupId>com.redhat.cloud.notifications</groupId>
<artifactId>notifications-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<dependencies>

<!-- Scope: compile -->

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-fault-tolerance</artifactId>
</dependency>

</dependencies>

<build>
<plugins>

<!-- The following plugin is required to inject beans from this module into other modules. -->
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.2.3</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>

<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemPropertyVariables>
</configuration>
</plugin>

</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.redhat.cloud.notifications.connector.sources;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Secret {

public String username;
public String password;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.redhat.cloud.notifications.connector.sources;

import io.quarkus.rest.client.reactive.ClientExceptionMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.faulttolerance.Retry;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.reactive.RestPath;

/**
* <p>REST Client for the Sources API. The OpenAPI spec is available at:</p>
*
* <ul>
* <li><a href="https://console.stage.redhat.com/docs/api/sources/v3.1">OpenApi v3.1 in the stage environment.</a></li>
* <li><a href="https://console.redhat.com/docs/api/sources/v3.1">OpenApi v3.1 in the production environment.</a></li>
* <li><a href="https://github.com/RedHatInsights/sources-api-go/blob/main/public/openapi-3-v3.1.json">OpenApi v3.1 JSON file on GitHub.</a></li>
* </ul>
*
* <p>Please be aware of the following:</p>
*
* <ul>
* <li>If sources is using a database backend, only the {@link Secret#password} field will get encrypted.</li>
* <li>On the other hand, if sources is using the AWS Secrets Manager, then the whole secret will get encrypted.</li>
* </ul>
*
* <p>The authentication to Sources works by using a service-to-service PSK that will be sent in the header that
* Sources expects. At the same time, the organization id will be sent so that Sources knows to which tenants belongs
* the operation that is going to be performed.</p>
*/
@RegisterRestClient(configKey = "sources")
public interface SourcesClient {

/**
* Get a single secret from Sources. In this case we need to hit the internal endpoint —which is only available for
* requests coming from inside the cluster— to be able to get the password of these secrets.
* @param xRhSourcesOrgId the organization id related to this operation for the tenant identification.
* @param xRhSourcesPsk the sources PSK required for the authorization.
* @param id the secret id.
* @return a {@link Secret} instance.
*/
@GET
@Path("/internal/v2.0/secrets/{id}")
@Retry
Secret getById(
@HeaderParam("x-rh-sources-org-id") @NotBlank String xRhSourcesOrgId,
@HeaderParam("x-rh-sources-psk") @NotBlank String xRhSourcesPsk,
@RestPath long id
);

/**
* Throws a runtime exception with the client's response for an easier debugging.
* @param response the received response from Sources.
* @return the {@link RuntimeException} to be thrown.
*/
@ClientExceptionMapper
static RuntimeException toException(final Response response) {
final var errMessage = String.format("Sources responded with a %s status: %s", response.getStatus(), response.readEntity(String.class));

throw new WebApplicationException(errMessage, response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.redhat.cloud.notifications.connector.sources;

public class SourcesExchangeProperty {

public static final String SECRET_ID = "secretId";
public static final String SECRET_PASSWORD = "secretPassword";
public static final String SECRET_USERNAME = "secretUsername";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.redhat.cloud.notifications.connector.sources;

import io.quarkus.logging.Log;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import static com.redhat.cloud.notifications.connector.ExchangeProperty.ORG_ID;
import static com.redhat.cloud.notifications.connector.sources.SourcesExchangeProperty.SECRET_ID;
import static com.redhat.cloud.notifications.connector.sources.SourcesExchangeProperty.SECRET_PASSWORD;
import static com.redhat.cloud.notifications.connector.sources.SourcesExchangeProperty.SECRET_USERNAME;

@ApplicationScoped
public class SourcesProcessor implements Processor {

private static final String SOURCES_ENABLED = "notifications.connector.sources.enabled";
private static final String SOURCES_PSK = "notifications.connector.sources.psk";

@ConfigProperty(name = SOURCES_ENABLED, defaultValue = "false")
boolean sourcesEnabled;

@ConfigProperty(name = SOURCES_PSK)
String sourcesPsk;

@Inject
@RestClient
SourcesClient sourcesClient;

@Override
public void process(Exchange exchange) {
if (sourcesEnabled) {
// TODO metrics like engine
Long secretId = exchange.getProperty(SECRET_ID, Long.class);
if (secretId != null) {
String orgId = exchange.getProperty(ORG_ID, String.class);
Secret secret = sourcesClient.getById(orgId, sourcesPsk, secretId);
if (secret.username != null) {
exchange.setProperty(SECRET_USERNAME, secret.username);
}
if (secret.password != null) {
exchange.setProperty(SECRET_PASSWORD, secret.password);
}


// TODO log
}
}
}
}
Loading

0 comments on commit 0683f98

Please sign in to comment.