Search in sources :

Example 1 with JobExecutionSourceChunk

use of org.folio.rest.jaxrs.model.JobExecutionSourceChunk in project mod-source-record-manager by folio-org.

the class JobExecutionSourceChunkDaoImpl method mapResultSetToJobExecutionSourceChunks.

private List<JobExecutionSourceChunk> mapResultSetToJobExecutionSourceChunks(RowSet<Row> resultSet) {
    List<JobExecutionSourceChunk> result = new ArrayList<>();
    resultSet.forEach(row -> {
        JsonObject jsonb = row.getJsonObject("jsonb");
        JobExecutionSourceChunk chunk = new JobExecutionSourceChunk().withId(row.getUUID(ID_FIELD).toString()).withJobExecutionId(row.getUUID(JOB_EXECUTION_ID_FIELD).toString()).withChunkSize(jsonb.getInteger(CHUNK_SIZE_JSONB_FIELD)).withState(State.fromValue(jsonb.getString(STATE_JSONB_FIELD))).withCreatedDate(new Date(jsonb.getLong(CREATED_DATE_JSONB_FIELD))).withLast(jsonb.getBoolean(LAST_JSONB_FIELD));
        result.add(chunk);
    });
    return result;
}
Also used : ArrayList(java.util.ArrayList) JsonObject(io.vertx.core.json.JsonObject) JobExecutionSourceChunk(org.folio.rest.jaxrs.model.JobExecutionSourceChunk) Date(java.util.Date)

Example 2 with JobExecutionSourceChunk

use of org.folio.rest.jaxrs.model.JobExecutionSourceChunk in project mod-source-record-manager by folio-org.

the class EventDrivenChunkProcessingServiceImpl method processRawRecordsChunk.

@Override
protected Future<Boolean> processRawRecordsChunk(RawRecordsDto incomingChunk, JobExecutionSourceChunk sourceChunk, String jobExecutionId, OkapiConnectionParams params) {
    LOGGER.debug("Starting to process raw records chunk with id: {} for jobExecutionId: {}. Chunk size: {}.", sourceChunk.getId(), jobExecutionId, sourceChunk.getChunkSize());
    Promise<Boolean> promise = Promise.promise();
    initializeJobExecutionProgressIfNecessary(jobExecutionId, incomingChunk, params.getTenantId()).compose(ar -> checkAndUpdateJobExecutionStatusIfNecessary(jobExecutionId, new StatusDto().withStatus(StatusDto.Status.PARSING_IN_PROGRESS), params)).compose(jobExec -> changeEngineService.parseRawRecordsChunkForJobExecution(incomingChunk, jobExec, sourceChunk.getId(), params)).onComplete(sendEventsAr -> updateJobExecutionIfAllSourceChunksMarkedAsError(jobExecutionId, params).onComplete(updateAr -> promise.handle(sendEventsAr.map(true))));
    return promise.future();
}
Also used : StatusDto(org.folio.rest.jaxrs.model.StatusDto) StatusDto(org.folio.rest.jaxrs.model.StatusDto) Promise(io.vertx.core.Promise) Autowired(org.springframework.beans.factory.annotation.Autowired) JobExecutionSourceChunk(org.folio.rest.jaxrs.model.JobExecutionSourceChunk) Future(io.vertx.core.Future) OkapiConnectionParams(org.folio.dataimport.util.OkapiConnectionParams) NotFoundException(javax.ws.rs.NotFoundException) RawRecordsDto(org.folio.rest.jaxrs.model.RawRecordsDto) Logger(org.apache.logging.log4j.Logger) JobExecutionProgress(org.folio.rest.jaxrs.model.JobExecutionProgress) JobExecutionProgressService(org.folio.services.progress.JobExecutionProgressService) CollectionUtils.isNotEmpty(org.apache.commons.collections4.CollectionUtils.isNotEmpty) PARSING_IN_PROGRESS(org.folio.rest.jaxrs.model.StatusDto.Status.PARSING_IN_PROGRESS) Service(org.springframework.stereotype.Service) JobExecutionSourceChunkDao(org.folio.dao.JobExecutionSourceChunkDao) JobExecution(org.folio.rest.jaxrs.model.JobExecution) LogManager(org.apache.logging.log4j.LogManager)

