Search in sources :

Example 1 with Request

use of org.folio.oaipmh.Request in project mod-oai-pmh by folio-org.

the class AbstractGetRecordsHelper method buildRecords.

/**
 * Builds {@link Map} with storage id as key and {@link RecordType} with populated header if there is any,
 * otherwise empty map is returned
 */
private Map<String, RecordType> buildRecords(Context context, Request request, JsonArray instances) {
    final boolean suppressedRecordsProcessingEnabled = getBooleanProperty(request.getRequestId(), REPOSITORY_SUPPRESSED_RECORDS_PROCESSING);
    if (instances != null && !instances.isEmpty()) {
        Map<String, RecordType> records = new HashMap<>();
        RecordMetadataManager metadataManager = RecordMetadataManager.getInstance();
        // Using LinkedHashMap just to rely on order returned by storage service
        String identifierPrefix = request.getIdentifierPrefix();
        instances.stream().map(JsonObject.class::cast).filter(instance -> isNotEmpty(storageHelper.getIdentifierId(instance))).forEach(instance -> {
            String recordId = storageHelper.getRecordId(instance);
            String identifierId = storageHelper.getIdentifierId(instance);
            RecordType record = createRecord(request, identifierPrefix, instance, identifierId);
            // Some repositories like SRS can return record source data along with other info
            String source = storageHelper.getInstanceRecordSource(instance);
            if (source != null && record.getHeader().getStatus() == null) {
                if (suppressedRecordsProcessingEnabled) {
                    source = metadataManager.updateMetadataSourceWithDiscoverySuppressedData(source, instance);
                }
                try {
                    record.withMetadata(buildOaiMetadata(request, source));
                } catch (Exception e) {
                    logger.error("Error occurred while converting record to xml representation. {}.", e.getMessage(), e);
                    logger.debug("Skipping problematic record due the conversion error. Source record id - {}.", recordId);
                    return;
                }
            } else {
                context.put(recordId, instance);
            }
            if (filterInstance(request, instance)) {
                records.put(recordId, record);
            }
        });
        return records;
    }
    return Collections.emptyMap();
}
Also used : HttpResponse(io.vertx.ext.web.client.HttpResponse) SourceStorageSourceRecordsClientWrapper(org.folio.oaipmh.service.SourceStorageSourceRecordsClientWrapper) DecodeException(io.vertx.core.json.DecodeException) Date(java.util.Date) StatusType(org.openarchives.oai._2.StatusType) SEND_REQUEST(org.folio.oaipmh.service.MetricsCollectingService.MetricOperation.SEND_REQUEST) HashMap(java.util.HashMap) REPOSITORY_MAX_RECORDS_PER_RESPONSE(org.folio.oaipmh.Constants.REPOSITORY_MAX_RECORDS_PER_RESPONSE) GENERIC_ERROR_MESSAGE(org.folio.oaipmh.Constants.GENERIC_ERROR_MESSAGE) Context(io.vertx.core.Context) StringUtils.isNotEmpty(org.apache.commons.lang3.StringUtils.isNotEmpty) OAIPMHerrorType(org.openarchives.oai._2.OAIPMHerrorType) ResumptionTokenType(org.openarchives.oai._2.ResumptionTokenType) RepositoryConfigurationUtil.getBooleanProperty(org.folio.oaipmh.helpers.RepositoryConfigurationUtil.getBooleanProperty) Request(org.folio.oaipmh.Request) OAIPMH(org.openarchives.oai._2.OAIPMH) Map(java.util.Map) BAD_RESUMPTION_TOKEN(org.openarchives.oai._2.OAIPMHerrorcodeType.BAD_RESUMPTION_TOKEN) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult) RESUMPTION_TOKEN_FLOW_ERROR(org.folio.oaipmh.Constants.RESUMPTION_TOKEN_FLOW_ERROR) Promise(io.vertx.core.Promise) Collection(java.util.Collection) RecordMetadataManager(org.folio.oaipmh.helpers.records.RecordMetadataManager) MetricsCollectingService(org.folio.oaipmh.service.MetricsCollectingService) Future(io.vertx.core.Future) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Buffer(io.vertx.core.buffer.Buffer) Response(javax.ws.rs.core.Response) WebClientProvider(org.folio.oaipmh.WebClientProvider) RecordType(org.openarchives.oai._2.RecordType) RepositoryConfigurationUtil.isDeletedRecordsEnabled(org.folio.oaipmh.helpers.RepositoryConfigurationUtil.isDeletedRecordsEnabled) REPOSITORY_SUPPRESSED_RECORDS_PROCESSING(org.folio.oaipmh.Constants.REPOSITORY_SUPPRESSED_RECORDS_PROCESSING) ListRecordsType(org.openarchives.oai._2.ListRecordsType) Handler(io.vertx.core.Handler) Response.isSuccess(org.folio.rest.tools.client.Response.isSuccess) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) RecordType(org.openarchives.oai._2.RecordType) HashMap(java.util.HashMap) RecordMetadataManager(org.folio.oaipmh.helpers.records.RecordMetadataManager) JsonObject(io.vertx.core.json.JsonObject) DecodeException(io.vertx.core.json.DecodeException)

