Search in sources :

Example 1 with AttributeModificationType

use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.

the class SpannerEntryManager method merge.

@Override
public void merge(String dn, String[] objectClasses, List<AttributeDataModification> attributeDataModifications, Integer expirationValue) {
    // Update entry
    try {
        List<AttributeDataModification> modifications = new ArrayList<AttributeDataModification>(attributeDataModifications.size());
        for (AttributeDataModification attributeDataModification : attributeDataModifications) {
            AttributeData attribute = attributeDataModification.getAttribute();
            AttributeData oldAttribute = attributeDataModification.getOldAttribute();
            String attributeName = null;
            Object[] attributeValues = null;
            Boolean multiValued = null;
            if (attribute != null) {
                attributeName = attribute.getName();
                attributeValues = attribute.getValues();
                multiValued = attribute.getMultiValued();
            }
            String oldAttributeName = null;
            Object[] oldAttributeValues = null;
            if (oldAttribute != null) {
                oldAttributeName = oldAttribute.getName();
                oldAttributeValues = oldAttribute.getValues();
            }
            AttributeDataModification modification = null;
            AttributeModificationType modificationType = attributeDataModification.getModificationType();
            if ((AttributeModificationType.ADD == modificationType) || (AttributeModificationType.FORCE_UPDATE == modificationType)) {
                modification = createModification(modificationType, toInternalAttribute(attributeName), multiValued, attributeValues, oldAttributeValues);
            } else {
                if ((AttributeModificationType.REMOVE == modificationType)) {
                    if ((attribute == null) && isEmptyAttributeValues(oldAttribute)) {
                        // It's RDBS case. We don't need to set null to already empty table cell
                        continue;
                    }
                    modification = createModification(AttributeModificationType.REMOVE, toInternalAttribute(oldAttributeName), multiValued, oldAttributeValues, null);
                } else if ((AttributeModificationType.REPLACE == modificationType)) {
                    modification = createModification(AttributeModificationType.REPLACE, toInternalAttribute(attributeName), multiValued, attributeValues, oldAttributeValues);
                }
            }
            if (modification != null) {
                modifications.add(modification);
            }
        }
        if (modifications.size() > 0) {
            boolean result = getOperationService().updateEntry(toSQLKey(dn).getKey(), objectClasses[0], modifications);
            if (!result) {
                throw new EntryPersistenceException(String.format("Failed to update entry: '%s'", dn));
            }
        }
    } catch (Exception ex) {
        throw new EntryPersistenceException(String.format("Failed to update entry: '%s'", dn), ex);
    }
}
Also used : AttributeDataModification(io.jans.orm.model.AttributeDataModification) AttributeModificationType(io.jans.orm.model.AttributeDataModification.AttributeModificationType) ArrayList(java.util.ArrayList) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) AttributeData(io.jans.orm.model.AttributeData) MappingException(io.jans.orm.exception.MappingException) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) EntryDeleteException(io.jans.orm.exception.EntryDeleteException) SearchException(io.jans.orm.exception.operation.SearchException) AuthenticationException(io.jans.orm.exception.AuthenticationException)

Example 2 with AttributeModificationType

use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.

the class SqlEntryManager method merge.

