Search in sources :

Example 56 with AttributeData

use of io.jans.orm.model.AttributeData in project jans by JanssenProject.

the class SpannerOperationServiceImpl method getAttributeDataList.

private List<AttributeData> getAttributeDataList(String objectClass, ResultSet resultSet, boolean skipDn) throws EntryConvertationException {
    try {
        if ((resultSet == null)) {
            return null;
        }
        if (!resultSet.next()) {
            return null;
        }
        List<AttributeData> result = new ArrayList<AttributeData>();
        // TODO: Include child table columns
        Set<String> nullableColumns = connectionProvider.getTableNullableColumns(objectClass);
        List<StructField> structFields = resultSet.getType().getStructFields();
        int columnsCount = resultSet.getColumnCount();
        for (int i = 0; i < columnsCount; i++) {
            StructField structField = structFields.get(i);
            String attributeName = structField.getName();
            Code columnTypeCode = structField.getType().getCode();
            boolean isNullable = nullableColumns.contains(attributeName.toLowerCase());
            if (SpannerOperationService.DOC_ID.equalsIgnoreCase(attributeName) || SpannerOperationService.ID.equalsIgnoreCase(attributeName)) {
                // Skip internal attributes
                continue;
            }
            if (skipDn && SpannerOperationService.DN.equalsIgnoreCase(attributeName)) {
                // Skip DN attribute
                continue;
            }
            Boolean multiValued = Boolean.FALSE;
            Object[] attributeValueObjects;
            if (resultSet.isNull(i)) {
                attributeValueObjects = NO_OBJECTS;
                if (isNullable) {
                    // Ignore columns with default NULL values
                    continue;
                }
            } else {
                if (Code.ARRAY == columnTypeCode) {
                    attributeValueObjects = convertDbArrayToValue(resultSet, structField.getType().getArrayElementType(), i, attributeName);
                    multiValued = Boolean.TRUE;
                } else if (Code.BOOL == columnTypeCode) {
                    attributeValueObjects = new Object[] { resultSet.getBoolean(i) };
                } else if (Code.DATE == columnTypeCode) {
                    attributeValueObjects = new Object[] { com.google.cloud.Date.toJavaUtilDate(resultSet.getDate(i)) };
                } else if (Code.TIMESTAMP == columnTypeCode) {
                    attributeValueObjects = new Object[] { resultSet.getTimestamp(i).toDate() };
                } else if (Code.INT64 == columnTypeCode) {
                    attributeValueObjects = new Object[] { resultSet.getLong(i) };
                } else if (Code.NUMERIC == columnTypeCode) {
                    attributeValueObjects = new Object[] { resultSet.getBigDecimal(i).longValue() };
                } else if (Code.STRING == columnTypeCode) {
                    Object value = resultSet.getString(i);
                    try {
                        value = com.google.cloud.Timestamp.parseTimestamp(value.toString());
                    } catch (Exception ex) {
                    }
                    attributeValueObjects = new Object[] { value };
                } else {
                    throw new EntryConvertationException(String.format("Column with name '%s' does not contain unsupported type '%s'", attributeName, columnTypeCode));
                }
            }
            unescapeValues(attributeValueObjects);
            AttributeData tmpAttribute = new AttributeData(attributeName, attributeValueObjects, multiValued);
            if (multiValued != null) {
                tmpAttribute.setMultiValued(multiValued);
            }
            result.add(tmpAttribute);
        }
        return result;
    } catch (SpannerException ex) {
        throw new EntryConvertationException("Failed to convert entry!", ex);
    }
}
Also used : ArrayList(java.util.ArrayList) Code(com.google.cloud.spanner.Type.Code) DeleteException(io.jans.orm.exception.operation.DeleteException) IncompatibleTypeException(io.jans.orm.exception.operation.IncompatibleTypeException) PersistenceException(io.jans.orm.exception.operation.PersistenceException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) EntryConvertationException(io.jans.orm.exception.operation.EntryConvertationException) DuplicateEntryException(io.jans.orm.exception.operation.DuplicateEntryException) SpannerException(com.google.cloud.spanner.SpannerException) SearchException(io.jans.orm.exception.operation.SearchException) EntryNotFoundException(io.jans.orm.exception.operation.EntryNotFoundException) ValueWithStructField(io.jans.orm.cloud.spanner.model.ValueWithStructField) StructField(com.google.cloud.spanner.Type.StructField) EntryConvertationException(io.jans.orm.exception.operation.EntryConvertationException) SpannerException(com.google.cloud.spanner.SpannerException) AttributeData(io.jans.orm.model.AttributeData)

Example 57 with AttributeData

use of io.jans.orm.model.AttributeData 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)

Example 58 with AttributeData

use of io.jans.orm.model.AttributeData in project jans by JanssenProject.

the class SqlEntryManager method updateMergeChanges.

@Override
protected <T> void updateMergeChanges(String baseDn, T entry, boolean isConfigurationUpdate, Class<?> entryClass, Map<String, AttributeData> attributesFromDbMap, List<AttributeDataModification> attributeDataModifications, boolean forceUpdate) {
    if (forceUpdate) {
        // SQL ORM can't update objectClass because it select table by objectClass name
        return;
    }
    // Update object classes if entry contains custom object classes
    if (!isConfigurationUpdate) {
        String[] objectClasses = getObjectClasses(entry, entryClass);
        if (ArrayHelper.isEmpty(objectClasses)) {
            throw new UnsupportedOperationException(String.format("There is no attribute with objectClasses to persist! Entry is invalid: '%s'", entry));
        }
        AttributeData objectClassAttributeData = attributesFromDbMap.get(OBJECT_CLASS.toLowerCase());
        if (objectClassAttributeData == null) {
            throw new UnsupportedOperationException(String.format("There is no attribute with objectClasses in DB! Entry is invalid: '%s'", entry));
        }
        String[] objectClassesFromDb = objectClassAttributeData.getStringValues();
        if (ArrayHelper.isEmpty(objectClassesFromDb)) {
            throw new UnsupportedOperationException(String.format("There is no attribute with objectClasses in DB! Entry is invalid: '%s'", entry));
        }
        // We need to check only first element of each array because objectCLass in SQL is single value attribute
        if (!StringHelper.equals(objectClassesFromDb[0], objectClasses[0])) {
            throw new UnsupportedOperationException(String.format("It's not possible to change objectClasses of already persisted entry! Entry is invalid: '%s'", entry));
        }
    }
}
Also used : AttributeData(io.jans.orm.model.AttributeData)

