return EventBusMessage.forOperation(CredentialsAction.get.toString()) .setTenant(tenantId) .setJsonPayload(payload)
/** * Processes a Credentials API request received via the vert.x event bus. * <p> * This method validates the request parameters against the Credentials API * specification before invoking the corresponding {@code CredentialsService} 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); final String operation = request.getOperation(); switch (CredentialsConstants.CredentialsAction.from(operation)) { case get: return processGetRequest(request); default: return processCustomCredentialsMessage(request); } }
/** * Checks whether a given credentials message contains all required properties. * * @param linkTarget The resource path to check the message's properties against for consistency. * @param msg The AMQP 1.0 message to perform the checks on. * @return {@code true} if the message passes all checks. */ public static boolean verify(final ResourceIdentifier linkTarget, final Message msg) { if (msg.getMessageId() == null && msg.getCorrelationId() == null) { LOG.trace("message has neither a message-id nor correlation-id"); return false; } else if (!CredentialsConstants.CredentialsAction.isValid(msg.getSubject())) { LOG.trace("message [{}] does not contain valid subject property", msg.getMessageId()); return false; } else if (msg.getReplyTo() == null) { LOG.trace("message [{}] has no reply-to address set", msg.getMessageId()); return false; } else if (!MessageHelper.hasDataBody(msg, true)) { LOG.trace("message [{}] contains no AmqpValue or Data section payload", msg.getMessageId()); return false; } else { return true; } }
return EventBusMessage.forOperation(CredentialsAction.get.toString()) .setTenant(tenantId) .setJsonPayload(payload)
private void updateCredentials(final RoutingContext ctx) { final JsonObject payload = (JsonObject) ctx.get(KEY_REQUEST_BODY); final String deviceId = payload.getString(CredentialsConstants.FIELD_PAYLOAD_DEVICE_ID); final String authId = payload.getString(CredentialsConstants.FIELD_AUTH_ID); final String type = payload.getString(CredentialsConstants.FIELD_TYPE); final String tenantId = getTenantParam(ctx); final String authIdFromUri = getAuthIdParam(ctx); final String typeFromUri = getTypeParam(ctx); // auth-id and type from URI must match payload if (!authIdFromUri.equals(authId)) { ctx.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "Non-matching authentication identifier")); } else if (!typeFromUri.equals(type)) { ctx.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "Non-matching credentials type")); } else { logger.debug("updating credentials [tenant: {}, device-id: {}, auth-id: {}, type: {}]", tenantId, deviceId, authId, type); final JsonObject requestMsg = EventBusMessage.forOperation(CredentialsConstants.CredentialsAction.update.toString()) .setTenant(tenantId) .setDeviceId(deviceId) .setJsonPayload(payload) .toJson(); sendAction(ctx, requestMsg, getDefaultResponseHandler(ctx)); } }
/** * Processes a Credentials API request received via the vert.x event bus. * <p> * This method validates the request parameters against the Credentials API * specification before invoking the corresponding {@code CredentialsService} 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 final Future<EventBusMessage> processRequest(final EventBusMessage request) { Objects.requireNonNull(request); final String operation = request.getOperation(); switch (CredentialsConstants.CredentialsAction.from(operation)) { case get: return processGetRequest(request); case add: return processAddRequest(request); case update: return processUpdateRequest(request); case remove: return processRemoveRequest(request); default: return processCustomCredentialsMessage(request); } }
/** * Invokes the <em>Get Credentials</em> operation of Hono's * <a href="https://www.eclipse.org/hono/api/Credentials-API">Credentials API</a> * on the service represented by the <em>sender</em> and <em>receiver</em> links. */ @Override public final Future<CredentialsObject> get(final String type, final String authId, final JsonObject clientContext) { Objects.requireNonNull(type); Objects.requireNonNull(authId); final Future<CredentialsResult<CredentialsObject>> responseTracker = Future.future(); final JsonObject specification = new JsonObject() .put(CredentialsConstants.FIELD_TYPE, type) .put(CredentialsConstants.FIELD_AUTH_ID, authId) .mergeIn(clientContext); createAndSendRequest(CredentialsConstants.CredentialsAction.get.toString(), specification.toBuffer(), responseTracker.completer()); return responseTracker.map(response -> { switch(response.getStatus()) { case HttpURLConnection.HTTP_OK: return response.getPayload(); case HttpURLConnection.HTTP_NOT_FOUND: throw new ClientErrorException(response.getStatus(), "no such credentials"); default: throw StatusCodeMapper.from(response); } }); } }
private void updateCredentials(final RoutingContext ctx) { final JsonObject payload = (JsonObject) ctx.get(KEY_REQUEST_BODY); final String deviceId = payload.getString(CredentialsConstants.FIELD_PAYLOAD_DEVICE_ID); final String authId = payload.getString(CredentialsConstants.FIELD_AUTH_ID); final String type = payload.getString(CredentialsConstants.FIELD_TYPE); final String tenantId = getTenantParam(ctx); final String authIdFromUri = getAuthIdParam(ctx); final String typeFromUri = getTypeParam(ctx); // auth-id and type from URI must match payload if (!authIdFromUri.equals(authId)) { ctx.response().setStatusMessage("Non-matching authentication identifier"); ctx.fail(HttpURLConnection.HTTP_BAD_REQUEST); } else if (!typeFromUri.equals(type)) { ctx.response().setStatusMessage("Non-matching credentials type"); ctx.fail(HttpURLConnection.HTTP_BAD_REQUEST); } else { logger.debug("updating credentials [tenant: {}, device-id: {}, auth-id: {}, type: {}]", tenantId, deviceId, authId, type); final JsonObject requestMsg = EventBusMessage.forOperation(CredentialsConstants.CredentialsAction.update.toString()) .setTenant(tenantId) .setDeviceId(deviceId) .setJsonPayload(payload) .toJson(); sendAction(ctx, requestMsg, getDefaultResponseHandler(ctx)); } }
/** * Processes a Credentials API request received via the vert.x event bus. * <p> * This method validates the request parameters against the Credentials API * specification before invoking the corresponding {@code CredentialsService} 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 final Future<EventBusMessage> processRequest(final EventBusMessage request) { Objects.requireNonNull(request); final String operation = request.getOperation(); switch (CredentialsConstants.CredentialsAction.from(operation)) { case get: return processGetRequest(request); case add: return processAddRequest(request); case update: return processUpdateRequest(request); case remove: return processRemoveRequest(request); default: return processCustomCredentialsMessage(request); } }
/** * Checks whether a given credentials message contains all required properties. * * @param linkTarget The resource path to check the message's properties against for consistency. * @param msg The AMQP 1.0 message to perform the checks on. * @return {@code true} if the message passes all checks. */ public static boolean verify(final ResourceIdentifier linkTarget, final Message msg) { if (msg.getMessageId() == null && msg.getCorrelationId() == null) { LOG.trace("message has neither a message-id nor correlation-id"); return false; } else if (!CredentialsConstants.CredentialsAction.isValid(msg.getSubject())) { LOG.trace("message [{}] does not contain valid subject property", msg.getMessageId()); return false; } else if (msg.getReplyTo() == null) { LOG.trace("message [{}] has no reply-to address set", msg.getMessageId()); return false; } else if (!MessageHelper.hasDataBody(msg)) { LOG.trace("message [{}] contains no Data section payload", msg.getMessageId()); return false; } else { return true; } }
private void addCredentials(final RoutingContext ctx) { final JsonObject payload = (JsonObject) ctx.get(KEY_REQUEST_BODY); final String deviceId = payload.getString(CredentialsConstants.FIELD_PAYLOAD_DEVICE_ID); final String authId = payload.getString(CredentialsConstants.FIELD_AUTH_ID); final String type = payload.getString(CredentialsConstants.FIELD_TYPE); final String tenantId = getTenantParam(ctx); logger.debug("adding credentials [tenant: {}, device-id: {}, auth-id: {}, type: {}]", tenantId, deviceId, authId, type); final JsonObject requestMsg = EventBusMessage.forOperation(CredentialsConstants.CredentialsAction.add.toString()) .setTenant(tenantId) .setDeviceId(deviceId) .setJsonPayload(payload) .toJson(); sendAction(ctx, requestMsg, getDefaultResponseHandler(ctx, status -> status == HttpURLConnection.HTTP_CREATED, httpServerResponse -> httpServerResponse.putHeader(HttpHeaders.LOCATION, String.format("/%s/%s/%s/%s", CredentialsConstants.CREDENTIALS_ENDPOINT, tenantId, authId, type)) ) ); }
private void addCredentials(final RoutingContext ctx) { final JsonObject payload = (JsonObject) ctx.get(KEY_REQUEST_BODY); final String deviceId = payload.getString(CredentialsConstants.FIELD_PAYLOAD_DEVICE_ID); final String authId = payload.getString(CredentialsConstants.FIELD_AUTH_ID); final String type = payload.getString(CredentialsConstants.FIELD_TYPE); final String tenantId = getTenantParam(ctx); logger.debug("adding credentials [tenant: {}, device-id: {}, auth-id: {}, type: {}]", tenantId, deviceId, authId, type); final JsonObject requestMsg = EventBusMessage.forOperation(CredentialsConstants.CredentialsAction.add.toString()) .setTenant(tenantId) .setDeviceId(deviceId) .setJsonPayload(payload) .toJson(); sendAction(ctx, requestMsg, getDefaultResponseHandler(ctx, status -> status == HttpURLConnection.HTTP_CREATED, httpServerResponse -> httpServerResponse.putHeader(HttpHeaders.LOCATION, String.format("/%s/%s/%s/%s", CredentialsConstants.CREDENTIALS_ENDPOINT, tenantId, authId, type)) ) ); }
/** * Processes a Credentials API request received via the vert.x event bus. * <p> * This method validates the request parameters against the Credentials API * specification before invoking the corresponding {@code CredentialsService} 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); final String operation = request.getOperation(); switch (CredentialsConstants.CredentialsAction.from(operation)) { case get: return processGetRequest(request); default: return processCustomCredentialsMessage(request); } }
/** * Verifies that the endpoint forwards a request message via the event bus. */ @Test public void testProcessMessageSendsRequestViaEventBus() { final Message msg = ProtonHelper.message(); msg.setMessageId("random-id"); msg.setSubject(CredentialsConstants.CredentialsAction.add.toString()); MessageHelper.addDeviceId(msg, "4711"); MessageHelper.addTenantId(msg, Constants.DEFAULT_TENANT); MessageHelper.annotate(msg, resource); msg.setBody(new AmqpValue(new JsonObject().put("temp", 15).encode())); endpoint.processRequest(msg, resource, Constants.PRINCIPAL_ANONYMOUS); verify(eventBus).send(eq(CredentialsConstants.EVENT_BUS_ADDRESS_CREDENTIALS_IN), any(JsonObject.class), any(DeliveryOptions.class)); } }
private void removeCredentials(final RoutingContext ctx) { final String tenantId = getTenantParam(ctx); final String type = getTypeParam(ctx); final String authId = getAuthIdParam(ctx); logger.debug("removeCredentials [tenant: {}, type: {}, authId: {}]", tenantId, type, authId); final JsonObject payload = new JsonObject(); payload.put(CredentialsConstants.FIELD_TYPE, type); payload.put(CredentialsConstants.FIELD_AUTH_ID, authId); final JsonObject requestMsg = EventBusMessage.forOperation(CredentialsConstants.CredentialsAction.remove.toString()) .setTenant(tenantId) .setJsonPayload(payload) .toJson(); sendAction(ctx, requestMsg, getDefaultResponseHandler(ctx, status -> status == HttpURLConnection.HTTP_NO_CONTENT, null)); }
/** * Construct a CredentialsAction from a subject. * * @param subject The subject from which the CredentialsAction needs to be constructed. * @return CredentialsAction The CredentialsAction as enum, or {@link CredentialsAction#unknown} otherwise. */ public static CredentialsAction from(final String subject) { if (subject != null) { try { return CredentialsAction.valueOf(subject); } catch (final IllegalArgumentException e) { } } return unknown; }
/** * Construct a CredentialsAction from a subject. * * @param subject The subject from which the CredentialsAction needs to be constructed. * @return CredentialsAction The CredentialsAction as enum, or {@link CredentialsAction#unknown} otherwise. */ public static CredentialsAction from(final String subject) { if (subject != null) { try { return CredentialsAction.valueOf(subject); } catch (final IllegalArgumentException e) { } } return unknown; }
private void removeCredentialsForDevice(final RoutingContext ctx) { final String tenantId = getTenantParam(ctx); final String deviceId = getDeviceIdParam(ctx); logger.debug("removeCredentialsForDevice: [tenant: {}, device-id: {}]", tenantId, deviceId); final JsonObject payload = new JsonObject(); payload.put(CredentialsConstants.FIELD_PAYLOAD_DEVICE_ID, deviceId); payload.put(CredentialsConstants.FIELD_TYPE, CredentialsConstants.SPECIFIER_WILDCARD); final JsonObject requestMsg = EventBusMessage.forOperation(CredentialsConstants.CredentialsAction.remove.toString()) .setTenant(tenantId) .setDeviceId(deviceId) .setJsonPayload(payload) .toJson(); sendAction(ctx, requestMsg, getDefaultResponseHandler(ctx, status -> status == HttpURLConnection.HTTP_NO_CONTENT, null)); }
private void removeCredentials(final RoutingContext ctx) { final String tenantId = getTenantParam(ctx); final String type = getTypeParam(ctx); final String authId = getAuthIdParam(ctx); logger.debug("removeCredentials [tenant: {}, type: {}, authId: {}]", tenantId, type, authId); final JsonObject payload = new JsonObject(); payload.put(CredentialsConstants.FIELD_TYPE, type); payload.put(CredentialsConstants.FIELD_AUTH_ID, authId); final JsonObject requestMsg = EventBusMessage.forOperation(CredentialsConstants.CredentialsAction.remove.toString()) .setTenant(tenantId) .setJsonPayload(payload) .toJson(); sendAction(ctx, requestMsg, getDefaultResponseHandler(ctx, status -> status == HttpURLConnection.HTTP_NO_CONTENT, null)); }
private void removeCredentialsForDevice(final RoutingContext ctx) { final String tenantId = getTenantParam(ctx); final String deviceId = getDeviceIdParam(ctx); logger.debug("removeCredentialsForDevice: [tenant: {}, device-id: {}]", tenantId, deviceId); final JsonObject payload = new JsonObject(); payload.put(CredentialsConstants.FIELD_PAYLOAD_DEVICE_ID, deviceId); payload.put(CredentialsConstants.FIELD_TYPE, CredentialsConstants.SPECIFIER_WILDCARD); final JsonObject requestMsg = EventBusMessage.forOperation(CredentialsConstants.CredentialsAction.remove.toString()) .setTenant(tenantId) .setDeviceId(deviceId) .setJsonPayload(payload) .toJson(); sendAction(ctx, requestMsg, getDefaultResponseHandler(ctx, status -> status == HttpURLConnection.HTTP_NO_CONTENT, null)); }