aboutsummaryrefslogtreecommitdiffstats
path: root/athenz-identity-provider-service
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2021-03-22 16:46:58 +0100
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2021-03-22 16:46:58 +0100
commit8ef3b717ccb4f44fc79f44f768bbf6e6da12ff1d (patch)
tree3d69ae1d953c373e24c04072d86d7a343d2edc7b /athenz-identity-provider-service
parent81871d3f99f2155b0d81b347b61ac685a7bbc13e (diff)
Rewrite JAX-RS resources in athenz-identity-provider-service as request handlers
Diffstat (limited to 'athenz-identity-provider-service')
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityProviderRequestHandler.java101
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentResource.java67
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java3
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmationResource.java42
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceRefreshResource.java44
5 files changed, 103 insertions, 154 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityProviderRequestHandler.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityProviderRequestHandler.java
new file mode 100644
index 00000000000..ef98893c0f4
--- /dev/null
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityProviderRequestHandler.java
@@ -0,0 +1,101 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.athenz.instanceproviderservice;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.google.inject.Inject;
+import com.yahoo.container.jdisc.LoggingRequestHandler;
+import com.yahoo.restapi.RestApi;
+import com.yahoo.restapi.RestApiException;
+import com.yahoo.restapi.RestApiRequestHandler;
+import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper;
+import com.yahoo.vespa.athenz.identityprovider.api.IdentityType;
+import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity;
+import com.yahoo.vespa.hosted.athenz.instanceproviderservice.identitydocument.IdentityDocumentGenerator;
+import com.yahoo.vespa.hosted.athenz.instanceproviderservice.instanceconfirmation.InstanceConfirmation;
+import com.yahoo.vespa.hosted.athenz.instanceproviderservice.instanceconfirmation.InstanceValidator;
+
+import java.util.logging.Level;
+
+/**
+ * Handler implementing the Athenz Identity Provider API (Copper Argos).
+ *
+ * @author bjorncs
+ */
+public class IdentityProviderRequestHandler extends RestApiRequestHandler<IdentityProviderRequestHandler> {
+
+ private final IdentityDocumentGenerator documentGenerator;
+ private final InstanceValidator instanceValidator;
+
+ @Inject
+ public IdentityProviderRequestHandler(LoggingRequestHandler.Context context,
+ IdentityDocumentGenerator documentGenerator,
+ InstanceValidator instanceValidator) {
+ super(context, IdentityProviderRequestHandler::createRestApi);
+ this.documentGenerator = documentGenerator;
+ this.instanceValidator = instanceValidator;
+ }
+
+ private static RestApi createRestApi(IdentityProviderRequestHandler self) {
+ return RestApi.builder()
+ .addRoute(RestApi.route("/athenz/v1/provider/identity-document/node/{host}")
+ .get(self::getNodeIdentityDocument))
+ .addRoute(RestApi.route("/athenz/v1/provider/identity-document/tenant/{host}")
+ .get(self::getTenantIdentityDocument))
+ .addRoute(RestApi.route("/athenz/v1/provider/instance")
+ .post(self::confirmInstance))
+ .addRoute(RestApi.route("/athenz/v1/provider/refresh")
+ .post(self::confirmInstanceRefresh))
+ // Overriding object mapper to change serialization of timestamps
+ .setObjectMapper(new ObjectMapper()
+ .registerModule(new JavaTimeModule())
+ .registerModule(new Jdk8Module())
+ .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true))
+ .build();
+ }
+
+ private SignedIdentityDocumentEntity getNodeIdentityDocument(RestApi.RequestContext context) {
+ String host = context.pathParameters().getString("host").orElse(null);
+ return getIdentityDocument(host, IdentityType.NODE);
+ }
+
+ private SignedIdentityDocumentEntity getTenantIdentityDocument(RestApi.RequestContext context) {
+ String host = context.pathParameters().getString("host").orElse(null);
+ return getIdentityDocument(host, IdentityType.TENANT);
+ }
+
+ private InstanceConfirmation confirmInstance(RestApi.RequestContext context) {
+ InstanceConfirmation instanceConfirmation = context.requestContentOrThrow().consumeJacksonEntity(InstanceConfirmation.class);
+ log.log(Level.FINE, instanceConfirmation.toString());
+ if (!instanceValidator.isValidInstance(instanceConfirmation)) {
+ log.log(Level.SEVERE, "Invalid instance: " + instanceConfirmation);
+ throw new RestApiException.Forbidden("Instance is invalid");
+ }
+ return instanceConfirmation;
+ }
+
+ private InstanceConfirmation confirmInstanceRefresh(RestApi.RequestContext context) {
+ InstanceConfirmation instanceConfirmation = context.requestContentOrThrow().consumeJacksonEntity(InstanceConfirmation.class);
+ log.log(Level.FINE, instanceConfirmation.toString());
+ if (!instanceValidator.isValidRefresh(instanceConfirmation)) {
+ log.log(Level.SEVERE, "Invalid instance refresh: " + instanceConfirmation);
+ throw new RestApiException.Forbidden("Instance is invalid");
+ }
+ return instanceConfirmation;
+ }
+
+ private SignedIdentityDocumentEntity getIdentityDocument(String hostname, IdentityType identityType) {
+ if (hostname == null) {
+ throw new RestApiException.BadRequest("The 'hostname' query parameter is missing");
+ }
+ try {
+ return EntityBindingsMapper.toSignedIdentityDocumentEntity(documentGenerator.generateSignedIdentityDocument(hostname, identityType));
+ } catch (Exception e) {
+ String message = String.format("Unable to generate identity document for '%s': %s", hostname, e.getMessage());
+ log.log(Level.SEVERE, message, e);
+ throw new RestApiException.InternalServerError(message, e);
+ }
+ }
+}
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentResource.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentResource.java
deleted file mode 100644
index cb0b1e0557f..00000000000
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentResource.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.athenz.instanceproviderservice.identitydocument;
-
-import com.google.inject.Inject;
-import com.yahoo.container.jaxrs.annotation.Component;
-import java.util.logging.Level;
-import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper;
-import com.yahoo.vespa.athenz.identityprovider.api.IdentityType;
-import com.yahoo.vespa.athenz.identityprovider.api.bindings.IdentityDocumentApi;
-import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity;
-
-import javax.ws.rs.BadRequestException;
-import javax.ws.rs.GET;
-import javax.ws.rs.InternalServerErrorException;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import java.util.logging.Logger;
-
-/**
- * An API that issues signed identity documents for Vespa nodes.
- *
- * @author bjorncs
- */
-@Path("/identity-document")
-public class IdentityDocumentResource implements IdentityDocumentApi {
-
- private static final Logger log = Logger.getLogger(IdentityDocumentResource.class.getName());
-
- private final IdentityDocumentGenerator identityDocumentGenerator;
-
- @Inject
- public IdentityDocumentResource(@Component IdentityDocumentGenerator identityDocumentGenerator) {
- this.identityDocumentGenerator = identityDocumentGenerator;
- }
-
- private SignedIdentityDocumentEntity getIdentityDocument(String hostname, IdentityType identityType) {
- if (hostname == null) {
- throw new BadRequestException("The 'hostname' query parameter is missing");
- }
- try {
- return EntityBindingsMapper.toSignedIdentityDocumentEntity(identityDocumentGenerator.generateSignedIdentityDocument(hostname, identityType));
- } catch (Exception e) {
- String message = String.format("Unable to generate identity doument for '%s': %s", hostname, e.getMessage());
- log.log(Level.SEVERE, message, e);
- throw new InternalServerErrorException(message, e);
- }
- }
-
- @GET
- @Produces(MediaType.APPLICATION_JSON)
- @Path("/node/{host}")
- @Override
- public SignedIdentityDocumentEntity getNodeIdentityDocument(@PathParam("host") String host) {
- return getIdentityDocument(host, IdentityType.NODE);
- }
-
- @GET
- @Produces(MediaType.APPLICATION_JSON)
- @Path("/tenant/{host}")
- @Override
- public SignedIdentityDocumentEntity getTenantIdentityDocument(@PathParam("host") String host) {
- return getIdentityDocument(host, IdentityType.TENANT);
- }
-
-}
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java
index e6dd40faaca..0c6b5e67a80 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java
@@ -13,6 +13,7 @@ import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.yahoo.restapi.RestApi;
import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity;
import com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.Utils;
@@ -26,7 +27,7 @@ import java.util.Objects;
*
* @author bjorncs
*/
-public class InstanceConfirmation {
+public class InstanceConfirmation implements RestApi.JacksonRequestEntity {
@JsonProperty("provider") public final String provider;
@JsonProperty("domain") public final String domain;
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmationResource.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmationResource.java
deleted file mode 100644
index dbe26d3a6bb..00000000000
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmationResource.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.athenz.instanceproviderservice.instanceconfirmation;
-
-import com.google.inject.Inject;
-import com.yahoo.container.jaxrs.annotation.Component;
-import java.util.logging.Level;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.ForbiddenException;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import java.util.logging.Logger;
-
-/**
- * @author bjorncs
- */
-@Path("/instance")
-public class InstanceConfirmationResource {
-
- private static final Logger log = Logger.getLogger(InstanceConfirmationResource.class.getName());
-
- private final InstanceValidator instanceValidator;
-
- @Inject
- public InstanceConfirmationResource(@Component InstanceValidator instanceValidator) {
- this.instanceValidator = instanceValidator;
- }
-
- @POST
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public InstanceConfirmation confirmInstance(InstanceConfirmation instanceConfirmation) {
- log.log(Level.FINE, instanceConfirmation.toString());
- if (!instanceValidator.isValidInstance(instanceConfirmation)) {
- log.log(Level.SEVERE, "Invalid instance: " + instanceConfirmation);
- throw new ForbiddenException("Instance is invalid");
- }
- return instanceConfirmation;
- }
-}
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceRefreshResource.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceRefreshResource.java
deleted file mode 100644
index b49e03658e6..00000000000
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceRefreshResource.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.athenz.instanceproviderservice.instanceconfirmation;
-
-import com.google.inject.Inject;
-import com.yahoo.container.jaxrs.annotation.Component;
-import java.util.logging.Level;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.ForbiddenException;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import java.util.logging.Logger;
-
-/**
- * ZTS calls this resource when it's requested to refresh an instance certificate
- *
- * @author bjorncs
- */
-@Path("/refresh")
-public class InstanceRefreshResource {
-
- private static final Logger log = Logger.getLogger(InstanceRefreshResource.class.getName());
-
- private final InstanceValidator instanceValidator;
-
- @Inject
- public InstanceRefreshResource(@Component InstanceValidator instanceValidator) {
- this.instanceValidator = instanceValidator;
- }
-
- @POST
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public InstanceConfirmation confirmInstanceRefresh(InstanceConfirmation instanceConfirmation) {
- log.log(Level.FINE, instanceConfirmation.toString());
- if (!instanceValidator.isValidRefresh(instanceConfirmation)) {
- log.log(Level.SEVERE, "Invalid instance refresh: " + instanceConfirmation);
- throw new ForbiddenException("Instance is invalid");
- }
- return instanceConfirmation;
- }
-}