Search in sources :

Example 1 with OKAPI_TENANT_HEADER

use of org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER in project mod-circulation-storage by folio-org.

the class PubSubPublishingService method publishEvent.

public CompletableFuture<Boolean> publishEvent(String eventType, String payload) {
    Event event = new Event().withId(UUID.randomUUID().toString()).withEventType(eventType).withEventPayload(payload).withEventMetadata(new EventMetadata().withPublishedBy(PubSubClientUtils.getModuleId()).withTenantId(okapiHeaders.get(OKAPI_TENANT_HEADER)).withEventTTL(1));
    final CompletableFuture<Boolean> publishResult = new CompletableFuture<>();
    OkapiConnectionParams params = new OkapiConnectionParams();
    params.setOkapiUrl(okapiHeaders.get(OKAPI_URL_HEADER));
    params.setTenantId(okapiHeaders.get(OKAPI_TENANT_HEADER));
    params.setToken(okapiHeaders.get(OKAPI_TOKEN_HEADER));
    context.runOnContext(v -> PubSubClientUtils.sendEventMessage(event, params).whenComplete((result, throwable) -> {
        if (Boolean.TRUE.equals(result)) {
            logger.debug("Event published successfully. ID: {}, type: {}, payload: {}", event.getId(), event.getEventType(), event.getEventPayload());
            publishResult.complete(true);
        } else {
            logger.error("Failed to publish event. ID: {}, type: {}, payload: {}", throwable, event.getId(), event.getEventType(), event.getEventPayload());
            if (throwable == null) {
                publishResult.complete(false);
            } else {
                publishResult.completeExceptionally(throwable);
            }
        }
    }));
    return publishResult;
}
Also used : Event(org.folio.rest.jaxrs.model.Event) OKAPI_TENANT_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER) EventMetadata(org.folio.rest.jaxrs.model.EventMetadata) Vertx(io.vertx.core.Vertx) CompletableFuture(java.util.concurrent.CompletableFuture) OKAPI_URL_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_URL_HEADER) UUID(java.util.UUID) OkapiConnectionParams(org.folio.rest.util.OkapiConnectionParams) Context(io.vertx.core.Context) Logger(org.apache.logging.log4j.Logger) Map(java.util.Map) OKAPI_TOKEN_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_TOKEN_HEADER) PubSubClientUtils(org.folio.util.pubsub.PubSubClientUtils) LogManager(org.apache.logging.log4j.LogManager) CompletableFuture(java.util.concurrent.CompletableFuture) Event(org.folio.rest.jaxrs.model.Event) OkapiConnectionParams(org.folio.rest.util.OkapiConnectionParams) EventMetadata(org.folio.rest.jaxrs.model.EventMetadata)

Example 2 with OKAPI_TENANT_HEADER

use of org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER in project mod-circulation by folio-org.

the class PubSubPublishingService method publishEvent.

