Skip to content

Commit

Permalink
feat: add health-indicator for Aiven service
Browse files Browse the repository at this point in the history
  • Loading branch information
fhussonnois committed Sep 5, 2023
1 parent 8e1b14f commit 9d3ecb3
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static com.fasterxml.jackson.annotation.JsonInclude.Include;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import io.streamthoughts.jikkou.annotation.Reflectable;
import java.util.Collections;
Expand All @@ -31,6 +32,11 @@
* The {@link Health} wraps information about a service or sub-system.
*/
@Reflectable
@JsonPropertyOrder({
"name",
"status",
"details",
})
@JsonInclude(Include.NON_EMPTY)
public final class Health {

Expand All @@ -45,7 +51,7 @@ public final class Health {
/**
* Creates a new {@link Health} instance.
*
* @param name the status indicator name (may be {@code null}).
* @param name the status indicator name (maybe {@code null}).
* @param status the {@link Status} instance (cannot be {@code null}).
* @param details the status indicator details (cannot be {@code null}).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
package io.streamthoughts.jikkou.api.health;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.streamthoughts.jikkou.annotation.Reflectable;
import java.util.Objects;

@Reflectable
public record Status(String code) {

public static final Status UNKNOWN = new Status("UNKNOWN");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.streamthoughts.jikkou.extension.aiven.control.KafkaTopicAclEntryController;
import io.streamthoughts.jikkou.extension.aiven.control.SchemaRegistryAclEntryCollector;
import io.streamthoughts.jikkou.extension.aiven.control.SchemaRegistryAclEntryController;
import io.streamthoughts.jikkou.extension.aiven.health.AivenServiceHealthIndicator;
import io.streamthoughts.jikkou.extension.aiven.validation.SchemaRegistryAclEntryValidation;
import io.streamthoughts.jikkou.spi.ExtensionProvider;
import org.jetbrains.annotations.NotNull;
Expand All @@ -33,6 +34,7 @@ public class AivenExtensionsProvider implements ExtensionProvider {
@Override
public void registerExtensions(@NotNull ExtensionFactory factory,
@NotNull Configuration configuration) {
factory.register(AivenServiceHealthIndicator.class, AivenServiceHealthIndicator::new);
factory.register(KafkaTopicAclEntryCollector.class, KafkaTopicAclEntryCollector::new);
factory.register(KafkaTopicAclEntryController.class, KafkaTopicAclEntryController::new);
factory.register(SchemaRegistryAclEntryCollector.class, SchemaRegistryAclEntryCollector::new);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.streamthoughts.jikkou.extension.aiven.api.data.ListSchemaRegistryAclResponse;
import io.streamthoughts.jikkou.extension.aiven.api.data.MessageErrorsResponse;
import io.streamthoughts.jikkou.extension.aiven.api.data.SchemaRegistryAclEntry;
import io.streamthoughts.jikkou.extension.aiven.api.data.ServiceInformationResponse;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
Expand All @@ -34,9 +35,21 @@
/**
* REST API for Aiven (see <a href="https://api.aiven.io/doc/">https://api.aiven.io/doc/</a>)
*/
@Path("/project/{project}/service/{service_name}/")
@Path("/project/{project}/service/{service_name}")
public interface AivenApi extends AutoCloseable {

/**
* Get service information
*
* @param project Project name
* @param service Service name
*/
@GET
@Path("")
@Produces("application/json")
ServiceInformationResponse getServiceInformation(@PathParam("project") String project,
@PathParam("service_name") String service);

/**
* Add a Kafka ACL entry.
*
Expand All @@ -45,7 +58,7 @@ public interface AivenApi extends AutoCloseable {
* @param entry Kafka ACL entry
*/
@POST
@Path("acl")
@Path("/acl")
@Consumes("application/json")
ListKafkaAclResponse addKafkaAclEntry(@PathParam("project") String project,
@PathParam("service_name") String service,
Expand All @@ -58,7 +71,7 @@ ListKafkaAclResponse addKafkaAclEntry(@PathParam("project") String project,
* @param service Service name
*/
@GET
@Path("acl")
@Path("/acl")
@Produces("application/json")
ListKafkaAclResponse listKafkaAclEntries(@PathParam("project") String project,
@PathParam("service_name") String service);
Expand All @@ -71,7 +84,7 @@ ListKafkaAclResponse listKafkaAclEntries(@PathParam("project") String project,
* @param id Kafka ACL Entry ID
*/
@DELETE
@Path("acl/{kafka_acl_id}")
@Path("/acl/{kafka_acl_id}")
@Produces("application/json")
ListKafkaAclResponse deleteKafkaAclEntry(@PathParam("project") String project,
@PathParam("service_name") String service,
Expand All @@ -84,7 +97,7 @@ ListKafkaAclResponse deleteKafkaAclEntry(@PathParam("project") String project,
* @param service Service name
*/
@GET
@Path("kafka/schema-registry/acl")
@Path("/kafka/schema-registry/acl")
@Produces("application/json")
ListSchemaRegistryAclResponse listSchemaRegistryAclEntries(@PathParam("project") String project,
@PathParam("service_name") String service);
Expand All @@ -97,7 +110,7 @@ ListSchemaRegistryAclResponse listSchemaRegistryAclEntries(@PathParam("project")
* @param entry Schema Registry ACL entries
*/
@POST
@Path("kafka/schema-registry/acl")
@Path("/kafka/schema-registry/acl")
@Consumes("application/json")
ListSchemaRegistryAclResponse addSchemaRegistryAclEntry(@PathParam("project") String project,
@PathParam("service_name") String service,
Expand All @@ -111,7 +124,7 @@ ListSchemaRegistryAclResponse addSchemaRegistryAclEntry(@PathParam("project") St
* @param id Kafka ACL Entry ID
*/
@DELETE
@Path("kafka/schema-registry/acl/{schema_registry_acl_id}")
@Path("/kafka/schema-registry/acl/{schema_registry_acl_id}")
@Produces("application/json")
ListSchemaRegistryAclResponse deleteSchemaRegistryAclEntry(@PathParam("project") String project,
@PathParam("service_name") String service,
Expand All @@ -124,7 +137,7 @@ ListSchemaRegistryAclResponse deleteSchemaRegistryAclEntry(@PathParam("project")
* @param service Service name
*/
@GET
@Path("quota")
@Path("/quota")
@Produces("application/json")
ListKafkaQuotaResponse listKafkaQuotas(@PathParam("project") String project,
@PathParam("service_name") String service);
Expand All @@ -136,7 +149,7 @@ ListKafkaQuotaResponse listKafkaQuotas(@PathParam("project") String project,
* @param service Service name
*/
@POST
@Path("quota")
@Path("/quota")
@Consumes("application/json")
MessageErrorsResponse createKafkaQuota(@PathParam("project") String project,
@PathParam("service_name") String service,
Expand All @@ -149,7 +162,7 @@ MessageErrorsResponse createKafkaQuota(@PathParam("project") String project,
* @param service Service name
*/
@DELETE
@Path("quota")
@Path("/quota")
@Consumes("application/json")
MessageErrorsResponse deleteKafkaQuota(@PathParam("project") String project,
@PathParam("service_name") String service,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.streamthoughts.jikkou.extension.aiven.api.data.ListSchemaRegistryAclResponse;
import io.streamthoughts.jikkou.extension.aiven.api.data.MessageErrorsResponse;
import io.streamthoughts.jikkou.extension.aiven.api.data.SchemaRegistryAclEntry;
import io.streamthoughts.jikkou.extension.aiven.api.data.ServiceInformationResponse;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;

Expand All @@ -48,6 +49,16 @@ public AivenApiClient(final @NotNull AivenApi api,
this.service = Objects.requireNonNull(service, "service must not be null");
}

/**
* Get service information
*
* @see AivenApi#getServiceInformation(String, String)
*/
public ServiceInformationResponse getServiceInformation() {
return this.api.getServiceInformation(project, service);
}


/**
* Add a Kafka ACL entry.
*
Expand Down Expand Up @@ -115,7 +126,7 @@ public MessageErrorsResponse createKafkaQuota(final KafkaQuotaEntry entry) {
}

/**
* List Kfka quota
* List Kafka quota
*
* @see AivenApi#listSchemaRegistryAclEntries(String, String)
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2023 The original authors
*
* 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 io.streamthoughts.jikkou.extension.aiven.api.data;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.streamthoughts.jikkou.annotation.Reflectable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

@Reflectable
public final class ServiceInformationResponse {

/**
* The service information
*/
private final Map<String, Object> service;

/**
* List of errors occurred during request processing
*/
private final List<Error> errors;

/**
* Printable result of the request
*/
private final String message;

@JsonCreator
public ServiceInformationResponse(@JsonProperty("service") Map<String, Object> service,
@JsonProperty("errors") List<Error> errors,
@JsonProperty("message") String message) {
this.service = service;
this.errors = errors;
this.message = message;
}

public Map<String, Object> service() {
return service;
}

public List<Error> errors() {
return Optional.ofNullable(errors).orElseGet(Collections::emptyList);
}

public String message() {
return message;
}

/** {@inheritDoc} **/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ServiceInformationResponse that = (ServiceInformationResponse) o;
return Objects.equals(service, that.service) && Objects.equals(errors, that.errors) && Objects.equals(message, that.message);
}

/** {@inheritDoc} **/
@Override
public int hashCode() {
return Objects.hash(service, errors, message);
}
/** {@inheritDoc} **/
@Override
public String toString() {
return "ServiceInformation{" +
"service=" + service +
", errors=" + errors +
", message='" + message + '\'' +
'}';
}
}
Loading

0 comments on commit 9d3ecb3

Please sign in to comment.