Search in sources :

Example 1 with I_EntryAccess

use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.

the class CompositionServiceImp method internalUpdate.

/**
 * Update of an existing composition. With optional custom contribution, or existing one will be
 * updated.
 *
 * @param compositionId  ID of existing composition
 * @param composition    RMObject instance of the given Composition which represents the new
 *                       version
 * @param systemId       Audit system; or NULL if contribution is given
 * @param committerId    Audit committer; or NULL if contribution is given
 * @param description    (Optional) Audit description; or NULL if contribution is given
 * @param contributionId NULL if new one should be created; or ID of given custom contribution
 * @return Version UID pointing to updated composition
 */
private ObjectVersionId internalUpdate(UUID compositionId, Composition composition, UUID systemId, UUID committerId, String description, UUID contributionId) {
    boolean result;
    try {
        var compositionAccess = I_CompositionAccess.retrieveInstance(getDataAccess(), compositionId);
        if (compositionAccess == null) {
            throw new ObjectNotFoundException(I_CompositionAccess.class.getName(), "Could not find composition: " + compositionId);
        }
        // validate RM composition
        validationService.check(composition);
        // Check if template ID is not the same in existing and given data -> error
        String existingTemplateId = compositionAccess.getContent().get(0).getTemplateId();
        String inputTemplateId = composition.getArchetypeDetails().getTemplateId().getValue();
        if (!existingTemplateId.equals(inputTemplateId)) {
            // check if base template ID doesn't match  (template ID schema: "$NAME.$LANG.v$VER")
            if (!existingTemplateId.split("\\.")[0].equals(inputTemplateId.split("\\.")[0])) {
                throw new InvalidApiParameterException("Can't update composition to have different template.");
            }
            // if base matches, check if given template ID is just a new version of the correct template
            int existingTemplateIdVersion = Integer.parseInt(existingTemplateId.split("\\.v")[1]);
            int inputTemplateIdVersion = Integer.parseInt(inputTemplateId.substring(inputTemplateId.lastIndexOf("\\.v") + 1));
            if (inputTemplateIdVersion < existingTemplateIdVersion) {
                throw new InvalidApiParameterException("Can't update composition with wrong template version bump.");
            }
        }
        // to keep reference to entry to update: pull entry out of composition access and replace
        // composition content with input, then write back to the original access
        List<I_EntryAccess> contentList = compositionAccess.getContent();
        contentList.get(0).setCompositionData(composition);
        compositionAccess.setContent(contentList);
        compositionAccess.setComposition(composition);
        if (contributionId != null) {
            // if custom contribution should be set
            compositionAccess.setContributionId(contributionId);
            result = compositionAccess.update(LocalDateTime.now(), contributionId);
        } else {
            // else existing one will be updated
            if (committerId == null || systemId == null) {
                throw new InternalServerException("Failed to update composition, missing mandatory audit meta data.");
            }
            result = compositionAccess.update(LocalDateTime.now(), committerId, systemId, description, ContributionChangeType.MODIFICATION);
        }
    } catch (ObjectNotFoundException | InvalidApiParameterException e) {
        // otherwise exceptions would always get sucked up by the catch below
        throw e;
    } catch (Exception e) {
        throw new InternalServerException(e);
    }
    if (!result) {
        throw new InternalServerException("Update failed on composition:" + compositionId);
    }
    return new ObjectVersionId(compositionId.toString(), this.getServerConfig().getNodename(), getLastVersionNumber(compositionId).toString());
}
Also used : InvalidApiParameterException(org.ehrbase.api.exception.InvalidApiParameterException) I_EntryAccess(org.ehrbase.dao.access.interfaces.I_EntryAccess) InternalServerException(org.ehrbase.api.exception.InternalServerException) StructuredString(org.ehrbase.response.ehrscape.StructuredString) ObjectVersionId(com.nedap.archie.rm.support.identification.ObjectVersionId) UnexpectedSwitchCaseException(org.ehrbase.api.exception.UnexpectedSwitchCaseException) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) InternalServerException(org.ehrbase.api.exception.InternalServerException) ValidationException(org.ehrbase.api.exception.ValidationException) InvalidApiParameterException(org.ehrbase.api.exception.InvalidApiParameterException) UnprocessableEntityException(org.ehrbase.api.exception.UnprocessableEntityException) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) I_CompositionAccess(org.ehrbase.dao.access.interfaces.I_CompositionAccess)

Example 2 with I_EntryAccess

use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.

the class CompositionAccess method retrieveCompositionVersion.

