/** * Returns a Command for retrieving the Thing with the given ID. * * @param thingId the ID of a single Thing to be retrieved by this command. * @param dittoHeaders the headers of the command. * @return a Command for retrieving the Thing with the {@code thingId} as its ID which is readable from the passed * authorization context. * @throws NullPointerException if {@code dittoHeaders} is {@code null}. * @throws org.eclipse.ditto.model.things.ThingIdInvalidException if the parsed thing ID did not comply to {@link * org.eclipse.ditto.model.things.Thing#ID_REGEX}. */ public static RetrieveThing of(final CharSequence thingId, final DittoHeaders dittoHeaders) { return getBuilder(thingId, dittoHeaders).build(); }
private static DittoRuntimeException getThingUnavailableException(final RetrieveThing command) { // reset command headers so that correlation-id etc. is preserved return ThingUnavailableException.newBuilder(command.getThingId()) .dittoHeaders(command.getDittoHeaders()) .build(); }
public RetrieveThing build() { return new RetrieveThing(this); }
final JsonFieldSelectorBuilder jsonFieldSelectorBuilder = JsonFactory.newFieldSelectorBuilder().addFieldDefinition(Thing.JsonFields.ACL); retrieveThing.getSelectedFields().ifPresent(jsonFieldSelectorBuilder::addPointers); final DittoHeaders dittoHeaders = retrieveThing .getDittoHeaders() .toBuilder() .schemaVersion(JsonSchemaVersion.V_1) .build(); final RetrieveThing retrieveThingV1 = RetrieveThing.getBuilder(retrieveThing.getThingId(), dittoHeaders) .withSelectedFields(jsonFieldSelectorBuilder.build()) .build(); final Policy policy = PoliciesAclMigrations.accessControlListToPolicyEntries(aclOptional.get(), retrieveThing.getThingId(), subjectIssuersForPolicyMigration); reportAggregatedThingAndPolicy(retrieveThing, retrieveThingResponse.setDittoHeaders(retrieveThing.getDittoHeaders()), policy, enforcer, sender); } else { replyToSender(retrieveThingResponse.setDittoHeaders(retrieveThing.getDittoHeaders()), sender); replyToSender(withDittoHeaders.setDittoHeaders(retrieveThing.getDittoHeaders()), sender); } else if (isAskTimeoutException(response, error)) { reportThingUnavailable(retrieveThing.getThingId(), retrieveThing.getDittoHeaders(), sender); } else { reportUnexpectedErrorOrResponse("retrieving thing for ACL migration", sender, response, error, retrieveThing.getDittoHeaders());
private void retrieveThingsAndSendResult(final List<String> thingIds, @Nullable final JsonFieldSelector selectedFields, final Command<?> command, final ActorRef resultReceiver) { final DittoHeaders dittoHeaders = command.getDittoHeaders(); final CompletionStage<?> commandResponseSource = Source.from(thingIds) .filter(Objects::nonNull) .filterNot(String::isEmpty) .filter(thingId -> THING_ID_PATTERN.matcher(thingId).matches()) .map(thingId -> { final Command<?> toBeWrapped; if (command instanceof RetrieveThings) { toBeWrapped = Optional.ofNullable(selectedFields) .map(sf -> RetrieveThing.getBuilder(thingId, dittoHeaders) .withSelectedFields(sf) .build()) .orElse(RetrieveThing.of(thingId, dittoHeaders)); } else { toBeWrapped = Optional.ofNullable(selectedFields) .map(sf -> SudoRetrieveThing.of(thingId, sf, dittoHeaders)) .orElse(SudoRetrieveThing.of(thingId, dittoHeaders)); } return ConciergeWrapper.wrapForEnforcer(toBeWrapped); }) .ask(calculateParallelism(thingIds), targetActor, Jsonifiable.class, Timeout.apply(retrieveSingleThingTimeout.toMillis(), TimeUnit.MILLISECONDS)) .log("command-response", log) .runWith(StreamRefs.sourceRef(), actorMaterializer); PatternsCS.pipe(commandResponseSource, aggregatorDispatcher) .to(resultReceiver); }
@Override protected Result unhandled(final Context context, @Nullable final Thing thing, final long nextRevision, final RetrieveThing command) { return ResultFactory.newErrorResult( new ThingNotAccessibleException(context.getThingId(), command.getDittoHeaders())); }
/** * Retrieve inlined policy after retrieving a thing. Do not report errors. * * @param retrieveThing the original command. * @param retrievePolicy the command to retrieve the thing's policy. * @return future response from policies-shard-region. */ private CompletionStage<Optional<RetrievePolicyResponse>> retrieveInlinedPolicyForThing( final RetrieveThing retrieveThing, final RetrievePolicy retrievePolicy) { return blockCachedNamespaces.apply(retrievePolicy) .thenCompose(msg -> PatternsCS.ask(policiesShardRegion, msg, getAskTimeout())) .handleAsync((response, error) -> { LOGGER.debug("Response of policiesShardRegion: <{}>", response); if (response instanceof RetrievePolicyResponse) { return Optional.of((RetrievePolicyResponse) response); } else if (error != null) { log(error).error(error, "retrieving inlined policy after RetrieveThing"); } else { log(response).info( "No authorized response when retrieving inlined policy <{}> for thing <{}>: {}", retrievePolicy.getId(), retrieveThing.getThingId(), response); } return Optional.empty(); }, getEnforcementExecutor()); }
/** * Creates a new {@code RetrieveThing} from a JSON string. * * @param jsonString the JSON string of which the command is to be created. * @param dittoHeaders the headers of the command. * @return the command. * @throws NullPointerException if {@code jsonString} is {@code null}. * @throws IllegalArgumentException if {@code jsonString} is empty. * @throws org.eclipse.ditto.json.JsonParseException if the passed in {@code jsonString} was not in the expected * format. */ public static RetrieveThing fromJson(final String jsonString, final DittoHeaders dittoHeaders) { return fromJson(JsonFactory.newObject(jsonString), dittoHeaders); }
@SuppressWarnings({"squid:MethodCyclomaticComplexity", "squid:S1067", "OverlyComplexMethod"}) @Override public boolean equals(@Nullable final Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } final RetrieveThing that = (RetrieveThing) obj; return that.canEqual(this) && Objects.equals(thingId, that.thingId) && Objects.equals(selectedFields, that.selectedFields) && snapshotRevision == that.snapshotRevision && super.equals(that); }
@Override protected Result unhandled(final Context context, @Nullable final Thing thing, final long nextRevision, final RetrieveThing command) { return ResultFactory.newErrorResult( new ThingNotAccessibleException(context.getThingId(), command.getDittoHeaders())); }
/** * Creates a new {@code RetrieveThing} from a JSON string. * * @param jsonString the JSON string of which the command is to be created. * @param dittoHeaders the headers of the command. * @return the command. * @throws NullPointerException if {@code jsonString} is {@code null}. * @throws IllegalArgumentException if {@code jsonString} is empty. * @throws org.eclipse.ditto.json.JsonParseException if the passed in {@code jsonString} was not in the expected * format. */ public static RetrieveThing fromJson(final String jsonString, final DittoHeaders dittoHeaders) { return fromJson(JsonFactory.newObject(jsonString), dittoHeaders); }
@SuppressWarnings({"squid:MethodCyclomaticComplexity", "squid:S1067", "OverlyComplexMethod"}) @Override public boolean equals(@Nullable final Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } final RetrieveThing that = (RetrieveThing) obj; return that.canEqual(this) && Objects.equals(thingId, that.thingId) && Objects.equals(selectedFields, that.selectedFields) && snapshotRevision == that.snapshotRevision && super.equals(that); }
/** * Returns a Command for retrieving the Thing with the given ID. * * @param thingId the ID of a single Thing to be retrieved by this command. * @param dittoHeaders the headers of the command. * @return a Command for retrieving the Thing with the {@code thingId} as its ID which is readable from the passed * authorization context. * @throws NullPointerException if {@code dittoHeaders} is {@code null}. * @throws org.eclipse.ditto.model.things.ThingIdInvalidException if the parsed thing ID did not comply to {@link * org.eclipse.ditto.model.things.Thing#ID_REGEX}. */ public static RetrieveThing of(final CharSequence thingId, final DittoHeaders dittoHeaders) { return getBuilder(thingId, dittoHeaders).build(); }
private static DittoRuntimeException getThingUnavailableException(final RetrieveThing command) { // reset command headers so that correlation-id etc. is preserved return ThingUnavailableException.newBuilder(command.getThingId()) .dittoHeaders(command.getDittoHeaders()) .build(); }
final ActorRef sender) { final DittoHeaders dittoHeadersWithoutPreconditionHeaders = retrieveThing.getDittoHeaders() .toBuilder() .removePreconditionHeaders()
public RetrieveThing build() { return new RetrieveThing(this); }
@Override public RetrieveThing setDittoHeaders(final DittoHeaders dittoHeaders) { return getBuilder(thingId, dittoHeaders) .withSelectedFields(selectedFields) .withSnapshotRevision(snapshotRevision) .build(); }
/** * Retrieve a thing before retrieving its inlined policy. Report errors to sender. * * @param retrieveThing the command. * @param sender whom to report errors to. * @return future response from things-shard-region. */ private CompletionStage<Optional<RetrieveThingResponse>> retrieveThingBeforePolicy( final RetrieveThing retrieveThing, final ActorRef sender) { return PatternsCS.ask(thingsShardRegion, retrieveThing, getAskTimeout().toMillis()) .handleAsync((response, error) -> { if (response instanceof RetrieveThingResponse) { return Optional.of((RetrieveThingResponse) response); } else if (response instanceof ThingErrorResponse || response instanceof DittoRuntimeException) { replyToSender(response, sender); } else if (isAskTimeoutException(response, error)) { reportThingUnavailable(retrieveThing.getThingId(), retrieveThing.getDittoHeaders(), sender); } else { reportUnexpectedErrorOrResponse("retrieving thing before inlined policy", sender, response, error, retrieveThing.getDittoHeaders()); } return Optional.empty(); }, getEnforcementExecutor()); }
@Override public RetrieveThing setDittoHeaders(final DittoHeaders dittoHeaders) { return getBuilder(thingId, dittoHeaders) .withSelectedFields(selectedFields) .withSnapshotRevision(snapshotRevision) .build(); }
@Override public RetrieveThingLiveCommand setDittoHeaders(final DittoHeaders dittoHeaders) { final RetrieveThing twinCommand = RetrieveThing.getBuilder(getThingId(), dittoHeaders) .withSelectedFields(getSelectedFields().orElse(null)) .build(); return of(twinCommand); }