Example 2 with Request

use of org.folio.oaipmh.Request in project mod-oai-pmh by folio-org.

the class MarcWithHoldingsRequestHelper method processBatch.

private void processBatch(Request request, Context context, Promise<Response> oaiPmhResponsePromise, String requestId, boolean firstBatch) {
    try {
        boolean deletedRecordSupport = RepositoryConfigurationUtil.isDeletedRecordsEnabled(request.getRequestId());
        int batchSize = Integer.parseInt(RepositoryConfigurationUtil.getProperty(request.getRequestId(), REPOSITORY_MAX_RECORDS_PER_RESPONSE));
        getNextInstances(request, batchSize, requestId, firstBatch).future().onComplete(fut -> {
            if (fut.failed()) {
                logger.error("Get instances failed: {}.", fut.cause().getMessage(), fut.cause());
                oaiPmhResponsePromise.fail(fut.cause());
                return;
            }
            List<JsonObject> instances = fut.result();
            logger.debug("Processing instances: {}.", instances.size());
            if (CollectionUtils.isEmpty(instances) && !firstBatch) {
                handleException(oaiPmhResponsePromise, new IllegalArgumentException("Specified resumption token doesn't exists."));
                return;
            }
            if (!firstBatch && (CollectionUtils.isNotEmpty(instances) && !instances.get(0).getString(INSTANCE_ID_FIELD_NAME).equals(request.getNextRecordId()))) {
                handleException(oaiPmhResponsePromise, new IllegalArgumentException("Stale resumption token."));
                return;
            }
            if (CollectionUtils.isEmpty(instances)) {
                logger.debug("Got empty instances.");
                buildRecordsResponse(request, requestId, instances, new HashMap<>(), firstBatch, null, deletedRecordSupport).onSuccess(oaiPmhResponsePromise::complete).onFailure(e -> handleException(oaiPmhResponsePromise, e));
                return;
            }
            String nextInstanceId = instances.size() <= batchSize ? null : instances.get(batchSize).getString(INSTANCE_ID_FIELD_NAME);
            List<JsonObject> instancesWithoutLast = nextInstanceId != null ? instances.subList(0, batchSize) : instances;
            final SourceStorageSourceRecordsClientWrapper srsClient = createAndSetupSrsClient(request);
            int retryAttempts = Integer.parseInt(RepositoryConfigurationUtil.getProperty(request.getRequestId(), REPOSITORY_SRS_HTTP_REQUEST_RETRY_ATTEMPTS));
            requestSRSByIdentifiers(srsClient, context.owner(), instancesWithoutLast, deletedRecordSupport, retryAttempts).onSuccess(res -> buildRecordsResponse(request, requestId, instancesWithoutLast, res, firstBatch, nextInstanceId, deletedRecordSupport).onSuccess(oaiPmhResponsePromise::complete).onFailure(e -> handleException(oaiPmhResponsePromise, e))).onFailure(e -> handleException(oaiPmhResponsePromise, e));
        });
    } catch (Exception e) {
        handleException(oaiPmhResponsePromise, e);
    }
}
Also used : CONTENT_TYPE(javax.ws.rs.core.HttpHeaders.CONTENT_TYPE) OFFSET_PARAM(org.folio.oaipmh.Constants.OFFSET_PARAM) DecodeException(io.vertx.core.json.DecodeException) Date(java.util.Date) NEXT_INSTANCE_PK_VALUE(org.folio.oaipmh.Constants.NEXT_INSTANCE_PK_VALUE) StatusType(org.openarchives.oai._2.StatusType) Autowired(org.springframework.beans.factory.annotation.Autowired) NEXT_RECORD_ID_PARAM(org.folio.oaipmh.Constants.NEXT_RECORD_ID_PARAM) SEND_REQUEST(org.folio.oaipmh.service.MetricsCollectingService.MetricOperation.SEND_REQUEST) RESUMPTION_TOKEN_TIMEOUT(org.folio.oaipmh.Constants.RESUMPTION_TOKEN_TIMEOUT) Context(io.vertx.core.Context) WorkerExecutor(io.vertx.core.WorkerExecutor) Tuple(io.vertx.sqlclient.Tuple) OAIPMHerrorType(org.openarchives.oai._2.OAIPMHerrorType) ResumptionTokenType(org.openarchives.oai._2.ResumptionTokenType) Request(org.folio.oaipmh.Request) NAME(org.folio.oaipmh.helpers.records.RecordMetadataManager.NAME) OAIPMH(org.openarchives.oai._2.OAIPMH) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) JsonObject(io.vertx.core.json.JsonObject) BigInteger(java.math.BigInteger) APPLICATION_JSON(javax.ws.rs.core.MediaType.APPLICATION_JSON) AbstractHelper(org.folio.oaipmh.helpers.AbstractHelper) UNTIL_PARAM(org.folio.oaipmh.Constants.UNTIL_PARAM) EXPIRATION_DATE_RESUMPTION_TOKEN_PARAM(org.folio.oaipmh.Constants.EXPIRATION_DATE_RESUMPTION_TOKEN_PARAM) OKAPI_TENANT(org.folio.oaipmh.Constants.OKAPI_TENANT) InstancesService(org.folio.oaipmh.service.InstancesService) ITEMS(org.folio.oaipmh.helpers.records.RecordMetadataManager.ITEMS) MetricsCollectingService(org.folio.oaipmh.service.MetricsCollectingService) UUID(java.util.UUID) ITEMS_AND_HOLDINGS_FIELDS(org.folio.oaipmh.helpers.records.RecordMetadataManager.ITEMS_AND_HOLDINGS_FIELDS) Instant(java.time.Instant) Future(io.vertx.core.Future) TenantTool(org.folio.rest.tools.utils.TenantTool) Collectors(java.util.stream.Collectors) PostgresClient(org.folio.rest.persist.PostgresClient) ZoneId(java.time.ZoneId) String.format(java.lang.String.format) RepositoryConfigurationUtil(org.folio.oaipmh.helpers.RepositoryConfigurationUtil) REQUEST_ID_PARAM(org.folio.oaipmh.Constants.REQUEST_ID_PARAM) CALL_NUMBER(org.folio.oaipmh.helpers.records.RecordMetadataManager.CALL_NUMBER) Objects(java.util.Objects) List(java.util.List) Logger(org.apache.logging.log4j.Logger) OffsetDateTime(java.time.OffsetDateTime) Buffer(io.vertx.core.buffer.Buffer) Response(javax.ws.rs.core.Response) WebClientProvider(org.folio.oaipmh.WebClientProvider) RETRY_ATTEMPTS(org.folio.oaipmh.Constants.RETRY_ATTEMPTS) STATUS_MESSAGE(org.folio.oaipmh.Constants.STATUS_MESSAGE) ChronoField(java.time.temporal.ChronoField) HttpResponse(io.vertx.ext.web.client.HttpResponse) SourceStorageSourceRecordsClientWrapper(org.folio.oaipmh.service.SourceStorageSourceRecordsClientWrapper) RequestMetadataLb(org.folio.rest.jooq.tables.pojos.RequestMetadataLb) BodyCodec(io.vertx.ext.web.codec.BodyCodec) INSTANCES_PROCESSING(org.folio.oaipmh.service.MetricsCollectingService.MetricOperation.INSTANCES_PROCESSING) HashMap(java.util.HashMap) OKAPI_TOKEN(org.folio.oaipmh.Constants.OKAPI_TOKEN) REPOSITORY_MAX_RECORDS_PER_RESPONSE(org.folio.oaipmh.Constants.REPOSITORY_MAX_RECORDS_PER_RESPONSE) JsonEvent(io.vertx.core.parsetools.JsonEvent) CollectionUtils(org.apache.commons.collections4.CollectionUtils) SpringContextUtil(org.folio.spring.SpringContextUtil) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) RepositoryConfigurationUtil.getBooleanProperty(org.folio.oaipmh.helpers.RepositoryConfigurationUtil.getBooleanProperty) HttpRequestImpl(io.vertx.ext.web.client.impl.HttpRequestImpl) AsyncResult(io.vertx.core.AsyncResult) STATUS_CODE(org.folio.oaipmh.Constants.STATUS_CODE) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Instances(org.folio.rest.jooq.tables.pojos.Instances) RecordMetadataManager(org.folio.oaipmh.helpers.records.RecordMetadataManager) Maps(com.google.common.collect.Maps) HttpRequest(io.vertx.ext.web.client.HttpRequest) JsonArray(io.vertx.core.json.JsonArray) ResponseHelper(org.folio.oaipmh.helpers.response.ResponseHelper) PgConnection(io.vertx.pgclient.PgConnection) Collectors.toList(java.util.stream.Collectors.toList) RecordType(org.openarchives.oai._2.RecordType) REPOSITORY_SRS_HTTP_REQUEST_RETRY_ATTEMPTS(org.folio.oaipmh.Constants.REPOSITORY_SRS_HTTP_REQUEST_RETRY_ATTEMPTS) ACCEPT(javax.ws.rs.core.HttpHeaders.ACCEPT) LOCATION(org.folio.oaipmh.Constants.LOCATION) REPOSITORY_SUPPRESSED_RECORDS_PROCESSING(org.folio.oaipmh.Constants.REPOSITORY_SUPPRESSED_RECORDS_PROCESSING) ListRecordsType(org.openarchives.oai._2.ListRecordsType) Handler(io.vertx.core.Handler) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) JsonObject(io.vertx.core.json.JsonObject) SourceStorageSourceRecordsClientWrapper(org.folio.oaipmh.service.SourceStorageSourceRecordsClientWrapper) DecodeException(io.vertx.core.json.DecodeException)

