/** * Returns new empty {@code Headers}. * * @return the headers. */ public static DittoHeaders emptyHeaders() { return DittoHeaders.empty(); }
/** * Enhances the MDC around the passed SLF4J {@code Logger} with the {@code correlation-id} extracted from the passed * {@code dittoHeaders}. Invokes the passed in {@code logConsumer} around the MDC setting/removing. * * @param slf4jLogger the SLF4J logger to log with. * @param dittoHeaders where to extract a possible correlationId from. * @param logConsumer the consumer with which the caller must log. */ public static void logWithCorrelationId(final Logger slf4jLogger, final DittoHeaders dittoHeaders, final Consumer<Logger> logConsumer) { logWithCorrelationId(slf4jLogger, dittoHeaders.getCorrelationId(), logConsumer); }
private boolean shouldForbidNorCriteria() { // should forbid NorCriteria only for API >= 2 return dittoHeaders.getSchemaVersion() .map(JsonSchemaVersion::toInt) .filter(v -> v >= JsonSchemaVersion.V_2.toInt()) .isPresent(); }
/** * Returns new {@code Headers} for the specified {@code headers} map. * * @param headers the headers map. * @return the headers. */ public static DittoHeaders newHeadersWithDittoContentType(final Map<String, String> headers) { return DittoHeaders.of(headers).toBuilder().contentType(DittoConstants.DITTO_PROTOCOL_CONTENT_TYPE).build(); }
/** * Add to headers any information that will be missing from topic path. * * @param filteredHeaders headers read from external headers. * @param topicPath topic path of an adaptable. * @return filteredHeaders with extra information from topicPath. */ private static DittoHeaders addTopicPathInfo(final DittoHeaders filteredHeaders, final TopicPath topicPath) { final DittoHeaders extraInfo = mapTopicPathToHeaders(topicPath); return extraInfo.isEmpty() ? filteredHeaders : filteredHeaders.toBuilder().putHeaders(extraInfo).build(); }
/** * Returns a new instance of {@code DittoHeaders} containing the specified key-value-pairs. * * @param headers the key-value-pairs of the result. * @return the DittoHeaders. * @throws NullPointerException if {@code headers} is {@code null}. * @throws IllegalArgumentException if {@code headers} contains an invalid key-value-pair. */ static DittoHeaders of(final Map<String, String> headers) { return newBuilder(headers).build(); }
private CommandResponse unfixCorrelationId(final CommandResponse response) { final String correlationId = response.getDittoHeaders() .getCorrelationId() .flatMap(s -> decodeCommandCorrelationId(s).getValue(ORIGINAL_CORRELATION_ID)) .map(JsonValue::asString) .orElse(null); final DittoHeaders dittoHeaders = response.getDittoHeaders().toBuilder() .correlationId(correlationId) .build(); return response.setDittoHeaders(dittoHeaders); }
private void handleDittoRuntimeException(final ActorRef delegateActor, final DittoRuntimeException cre) { LogUtil.enhanceLogWithCorrelationId(logger, cre.getDittoHeaders().getCorrelationId()); logger.info("Got 'DittoRuntimeException': {} {}", cre.getClass().getName(), cre.getMessage()); cre.getDittoHeaders().getCorrelationId().ifPresent(outstandingCommandCorrelationIds::remove); if (cre.getDittoHeaders().isResponseRequired()) { delegateActor.forward(cre, getContext()); } else { logger.debug("Requester did not require response (via DittoHeader '{}') - not sending one", DittoHeaderDefinition.RESPONSE_REQUIRED); } }
final Enforcer enforcer = enforcerEntry.getValue(); final String correlationId = signal.getDittoHeaders().getCorrelationId().get(); if (signal instanceof SendClaimMessage) { if (signal.getDittoHeaders().isResponseRequired()) { responseReceivers.put(correlationId, sender); if (wasPublished && signal.getDittoHeaders().isResponseRequired()) { responseReceivers.put(correlationId, sender); publishToMediator(withReadSubjects, StreamingType.LIVE_COMMANDS.getDistributedPubSubTopic(), sender); if (signal.getDittoHeaders().isResponseRequired()) { responseReceivers.put(correlationId, sender); signal.getDittoHeaders().getAuthorizationContext(), WRITE); if (authorized) {
private DittoHeaders appendETagIfNotNull(final DittoHeaders dittoHeaders, @Nullable final EntityTag entityTag) { if (entityTag == null) { return dittoHeaders; } return dittoHeaders.toBuilder().eTag(entityTag).build(); } }
@Override public String apply(final DittoHeaders dittoHeaders) { requireNonNull(dittoHeaders); return dittoHeaders.getAuthorizationContext().getFirstAuthorizationSubject() .map(AuthorizationSubject::getId) .orElseThrow(() -> new IllegalStateException("AuthorizationContext must be available when this " + "function is applied!")); } }
/** * Tests whether a signal is applicable for live signal enforcement. * * @param signal the signal to test. * @return whether the signal belongs to the live channel. */ static boolean isLiveSignal(final Signal signal) { return signal.getDittoHeaders().getChannel().filter(TopicPath.Channel.LIVE.getName()::equals).isPresent(); }
private boolean isResponseExpected(final Signal<?> signal) { return signal instanceof Command && signal.getDittoHeaders().isResponseRequired(); }
@Override public DittoHeaders apply(final ExternalMessage externalMessage, final DittoHeaders dittoHeaders) { final DittoHeadersBuilder dittoHeadersBuilder = dittoHeaders.toBuilder(); final String beforeMapping = externalMessage .findHeader(DittoHeaderDefinition.AUTHORIZATION_SUBJECTS.getKey()) .orElseThrow(() -> new IllegalArgumentException( "Missing header " + DittoHeaderDefinition.AUTHORIZATION_SUBJECTS.getKey())); // do not use dittoHeadersBuilder.authorizationSubjects(beforeMapping); // because beforeMapping is a JsonArray String, we need to set AUTHORIZATION_SUBJECTS header directly dittoHeadersBuilder.putHeader(DittoHeaderDefinition.AUTHORIZATION_SUBJECTS.getKey(), beforeMapping); if (!dittoHeaders.getOrigin().isPresent()) { dittoHeadersBuilder.origin(connectionId); } // overwrite the auth-subjects to the configured ones after mapping in order to be sure that the mapping // does not choose/change the auth-subjects itself: return dittoHeadersBuilder.build(); }
/** * Returns new {@code Headers} for the specified {@code headersAsJson}. * * @param headersAsJson the headers as JSON. * @return the headers. */ public static DittoHeaders newHeaders(final JsonObject headersAsJson) { return DittoHeaders.newBuilder(headersAsJson).build(); }
private WithDittoHeaders appendETagHeader(final C command, final WithDittoHeaders response) { final DittoHeaders dittoHeaders = response.getDittoHeaders(); final Optional<EntityTag> entityTagOpt = determineETagEntity(command) .flatMap(EntityTag::fromEntity); if (entityTagOpt.isPresent()) { final DittoHeaders newDittoHeaders = dittoHeaders.toBuilder().eTag(entityTagOpt.get()).build(); return response.setDittoHeaders(newDittoHeaders); } return response; }
private Optional<CreateThingWithEnforcer> enforceCreateThingByAuthorizationContext(final CreateThing createThing) { // Command without authorization information is authorized by default. final Set<String> authorizedSubjects = createThing.getDittoHeaders() .getAuthorizationContext() .getFirstAuthorizationSubject() .map(subject -> Collections.singleton(subject.getId())) .orElse(Collections.emptySet()); final CreateThing command = AbstractEnforcement.addReadSubjectsToSignal(createThing, authorizedSubjects); final Enforcer enforcer = new AuthorizedSubjectsEnforcer(authorizedSubjects); return Optional.of(new CreateThingWithEnforcer(command, enforcer)); }
/** * Returns new {@code Headers} for the specified {@code headers} map. * * @param headers the headers map. * @return the headers. */ public static DittoHeaders newHeadersWithDittoContentType(final Map<String, String> headers) { return DittoHeaders.of(headers).toBuilder().contentType(DittoConstants.DITTO_PROTOCOL_CONTENT_TYPE).build(); }
private static boolean isLiveSignal(final Signal<?> signal) { return signal.getDittoHeaders().getChannel().filter(TopicPath.Channel.LIVE.getName()::equals).isPresent(); }
/** * Tests whether a message command is fire-and-forget. * * @param command The message command. * @return {@code true} if the message's timeout header is 0 or if the message is flagged not to require a response, * {@code false} otherwise. */ private static boolean isFireAndForgetMessage(final MessageCommand<?, ?> command) { return command.getMessage() .getTimeout() .map(Duration::isZero) .orElseGet(() -> !command.getDittoHeaders().isResponseRequired()); }