@Override public final void get(final X500Principal subjectDn, final Handler<AsyncResult<TenantResult<JsonObject>>> resultHandler) { get(subjectDn, NoopSpan.INSTANCE, resultHandler); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void get(final String tenantId, final Span span, final Handler<AsyncResult<TenantResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
final JsonObject payload = request.getJsonPayload(); final Span span = newChildSpan(SPAN_NAME_GET_TENANT, request.getSpanContext(), tenantId); final Future<EventBusMessage> resultFuture; if (tenantId == null && payload == null) { span.log("using deprecated variant of get tenant request"); resultFuture = processGetByIdRequest(request, tenantId, span); final String tenantIdFromPayload = getTypesafeValueForField(String.class, payload, TenantConstants.FIELD_PAYLOAD_TENANT_ID); final String subjectDn = getTypesafeValueForField(String.class, payload, TenantConstants.FIELD_PAYLOAD_SUBJECT_DN); log.debug("retrieving tenant [id: {}]", tenantIdFromPayload); span.setTag(MessageHelper.APP_PROPERTY_TENANT_ID, tenantIdFromPayload); resultFuture = processGetByIdRequest(request, tenantIdFromPayload, span); } else { span.setTag(TAG_SUBJECT_DN_NAME, subjectDn); resultFuture = processGetByCaRequest(request, subjectDn, span); return finishSpanOnFutureCompletion(span, resultFuture);
Future<EventBusMessage> processGetRequest(final EventBusMessage request) { final String tenantId = request.getTenant(); final JsonObject payload = request.getJsonPayload(); if (tenantId == null && payload == null) { log.debug("request does not contain any query parameters"); return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST)); } else if (tenantId != null) { // deprecated API log.debug("retrieving tenant [{}] using deprecated variant of get tenant request", tenantId); return processGetByIdRequest(request, tenantId); } else { final String tenantIdFromPayload = getTypesafeValueForField(String.class, payload, TenantConstants.FIELD_PAYLOAD_TENANT_ID); final String subjectDn = getTypesafeValueForField(String.class, payload, TenantConstants.FIELD_PAYLOAD_SUBJECT_DN); if (tenantIdFromPayload == null && subjectDn == null) { log.debug("payload does not contain any query parameters"); return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST)); } else if (tenantIdFromPayload != null) { log.debug("retrieving tenant [id: {}]", tenantIdFromPayload); return processGetByIdRequest(request, tenantIdFromPayload); } else { return processGetByCaRequest(request, subjectDn); } } }
/** * Processes a Tenant API request message received via the vert.x event bus. * <p> * This method validates the request payload against the Tenant API specification * before invoking the corresponding {@code TenantService} methods. * * @param request The request message. * @return A future indicating the outcome of the service invocation. * @throws NullPointerException If the request message is {@code null}. */ @Override public Future<EventBusMessage> processRequest(final EventBusMessage request) { Objects.requireNonNull(request); switch (TenantConstants.TenantAction.from(request.getOperation())) { case get: return processGetRequest(request); default: return processCustomTenantMessage(request); } }
private Future<EventBusMessage> processGetByCaRequest(final EventBusMessage request, final String subjectDn) { try { final X500Principal dn = new X500Principal(subjectDn); log.debug("retrieving tenant [subject DN: {}]", subjectDn); final Future<TenantResult<JsonObject>> getResult = Future.future(); get(dn, getResult.completer()); return getResult.map(tr -> { final EventBusMessage response = request.getResponse(tr.getStatus()) .setJsonPayload(tr.getPayload()) .setCacheDirective(tr.getCacheDirective()); if (tr.isOk() && tr.getPayload() != null) { response.setTenant(getTypesafeValueForField(String.class, tr.getPayload(), TenantConstants.FIELD_PAYLOAD_TENANT_ID)); } return response; }); } catch (final IllegalArgumentException e) { // the given subject DN is invalid log.debug("cannot parse subject DN [{}] provided by client", subjectDn); return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST)); } }
/** * Verifies that the base service routes a deprecated request for retrieving * a tenant by its identifier to the corresponding <em>get</em> method. * * @param ctx The vert.x test context. */ @Test public void testDeprecatedGetByIdSucceeds(final TestContext ctx) { final EventBusMessage request = EventBusMessage.forOperation(TenantConstants.TenantAction.get.toString()) .setJsonPayload(new JsonObject().put(TenantConstants.FIELD_PAYLOAD_TENANT_ID, "my-tenant")); tenantService.processRequest(request).setHandler(ctx.asyncAssertSuccess(response -> { ctx.assertEquals(HttpURLConnection.HTTP_OK, response.getStatus()); ctx.assertEquals("getById", response.getJsonPayload().getString("operation")); })); }
/** * Processes a Tenant API request message received via the vert.x event bus. * <p> * This method validates the request payload against the Tenant API specification * before invoking the corresponding {@code TenantService} methods. * * @param request The request message. * @return A future indicating the outcome of the service invocation. * @throws NullPointerException If the request message is {@code null}. */ @Override public Future<EventBusMessage> processRequest(final EventBusMessage request) { Objects.requireNonNull(request); switch (TenantConstants.TenantAction.from(request.getOperation())) { case get: return processGetRequest(request); default: return processCustomTenantMessage(request); } }
private Future<EventBusMessage> processGetByCaRequest(final EventBusMessage request, final String subjectDn, final Span span) { try { final X500Principal dn = new X500Principal(subjectDn); log.debug("retrieving tenant [subject DN: {}]", subjectDn); final Future<TenantResult<JsonObject>> getResult = Future.future(); get(dn, span, getResult.completer()); return getResult.map(tr -> { final EventBusMessage response = request.getResponse(tr.getStatus()) .setJsonPayload(tr.getPayload()) .setCacheDirective(tr.getCacheDirective()); if (tr.isOk() && tr.getPayload() != null) { final String tenantId = getTypesafeValueForField(String.class, tr.getPayload(), TenantConstants.FIELD_PAYLOAD_TENANT_ID); span.setTag(MessageHelper.APP_PROPERTY_TENANT_ID, tenantId); response.setTenant(tenantId); } return response; }); } catch (final IllegalArgumentException e) { TracingHelper.logError(span, "illegal subject DN provided by client: " + subjectDn); // the given subject DN is invalid log.debug("cannot parse subject DN [{}] provided by client", subjectDn); return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST)); } }
/** * Verifies that the base service routes a request for retrieving * a tenant by its trusted certificate authority to the corresponding * <em>get</em> method. * * @param ctx The vert.x test context. */ @Test public void testGetByCaSucceeds(final TestContext ctx) { final EventBusMessage request = EventBusMessage.forOperation(TenantConstants.TenantAction.get.toString()) .setJsonPayload(new JsonObject().put(TenantConstants.FIELD_PAYLOAD_SUBJECT_DN, "CN=test")); tenantService.processRequest(request).setHandler(ctx.asyncAssertSuccess(response -> { ctx.assertEquals(HttpURLConnection.HTTP_OK, response.getStatus()); ctx.assertEquals("getByCa", response.getJsonPayload().getString("operation")); })); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void get(final X500Principal subjectDn, final Span span, final Handler<AsyncResult<TenantResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
@Override public final void get(final String tenantId, final Handler<AsyncResult<TenantResult<JsonObject>>> resultHandler) { get(tenantId, NoopSpan.INSTANCE, resultHandler); }
/** * Verifies that the base service routes a request for retrieving * a tenant by its identifier to the corresponding <em>get</em> method. * * @param ctx The vert.x test context. */ @Test public void testGetByIdSucceeds(final TestContext ctx) { final EventBusMessage request = createRequest(TenantConstants.TenantAction.get, null); tenantService.processRequest(request).setHandler(ctx.asyncAssertSuccess(response -> { ctx.assertEquals(HttpURLConnection.HTTP_OK, response.getStatus()); ctx.assertEquals(TEST_TENANT, response.getJsonPayload().getString(TenantConstants.FIELD_PAYLOAD_TENANT_ID)); })); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void get(final String tenantId, final Handler<AsyncResult<TenantResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
private Future<EventBusMessage> processGetByIdRequest(final EventBusMessage request, final String tenantId) { final Future<TenantResult<JsonObject>> getResult = Future.future(); get(tenantId, getResult.completer()); return getResult.map(tr -> { return request.getResponse(tr.getStatus()) .setJsonPayload(tr.getPayload()) .setTenant(tenantId) .setCacheDirective(tr.getCacheDirective()); }); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void get(final X500Principal subjectDn, final Handler<AsyncResult<TenantResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
private Future<EventBusMessage> processGetByIdRequest(final EventBusMessage request, final String tenantId, final Span span) { final Future<TenantResult<JsonObject>> getResult = Future.future(); get(tenantId, span, getResult.completer()); return getResult.map(tr -> { return request.getResponse(tr.getStatus()) .setJsonPayload(tr.getPayload()) .setTenant(tenantId) .setCacheDirective(tr.getCacheDirective()); }); }