Example 3 with Request

use of org.folio.oaipmh.Request in project mod-oai-pmh by folio-org.

the class MarcWithHoldingsRequestHelper method enrichInstances.

private Future<List<JsonObject>> enrichInstances(List<JsonObject> result, Request request) {
    Map<String, JsonObject> instances = result.stream().collect(LinkedHashMap::new, (map, instance) -> map.put(instance.getString(INSTANCE_ID_FIELD_NAME), instance), Map::putAll);
    Promise<List<JsonObject>> promise = Promise.promise();
    var webClient = WebClientProvider.getWebClient();
    var httpRequest = webClient.postAbs(request.getOkapiUrl() + INVENTORY_ITEMS_AND_HOLDINGS_ENDPOINT);
    if (request.getOkapiUrl().contains("https:")) {
        httpRequest.ssl(true);
    }
    httpRequest.putHeader(OKAPI_TOKEN, request.getOkapiToken());
    httpRequest.putHeader(OKAPI_TENANT, TenantTool.tenantId(request.getOkapiHeaders()));
    httpRequest.putHeader(ACCEPT, APPLICATION_JSON);
    httpRequest.putHeader(CONTENT_TYPE, APPLICATION_JSON);
    JsonObject entries = new JsonObject();
    entries.put(INSTANCE_IDS_ENRICH_PARAM_NAME, new JsonArray(new ArrayList<>(instances.keySet())));
    entries.put(SKIP_SUPPRESSED_FROM_DISCOVERY_RECORDS, isSkipSuppressed(request));
    Promise<Boolean> responseChecked = Promise.promise();
    var jsonParser = new OaiPmhJsonParser().objectValueMode();
    jsonParser.handler(event -> {
        JsonObject itemsAndHoldingsFields = event.objectValue();
        String instanceId = itemsAndHoldingsFields.getString(INSTANCE_ID_FIELD_NAME);
        JsonObject instance = instances.get(instanceId);
        if (instance != null) {
            enrichDiscoverySuppressed(itemsAndHoldingsFields, instance);
            instance.put(RecordMetadataManager.ITEMS_AND_HOLDINGS_FIELDS, itemsAndHoldingsFields);
            // case when no items
            if (itemsAndHoldingsFields.getJsonArray(ITEMS).isEmpty()) {
                enrichOnlyEffectiveLocationEffectiveCallNumberFromHoldings(instance);
            } else {
                adjustItems(instance);
            }
        } else {
            logger.info("Instance with instanceId {} wasn't in the request.", instanceId);
        }
    });
    jsonParser.exceptionHandler(throwable -> responseChecked.future().onSuccess(invalidResponseReceivedAndProcessed -> {
        if (invalidResponseReceivedAndProcessed) {
            return;
        }
        logger.error("Error has been occurred at JsonParser while reading data from items-and-holdings response. Message:{}", throwable.getMessage(), throwable);
        promise.fail(throwable);
    }));
    httpRequest.as(BodyCodec.jsonStream(jsonParser)).sendBuffer(entries.toBuffer()).onSuccess(response -> {
        switch(response.statusCode()) {
            case 200:
                responseChecked.complete(false);
                break;
            case 403:
                {
                    String errorMsg = getErrorFromStorageMessage(INVENTORY_STORAGE, request.getOkapiUrl() + INVENTORY_ITEMS_AND_HOLDINGS_ENDPOINT, ENRICH_INSTANCES_MISSED_PERMISSION);
                    logger.error(errorMsg);
                    promise.fail(new IllegalStateException(errorMsg));
                    responseChecked.complete(true);
                    break;
                }
            default:
                {
                    String errorFromStorageMessage = getErrorFromStorageMessage(INVENTORY_STORAGE, request.getOkapiUrl() + INVENTORY_ITEMS_AND_HOLDINGS_ENDPOINT, response.statusMessage());
                    String errorMessage = errorFromStorageMessage + response.statusCode();
                    logger.error(errorMessage);
                    promise.fail(new IllegalStateException(errorFromStorageMessage));
                    responseChecked.complete(true);
                }
        }
        promise.complete(new ArrayList<>(instances.values()));
    }).onFailure(e -> {
        logger.error(e.getMessage());
        promise.fail(e);
    });
    return promise.future();
}
Also used : CONTENT_TYPE(javax.ws.rs.core.HttpHeaders.CONTENT_TYPE) OFFSET_PARAM(org.folio.oaipmh.Constants.OFFSET_PARAM) DecodeException(io.vertx.core.json.DecodeException) Date(java.util.Date) NEXT_INSTANCE_PK_VALUE(org.folio.oaipmh.Constants.NEXT_INSTANCE_PK_VALUE) StatusType(org.openarchives.oai._2.StatusType) Autowired(org.springframework.beans.factory.annotation.Autowired) NEXT_RECORD_ID_PARAM(org.folio.oaipmh.Constants.NEXT_RECORD_ID_PARAM) SEND_REQUEST(org.folio.oaipmh.service.MetricsCollectingService.MetricOperation.SEND_REQUEST) RESUMPTION_TOKEN_TIMEOUT(org.folio.oaipmh.Constants.RESUMPTION_TOKEN_TIMEOUT) Context(io.vertx.core.Context) WorkerExecutor(io.vertx.core.WorkerExecutor) Tuple(io.vertx.sqlclient.Tuple) OAIPMHerrorType(org.openarchives.oai._2.OAIPMHerrorType) ResumptionTokenType(org.openarchives.oai._2.ResumptionTokenType) Request(org.folio.oaipmh.Request) NAME(org.folio.oaipmh.helpers.records.RecordMetadataManager.NAME) OAIPMH(org.openarchives.oai._2.OAIPMH) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) JsonObject(io.vertx.core.json.JsonObject) BigInteger(java.math.BigInteger) APPLICATION_JSON(javax.ws.rs.core.MediaType.APPLICATION_JSON) AbstractHelper(org.folio.oaipmh.helpers.AbstractHelper) UNTIL_PARAM(org.folio.oaipmh.Constants.UNTIL_PARAM) EXPIRATION_DATE_RESUMPTION_TOKEN_PARAM(org.folio.oaipmh.Constants.EXPIRATION_DATE_RESUMPTION_TOKEN_PARAM) OKAPI_TENANT(org.folio.oaipmh.Constants.OKAPI_TENANT) InstancesService(org.folio.oaipmh.service.InstancesService) ITEMS(org.folio.oaipmh.helpers.records.RecordMetadataManager.ITEMS) MetricsCollectingService(org.folio.oaipmh.service.MetricsCollectingService) UUID(java.util.UUID) ITEMS_AND_HOLDINGS_FIELDS(org.folio.oaipmh.helpers.records.RecordMetadataManager.ITEMS_AND_HOLDINGS_FIELDS) Instant(java.time.Instant) Future(io.vertx.core.Future) TenantTool(org.folio.rest.tools.utils.TenantTool) Collectors(java.util.stream.Collectors) PostgresClient(org.folio.rest.persist.PostgresClient) ZoneId(java.time.ZoneId) String.format(java.lang.String.format) RepositoryConfigurationUtil(org.folio.oaipmh.helpers.RepositoryConfigurationUtil) REQUEST_ID_PARAM(org.folio.oaipmh.Constants.REQUEST_ID_PARAM) CALL_NUMBER(org.folio.oaipmh.helpers.records.RecordMetadataManager.CALL_NUMBER) Objects(java.util.Objects) List(java.util.List) Logger(org.apache.logging.log4j.Logger) OffsetDateTime(java.time.OffsetDateTime) Buffer(io.vertx.core.buffer.Buffer) Response(javax.ws.rs.core.Response) WebClientProvider(org.folio.oaipmh.WebClientProvider) RETRY_ATTEMPTS(org.folio.oaipmh.Constants.RETRY_ATTEMPTS) STATUS_MESSAGE(org.folio.oaipmh.Constants.STATUS_MESSAGE) ChronoField(java.time.temporal.ChronoField) HttpResponse(io.vertx.ext.web.client.HttpResponse) SourceStorageSourceRecordsClientWrapper(org.folio.oaipmh.service.SourceStorageSourceRecordsClientWrapper) RequestMetadataLb(org.folio.rest.jooq.tables.pojos.RequestMetadataLb) BodyCodec(io.vertx.ext.web.codec.BodyCodec) INSTANCES_PROCESSING(org.folio.oaipmh.service.MetricsCollectingService.MetricOperation.INSTANCES_PROCESSING) HashMap(java.util.HashMap) OKAPI_TOKEN(org.folio.oaipmh.Constants.OKAPI_TOKEN) REPOSITORY_MAX_RECORDS_PER_RESPONSE(org.folio.oaipmh.Constants.REPOSITORY_MAX_RECORDS_PER_RESPONSE) JsonEvent(io.vertx.core.parsetools.JsonEvent) CollectionUtils(org.apache.commons.collections4.CollectionUtils) SpringContextUtil(org.folio.spring.SpringContextUtil) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) RepositoryConfigurationUtil.getBooleanProperty(org.folio.oaipmh.helpers.RepositoryConfigurationUtil.getBooleanProperty) HttpRequestImpl(io.vertx.ext.web.client.impl.HttpRequestImpl) AsyncResult(io.vertx.core.AsyncResult) STATUS_CODE(org.folio.oaipmh.Constants.STATUS_CODE) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Instances(org.folio.rest.jooq.tables.pojos.Instances) RecordMetadataManager(org.folio.oaipmh.helpers.records.RecordMetadataManager) Maps(com.google.common.collect.Maps) HttpRequest(io.vertx.ext.web.client.HttpRequest) JsonArray(io.vertx.core.json.JsonArray) ResponseHelper(org.folio.oaipmh.helpers.response.ResponseHelper) PgConnection(io.vertx.pgclient.PgConnection) Collectors.toList(java.util.stream.Collectors.toList) RecordType(org.openarchives.oai._2.RecordType) REPOSITORY_SRS_HTTP_REQUEST_RETRY_ATTEMPTS(org.folio.oaipmh.Constants.REPOSITORY_SRS_HTTP_REQUEST_RETRY_ATTEMPTS) ACCEPT(javax.ws.rs.core.HttpHeaders.ACCEPT) LOCATION(org.folio.oaipmh.Constants.LOCATION) REPOSITORY_SUPPRESSED_RECORDS_PROCESSING(org.folio.oaipmh.Constants.REPOSITORY_SUPPRESSED_RECORDS_PROCESSING) ListRecordsType(org.openarchives.oai._2.ListRecordsType) Handler(io.vertx.core.Handler) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) ArrayList(java.util.ArrayList) JsonObject(io.vertx.core.json.JsonObject) LinkedHashMap(java.util.LinkedHashMap) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) ArrayList(java.util.ArrayList) Collectors.toList(java.util.stream.Collectors.toList) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Example 4 with Request

use of org.folio.oaipmh.Request in project mod-oai-pmh by folio-org.

the class VerbValidator method validateExclusiveParam.

/**
 * In case of resumption token param presence verifies if there any other parameters were specified too. If they were then error
 * will be added to error list.
 *
 * @param verb          - verb
 * @param requestParams - request parameters
 * @param request       - oai-pmh request
 * @param errors        - list of errors
 */
private void validateExclusiveParam(Verb verb, Map<String, String> requestParams, Request request, List<OAIPMHerrorType> errors) {
    String resumptionToken = requestParams.get(verb.getExclusiveParam());
    if (verb.getExclusiveParam() != null && resumptionToken != null) {
        requestParams.keySet().stream().filter(p -> !verb.getExcludedParams().contains(p)).filter(p -> !verb.getExclusiveParam().equals(p)).findAny().ifPresent(param -> {
            if (!param.equals(VERB_PARAM)) {
                errors.add(new OAIPMHerrorType().withCode(BAD_ARGUMENT).withValue(format(EXCLUSIVE_PARAM_ERROR_MESSAGE, verb.name(), verb.getExclusiveParam())));
            }
        });
        if (!request.isResumptionTokenParsableAndValid()) {
            OAIPMHerrorType error = new OAIPMHerrorType().withCode(BAD_RESUMPTION_TOKEN).withValue(format(INVALID_RESUMPTION_TOKEN, verb.name()));
            errors.add(error);
            return;
        }
        if (request.isResumptionTokenTimeExpired()) {
            OAIPMHerrorType errorByExpiredTime = new OAIPMHerrorType().withCode(BAD_RESUMPTION_TOKEN).withValue(EXPIRED_RESUMPTION_TOKEN);
            errors.add(errorByExpiredTime);
        }
    }
}
Also used : INVALID_RESUMPTION_TOKEN(org.folio.oaipmh.Constants.INVALID_RESUMPTION_TOKEN) EXPIRED_RESUMPTION_TOKEN(org.folio.oaipmh.Constants.EXPIRED_RESUMPTION_TOKEN) Set(java.util.Set) VERB_PARAM(org.folio.oaipmh.Constants.VERB_PARAM) StringUtils(org.apache.commons.lang3.StringUtils) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) BAD_ARGUMENT(org.openarchives.oai._2.OAIPMHerrorcodeType.BAD_ARGUMENT) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Objects(java.util.Objects) OAIPMHerrorType(org.openarchives.oai._2.OAIPMHerrorType) Component(org.springframework.stereotype.Component) List(java.util.List) Request(org.folio.oaipmh.Request) Verb(org.folio.oaipmh.domain.Verb) Map(java.util.Map) BAD_RESUMPTION_TOKEN(org.openarchives.oai._2.OAIPMHerrorcodeType.BAD_RESUMPTION_TOKEN) BAD_VERB(org.openarchives.oai._2.OAIPMHerrorcodeType.BAD_VERB) OAIPMHerrorType(org.openarchives.oai._2.OAIPMHerrorType)