@Override
public void merge(String dn, String[] objectClasses, List<AttributeDataModification> attributeDataModifications, Integer expirationValue) {
    // Update entry
    try {
        List<AttributeDataModification> modifications = new ArrayList<AttributeDataModification>(attributeDataModifications.size());
        for (AttributeDataModification attributeDataModification : attributeDataModifications) {
            AttributeData attribute = attributeDataModification.getAttribute();
            AttributeData oldAttribute = attributeDataModification.getOldAttribute();
            String attributeName = null;
            Object[] attributeValues = null;
            Boolean multiValued = null;
            if (attribute != null) {
                attributeName = attribute.getName();
                attributeValues = attribute.getValues();
                multiValued = attribute.getMultiValued();
            }
            String oldAttributeName = null;
            Object[] oldAttributeValues = null;
            if (oldAttribute != null) {
                oldAttributeName = oldAttribute.getName();
                oldAttributeValues = oldAttribute.getValues();
            }
            AttributeDataModification modification = null;
            AttributeModificationType modificationType = attributeDataModification.getModificationType();
            if ((AttributeModificationType.ADD == modificationType) || (AttributeModificationType.FORCE_UPDATE == modificationType)) {
                modification = createModification(modificationType, toInternalAttribute(attributeName), multiValued, attributeValues);
            } else {
                if ((AttributeModificationType.REMOVE == modificationType)) {
                    if ((attribute == null) && isEmptyAttributeValues(oldAttribute)) {
                        // It's RDBS case. We don't need to set null to already empty table cell
                        continue;
                    }
                    modification = createModification(AttributeModificationType.REMOVE, toInternalAttribute(oldAttributeName), multiValued, oldAttributeValues);
                } else if ((AttributeModificationType.REPLACE == modificationType)) {
                    modification = createModification(AttributeModificationType.REPLACE, toInternalAttribute(attributeName), multiValued, attributeValues);
                }
            }
            if (modification != null) {
                modifications.add(modification);
            }
        }
        if (modifications.size() > 0) {
            boolean result = getOperationService().updateEntry(toSQLKey(dn).getKey(), objectClasses[0], modifications);
            if (!result) {
                throw new EntryPersistenceException(String.format("Failed to update entry: '%s'", dn));
            }
        }
    } catch (Exception ex) {
        throw new EntryPersistenceException(String.format("Failed to update entry: '%s'", dn), ex);
    }
}
Also used : AttributeDataModification(io.jans.orm.model.AttributeDataModification) AttributeModificationType(io.jans.orm.model.AttributeDataModification.AttributeModificationType) ArrayList(java.util.ArrayList) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) AttributeData(io.jans.orm.model.AttributeData) MappingException(io.jans.orm.exception.MappingException) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) EntryDeleteException(io.jans.orm.exception.EntryDeleteException) SearchException(io.jans.orm.exception.operation.SearchException) DateTimeParseException(java.time.format.DateTimeParseException) AuthenticationException(io.jans.orm.exception.AuthenticationException)

Example 3 with AttributeModificationType

use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.

the class SqlOperationServiceImpl method updateEntryImpl.

private boolean updateEntryImpl(TableMapping tableMapping, String key, List<AttributeDataModification> mods) throws PersistenceException {
    try {
        Map<String, String> columTypes = tableMapping.getColumTypes();
        RelationalPathBase<Object> tableRelationalPath = buildTableRelationalPath(tableMapping);
        SQLUpdateClause sqlUpdateQuery = this.sqlQueryFactory.update(tableRelationalPath);
        for (AttributeDataModification attributeMod : mods) {
            AttributeData attribute = attributeMod.getAttribute();
            Path path = Expressions.stringPath(attribute.getName());
            String attributeType = columTypes.get(attribute.getName().toLowerCase());
            boolean multiValued = (attributeType != null) && isJsonColumn(tableMapping.getTableName(), attributeType);
            AttributeModificationType type = attributeMod.getModificationType();
            if ((AttributeModificationType.ADD == type) || (AttributeModificationType.FORCE_UPDATE == type)) {
                if (multiValued || Boolean.TRUE.equals(attribute.getMultiValued())) {
                    sqlUpdateQuery.set(path, convertValueToDbJson(attribute.getValues()));
                } else {
                    sqlUpdateQuery.set(path, attribute.getValue());
                }
            } else if (AttributeModificationType.REPLACE == type) {
                if (multiValued || Boolean.TRUE.equals(attribute.getMultiValued())) {
                    sqlUpdateQuery.set(path, convertValueToDbJson(attribute.getValues()));
                } else {
                    sqlUpdateQuery.set(path, attribute.getValue());
                }
            } else if (AttributeModificationType.REMOVE == type) {
                sqlUpdateQuery.setNull(path);
            } else {
                throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented");
            }
        }
        Predicate whereExp = ExpressionUtils.eq(Expressions.stringPath(SqlOperationService.DOC_ID), Expressions.constant(key));
        long rowInserted = sqlUpdateQuery.where(whereExp).execute();
        return rowInserted == 1;
    } catch (QueryException ex) {
        throw new PersistenceException("Failed to update entry", ex);
    }
}
Also used : Path(com.querydsl.core.types.Path) AttributeModificationType(io.jans.orm.model.AttributeDataModification.AttributeModificationType) Predicate(com.querydsl.core.types.Predicate) QueryException(com.querydsl.core.QueryException) AttributeDataModification(io.jans.orm.model.AttributeDataModification) SQLUpdateClause(com.querydsl.sql.dml.SQLUpdateClause) PersistenceException(io.jans.orm.exception.operation.PersistenceException) AttributeData(io.jans.orm.model.AttributeData)

Example 4 with AttributeModificationType

use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.

the class BaseEntryManager method collectAttributeModifications.

