Search in sources :

Example 6 with ImportCount

use of org.hisp.dhis.dxf2.importsummary.ImportCount in project dhis2-core by dhis2.

the class DefaultDataValueSetService method saveDataValueSet.

/**
     * There are specific id schemes for data elements and organisation units and
     * a generic id scheme for all objects. The specific id schemes will take
     * precedence over the generic id scheme. The generic id scheme also applies
     * to data set and category option combo.
     * <p>
     * The id schemes uses the following order of precedence:
     * <p>
     * <ul>
     * <li>Id scheme from the data value set</li>
     * <li>Id scheme from the import options</li>
     * <li>Default id scheme which is UID</li>
     * <ul>
     * <p>
     * If id scheme is specific in the data value set, any id schemes in the import
     * options will be ignored.
     *
     * @param importOptions
     * @param id
     * @param dataValueSet
     * @return
     */
private ImportSummary saveDataValueSet(ImportOptions importOptions, TaskId id, DataValueSet dataValueSet) {
    importOptions = ObjectUtils.firstNonNull(importOptions, ImportOptions.getDefaultImportOptions());
    Clock clock = new Clock(log).startClock().logTime("Starting data value import, options: " + importOptions);
    NotificationLevel notificationLevel = importOptions.getNotificationLevel(INFO);
    notifier.clear(id).notify(id, notificationLevel, "Process started");
    ImportSummary summary = new ImportSummary().setImportOptions(importOptions);
    boolean isIso8601 = calendarService.getSystemCalendar().isIso8601();
    boolean skipLockExceptionCheck = !lockExceptionStore.anyExists();
    log.info(String.format("Is ISO calendar: %b, skip lock exception check: %b", isIso8601, skipLockExceptionCheck));
    I18n i18n = i18nManager.getI18n();
    // ---------------------------------------------------------------------
    // Get import options
    // ---------------------------------------------------------------------
    log.info("Import options: " + importOptions);
    IdScheme dvSetIdScheme = IdScheme.from(dataValueSet.getIdSchemeProperty());
    IdScheme dvSetDataElementIdScheme = IdScheme.from(dataValueSet.getDataElementIdSchemeProperty());
    IdScheme dvSetOrgUnitIdScheme = IdScheme.from(dataValueSet.getOrgUnitIdSchemeProperty());
    IdScheme dvSetCategoryOptComboIdScheme = IdScheme.from(dataValueSet.getCategoryOptionComboIdSchemeProperty());
    IdScheme dvSetDataSetIdScheme = IdScheme.from(dataValueSet.getDataSetIdSchemeProperty());
    log.info("Data value set identifier scheme: " + dvSetIdScheme + ", data element: " + dvSetDataElementIdScheme + ", org unit: " + dvSetOrgUnitIdScheme + ", category option combo: " + dvSetCategoryOptComboIdScheme + ", data set: " + dvSetDataSetIdScheme);
    IdScheme idScheme = dvSetIdScheme.isNotNull() ? dvSetIdScheme : importOptions.getIdSchemes().getIdScheme();
    IdScheme dataElementIdScheme = dvSetDataElementIdScheme.isNotNull() ? dvSetDataElementIdScheme : importOptions.getIdSchemes().getDataElementIdScheme();
    IdScheme orgUnitIdScheme = dvSetOrgUnitIdScheme.isNotNull() ? dvSetOrgUnitIdScheme : importOptions.getIdSchemes().getOrgUnitIdScheme();
    IdScheme categoryOptComboIdScheme = dvSetCategoryOptComboIdScheme.isNotNull() ? dvSetCategoryOptComboIdScheme : importOptions.getIdSchemes().getCategoryOptionComboIdScheme();
    IdScheme dataSetIdScheme = dvSetDataSetIdScheme.isNotNull() ? dvSetDataSetIdScheme : importOptions.getIdSchemes().getDataSetIdScheme();
    log.info("Identifier scheme: " + idScheme + ", data element: " + dataElementIdScheme + ", org unit: " + orgUnitIdScheme + ", category option combo: " + categoryOptComboIdScheme + ", data set: " + dataSetIdScheme);
    ImportStrategy strategy = dataValueSet.getStrategy() != null ? ImportStrategy.valueOf(dataValueSet.getStrategy()) : importOptions.getImportStrategy();
    boolean dryRun = dataValueSet.getDryRun() != null ? dataValueSet.getDryRun() : importOptions.isDryRun();
    boolean skipExistingCheck = importOptions.isSkipExistingCheck();
    boolean strictPeriods = importOptions.isStrictPeriods() || (Boolean) systemSettingManager.getSystemSetting(SettingKey.DATA_IMPORT_STRICT_PERIODS);
    boolean strictCategoryOptionCombos = importOptions.isStrictCategoryOptionCombos() || (Boolean) systemSettingManager.getSystemSetting(SettingKey.DATA_IMPORT_STRICT_CATEGORY_OPTION_COMBOS);
    boolean strictAttrOptionCombos = importOptions.isStrictAttributeOptionCombos() || (Boolean) systemSettingManager.getSystemSetting(SettingKey.DATA_IMPORT_STRICT_ATTRIBUTE_OPTION_COMBOS);
    boolean strictOrgUnits = importOptions.isStrictOrganisationUnits() || (Boolean) systemSettingManager.getSystemSetting(SettingKey.DATA_IMPORT_STRICT_ORGANISATION_UNITS);
    boolean requireCategoryOptionCombo = importOptions.isRequireCategoryOptionCombo() || (Boolean) systemSettingManager.getSystemSetting(SettingKey.DATA_IMPORT_REQUIRE_CATEGORY_OPTION_COMBO);
    boolean requireAttrOptionCombo = importOptions.isRequireAttributeOptionCombo() || (Boolean) systemSettingManager.getSystemSetting(SettingKey.DATA_IMPORT_REQUIRE_ATTRIBUTE_OPTION_COMBO);
    // ---------------------------------------------------------------------
    // Create meta-data maps
    // ---------------------------------------------------------------------
    CachingMap<String, DataElement> dataElementMap = new CachingMap<>();
    CachingMap<String, OrganisationUnit> orgUnitMap = new CachingMap<>();
    CachingMap<String, DataElementCategoryOptionCombo> optionComboMap = new CachingMap<>();
    CachingMap<String, DataSet> dataElementDataSetMap = new CachingMap<>();
    CachingMap<String, Period> periodMap = new CachingMap<>();
    CachingMap<String, Set<PeriodType>> dataElementPeriodTypesMap = new CachingMap<>();
    CachingMap<String, Set<DataElementCategoryOptionCombo>> dataElementCategoryOptionComboMap = new CachingMap<>();
    CachingMap<String, Set<DataElementCategoryOptionCombo>> dataElementAttrOptionComboMap = new CachingMap<>();
    CachingMap<String, Boolean> dataElementOrgUnitMap = new CachingMap<>();
    CachingMap<String, Boolean> dataSetLockedMap = new CachingMap<>();
    CachingMap<String, Period> dataElementLatestFuturePeriodMap = new CachingMap<>();
    CachingMap<String, Boolean> orgUnitInHierarchyMap = new CachingMap<>();
    CachingMap<String, DateRange> attrOptionComboDateRangeMap = new CachingMap<>();
    CachingMap<String, Boolean> attrOptionComboOrgUnitMap = new CachingMap<>();
    CachingMap<String, Optional<Set<String>>> dataElementOptionsMap = new CachingMap<>();
    CachingMap<String, Boolean> approvalMap = new CachingMap<>();
    CachingMap<String, Boolean> lowestApprovalLevelMap = new CachingMap<>();
    CachingMap<String, Boolean> periodOpenForDataElement = new CachingMap<>();
    // ---------------------------------------------------------------------
    // Get meta-data maps
    // ---------------------------------------------------------------------
    IdentifiableObjectCallable<DataElement> dataElementCallable = new IdentifiableObjectCallable<>(identifiableObjectManager, DataElement.class, dataElementIdScheme, null);
    IdentifiableObjectCallable<OrganisationUnit> orgUnitCallable = new IdentifiableObjectCallable<>(identifiableObjectManager, OrganisationUnit.class, orgUnitIdScheme, trimToNull(dataValueSet.getOrgUnit()));
    IdentifiableObjectCallable<DataElementCategoryOptionCombo> categoryOptionComboCallable = new CategoryOptionComboAclCallable(categoryService, categoryOptComboIdScheme, null);
    IdentifiableObjectCallable<DataElementCategoryOptionCombo> attributeOptionComboCallable = new CategoryOptionComboAclCallable(categoryService, categoryOptComboIdScheme, null);
    IdentifiableObjectCallable<Period> periodCallable = new PeriodCallable(periodService, null, trimToNull(dataValueSet.getPeriod()));
    if (importOptions.isPreheatCacheDefaultFalse()) {
        dataElementMap.load(identifiableObjectManager.getAll(DataElement.class), o -> o.getPropertyValue(dataElementIdScheme));
        orgUnitMap.load(identifiableObjectManager.getAll(OrganisationUnit.class), o -> o.getPropertyValue(orgUnitIdScheme));
        optionComboMap.load(identifiableObjectManager.getAll(DataElementCategoryOptionCombo.class), o -> o.getPropertyValue(categoryOptComboIdScheme));
    }
    // ---------------------------------------------------------------------
    // Get outer meta-data
    // ---------------------------------------------------------------------
    DataSet dataSet = dataValueSet.getDataSet() != null ? identifiableObjectManager.getObject(DataSet.class, dataSetIdScheme, dataValueSet.getDataSet()) : null;
    Date completeDate = parseDate(dataValueSet.getCompleteDate());
    Period outerPeriod = periodMap.get(trimToNull(dataValueSet.getPeriod()), periodCallable);
    OrganisationUnit outerOrgUnit = orgUnitMap.get(trimToNull(dataValueSet.getOrgUnit()), orgUnitCallable);
    DataElementCategoryOptionCombo fallbackCategoryOptionCombo = categoryService.getDefaultDataElementCategoryOptionCombo();
    DataElementCategoryOptionCombo outerAttrOptionCombo = null;
    if (dataValueSet.getAttributeOptionCombo() != null) {
        outerAttrOptionCombo = optionComboMap.get(trimToNull(dataValueSet.getAttributeOptionCombo()), attributeOptionComboCallable.setId(trimToNull(dataValueSet.getAttributeOptionCombo())));
    } else if (dataValueSet.getAttributeCategoryOptions() != null) {
        outerAttrOptionCombo = inputUtils.getAttributeOptionCombo(dataSet.getCategoryCombo(), new HashSet<String>(dataValueSet.getAttributeCategoryOptions()), idScheme);
    }
    if (dataSet == null && trimToNull(dataValueSet.getDataSet()) != null) {
        summary.getConflicts().add(new ImportConflict(dataValueSet.getDataSet(), "Data set not found or not accessible"));
        summary.setStatus(ImportStatus.ERROR);
    }
    if (outerOrgUnit == null && trimToNull(dataValueSet.getOrgUnit()) != null) {
        summary.getConflicts().add(new ImportConflict(dataValueSet.getDataSet(), "Org unit not found or not accessible"));
        summary.setStatus(ImportStatus.ERROR);
    }
    if (outerAttrOptionCombo == null && trimToNull(dataValueSet.getAttributeOptionCombo()) != null) {
        summary.getConflicts().add(new ImportConflict(dataValueSet.getDataSet(), "Attribute option combo not found or not accessible"));
        summary.setStatus(ImportStatus.ERROR);
    }
    if (ImportStatus.ERROR.equals(summary.getStatus())) {
        summary.setDescription("Import process was aborted");
        notifier.notify(id, WARN, "Import process aborted", true).addTaskSummary(id, summary);
        dataValueSet.close();
        return summary;
    }
    if (dataSet != null && completeDate != null) {
        notifier.notify(id, notificationLevel, "Completing data set");
        //TODO
        handleComplete(dataSet, completeDate, outerPeriod, outerOrgUnit, fallbackCategoryOptionCombo, summary);
    } else {
        summary.setDataSetComplete(Boolean.FALSE.toString());
    }
    final String currentUser = currentUserService.getCurrentUsername();
    final Set<OrganisationUnit> currentOrgUnits = currentUserService.getCurrentUserOrganisationUnits();
    BatchHandler<DataValue> dataValueBatchHandler = batchHandlerFactory.createBatchHandler(DataValueBatchHandler.class).init();
    BatchHandler<DataValueAudit> auditBatchHandler = batchHandlerFactory.createBatchHandler(DataValueAuditBatchHandler.class).init();
    int importCount = 0;
    int updateCount = 0;
    int deleteCount = 0;
    int totalCount = 0;
    // ---------------------------------------------------------------------
    // Data values
    // ---------------------------------------------------------------------
    Date now = new Date();
    clock.logTime("Validated outer meta-data");
    notifier.notify(id, notificationLevel, "Importing data values");
    while (dataValueSet.hasNextDataValue()) {
        org.hisp.dhis.dxf2.datavalue.DataValue dataValue = dataValueSet.getNextDataValue();
        totalCount++;
        final DataElement dataElement = dataElementMap.get(trimToNull(dataValue.getDataElement()), dataElementCallable.setId(trimToNull(dataValue.getDataElement())));
        final Period period = outerPeriod != null ? outerPeriod : periodMap.get(trimToNull(dataValue.getPeriod()), periodCallable.setId(trimToNull(dataValue.getPeriod())));
        final OrganisationUnit orgUnit = outerOrgUnit != null ? outerOrgUnit : orgUnitMap.get(trimToNull(dataValue.getOrgUnit()), orgUnitCallable.setId(trimToNull(dataValue.getOrgUnit())));
        DataElementCategoryOptionCombo categoryOptionCombo = optionComboMap.get(trimToNull(dataValue.getCategoryOptionCombo()), categoryOptionComboCallable.setId(trimToNull(dataValue.getCategoryOptionCombo())));
        DataElementCategoryOptionCombo attrOptionCombo = outerAttrOptionCombo != null ? outerAttrOptionCombo : optionComboMap.get(trimToNull(dataValue.getAttributeOptionCombo()), attributeOptionComboCallable.setId(trimToNull(dataValue.getAttributeOptionCombo())));
        if (!dataElementMap.isCacheLoaded() && dataElementMap.getCacheMissCount() > CACHE_MISS_THRESHOLD) {
            dataElementMap.load(identifiableObjectManager.getAll(DataElement.class), o -> o.getPropertyValue(dataElementIdScheme));
            log.info("Data element cache heated after cache miss threshold reached");
        }
        if (!orgUnitMap.isCacheLoaded() && orgUnitMap.getCacheMissCount() > CACHE_MISS_THRESHOLD) {
            orgUnitMap.load(identifiableObjectManager.getAll(OrganisationUnit.class), o -> o.getPropertyValue(orgUnitIdScheme));
            log.info("Org unit cache heated after cache miss threshold reached");
        }
        if (dataElement == null) {
            summary.getConflicts().add(new ImportConflict(dataValue.getDataElement(), "Data element not found or not accessible"));
            continue;
        }
        if (period == null) {
            summary.getConflicts().add(new ImportConflict(dataValue.getPeriod(), "Period not valid"));
            continue;
        }
        if (orgUnit == null) {
            summary.getConflicts().add(new ImportConflict(dataValue.getOrgUnit(), "Organisation unit not found or not accessible"));
            continue;
        }
        if (categoryOptionCombo == null && trimToNull(dataValue.getCategoryOptionCombo()) != null) {
            summary.getConflicts().add(new ImportConflict(dataValue.getCategoryOptionCombo(), "Category option combo not found or not accessible"));
            continue;
        }
        if (attrOptionCombo == null && trimToNull(dataValue.getAttributeOptionCombo()) != null) {
            summary.getConflicts().add(new ImportConflict(dataValue.getAttributeOptionCombo(), "Attribute option combo not found or not accessible"));
            continue;
        }
        boolean inUserHierarchy = orgUnitInHierarchyMap.get(orgUnit.getUid(), () -> orgUnit.isDescendant(currentOrgUnits));
        if (!inUserHierarchy) {
            summary.getConflicts().add(new ImportConflict(orgUnit.getUid(), "Organisation unit not in hierarchy of current user: " + currentUser));
            continue;
        }
        if (dataValue.isNullValue() && !dataValue.isDeletedValue()) {
            summary.getConflicts().add(new ImportConflict("Value", "Data value or comment not specified for data element: " + dataElement.getUid()));
            continue;
        }
        dataValue.setValueForced(ValidationUtils.normalizeBoolean(dataValue.getValue(), dataElement.getValueType()));
        String valueValid = ValidationUtils.dataValueIsValid(dataValue.getValue(), dataElement);
        if (valueValid != null) {
            summary.getConflicts().add(new ImportConflict(dataValue.getValue(), i18n.getString(valueValid) + ", must match data element type: " + dataElement.getUid()));
            continue;
        }
        String commentValid = ValidationUtils.commentIsValid(dataValue.getComment());
        if (commentValid != null) {
            summary.getConflicts().add(new ImportConflict("Comment", i18n.getString(commentValid)));
            continue;
        }
        Optional<Set<String>> optionCodes = dataElementOptionsMap.get(dataElement.getUid(), () -> dataElement.hasOptionSet() ? Optional.of(dataElement.getOptionSet().getOptionCodesAsSet()) : Optional.empty());
        if (optionCodes.isPresent() && !optionCodes.get().contains(dataValue.getValue())) {
            summary.getConflicts().add(new ImportConflict(dataValue.getValue(), "Data value is not a valid option of the data element option set: " + dataElement.getUid()));
            continue;
        }
        if (categoryOptionCombo == null) {
            if (requireCategoryOptionCombo) {
                summary.getConflicts().add(new ImportConflict(dataValue.getValue(), "Category option combo is required but is not specified"));
                continue;
            } else {
                categoryOptionCombo = fallbackCategoryOptionCombo;
            }
        }
        if (attrOptionCombo == null) {
            if (requireAttrOptionCombo) {
                summary.getConflicts().add(new ImportConflict(dataValue.getValue(), "Attribute option combo is required but is not specified"));
                continue;
            } else {
                attrOptionCombo = fallbackCategoryOptionCombo;
            }
        }
        if (strictPeriods && !dataElementPeriodTypesMap.get(dataElement.getUid(), () -> dataElement.getPeriodTypes()).contains(period.getPeriodType())) {
            summary.getConflicts().add(new ImportConflict(dataValue.getPeriod(), "Period type of period: " + period.getIsoDate() + " not valid for data element: " + dataElement.getUid()));
            continue;
        }
        if (strictCategoryOptionCombos && !dataElementCategoryOptionComboMap.get(dataElement.getUid(), () -> dataElement.getCategoryOptionCombos()).contains(categoryOptionCombo)) {
            summary.getConflicts().add(new ImportConflict(categoryOptionCombo.getUid(), "Category option combo: " + categoryOptionCombo.getUid() + " must be part of category combo of data element: " + dataElement.getUid()));
            continue;
        }
        if (strictAttrOptionCombos && !dataElementAttrOptionComboMap.get(dataElement.getUid(), () -> dataElement.getDataSetCategoryOptionCombos()).contains(attrOptionCombo)) {
            summary.getConflicts().add(new ImportConflict(attrOptionCombo.getUid(), "Attribute option combo: " + attrOptionCombo.getUid() + " must be part of category combo of data sets of data element: " + dataElement.getUid()));
            continue;
        }
        if (strictOrgUnits && BooleanUtils.isFalse(dataElementOrgUnitMap.get(dataElement.getUid() + orgUnit.getUid(), () -> orgUnit.hasDataElement(dataElement)))) {
            summary.getConflicts().add(new ImportConflict(orgUnit.getUid(), "Data element: " + dataElement.getUid() + " must be assigned through data sets to organisation unit: " + orgUnit.getUid()));
            continue;
        }
        boolean zeroInsignificant = ValidationUtils.dataValueIsZeroAndInsignificant(dataValue.getValue(), dataElement);
        if (zeroInsignificant) {
            summary.getConflicts().add(new ImportConflict(dataValue.getValue(), "Value is zero and not significant, must match data element: " + dataElement.getUid()));
            continue;
        }
        String storedByValid = ValidationUtils.storedByIsValid(dataValue.getStoredBy());
        if (storedByValid != null) {
            summary.getConflicts().add(new ImportConflict(dataValue.getStoredBy(), i18n.getString(storedByValid)));
            continue;
        }
        String storedBy = dataValue.getStoredBy() == null || dataValue.getStoredBy().trim().isEmpty() ? currentUser : dataValue.getStoredBy();
        final DataElementCategoryOptionCombo aoc = attrOptionCombo;
        DateRange aocDateRange = attrOptionComboDateRangeMap.get(attrOptionCombo.getUid(), () -> aoc.getDateRange());
        if ((aocDateRange.getStartDate() != null && aocDateRange.getStartDate().compareTo(period.getStartDate()) > 0) || (aocDateRange.getEndDate() != null && aocDateRange.getEndDate().compareTo(period.getEndDate()) < 0)) {
            summary.getConflicts().add(new ImportConflict(orgUnit.getUid(), "Period: " + period.getIsoDate() + " is not within date range of attribute option combo: " + attrOptionCombo.getUid()));
            continue;
        }
        if (!attrOptionComboOrgUnitMap.get(attrOptionCombo.getUid() + orgUnit.getUid(), () -> {
            Set<OrganisationUnit> aocOrgUnits = aoc.getOrganisationUnits();
            return aocOrgUnits == null || orgUnit.isDescendant(aocOrgUnits);
        })) {
            summary.getConflicts().add(new ImportConflict(orgUnit.getUid(), "Organisation unit: " + orgUnit.getUid() + " is not valid for attribute option combo: " + attrOptionCombo.getUid()));
            continue;
        }
        final DataSet approvalDataSet = dataSet != null ? dataSet : dataElementDataSetMap.get(dataElement.getUid(), () -> dataElement.getApprovalDataSet());
        if (// Data element is assigned to at least one data set
        approvalDataSet != null) {
            if (dataSetLockedMap.get(approvalDataSet.getUid() + period.getUid() + orgUnit.getUid(), () -> isLocked(approvalDataSet, period, orgUnit, skipLockExceptionCheck))) {
                summary.getConflicts().add(new ImportConflict(period.getIsoDate(), "Current date is past expiry days for period " + period.getIsoDate() + " and data set: " + approvalDataSet.getUid()));
                continue;
            }
            Period latestFuturePeriod = dataElementLatestFuturePeriodMap.get(dataElement.getUid(), () -> dataElement.getLatestOpenFuturePeriod());
            if (period.isAfter(latestFuturePeriod) && isIso8601) {
                summary.getConflicts().add(new ImportConflict(period.getIsoDate(), "Period: " + period.getIsoDate() + " is after latest open future period: " + latestFuturePeriod.getIsoDate() + " for data element: " + dataElement.getUid()));
                continue;
            }
            DataApprovalWorkflow workflow = approvalDataSet.getWorkflow();
            if (workflow != null) {
                final String workflowPeriodAoc = workflow.getUid() + period.getUid() + attrOptionCombo.getUid();
                if (approvalMap.get(orgUnit.getUid() + workflowPeriodAoc, () -> {
                    DataApproval lowestApproval = DataApproval.getLowestApproval(new DataApproval(null, workflow, period, orgUnit, aoc));
                    return lowestApprovalLevelMap.get(lowestApproval.getDataApprovalLevel().getUid() + lowestApproval.getOrganisationUnit().getUid() + workflowPeriodAoc, () -> approvalService.getDataApproval(lowestApproval) != null);
                })) {
                    summary.getConflicts().add(new ImportConflict(orgUnit.getUid(), "Data is already approved for data set: " + approvalDataSet.getUid() + " period: " + period.getIsoDate() + " organisation unit: " + orgUnit.getUid() + " attribute option combo: " + attrOptionCombo.getUid()));
                    continue;
                }
            }
        }
        if (approvalDataSet != null && !approvalDataSet.isDataInputPeriodAndDateAllowed(period, new Date())) {
            summary.getConflicts().add(new ImportConflict(orgUnit.getUid(), "Period: " + period.getIsoDate() + " is not open for this data set at this time: " + approvalDataSet.getUid()));
            continue;
        }
        if (!periodOpenForDataElement.get(dataElement.getUid() + period.getIsoDate(), () -> dataElement.isDataInputAllowedForPeriodAndDate(period, new Date()))) {
            summary.getConflicts().add(new ImportConflict(orgUnit.getUid(), "Period " + period.getName() + " does not conform to the open periods of associated data sets"));
            continue;
        }
        // -----------------------------------------------------------------
        // Create data value
        // -----------------------------------------------------------------
        DataValue internalValue = new DataValue();
        internalValue.setDataElement(dataElement);
        internalValue.setPeriod(period);
        internalValue.setSource(orgUnit);
        internalValue.setCategoryOptionCombo(categoryOptionCombo);
        internalValue.setAttributeOptionCombo(attrOptionCombo);
        internalValue.setValue(trimToNull(dataValue.getValue()));
        internalValue.setStoredBy(storedBy);
        internalValue.setCreated(dataValue.hasCreated() ? parseDate(dataValue.getCreated()) : now);
        internalValue.setLastUpdated(dataValue.hasLastUpdated() ? parseDate(dataValue.getLastUpdated()) : now);
        internalValue.setComment(trimToNull(dataValue.getComment()));
        internalValue.setFollowup(dataValue.getFollowup());
        internalValue.setDeleted(BooleanUtils.isTrue(dataValue.getDeleted()));
        // -----------------------------------------------------------------
        // Save, update or delete data value
        // -----------------------------------------------------------------
        DataValue existingValue = !skipExistingCheck ? dataValueBatchHandler.findObject(internalValue) : null;
        if (!skipExistingCheck && existingValue != null && !existingValue.isDeleted()) {
            if (strategy.isCreateAndUpdate() || strategy.isUpdate()) {
                DataValueAudit auditValue = new DataValueAudit(internalValue, existingValue.getValue(), storedBy, AuditType.UPDATE);
                if (internalValue.isNullValue() || internalValue.isDeleted()) {
                    internalValue.setDeleted(true);
                    auditValue.setAuditType(AuditType.DELETE);
                    deleteCount++;
                } else {
                    updateCount++;
                }
                if (!dryRun) {
                    dataValueBatchHandler.updateObject(internalValue);
                    auditBatchHandler.addObject(auditValue);
                }
            } else if (strategy.isDelete()) {
                DataValueAudit auditValue = new DataValueAudit(internalValue, existingValue.getValue(), storedBy, AuditType.DELETE);
                internalValue.setDeleted(true);
                deleteCount++;
                if (!dryRun) {
                    dataValueBatchHandler.updateObject(internalValue);
                    auditBatchHandler.addObject(auditValue);
                }
            }
        } else {
            if (strategy.isCreateAndUpdate() || strategy.isCreate()) {
                if (// Ignore null values
                !internalValue.isNullValue()) {
                    if (existingValue != null && existingValue.isDeleted()) {
                        importCount++;
                        if (!dryRun) {
                            dataValueBatchHandler.updateObject(internalValue);
                        }
                    } else {
                        boolean added = false;
                        if (!dryRun) {
                            added = dataValueBatchHandler.addObject(internalValue);
                        }
                        if (dryRun || added) {
                            importCount++;
                        }
                    }
                }
            }
        }
    }
    dataValueBatchHandler.flush();
    auditBatchHandler.flush();
    int ignores = totalCount - importCount - updateCount - deleteCount;
    summary.setImportCount(new ImportCount(importCount, updateCount, ignores, deleteCount));
    summary.setStatus(summary.getConflicts().isEmpty() ? ImportStatus.SUCCESS : ImportStatus.WARNING);
    summary.setDescription("Import process completed successfully");
    clock.logTime("Data value import done, total: " + totalCount + ", import: " + importCount + ", update: " + updateCount + ", delete: " + deleteCount);
    notifier.notify(id, notificationLevel, "Import done", true).addTaskSummary(id, notificationLevel, summary);
    dataValueSet.close();
    return summary;
}
Also used : DataValueAuditBatchHandler(org.hisp.dhis.jdbc.batchhandler.DataValueAuditBatchHandler) DataValueBatchHandler(org.hisp.dhis.jdbc.batchhandler.DataValueBatchHandler) DataSet(org.hisp.dhis.dataset.DataSet) DataValue(org.hisp.dhis.datavalue.DataValue) DataApprovalWorkflow(org.hisp.dhis.dataapproval.DataApprovalWorkflow) Clock(org.hisp.dhis.system.util.Clock) CachingMap(org.hisp.dhis.commons.collection.CachingMap) I18n(org.hisp.dhis.i18n.I18n) OrganisationUnit(org.hisp.dhis.organisationunit.OrganisationUnit) DataApproval(org.hisp.dhis.dataapproval.DataApproval) ImportCount(org.hisp.dhis.dxf2.importsummary.ImportCount) Period(org.hisp.dhis.period.Period) PeriodCallable(org.hisp.dhis.system.callable.PeriodCallable) NotificationLevel(org.hisp.dhis.system.notification.NotificationLevel) DataElementCategoryOptionCombo(org.hisp.dhis.dataelement.DataElementCategoryOptionCombo) DataSet(org.hisp.dhis.dataset.DataSet) ImportSummary(org.hisp.dhis.dxf2.importsummary.ImportSummary) DataElement(org.hisp.dhis.dataelement.DataElement) ImportStrategy(org.hisp.dhis.importexport.ImportStrategy) ImportConflict(org.hisp.dhis.dxf2.importsummary.ImportConflict) CategoryOptionComboAclCallable(org.hisp.dhis.system.callable.CategoryOptionComboAclCallable) IdentifiableObjectCallable(org.hisp.dhis.system.callable.IdentifiableObjectCallable) DateUtils.parseDate(org.hisp.dhis.system.util.DateUtils.parseDate) DataValueAudit(org.hisp.dhis.datavalue.DataValueAudit)