Example 5 with Request

use of org.folio.oaipmh.Request in project mod-oai-pmh by folio-org.

the class GetOaiIdentifiersHelper method buildListIdentifiers.

/**
 * Builds {@link ListIdentifiersType} with headers if there is any item or {@code null}
 *
 * @param request           request
 * @param srsRecords the response from the storage which contains items
 * @return {@link ListIdentifiersType} with headers if there is any or {@code null}
 */
private OAIPMH buildListIdentifiers(Request request, JsonObject srsRecords) {
    ResponseHelper responseHelper = getResponseHelper();
    JsonArray instances = storageHelper.getItems(srsRecords);
    Integer totalRecords = storageHelper.getTotalRecords(srsRecords);
    if (request.isRestored() && !canResumeRequestSequence(request, totalRecords, instances)) {
        return responseHelper.buildOaipmhResponseWithErrors(request, BAD_RESUMPTION_TOKEN, RESUMPTION_TOKEN_FLOW_ERROR);
    }
    if (instances != null && !instances.isEmpty()) {
        logger.debug("{} entries retrieved out of {}.", instances.size(), totalRecords);
        ListIdentifiersType identifiers = new ListIdentifiersType().withResumptionToken(buildResumptionToken(request, instances, totalRecords));
        String identifierPrefix = request.getIdentifierPrefix();
        instances.stream().map(object -> (JsonObject) object).filter(instance -> StringUtils.isNotEmpty(storageHelper.getIdentifierId(instance))).filter(instance -> filterInstance(request, instance)).map(instance -> addHeader(identifierPrefix, request, instance)).forEach(identifiers::withHeaders);
        if (identifiers.getHeaders().isEmpty()) {
            OAIPMH oaipmh = responseHelper.buildBaseOaipmhResponse(request);
            return oaipmh.withErrors(createNoRecordsFoundError());
        }
        ResumptionTokenType resumptionToken = buildResumptionToken(request, instances, totalRecords);
        OAIPMH oaipmh = responseHelper.buildBaseOaipmhResponse(request).withListIdentifiers(identifiers);
        addResumptionTokenToOaiResponse(oaipmh, resumptionToken);
        return oaipmh;
    }
    return responseHelper.buildOaipmhResponseWithErrors(request, createNoRecordsFoundError());
}
Also used : JsonArray(io.vertx.core.json.JsonArray) RESUMPTION_TOKEN_FLOW_ERROR(org.folio.oaipmh.Constants.RESUMPTION_TOKEN_FLOW_ERROR) Promise(io.vertx.core.Promise) ListIdentifiersType(org.openarchives.oai._2.ListIdentifiersType) Context(io.vertx.core.Context) Future(io.vertx.core.Future) StringUtils(org.apache.commons.lang3.StringUtils) JsonArray(io.vertx.core.json.JsonArray) ResponseHelper(org.folio.oaipmh.helpers.response.ResponseHelper) OAIPMHerrorType(org.openarchives.oai._2.OAIPMHerrorType) ResumptionTokenType(org.openarchives.oai._2.ResumptionTokenType) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Request(org.folio.oaipmh.Request) Response(javax.ws.rs.core.Response) OAIPMH(org.openarchives.oai._2.OAIPMH) BAD_RESUMPTION_TOKEN(org.openarchives.oai._2.OAIPMHerrorcodeType.BAD_RESUMPTION_TOKEN) RESUMPTION_TOKEN_FORMAT_ERROR(org.folio.oaipmh.Constants.RESUMPTION_TOKEN_FORMAT_ERROR) JsonObject(io.vertx.core.json.JsonObject) LogManager(org.apache.logging.log4j.LogManager) ListIdentifiersType(org.openarchives.oai._2.ListIdentifiersType) OAIPMH(org.openarchives.oai._2.OAIPMH) ResumptionTokenType(org.openarchives.oai._2.ResumptionTokenType) ResponseHelper(org.folio.oaipmh.helpers.response.ResponseHelper)

Aggregations

List (java.util.List)9 Request (org.folio.oaipmh.Request)9 OAIPMHerrorType (org.openarchives.oai._2.OAIPMHerrorType)9 Map (java.util.Map)8 Context (io.vertx.core.Context)7 Future (io.vertx.core.Future)7 Promise (io.vertx.core.Promise)7 JsonArray (io.vertx.core.json.JsonArray)7 JsonObject (io.vertx.core.json.JsonObject)7 String.format (java.lang.String.format)7 ArrayList (java.util.ArrayList)7 Objects (java.util.Objects)7 Collectors (java.util.stream.Collectors)7 Response (javax.ws.rs.core.Response)7 LogManager (org.apache.logging.log4j.LogManager)7 Logger (org.apache.logging.log4j.Logger)7 OAIPMH (org.openarchives.oai._2.OAIPMH)7 ResumptionTokenType (org.openarchives.oai._2.ResumptionTokenType)7 AsyncResult (io.vertx.core.AsyncResult)6 Handler (io.vertx.core.Handler)6