Example 3 with JobExecutionSourceChunk

use of org.folio.rest.jaxrs.model.JobExecutionSourceChunk in project mod-source-record-manager by folio-org.

the class JobExecutionDaoImplTest method prepareDataForDeletion.

private Future<JobExecution> prepareDataForDeletion(Instant completedDate) {
    InitJobExecutionsRsDto response = constructAndPostInitJobExecutionRqDto(1);
    List<JobExecution> createdJobExecutions = response.getJobExecutions();
    assertThat(createdJobExecutions.size(), Matchers.is(1));
    JobExecution jobExec = createdJobExecutions.get(0);
    jobExec.withCompletedDate(Date.from(completedDate));
    JobExecutionProgress jobExecutionProgress = new JobExecutionProgress().withJobExecutionId(jobExec.getId()).withTotal(1).withCurrentlySucceeded(1).withCurrentlyFailed(0);
    JobMonitoring jobMonitoring = new JobMonitoring().withId(UUID.randomUUID().toString()).withJobExecutionId(jobExec.getId()).withNotificationSent(true).withLastEventTimestamp(new Date());
    JournalRecord journalRecord = new JournalRecord().withJobExecutionId(jobExec.getId()).withSourceRecordOrder(0).withSourceId(UUID.randomUUID().toString()).withEntityType(JournalRecord.EntityType.MARC_BIBLIOGRAPHIC).withEntityId(UUID.randomUUID().toString()).withActionType(CREATE).withActionDate(new Date()).withActionStatus(COMPLETED);
    JobExecutionSourceChunk jobExecutionSourceChunk = new JobExecutionSourceChunk().withId("67dfac11-1caf-4470-9ad1-d533f6360bdd").withJobExecutionId(jobExec.getId()).withLast(false).withState(JobExecutionSourceChunk.State.COMPLETED).withChunkSize(10).withProcessedAmount(42);
    return jobExecutionDao.updateJobExecution(jobExec, TENANT_ID).compose(jobExecution -> {
        Future<RowSet<Row>> saveProgressFuture = jobExecutionProgressDao.save(jobExecutionProgress, TENANT_ID);
        Future<String> saveMonitoringFuture = jobMonitoringDao.save(jobMonitoring, TENANT_ID);
        Future<String> saveJournalFuture = journalRecordDao.save(journalRecord, TENANT_ID);
        Future<String> saveSourceChunkFuture = jobExecutionSourceChunkDao.save(jobExecutionSourceChunk, TENANT_ID);
        return CompositeFuture.all(saveProgressFuture, saveMonitoringFuture, saveJournalFuture, saveSourceChunkFuture).compose(ar -> Future.succeededFuture(jobExecution));
    });
}
Also used : JobExecution(org.folio.rest.jaxrs.model.JobExecution) JobExecutionProgress(org.folio.rest.jaxrs.model.JobExecutionProgress) RowSet(io.vertx.sqlclient.RowSet) JobExecutionSourceChunk(org.folio.rest.jaxrs.model.JobExecutionSourceChunk) InitJobExecutionsRsDto(org.folio.rest.jaxrs.model.InitJobExecutionsRsDto) JobMonitoring(org.folio.rest.jaxrs.model.JobMonitoring) Date(java.util.Date) JournalRecord(org.folio.rest.jaxrs.model.JournalRecord)

Example 4 with JobExecutionSourceChunk

use of org.folio.rest.jaxrs.model.JobExecutionSourceChunk in project mod-source-record-manager by folio-org.

the class AbstractChunkProcessingService method processChunk.

