use of akka.japi.pf.PFBuilder in project ditto by eclipse.
the class StreamingSessionActor method createOutgoingSignalBehavior.
private Receive createOutgoingSignalBehavior() {
final PartialFunction<Object, Object> setCorrelationIdAndStartAckForwarder = new PFBuilder<>().match(Signal.class, this::startAckForwarder).match(DittoRuntimeException.class, x -> x).build();
final Receive publishSignal = ReceiveBuilder.create().match(SubscriptionEvent.class, signal -> {
logger.debug("Got SubscriptionEvent in <{}> session, publishing: {}", type, signal);
eventAndResponsePublisher.offer(SessionedJsonifiable.subscription(signal));
}).match(CommandResponse.class, this::publishResponseOrError).match(DittoRuntimeException.class, this::publishResponseOrError).match(Signal.class, this::isSameOrigin, signal -> logger.withCorrelationId(signal).debug("Got Signal of type <{}> in <{}> session, but this was issued by " + " this connection itself, not publishing", signal.getType(), type)).match(Signal.class, signal -> {
// check if this session is "allowed" to receive the Signal
final var streamingType = determineStreamingType(signal);
@Nullable final var session = streamingSessions.get(streamingType);
if (null != session && isSessionAllowedToReceiveSignal(signal, session, streamingType)) {
final ThreadSafeDittoLoggingAdapter l = logger.withCorrelationId(signal);
l.info("Publishing Signal of type <{}> in <{}> session", signal.getType(), type);
l.debug("Publishing Signal of type <{}> in <{}> session: {}", type, signal.getType(), signal);
final DittoHeaders sessionHeaders = DittoHeaders.newBuilder().authorizationContext(authorizationContext).schemaVersion(jsonSchemaVersion).build();
final var sessionedJsonifiable = SessionedJsonifiable.signal(signal, sessionHeaders, session);
eventAndResponsePublisher.offer(sessionedJsonifiable);
}
}).matchEquals(Done.getInstance(), done -> {
/* already done, nothing to publish */
}).build();
return addPreprocessors(List.of(setCorrelationIdAndStartAckForwarder), publishSignal);
}
use of akka.japi.pf.PFBuilder in project ditto by eclipse.
the class SearchSource method retrieveThingForElement.
private Source<Pair<String, JsonObject>, NotUsed> retrieveThingForElement(final String thingId) {
if (thingIdOnly) {
final JsonObject idOnlyThingJson = JsonObject.newBuilder().set(Thing.JsonFields.ID, thingId).build();
return Source.single(Pair.create(thingId, idOnlyThingJson));
} else {
return retrieveThing(thingId, fields).map(thingJson -> Pair.create(thingId, thingJson)).recoverWithRetries(1, new PFBuilder<Throwable, Graph<SourceShape<Pair<String, JsonObject>>, NotUsed>>().match(ThingNotAccessibleException.class, thingNotAccessible -> {
// out-of-sync thing detected
final ThingsOutOfSync thingsOutOfSync = ThingsOutOfSync.of(Collections.singletonList(ThingId.of(thingId)), getDittoHeaders());
pubSubMediator.tell(DistPubSubAccess.publishViaGroup(ThingsOutOfSync.TYPE, thingsOutOfSync), ActorRef.noSender());
return Source.empty();
}).build());
}
}
use of akka.japi.pf.PFBuilder in project ditto by eclipse.
the class WebSocketRoute method createOutgoing.
private Pair<Connect, Flow<DittoRuntimeException, Message, NotUsed>> createOutgoing(final JsonSchemaVersion version, final CharSequence connectionCorrelationId, final AuthorizationContext connectionAuthContext, final DittoHeaders additionalHeaders, final ProtocolAdapter adapter, final HttpRequest request, final WebsocketConfig websocketConfig, @Nullable final SignalEnrichmentFacade signalEnrichmentFacade, final ThreadSafeDittoLogger logger) {
final Optional<JsonWebToken> optJsonWebToken = extractJwtFromRequestIfPresent(request);
final Source<SessionedJsonifiable, SupervisedStream.WithQueue> publisherSource = SupervisedStream.sourceQueue(websocketConfig.getPublisherBackpressureBufferSize());
final Source<SessionedJsonifiable, Connect> sourceToPreMaterialize = publisherSource.mapMaterializedValue(withQueue -> {
webSocketSupervisor.supervise(withQueue.getSupervisedStream(), connectionCorrelationId, additionalHeaders);
return new Connect(withQueue.getSourceQueue(), connectionCorrelationId, STREAMING_TYPE_WS, version, optJsonWebToken.map(JsonWebToken::getExpirationTime).orElse(null), readDeclaredAcknowledgementLabels(additionalHeaders), connectionAuthContext);
}).recoverWithRetries(1, new PFBuilder<Throwable, Source<SessionedJsonifiable, NotUsed>>().match(GatewayWebsocketSessionExpiredException.class, ex -> {
logger.info("WebSocket connection terminated because JWT expired!");
return Source.empty();
}).match(GatewayWebsocketSessionClosedException.class, ex -> {
logger.info("WebSocket connection terminated because authorization context changed!");
return Source.empty();
}).match(DittoRuntimeException.class, ex -> Source.single(SessionedJsonifiable.error(ex))).build());
final Pair<Connect, Source<SessionedJsonifiable, NotUsed>> sourcePair = sourceToPreMaterialize.preMaterialize(materializer);
final Connect connect = sourcePair.first();
final Source<SessionedJsonifiable, NotUsed> eventAndResponseSource = sourcePair.second();
final Flow<DittoRuntimeException, SessionedJsonifiable, NotUsed> errorFlow = Flow.fromFunction(SessionedJsonifiable::error);
final int signalEnrichmentParallelism = streamingConfig.getParallelism();
final Flow<SessionedJsonifiable, Message, NotUsed> messageFlow = Flow.<SessionedJsonifiable>create().mapAsync(signalEnrichmentParallelism, postprocess(adapter, signalEnrichmentFacade, logger)).mapConcat(x -> x).via(Flow.fromFunction(result -> {
logger.debug("Sending outgoing WebSocket message: {}", result);
return result;
})).via(outgoingMessageSniffer.toAsyncFlow(request)).<Message>map(TextMessage::create).via(Flow.fromFunction(msg -> {
OUT_COUNTER.increment();
return msg;
}));
return Pair.create(connect, joinOutgoingFlows(eventAndResponseSource, errorFlow, messageFlow));
}
use of akka.japi.pf.PFBuilder in project ditto by eclipse.
the class MongoOpsUtil method doDeleteByFilter.
private static Source<Optional<Throwable>, NotUsed> doDeleteByFilter(final MongoCollection<Document> collection, final Bson filter) {
// https://stackoverflow.com/a/33164008
// claims unordered bulk ops halve MongoDB load
final List<WriteModel<Document>> writeModel = Collections.singletonList(new DeleteManyModel<>(filter));
final BulkWriteOptions options = new BulkWriteOptions().ordered(false);
return Source.fromPublisher(collection.bulkWrite(writeModel, options)).map(result -> {
if (LOGGER.isDebugEnabled()) {
// in contrast to Bson, BsonDocument has meaningful toString()
final BsonDocument filterBsonDoc = BsonUtil.toBsonDocument(filter);
LOGGER.debug("Deleted <{}> documents from collection <{}>. Filter was <{}>.", result.getDeletedCount(), collection.getNamespace(), filterBsonDoc);
}
return Optional.<Throwable>empty();
}).recoverWithRetries(RETRY_ATTEMPTS, new PFBuilder<Throwable, Source<Optional<Throwable>, NotUsed>>().matchAny(throwable -> Source.single(Optional.of(throwable))).build());
}
use of akka.japi.pf.PFBuilder in project ditto by eclipse.
the class MongoThingsSearchUpdaterPersistence method purge.
@Override
public Source<List<Throwable>, NotUsed> purge(final CharSequence namespace) {
final Bson filter = thingNamespaceFilter(namespace);
final Bson update = new BsonDocument().append(AbstractWriteModel.SET, new BsonDocument().append(PersistenceConstants.FIELD_DELETE_AT, new BsonDateTime(0L)));
final UpdateOptions updateOptions = new UpdateOptions().bypassDocumentValidation(true);
final WriteModel<Document> writeModel = new UpdateManyModel<>(filter, update, updateOptions);
return Source.fromPublisher(collection.bulkWrite(Collections.singletonList(writeModel))).map(bulkWriteResult -> Collections.<Throwable>emptyList()).recoverWithRetries(1, new PFBuilder<Throwable, Source<List<Throwable>, NotUsed>>().matchAny(throwable -> Source.single(Collections.singletonList(throwable))).build());
}
Aggregations