public CompletableFuture<Boolean> publishEvent(String eventType, String payload) {
    Event event = new Event().withId(UUID.randomUUID().toString()).withEventType(eventType).withEventPayload(payload).withEventMetadata(new EventMetadata().withPublishedBy(PubSubClientUtils.getModuleId()).withTenantId(okapiHeaders.get(OKAPI_TENANT_HEADER)).withEventTTL(1));
    final CompletableFuture<Boolean> publishResult = new CompletableFuture<>();
    OkapiConnectionParams params = new OkapiConnectionParams();
    params.setOkapiUrl(okapiHeaders.get(OKAPI_URL_HEADER));
    params.setTenantId(okapiHeaders.get(OKAPI_TENANT_HEADER));
    params.setToken(okapiHeaders.get(OKAPI_TOKEN_HEADER));
    vertxContext.runOnContext(v -> PubSubClientUtils.sendEventMessage(event, params).whenComplete((result, throwable) -> {
        if (Boolean.TRUE.equals(result)) {
            logger.info("Event published successfully. ID: {}, type: {}, payload: {}", event.getId(), event.getEventType(), event.getEventPayload());
            publishResult.complete(true);
        } else {
            logger.error("Failed to publish event. ID: {}, type: {}, payload: {}, cause: {}", event.getId(), event.getEventType(), event.getEventPayload(), throwable);
            if (throwable == null) {
                publishResult.complete(false);
            } else {
                publishResult.completeExceptionally(throwable);
            }
        }
    }));
    return publishResult;
}
Also used : Event(org.folio.rest.jaxrs.model.Event) ClientErrorResponse(org.folio.circulation.support.http.server.ClientErrorResponse) OKAPI_TENANT_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER) HttpResponse(io.vertx.ext.web.client.HttpResponse) EventMetadata(org.folio.rest.jaxrs.model.EventMetadata) ValidationErrorFailure(org.folio.circulation.support.ValidationErrorFailure) WebContext(org.folio.circulation.support.http.server.WebContext) CompleteFuture(io.netty.util.concurrent.CompleteFuture) Vertx(io.vertx.core.Vertx) CompletableFuture(java.util.concurrent.CompletableFuture) OKAPI_URL_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_URL_HEADER) UUID(java.util.UUID) RoutingContext(io.vertx.ext.web.RoutingContext) ValidationError(org.folio.circulation.support.http.server.ValidationError) Result(org.folio.circulation.support.results.Result) OkapiConnectionParams(org.folio.rest.util.OkapiConnectionParams) Context(io.vertx.core.Context) Logger(org.apache.logging.log4j.Logger) Map(java.util.Map) OKAPI_TOKEN_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_TOKEN_HEADER) EventSendingException(org.folio.util.pubsub.exceptions.EventSendingException) PubSubClientUtils(org.folio.util.pubsub.PubSubClientUtils) LogManager(org.apache.logging.log4j.LogManager) CompletableFuture(java.util.concurrent.CompletableFuture) Event(org.folio.rest.jaxrs.model.Event) OkapiConnectionParams(org.folio.rest.util.OkapiConnectionParams) EventMetadata(org.folio.rest.jaxrs.model.EventMetadata)

Example 3 with OKAPI_TENANT_HEADER

use of org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER in project mod-inventory by folio-org.

the class MarcBibInstanceHridSetKafkaHandler method handle.

@Override
public Future<String> handle(KafkaConsumerRecord<String, String> record) {
    try {
        Promise<String> promise = Promise.promise();
        Event event = OBJECT_MAPPER.readValue(record.value(), Event.class);
        @SuppressWarnings("unchecked") HashMap<String, String> eventPayload = OBJECT_MAPPER.readValue(event.getEventPayload(), HashMap.class);
        Map<String, String> headersMap = KafkaHeaderUtils.kafkaHeadersToMap(record.headers());
        String recordId = headersMap.get(RECORD_ID_HEADER);
        String chunkId = headersMap.get(CHUNK_ID_HEADER);
        String jobExecutionId = eventPayload.get(JOB_EXECUTION_ID_HEADER);
        LOGGER.info("Event payload has been received with event type: {}, recordId: {} by jobExecution: {} and chunkId: {}", event.getEventType(), recordId, jobExecutionId, chunkId);
        if (isEmpty(eventPayload.get(MARC_KEY))) {
            String message = format("Event payload does not contain required data to update Instance with event type: '%s', recordId: '%s' by jobExecution: '%s' and chunkId: '%s'", event.getEventType(), recordId, jobExecutionId, chunkId);
            LOGGER.error(message);
            return Future.failedFuture(message);
        }
        Context context = EventHandlingUtil.constructContext(headersMap.get(OKAPI_TENANT_HEADER), headersMap.get(OKAPI_TOKEN_HEADER), headersMap.get(OKAPI_URL_HEADER));
        Record marcRecord = new JsonObject(eventPayload.get(MARC_KEY)).mapTo(Record.class);
        mappingMetadataCache.get(jobExecutionId, context).map(metadataOptional -> metadataOptional.orElseThrow(() -> new EventProcessingException(format(MAPPING_METADATA_NOT_FOUND_MSG, jobExecutionId)))).onSuccess(mappingMetadataDto -> ensureEventPayloadWithMappingMetadata(eventPayload, mappingMetadataDto)).compose(v -> instanceUpdateDelegate.handle(eventPayload, marcRecord, context)).onComplete(ar -> {
            if (ar.succeeded()) {
                eventPayload.remove(CURRENT_RETRY_NUMBER);
                promise.complete(record.key());
            } else {
                if (ar.cause() instanceof OptimisticLockingException) {
                    processOLError(record, promise, eventPayload, ar);
                } else {
                    eventPayload.remove(CURRENT_RETRY_NUMBER);
                    LOGGER.error("Failed to set MarcBib Hrid by jobExecutionId {}:{}", jobExecutionId, ar.cause());
                    promise.fail(ar.cause());
                }
            }
        });
        return promise.future();
    } catch (Exception e) {
        LOGGER.error(format("Failed to process data import kafka record from topic %s", record.topic()), e);
        return Future.failedFuture(e);
    }
}
Also used : Context(org.folio.inventory.common.Context) MappingMetadataDto(org.folio.MappingMetadataDto) Context(org.folio.inventory.common.Context) OKAPI_TENANT_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER) HashMap(java.util.HashMap) OKAPI_URL_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_URL_HEADER) ObjectMapperTool(org.folio.dbschema.ObjectMapperTool) Map(java.util.Map) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult) StringUtils.isEmpty(org.apache.commons.lang3.StringUtils.isEmpty) Event(org.folio.rest.jaxrs.model.Event) Record(org.folio.rest.jaxrs.model.Record) Promise(io.vertx.core.Promise) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) AsyncRecordHandler(org.folio.kafka.AsyncRecordHandler) Future(io.vertx.core.Future) String.format(java.lang.String.format) InstanceUpdateDelegate(org.folio.inventory.dataimport.handlers.actions.InstanceUpdateDelegate) Logger(org.apache.logging.log4j.Logger) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) KafkaConsumerRecord(io.vertx.kafka.client.consumer.KafkaConsumerRecord) EventHandlingUtil(org.folio.inventory.dataimport.handlers.matching.util.EventHandlingUtil) OKAPI_TOKEN_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_TOKEN_HEADER) Instance(org.folio.inventory.domain.instances.Instance) OptimisticLockingException(org.folio.inventory.dataimport.exceptions.OptimisticLockingException) LogManager(org.apache.logging.log4j.LogManager) KafkaHeaderUtils(org.folio.kafka.KafkaHeaderUtils) MappingMetadataCache(org.folio.inventory.dataimport.cache.MappingMetadataCache) OptimisticLockingException(org.folio.inventory.dataimport.exceptions.OptimisticLockingException) JsonObject(io.vertx.core.json.JsonObject) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) OptimisticLockingException(org.folio.inventory.dataimport.exceptions.OptimisticLockingException) Event(org.folio.rest.jaxrs.model.Event) Record(org.folio.rest.jaxrs.model.Record) KafkaConsumerRecord(io.vertx.kafka.client.consumer.KafkaConsumerRecord) EventProcessingException(org.folio.processing.exceptions.EventProcessingException)

