/** * Constructs a new MutableExternalMessageBuilder initialized with the passed {@code message}. * * @param message the ExternalMessage to use for initialization. */ UnmodifiableExternalMessageBuilder(final ExternalMessage message) { this.headers = new HashMap<>(message.getHeaders()); this.bytePayload = message.getBytePayload().orElse(null); this.textPayload = message.getTextPayload().orElse(null); this.payloadType = message.getPayloadType(); this.response = message.isResponse(); this.error = message.isError(); this.authorizationContext = message.getAuthorizationContext().orElse(null); this.topicPath = message.getTopicPath().orElse(null); this.enforcementFilter = message.getEnforcementFilter().orElse(null); this.headerMapping = message.getHeaderMapping().orElse(null); }
private static String extractPayloadAsString(final ExternalMessage message) { final Optional<String> payload; if (message.isTextMessage()) { payload = message.getTextPayload(); } else if (message.isBytesMessage()) { final Charset charset = Optional.ofNullable(message.getHeaders() .get(ExternalMessage.CONTENT_TYPE_HEADER)) .map(MessageMappers::determineCharset) .orElse(StandardCharsets.UTF_8); payload = message.getBytePayload().map(charset::decode).map(CharBuffer::toString); } else { payload = Optional.empty(); } return payload.filter(s -> !s.isEmpty()).orElseThrow(() -> MessageMappingFailedException.newBuilder(message.findContentType().orElse("")) .description( "As payload was absent or empty, please make sure to send payload in your messages.") .dittoHeaders(DittoHeaders.of((message.getHeaders()))) .build()); }
/** * @return the optional value of the Content-Type header */ default Optional<String> findContentType() { return findHeaderIgnoreCase(CONTENT_TYPE_HEADER); }
/** * Checks whether the passed in {@code outboundSignal} is a response or an error. * * @param outboundSignal the OutboundSignal to check. * @return {@code true} if the OutboundSignal is a response or an error, {@code false} otherwise */ private boolean isResponseOrError(final OutboundSignal.WithExternalMessage outboundSignal) { return (outboundSignal.getExternalMessage().isResponse() || outboundSignal.getExternalMessage().isError()); }
private void testBuildExternalMessage(final boolean bytePayload) { final AuthorizationContext authorizationContext = Mockito.mock(AuthorizationContext.class); final TopicPath topicPath = Mockito.mock(TopicPath.class); final Map<String, String> headers = new HashMap<>(); headers.put("eclipse", "ditto"); final UnmodifiableExternalMessageBuilder messageBuilder = new UnmodifiableExternalMessageBuilder(headers); messageBuilder.withAdditionalHeaders("ditto", "eclipse"); messageBuilder.withAuthorizationContext(authorizationContext); messageBuilder.withTopicPath(topicPath); if (bytePayload) { messageBuilder.withBytes(BYTES); } else { messageBuilder.withText(PAYLOAD); } final ExternalMessage externalMessage = messageBuilder.build(); Assertions.assertThat(externalMessage.getHeaders()).containsEntry("eclipse", "ditto"); Assertions.assertThat(externalMessage.getHeaders()).containsEntry("ditto", "eclipse"); Assertions.assertThat(externalMessage.getAuthorizationContext()).contains(authorizationContext); Assertions.assertThat(externalMessage.getTopicPath()).contains(topicPath); Assertions.assertThat(externalMessage.isError()).isFalse(); Assertions.assertThat(externalMessage.isResponse()).isFalse(); if (bytePayload) { Assertions.assertThat(externalMessage.getTextPayload()).isEmpty(); Assertions.assertThat(externalMessage.getBytePayload()).contains(ByteBuffer.wrap(BYTES)); } else { Assertions.assertThat(externalMessage.getTextPayload()).contains(PAYLOAD); Assertions.assertThat(externalMessage.getBytePayload()).isEmpty(); } }
lastMessagePublishedAt = Instant.now(); final String contentType = message.getHeaders().get(ExternalMessage.CONTENT_TYPE_HEADER); final String correlationId = message.getHeaders().get(DittoHeaderDefinition.CORRELATION_ID.getKey()); message.getHeaders().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, (e -> (Object) e.getValue()))); if (message.isTextMessage()) { body = message.getTextPayload() .map(text -> text.getBytes(MessageMappers.determineCharset(contentType))) .orElseThrow(() -> new IllegalArgumentException("Failed to convert text to bytes.")); } else { body = message.getBytePayload() .map(ByteBuffer::array) .orElse(new byte[]{});
return Optional.ofNullable((Adaptable) contextFactory.call(cx -> { final NativeObject headersObj = new NativeObject(); message.getHeaders().forEach((key, value) -> headersObj.put(key, headersObj, value)); if (message.getBytePayload().isPresent()) { final ByteBuffer byteBuffer = message.getBytePayload().get(); final byte[] array = byteBuffer.array(); bytePayload = new NativeArrayBuffer(array.length); final String contentType = message.getHeaders().get(ExternalMessage.CONTENT_TYPE_HEADER); final String textPayload = message.getTextPayload().orElse(null); })); } catch (final RhinoException e) { throw buildMessageMappingFailedException(e, message.findContentType().orElse(""), DittoHeaders.of(message.getHeaders())); } catch (final Throwable e) { throw MessageMappingFailedException.newBuilder(message.findContentType().orElse(null)) .description(e.getMessage()) .dittoHeaders(DittoHeaders.of(message.getHeaders())) .cause(e) .build();
private Message toJmsMessage(final ExternalMessage externalMessage) throws JMSException { final Message message; final Optional<String> optTextPayload = externalMessage.getTextPayload(); if (optTextPayload.isPresent()) { message = session.createTextMessage(optTextPayload.get()); } else if (externalMessage.getBytePayload().isPresent()) { final BytesMessage bytesMessage = session.createBytesMessage(); bytesMessage.writeBytes(externalMessage.getBytePayload().map(ByteBuffer::array).orElse(new byte[]{})); message = bytesMessage; } else { final Map<String, String> headers = externalMessage.getHeaders(); JMS_HEADER_MAPPING.entrySet().stream() .filter(entry -> headers.containsKey(entry.getKey())) if (facade instanceof AmqpJmsMessageFacade) { final AmqpJmsMessageFacade amqpJmsMessageFacade = (AmqpJmsMessageFacade) facade; externalMessage.getHeaders() .entrySet() .stream()
/** * Merge message headers of message and adaptable. Adaptable headers do override message headers! * * @param message the message * @param adaptable the adaptable * @return the merged headers */ private static DittoHeaders mergeHeaders(final ExternalMessage message, final Adaptable adaptable) { final Map<String, String> headers = new HashMap<>(message.getHeaders()); adaptable.getHeaders().ifPresent(headers::putAll); return DittoHeaders.of(headers); }
final ExternalMessage externalMessage = builder.build(); LogUtil.enhanceLogWithCorrelationId(log, externalMessage .findHeader(DittoHeaderDefinition.CORRELATION_ID.getKey())); if (log.isDebugEnabled()) { log.debug("Received message from AMQP 1.0 ({}): {}", externalMessage.getHeaders(), externalMessage.getTextPayload().orElse("binary"));
private MessageMapper getMapper(final ExternalMessage message) { LogUtil.enhanceLogWithCorrelationId(log, message.getHeaders().get("correlation-id")); LogUtil.enhanceLogWithCustomField(log, BaseClientData.MDC_CONNECTION_ID, connectionId); final Optional<String> contentTypeOpt = message.findContentType(); if (contentTypeOpt.isPresent()) { final String contentType = contentTypeOpt.get(); if (registry.getDefaultMapper().getContentType().filter(contentType::equals).isPresent()) { log.info("Selected Default MessageMapper for mapping ExternalMessage as content-type matched <{}>", contentType); return registry.getDefaultMapper(); } } return registry.getMapper().orElseGet(() -> { log.debug("Falling back to Default MessageMapper for mapping ExternalMessage " + "as no MessageMapper was present: {}", message); return registry.getDefaultMapper(); }); }
@Override public Optional<Adaptable> apply(final ExternalMessage message) { return Optional.ofNullable( message.getTextPayload() .orElseGet(() -> message.getBytePayload() .map(b -> StandardCharsets.UTF_8.decode(b).toString()) .orElse(null)) ).map(plainString -> DittoJsonException.wrapJsonRuntimeException(() -> { final JsonObject jsonObject = JsonFactory.readFrom(plainString).asObject(); return ProtocolFactory.jsonifiableAdaptableFromJson(jsonObject); })); } }
final Map<String, String> originalHeaders = new HashMap<>(originalMessage.getHeaders()); PlaceholderFilter.apply(e.getValue(), sourceSignal.getId(), THING_PLACEHOLDER, true)) .map(e -> originalMessage.getTopicPath() .map(topicPath -> new AbstractMap.SimpleEntry<>(e.getKey(), PlaceholderFilter.apply(e.getValue(), topicPath, TOPIC_PLACEHOLDER, true))
@Override public ExternalMessage apply(final ExternalMessage externalMessage) { final AuthorizationContext authorizationContext = getAuthorizationContextFromMessage(externalMessage); final AuthorizationContext filteredContext = PlaceholderFilter.filterAuthorizationContext(authorizationContext, externalMessage.getHeaders()); final JsonArray authSubjectsArray = mapAuthorizationContextToSubjectsArray(filteredContext); final ExternalMessage externalMessageWithSourceHeader = authSubjectsArray.get(0) .map(JsonValue::asString) .map(firstAuthorizationSubject -> externalMessage.withHeader(DittoHeaderDefinition.SOURCE.getKey(), firstAuthorizationSubject)) .orElse(externalMessage); return externalMessageWithSourceHeader.withHeader(DittoHeaderDefinition.AUTHORIZATION_SUBJECTS.getKey(), authSubjectsArray.toString()); }
private static AuthorizationContext getAuthorizationContextFromMessage(final ExternalMessage externalMessage) { final AuthorizationContext authorizationContext = externalMessage .getAuthorizationContext() .orElseThrow(() -> new IllegalArgumentException("No authorizationContext available.")); if (authorizationContext.isEmpty()) { throw new IllegalArgumentException("Empty authorization context not allowed."); } return authorizationContext; }
@Override public void accept(final ExternalMessage externalMessage, final Signal<?> signal) { externalMessage.getEnforcementFilter().ifPresent(enforcementFilter -> { log.debug("Connection Signal ID Enforcement enabled: {}", enforcementFilter); enforcementFilter.match(signal.getId(), signal.getDittoHeaders()); }); } }
lastMessagePublishedAt = Instant.now(); final String contentType = message.getHeaders().get(ExternalMessage.CONTENT_TYPE_HEADER); final String correlationId = message.getHeaders().get(DittoHeaderDefinition.CORRELATION_ID.getKey()); message.getHeaders().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, (e -> (Object) e.getValue()))); if (message.isTextMessage()) { body = message.getTextPayload() .map(text -> text.getBytes(MessageMappers.determineCharset(contentType))) .orElseThrow(() -> new IllegalArgumentException("Failed to convert text to bytes.")); } else { body = message.getBytePayload() .map(ByteBuffer::array) .orElse(new byte[]{});
return Optional.ofNullable((Adaptable) contextFactory.call(cx -> { final NativeObject headersObj = new NativeObject(); message.getHeaders().forEach((key, value) -> headersObj.put(key, headersObj, value)); if (message.getBytePayload().isPresent()) { final ByteBuffer byteBuffer = message.getBytePayload().get(); final byte[] array = byteBuffer.array(); bytePayload = new NativeArrayBuffer(array.length); final String contentType = message.getHeaders().get(ExternalMessage.CONTENT_TYPE_HEADER); final String textPayload = message.getTextPayload().orElse(null); })); } catch (final RhinoException e) { throw buildMessageMappingFailedException(e, message.findContentType().orElse(""), DittoHeaders.of(message.getHeaders())); } catch (final Throwable e) { throw MessageMappingFailedException.newBuilder(message.findContentType().orElse(null)) .description(e.getMessage()) .dittoHeaders(DittoHeaders.of(message.getHeaders())) .cause(e) .build();
private Message toJmsMessage(final ExternalMessage externalMessage) throws JMSException { final Message message; final Optional<String> optTextPayload = externalMessage.getTextPayload(); if (optTextPayload.isPresent()) { message = session.createTextMessage(optTextPayload.get()); } else if (externalMessage.getBytePayload().isPresent()) { final BytesMessage bytesMessage = session.createBytesMessage(); bytesMessage.writeBytes(externalMessage.getBytePayload().map(ByteBuffer::array).orElse(new byte[]{})); message = bytesMessage; } else { final Map<String, String> headers = externalMessage.getHeaders(); JMS_HEADER_MAPPING.entrySet().stream() .filter(entry -> headers.containsKey(entry.getKey())) if (facade instanceof AmqpJmsMessageFacade) { final AmqpJmsMessageFacade amqpJmsMessageFacade = (AmqpJmsMessageFacade) facade; externalMessage.getHeaders() .entrySet() .stream()
/** * Merge message headers of message and adaptable. Adaptable headers do override message headers! * * @param message the message * @param adaptable the adaptable * @return the merged headers */ private static DittoHeaders mergeHeaders(final ExternalMessage message, final Adaptable adaptable) { final Map<String, String> headers = new HashMap<>(message.getHeaders()); adaptable.getHeaders().ifPresent(headers::putAll); return DittoHeaders.of(headers); }