Example 59 with AttributeData

use of io.jans.orm.model.AttributeData in project jans by JanssenProject.

the class SqlOperationServiceImpl method addEntryImpl.

private boolean addEntryImpl(TableMapping tableMapping, String key, Collection<AttributeData> attributes) throws PersistenceException {
    try {
        Map<String, String> columTypes = tableMapping.getColumTypes();
        RelationalPathBase<Object> tableRelationalPath = buildTableRelationalPath(tableMapping);
        SQLInsertClause sqlInsertQuery = this.sqlQueryFactory.insert(tableRelationalPath);
        for (AttributeData attribute : attributes) {
            String attributeType = columTypes.get(attribute.getName().toLowerCase());
            boolean multiValued = (attributeType != null) && isJsonColumn(tableMapping.getTableName(), attributeType);
            sqlInsertQuery.columns(Expressions.stringPath(attribute.getName()));
            if (multiValued || Boolean.TRUE.equals(attribute.getMultiValued())) {
                sqlInsertQuery.values(convertValueToDbJson(attribute.getValues()));
            } else {
                sqlInsertQuery.values(attribute.getValue());
            }
        }
        long rowInserted = sqlInsertQuery.execute();
        return rowInserted == 1;
    } catch (QueryException ex) {
        throw new PersistenceException("Failed to add entry", ex);
    }
}
Also used : QueryException(com.querydsl.core.QueryException) SQLInsertClause(com.querydsl.sql.dml.SQLInsertClause) PersistenceException(io.jans.orm.exception.operation.PersistenceException) AttributeData(io.jans.orm.model.AttributeData)

Example 60 with AttributeData

use of io.jans.orm.model.AttributeData in project jans by JanssenProject.

the class SqlOperationServiceImpl method authenticateImpl.

private boolean authenticateImpl(String key, String password, String objectClass) throws SearchException {
    Instant startTime = OperationDurationUtil.instance().now();
    boolean result = false;
    if (password != null) {
        try {
            List<AttributeData> attributes = lookup(key, objectClass, USER_PASSWORD);
            Object userPasswordObj = null;
            for (AttributeData attribute : attributes) {
                if (StringHelper.equalsIgnoreCase(attribute.getName(), USER_PASSWORD)) {
                    userPasswordObj = attribute.getValue();
                }
            }
            String userPassword = null;
            if (userPasswordObj instanceof String) {
                userPassword = (String) userPasswordObj;
            }
            if (userPassword != null) {
                if (persistenceExtension == null) {
                    result = PasswordEncryptionHelper.compareCredentials(password, userPassword);
                } else {
                    result = persistenceExtension.compareHashedPasswords(password, userPassword);
                }
            }
        } catch (EntryConvertationException ex) {
            throw new SearchException(String.format("Failed to get '%s' attribute", USER_PASSWORD), ex);
        }
    }
    Duration duration = OperationDurationUtil.instance().duration(startTime);
    TableMapping tableMapping = connectionProvider.getTableMappingByKey(key, objectClass);
    OperationDurationUtil.instance().logDebug("SQL operation: bind, duration: {}, table: {}, key: {}", duration, tableMapping.getTableName(), key);
    return result;
}
Also used : Instant(java.time.Instant) SearchException(io.jans.orm.exception.operation.SearchException) TableMapping(io.jans.orm.sql.model.TableMapping) EntryConvertationException(io.jans.orm.exception.operation.EntryConvertationException) Duration(java.time.Duration) AttributeData(io.jans.orm.model.AttributeData)

Aggregations

AttributeData (io.jans.orm.model.AttributeData)62 MappingException (io.jans.orm.exception.MappingException)29 ArrayList (java.util.ArrayList)23 SearchException (io.jans.orm.exception.operation.SearchException)22 EntryPersistenceException (io.jans.orm.exception.EntryPersistenceException)17 AuthenticationException (io.jans.orm.exception.AuthenticationException)15 EntryDeleteException (io.jans.orm.exception.EntryDeleteException)15 PropertyAnnotation (io.jans.orm.reflect.property.PropertyAnnotation)14 AttributeDataModification (io.jans.orm.model.AttributeDataModification)13 JsonObject (io.jans.orm.annotation.JsonObject)10 LinkedList (java.util.LinkedList)10 DateTimeParseException (java.time.format.DateTimeParseException)8 List (java.util.List)8 ParsedKey (io.jans.orm.impl.model.ParsedKey)7 JsonObject (com.couchbase.client.java.document.json.JsonObject)6 AttributeName (io.jans.orm.annotation.AttributeName)6 PersistenceException (io.jans.orm.exception.operation.PersistenceException)6 Annotation (java.lang.annotation.Annotation)6 AttributeModificationType (io.jans.orm.model.AttributeDataModification.AttributeModificationType)5 LinkedHashMap (java.util.LinkedHashMap)5