protected List<AttributeDataModification> collectAttributeModifications(List<PropertyAnnotation> propertiesAnnotations, Map<String, AttributeData> attributesToPersistMap, Map<String, AttributeData> attributesFromLdapMap, boolean isSchemaUpdate, AttributeModificationType schemaModificationType, boolean forceUpdate) {
    List<AttributeDataModification> attributeDataModifications = new ArrayList<AttributeDataModification>();
    for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) {
        String propertyName = propertiesAnnotation.getPropertyName();
        Annotation ldapAttribute;
        ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), AttributeName.class);
        if (ldapAttribute != null) {
            String ldapAttributeName = ((AttributeName) ldapAttribute).name();
            if (StringHelper.isEmpty(ldapAttributeName)) {
                ldapAttributeName = propertyName;
            }
            ldapAttributeName = ldapAttributeName.toLowerCase();
            AttributeData attributeToPersist = attributesToPersistMap.get(ldapAttributeName);
            AttributeData attributeFromLdap = attributesFromLdapMap.get(ldapAttributeName);
            // Remove processed attributes
            attributesToPersistMap.remove(ldapAttributeName);
            attributesFromLdapMap.remove(ldapAttributeName);
            AttributeName ldapAttributeAnnotation = (AttributeName) ldapAttribute;
            if (ldapAttributeAnnotation.ignoreDuringUpdate()) {
                continue;
            }
            if (attributeFromLdap != null && attributeToPersist != null) {
                // Modify DN entry attribute in DS
                if (!attributeFromLdap.equals(attributeToPersist)) {
                    if (isEmptyAttributeValues(attributeToPersist) && !ldapAttributeAnnotation.updateOnly()) {
                        attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
                    } else {
                        attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REPLACE, attributeToPersist, attributeFromLdap));
                    }
                }
            } else if ((attributeFromLdap == null) && (attributeToPersist != null)) {
                // Add entry attribute or change schema
                if (isSchemaUpdate && (attributeToPersist.getValue() == null && Arrays.equals(attributeToPersist.getValues(), new Object[] {}))) {
                    continue;
                }
                AttributeModificationType modType = isSchemaUpdate ? schemaModificationType : AttributeModificationType.ADD;
                if (AttributeModificationType.ADD == modType) {
                    if (isEmptyAttributeValues(attributeToPersist)) {
                        if (forceUpdate) {
                            attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeToPersist));
                        }
                    } else {
                        modType = forceUpdate ? AttributeModificationType.FORCE_UPDATE : modType;
                        attributeDataModifications.add(new AttributeDataModification(modType, attributeToPersist));
                    }
                } else {
                    attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeToPersist));
                }
            } else if ((attributeFromLdap != null) && (attributeToPersist == null)) {
                // or updateOnly = true
                if (!ldapAttributeAnnotation.ignoreDuringRead() && !ldapAttributeAnnotation.updateOnly()) {
                    if (isEmptyAttributeValues(attributeFromLdap) && isStoreFullEntry()) {
                        // It's RDBS case. We don't need to set null to already empty table cell
                        continue;
                    }
                    attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
                }
            } else if (forceUpdate && (attributeFromLdap == null) && (attributeToPersist == null)) {
                attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, new AttributeData(ldapAttributeName, null)));
            }
        }
    }
    // Process properties with @AttributesList annotation
    for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) {
        Annotation ldapAttribute;
        ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), AttributesList.class);
        if (ldapAttribute != null) {
            Map<String, AttributeName> ldapAttributesConfiguration = new HashMap<String, AttributeName>();
            for (AttributeName ldapAttributeConfiguration : ((AttributesList) ldapAttribute).attributesConfiguration()) {
                ldapAttributesConfiguration.put(ldapAttributeConfiguration.name(), ldapAttributeConfiguration);
            }
            // Prepare attributes for removal
            for (AttributeData attributeFromLdap : attributesFromLdapMap.values()) {
                String attributeName = attributeFromLdap.getName();
                if (OBJECT_CLASS.equalsIgnoreCase(attributeName)) {
                    continue;
                }
                AttributeName ldapAttributeConfiguration = ldapAttributesConfiguration.get(attributeName);
                if ((ldapAttributeConfiguration != null) && ldapAttributeConfiguration.ignoreDuringUpdate()) {
                    continue;
                }
                if (!attributesToPersistMap.containsKey(attributeName.toLowerCase())) {
                    // Remove if attribute not marked as ignoreDuringRead = true
                    if ((ldapAttributeConfiguration == null) || ((ldapAttributeConfiguration != null) && !ldapAttributeConfiguration.ignoreDuringRead())) {
                        attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
                    }
                }
            }
            // Prepare attributes for adding and replace
            for (AttributeData attributeToPersist : attributesToPersistMap.values()) {
                String attributeName = attributeToPersist.getName();
                AttributeName ldapAttributeConfiguration = ldapAttributesConfiguration.get(attributeName);
                if ((ldapAttributeConfiguration != null) && ldapAttributeConfiguration.ignoreDuringUpdate()) {
                    continue;
                }
                AttributeData attributeFromLdap = attributesFromLdapMap.get(attributeName.toLowerCase());
                if (attributeFromLdap == null) {
                    // Add entry attribute or change schema
                    AttributeModificationType modType = isSchemaUpdate ? schemaModificationType : AttributeModificationType.ADD;
                    if (AttributeModificationType.ADD.equals(modType)) {
                        if (!isEmptyAttributeValues(attributeToPersist)) {
                            attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.ADD, attributeToPersist));
                        }
                    } else {
                        attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeToPersist));
                    }
                } else if ((attributeFromLdap != null) && isEmptyAttributeValues(attributeToPersist)) {
                    if (isEmptyAttributeValues(attributeFromLdap) && isStoreFullEntry()) {
                        // It's RDBS case. We don't need to set null to already empty table cell
                        continue;
                    }
                    attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
                } else {
                    if (!attributeFromLdap.equals(attributeToPersist)) {
                        if (isEmptyAttributeValues(attributeToPersist) && (ldapAttributeConfiguration == null || !ldapAttributeConfiguration.updateOnly())) {
                            if (isEmptyAttributeValues(attributeFromLdap) && isStoreFullEntry()) {
                                // It's RDBS case. We don't need to set null to already empty table cell
                                continue;
                            }
                            attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
                        } else {
                            attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REPLACE, attributeToPersist, attributeFromLdap));
                        }
                    }
                }
            }
        }
    }
    return attributeDataModifications;
}
Also used : AttributeDataModification(io.jans.orm.model.AttributeDataModification) AttributeModificationType(io.jans.orm.model.AttributeDataModification.AttributeModificationType) AttributesList(io.jans.orm.annotation.AttributesList) HashMap(java.util.HashMap) IdentityHashMap(java.util.IdentityHashMap) ArrayList(java.util.ArrayList) AttributeName(io.jans.orm.annotation.AttributeName) PropertyAnnotation(io.jans.orm.reflect.property.PropertyAnnotation) Annotation(java.lang.annotation.Annotation) AttributeData(io.jans.orm.model.AttributeData) PropertyAnnotation(io.jans.orm.reflect.property.PropertyAnnotation)

