use of io.micronaut.context.exceptions.DisabledBeanException in project micronaut-core by micronaut-projects.
the class AbstractProviderDefinition method build.
@Override
public T build(BeanResolutionContext resolutionContext, BeanContext context, BeanDefinition<T> definition) throws BeanInstantiationException {
final BeanResolutionContext.Segment<?> segment = resolutionContext.getPath().currentSegment().orElse(null);
if (segment != null) {
final InjectionPoint<?> injectionPoint = segment.getInjectionPoint();
if (injectionPoint instanceof ArgumentCoercible) {
Argument<?> injectionPointArgument = ((ArgumentCoercible<?>) injectionPoint).asArgument();
Argument<?> resolveArgument = injectionPointArgument;
if (resolveArgument.isOptional()) {
resolveArgument = resolveArgument.getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT);
}
@SuppressWarnings("unchecked") Argument<Object> argument = (Argument<Object>) resolveArgument.getFirstTypeVariable().orElse(null);
if (argument != null) {
Qualifier<Object> qualifier = (Qualifier<Object>) resolutionContext.getCurrentQualifier();
if (qualifier == null && segment.getDeclaringType().isIterable()) {
final Object n = resolutionContext.getAttribute(Named.class.getName());
if (n != null) {
qualifier = Qualifiers.byName(n.toString());
}
}
boolean hasBean = context.containsBean(argument, qualifier);
if (hasBean) {
return buildProvider(resolutionContext, context, argument, qualifier, definition.isSingleton());
} else {
if (injectionPointArgument.isOptional()) {
return (T) Optional.empty();
} else if (injectionPointArgument.isNullable()) {
throw new DisabledBeanException("Nullable bean doesn't exist");
} else {
if (qualifier instanceof AnyQualifier || isAllowEmptyProviders(context)) {
return buildProvider(resolutionContext, context, argument, qualifier, definition.isSingleton());
} else {
throw new NoSuchBeanException(argument, qualifier);
}
}
}
}
}
}
throw new UnsupportedOperationException("Cannot inject provider for Object type");
}
use of io.micronaut.context.exceptions.DisabledBeanException in project micronaut-core by micronaut-projects.
the class ServiceHttpClientFactory method healthCheckStarter.
/**
* Creates a {@link ApplicationEventListener} that listens to {@link ServerStartupEvent} for each configured HTTP client
* in order to register a health check if necessary.
*
* @param configuration The configuration
* @param instanceList The instance list
* @return The event listener
*/
@EachBean(ServiceHttpClientConfiguration.class)
@Requires(condition = ServiceHttpClientCondition.class)
ApplicationEventListener<ServerStartupEvent> healthCheckStarter(@Parameter ServiceHttpClientConfiguration configuration, @Parameter StaticServiceInstanceList instanceList) {
if (configuration.isHealthCheck()) {
return event -> {
final List<URI> originalURLs = configuration.getUrls();
Collection<URI> loadBalancedURIs = instanceList.getLoadBalancedURIs();
final HttpClient httpClient = clientFactory.get().getClient(configuration.getHttpVersion(), configuration.getServiceId(), configuration.getPath().orElse(null));
final Duration initialDelay = configuration.getHealthCheckInterval();
Duration delay = configuration.getHealthCheckInterval();
taskScheduler.scheduleWithFixedDelay(initialDelay, delay, () -> Flux.fromIterable(originalURLs).flatMap(originalURI -> {
URI healthCheckURI = originalURI.resolve(configuration.getHealthCheckUri());
return Flux.from(httpClient.exchange(HttpRequest.GET(healthCheckURI))).onErrorResume(throwable -> {
if (throwable instanceof HttpClientResponseException) {
HttpClientResponseException responseException = (HttpClientResponseException) throwable;
return Flux.just((HttpResponse<ByteBuffer>) responseException.getResponse());
}
return Flux.just(HttpResponse.serverError());
}).map(response -> Collections.singletonMap(originalURI, response.getStatus()));
}).subscribe(uriToStatusMap -> {
Map.Entry<URI, HttpStatus> entry = uriToStatusMap.entrySet().iterator().next();
URI uri = entry.getKey();
HttpStatus status = entry.getValue();
if (status.getCode() >= 300) {
loadBalancedURIs.remove(uri);
} else if (!loadBalancedURIs.contains(uri)) {
loadBalancedURIs.add(uri);
}
}));
};
}
throw new DisabledBeanException("HTTP Client Health Check not enabled");
}
use of io.micronaut.context.exceptions.DisabledBeanException in project micronaut-core by micronaut-projects.
the class DefaultBeanContext method doCreateBean.
/**
* Execution the creation of a bean. The returned value can be null if a
* factory method returned null.
*
* @param resolutionContext The {@link BeanResolutionContext}
* @param beanDefinition The {@link BeanDefinition}
* @param qualifier The {@link Qualifier}
* @param qualifierBeanType The bean type used in the qualifier
* @param isSingleton Whether the bean is a singleton
* @param argumentValues Any argument values passed to create the bean
* @param <T> The bean generic type
* @return The created bean
*/
@Nullable
protected <T> T doCreateBean(@NonNull BeanResolutionContext resolutionContext, @NonNull BeanDefinition<T> beanDefinition, @Nullable Qualifier<T> qualifier, @Nullable Argument<T> qualifierBeanType, boolean isSingleton, @Nullable Map<String, Object> argumentValues) {
if (argumentValues == null) {
argumentValues = Collections.emptyMap();
}
Qualifier<T> declaredQualifier = beanDefinition.getDeclaredQualifier();
Class<T> beanType = beanDefinition.getBeanType();
if (isSingleton) {
BeanRegistration<T> beanRegistration = singletonObjects.get(new BeanKey<>(beanDefinition, declaredQualifier));
final Class<T> beanClass = qualifierBeanType.getType();
if (beanRegistration != null) {
if (qualifier == null || qualifier.reduce(beanClass, Stream.of(beanRegistration.beanDefinition)).findFirst().isPresent()) {
return beanRegistration.bean;
}
} else if (qualifier != null) {
beanRegistration = singletonObjects.get(new BeanKey<>(beanDefinition, null));
if (beanRegistration != null && qualifier.reduce(beanClass, Stream.of(beanRegistration.beanDefinition)).findFirst().isPresent()) {
return beanRegistration.bean;
}
}
}
T bean;
if (beanDefinition instanceof BeanFactory) {
BeanFactory<T> beanFactory = (BeanFactory<T>) beanDefinition;
try {
if (beanFactory instanceof ParametrizedBeanFactory) {
ParametrizedBeanFactory<T> parametrizedBeanFactory = (ParametrizedBeanFactory<T>) beanFactory;
Argument<?>[] requiredArguments = parametrizedBeanFactory.getRequiredArguments();
Map<String, Object> convertedValues = new LinkedHashMap<>(argumentValues);
for (Argument<?> requiredArgument : requiredArguments) {
String argumentName = requiredArgument.getName();
Object val = argumentValues.get(argumentName);
if (val == null && !requiredArgument.isDeclaredNullable()) {
throw new BeanInstantiationException(resolutionContext, "Missing bean argument [" + requiredArgument + "] for type: " + beanType.getName() + ". Required arguments: " + ArrayUtils.toString(requiredArguments));
}
Object convertedValue = null;
if (val != null) {
if (requiredArgument.getType().isInstance(val)) {
convertedValue = val;
} else {
convertedValue = ConversionService.SHARED.convert(val, requiredArgument).orElseThrow(() -> new BeanInstantiationException(resolutionContext, "Invalid bean argument [" + requiredArgument + "]. Cannot convert object [" + val + "] to required type: " + requiredArgument.getType()));
}
}
convertedValues.put(argumentName, convertedValue);
}
bean = parametrizedBeanFactory.build(resolutionContext, this, beanDefinition, convertedValues);
} else {
boolean propagateQualifier = beanDefinition.isProxy() && declaredQualifier instanceof Named;
if (propagateQualifier) {
resolutionContext.setAttribute(BeanDefinition.NAMED_ATTRIBUTE, ((Named) declaredQualifier).getName());
}
resolutionContext.setCurrentQualifier(declaredQualifier != null ? declaredQualifier : qualifier);
try {
bean = beanFactory.build(resolutionContext, this, beanDefinition);
} finally {
resolutionContext.setCurrentQualifier(null);
if (propagateQualifier) {
resolutionContext.removeAttribute(BeanDefinition.NAMED_ATTRIBUTE);
}
}
if (bean == null) {
throw new BeanInstantiationException(resolutionContext, "Bean Factory [" + beanFactory + "] returned null");
} else {
if (bean instanceof Qualified) {
((Qualified) bean).$withBeanQualifier(declaredQualifier);
}
}
}
} catch (Throwable e) {
if (e instanceof DependencyInjectionException) {
throw e;
}
if (e instanceof DisabledBeanException) {
throw e;
}
if (e instanceof BeanInstantiationException) {
throw e;
} else {
if (!resolutionContext.getPath().isEmpty()) {
throw new BeanInstantiationException(resolutionContext, e);
} else {
throw new BeanInstantiationException(beanDefinition, e);
}
}
}
} else {
ConstructorInjectionPoint<T> constructor = beanDefinition.getConstructor();
Argument<?>[] requiredConstructorArguments = constructor.getArguments();
if (requiredConstructorArguments.length == 0) {
bean = constructor.invoke();
} else {
Object[] constructorArgs = new Object[requiredConstructorArguments.length];
for (int i = 0; i < requiredConstructorArguments.length; i++) {
Class<?> argument = requiredConstructorArguments[i].getType();
constructorArgs[i] = getBean(resolutionContext, argument);
}
bean = constructor.invoke(constructorArgs);
}
inject(resolutionContext, null, bean);
}
if (bean != null) {
Qualifier<T> finalQualifier = qualifier != null ? qualifier : declaredQualifier;
if (!(bean instanceof BeanCreatedEventListener) && CollectionUtils.isNotEmpty(beanCreationEventListeners)) {
for (Map.Entry<Class, List<BeanCreatedEventListener>> entry : beanCreationEventListeners) {
if (entry.getKey().isAssignableFrom(beanType)) {
BeanKey<T> beanKey = new BeanKey<>(beanDefinition, finalQualifier);
for (BeanCreatedEventListener<?> listener : entry.getValue()) {
bean = (T) listener.onCreated(new BeanCreatedEvent(this, beanDefinition, beanKey, bean));
if (bean == null) {
throw new BeanInstantiationException(resolutionContext, "Listener [" + listener + "] returned null from onCreated event");
}
}
}
}
}
if (beanDefinition instanceof ValidatedBeanDefinition) {
bean = ((ValidatedBeanDefinition<T>) beanDefinition).validate(resolutionContext, bean);
}
if (LOG_LIFECYCLE.isDebugEnabled()) {
LOG_LIFECYCLE.debug("Created bean [{}] from definition [{}] with qualifier [{}]", bean, beanDefinition, finalQualifier);
}
}
return bean;
}
use of io.micronaut.context.exceptions.DisabledBeanException in project micronaut-core by micronaut-projects.
the class DefaultBeanContext method addCandidateToList.
private <T> void addCandidateToList(@Nullable BeanResolutionContext resolutionContext, Argument<T> beanType, BeanDefinition<T> candidate, Collection<BeanRegistration<T>> beansOfTypeList, Qualifier<T> qualifier, boolean singleCandidate) {
T bean = null;
final boolean isContainerType = candidate.isContainerType();
try {
if (candidate.isSingleton()) {
synchronized (singletonObjects) {
try (BeanResolutionContext context = newResolutionContext(candidate, resolutionContext)) {
if (candidate instanceof NoInjectionBeanDefinition) {
NoInjectionBeanDefinition noibd = (NoInjectionBeanDefinition) candidate;
final BeanKey key = new BeanKey(noibd.singletonClass, noibd.qualifier);
final BeanRegistration beanRegistration = singletonObjects.get(key);
if (beanRegistration != null) {
bean = (T) beanRegistration.bean;
} else {
throw new IllegalStateException("Singleton not present for key: " + key);
}
} else {
bean = doCreateBean(context, candidate, qualifier, beanType, true, null);
if (candidate.getBeanType() != beanType.getType() && isContainerType) {
registerSingletonBean(candidate, candidate.asArgument(), bean, qualifier, singleCandidate, context.getAndResetDependentBeans());
} else {
registerSingletonBean(candidate, beanType, bean, qualifier, singleCandidate, context.getAndResetDependentBeans());
}
}
}
}
} else {
try (BeanResolutionContext context = newResolutionContext(candidate, resolutionContext)) {
bean = getScopedBeanForDefinition(context, candidate.asArgument(), qualifier, true, candidate);
}
}
} catch (DisabledBeanException e) {
if (AbstractBeanContextConditional.LOG.isDebugEnabled()) {
AbstractBeanContextConditional.LOG.debug("Bean of type [{}] disabled for reason: {}", beanType.getTypeName(), e.getMessage());
}
}
if (bean != null) {
if (isContainerType && bean instanceof Iterable) {
Iterable<Object> iterable = (Iterable<Object>) bean;
int i = 0;
for (Object o : iterable) {
if (o == null || !beanType.isInstance(o)) {
continue;
}
beansOfTypeList.add(new BeanRegistration(new BeanKey(beanType, Qualifiers.byQualifiers(Qualifiers.byName(String.valueOf(i++)), qualifier)), candidate, o));
}
} else {
beansOfTypeList.add(new BeanRegistration(new BeanKey(beanType, candidate.getDeclaredQualifier()), candidate, bean));
}
}
}
use of io.micronaut.context.exceptions.DisabledBeanException in project micronaut-core by micronaut-projects.
the class DefaultBeanContext method initializeContext.
/**
* Initialize the context with the given {@link io.micronaut.context.annotation.Context} scope beans.
*
* @param contextScopeBeans The context scope beans
* @param processedBeans The beans that require {@link ExecutableMethodProcessor} handling
* @param parallelBeans The parallel bean definitions
*/
protected void initializeContext(@NonNull List<BeanDefinitionReference> contextScopeBeans, @NonNull List<BeanDefinitionReference> processedBeans, @NonNull List<BeanDefinitionReference> parallelBeans) {
if (CollectionUtils.isNotEmpty(contextScopeBeans)) {
final Collection<BeanDefinition> contextBeans = new ArrayList<>(contextScopeBeans.size());
for (BeanDefinitionReference contextScopeBean : contextScopeBeans) {
try {
loadContextScopeBean(contextScopeBean, contextBeans::add);
} catch (Throwable e) {
throw new BeanInstantiationException("Bean definition [" + contextScopeBean.getName() + "] could not be loaded: " + e.getMessage(), e);
}
}
filterProxiedTypes((Collection) contextBeans, true, false, null);
filterReplacedBeans(null, (Collection) contextBeans);
for (BeanDefinition contextScopeDefinition : contextBeans) {
try {
loadContextScopeBean(contextScopeDefinition);
} catch (DisabledBeanException e) {
if (AbstractBeanContextConditional.LOG.isDebugEnabled()) {
AbstractBeanContextConditional.LOG.debug("Bean of type [{}] disabled for reason: {}", contextScopeDefinition.getBeanType().getSimpleName(), e.getMessage());
}
} catch (Throwable e) {
throw new BeanInstantiationException("Bean definition [" + contextScopeDefinition.getName() + "] could not be loaded: " + e.getMessage(), e);
}
}
}
if (!processedBeans.isEmpty()) {
@SuppressWarnings("unchecked") Stream<BeanDefinitionMethodReference<?, ?>> methodStream = processedBeans.stream().filter(ref -> ref.isEnabled(this)).map((Function<BeanDefinitionReference, BeanDefinition<?>>) reference -> {
try {
return reference.load(this);
} catch (Exception e) {
throw new BeanInstantiationException("Bean definition [" + reference.getName() + "] could not be loaded: " + e.getMessage(), e);
}
}).filter(bean -> bean.isEnabled(this)).flatMap(beanDefinition -> beanDefinition.getExecutableMethods().parallelStream().filter(method -> method.hasStereotype(Executable.class)).map((Function<ExecutableMethod<?, ?>, BeanDefinitionMethodReference<?, ?>>) executableMethod -> BeanDefinitionMethodReference.of((BeanDefinition) beanDefinition, executableMethod)));
// group the method references by annotation type such that we have a map of Annotation -> MethodReference
// ie. Class<Scheduled> -> @Scheduled void someAnnotation()
Map<Class<? extends Annotation>, List<BeanDefinitionMethodReference<?, ?>>> byAnnotation = new HashMap<>(processedBeans.size());
methodStream.forEach(reference -> {
List<Class<? extends Annotation>> annotations = reference.getAnnotationTypesByStereotype(Executable.class);
annotations.forEach(annotation -> byAnnotation.compute(annotation, (ann, list) -> {
if (list == null) {
list = new ArrayList<>(10);
}
list.add(reference);
return list;
}));
});
// Find ExecutableMethodProcessor for each annotation and process the BeanDefinitionMethodReference
byAnnotation.forEach((annotationType, methods) -> streamOfType(ExecutableMethodProcessor.class, Qualifiers.byTypeArguments(annotationType)).forEach(processor -> {
if (processor instanceof LifeCycle<?>) {
((LifeCycle<?>) processor).start();
}
for (BeanDefinitionMethodReference<?, ?> method : methods) {
BeanDefinition<?> beanDefinition = method.getBeanDefinition();
// If declared at the class level it will already have been processed by AnnotationProcessorListener
if (!beanDefinition.hasStereotype(annotationType)) {
// noinspection unchecked
if (method.hasDeclaredStereotype(Parallel.class)) {
ForkJoinPool.commonPool().execute(() -> {
try {
processor.process(beanDefinition, method);
} catch (Throwable e) {
if (LOG.isErrorEnabled()) {
LOG.error("Error processing bean method " + beanDefinition + "." + method + " with processor (" + processor + "): " + e.getMessage(), e);
}
Boolean shutdownOnError = method.booleanValue(Parallel.class, "shutdownOnError").orElse(true);
if (shutdownOnError) {
stop();
}
}
});
} else {
processor.process(beanDefinition, method);
}
}
}
if (processor instanceof LifeCycle<?>) {
((LifeCycle<?>) processor).stop();
}
}));
}
if (CollectionUtils.isNotEmpty(parallelBeans)) {
processParallelBeans(parallelBeans);
}
final Runnable runnable = () -> beanDefinitionsClasses.removeIf((BeanDefinitionReference beanDefinitionReference) -> !beanDefinitionReference.isEnabled(this));
ForkJoinPool.commonPool().execute(runnable);
}
Aggregations