package org.alien4cloud.bootstrap;

import java.io.IOException;
import java.net.Authenticator;
import java.net.PasswordAuthentication;

import javax.servlet.MultipartConfigElement;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.filter.CommonsRequestLoggingFilter;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;

import alien4cloud.servlet.ImageServlet;
import alien4cloud.utils.AlienYamlPropertiesFactoryBeanFactory;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration("bootstrap-config")
@EnableAutoConfiguration(exclude = { HypermediaAutoConfiguration.class })
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackages = { "org.alien4cloud.bootstrap", "alien4cloud.audit", "alien4cloud.security", "alien4cloud.webconfiguration",
        "org.alien4cloud.exception", "org.elasticsearch.mapping", "alien4cloud.dao", "alien4cloud.servlet", "alien4cloud.images", "alien4cloud.metaproperty" })
public class Bootstrap {

    /**
     * Alien 4 cloud standalone entry point.
     *
     * @param args Arguments that will be delegated to spring.
     */
    public static void main(String[] args) {
        configure();
        initializeProxyAuthenticator();
        SpringApplication.run(Bootstrap.class, args);
    }

    public static void initializeProxyAuthenticator() {
        final String proxyUser = System.getProperty("http.proxyUser");
        final String proxyPassword = System.getProperty("http.proxyPassword");

        if (proxyUser != null && proxyPassword != null) {
            log.debug("Set http proxy credentials (" + proxyUser + ")");
            Authenticator.setDefault(new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray());
                }
            });
        }
    }

    public static void configure() {
        System.setProperty("security.basic.enabled", "false");
        System.setProperty("management.contextPath", "/rest/admin");
        System.setProperty("spring.config.name", AlienYamlPropertiesFactoryBeanFactory.ALIEN_CONFIGURATION);
    }

    @Bean(name = { "alienconfig", "elasticsearchConfig" })
    public static YamlPropertiesFactoryBean alienConfig(ResourceLoader resourceLoader) throws IOException {
        return AlienYamlPropertiesFactoryBeanFactory.get(resourceLoader);
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        // this to avoid errors when properties are not resolvable
        // beans should use default value syntax to verify that the property exists
        // @Value("${some.key:#{null}}")
        configurer.setIgnoreUnresolvablePlaceholders(true);
        return configurer;
    }

    @Bean
    public MultipartConfigElement multipartConfigElement(@Value("${upload.max_archive_size}") long maxUploadSize) {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxRequestSize(maxUploadSize);
        factory.setMaxFileSize(maxUploadSize);
        return factory.createMultipartConfig();
    }

    @Bean
    public StandardServletMultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

    @Bean
    public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet, MultipartConfigElement multipartConfig) {
        ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
        registration.addUrlMappings("/*");
        registration.setMultipartConfig(multipartConfig);
        registration.setAsyncSupported(true);
        return registration;
    }

    @Bean
    public ServletRegistrationBean imageRegistration(ImageServlet imageServlet) {
        ServletRegistrationBean registration = new ServletRegistrationBean(imageServlet);
        registration.addUrlMappings("/img/*");
        return registration;
    }
    
    @Bean
    public CommonsRequestLoggingFilter requestLoggingFilter() {
        CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
        loggingFilter.setIncludeClientInfo(true);
        loggingFilter.setIncludeQueryString(true);
        loggingFilter.setIncludePayload(true);
        loggingFilter.setMaxPayloadLength(64000);
        return loggingFilter;
    }

}

@@ -4974,13 +4974,135 @@
   %7D%0A
+%0A//
     
-%0A
+/**%0A//     * Activate debug level on org.springframework.web.filter.CommonsRequestLoggingFilter to use this%0A//     */%0A//
     
@@ -5099,32 +5099,34 @@
  */%0A//    @Bean%0A
+//
     public Commo
@@ -5169,24 +5169,26 @@
 gFilter() %7B%0A
+//
         Comm
@@ -5258,24 +5258,26 @@
 ngFilter();%0A
+//
         logg
@@ -5306,32 +5306,34 @@
 ientInfo(true);%0A
+//
         loggingF
@@ -5359,32 +5359,34 @@
 ryString(true);%0A
+//
         loggingF
@@ -5408,32 +5408,34 @@
 ePayload(true);%0A
+//
         loggingF
@@ -5468,16 +5468,18 @@
 64000);%0A
+//
         
@@ -5496,21 +5496,23 @@
 gingFilter;%0A
+//
     %7D%0A%0A%7D%0A

Comment CommonsRequestLoggingFilter