Example 5 with AttributeModificationType

use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.

the class SpannerOperationServiceImpl method updateEntryImpl.

private boolean updateEntryImpl(TableMapping tableMapping, String key, List<AttributeDataModification> mods) throws PersistenceException {
    try {
        MessageDigest messageDigest = getMessageDigestInstance();
        Map<String, StructField> columTypes = tableMapping.getColumTypes();
        WriteBuilder mutationBuilder = Mutation.newInsertOrUpdateBuilder(tableMapping.getTableName()).set(SpannerOperationService.DOC_ID).to(key);
        List<Mutation> mutations = new LinkedList<>();
        for (AttributeDataModification attributeMod : mods) {
            AttributeData attribute = attributeMod.getAttribute();
            AttributeModificationType type = attributeMod.getModificationType();
            String attributeName = attribute.getName();
            StructField attributeType = columTypes.get(attributeName.toLowerCase());
            // If column not inside table we should check if there is child table
            if (attributeType == null) {
                TableMapping childTableMapping = connectionProvider.getChildTableMappingByKey(key, tableMapping, attributeName);
                if (childTableMapping == null) {
                    throw new PersistenceException(String.format("Failed to update entry. Column '%s' is undefined", attributeName));
                }
                Map<String, StructField> childColumTypes = childTableMapping.getColumTypes();
                StructField childAttributeType = childColumTypes.get(attributeName.toLowerCase());
                // Build Mutation for child table
                Map<String, Object> oldValues = null;
                if ((attributeMod.getOldAttribute() != null) && (attributeMod.getOldAttribute().getValues() != null)) {
                    oldValues = new HashMap<>();
                    for (Object oldValue : attributeMod.getOldAttribute().getValues()) {
                        String dictDocId = getStringUniqueKey(messageDigest, oldValue);
                        oldValues.put(dictDocId, oldValue);
                    }
                }
                if ((AttributeModificationType.ADD == type) || (AttributeModificationType.FORCE_UPDATE == type) || (AttributeModificationType.REPLACE == type)) {
                    for (Object value : attribute.getValues()) {
                        WriteBuilder childMutationBuilder = Mutation.newInsertOrUpdateBuilder(childTableMapping.getTableName());
                        String dictDocId = getStringUniqueKey(messageDigest, value);
                        childMutationBuilder.set(SpannerOperationService.DOC_ID).to(key).set(SpannerOperationService.DICT_DOC_ID).to(dictDocId);
                        setMutationBuilderValue(childMutationBuilder, childAttributeType, value);
                        mutations.add(childMutationBuilder.build());
                        if (oldValues != null) {
                            oldValues.remove(dictDocId);
                        }
                    }
                } else if (AttributeModificationType.REMOVE == type) {
                    // Build Mutation for child table
                    com.google.cloud.spanner.KeySet.Builder keySetBuilder = KeySet.newBuilder();
                    for (Object value : attribute.getValues()) {
                        String dictDocId = getStringUniqueKey(messageDigest, value);
                        keySetBuilder.addKey(Key.of(key, dictDocId));
                    }
                    Mutation childMutation = Mutation.delete(childTableMapping.getTableName(), keySetBuilder.build());
                    mutations.add(childMutation);
                } else {
                    throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented");
                }
                if ((oldValues != null) && (oldValues.size() > 0)) {
                    com.google.cloud.spanner.KeySet.Builder keySetBuilder = KeySet.newBuilder();
                    for (String removeDictDocId : oldValues.keySet()) {
                        keySetBuilder.addKey(Key.of(key, removeDictDocId));
                    }
                    Mutation childMutation = Mutation.delete(childTableMapping.getTableName(), keySetBuilder.build());
                    mutations.add(childMutation);
                }
            } else {
                if ((AttributeModificationType.ADD == type) || (AttributeModificationType.FORCE_UPDATE == type) || (AttributeModificationType.REPLACE == type)) {
                    setMutationBuilderValue(mutationBuilder, attributeType, attribute.getValues());
                } else if (AttributeModificationType.REMOVE == type) {
                    removeMutationBuilderValue(mutationBuilder, attribute, attributeType);
                } else {
                    throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented");
                }
            }
        }
        mutations.add(0, mutationBuilder.build());
        databaseClient.write(mutations);
        return true;
    } catch (SpannerException | IllegalStateException ex) {
        throw new PersistenceException("Failed to update entry", ex);
    }
}
Also used : AttributeModificationType(io.jans.orm.model.AttributeDataModification.AttributeModificationType) WriteBuilder(com.google.cloud.spanner.Mutation.WriteBuilder) Builder(com.google.cloud.spanner.Statement.Builder) ValueWithStructField(io.jans.orm.cloud.spanner.model.ValueWithStructField) StructField(com.google.cloud.spanner.Type.StructField) MessageDigest(java.security.MessageDigest) KeySet(com.google.cloud.spanner.KeySet) TableMapping(io.jans.orm.cloud.spanner.model.TableMapping) LinkedList(java.util.LinkedList) AttributeDataModification(io.jans.orm.model.AttributeDataModification) WriteBuilder(com.google.cloud.spanner.Mutation.WriteBuilder) PersistenceException(io.jans.orm.exception.operation.PersistenceException) Mutation(com.google.cloud.spanner.Mutation) SpannerException(com.google.cloud.spanner.SpannerException) AttributeData(io.jans.orm.model.AttributeData)