/**
 * @throws IllegalArgumentException when version number is not greater 0
 * @throws ObjectNotFoundException  when no composition could be found with given input
 */
public static I_CompositionAccess retrieveCompositionVersion(I_DomainAccess domainAccess, UUID id, int version) {
    if (version < 1) {
        throw new IllegalArgumentException("Version number must be > 0  please check your code");
    }
    // check if this version number matches the current version
    if (getLastVersionNumber(domainAccess, id) == version) {
        // current version
        return retrieveInstance(domainAccess, id);
    }
    // FIXME make jooq compliant
    String versionQuery = "select " + "row_id, " + "in_contribution, " + "ehr_id, " + "language, " + "territory, " + "composer, " + "sys_transaction, " + "has_audit," + "attestation_ref, " + "feeder_audit, " + "links from \n" + "  (select ROW_NUMBER() OVER (ORDER BY sys_transaction ASC ) AS row_id, * from ehr.composition_history " + "       WHERE id = ?) \n" + "    AS Version WHERE row_id = ?;";
    Connection connection = domainAccess.getConnection();
    I_CompositionAccess compositionHistoryAccess = null;
    try (PreparedStatement preparedStatement = connection.prepareStatement(versionQuery)) {
        preparedStatement.setObject(1, id);
        preparedStatement.setInt(2, version);
        try (ResultSet resultSet = preparedStatement.executeQuery()) {
            while (resultSet.next()) {
                CompositionRecord compositionRecord1 = domainAccess.getContext().newRecord(COMPOSITION);
                compositionRecord1.setId(id);
                compositionRecord1.setInContribution(UUID.fromString(resultSet.getString("in_contribution")));
                compositionRecord1.setEhrId(UUID.fromString(resultSet.getString("ehr_id")));
                compositionRecord1.setLanguage(resultSet.getString("language"));
                compositionRecord1.setTerritory(resultSet.getInt("territory"));
                compositionRecord1.setComposer(UUID.fromString(resultSet.getString("composer")));
                compositionRecord1.setSysTransaction(resultSet.getTimestamp("sys_transaction"));
                compositionRecord1.setHasAudit(UUID.fromString(resultSet.getString("has_audit")));
                compositionRecord1.setFeederAudit(JSONB.valueOf(resultSet.getString("feeder_audit")));
                /* TODO: uncomment when links encode/decode is fully implemented
                    compositionRecord1.setLinks(JSONB.valueOf(resultSet.getString("links")));
                     */
                compositionHistoryAccess = new CompositionAccess(domainAccess, compositionRecord1);
            }
        }
    } catch (SQLException e) {
        throw new ObjectNotFoundException(COMPOSITION_LITERAL, "Composition not found or or invalid DB content", e);
    }
    if (compositionHistoryAccess != null) {
        compositionHistoryAccess.setContent(I_EntryAccess.retrieveInstanceInCompositionVersion(domainAccess, compositionHistoryAccess, version));
        // retrieve the corresponding contribution
        I_ContributionAccess contributionAccess = I_ContributionAccess.retrieveInstance(domainAccess, compositionHistoryAccess.getContributionId());
        compositionHistoryAccess.setContributionAccess(contributionAccess);
        I_AuditDetailsAccess auditDetailsAccess = new AuditDetailsAccess(domainAccess.getDataAccess()).retrieveInstance(domainAccess.getDataAccess(), compositionHistoryAccess.getAuditDetailsId());
        compositionHistoryAccess.setAuditDetailsAccess(auditDetailsAccess);
        // retrieve versioned context
        EventContext historicalEventContext = I_ContextAccess.retrieveHistoricalEventContext(domainAccess, id, compositionHistoryAccess.getSysTransaction());
        // adjust context for entries
        if (historicalEventContext != null) {
            for (I_EntryAccess entryAccess : compositionHistoryAccess.getContent()) {
                entryAccess.getComposition().setContext(historicalEventContext);
            }
        }
    }
    domainAccess.releaseConnection(connection);
    return compositionHistoryAccess;
}
Also used : I_EntryAccess(org.ehrbase.dao.access.interfaces.I_EntryAccess) I_AuditDetailsAccess(org.ehrbase.dao.access.interfaces.I_AuditDetailsAccess) SQLException(java.sql.SQLException) I_CompositionAccess(org.ehrbase.dao.access.interfaces.I_CompositionAccess) I_ContributionAccess(org.ehrbase.dao.access.interfaces.I_ContributionAccess) Connection(java.sql.Connection) I_AuditDetailsAccess(org.ehrbase.dao.access.interfaces.I_AuditDetailsAccess) PreparedStatement(java.sql.PreparedStatement) EventContext(com.nedap.archie.rm.composition.EventContext) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) ResultSet(java.sql.ResultSet) I_CompositionAccess(org.ehrbase.dao.access.interfaces.I_CompositionAccess) CompositionRecord(org.ehrbase.jooq.pg.tables.records.CompositionRecord)