Example 7 with ImportCount

use of org.hisp.dhis.dxf2.importsummary.ImportCount in project dhis2-core by dhis2.

the class DefaultCompleteDataSetRegistrationExchangeService method finalizeSummary.

private static void finalizeSummary(ImportSummary summary, int totalCount, int importCount, int updateCount, int deleteCount) {
    int ignores = totalCount - importCount - updateCount - deleteCount;
    summary.setImportCount(new ImportCount(importCount, updateCount, ignores, deleteCount));
    summary.setStatus(totalCount == ignores ? ImportStatus.ERROR : ImportStatus.SUCCESS);
    summary.setDescription("Import process complete.");
}
Also used : ImportCount(org.hisp.dhis.dxf2.importsummary.ImportCount)

Example 8 with ImportCount

use of org.hisp.dhis.dxf2.importsummary.ImportCount in project dhis2-core by dhis2.

the class DefaultSynchronizationManager method executeDataValuePush.

/**
 * Executes a push of data values to the given remote instance.
 *
 * @param instance the remote system instance.
 * @return an ImportSummary.
 */
private ImportConflicts executeDataValuePush(SystemInstance instance) throws WebMessageParseException {
    // ---------------------------------------------------------------------
    // Set time for last success to start of process to make data saved
    // subsequently part of next synch process without being ignored
    // ---------------------------------------------------------------------
    final Date startTime = new Date();
    final Date lastSuccessTime = SyncUtils.getLastSyncSuccess(systemSettingManager, SettingKey.LAST_SUCCESSFUL_DATA_VALUE_SYNC);
    final Date skipChangedBefore = systemSettingManager.getDateSetting(SettingKey.SKIP_SYNCHRONIZATION_FOR_DATA_CHANGED_BEFORE);
    final Date lastUpdatedAfter = lastSuccessTime.after(skipChangedBefore) ? lastSuccessTime : skipChangedBefore;
    final int objectsToSynchronize = dataValueService.getDataValueCountLastUpdatedAfter(lastUpdatedAfter, true);
    log.info("DataValues last changed before " + skipChangedBefore + " will not be synchronized.");
    if (objectsToSynchronize == 0) {
        SyncUtils.setLastSyncSuccess(systemSettingManager, SettingKey.LAST_SUCCESSFUL_DATA_VALUE_SYNC, startTime);
        log.debug("Skipping data values push, no new or updated data values");
        ImportCount importCount = new ImportCount(0, 0, 0, 0);
        return new ImportSummary(ImportStatus.SUCCESS, "No new or updated data values to push.", importCount);
    }
    log.info("Data Values: " + objectsToSynchronize + " to push since last synchronization success: " + lastSuccessTime);
    log.info("Remote server POST URL: " + instance.getUrl());
    final RequestCallback requestCallback = request -> {
        request.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        request.getHeaders().add(HEADER_AUTHORIZATION, CodecUtils.getBasicAuthString(instance.getUsername(), instance.getPassword()));
        dataValueSetService.exportDataValueSetJson(lastUpdatedAfter, request.getBody(), new IdSchemes());
    };
    final int maxSyncAttempts = systemSettingManager.getIntSetting(SettingKey.MAX_SYNC_ATTEMPTS);
    Optional<AbstractWebMessageResponse> responseSummary = SyncUtils.runSyncRequest(restTemplate, requestCallback, SyncEndpoint.DATA_VALUE_SETS.getKlass(), instance.getUrl(), maxSyncAttempts);
    ImportSummary summary = null;
    if (responseSummary.isPresent()) {
        summary = (ImportSummary) responseSummary.get();
        if (ImportStatus.SUCCESS.equals(summary.getStatus())) {
            log.info("Push successful: " + summary);
        } else {
            log.warn("Push failed: " + summary);
        }
    }
    return summary;
}
Also used : AtomicMode(org.hisp.dhis.dxf2.metadata.AtomicMode) WebMessageParseException(org.hisp.dhis.dxf2.webmessage.WebMessageParseException) ImportReport(org.hisp.dhis.dxf2.metadata.feedback.ImportReport) Date(java.util.Date) ImportCount(org.hisp.dhis.dxf2.importsummary.ImportCount) SyncEndpoint(org.hisp.dhis.dxf2.sync.SyncEndpoint) DataValueService(org.hisp.dhis.datavalue.DataValueService) ImportSummary(org.hisp.dhis.dxf2.importsummary.ImportSummary) Metadata(org.hisp.dhis.dxf2.metadata.Metadata) ImportConflicts(org.hisp.dhis.dxf2.importsummary.ImportConflicts) MetadataImportService(org.hisp.dhis.dxf2.metadata.MetadataImportService) AbstractWebMessageResponse(org.hisp.dhis.dxf2.webmessage.AbstractWebMessageResponse) User(org.hisp.dhis.user.User) SyncUtils(org.hisp.dhis.dxf2.sync.SyncUtils) ImportStatus(org.hisp.dhis.dxf2.importsummary.ImportStatus) SystemSettingManager(org.hisp.dhis.setting.SystemSettingManager) RestTemplate(org.springframework.web.client.RestTemplate) IdSchemes(org.hisp.dhis.common.IdSchemes) DataValueSetService(org.hisp.dhis.dxf2.datavalueset.DataValueSetService) MediaType(org.springframework.http.MediaType) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IOException(java.io.IOException) SchemaService(org.hisp.dhis.schema.SchemaService) MetadataImportParams(org.hisp.dhis.dxf2.metadata.MetadataImportParams) RequestCallback(org.springframework.web.client.RequestCallback) CodecUtils(org.hisp.dhis.system.util.CodecUtils) Slf4j(lombok.extern.slf4j.Slf4j) Component(org.springframework.stereotype.Component) CurrentUserService(org.hisp.dhis.user.CurrentUserService) Optional(java.util.Optional) SettingKey(org.hisp.dhis.setting.SettingKey) RequestCallback(org.springframework.web.client.RequestCallback) IdSchemes(org.hisp.dhis.common.IdSchemes) AbstractWebMessageResponse(org.hisp.dhis.dxf2.webmessage.AbstractWebMessageResponse) ImportCount(org.hisp.dhis.dxf2.importsummary.ImportCount) ImportSummary(org.hisp.dhis.dxf2.importsummary.ImportSummary) Date(java.util.Date) SyncEndpoint(org.hisp.dhis.dxf2.sync.SyncEndpoint)