Aggregations

AttributeData (io.jans.orm.model.AttributeData)5 AttributeDataModification (io.jans.orm.model.AttributeDataModification)5 AttributeModificationType (io.jans.orm.model.AttributeDataModification.AttributeModificationType)5 ArrayList (java.util.ArrayList)3 AuthenticationException (io.jans.orm.exception.AuthenticationException)2 EntryDeleteException (io.jans.orm.exception.EntryDeleteException)2 EntryPersistenceException (io.jans.orm.exception.EntryPersistenceException)2 MappingException (io.jans.orm.exception.MappingException)2 PersistenceException (io.jans.orm.exception.operation.PersistenceException)2 SearchException (io.jans.orm.exception.operation.SearchException)2 KeySet (com.google.cloud.spanner.KeySet)1 Mutation (com.google.cloud.spanner.Mutation)1 WriteBuilder (com.google.cloud.spanner.Mutation.WriteBuilder)1 SpannerException (com.google.cloud.spanner.SpannerException)1 Builder (com.google.cloud.spanner.Statement.Builder)1 StructField (com.google.cloud.spanner.Type.StructField)1 QueryException (com.querydsl.core.QueryException)1 Path (com.querydsl.core.types.Path)1 Predicate (com.querydsl.core.types.Predicate)1 SQLUpdateClause (com.querydsl.sql.dml.SQLUpdateClause)1