All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.blossomproject.autoconfigure.core.CommonAutoConfiguration Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
package com.blossomproject.autoconfigure.core;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.blossomproject.core.common.mapper.MapperPlugin;
import com.blossomproject.core.common.service.AssociationServicePlugin;
import com.blossomproject.core.common.service.ReadOnlyServicePlugin;
import com.blossomproject.core.common.utils.action_token.ActionTokenService;
import com.blossomproject.core.common.utils.action_token.ActionTokenServiceImpl;
import com.blossomproject.core.common.utils.privilege.Privilege;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.tika.Tika;
import org.elasticsearch.action.bulk.BulkProcessor;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
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.context.MessageSourceProperties;
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.plugin.core.config.EnablePluginRegistries;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.token.KeyBasedPersistenceTokenService;
import org.springframework.security.core.token.TokenService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;

/**
 * Created by Maël Gargadennnec on 04/05/2017.
 */
@Configuration
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@AutoConfigureBefore(ElasticsearchAutoConfiguration.class)
@EnablePluginRegistries({
  MapperPlugin.class, ReadOnlyServicePlugin.class, AssociationServicePlugin.class, Privilege.class})
@EnableJpaAuditing
@PropertySource({
  "classpath:/freemarker.properties",
  "classpath:/jpa.properties",
  "classpath:/languages.properties"})
@EnableTransactionManagement
public class CommonAutoConfiguration {

  private final static Logger logger = LoggerFactory.getLogger(CommonAutoConfiguration.class);

  @Bean
  public Set availableLocales(@Value("${blossom.languages}") String[] languages) {
    return Stream.of(languages).sequential().map(language -> Locale.forLanguageTag(language))
      .collect(Collectors.toCollection(LinkedHashSet::new));
  }

  @Bean
  @ConditionalOnMissingBean(TokenService.class)
  public KeyBasedPersistenceTokenService keyBasedPersistenceTokenService(
    SecureRandom secureRandom) {
    KeyBasedPersistenceTokenService keyBasedPersistenceTokenService = new KeyBasedPersistenceTokenService();
    keyBasedPersistenceTokenService.setServerInteger(secureRandom.nextInt());
    keyBasedPersistenceTokenService.setServerSecret(secureRandom.nextLong() + "");
    keyBasedPersistenceTokenService.setSecureRandom(secureRandom);

    return keyBasedPersistenceTokenService;
  }

  @Bean
  @ConditionalOnClass(ActionTokenService.class)
  public ActionTokenService defaultActionTokenService(
    TokenService tokenService) {
    return new ActionTokenServiceImpl(tokenService);
  }

  @Bean
  @ConditionalOnMissingBean(PasswordEncoder.class)
  public PasswordEncoder passwordEncoder(SecureRandom secureRandom) {
    return new BCryptPasswordEncoder(10, secureRandom);
  }

  @Bean
  @ConditionalOnMissingBean(BulkProcessor.class)
  public BulkProcessor bulkProcessor(Client client) {
    return BulkProcessor.builder(client, new BulkProcessor.Listener() {

      @Override
      public void beforeBulk(long executionId, BulkRequest request) {
        logger.info("Before bulk {} with {} actions to execute", executionId,
          request.numberOfActions());
      }

      @Override
      public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
        logger.error("Error on bulk {} with {} actions to execute", executionId,
          request.numberOfActions(), failure);
      }

      @Override
      public void afterBulk(long executionId, BulkRequest request, BulkResponse response) {
        logger.info("Successful bulk {} with {} actions executed in {} ms.", executionId,
          request.numberOfActions(), response.getTookInMillis());
      }
    })
      .setName("Blossom Bulk Processor")
      .setBulkActions(500)
      .setBulkSize(new ByteSizeValue(10, ByteSizeUnit.MB))
      .setFlushInterval(new TimeValue(30, TimeUnit.SECONDS))
      .build();
  }

  @Bean
  @ConfigurationProperties(prefix = "spring.messages")
  public MessageSourceProperties messageSourceProperties() {
    return new MessageSourceProperties();
  }

  @Bean
  @Primary
  public MessageSource messageSource( BlossomReloadableResourceBundleMessageSource parentMmessageSource) {
    MessageSourceProperties properties = messageSourceProperties();
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    if (StringUtils.hasText(properties.getBasename())) {
      messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
        StringUtils.trimAllWhitespace(properties.getBasename())));
    }
    if (properties.getEncoding() != null) {
      messageSource.setDefaultEncoding(properties.getEncoding().name());
    }
    messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
    Duration cacheDuration = properties.getCacheDuration();
    messageSource.setCacheSeconds(
      cacheDuration == null ? -1 : (int) cacheDuration.getSeconds());
    messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
    messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
    messageSource.setParentMessageSource(parentMmessageSource);
    return messageSource;
  }

  @Bean
  public BlossomReloadableResourceBundleMessageSource parentMmessageSource() throws IOException {
    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    Set resources = Lists
      .newArrayList(resolver.getResources("classpath*:/messages/*.properties")).stream()
      .filter(resource -> !resource.getFilename().contains("_"))
      .map(resource -> "classpath*:/messages/" + resource.getFilename().replace(".properties", ""))
      .collect(Collectors.toSet());

    logger.info("Found {} i18n files :\n{}", resources.size(), Joiner.on(",").join(resources));

    BlossomReloadableResourceBundleMessageSource messageSource = new BlossomReloadableResourceBundleMessageSource();
    messageSource.setBasenames(resources.toArray(new String[resources.size()]));
    messageSource.setFallbackToSystemLocale(false);
    messageSource.setCacheSeconds(3600);
    messageSource.setDefaultEncoding(Charset.forName("UTF-8").displayName());
    return messageSource;
  }

  @Bean
  public AuditorAware createAuditorProvider() {
    return new SecurityAuditor();
  }

  @Bean
  public AuditingEntityListener createAuditingListener() {
    return new AuditingEntityListener();
  }

  @Bean
  public Tika tika() {
    return new Tika();
  }

  public static class SecurityAuditor implements AuditorAware {

    @Override
    public Optional getCurrentAuditor() {
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();
      if (auth == null) {
        return Optional.of("anonymous");
      }
      String username = auth.getName();
      Optional switchUserAuthorities = auth.getAuthorities().stream().filter(a -> a instanceof SwitchUserGrantedAuthority).findAny();
      if(switchUserAuthorities.isPresent()){
        username = ((SwitchUserGrantedAuthority)switchUserAuthorities.get()).getSource().getName();
      }
      return Optional.of(username);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy