All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.turbospaces.gcp.pubsub.producer.PubsubPostTemplate Maven / Gradle / Ivy
package com.turbospaces.gcp.pubsub.producer;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import org.slf4j.MDC;
import com.google.cloud.spring.pubsub.support.PublisherFactory;
import com.google.protobuf.Any;
import com.google.pubsub.v1.PubsubMessage;
import com.turbospaces.annotations.NotInTransactionGuard;
import com.turbospaces.api.facade.MDCToHeadersContexPropagator;
import com.turbospaces.api.facade.RequestWrapperFacade;
import com.turbospaces.cfg.ApplicationProperties;
import com.turbospaces.dispatch.EventQueuePostSpec;
import com.turbospaces.dispatch.NotifyQueuePostSpec;
import com.turbospaces.dispatch.QueuePostSpec;
import com.turbospaces.dispatch.RequestQueuePostSpec;
import com.turbospaces.http.HttpProto;
import com.turbospaces.mdc.MdcTags;
import com.turbospaces.rpc.DefaultRequestReplyMapper;
import com.turbospaces.rpc.DefaultWrappedQueuePost;
import com.turbospaces.rpc.QueuePostTemplate;
import com.turbospaces.rpc.WrappedQueuePost;
import api.v1.ApiFactory;
import io.cloudevents.core.builder.CloudEventBuilder;
import io.cloudevents.gpubsub.impl.PubsubWithRoutingKeyMessageWriterImpl;
import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentracing.Tracer.SpanBuilder;
import io.opentracing.propagation.Format.Builtin;
import jakarta.inject.Inject;
public class PubsubPostTemplate extends DefaultPubsubPublisher implements QueuePostTemplate {
private final Tracer tracer;
private final ApiFactory apiFactory;
private final DefaultRequestReplyMapper mapper;
private final Supplier defaultTimeout;
@Inject
public PubsubPostTemplate(
ApplicationProperties props,
Tracer tracer,
ApiFactory apiFactory,
DefaultRequestReplyMapper mapper,
PublisherFactory producerFactory,
Supplier timeout) throws Exception {
super(props, producerFactory);
this.tracer = Objects.requireNonNull(tracer);
this.apiFactory = Objects.requireNonNull(apiFactory);
this.mapper = Objects.requireNonNull(mapper);
this.defaultTimeout = Objects.requireNonNull(timeout);
}
@Override
@NotInTransactionGuard
public WrappedQueuePost sendReq(RequestQueuePostSpec spec) {
Duration operationTimeout = spec.timeout().orElse(defaultTimeout.get());
long now = System.currentTimeMillis();
String qualifier = spec.topic().name().toString();
UUID messageId = spec.messageId();
CloudEventBuilder eventTemplate = apiFactory.eventTemplate();
RequestWrapperFacade reqw = apiFactory.requestMapper().pack(spec, new MDCToHeadersContexPropagator(), defaultTimeout.get());
String typeUrl = reqw.body().getTypeUrl();
CloudEventBuilder event = eventTemplate.newBuilder()
.withId(messageId.toString())
.withTime(OffsetDateTime.ofInstant(Instant.ofEpochMilli(now), UTC))
.withType(typeUrl);
var record = PubsubMessage.newBuilder();
record.setData(reqw.toByteString());
if (spec.routingKey().isPresent()) {
record.setOrderingKey(spec.routingKey().get().toString());
}
record.putAttributes(HttpProto.HEADER_X_TIMESTAMP, String.valueOf(now));
var post = span(spec, record);
var messageWriter = new PubsubWithRoutingKeyMessageWriterImpl(record);
var future = mapper.acquire(messageId, operationTimeout);
var callback = new LoggingCallback(typeUrl, messageId, spec.topic(), now) {
@Override
public void onSuccess(String result) {
super.onSuccess(result);
post.finish();
}
@Override
public void onFailure(Throwable ex) {
super.onFailure(ex);
future.setException(ex);
post.finish();
}
};
publish(qualifier, messageWriter.writeBinary(event.build()), new BiConsumer() {
@Override
public void accept(String result, Throwable ex) {
if (Objects.nonNull(ex)) {
callback.onFailure(ex);
} else {
callback.onSuccess(result);
}
}
});
return new DefaultWrappedQueuePost(future, reqw);
}
@Override
@NotInTransactionGuard
public CompletableFuture sendEvent(EventQueuePostSpec spec) {
Any any = spec.pack();
long now = System.currentTimeMillis();
String qualifier = spec.topic().name().toString();
String typeUrl = any.getTypeUrl();
UUID messageId = spec.messageId();
var record = PubsubMessage.newBuilder();
record.setData(any.toByteString());
if (spec.routingKey().isPresent()) {
record.setOrderingKey(spec.routingKey().get().toString());
}
var traceId = MDC.get(MdcTags.MDC_TRACE_ID);
if (Objects.nonNull(traceId)) {
record.putAttributes(MdcTags.MDC_TRACE_ID, traceId);
}
CloudEventBuilder eventTemplate = CloudEventBuilder.v1().withSource(URI.create(props.CLOUD_APP_ID.get()));
CloudEventBuilder event = eventTemplate.newBuilder()
.withId(messageId.toString())
.withTime(OffsetDateTime.ofInstant(Instant.ofEpochMilli(now), UTC))
.withType(typeUrl);
var post = span(spec, record);
var messageWriter = new PubsubWithRoutingKeyMessageWriterImpl(record);
var callback = new LoggingCallback(typeUrl, messageId, spec.topic(), now) {
@Override
public void onSuccess(String result) {
super.onSuccess(result);
post.finish();
}
@Override
public void onFailure(Throwable ex) {
super.onFailure(ex);
post.finish();
}
};
return publish(qualifier, messageWriter.writeBinary(event.build()), new BiConsumer() {
@Override
public void accept(String result, Throwable ex) {
if (Objects.nonNull(ex)) {
callback.onFailure(ex);
} else {
callback.onSuccess(result);
}
}
});
}
@Override
@NotInTransactionGuard
public CompletableFuture sendNotify(NotifyQueuePostSpec spec) {
long now = System.currentTimeMillis();
String qualifier = spec.topic().name().toString();
String typeUrl = spec.body().getTypeUrl();
UUID messageId = spec.messageId();
var record = PubsubMessage.newBuilder();
record.setData(spec.toByteString());
if (spec.routingKey().isPresent()) {
record.setOrderingKey(spec.routingKey().get().toString());
}
var traceId = MDC.get(MdcTags.MDC_TRACE_ID);
if (Objects.nonNull(traceId)) {
record.putAttributes(MdcTags.MDC_TRACE_ID, traceId);
}
CloudEventBuilder eventTemplate = CloudEventBuilder.v1().withSource(URI.create(props.CLOUD_APP_ID.get()));
CloudEventBuilder event = eventTemplate.newBuilder()
.withId(messageId.toString())
.withTime(OffsetDateTime.ofInstant(Instant.ofEpochMilli(now), UTC))
.withType(typeUrl);
var post = span(spec, record);
var messageWriter = new PubsubWithRoutingKeyMessageWriterImpl(record);
var callback = new LoggingCallback(typeUrl, messageId, spec.topic(), now) {
@Override
public void onSuccess(String result) {
super.onSuccess(result);
post.finish();
}
@Override
public void onFailure(Throwable ex) {
super.onFailure(ex);
post.finish();
}
};
return publish(qualifier, messageWriter.writeBinary(event.build()), new BiConsumer() {
@Override
public void accept(String result, Throwable ex) {
if (Objects.nonNull(ex)) {
callback.onFailure(ex);
} else {
callback.onSuccess(result);
}
}
});
}
private Span span(QueuePostSpec spec, PubsubMessage.Builder recordBuilder) {
Span span = tracer.activeSpan();
SpanBuilder post = tracer.buildSpan("pubsub-post");
if (Objects.nonNull(span)) {
tracer.inject(span.context(), Builtin.TEXT_MAP, new PubsubSpanContextWriter(recordBuilder));
return post.asChildOf(span).start();
}
return post.start();
}
}