@Override
public Future<Boolean> processChunk(RawRecordsDto incomingChunk, String jobExecutionId, OkapiConnectionParams params) {
    LOGGER.debug("AbstractChunkProcessingService:: processChunk for jobExecutionId: {}", jobExecutionId);
    prepareChunk(incomingChunk);
    return jobExecutionService.getJobExecutionById(jobExecutionId, params.getTenantId()).compose(optionalJobExecution -> optionalJobExecution.map(jobExecution -> {
        JobExecutionSourceChunk sourceChunk = new JobExecutionSourceChunk().withId(incomingChunk.getId()).withJobExecutionId(jobExecutionId).withLast(incomingChunk.getRecordsMetadata().getLast()).withState(JobExecutionSourceChunk.State.IN_PROGRESS).withChunkSize(incomingChunk.getInitialRecords().size()).withCreatedDate(new Date());
        return jobExecutionSourceChunkDao.save(sourceChunk, params.getTenantId()).compose(ar -> processRawRecordsChunk(incomingChunk, sourceChunk, jobExecution.getId(), params)).map(true).recover(throwable -> throwable instanceof PgException && ((PgException) throwable).getCode().equals(UNIQUE_CONSTRAINT_VIOLATION_CODE) ? Future.failedFuture(new DuplicateEventException(String.format("Source chunk with %s id for %s jobExecution is already exists", incomingChunk.getId(), jobExecutionId))) : Future.failedFuture(throwable));
    }).orElse(Future.failedFuture(new NotFoundException(String.format("Couldn't find JobExecution with id %s", jobExecutionId)))));
}
Also used : DuplicateEventException(org.folio.kafka.exception.DuplicateEventException) NotFoundException(javax.ws.rs.NotFoundException) JobExecutionSourceChunk(org.folio.rest.jaxrs.model.JobExecutionSourceChunk) Date(java.util.Date) PgException(io.vertx.pgclient.PgException)

Example 5 with JobExecutionSourceChunk

use of org.folio.rest.jaxrs.model.JobExecutionSourceChunk in project mod-source-record-manager by folio-org.

the class ChangeEngineServiceImpl method parseRawRecordsChunkForJobExecution.

@Override
public Future<List<Record>> parseRawRecordsChunkForJobExecution(RawRecordsDto chunk, JobExecution jobExecution, String sourceChunkId, OkapiConnectionParams params) {
    Promise<List<Record>> promise = Promise.promise();
    Future<List<Record>> futureParsedRecords = parseRecords(chunk.getInitialRecords(), chunk.getRecordsMetadata().getContentType(), jobExecution, sourceChunkId, params.getTenantId(), params);
    futureParsedRecords.compose(parsedRecords -> ensureMappingMetaDataSnapshot(jobExecution.getId(), parsedRecords, params).map(parsedRecords)).onSuccess(parsedRecords -> {
        fillParsedRecordsWithAdditionalFields(parsedRecords);
        if (updateMarcActionExists(jobExecution)) {
            updateRecords(parsedRecords, jobExecution, params).onSuccess(ar -> promise.complete(parsedRecords)).onFailure(promise::fail);
        } else if (deleteMarcActionExists(jobExecution)) {
            deleteRecords(parsedRecords, jobExecution, params).onSuccess(ar -> promise.complete(parsedRecords)).onFailure(promise::fail);
        } else {
            saveRecords(params, jobExecution, parsedRecords).onComplete(postAr -> {
                if (postAr.failed()) {
                    StatusDto statusDto = new StatusDto().withStatus(StatusDto.Status.ERROR).withErrorStatus(StatusDto.ErrorStatus.RECORD_UPDATE_ERROR);
                    jobExecutionService.updateJobExecutionStatus(jobExecution.getId(), statusDto, params).onComplete(r -> {
                        if (r.failed()) {
                            LOGGER.error("Error during update jobExecution and snapshot status", r.cause());
                        }
                    });
                    jobExecutionSourceChunkDao.getById(sourceChunkId, params.getTenantId()).compose(optional -> optional.map(sourceChunk -> jobExecutionSourceChunkDao.update(sourceChunk.withState(JobExecutionSourceChunk.State.ERROR), params.getTenantId())).orElseThrow(() -> new NotFoundException(String.format("Couldn't update failed jobExecutionSourceChunk status to ERROR, jobExecutionSourceChunk with id %s was not found", sourceChunkId)))).onComplete(ar -> promise.fail(postAr.cause()));
                } else {
                    promise.complete(parsedRecords);
                }
            });
        }
    }).onFailure(th -> {
        LOGGER.error("Error parsing records: {}", th.getMessage());
        promise.fail(th);
    });
    return promise.future();
}
Also used : StringUtils(org.apache.commons.lang.StringUtils) MutableInt(org.apache.commons.lang3.mutable.MutableInt) TAG_999(org.folio.services.afterprocessing.AdditionalFieldsUtil.TAG_999) Autowired(org.springframework.beans.factory.annotation.Autowired) RecordAnalyzer(org.folio.dataimport.util.marc.RecordAnalyzer) MARC_HOLDING(org.folio.rest.jaxrs.model.Record.RecordType.MARC_HOLDING) RecordType(org.folio.rest.jaxrs.model.Record.RecordType) ProfileSnapshotWrapper(org.folio.rest.jaxrs.model.ProfileSnapshotWrapper) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MarcRecordAnalyzer(org.folio.dataimport.util.marc.MarcRecordAnalyzer) Map(java.util.Map) JobExecutionSourceChunkDao(org.folio.dao.JobExecutionSourceChunkDao) JobExecution(org.folio.rest.jaxrs.model.JobExecution) RecordParserBuilder(org.folio.services.parsers.RecordParserBuilder) JsonObject(io.vertx.core.json.JsonObject) DI_ERROR(org.folio.rest.jaxrs.model.DataImportEventTypes.DI_ERROR) AdditionalFieldsUtil.getValue(org.folio.services.afterprocessing.AdditionalFieldsUtil.getValue) InitialRecord(org.folio.rest.jaxrs.model.InitialRecord) StatusDto(org.folio.rest.jaxrs.model.StatusDto) MODULE_SPECIFIC_ARGS(org.folio.rest.RestVerticle.MODULE_SPECIFIC_ARGS) AdditionalFieldsUtil.getControlFieldValue(org.folio.services.afterprocessing.AdditionalFieldsUtil.getControlFieldValue) Collection(java.util.Collection) EventHandlingUtil.sendEventToKafka(org.folio.services.util.EventHandlingUtil.sendEventToKafka) UUID(java.util.UUID) JobExecutionSourceChunk(org.folio.rest.jaxrs.model.JobExecutionSourceChunk) RecordCollection(org.folio.rest.jaxrs.model.RecordCollection) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) String.format(java.lang.String.format) NotFoundException(javax.ws.rs.NotFoundException) OkapiConnectionParams(org.folio.dataimport.util.OkapiConnectionParams) KafkaHeaderImpl(io.vertx.kafka.client.producer.impl.KafkaHeaderImpl) FolioRecord(org.folio.rest.jaxrs.model.ActionProfile.FolioRecord) Objects(java.util.Objects) List(java.util.List) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) Logger(org.apache.logging.log4j.Logger) DI_MARC_FOR_UPDATE_RECEIVED(org.folio.rest.jaxrs.model.DataImportEventTypes.DI_MARC_FOR_UPDATE_RECEIVED) KafkaHeaderUtils(org.folio.kafka.KafkaHeaderUtils) ParsedRecord(org.folio.rest.jaxrs.model.ParsedRecord) HrIdFieldService(org.folio.services.afterprocessing.HrIdFieldService) Json(io.vertx.core.json.Json) DI_RAW_RECORDS_CHUNK_PARSED(org.folio.rest.jaxrs.model.DataImportEventTypes.DI_RAW_RECORDS_CHUNK_PARSED) DataImportEventPayload(org.folio.rest.jaxrs.model.DataImportEventPayload) RawRecord(org.folio.rest.jaxrs.model.RawRecord) HashMap(java.util.HashMap) RecordsMetadata(org.folio.rest.jaxrs.model.RecordsMetadata) Function(java.util.function.Function) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ArrayList(java.util.ArrayList) DI_MARC_FOR_DELETE_RECEIVED(org.folio.rest.jaxrs.model.DataImportEventTypes.DI_MARC_FOR_DELETE_RECEIVED) Value(org.springframework.beans.factory.annotation.Value) MARC_AUTHORITY(org.folio.rest.jaxrs.model.Record.RecordType.MARC_AUTHORITY) CompositeFuture(io.vertx.core.CompositeFuture) IterableUtils(org.apache.commons.collections4.IterableUtils) DataType(org.folio.rest.jaxrs.model.JobProfileInfo.DataType) Lists(com.google.common.collect.Lists) Action(org.folio.rest.jaxrs.model.ActionProfile.Action) ExternalIdsHolder(org.folio.rest.jaxrs.model.ExternalIdsHolder) Service(org.springframework.stereotype.Service) AdditionalFieldsUtil.addFieldToMarcRecord(org.folio.services.afterprocessing.AdditionalFieldsUtil.addFieldToMarcRecord) SourceStorageBatchClient(org.folio.rest.client.SourceStorageBatchClient) ActionProfile(org.folio.rest.jaxrs.model.ActionProfile) EntityType(org.folio.rest.jaxrs.model.EntityType) Record(org.folio.rest.jaxrs.model.Record) ParsedResult(org.folio.services.parsers.ParsedResult) RecordConversionUtil(org.folio.services.util.RecordConversionUtil) Promise(io.vertx.core.Promise) AdditionalFieldsUtil.hasIndicator(org.folio.services.afterprocessing.AdditionalFieldsUtil.hasIndicator) RawRecordsDto(org.folio.rest.jaxrs.model.RawRecordsDto) MARC_BIB(org.folio.rest.jaxrs.model.Record.RecordType.MARC_BIB) SUBFIELD_S(org.folio.services.afterprocessing.AdditionalFieldsUtil.SUBFIELD_S) StringUtils.isBlank(org.apache.commons.lang3.StringUtils.isBlank) ErrorRecord(org.folio.rest.jaxrs.model.ErrorRecord) SUBFIELD_I(org.folio.services.afterprocessing.AdditionalFieldsUtil.SUBFIELD_I) MarcRecordType(org.folio.dataimport.util.marc.MarcRecordType) Collections(java.util.Collections) KafkaHeader(io.vertx.kafka.client.producer.KafkaHeader) LogManager(org.apache.logging.log4j.LogManager) KafkaConfig(org.folio.kafka.KafkaConfig) StatusDto(org.folio.rest.jaxrs.model.StatusDto) NotFoundException(javax.ws.rs.NotFoundException) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