Example 3 with I_EntryAccess

use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.

the class CompositionAccess method internalCreate.

private UUID internalCreate(LocalDateTime timestamp, UUID committerId, UUID systemId, String description, UUID contribution) {
    // check if custom contribution is already set, because changing it would yield updating in DB which is not desired (creates wrong new "version")
    if (contribution != null) {
        // Retrieve audit metadata from given contribution
        var newContributionAccess = I_ContributionAccess.retrieveInstance(this.getDataAccess(), contribution);
        systemId = newContributionAccess.getAuditsSystemId();
        committerId = newContributionAccess.getAuditsCommitter();
        description = newContributionAccess.getAuditsDescription();
    } else {
        // if not set, create DB entry of contribution so it can get referenced in this composition
        // prepare contribution with given values
        contributionAccess.setDataType(ContributionDataType.composition);
        contributionAccess.setState(ContributionDef.ContributionState.COMPLETE);
        contributionAccess.setAuditDetailsValues(committerId, systemId, description, I_ConceptAccess.ContributionChangeType.CREATION);
        UUID contributionId = this.contributionAccess.commit();
        setContributionId(contributionId);
    }
    // create DB entry of prepared auditDetails so it can get referenced in this composition
    auditDetailsAccess.setChangeType(I_ConceptAccess.fetchContributionChangeType(this, I_ConceptAccess.ContributionChangeType.CREATION));
    // prepare composition audit with given values
    auditDetailsAccess.setSystemId(systemId);
    auditDetailsAccess.setCommitter(committerId);
    auditDetailsAccess.setDescription(description);
    UUID auditId = this.auditDetailsAccess.commit();
    compositionRecord.setHasAudit(auditId);
    compositionRecord.setSysTransaction(Timestamp.valueOf(timestamp));
    compositionRecord.store();
    if (content.isEmpty()) {
        logger.warn("Composition has no content:");
    }
    try {
        for (I_EntryAccess entryAccess : content) {
            entryAccess.commit(Timestamp.valueOf(timestamp));
        }
    } catch (Exception exception) {
        logger.error("Problem in committing content, rolling back, exception:" + exception);
        throw new IllegalArgumentException("Could not commit content:" + exception);
    }
    if (!composition.getCategory().getDefiningCode().getCodeString().equals("431")) {
        EventContext eventContext = composition.getContext();
        I_ContextAccess contextAccess = I_ContextAccess.getInstance(this, eventContext);
        if (!contextAccess.isVoid()) {
            contextAccess.setCompositionId(compositionRecord.getId());
            contextAccess.commit(Timestamp.valueOf(timestamp));
        }
    }
    return compositionRecord.getId();
}
Also used : EventContext(com.nedap.archie.rm.composition.EventContext) I_EntryAccess(org.ehrbase.dao.access.interfaces.I_EntryAccess) I_ContextAccess(org.ehrbase.dao.access.interfaces.I_ContextAccess) UUID(java.util.UUID) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) InternalServerException(org.ehrbase.api.exception.InternalServerException) SQLException(java.sql.SQLException)

Example 4 with I_EntryAccess

use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.

the class EntryAccess method retrieveInstanceInCompositionVersion.

