com.sap.cloud.yaas.servicesdk.springboot.jersey.JerseyFeaturesAutoConfiguration Maven / Gradle / Ivy
/*
* © 2017 SAP SE or an SAP affiliate company.
* All rights reserved.
* Please see http://www.sap.com/corporate-en/legal/copyright/index.epx for additional trademark information and
* notices.
*/
package com.sap.cloud.yaas.servicesdk.springboot.jersey;
import com.sap.cloud.yaas.servicesdk.jerseysupport.mappers.ThrowableMapper;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;
import javax.ws.rs.Path;
import javax.ws.rs.core.Feature;
import javax.ws.rs.ext.ExceptionMapper;
import java.util.Map;
import java.util.Map.Entry;
/**
* Configures Jersey from the properties file, registers all {@link Feature}s and {@link ExceptionMapper}s.
*/
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass(ResourceConfig.class)
@ConditionalOnMissingBean(ResourceConfig.class)
@AutoConfigureAfter(JsonFeatureAutoConfiguration.class)
@AutoConfigureBefore(JerseyAutoConfiguration.class)
@EnableConfigurationProperties(JerseyServiceProperties.class)
@PropertySource("classpath:/com/sap/cloud/yaas/servicesdk/springboot/jersey/jersey-service-default.properties")
public class JerseyFeaturesAutoConfiguration
{
@Autowired
private JerseyServiceProperties properties;
/**
* Returns default Jersey {@link ResourceConfig}, that configures Jersey from the properties file, and registers
* all Jersey related features of Service SDK.
*
* @return the default {@link ResourceConfig}
*/
@Bean
public ResourceConfig jerseyResourceConfig()
{
return new JerseyResourceConfig();
}
/**
* Adds support to set the jersey properties.
*
* @param properties properties to use
*/
void setProperties(final JerseyServiceProperties properties)
{
this.properties = properties;
}
/**
* Registers Jersey exception mappers.
*/
@Configuration
@ConditionalOnClass(ThrowableMapper.class)
@ComponentScan(basePackageClasses = ThrowableMapper.class, useDefaultFilters = false, //
includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ExceptionMapper.class))
public static class JerseyExceptionMappers
{
/**
* Registers the {@link NotFoundExceptionPassThroughMapper}.
*
* @return the {@link NotFoundExceptionPassThroughMapper}
*/
@Bean
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "FILTER")
public ExceptionMapper> notFoundExceptionPassThroughMapper()
{
return new NotFoundExceptionPassThroughMapper();
}
/**
* Registers the {@link ResourceNotFoundExceptionMapper}.
*
* @return the {@link ResourceNotFoundExceptionMapper}
*/
@Bean
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "FILTER")
public ExceptionMapper> resourceNotFoundExceptionMapper()
{
return new ResourceNotFoundExceptionMapper();
}
}
private class JerseyResourceConfig extends ResourceConfig implements ApplicationContextAware, InitializingBean
{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
@Override
public void afterPropertiesSet()
{
configureJersey();
registerFeatures();
registerExceptionMappers();
registerResources();
}
private void configureJersey()
{
for (final Entry configProperty : properties.getConfig().entrySet())
{
property("jersey.config." + configProperty.getKey(), configProperty.getValue());
}
}
private void registerFeatures()
{
final Map features = applicationContext.getBeansOfType(Feature.class);
for (final Feature feature : features.values())
{
register(feature);
}
}
@SuppressWarnings("rawtypes")
private void registerExceptionMappers()
{
final Map exceptionMappers = applicationContext.getBeansOfType(ExceptionMapper.class);
for (final ExceptionMapper exceptionMapper : exceptionMappers.values())
{
register(exceptionMapper);
}
}
private void registerResources()
{
final Map resources = applicationContext.getBeansWithAnnotation(Path.class);
for (final Object resource : resources.values())
{
register(resource);
}
}
}
}