Remove own code in favor of Spring Data KeyValue's extension points.
Remove code that would be duplicated by Spring Data KeyValue otherwise. Hook into extension points. Add package-info and nullability annotations. Closes gh-151.
This commit is contained in:
@@ -30,6 +30,7 @@ import org.springframework.data.keyvalue.repository.config.QueryCreatorType;
|
|||||||
import org.springframework.data.repository.config.DefaultRepositoryBaseClass;
|
import org.springframework.data.repository.config.DefaultRepositoryBaseClass;
|
||||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||||
|
import org.springframework.vault.repository.query.VaultPartTreeQuery;
|
||||||
import org.springframework.vault.repository.query.VaultQueryCreator;
|
import org.springframework.vault.repository.query.VaultQueryCreator;
|
||||||
import org.springframework.vault.repository.support.VaultRepositoryFactoryBean;
|
import org.springframework.vault.repository.support.VaultRepositoryFactoryBean;
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ import org.springframework.vault.repository.support.VaultRepositoryFactoryBean;
|
|||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
@Inherited
|
||||||
@Import(VaultRepositoriesRegistrar.class)
|
@Import(VaultRepositoriesRegistrar.class)
|
||||||
@QueryCreatorType(VaultQueryCreator.class)
|
@QueryCreatorType(value = VaultQueryCreator.class, repositoryQueryType = VaultPartTreeQuery.class)
|
||||||
public @interface EnableVaultRepositories {
|
public @interface EnableVaultRepositories {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,22 +18,14 @@ package org.springframework.vault.repository.configuration;
|
|||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.core.annotation.AnnotationAttributes;
|
|
||||||
import org.springframework.core.type.AnnotationMetadata;
|
|
||||||
import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension;
|
import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension;
|
||||||
import org.springframework.data.keyvalue.repository.config.QueryCreatorType;
|
|
||||||
import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery;
|
|
||||||
import org.springframework.data.keyvalue.repository.query.SpelQueryCreator;
|
|
||||||
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
|
|
||||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||||
import org.springframework.data.repository.config.RepositoryConfigurationSource;
|
import org.springframework.data.repository.config.RepositoryConfigurationSource;
|
||||||
import org.springframework.vault.repository.core.VaultKeyValueAdapter;
|
import org.springframework.vault.repository.core.VaultKeyValueAdapter;
|
||||||
@@ -69,70 +61,6 @@ public class VaultRepositoryConfigurationExtension extends
|
|||||||
return "vaultKeyValueTemplate";
|
return "vaultKeyValueTemplate";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this as soon as KeyValue provides overrides for the mapping context
|
|
||||||
// name.
|
|
||||||
@Override
|
|
||||||
public void postProcess(BeanDefinitionBuilder builder,
|
|
||||||
AnnotationRepositoryConfigurationSource config) {
|
|
||||||
|
|
||||||
AnnotationAttributes attributes = config.getAttributes();
|
|
||||||
|
|
||||||
builder.addPropertyReference("keyValueOperations",
|
|
||||||
attributes.getString(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE));
|
|
||||||
builder.addPropertyValue("queryCreator", getQueryCreatorType(config));
|
|
||||||
builder.addPropertyValue("queryType", getQueryType(config));
|
|
||||||
builder.addPropertyReference("mappingContext", VAULT_MAPPING_CONTEXT_BEAN_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects the query creator type to be used for the factory to set. Will lookup a
|
|
||||||
* {@link QueryCreatorType} annotation on the {@code @Enable}-annotation or use
|
|
||||||
* {@link SpelQueryCreator} if not found.
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static Class<?> getQueryCreatorType(
|
|
||||||
AnnotationRepositoryConfigurationSource config) {
|
|
||||||
|
|
||||||
AnnotationMetadata metadata = config.getEnableAnnotationMetadata();
|
|
||||||
|
|
||||||
Map<String, Object> queryCreatorAnnotationAttributes = metadata
|
|
||||||
.getAnnotationAttributes(QueryCreatorType.class.getName());
|
|
||||||
|
|
||||||
if (queryCreatorAnnotationAttributes == null) {
|
|
||||||
return SpelQueryCreator.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnnotationAttributes queryCreatorAttributes = new AnnotationAttributes(
|
|
||||||
queryCreatorAnnotationAttributes);
|
|
||||||
return queryCreatorAttributes.getClass("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects the query creator type to be used for the factory to set. Will lookup a
|
|
||||||
* {@link QueryCreatorType} annotation on the {@code @Enable}-annotation or use
|
|
||||||
* {@link SpelQueryCreator} if not found.
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static Class<?> getQueryType(AnnotationRepositoryConfigurationSource config) {
|
|
||||||
|
|
||||||
AnnotationMetadata metadata = config.getEnableAnnotationMetadata();
|
|
||||||
|
|
||||||
Map<String, Object> queryCreatorAnnotationAttributes = metadata
|
|
||||||
.getAnnotationAttributes(QueryCreatorType.class.getName());
|
|
||||||
|
|
||||||
if (queryCreatorAnnotationAttributes == null) {
|
|
||||||
return KeyValuePartTreeQuery.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnnotationAttributes queryCreatorAttributes = new AnnotationAttributes(
|
|
||||||
queryCreatorAnnotationAttributes);
|
|
||||||
return queryCreatorAttributes.getClass("repositoryQueryType");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerBeansForRoot(BeanDefinitionRegistry registry,
|
public void registerBeansForRoot(BeanDefinitionRegistry registry,
|
||||||
RepositoryConfigurationSource configurationSource) {
|
RepositoryConfigurationSource configurationSource) {
|
||||||
@@ -171,11 +99,11 @@ public class VaultRepositoryConfigurationExtension extends
|
|||||||
|
|
||||||
AbstractBeanDefinition beanDefinition = getDefaultKeyValueTemplateBeanDefinition(configurationSource);
|
AbstractBeanDefinition beanDefinition = getDefaultKeyValueTemplateBeanDefinition(configurationSource);
|
||||||
|
|
||||||
if (beanDefinition != null) {
|
registerIfNotAlreadyRegistered(beanDefinition, registry,
|
||||||
registerIfNotAlreadyRegistered(beanDefinition, registry,
|
keyValueTemplateName.get(), configurationSource.getSource());
|
||||||
keyValueTemplateName.get(), configurationSource.getSource());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
super.registerBeansForRoot(registry, configurationSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RootBeanDefinition createVaultMappingContext(
|
private RootBeanDefinition createVaultMappingContext(
|
||||||
@@ -186,6 +114,7 @@ public class VaultRepositoryConfigurationExtension extends
|
|||||||
RootBeanDefinition mappingContextBeanDef = new RootBeanDefinition(
|
RootBeanDefinition mappingContextBeanDef = new RootBeanDefinition(
|
||||||
VaultMappingContext.class);
|
VaultMappingContext.class);
|
||||||
mappingContextBeanDef.setConstructorArgumentValues(mappingContextArgs);
|
mappingContextBeanDef.setConstructorArgumentValues(mappingContextArgs);
|
||||||
|
mappingContextBeanDef.setSource(configurationSource.getSource());
|
||||||
|
|
||||||
return mappingContextBeanDef;
|
return mappingContextBeanDef;
|
||||||
}
|
}
|
||||||
@@ -214,4 +143,9 @@ public class VaultRepositoryConfigurationExtension extends
|
|||||||
protected Collection<Class<? extends Annotation>> getIdentifyingAnnotations() {
|
protected Collection<Class<? extends Annotation>> getIdentifyingAnnotations() {
|
||||||
return Collections.<Class<? extends Annotation>> singleton(Secret.class);
|
return Collections.<Class<? extends Annotation>> singleton(Secret.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getMappingContextBeanRef() {
|
||||||
|
return VAULT_MAPPING_CONTEXT_BEAN_NAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Support infrastructure for the configuration of Vault specific repositories.
|
||||||
|
*/
|
||||||
|
@org.springframework.lang.NonNullApi
|
||||||
|
package org.springframework.vault.repository.configuration;
|
||||||
@@ -27,6 +27,7 @@ import org.springframework.core.convert.TypeDescriptor;
|
|||||||
import org.springframework.core.convert.converter.GenericConverter;
|
import org.springframework.core.convert.converter.GenericConverter;
|
||||||
import org.springframework.data.convert.JodaTimeConverters;
|
import org.springframework.data.convert.JodaTimeConverters;
|
||||||
import org.springframework.data.convert.WritingConverter;
|
import org.springframework.data.convert.WritingConverter;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.vault.repository.mapping.VaultSimpleTypes;
|
import org.springframework.vault.repository.mapping.VaultSimpleTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,6 +44,7 @@ public class VaultCustomConversions extends
|
|||||||
org.springframework.data.convert.CustomConversions {
|
org.springframework.data.convert.CustomConversions {
|
||||||
|
|
||||||
private static final StoreConversions STORE_CONVERSIONS;
|
private static final StoreConversions STORE_CONVERSIONS;
|
||||||
|
|
||||||
private static final List<Object> STORE_CONVERTERS;
|
private static final List<Object> STORE_CONVERTERS;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -89,9 +91,10 @@ public class VaultCustomConversions extends
|
|||||||
return new HashSet<>(Arrays.asList(localeToString, booleanToString));
|
return new HashSet<>(Arrays.asList(localeToString, booleanToString));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType,
|
@Nullable
|
||||||
|
public Object convert(@Nullable Object source, TypeDescriptor sourceType,
|
||||||
TypeDescriptor targetType) {
|
TypeDescriptor targetType) {
|
||||||
return source.toString();
|
return source != null ? source.toString() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Spring Vault specific converter infrastructure.
|
* Spring Vault specific converter infrastructure.
|
||||||
*/
|
*/
|
||||||
@NonNullApi
|
@org.springframework.lang.NonNullApi
|
||||||
package org.springframework.vault.repository.convert;
|
package org.springframework.vault.repository.convert;
|
||||||
|
|
||||||
import org.springframework.lang.NonNullApi;
|
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class VaultKeyValueAdapter extends AbstractKeyValueAdapter {
|
|||||||
public VaultKeyValueAdapter(VaultOperations vaultOperations,
|
public VaultKeyValueAdapter(VaultOperations vaultOperations,
|
||||||
VaultConverter vaultConverter) {
|
VaultConverter vaultConverter) {
|
||||||
|
|
||||||
super(VaultQueryEngine.INSTANCE);
|
super(new VaultQueryEngine());
|
||||||
|
|
||||||
Assert.notNull(vaultOperations, "VaultOperations must not be null");
|
Assert.notNull(vaultOperations, "VaultOperations must not be null");
|
||||||
Assert.notNull(vaultConverter, "VaultConverter must not be null");
|
Assert.notNull(vaultConverter, "VaultConverter must not be null");
|
||||||
|
|||||||
@@ -18,22 +18,15 @@ package org.springframework.vault.repository.core;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
|
||||||
import org.springframework.data.domain.Sort.Direction;
|
|
||||||
import org.springframework.data.domain.Sort.NullHandling;
|
|
||||||
import org.springframework.data.domain.Sort.Order;
|
|
||||||
import org.springframework.data.keyvalue.core.CriteriaAccessor;
|
import org.springframework.data.keyvalue.core.CriteriaAccessor;
|
||||||
import org.springframework.data.keyvalue.core.QueryEngine;
|
import org.springframework.data.keyvalue.core.QueryEngine;
|
||||||
import org.springframework.data.keyvalue.core.SortAccessor;
|
import org.springframework.data.keyvalue.core.SpelSortAccessor;
|
||||||
import org.springframework.data.keyvalue.core.SpelPropertyComparator;
|
|
||||||
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
|
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
|
||||||
import org.springframework.data.mapping.PropertyPath;
|
|
||||||
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.vault.repository.query.VaultQuery;
|
import org.springframework.vault.repository.query.VaultQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,27 +43,26 @@ import org.springframework.vault.repository.query.VaultQuery;
|
|||||||
class VaultQueryEngine extends
|
class VaultQueryEngine extends
|
||||||
QueryEngine<VaultKeyValueAdapter, VaultQuery, Comparator<?>> {
|
QueryEngine<VaultKeyValueAdapter, VaultQuery, Comparator<?>> {
|
||||||
|
|
||||||
static final VaultQueryEngine INSTANCE = new VaultQueryEngine();
|
private static final SpelExpressionParser parser = new SpelExpressionParser();
|
||||||
|
|
||||||
private VaultQueryEngine() {
|
VaultQueryEngine() {
|
||||||
super(VaultCriteriaAccessor.INSTANCE, SpelSortAccessor.INSTANCE);
|
super(VaultCriteriaAccessor.INSTANCE, new SpelSortAccessor(parser));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Collection<?> execute(VaultQuery vaultQuery, Comparator<?> comparator,
|
public Collection<?> execute(@Nullable VaultQuery vaultQuery,
|
||||||
long offset, int rows, String keyspace) {
|
@Nullable Comparator<?> comparator, long offset, int rows, String keyspace) {
|
||||||
return execute(vaultQuery, comparator, offset, rows, keyspace, Object.class);
|
return execute(vaultQuery, comparator, offset, rows, keyspace, Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> Collection<T> execute(VaultQuery vaultQuery, Comparator<?> comparator,
|
public <T> Collection<T> execute(@Nullable VaultQuery vaultQuery,
|
||||||
long offset, int rows, String keyspace, Class<T> type) {
|
@Nullable Comparator<?> comparator, long offset, int rows, String keyspace,
|
||||||
|
Class<T> type) {
|
||||||
|
|
||||||
validatePropertyPaths(vaultQuery);
|
Stream<String> stream = getRequiredAdapter().doList(keyspace).stream();
|
||||||
|
|
||||||
Stream<String> stream = getAdapter().doList(keyspace).stream();
|
|
||||||
|
|
||||||
if (vaultQuery != null) {
|
if (vaultQuery != null) {
|
||||||
stream = stream.filter(vaultQuery::test);
|
stream = stream.filter(vaultQuery::test);
|
||||||
@@ -87,7 +79,7 @@ class VaultQueryEngine extends
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<T> typed = stream.map(it -> getAdapter().get(it, keyspace, type));
|
Stream<T> typed = stream.map(it -> getRequiredAdapter().get(it, keyspace, type));
|
||||||
|
|
||||||
if (comparator != null) {
|
if (comparator != null) {
|
||||||
|
|
||||||
@@ -106,11 +98,9 @@ class VaultQueryEngine extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long count(VaultQuery vaultQuery, String keyspace) {
|
public long count(@Nullable VaultQuery vaultQuery, String keyspace) {
|
||||||
|
|
||||||
validatePropertyPaths(vaultQuery);
|
Stream<String> stream = getRequiredAdapter().doList(keyspace).stream();
|
||||||
|
|
||||||
Stream<String> stream = getAdapter().doList(keyspace).stream();
|
|
||||||
|
|
||||||
if (vaultQuery != null) {
|
if (vaultQuery != null) {
|
||||||
stream = stream.filter(vaultQuery::test);
|
stream = stream.filter(vaultQuery::test);
|
||||||
@@ -119,26 +109,6 @@ class VaultQueryEngine extends
|
|||||||
return stream.count();
|
return stream.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validatePropertyPaths(VaultQuery vaultQuery) {
|
|
||||||
|
|
||||||
if (vaultQuery == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<PropertyPath> stream = vaultQuery.getPropertyPaths().stream();
|
|
||||||
|
|
||||||
stream.map(it -> getAdapter().getMappingContext().getPersistentPropertyPath(it))
|
|
||||||
.filter(it -> it.getLeafProperty() != null)
|
|
||||||
.map(PersistentPropertyPath::getLeafProperty)
|
|
||||||
.filter(it -> !it.isIdProperty())
|
|
||||||
.forEach(
|
|
||||||
property -> {
|
|
||||||
throw new InvalidDataAccessApiUsageException(String.format(
|
|
||||||
"Cannot create criteria for non-@Id property %s",
|
|
||||||
property));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
enum VaultCriteriaAccessor implements CriteriaAccessor<VaultQuery> {
|
enum VaultCriteriaAccessor implements CriteriaAccessor<VaultQuery> {
|
||||||
|
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
@@ -148,53 +118,4 @@ class VaultQueryEngine extends
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link SortAccessor} implementation capable of creating
|
|
||||||
* {@link SpelPropertyComparator}.
|
|
||||||
*/
|
|
||||||
enum SpelSortAccessor implements SortAccessor<Comparator<?>> {
|
|
||||||
INSTANCE;
|
|
||||||
|
|
||||||
private final SpelExpressionParser parser = new SpelExpressionParser();
|
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
|
||||||
@Override
|
|
||||||
public Comparator<?> resolve(KeyValueQuery<?> query) {
|
|
||||||
|
|
||||||
if (query == null || query.getSort() == null || query.getSort().isUnsorted()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<Comparator<?>> comparator = Optional.empty();
|
|
||||||
for (Order order : query.getSort()) {
|
|
||||||
|
|
||||||
SpelPropertyComparator<Object> spelSort = new SpelPropertyComparator<>(
|
|
||||||
order.getProperty(), parser);
|
|
||||||
|
|
||||||
if (Direction.DESC.equals(order.getDirection())) {
|
|
||||||
|
|
||||||
spelSort.desc();
|
|
||||||
|
|
||||||
if (!NullHandling.NATIVE.equals(order.getNullHandling())) {
|
|
||||||
spelSort = NullHandling.NULLS_FIRST.equals(order
|
|
||||||
.getNullHandling()) ? spelSort.nullsFirst() : spelSort
|
|
||||||
.nullsLast();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!comparator.isPresent()) {
|
|
||||||
comparator = Optional.of(spelSort);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
SpelPropertyComparator<Object> spelSortToUse = spelSort;
|
|
||||||
comparator = comparator.map(it -> it.thenComparing(spelSortToUse));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return comparator
|
|
||||||
.orElseThrow(() -> new IllegalStateException(
|
|
||||||
"No sort definitions have been added to this CompoundComparator to compare"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Spring Vault core repository implementation.
|
||||||
|
*/
|
||||||
|
@org.springframework.lang.NonNullApi
|
||||||
|
package org.springframework.vault.repository.core;
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Infrastructure for the Vault JSON-to-object mapping subsystem.
|
||||||
|
*/
|
||||||
|
@org.springframework.lang.NonNullApi
|
||||||
|
package org.springframework.vault.repository.mapping;
|
||||||
|
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.vault.repository.query;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import org.springframework.data.keyvalue.core.KeyValueOperations;
|
||||||
|
import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery;
|
||||||
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
|
import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||||
|
import org.springframework.data.repository.query.ParameterAccessor;
|
||||||
|
import org.springframework.data.repository.query.QueryMethod;
|
||||||
|
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||||
|
import org.springframework.data.repository.query.parser.PartTree;
|
||||||
|
import org.springframework.vault.repository.mapping.VaultPersistentEntity;
|
||||||
|
import org.springframework.vault.repository.mapping.VaultPersistentProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vault-specific {@link KeyValuePartTreeQuery}.
|
||||||
|
*
|
||||||
|
* @author Mark Paluch
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public class VaultPartTreeQuery extends KeyValuePartTreeQuery {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link VaultPartTreeQuery} for the given {@link QueryMethod},
|
||||||
|
* {@link EvaluationContextProvider}, {@link KeyValueOperations} and query creator
|
||||||
|
* type.
|
||||||
|
*
|
||||||
|
* @param queryMethod must not be {@literal null}.
|
||||||
|
* @param evaluationContextProvider must not be {@literal null}.
|
||||||
|
* @param keyValueOperations must not be {@literal null}.
|
||||||
|
* @param queryCreator must not be {@literal null}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public VaultPartTreeQuery(QueryMethod queryMethod,
|
||||||
|
EvaluationContextProvider evaluationContextProvider,
|
||||||
|
KeyValueOperations keyValueOperations,
|
||||||
|
Class<? extends AbstractQueryCreator<?, ?>> queryCreator) {
|
||||||
|
|
||||||
|
super(queryMethod, evaluationContextProvider, keyValueOperations,
|
||||||
|
new VaultQueryCreatorFactory(
|
||||||
|
(MappingContext) keyValueOperations.getMappingContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
static class VaultQueryCreatorFactory implements
|
||||||
|
QueryCreatorFactory<VaultQueryCreator> {
|
||||||
|
|
||||||
|
private final MappingContext<VaultPersistentEntity<?>, VaultPersistentProperty> mappingContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VaultQueryCreator queryCreatorFor(PartTree partTree,
|
||||||
|
ParameterAccessor accessor) {
|
||||||
|
return new VaultQueryCreator(partTree, accessor, mappingContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,12 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.vault.repository.query;
|
package org.springframework.vault.repository.query;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.springframework.data.mapping.PropertyPath;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.vault.repository.convert.SecretDocument;
|
import org.springframework.vault.repository.convert.SecretDocument;
|
||||||
|
|
||||||
@@ -39,8 +35,6 @@ public class VaultQuery {
|
|||||||
|
|
||||||
private final Predicate<String> predicate;
|
private final Predicate<String> predicate;
|
||||||
|
|
||||||
private final Set<PropertyPath> propertyPaths;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link VaultQuery} that evaluates unconditionally to {@literal true}.
|
* Create a new {@link VaultQuery} that evaluates unconditionally to {@literal true}.
|
||||||
*/
|
*/
|
||||||
@@ -54,30 +48,10 @@ public class VaultQuery {
|
|||||||
* @param predicate must not be {@literal null}.
|
* @param predicate must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public VaultQuery(Predicate<String> predicate) {
|
public VaultQuery(Predicate<String> predicate) {
|
||||||
this(predicate, Collections.emptySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link VaultQuery} given {@link Predicate} and {@link PropertyPath}.
|
|
||||||
*
|
|
||||||
* @param predicate must not be {@literal null}.
|
|
||||||
*/
|
|
||||||
public VaultQuery(Predicate<String> predicate, PropertyPath propertyPath) {
|
|
||||||
|
|
||||||
Assert.notNull(predicate, "Predicate must not be null");
|
|
||||||
Assert.notNull(propertyPath, "PropertyPath must not be null");
|
|
||||||
|
|
||||||
this.predicate = predicate;
|
|
||||||
this.propertyPaths = Collections.singleton(propertyPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private VaultQuery(Predicate<String> predicate, Set<PropertyPath> propertyPaths) {
|
|
||||||
|
|
||||||
Assert.notNull(propertyPaths, "PropertyPaths must not be null");
|
|
||||||
Assert.notNull(predicate, "Predicate must not be null");
|
Assert.notNull(predicate, "Predicate must not be null");
|
||||||
|
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.propertyPaths = propertyPaths;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,13 +89,19 @@ public class VaultQuery {
|
|||||||
* @see Predicate#and(Predicate)
|
* @see Predicate#and(Predicate)
|
||||||
*/
|
*/
|
||||||
public VaultQuery and(VaultQuery other) {
|
public VaultQuery and(VaultQuery other) {
|
||||||
|
return new VaultQuery(this.predicate.and(other.predicate));
|
||||||
|
}
|
||||||
|
|
||||||
Set<PropertyPath> propertyPaths = new HashSet<>(this.propertyPaths.size()
|
/**
|
||||||
+ other.propertyPaths.size(), 1);
|
* Compose a new {@link VaultQuery} using predicates of {@literal this} and the
|
||||||
propertyPaths.addAll(this.propertyPaths);
|
* {@code other} query using logical {@code AND}.
|
||||||
propertyPaths.addAll(other.propertyPaths);
|
*
|
||||||
|
* @param other must not be {@literal null}.
|
||||||
return new VaultQuery(this.predicate.and(other.predicate), propertyPaths);
|
* @return a new composed {@link VaultQuery}.
|
||||||
|
* @see Predicate#and(Predicate)
|
||||||
|
*/
|
||||||
|
public VaultQuery and(Predicate<String> predicate) {
|
||||||
|
return new VaultQuery(this.predicate.and(predicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,30 +113,7 @@ public class VaultQuery {
|
|||||||
* @see Predicate#and(Predicate)
|
* @see Predicate#and(Predicate)
|
||||||
*/
|
*/
|
||||||
public VaultQuery or(VaultQuery other) {
|
public VaultQuery or(VaultQuery other) {
|
||||||
|
return new VaultQuery(this.predicate.or(other.predicate));
|
||||||
Set<PropertyPath> propertyPaths = new HashSet<>(this.propertyPaths.size()
|
|
||||||
+ other.propertyPaths.size(), 1);
|
|
||||||
propertyPaths.addAll(this.propertyPaths);
|
|
||||||
propertyPaths.addAll(other.propertyPaths);
|
|
||||||
|
|
||||||
return new VaultQuery(this.predicate.or(other.predicate), propertyPaths);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compose a new {@link VaultQuery} using predicates of {@literal this} query and the
|
|
||||||
* {@code other} {@link Predicate} using logical {@code AND}.
|
|
||||||
*
|
|
||||||
* @param other must not be {@literal null}.
|
|
||||||
* @return a new composed {@link VaultQuery}.
|
|
||||||
* @see Predicate#and(Predicate)
|
|
||||||
*/
|
|
||||||
public VaultQuery and(Predicate<String> predicate, PropertyPath propertyPath) {
|
|
||||||
|
|
||||||
Set<PropertyPath> propertyPaths = new HashSet<>(this.propertyPaths.size() + 1, 1);
|
|
||||||
propertyPaths.addAll(this.propertyPaths);
|
|
||||||
propertyPaths.add(propertyPath);
|
|
||||||
|
|
||||||
return new VaultQuery(this.predicate.and(predicate), propertyPaths);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,11 +122,4 @@ public class VaultQuery {
|
|||||||
public Predicate<String> getPredicate() {
|
public Predicate<String> getPredicate() {
|
||||||
return predicate;
|
return predicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return constrained {@link PropertyPath}s for this {@link VaultQuery}.
|
|
||||||
*/
|
|
||||||
public Set<PropertyPath> getPropertyPaths() {
|
|
||||||
return Collections.unmodifiableSet(propertyPaths);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,14 +24,19 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
|
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
|
||||||
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
|
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
||||||
import org.springframework.data.repository.query.ParameterAccessor;
|
import org.springframework.data.repository.query.ParameterAccessor;
|
||||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||||
import org.springframework.data.repository.query.parser.Part;
|
import org.springframework.data.repository.query.parser.Part;
|
||||||
import org.springframework.data.repository.query.parser.PartTree;
|
import org.springframework.data.repository.query.parser.PartTree;
|
||||||
import org.springframework.data.repository.query.parser.Part.IgnoreCaseType;
|
import org.springframework.data.repository.query.parser.Part.IgnoreCaseType;
|
||||||
import org.springframework.data.repository.query.parser.Part.Type;
|
import org.springframework.data.repository.query.parser.Part.Type;
|
||||||
|
import org.springframework.vault.repository.mapping.VaultPersistentEntity;
|
||||||
|
import org.springframework.vault.repository.mapping.VaultPersistentProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query creator for Vault queries. Vault queries are limited to criterias constraining
|
* Query creator for Vault queries. Vault queries are limited to criterias constraining
|
||||||
@@ -44,14 +49,7 @@ import org.springframework.data.repository.query.parser.Part.Type;
|
|||||||
public class VaultQueryCreator extends
|
public class VaultQueryCreator extends
|
||||||
AbstractQueryCreator<KeyValueQuery<VaultQuery>, VaultQuery> {
|
AbstractQueryCreator<KeyValueQuery<VaultQuery>, VaultQuery> {
|
||||||
|
|
||||||
/**
|
private final MappingContext<VaultPersistentEntity<?>, VaultPersistentProperty> mappingContext;
|
||||||
* Create a new {@link VaultQueryCreator} given {@link PartTree}.
|
|
||||||
*
|
|
||||||
* @param tree must not be {@literal null}.
|
|
||||||
*/
|
|
||||||
public VaultQueryCreator(PartTree tree) {
|
|
||||||
super(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link VaultQueryCreator} given {@link PartTree} and
|
* Create a new {@link VaultQueryCreator} given {@link PartTree} and
|
||||||
@@ -59,27 +57,38 @@ public class VaultQueryCreator extends
|
|||||||
*
|
*
|
||||||
* @param tree must not be {@literal null}.
|
* @param tree must not be {@literal null}.
|
||||||
* @param parameters must not be {@literal null}.
|
* @param parameters must not be {@literal null}.
|
||||||
|
* @param mappingContext must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public VaultQueryCreator(PartTree tree, ParameterAccessor parameters) {
|
public VaultQueryCreator(
|
||||||
|
PartTree tree,
|
||||||
|
ParameterAccessor parameters,
|
||||||
|
MappingContext<VaultPersistentEntity<?>, VaultPersistentProperty> mappingContext) {
|
||||||
|
|
||||||
super(tree, parameters);
|
super(tree, parameters);
|
||||||
|
this.mappingContext = mappingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected VaultQuery create(Part part, Iterator<Object> parameters) {
|
protected VaultQuery create(Part part, Iterator<Object> parameters) {
|
||||||
return new VaultQuery(createPredicate(part, parameters), part.getProperty());
|
return new VaultQuery(createPredicate(part, parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected VaultQuery and(Part part, VaultQuery base, Iterator<Object> parameters) {
|
protected VaultQuery and(Part part, VaultQuery base, Iterator<Object> parameters) {
|
||||||
|
return base.and(createPredicate(part, parameters));
|
||||||
if (base == null) {
|
|
||||||
return create(part, parameters);
|
|
||||||
}
|
|
||||||
return base.and(createPredicate(part, parameters), part.getProperty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Predicate<String> createPredicate(Part part,
|
private Predicate<String> createPredicate(Part part, Iterator<Object> parameters) {
|
||||||
Iterator<Object> parameters) {
|
|
||||||
|
PersistentPropertyPath<VaultPersistentProperty> propertyPath = mappingContext
|
||||||
|
.getPersistentPropertyPath(part.getProperty());
|
||||||
|
|
||||||
|
if (propertyPath.getLeafProperty() != null
|
||||||
|
&& !propertyPath.getLeafProperty().isIdProperty()) {
|
||||||
|
throw new InvalidDataAccessApiUsageException(String.format(
|
||||||
|
"Cannot create criteria for non-@Id property %s",
|
||||||
|
propertyPath.getLeafProperty()));
|
||||||
|
}
|
||||||
|
|
||||||
VariableAccessor accessor = getVariableAccessor(part);
|
VariableAccessor accessor = getVariableAccessor(part);
|
||||||
|
|
||||||
@@ -167,7 +176,7 @@ public class VaultQueryCreator extends
|
|||||||
|
|
||||||
KeyValueQuery<VaultQuery> query = new KeyValueQuery<>(vaultQuery);
|
KeyValueQuery<VaultQuery> query = new KeyValueQuery<>(vaultQuery);
|
||||||
|
|
||||||
if (sort != null) {
|
if (sort.isSorted()) {
|
||||||
query.orderBy(sort);
|
query.orderBy(sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Query derivation mechanism for Vault specific repositories.
|
||||||
|
*/
|
||||||
|
@org.springframework.lang.NonNullApi
|
||||||
|
package org.springframework.vault.repository.query;
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Support infrastructure for query derivation of Vault specific repositories.
|
||||||
|
*/
|
||||||
|
@org.springframework.lang.NonNullApi
|
||||||
|
package org.springframework.vault.repository.support;
|
||||||
|
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.vault.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.FilterType;
|
||||||
|
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.map.repository.config.EnableMapRepositories;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.vault.core.VaultTemplate;
|
||||||
|
import org.springframework.vault.repository.MultipleSpringDataModulesIntegrationTests.MultipleModulesActiveTestConfiguration;
|
||||||
|
import org.springframework.vault.repository.configuration.EnableVaultRepositories;
|
||||||
|
import org.springframework.vault.util.IntegrationTestSupport;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mark Paluch
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@ContextConfiguration(classes = MultipleModulesActiveTestConfiguration.class)
|
||||||
|
public class MultipleSpringDataModulesIntegrationTests extends IntegrationTestSupport {
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableMapRepositories(considerNestedRepositories = true, //
|
||||||
|
excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, value = VaultRepository.class))
|
||||||
|
@EnableVaultRepositories(considerNestedRepositories = true, //
|
||||||
|
excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, value = MapRepository.class))
|
||||||
|
static class MultipleModulesActiveTestConfiguration extends
|
||||||
|
VaultIntegrationTestConfiguration {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
VaultRepository vaultRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MapRepository mapRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
VaultTemplate vaultTemplate;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
vaultRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadAndSave() {
|
||||||
|
|
||||||
|
Person person = new Person();
|
||||||
|
person.setId("foo-key");
|
||||||
|
person.setName("bar");
|
||||||
|
|
||||||
|
vaultRepository.save(person);
|
||||||
|
|
||||||
|
Iterable<Person> all = vaultRepository.findAll();
|
||||||
|
|
||||||
|
assertThat(all).contains(person);
|
||||||
|
assertThat(vaultRepository.findByIdStartsWith("foo-key")).contains(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadAndSaveMapRepository() {
|
||||||
|
|
||||||
|
vaultRepository.findAll().forEach(vaultRepository::delete);
|
||||||
|
|
||||||
|
Person person = new Person();
|
||||||
|
person.setId("foo-key");
|
||||||
|
person.setName("bar");
|
||||||
|
|
||||||
|
mapRepository.save(person);
|
||||||
|
|
||||||
|
Iterable<Person> all = mapRepository.findAll();
|
||||||
|
|
||||||
|
assertThat(all).contains(person);
|
||||||
|
assertThat(mapRepository.findByNameStartsWith("bar")).contains(person);
|
||||||
|
assertThat(vaultRepository.findById("foo-key")).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VaultRepository extends CrudRepository<Person, String> {
|
||||||
|
|
||||||
|
List<Person> findByIdStartsWith(String prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MapRepository extends CrudRepository<Person, String> {
|
||||||
|
|
||||||
|
List<Person> findByNameStartsWith(String prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
static class Person {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,10 +20,12 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
import org.springframework.data.repository.query.DefaultParameters;
|
import org.springframework.data.repository.query.DefaultParameters;
|
||||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||||
import org.springframework.data.repository.query.parser.PartTree;
|
import org.springframework.data.repository.query.parser.PartTree;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
import org.springframework.vault.repository.mapping.VaultMappingContext;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -34,6 +36,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
*/
|
*/
|
||||||
public class VaultQueryCreatorUnitTests {
|
public class VaultQueryCreatorUnitTests {
|
||||||
|
|
||||||
|
private VaultMappingContext mappingContext = new VaultMappingContext();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void greaterThan() {
|
public void greaterThan() {
|
||||||
|
|
||||||
@@ -178,6 +182,11 @@ public class VaultQueryCreatorUnitTests {
|
|||||||
assertThat(query.getPredicate()).accepts("3", "4").rejects("2", "5", "6");
|
assertThat(query.getPredicate()).accepts("3", "4").rejects("2", "5", "6");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidDataAccessApiUsageException.class)
|
||||||
|
public void failsForNonIdProperties() {
|
||||||
|
createQuery("findByName", "");
|
||||||
|
}
|
||||||
|
|
||||||
VaultQuery createQuery(String methodName, String value) {
|
VaultQuery createQuery(String methodName, String value) {
|
||||||
|
|
||||||
DefaultParameters defaultParameters = new DefaultParameters(
|
DefaultParameters defaultParameters = new DefaultParameters(
|
||||||
@@ -187,7 +196,8 @@ public class VaultQueryCreatorUnitTests {
|
|||||||
PartTree partTree = new PartTree(methodName, Credentials.class);
|
PartTree partTree = new PartTree(methodName, Credentials.class);
|
||||||
VaultQueryCreator queryCreator = new VaultQueryCreator(
|
VaultQueryCreator queryCreator = new VaultQueryCreator(
|
||||||
partTree,
|
partTree,
|
||||||
new ParametersParameterAccessor(defaultParameters, new Object[] { value }));
|
new ParametersParameterAccessor(defaultParameters, new Object[] { value }),
|
||||||
|
mappingContext);
|
||||||
|
|
||||||
return queryCreator.createQuery().getCriteria();
|
return queryCreator.createQuery().getCriteria();
|
||||||
}
|
}
|
||||||
@@ -201,7 +211,8 @@ public class VaultQueryCreatorUnitTests {
|
|||||||
PartTree partTree = new PartTree(methodName, Credentials.class);
|
PartTree partTree = new PartTree(methodName, Credentials.class);
|
||||||
VaultQueryCreator queryCreator = new VaultQueryCreator(
|
VaultQueryCreator queryCreator = new VaultQueryCreator(
|
||||||
partTree,
|
partTree,
|
||||||
new ParametersParameterAccessor(defaultParameters, new Object[] { value }));
|
new ParametersParameterAccessor(defaultParameters, new Object[] { value }),
|
||||||
|
mappingContext);
|
||||||
|
|
||||||
return queryCreator.createQuery().getCriteria();
|
return queryCreator.createQuery().getCriteria();
|
||||||
}
|
}
|
||||||
@@ -215,7 +226,7 @@ public class VaultQueryCreatorUnitTests {
|
|||||||
PartTree partTree = new PartTree(methodName, Credentials.class);
|
PartTree partTree = new PartTree(methodName, Credentials.class);
|
||||||
VaultQueryCreator queryCreator = new VaultQueryCreator(partTree,
|
VaultQueryCreator queryCreator = new VaultQueryCreator(partTree,
|
||||||
new ParametersParameterAccessor(defaultParameters, new Object[] { value,
|
new ParametersParameterAccessor(defaultParameters, new Object[] { value,
|
||||||
anotherValue }));
|
anotherValue }), mappingContext);
|
||||||
|
|
||||||
return queryCreator.createQuery().getCriteria();
|
return queryCreator.createQuery().getCriteria();
|
||||||
}
|
}
|
||||||
@@ -231,6 +242,6 @@ public class VaultQueryCreatorUnitTests {
|
|||||||
|
|
||||||
static class Credentials {
|
static class Credentials {
|
||||||
|
|
||||||
String id;
|
String id, name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user