public static List<I_EntryAccess> retrieveInstanceInCompositionVersion(I_DomainAccess domainAccess, I_CompositionAccess compositionHistoryAccess, int version) {
    Result<EntryHistoryRecord> entryHistoryRecords = domainAccess.getContext().selectFrom(ENTRY_HISTORY).where(ENTRY_HISTORY.COMPOSITION_ID.eq(compositionHistoryAccess.getId())).and(ENTRY_HISTORY.SYS_TRANSACTION.eq(compositionHistoryAccess.getSysTransaction())).fetch();
    // build the list of parameters to recreate the composition
    Map<SystemValue, Object> values = new HashMap<>();
    values.put(SystemValue.COMPOSER, new PersistedPartyProxy(domainAccess).retrieve(compositionHistoryAccess.getComposerId()));
    EventContext context = I_ContextAccess.retrieveHistoricalEventContext(domainAccess, compositionHistoryAccess.getId(), compositionHistoryAccess.getSysTransaction());
    if (context == null) {
        // unchanged context use the current one!
        // also optional handling of context, because persistent compositions don't have a context
        compositionHistoryAccess.getContextId().ifPresent(uuid -> I_ContextAccess.retrieveInstance(domainAccess, uuid).mapRmEventContext());
    }
    values.put(SystemValue.CONTEXT, context);
    values.put(SystemValue.LANGUAGE, new CodePhrase(new TerminologyId("ISO_639-1"), compositionHistoryAccess.getLanguageCode()));
    String territory2letters = domainAccess.getContext().fetchOne(TERRITORY, TERRITORY.CODE.eq(compositionHistoryAccess.getTerritoryCode())).getTwoletter();
    values.put(SystemValue.TERRITORY, new CodePhrase(new TerminologyId("ISO_3166-1"), territory2letters));
    values.put(SystemValue.FEEDER_AUDIT, new FeederAuditEncoding().fromDB(compositionHistoryAccess.getFeederAudit()));
    List<I_EntryAccess> content = new ArrayList<>();
    try {
        EntryAccess entryAccess = new EntryAccess(domainAccess);
        for (EntryHistoryRecord record : entryHistoryRecords) {
            // set the record UID in the composition
            UUID compositionId = compositionHistoryAccess.getId();
            values.put(SystemValue.UID, new ObjectVersionId(compositionId.toString() + "::" + domainAccess.getServerConfig().getNodename() + "::" + version));
            entryAccess.entryRecord = domainAccess.getContext().newRecord(ENTRY);
            entryAccess.entryRecord.from(record);
            entryAccess.composition = new RawJson().unmarshal(record.getEntry().data(), Composition.class);
            setCompositionAttributes(entryAccess.composition, values);
            buildArchetypeDetails(entryAccess);
            content.add(entryAccess);
        }
    } catch (Exception e) {
        throw new IllegalArgumentException(DB_INCONSISTENCY + e);
    }
    return content;
}
Also used : TerminologyId(com.nedap.archie.rm.support.identification.TerminologyId) I_EntryAccess(org.ehrbase.dao.access.interfaces.I_EntryAccess) Composition(com.nedap.archie.rm.composition.Composition) CodePhrase(com.nedap.archie.rm.datatypes.CodePhrase) HashMap(java.util.HashMap) RawJson(org.ehrbase.serialisation.dbencoding.RawJson) EntryHistoryRecord(org.ehrbase.jooq.pg.tables.records.EntryHistoryRecord) ArrayList(java.util.ArrayList) ObjectVersionId(com.nedap.archie.rm.support.identification.ObjectVersionId) InternalServerException(org.ehrbase.api.exception.InternalServerException) PersistedPartyProxy(org.ehrbase.dao.access.jooq.party.PersistedPartyProxy) I_EntryAccess(org.ehrbase.dao.access.interfaces.I_EntryAccess) EventContext(com.nedap.archie.rm.composition.EventContext) FeederAuditEncoding(org.ehrbase.serialisation.dbencoding.rmobject.FeederAuditEncoding) UUID(java.util.UUID)

Example 5 with I_EntryAccess

use of org.ehrbase.dao.access.interfaces.I_EntryAccess in project ehrbase by ehrbase.

the class EntryAccess method retrieveInstanceInComposition.

/**
 * @throws IllegalArgumentException if DB is inconsistent or operation fails
 */
