/** * Checks if an AMQP message contains either a message ID or a correlation ID. * * @param msg The message. * @return {@code true} if the message has an ID that can be used for correlation. */ protected static final boolean hasCorrelationId(final Message msg) { if (msg.getMessageId() == null && msg.getCorrelationId() == null) { LOG.trace("message has neither a message-id nor correlation-id"); return false; } else { return true; } } }
/** * Checks if an AMQP message contains either a message ID or a correlation ID. * * @param msg The message. * @return {@code true} if the message has an ID that can be used for correlation. */ protected static final boolean hasCorrelationId(final Message msg) { if (msg.getMessageId() == null && msg.getCorrelationId() == null) { LOG.trace("message has neither a message-id nor correlation-id"); return false; } else { return true; } } }
/** * Return an AMQP_PUBREL message from the raw AMQP one * * @param message raw AMQP message * @return AMQP_PUBREL message */ public static AmqpPubrelMessage from(Message message) { if (!message.getSubject().equals(AMQP_SUBJECT)) { throw new IllegalArgumentException(String.format("AMQP message subject is no %s", AMQP_SUBJECT)); } return new AmqpPubrelMessage(message.getMessageId()); }
private void addHeadersToResponse(final Message request, final JsonObject message) { final boolean isApplicationCorrelationId = MessageHelper.getXOptAppCorrelationId(request); logger.debug("registration request [{}] uses application specific correlation ID: {}", request.getMessageId(), isApplicationCorrelationId); if (isApplicationCorrelationId) { message.put(ANNOTATION_X_OPT_APP_CORRELATION_ID, isApplicationCorrelationId); } final JsonObject correlationIdJson = encodeIdToJson(getCorrelationId(request)); message.put(APP_PROPERTY_CORRELATION_ID, correlationIdJson); }
/** * Checks whether a given tenant 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 (msg.getSubject() == null) { LOG.trace("message [{}] does not contain subject", msg.getMessageId()); return false; } else if (msg.getReplyTo() == null) { LOG.trace("message [{}] contains no reply-to address", msg.getMessageId()); return false; } else if (msg.getBody() != null && !MessageHelper.hasDataBody(msg)) { LOG.trace("message [{}] contains no Data section payload", msg.getMessageId()); return false; } else { return true; } } }
/** * 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; } }
/** * 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; } }
/** * Checks whether a given tenant 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 (msg.getSubject() == null) { LOG.trace("message [{}] does not contain subject", msg.getMessageId()); return false; } else if (msg.getReplyTo() == null) { LOG.trace("message [{}] contains no reply-to address", msg.getMessageId()); return false; } else if (msg.getBody() != null && !MessageHelper.hasDataBody(msg, true)) { LOG.trace("message [{}] contains no AmqpValue or Data section payload", msg.getMessageId()); return false; } else { return true; } } }
/** * @param request the request message from which to extract the correlationId * @return The ID used to correlate the given request message. This can either be the provided correlationId * (Correlation ID Pattern) or the messageId of the request (Message ID Pattern, if no correlationId is provided). */ private Object getCorrelationId(final Message request) { /* if a correlationId is provided, we use it to correlate the response -> Correlation ID Pattern */ if (request.getCorrelationId() != null) { return request.getCorrelationId(); } else { /* otherwise we use the message id -> Message ID Pattern */ return request.getMessageId(); } } }
private void sendMessage(final Message msg) { ByteBuffer b = ByteBuffer.allocate(4); b.putInt(count.getAndIncrement()); b.flip(); LOG.trace("sending message [id: {}] to peer", msg.getMessageId()); if (ProtonQoS.AT_MOST_ONCE.equals(sender.getQoS())) { sender.send(b.array(), msg); sentHandler.handle(null); } else { sender.send(b.array(), msg, res -> { if (Accepted.class.isInstance(res.getRemoteState())) { LOG.trace("message [id: {}, remotelySettled: {}] has been accepted by peer", msg.getMessageId(), res.remotelySettled()); res.settle(); if (sentHandler != null) { sentHandler.handle(null); } } else { LOG.warn("message [id: {}] has not been accepted by peer: {}", msg.getMessageId(), res.getRemoteState()); } }); } } }
/** * Adds a property for the correlation identifier. * <p> * The value of the property is set * <ol> * <li>to the AMQP message's correlation identifier, if not {@code null}, or<li> * <li>to the AMQP message's message identifier, if not {@code null}.</li> * </ol> * * @param message The AMQP message to retrieve the value from. * @return This message for chaining. * @throws IllegalArgumentException if the message doesn't contain a correlation id * nor a message id. */ public EventBusMessage setCorrelationId(final Message message) { if (message.getCorrelationId() != null) { return setCorrelationId(message.getCorrelationId()); } else if (message.getMessageId() != null) { return setCorrelationId(message.getMessageId()); } else { throw new IllegalArgumentException("message does not contain message-id nor correlation-id"); } }
/** * Adds a property for the correlation identifier. * <p> * The value of the property is set * <ol> * <li>to the AMQP message's correlation identifier, if not {@code null}, or<li> * <li>to the AMQP message's message identifier, if not {@code null}.</li> * </ol> * * @param message The AMQP message to retrieve the value from. * @return This message for chaining. * @throws IllegalArgumentException if the message doesn't contain a correlation id * nor a message id. */ public EventBusMessage setCorrelationId(final Message message) { if (message.getCorrelationId() != null) { return setCorrelationId(message.getCorrelationId()); } else if (message.getMessageId() != null) { return setCorrelationId(message.getMessageId()); } else { throw new IllegalArgumentException("message does not contain message-id nor correlation-id"); } }
/** * Checks whether a given registration 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 (!hasValidDeviceId(linkTarget, msg)) { return false; } else if (!hasCorrelationId(msg)) { return false; } else if (!RegistrationConstants.isValidAction(msg.getSubject())) { LOG.trace("message [{}] does not contain valid action property", msg.getMessageId()); return false; } else if (msg.getReplyTo() == null) { LOG.trace("message [{}] contains no reply-to address", msg.getMessageId()); return false; } else if (msg.getBody() != null && !MessageHelper.hasDataBody(msg)) { LOG.trace("message [{}] contains no Data section payload", msg.getMessageId()); return false; } else { return true; } } }
/** * Checks whether a given registration 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 (!hasValidDeviceId(linkTarget, msg)) { return false; } else if (!hasCorrelationId(msg)) { return false; } else if (!RegistrationConstants.isValidAction(msg.getSubject())) { LOG.trace("message [{}] does not contain valid action property", msg.getMessageId()); return false; } else if (msg.getReplyTo() == null) { LOG.trace("message [{}] contains no reply-to address", msg.getMessageId()); return false; } else if (msg.getBody() != null && !MessageHelper.hasDataBody(msg, true)) { LOG.trace("message [{}] contains no AmqpValue or Data section payload", msg.getMessageId()); return false; } else { return true; } } }
/** * Checks if an AMQP message contains a valid device identifier. * * @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 following conditions are met: * <ul> * <li>The message contains an application property {@link MessageHelper#APP_PROPERTY_DEVICE_ID}.</li> * <li>If the link target contains a resource ID, it matches the ID from the property.</li> * </ul> */ protected static final boolean hasValidDeviceId(final ResourceIdentifier linkTarget, final Message msg) { final String deviceIdProperty = MessageHelper.getDeviceId(msg); if (deviceIdProperty == null) { LOG.trace("message [{}] contains no {} application property", msg.getMessageId(), MessageHelper.APP_PROPERTY_DEVICE_ID); return false; } else if (linkTarget.getResourceId() != null && !deviceIdProperty.equals(linkTarget.getResourceId())) { LOG.trace("message's {} property contains invalid device ID [expected: {}, but was: {}]", MessageHelper.APP_PROPERTY_DEVICE_ID, linkTarget.getResourceId(), deviceIdProperty); return false; } else { return true; } }
/** * Checks if an AMQP message contains a valid device identifier. * * @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 following conditions are met: * <ul> * <li>The message contains an application property {@link MessageHelper#APP_PROPERTY_DEVICE_ID}.</li> * <li>If the link target contains a resource ID, it matches the ID from the property.</li> * </ul> */ protected static final boolean hasValidDeviceId(final ResourceIdentifier linkTarget, final Message msg) { final String deviceIdProperty = MessageHelper.getDeviceId(msg); if (deviceIdProperty == null) { LOG.trace("message [{}] contains no {} application property", msg.getMessageId(), MessageHelper.APP_PROPERTY_DEVICE_ID); return false; } else if (linkTarget.getResourceId() != null && !deviceIdProperty.equals(linkTarget.getResourceId())) { LOG.trace("message's {} property contains invalid device ID [expected: {}, but was: {}]", MessageHelper.APP_PROPERTY_DEVICE_ID, linkTarget.getResourceId(), deviceIdProperty); return false; } else { return true; } }
public void request( final Message message, final OperationResult<Message, Exception> onResponse) { if (message == null) throw new IllegalArgumentException("message cannot be null"); if (message.getMessageId() != null) throw new IllegalArgumentException("message.getMessageId() should be null"); if (message.getReplyTo() != null) throw new IllegalArgumentException("message.getReplyTo() should be null"); message.setMessageId("request" + UnsignedLong.valueOf(this.requestId.incrementAndGet()).toString()); message.setReplyTo(this.replyTo); this.inflightRequests.put(message.getMessageId(), onResponse); sendLink.delivery(UUID.randomUUID().toString().replace("-", StringUtil.EMPTY).getBytes()); final int payloadSize = AmqpUtil.getDataSerializedSize(message) + 512; // need buffer for headers final byte[] bytes = new byte[payloadSize]; final int encodedSize = message.encode(bytes, 0, payloadSize); receiveLink.flow(1); sendLink.send(bytes, 0, encodedSize); sendLink.advance(); }
@Override public void processMessage(final UpstreamReceiver client, final ProtonDelivery delivery, final Message data) { LinkStatus status = statusMap.get(client.getLinkId()); if (status == null) { LOG.debug("creating new link status object [{}]", client.getLinkId()); status = new LinkStatus(client); statusMap.put(client.getLinkId(), status); } LOG.debug("processing telemetry data [id: {}, to: {}, content-type: {}]", data.getMessageId(), data.getAddress(), data.getContentType()); if (messageConsumer != null) { messageConsumer.accept(data); } ProtonHelper.accepted(delivery, true); status.onMsgReceived(); }
private void processRequest(final Message msg) { final JsonObject registrationMsg = RegistrationConstants.getRegistrationMsg(msg); vertx.eventBus().send(EVENT_BUS_ADDRESS_REGISTRATION_IN, registrationMsg, result -> { JsonObject response = null; if (result.succeeded()) { // TODO check for correct session here...? response = (JsonObject) result.result().body(); } else { logger.debug("failed to process request [msg ID: {}] due to {}", msg.getMessageId(), result.cause()); // we need to inform client about failure response = RegistrationConstants.getReply( HttpURLConnection.HTTP_INTERNAL_ERROR, MessageHelper.getTenantIdAnnotation(msg), MessageHelper.getDeviceIdAnnotation(msg), null); } addHeadersToResponse(msg, response); vertx.eventBus().send(msg.getReplyTo(), response); }); }
this.deliveries.put(message.getMessageId(), delivery);