Skip to content

Commit

Permalink
HSEARCH-3102 Expose references to beans configured for a given role f…
Browse files Browse the repository at this point in the history
…rom BeanResolver
  • Loading branch information
yrodiere committed Jul 13, 2020
1 parent e0808e7 commit 9da99d7
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 24 deletions.
Expand Up @@ -25,6 +25,7 @@
import org.hibernate.search.engine.environment.bean.BeanReference;
import org.hibernate.search.engine.environment.bean.BeanResolver;
import org.hibernate.search.engine.environment.thread.spi.ThreadProvider;
import org.hibernate.search.util.common.impl.SuppressingCloser;
import org.hibernate.search.util.common.logging.impl.LoggerFactory;

import org.apache.http.auth.AuthScope;
Expand All @@ -47,11 +48,20 @@ public class ElasticsearchClientFactoryImpl implements ElasticsearchClientFactor
private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() );

public static final BeanReference<ElasticsearchClientFactory> REFERENCE = (BeanResolver beanResolver) -> {
List<BeanReference<ElasticsearchHttpClientConfigurer>> httpClientConfigurerReferences =
beanResolver.allConfiguredForRole( ElasticsearchHttpClientConfigurer.class );
BeanHolder<List<ElasticsearchHttpClientConfigurer>> httpClientConfigurerHolders =
beanResolver.resolveRole( ElasticsearchHttpClientConfigurer.class );
ElasticsearchClientFactoryImpl factory = new ElasticsearchClientFactoryImpl( httpClientConfigurerHolders.get() );
return BeanHolder.<ElasticsearchClientFactory>of( factory )
.withDependencyAutoClosing( httpClientConfigurerHolders );
beanResolver.resolve( httpClientConfigurerReferences );
try {
ElasticsearchClientFactoryImpl factory = new ElasticsearchClientFactoryImpl(
httpClientConfigurerHolders.get() );
return BeanHolder.<ElasticsearchClientFactory>of( factory )
.withDependencyAutoClosing( httpClientConfigurerHolders );
}
catch (RuntimeException e) {
new SuppressingCloser( e ).push( httpClientConfigurerHolders );
throw e;
}
};