Example 4 with OKAPI_TENANT_HEADER

use of org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER in project mod-inventory by folio-org.

the class MarcHoldingsRecordHridSetKafkaHandler method handle.

@Override
public Future<String> handle(KafkaConsumerRecord<String, String> record) {
    try {
        Promise<String> promise = Promise.promise();
        Event event = OBJECT_MAPPER.readValue(record.value(), Event.class);
        @SuppressWarnings("unchecked") HashMap<String, String> eventPayload = OBJECT_MAPPER.readValue(event.getEventPayload(), HashMap.class);
        Map<String, String> headersMap = KafkaHeaderUtils.kafkaHeadersToMap(record.headers());
        String recordId = headersMap.get(RECORD_ID_HEADER);
        String chunkId = headersMap.get(CHUNK_ID_HEADER);
        String jobExecutionId = eventPayload.get(JOB_EXECUTION_ID_HEADER);
        LOGGER.info("Event payload has been received with event type: {}, recordId: {} by jobExecution: {} and chunkId: {}", event.getEventType(), recordId, jobExecutionId, chunkId);
        if (isEmpty(eventPayload.get(MARC_KEY))) {
            String message = String.format("Event payload does not contain required data to update Holdings with event type: '%s', recordId: '%s' by jobExecution: '%s' and chunkId: '%s'", event.getEventType(), recordId, jobExecutionId, chunkId);
            LOGGER.error(message);
            return Future.failedFuture(message);
        }
        Context context = constructContext(headersMap.get(OKAPI_TENANT_HEADER), headersMap.get(OKAPI_TOKEN_HEADER), headersMap.get(OKAPI_URL_HEADER));
        Record marcRecord = Json.decodeValue(eventPayload.get(MARC_KEY), Record.class);
        mappingMetadataCache.get(jobExecutionId, context).map(metadataOptional -> metadataOptional.orElseThrow(() -> new EventProcessingException(format(MAPPING_METADATA_NOT_FOUND_MSG, jobExecutionId)))).onSuccess(mappingMetadataDto -> ensureEventPayloadWithMappingMetadata(eventPayload, mappingMetadataDto)).compose(v -> holdingsRecordUpdateDelegate.handle(eventPayload, marcRecord, context)).onComplete(ar -> {
            if (ar.succeeded()) {
                eventPayload.remove(CURRENT_RETRY_NUMBER);
                promise.complete(record.key());
            } else {
                if (ar.cause() instanceof OptimisticLockingException) {
                    processOLError(record, promise, eventPayload, ar);
                } else {
                    eventPayload.remove(CURRENT_RETRY_NUMBER);
                    LOGGER.error("Failed to process data import event payload ", ar.cause());
                    promise.fail(ar.cause());
                }
            }
        });
        return promise.future();
    } catch (Exception e) {
        LOGGER.error(format("Failed to process data import kafka record from topic %s ", record.topic()), e);
        return Future.failedFuture(e);
    }
}
Also used : Context(org.folio.inventory.common.Context) EventHandlingUtil.constructContext(org.folio.inventory.dataimport.handlers.matching.util.EventHandlingUtil.constructContext) Json(io.vertx.core.json.Json) Context(org.folio.inventory.common.Context) MappingMetadataDto(org.folio.MappingMetadataDto) OKAPI_TENANT_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER) HashMap(java.util.HashMap) OKAPI_URL_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_URL_HEADER) EventHandlingUtil.constructContext(org.folio.inventory.dataimport.handlers.matching.util.EventHandlingUtil.constructContext) HoldingsUpdateDelegate(org.folio.inventory.dataimport.handlers.actions.HoldingsUpdateDelegate) ObjectMapperTool(org.folio.dbschema.ObjectMapperTool) Map(java.util.Map) AsyncResult(io.vertx.core.AsyncResult) StringUtils.isEmpty(org.apache.commons.lang3.StringUtils.isEmpty) Event(org.folio.rest.jaxrs.model.Event) Record(org.folio.rest.jaxrs.model.Record) Promise(io.vertx.core.Promise) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) AsyncRecordHandler(org.folio.kafka.AsyncRecordHandler) Future(io.vertx.core.Future) HoldingsRecord(org.folio.HoldingsRecord) String.format(java.lang.String.format) Logger(org.apache.logging.log4j.Logger) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) KafkaConsumerRecord(io.vertx.kafka.client.consumer.KafkaConsumerRecord) OKAPI_TOKEN_HEADER(org.folio.rest.util.OkapiConnectionParams.OKAPI_TOKEN_HEADER) OptimisticLockingException(org.folio.inventory.dataimport.exceptions.OptimisticLockingException) LogManager(org.apache.logging.log4j.LogManager) KafkaHeaderUtils(org.folio.kafka.KafkaHeaderUtils) MappingMetadataCache(org.folio.inventory.dataimport.cache.MappingMetadataCache) OptimisticLockingException(org.folio.inventory.dataimport.exceptions.OptimisticLockingException) Event(org.folio.rest.jaxrs.model.Event) Record(org.folio.rest.jaxrs.model.Record) HoldingsRecord(org.folio.HoldingsRecord) KafkaConsumerRecord(io.vertx.kafka.client.consumer.KafkaConsumerRecord) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) OptimisticLockingException(org.folio.inventory.dataimport.exceptions.OptimisticLockingException) EventProcessingException(org.folio.processing.exceptions.EventProcessingException)

Aggregations

Map (java.util.Map)4 LogManager (org.apache.logging.log4j.LogManager)4 Logger (org.apache.logging.log4j.Logger)4 Event (org.folio.rest.jaxrs.model.Event)4 OKAPI_TENANT_HEADER (org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER)4 OKAPI_TOKEN_HEADER (org.folio.rest.util.OkapiConnectionParams.OKAPI_TOKEN_HEADER)4 OKAPI_URL_HEADER (org.folio.rest.util.OkapiConnectionParams.OKAPI_URL_HEADER)4 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 AsyncResult (io.vertx.core.AsyncResult)2 Context (io.vertx.core.Context)2 Future (io.vertx.core.Future)2 Promise (io.vertx.core.Promise)2 Vertx (io.vertx.core.Vertx)2 KafkaConsumerRecord (io.vertx.kafka.client.consumer.KafkaConsumerRecord)2 String.format (java.lang.String.format)2 HashMap (java.util.HashMap)2 UUID (java.util.UUID)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 StringUtils.isEmpty (org.apache.commons.lang3.StringUtils.isEmpty)2 MappingMetadataDto (org.folio.MappingMetadataDto)2