Aggregations

ImportCount (org.hisp.dhis.dxf2.importsummary.ImportCount)8 ImportSummary (org.hisp.dhis.dxf2.importsummary.ImportSummary)6 IOException (java.io.IOException)3 CachingMap (org.hisp.dhis.commons.collection.CachingMap)3 DataElement (org.hisp.dhis.dataelement.DataElement)3 DataSet (org.hisp.dhis.dataset.DataSet)3 ImportConflict (org.hisp.dhis.dxf2.importsummary.ImportConflict)3 Clock (org.hisp.dhis.system.util.Clock)3 PipedOutputStream (java.io.PipedOutputStream)2 Date (java.util.Date)2 LinkedList (java.util.LinkedList)2 ExecutionException (java.util.concurrent.ExecutionException)2 ExecutorService (java.util.concurrent.ExecutorService)2 TimeoutException (java.util.concurrent.TimeoutException)2 XMLOutputFactory (javax.xml.stream.XMLOutputFactory)2 XMLStreamException (javax.xml.stream.XMLStreamException)2 XMLStreamWriter (javax.xml.stream.XMLStreamWriter)2 IdScheme (org.hisp.dhis.common.IdScheme)2 ImportOptions (org.hisp.dhis.dxf2.common.ImportOptions)2 IdentifiableObjectCallable (org.hisp.dhis.system.callable.IdentifiableObjectCallable)2