private static final ConfigurationProperty<List<String>> HOSTS =
Expand Down
Expand Up @@ -9,6 +9,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.hibernate.search.engine.environment.bean.spi.BeanProvider;
Expand All @@ -25,8 +26,9 @@
* Regardless of the underlying implementation, this interface is used to resolve beans,
* referenced either
* {@link #resolve(Class) by their type},
* or {@link #resolve(Class, String) by their type and name},
* or {@link #resolveRole(Class) by their role}.
* or {@link #resolve(Class, String) by their type and name}.
* <p>
* It also offers ways to {@link #allConfiguredForRole(Class) get references to configured beans of a given type}.
* <p>
* This interface is API,
* but should only be implemented by Hibernate Search itself;
Expand Down Expand Up @@ -105,18 +107,31 @@ default <T> BeanHolder<List<T>> resolve(List<? extends BeanReference<? extends T
}

/**
* Resolve the given role into a list of beans.
* Return all the bean references configured for the given role.
* <p>
* <strong>WARNING:</strong> this does not just return references to all the beans that implement {@code role}.
* Only beans registered during
* {@link org.hibernate.search.engine.environment.bean.spi.BeanConfigurer bean configuration}
* are taken into account.
*
* @param <T> The expected bean type.
* @param role The role that must have been assigned to the retrieved beans. Must be non-null and non-empty.
* @return A {@link List} of bean references, possibly empty.
*/
<T> List<BeanReference<T>> allConfiguredForRole(Class<T> role);

/**
* Return named bean references configured for the given role.
* <p>
* <strong>WARNING:</strong> this does not just return all the beans that implement {@code role}.
* <strong>WARNING:</strong> this does not just return references to all the beans that implement {@code role}.
* Only beans registered during
* {@link org.hibernate.search.engine.environment.bean.spi.BeanConfigurer bean configuration}
* are taken into account.
*
* @param <T> The expected bean type.
* @param role The role that must have been assigned to the retrieved beans. Must be non-null and non-empty.
* @return A {@link BeanHolder} containing a {@link List} containing the resolved beans.
* @throws SearchException if one of the references assigned to the role cannot be resolved.
* @return A {@link Map} from name to bean reference, possibly empty.
*/
<T> BeanHolder<List<T>> resolveRole(Class<T> role);
<T> Map<String, BeanReference<T>> namedConfiguredForRole(Class<T> role);

}
Expand Up @@ -7,8 +7,10 @@
package org.hibernate.search.engine.environment.bean.impl;

import java.util.List;
import java.util.Map;

import org.hibernate.search.engine.environment.bean.BeanHolder;
import org.hibernate.search.engine.environment.bean.BeanReference;
import org.hibernate.search.engine.environment.bean.BeanResolver;
import org.hibernate.search.engine.environment.bean.spi.BeanProvider;
import org.hibernate.search.util.common.AssertionFailure;
Expand Down Expand Up @@ -39,7 +41,12 @@ public <T> BeanHolder<T> resolve(Class<T> typeReference, String nameReference) {
}

@Override
public <T> BeanHolder<List<T>> resolveRole(Class<T> role) {
throw new AssertionFailure( "Unexpected call to resolveRole before roles are even defined." );
public <T> List<BeanReference<T>> allConfiguredForRole(Class<T> role) {
throw new AssertionFailure( "Unexpected call to allConfiguredForRole(...) before roles are even defined." );
}

@Override
public <T> Map<String, BeanReference<T>> namedConfiguredForRole(Class<T> role) {
throw new AssertionFailure( "Unexpected call to namedConfiguredForRole(...) before roles are even defined." );
}
}
Expand Up @@ -41,6 +41,10 @@ public final List<BeanReference<T>> all() {
return Collections.unmodifiableList( all );
}

public Map<String, BeanReference<T>> named() {
return Collections.unmodifiableMap( named );
}

public BeanReference<T> single() {
if ( all.size() == 1 ) {
return all.get( 0 );
Expand Down
Expand Up @@ -93,19 +93,23 @@ public <T> BeanHolder<T> resolve(Class<T> typeReference, String nameReference) {
}

@Override
public <T> BeanHolder<List<T>> resolveRole(Class<T> role) {
public <T> List<BeanReference<T>> allConfiguredForRole(Class<T> role) {
Contracts.assertNotNull( role, "role" );
BeanReferenceRegistryForType<T> registry = explicitlyConfiguredBeans( role );
if ( registry == null ) {
return BeanHolder.of( Collections.emptyList() );
return Collections.emptyList();
}
List<BeanReference<? extends T>> references = registry.all();
if ( references.isEmpty() ) {
return BeanHolder.of( Collections.emptyList() );
}
else {
return resolve( references );
return registry.all();
}

@Override
public <T> Map<String, BeanReference<T>> namedConfiguredForRole(Class<T> role) {
Contracts.assertNotNull( role, "role" );
BeanReferenceRegistryForType<T> registry = explicitlyConfiguredBeans( role );
if ( registry == null ) {
return Collections.emptyMap();
}
return registry.named();
}

/*
Expand Down
Expand Up @@ -416,22 +416,25 @@ public void resolveRole() {
expect( beanReference3Mock.resolve( EasyMock.anyObject() ) ).andReturn( beanHolder3 );
expect( beanReference4Mock.resolve( EasyMock.anyObject() ) ).andReturn( beanHolder4 );
replayAll();
BeanHolder<List<RoleType>> beansWithRole = beanResolver.resolveRole( RoleType.class );
List<BeanReference<RoleType>> beanReferencesWithRole = beanResolver.allConfiguredForRole( RoleType.class );
BeanHolder<List<RoleType>> beansWithRole = beanResolver.resolve( beanReferencesWithRole );
verifyAll();
assertThat( beansWithRole.get() )
.containsExactlyInAnyOrder( beanHolder1.get(), beanHolder2.get(), beanHolder3.get(), beanHolder4.get() );

// Roles should ignore inheritance
resetAll();
replayAll();
BeanHolder<List<Object>> beansWithObjectRole = beanResolver.resolveRole( Object.class );
List<BeanReference<Object>> beanReferencesWithObjectRole = beanResolver.allConfiguredForRole( Object.class );
BeanHolder<List<Object>> beansWithObjectRole = beanResolver.resolve( beanReferencesWithObjectRole );
verifyAll();
assertThat( beansWithObjectRole.get() ).isEmpty();

// Unassigned roles should result in an empty list
resetAll();
replayAll();
BeanHolder<List<NonRoleType>> beansWithNonRole = beanResolver.resolveRole( NonRoleType.class );
List<BeanReference<NonRoleType>> beanReferencesWithNonRole = beanResolver.allConfiguredForRole( NonRoleType.class );
BeanHolder<List<NonRoleType>> beansWithNonRole = beanResolver.resolve( beanReferencesWithNonRole );
verifyAll();
assertThat( beansWithNonRole.get() ).isEmpty();
}
Expand Down

0 comments on commit 9da99d7

Please sign in to comment.