JobExecutionSourceChunk (org.folio.rest.jaxrs.model.JobExecutionSourceChunk)19 JobExecution (org.folio.rest.jaxrs.model.JobExecution)14 RawRecordsDto (org.folio.rest.jaxrs.model.RawRecordsDto)14 List (java.util.List)12 Test (org.junit.Test)12 ArgumentMatchers.anyList (org.mockito.ArgumentMatchers.anyList)9 JsonObject (io.vertx.core.json.JsonObject)6 NotFoundException (javax.ws.rs.NotFoundException)5 JobExecutionSourceChunkDao (org.folio.dao.JobExecutionSourceChunkDao)5 Future (io.vertx.core.Future)4 OkapiConnectionParams (org.folio.dataimport.util.OkapiConnectionParams)4 ActionProfile (org.folio.rest.jaxrs.model.ActionProfile)4 ProfileSnapshotWrapper (org.folio.rest.jaxrs.model.ProfileSnapshotWrapper)4 Promise (io.vertx.core.Promise)3 Json (io.vertx.core.json.Json)3 KafkaHeader (io.vertx.kafka.client.producer.KafkaHeader)3 ArrayList (java.util.ArrayList)3 Collections (java.util.Collections)3 Date (java.util.Date)3 HashMap (java.util.HashMap)3