public static List<I_EntryAccess> retrieveInstanceInComposition(I_DomainAccess domainAccess, I_CompositionAccess compositionAccess) {
    Result<EntryRecord> entryRecords = domainAccess.getContext().selectFrom(ENTRY).where(ENTRY.COMPOSITION_ID.eq(compositionAccess.getId())).fetch();
    // build the list of parameters to recreate the composition
    Map<SystemValue, Object> values = new HashMap<>();
    values.put(SystemValue.COMPOSER, new PersistedPartyProxy(domainAccess).retrieve(compositionAccess.getComposerId()));
    // optional handling for persistent compositions that do not have a context
    Optional<I_ContextAccess> opContextAccess = compositionAccess.getContextId().map(id -> I_ContextAccess.retrieveInstance(domainAccess, id));
    opContextAccess.ifPresent(context -> values.put(SystemValue.CONTEXT, context.mapRmEventContext()));
    values.put(SystemValue.LANGUAGE, new CodePhrase(new TerminologyId("ISO_639-1"), compositionAccess.getLanguageCode()));
    String territory2letters = domainAccess.getContext().fetchOne(TERRITORY, TERRITORY.CODE.eq(compositionAccess.getTerritoryCode())).getTwoletter();
    values.put(SystemValue.TERRITORY, new CodePhrase(new TerminologyId("ISO_3166-1"), territory2letters));
    if (compositionAccess.getFeederAudit() != null) {
        values.put(SystemValue.FEEDER_AUDIT, new FeederAuditEncoding().fromDB(compositionAccess.getFeederAudit()));
    }
    if (compositionAccess.getLinks() != null) {
        values.put(SystemValue.LINKS, new LinksEncoding().fromDB(compositionAccess.getLinks()));
    }
    List<I_EntryAccess> content = new ArrayList<>();
    try {
        EntryAccess entryAccess = new EntryAccess(domainAccess);
        for (EntryRecord record : entryRecords) {
            // set the record UID in the composition with matching version number
            Integer version = I_CompositionAccess.getLastVersionNumber(domainAccess, compositionAccess.getId());
            values.put(SystemValue.UID, new ObjectVersionId(compositionAccess.getId().toString() + "::" + domainAccess.getServerConfig().getNodename() + "::" + version));
            entryAccess.entryRecord = record;
            String value = record.getEntry().data();
            entryAccess.composition = new RawJson().unmarshal(value, Composition.class);
            // continuing optional handling for persistent compositions
            opContextAccess.map(I_ContextAccess::mapRmEventContext).ifPresent(ec -> values.put(SystemValue.CONTEXT, ec));
            values.put(SystemValue.CATEGORY, new RecordedDvCodedText().fromDB(record, ENTRY.CATEGORY));
            setCompositionAttributes(entryAccess.composition, values);
            buildArchetypeDetails(entryAccess);
            content.add(entryAccess);
        }
    } catch (Exception e) {
        throw new IllegalArgumentException(DB_INCONSISTENCY + e);
    }
    return content;
}
Also used : I_EntryAccess(org.ehrbase.dao.access.interfaces.I_EntryAccess) CodePhrase(com.nedap.archie.rm.datatypes.CodePhrase) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ObjectVersionId(com.nedap.archie.rm.support.identification.ObjectVersionId) I_EntryAccess(org.ehrbase.dao.access.interfaces.I_EntryAccess) RecordedDvCodedText(org.ehrbase.service.RecordedDvCodedText) FeederAuditEncoding(org.ehrbase.serialisation.dbencoding.rmobject.FeederAuditEncoding) LinksEncoding(org.ehrbase.serialisation.dbencoding.rmobject.LinksEncoding) TerminologyId(com.nedap.archie.rm.support.identification.TerminologyId) Composition(com.nedap.archie.rm.composition.Composition) RawJson(org.ehrbase.serialisation.dbencoding.RawJson) InternalServerException(org.ehrbase.api.exception.InternalServerException) PersistedPartyProxy(org.ehrbase.dao.access.jooq.party.PersistedPartyProxy) I_ContextAccess(org.ehrbase.dao.access.interfaces.I_ContextAccess) EntryRecord(org.ehrbase.jooq.pg.tables.records.EntryRecord)

Aggregations

I_EntryAccess (org.ehrbase.dao.access.interfaces.I_EntryAccess)6 EventContext (com.nedap.archie.rm.composition.EventContext)4 InternalServerException (org.ehrbase.api.exception.InternalServerException)4 ObjectVersionId (com.nedap.archie.rm.support.identification.ObjectVersionId)3 UUID (java.util.UUID)3 ObjectNotFoundException (org.ehrbase.api.exception.ObjectNotFoundException)3 I_ContextAccess (org.ehrbase.dao.access.interfaces.I_ContextAccess)3 Composition (com.nedap.archie.rm.composition.Composition)2 CodePhrase (com.nedap.archie.rm.datatypes.CodePhrase)2 TerminologyId (com.nedap.archie.rm.support.identification.TerminologyId)2 SQLException (java.sql.SQLException)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 I_CompositionAccess (org.ehrbase.dao.access.interfaces.I_CompositionAccess)2 PersistedPartyProxy (org.ehrbase.dao.access.jooq.party.PersistedPartyProxy)2 RawJson (org.ehrbase.serialisation.dbencoding.RawJson)2 FeederAuditEncoding (org.ehrbase.serialisation.dbencoding.rmobject.FeederAuditEncoding)2 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1