diff options
Diffstat (limited to 'connector/src/main')
23 files changed, 821 insertions, 743 deletions
| diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java index 6e8e06ef..40ed283b 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java @@ -32,11 +32,15 @@ public class MsSpecificEidasNodeSpringResourceProvider implements SpringResource    @Override    public Resource[] getResourcesToLoad() { -    final ClassPathResource msEidasNode = new ClassPathResource("/specific_eIDAS_connector.beans.xml", -        MsSpecificEidasNodeSpringResourceProvider.class); +    final ClassPathResource generic = +        new ClassPathResource("/applicationContext.xml", MsSpecificEidasNodeSpringResourceProvider.class); +     +    final ClassPathResource msEidasNode = new ClassPathResource( +        "/specific_eIDAS_connector.beans.xml", MsSpecificEidasNodeSpringResourceProvider.class); +          final ClassPathResource msEidasNodeStorage = new ClassPathResource(          "/specific_eIDAS_connector.storage.beans.xml", MsSpecificEidasNodeSpringResourceProvider.class); -    return new Resource[] { msEidasNode, msEidasNodeStorage }; +    return new Resource[] { generic, msEidasNode, msEidasNodeStorage };    }    @Override diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificSpringBootApplicationContextInitializer.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificSpringBootApplicationContextInitializer.java new file mode 100644 index 00000000..399d1286 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificSpringBootApplicationContextInitializer.java @@ -0,0 +1,82 @@ +package at.asitplus.eidas.specific.connector; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertiesPropertySource; + +import at.gv.egiz.components.spring.api.SpringBootApplicationContextInitializer; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MsSpecificSpringBootApplicationContextInitializer extends +    SpringBootApplicationContextInitializer { + +  private static final String SYSTEMD_PROP_NAME = "eidas.ms.configuration"; +  private static final String PATH_FILE_PREFIX = "file:"; +   +  @Override +  public void initialize(ConfigurableApplicationContext applicationContext) {     +    String configPath = System.getProperty(SYSTEMD_PROP_NAME); +    if (StringUtils.isNotEmpty(configPath)) { +      log.debug("Find configuration-source from SystemD Property: '{}' ...", SYSTEMD_PROP_NAME);       +      if (configPath.startsWith(PATH_FILE_PREFIX)) { +        configPath = configPath.substring(PATH_FILE_PREFIX.length()); +         +      }       +      injectConfiguration(configPath, applicationContext);             + +    } else { +      log.info("Find NO SystemD Property: '{}' Maybe no configuration available", SYSTEMD_PROP_NAME); +       +    } +     +    super.initialize(applicationContext); +         +  } +   +  private void injectConfiguration(String configPath, ConfigurableApplicationContext applicationContext) { +    InputStream is = null; +    try { +      Path path = Paths.get(configPath); +      if (Files.exists(path)) { +        File file = new File(configPath);              +        Properties props = new Properties(); +        is = new FileInputStream(file); +        props.load(is);       +        MutablePropertySources sources = applicationContext.getEnvironment().getPropertySources();        +        sources.addFirst(new PropertiesPropertySource(SYSTEMD_PROP_NAME, props)); +        log.info("Set configuration-source from SystemD-Property: {}", SYSTEMD_PROP_NAME); +       +      } else { +        log.error("Configuration from SystemD Property: '{}' at Location: {} DOES NOT exist",  +            SYSTEMD_PROP_NAME, configPath); +         +      } +       +    } catch (IOException e) { +      log.error("Configuration from SystemD Property: '{}' at Location: {} CAN NOT be loaded",  +          SYSTEMD_PROP_NAME, configPath, e); +       +    } finally { +      try { +        if (is != null) { +          is.close(); +           +        }         +      } catch (IOException e) { +        log.error("Can not close InputStream of configLoader: {}", configPath, e); +         +      } +    }         +  } +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringBootApplicationInitializer.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringBootApplicationInitializer.java new file mode 100644 index 00000000..428f5f56 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringBootApplicationInitializer.java @@ -0,0 +1,105 @@ +package at.asitplus.eidas.specific.connector; + +import org.opensaml.core.config.InitializationException; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.web.context.WebApplicationContext; + +import at.gv.egiz.eaaf.core.api.IStatusMessenger; +import at.gv.egiz.eaaf.core.impl.logging.LogMessageProviderFactory; +import at.gv.egiz.eaaf.core.impl.logging.SimpleStatusMessager; +import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; +import lombok.extern.slf4j.Slf4j; +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; + +@Slf4j +@SpringBootApplication(scanBasePackages = { +    "at.asitplus.eidas.specific.connector",  +    "at.gv.egiz.eaaf.utils.springboot.ajp" +    }) +public class SpringBootApplicationInitializer extends SpringBootServletInitializer { + +  private static ConfigurableApplicationContext ctx; + +  /** +   * Starts MS-specific eIDAS-Implementation SpringBoot application. +   * +   * @param args Starting parameters +   * @throws Throwable In case of a start-up error +   */ +  public static void main(final String[] args) throws Throwable { +    try { +      log.info("=============== Initializing Spring-Boot context! ==============="); +      LogMessageProviderFactory.setStatusMessager(new SimpleStatusMessager()); +      final SpringApplication springApp = +          new SpringApplication(SpringBootApplicationInitializer.class); +      springApp.addInitializers(new MsSpecificSpringBootApplicationContextInitializer()); + +      log.info("Bootstrap openSAML .... "); +      EaafOpenSaml3xInitializer.eaafInitialize(); +       +      log.debug("Run SpringBoot initialization process ... "); +      ctx = springApp.run(args); + +      // initialize status messenger +      LogMessageProviderFactory.setStatusMessager(ctx.getBean(IStatusMessenger.class)); +       +      log.info("Initialization of MS-specific eIDAS-Implementation finished."); + +    } catch (final Throwable e) { +      log.error("MS-specific eIDAS-Implementation initialization FAILED!", e); +      throw e; + +    } + +  } + +   +  protected SpringApplicationBuilder createSpringApplicationBuilder() {     +    try { +      log.info("Bootstrap openSAML .... "); +      EaafOpenSaml3xInitializer.eaafInitialize(); +            +    } catch (InitializationException | ComponentInitializationException e) { +      throw new RuntimeException(e); +       +    } +     +    SpringApplicationBuilder builder = new SpringApplicationBuilder(); +    builder.initializers(new MsSpecificSpringBootApplicationContextInitializer());     +    return builder; +     +  } +   +  protected WebApplicationContext run(SpringApplication application) { +    WebApplicationContext internalContext = (WebApplicationContext) application.run(); +    +    // initialize status messenger +    LogMessageProviderFactory.setStatusMessager(internalContext.getBean(IStatusMessenger.class)); +    +    log.info("Initialization of MS-specific eIDAS-Implementation finished."); +     +    return internalContext; +  } +   +  /** +   * Stops SpringBoot application of MS-specific eIDAS-Implementation. +   *  +   */ +  public static void exit() { +    if (ctx != null) { +      log.info("Stopping SpringBoot application ... "); +      SpringApplication.exit(ctx, () -> 0); +      ctx = null; +       +    } else { +      log.info("No SpringBoot context. Nothing todo"); +       +    } + +  } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringContextCloseHandler.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringContextCloseHandler.java new file mode 100644 index 00000000..e884b5c6 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringContextCloseHandler.java @@ -0,0 +1,170 @@ +package at.asitplus.eidas.specific.connector; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; + +import at.gv.egiz.components.spring.api.IDestroyableObject; +import eu.eidas.auth.cache.IgniteInstanceInitializerSpecificCommunication; + +/** + * SpringContext CloseHandler. + * + * @author tlenz + * + */ + +public class SpringContextCloseHandler +    implements ApplicationListener<ContextClosedEvent>, ApplicationContextAware, BeanPostProcessor { + +  private static final Logger log = +      org.slf4j.LoggerFactory.getLogger(SpringContextCloseHandler.class); + +  private ApplicationContext context; + +  /* +   * (non-Javadoc) +   * +   * @see org.springframework.context.ApplicationListener#onApplicationEvent(org. +   * springframework.context. ApplicationEvent) +   */ +  @Override +  @EventListener +  public void onApplicationEvent(final ContextClosedEvent arg0) { +    log.info("MS-specific eIDAS-Node shutdown process started ..."); + +    try { +      log.debug("CleanUp objects with implements the IDestroyable interface ... "); +      final Map<String, IDestroyableObject> objectsToDestroy = +          context.getBeansOfType(IDestroyableObject.class); +      internalIDestroyableObject(objectsToDestroy); +      log.info("Object cleanUp complete"); + +      log.debug("Stopping Spring Thread-Pools ... "); +      // shut-down task schedulers +      final Map<String, ThreadPoolTaskScheduler> schedulers = +          context.getBeansOfType(ThreadPoolTaskScheduler.class); +      internalThreadPoolTaskScheduler(schedulers); + +      // shut-down task executors +      final Map<String, ThreadPoolTaskExecutor> executers = +          context.getBeansOfType(ThreadPoolTaskExecutor.class); +      internalThreadPoolTaskExecutor(executers); +      log.debug("Spring Thread-Pools stopped"); +       +       +      //clean-up eIDAS node +      Map<String, IgniteInstanceInitializerSpecificCommunication> nodeIgnite =  +          context.getBeansOfType(IgniteInstanceInitializerSpecificCommunication.class); +      log.info("Find #{} Apache Ignite instances from eIDAS Ref. impl.", nodeIgnite.size()); +      for (Entry<String, IgniteInstanceInitializerSpecificCommunication> el : nodeIgnite.entrySet()) { +        if (el.getValue().getInstance() != null) { +          el.getValue().getInstance().close(); +          el.getValue().destroyInstance(); +          log.debug("Shutdown Apache-Ignite: {}", el.getKey()); +           +        }         +      } +             +      log.info("MS-specific eIDAS-Node shutdown process finished"); + +    } catch (final Exception e) { +      log.warn("MS-specific eIDAS-Node shutdown process has an error.", e); + +    } + +  } + +  /* +   * (non-Javadoc) +   * +   * @see org.springframework.beans.factory.config.BeanPostProcessor# +   * postProcessAfterInitialization(java. lang.Object, java.lang.String) +   */ +  @Override +  public Object postProcessAfterInitialization(final Object arg0, final String arg1) +      throws BeansException { +    if (arg0 instanceof ThreadPoolTaskScheduler) { +      ((ThreadPoolTaskScheduler) arg0).setWaitForTasksToCompleteOnShutdown(true); +    } +    if (arg0 instanceof ThreadPoolTaskExecutor) { +      ((ThreadPoolTaskExecutor) arg0).setWaitForTasksToCompleteOnShutdown(true); +    } +    return arg0; + +  } + +  /* +   * (non-Javadoc) +   * +   * @see org.springframework.beans.factory.config.BeanPostProcessor# +   * postProcessBeforeInitialization(java .lang.Object, java.lang.String) +   */ +  @Override +  public Object postProcessBeforeInitialization(final Object arg0, final String arg1) +      throws BeansException { +    return arg0; + +  } + +  /* +   * (non-Javadoc) +   * +   * @see +   * org.springframework.context.ApplicationContextAware#setApplicationContext(org +   * .springframework. context.ApplicationContext) +   */ +  @Override +  public void setApplicationContext(final ApplicationContext arg0) throws BeansException { +    this.context = arg0; + +  } + +  private void internalThreadPoolTaskExecutor(final Map<String, ThreadPoolTaskExecutor> executers) { +    for (final ThreadPoolTaskExecutor executor : executers.values()) { +      executor.shutdown(); +      log.debug("Executer {} with active {} work has killed", executor.getThreadNamePrefix(), +          executor.getActiveCount()); + +    } + +  } + +  // Not required at the moment +  private void internalThreadPoolTaskScheduler( +      final Map<String, ThreadPoolTaskScheduler> schedulers) { +    log.trace("Stopping #{} task-schedulers", schedulers.size()); +     +  } + +  private void internalIDestroyableObject(final Map<String, IDestroyableObject> objectsToDestroy) { +    if (objectsToDestroy != null) { +      final Iterator<Entry<String, IDestroyableObject>> interator = +          objectsToDestroy.entrySet().iterator(); +      while (interator.hasNext()) { +        final Entry<String, IDestroyableObject> object = interator.next(); +        try { +          object.getValue().fullyDestroy(); +          log.debug("Object with ID: {} is destroyed", object.getKey()); + +        } catch (final Exception e) { +          log.warn("Destroing object with ID: {} FAILED!", object.getKey(), null, e); + +        } +      } +    } + +  } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringInitializer.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringInitializer.java deleted file mode 100644 index 417828a6..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringInitializer.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. -*/ - -package at.asitplus.eidas.specific.connector; - -import java.util.Arrays; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.io.ClassPathResource; -import org.springframework.web.WebApplicationInitializer; -import org.springframework.web.context.ContextLoaderListener; -import org.springframework.web.context.request.RequestContextListener; -import org.springframework.web.context.support.GenericWebApplicationContext; -import org.springframework.web.context.support.ServletContextResource; -import org.springframework.web.servlet.DispatcherServlet; - -import at.gv.egiz.components.spring.api.SpringLoader; -import at.gv.egiz.eaaf.core.api.IStatusMessenger; -import at.gv.egiz.eaaf.core.impl.logging.LogMessageProviderFactory; -import at.gv.egiz.eaaf.core.impl.utils.Random; -import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; - -/** - * Web application initializer. - * - * @author Thomas Lenz - */ -public class SpringInitializer implements WebApplicationInitializer { - -  private static final Logger log = LoggerFactory.getLogger(SpringInitializer.class); - -  private String[] rootServletContexts = null; -  private String[] servletContexts = null; - -  /** -   * Application specific Spring initializer. -   *   -   */ -  public SpringInitializer() { -    this.rootServletContexts = null; -    this.servletContexts = new String[] { -        "/applicationContext.xml", - -    }; -  } - -  /* -   * (non-Javadoc) -   *  -   * @see -   * org.springframework.web.WebApplicationInitializer#onStartup(javax.servlet. -   * ServletContext) -   */ -  @Override -  public void onStartup(ServletContext servletContext) throws ServletException { -    try { -      log.info("=============== Loading Config Root Context! ==============="); -      final ApplicationContext cfgRootContext = -          new ClassPathXmlApplicationContext(new String[] { -              "/applicationContext.xml" -          }); - -      log.info("=============== Loading Root Context! ==============="); -      final GenericWebApplicationContext rootContext = new GenericWebApplicationContext(); -      rootContext.setServletContext(servletContext); -      rootContext.setParent(cfgRootContext); - -      log.info("Spring-context was initialized with active profiles: {}",  -          Arrays.asList(rootContext.getEnvironment().getActiveProfiles())); - -      log.info("=============== Loading Local Contexts! ==============="); -      final XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader( -          rootContext); -      if (rootServletContexts != null) { -        for (final String rootServletContext : rootServletContexts) { -          log.debug("Loading: " + rootServletContext); -          xmlReader.loadBeanDefinitions(new ServletContextResource( -              servletContext, rootServletContext)); -        } -      } -      // Manage the lifecycle of the root application context -      servletContext.addListener(new ContextLoaderListener(rootContext)); - -      // log.debug("Beans after logAMQP in {}", rootContext); -      // dumpBeanDefinitions(rootContext); - -      log.info("=============== Loading SPI Context! ==============="); -      log.debug("Loading modules and components"); -      SpringLoader.loadSpringServices(rootContext); - -      log.trace("Beans after SPI in " + rootContext); -      dumpBeanDefinitions(rootContext); - -      log.debug("Loading servlet config in " + rootContext); -      if (servletContexts != null) { -        for (final String servletContextString : servletContexts) { -          xmlReader.loadBeanDefinitions(new ClassPathResource(servletContextString, SpringInitializer.class)); -        } - -      } - -      log.debug("Refreshing context " + rootContext); -      rootContext.refresh(); - -      log.info("=============== Register Dispatcher Servlet! ==============="); - -      log.trace("Final Beans in " + rootContext); -      dumpBeanDefinitions(rootContext); - -      log.info("Registering dispatcher configuration"); -      final ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", -          new DispatcherServlet(rootContext)); -      if (dispatcher != null) { -        dispatcher.setLoadOnStartup(1); -        dispatcher.addMapping("/"); -        dispatcher.setAsyncSupported(true); - -      } else { -        log.error("Failed to register dispatcher server in servlet context!"); -      } - -      log.info("=============== Register RequestContextListener! ==============="); -      servletContext.addListener(new RequestContextListener()); - -      // initialize status messenger -      LogMessageProviderFactory.setStatusMessager(rootContext.getBean(IStatusMessenger.class)); - -      log.info("Bootstrap openSAML .... "); -      EaafOpenSaml3xInitializer.eaafInitialize(); - -      log.info("Seed random number generator ... "); -      Random.seedRandom(); - -      log.info("Initialization of MS-specific eIDAS-connector finished."); - -    } catch (final Throwable e) { -      log.error("MS-specific eIDAS-connector initialization FAILED!", e); - -    } - -  } - -  private void dumpBeanDefinitions(GenericApplicationContext context) { -    log.trace("Registered Bean in context " + context.toString()); - -    final String[] registeredBeans = context.getBeanDefinitionNames(); -    for (final String registeredBean : registeredBeans) { -      final BeanDefinition beanDefinition = context -          .getBeanDefinition(registeredBean); -      log.trace(registeredBean + " -> " + beanDefinition.getBeanClassName()); - -    } - -    log.trace("Registered Bean in context --" + context); -  } -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/attributes/AuthBlockAttributeBuilder.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/attributes/AuthBlockAttributeBuilder.java index be9f8862..1833f377 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/attributes/AuthBlockAttributeBuilder.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/attributes/AuthBlockAttributeBuilder.java @@ -22,6 +22,9 @@ package at.asitplus.eidas.specific.connector.attributes;  import static at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.EID_AUTHBLOCK_SIGNED_FRIENDLY_NAME;  import static at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions.EID_AUTHBLOCK_SIGNED_NAME; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +  import org.apache.commons.lang3.StringUtils;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; @@ -48,7 +51,8 @@ public class AuthBlockAttributeBuilder implements IPvpAttributeBuilder {      String authBlock = authData.getGenericData(Constants.SZR_AUTHBLOCK, String.class);      if (StringUtils.isNotEmpty(authBlock)) { -      return g.buildStringAttribute(EID_AUTHBLOCK_SIGNED_FRIENDLY_NAME, EID_AUTHBLOCK_SIGNED_NAME, authBlock); +      return g.buildStringAttribute(EID_AUTHBLOCK_SIGNED_FRIENDLY_NAME, EID_AUTHBLOCK_SIGNED_NAME,  +          Base64.getEncoder().encodeToString(authBlock.getBytes(StandardCharsets.UTF_8)));      } else {        throw new UnavailableAttributeException(EID_AUTHBLOCK_SIGNED_NAME); diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java index 2a10031b..a1e953f1 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java @@ -24,6 +24,7 @@  package at.asitplus.eidas.specific.connector.config;  import java.net.MalformedURLException; +import java.util.List;  import org.apache.commons.lang3.StringUtils;  import org.slf4j.Logger; @@ -35,11 +36,11 @@ import org.springframework.context.support.ReloadableResourceBundleMessageSource  import org.springframework.web.servlet.config.annotation.EnableWebMvc;  import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;  import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.i18n.CookieLocaleResolver;  import org.thymeleaf.templateresolver.FileTemplateResolver;  import at.asitplus.eidas.specific.connector.MsEidasNodeConstants;  import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation;  import at.gv.egiz.eaaf.core.impl.utils.FileUtils;  /** @@ -90,43 +91,63 @@ public class StaticResourceConfiguration implements WebMvcConfigurer {    }    /** -   * Internal i18n message source. -   *  +   * Get a message source with only internal message properties. +   * +   * @param ressourceLocations List of source-locations     * @return     */    @Bean -  public ReloadableResourceBundleMessageSource internalMessageSource() { -    final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); +  public ReloadableResourceBundleMessageSource internalMessageSource( +      @Autowired(required = false) final List<IMessageSourceLocation> ressourceLocations) { +    final ReloadableResourceBundleMessageSource messageSource = +        new ReloadableResourceBundleMessageSource();      // add default message source      messageSource.setBasename(DEFAULT_MESSAGE_SOURCE); + +    if (ressourceLocations != null) { +      // load more message sources +      for (final IMessageSourceLocation el : ressourceLocations) { +        if (el.getMessageSourceLocation() != null) { +          for (final String source : el.getMessageSourceLocation()) { +            messageSource.addBasenames(source); +            log.debug("Add additional messageSources: {}", el.getMessageSourceLocation().toArray()); + +          } +        } +      } +    } +      messageSource.setDefaultEncoding("UTF-8");      return messageSource;    }    /** -   * External i18n message source. -   *  +   * Get full message source with internal and external message-properties files. +   * +   * @param ressourceLocations List of source-locations     * @return     */    @Bean -  public ReloadableResourceBundleMessageSource messageSource() { -    final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); +  public ReloadableResourceBundleMessageSource messageSource( +      @Autowired(required = false) final List<IMessageSourceLocation> ressourceLocations) { +    final ReloadableResourceBundleMessageSource messageSource = +        new ReloadableResourceBundleMessageSource();      messageSource.setDefaultEncoding("UTF-8"); -    messageSource.setParentMessageSource(internalMessageSource()); +    messageSource.setParentMessageSource(internalMessageSource(ressourceLocations)); -    final String staticResources = basicConfig.getBasicConfiguration( -        MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_PROPERTIES_PATH); +    final String staticResources = basicConfig +        .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_PROPERTIES_PATH);      try {        if (StringUtils.isNotEmpty(staticResources)) { -        final String absPath = FileUtils.makeAbsoluteUrl(staticResources, basicConfig -            .getConfigurationRootDirectory()); +        final String absPath = +            FileUtils.makeAbsoluteUrl(staticResources, basicConfig.getConfigurationRootDirectory());          messageSource.setBasename(absPath); -        messageSource.setFallbackToSystemLocale(false);        } else {          log.debug("No Ressourcefolder for dynamic Web content templates"); +        }      } catch (final MalformedURLException e) { @@ -137,40 +158,28 @@ public class StaticResourceConfiguration implements WebMvcConfigurer {      return messageSource;    } - +        /** -   * Cookie based i18n language selector. -   *  -   * @return -   */ -  @Bean -  public CookieLocaleResolver localeResolver() { -    final CookieLocaleResolver localeResolver = new CookieLocaleResolver(); -    localeResolver.setCookieName("currentLanguage"); -    localeResolver.setCookieMaxAge(3600); -    return localeResolver; -  } -   -   -  /** -   * Thymeleaf based template resolver. -   *  +   * Get a Tyhmeleaf Template-Resolver with external configuration path. +   *     * @return     */    @Bean(name = "templateResolver")    public FileTemplateResolver templateResolver() { -    final String staticResources = basicConfig.getBasicConfiguration( -        MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_PATH); +    final String staticResources = basicConfig +        .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_PATH);      try {        if (StringUtils.isNotEmpty(staticResources)) { -        String absPath = FileUtils.makeAbsoluteUrl(staticResources, basicConfig -            .getConfigurationRootDirectory()); +        String absPath = +            FileUtils.makeAbsoluteUrl(staticResources, basicConfig.getConfigurationRootDirectory());          if (!absPath.endsWith("/")) {            absPath += "/"; +          }          if (absPath.startsWith("file:")) {            absPath = absPath.substring("file:".length()); +          }          final FileTemplateResolver viewResolver = new FileTemplateResolver(); @@ -179,11 +188,12 @@ public class StaticResourceConfiguration implements WebMvcConfigurer {          viewResolver.setTemplateMode("HTML");          viewResolver.setCacheable(false); -        log.info("Add Ressourcefolder: " + absPath + " for dynamic Web content templates"); +        log.info("Add Ressourcefolder: {} for dynamic Web content templates", absPath);          return viewResolver;        } else {          log.debug("No Ressourcefolder for dynamic Web content templates"); +        }      } catch (final MalformedURLException e) { @@ -191,8 +201,7 @@ public class StaticResourceConfiguration implements WebMvcConfigurer {      } -    // TODO: implement some backup solution -    return null; +    throw new RuntimeException("Can NOT initialize HTML template resolver");    }  } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java deleted file mode 100644 index f2d9fc8c..00000000 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2018 A-SIT Plus GmbH - * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, - * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "License"); - * You may not use this work except in compliance with the License. - * You may obtain a copy of the License at: - * https://joinup.ec.europa.eu/news/understanding-eupl-v12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. -*/ - -package at.asitplus.eidas.specific.connector.controller; - -import java.io.IOException; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.xml.transform.TransformerFactoryConfigurationError; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.text.StringEscapeUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.CloseableHttpClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; -import at.gv.egiz.eaaf.core.api.data.EaafConstants; -import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP; -import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory; -import at.gv.egiz.eaaf.core.impl.utils.DomUtils; -import at.gv.egiz.eaaf.core.impl.utils.Random; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory; -import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder; -import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; - -@Controller -public class MonitoringController { -  private static final Logger log = LoggerFactory.getLogger(MonitoringController.class); - -  private static final String MESSAGE_OK = "OK"; -  private static final String MESSAGE_ERROR = "ERROR"; -  private static final String MESSAGE_SKIPPED = "SKIPPED"; - -  private static final String TEST_STORAGE = "Storage: "; -  private static final String TEST_CONFIG = "Config: "; -  private static final String TEST_PVPMETADATA = "PVP_metadata: "; -  private static final String TEST_EIDASNODEMETADATA = "eIDASNode_metadata: "; - -  @Autowired -  private ITransactionStorage storage; -  @Autowired -  private IConfigurationWithSP config; - -  @Autowired private IHttpClientFactory httpClientFactory; -   -  @Autowired -  private PvpMetadataBuilder metadatabuilder; -  @Autowired -  private IPvpMetadataConfigurationFactory configFactory; -  private AbstractCredentialProvider pvpIdpCredentials; - -  /** -   * Sets a specific credential provider for PVP S-Profile IDP component. -   *  -   * @param pvpIdpCredentials credential provider -   */ -  public void setPvpIdpCredentials(AbstractCredentialProvider pvpIdpCredentials) { -    this.pvpIdpCredentials = pvpIdpCredentials; - -  } - -  /** -   * Generic exception handling that wrote an error-message to html response. -   *  -   * @param resp Http response object -   * @param exception Error -   * @throws IOException In case of a html response error. -   */ -  @ExceptionHandler({ Throwable.class }) -  public void genericExceptionHandler(HttpServletResponse resp, Exception exception) throws IOException { -    log.error("Monitoring Servlet receives an error.", exception); -    resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); -    resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); -    resp.getWriter().write("Reason: " -        + StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(exception.getMessage()))); - -  } - -  /** -   * MS-Connector status-monitoring end-point. -   *  -   * @param req http request -   * @param resp http response -   * @throws IOException In case of a general processing error -   */ -  @RequestMapping(value = { MsEidasNodeConstants.ENDPOINT_MONITORING_MONITOR }, -      method = { RequestMethod.GET }) -  public void startFullTest(HttpServletRequest req, HttpServletResponse resp) throws IOException { -    resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); - -    try { -      testConfig(); -      testStorage(); -      testPvpMetadata(); -      testEidasNodeMetadata(); -      resp.setStatus(HttpServletResponse.SC_OK); -      resp.getWriter().write(MESSAGE_OK); - -    } catch (final Exception e) { -      resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); -      resp.getWriter().write(MESSAGE_ERROR); - -    } - -  } - -  /** -   * MS-Connector internal verify monitoring end-point. -   *  -   * @param req http request object -   * @param resp http response object -   * @throws IOException In case of an internal processing error -   */ -  @RequestMapping(value = { MsEidasNodeConstants.ENDPOINT_MONITORING_VERIFY }, -      method = { RequestMethod.GET }) - -  public void startSingleTests(HttpServletRequest req, HttpServletResponse resp) throws IOException { -    String result = StringUtils.EMPTY; -    try { -      result += testConfig() + "<br>"; -    } catch (final Exception e) { -      result += e.getMessage() + "<br>"; -    } - -    try { -      result += testStorage() + "<br>"; -    } catch (final Exception e) { -      result += e.getMessage() + "<br>"; -    } - -    try { -      result += testPvpMetadata() + "<br>"; -    } catch (final Exception e) { -      result += e.getMessage() + "<br>"; -    } - -    try { -      result += testEidasNodeMetadata() + "<br>"; -    } catch (final Exception e) { -      result += e.getMessage() + "<br>"; -    } - -    resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8); -    resp.setStatus(HttpServletResponse.SC_OK); -    resp.getWriter().write(result); - -  } - -  private String testStorage() throws Exception { -    try { -      final String key = Random.nextHexRandom16(); -      final String value = Random.nextHexRandom16(); - -      storage.put(key, value, -1); -      final String result = storage.get(key, String.class); -      storage.remove(key); - -      if (result != null && result.equals(value)) { -        return TEST_STORAGE + MESSAGE_OK; -      } else { -        log.warn("Montioring: TestValue: " + value + " does NOT match in Storage test"); -      } - -    } catch (final EaafException e) { -      log.warn("Montioring: Can not read/write to storage.", e); - -    } - -    throw new Exception(TEST_STORAGE + MESSAGE_ERROR); - -  } - -  private String testConfig() throws Exception { -    try { -      if (config.getBasicConfigurationWithPrefix(MsEidasNodeConstants.PROP_CONFIG_SP_LIST_PREFIX) != null -          && config.getBasicConfigurationWithPrefix(MsEidasNodeConstants.PROP_CONFIG_SP_LIST_PREFIX) -              .size() > 0) { -        return TEST_CONFIG + MESSAGE_OK; -      } else { -        log.warn("Montioring: Can not read from configuration file."); -      } - -    } catch (final Exception e) { -      log.warn("Montioring: Can not read from configuration file.", e); -    } - -    throw new Exception(TEST_CONFIG + MESSAGE_ERROR); - -  } - -  private String testPvpMetadata() throws Exception { -    try { -      // build metadata -      final IPvpMetadataBuilderConfiguration metadataConfig = -          configFactory.generateMetadataBuilderConfiguration( -              "http://localhost/monitoring", -              pvpIdpCredentials); -      metadatabuilder.buildPvpMetadata(metadataConfig); -      return TEST_PVPMETADATA + MESSAGE_OK; - -    } catch (Exception | TransformerFactoryConfigurationError e) { -      log.warn("Monitoring: Has an error in '" + TEST_PVPMETADATA + "': " + e.getMessage(), e); -      throw new Exception(TEST_PVPMETADATA + MESSAGE_ERROR, e); - -    } - -  } - -  private String testEidasNodeMetadata() throws Exception { -    try { -      final String urlString = config.getBasicConfiguration( -          MsEidasNodeConstants.PROP_CONFIG_MONITORING_EIDASNODE_METADATAURL); -      if (StringUtils.isEmpty(urlString)) { -        log.debug("No eIDASNode metadata URL. Skipping test ... "); -        return TEST_EIDASNODEMETADATA + MESSAGE_SKIPPED; - -      } - -      // create HTTP client -      CloseableHttpClient httpClient = httpClientFactory.getHttpClient();       -      URIBuilder uriBuilder = new URIBuilder(urlString);       -      HttpUriRequest request = new HttpGet(uriBuilder.build()); - -      final CloseableHttpResponse respCode = httpClient.execute(request); -      if (respCode.getStatusLine().getStatusCode() != 200) { -        log.warn("Monitoring: Has an error in '" + TEST_EIDASNODEMETADATA + "': " + " HTTP responsecode: " -            + respCode); -        throw new Exception(TEST_EIDASNODEMETADATA + MESSAGE_ERROR); - -      } - -      // parse metadata -      DomUtils.parseXmlNonValidating(respCode.getEntity().getContent()); - -      return TEST_EIDASNODEMETADATA + MESSAGE_OK; - -    } catch (Exception | TransformerFactoryConfigurationError e) { -      log.warn("Monitoring: Has an error in '" + TEST_EIDASNODEMETADATA + "': " + e.getMessage(), e); -      throw new Exception(TEST_EIDASNODEMETADATA + MESSAGE_ERROR, e); - -    } - -  } - -} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/health/EidasNodeMetadataHealthIndicator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/EidasNodeMetadataHealthIndicator.java new file mode 100644 index 00000000..f160916c --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/EidasNodeMetadataHealthIndicator.java @@ -0,0 +1,69 @@ +package at.asitplus.eidas.specific.connector.health; + +import java.io.ByteArrayInputStream; + +import javax.xml.transform.TransformerFactoryConfigurationError; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.ContentType; +import org.apache.http.impl.client.CloseableHttpClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; + +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.impl.data.Triple; +import at.gv.egiz.eaaf.core.impl.http.HttpUtils; +import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory; +import at.gv.egiz.eaaf.core.impl.utils.DomUtils; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EidasNodeMetadataHealthIndicator implements HealthIndicator { + +  @Autowired IConfiguration config; +  @Autowired IHttpClientFactory httpClientFactory; +   +  @Override +  public Health health() { +    try { +      final String urlString = config.getBasicConfiguration( +          MsEidasNodeConstants.PROP_CONFIG_MONITORING_EIDASNODE_METADATAURL); +      if (StringUtils.isEmpty(urlString)) { +        log.trace("No eIDASNode metadata URL. Skipping test ... "); +        return Health.unknown().build(); + +      } + +      // create HTTP client +      CloseableHttpClient httpClient = httpClientFactory.getHttpClient();       +      URIBuilder uriBuilder = new URIBuilder(urlString);       +      HttpUriRequest request = new HttpGet(uriBuilder.build()); + +      final Triple<StatusLine, ByteArrayInputStream, ContentType> respCode = httpClient.execute(request, +          HttpUtils.bodyStatusCodeResponseHandler()); +      if (respCode.getFirst().getStatusCode() != 200) { +        log.warn("Monitoring: Get http StatusCode: {} from eIDAS-Node Metadata endpoint",  +            respCode.getFirst().getStatusCode()); +        return Health.down().withDetail("http StatusCode", respCode.getFirst().getStatusCode()).build(); + +      } + +      // parse metadata +      DomUtils.parseXmlNonValidating(respCode.getSecond()); + +      return Health.up().build(); + +    } catch (Exception | TransformerFactoryConfigurationError e) { +      log.warn("Monitoring: Can not read SAML2 metadata from eIDAS-Node", e); +      return Health.down().down(e).build(); + +    } +  } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/health/IgniteClusterHealthIndicator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/IgniteClusterHealthIndicator.java new file mode 100644 index 00000000..10517565 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/IgniteClusterHealthIndicator.java @@ -0,0 +1,52 @@ +package at.asitplus.eidas.specific.connector.health; + +import org.apache.ignite.Ignite; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; + +import eu.eidas.auth.cache.IgniteInstanceInitializerSpecificCommunication; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +/** + * HealthCheck that validate Nodes in Apache-Ignite Cluster. + *  + * @author tlenz + * + */ +@Slf4j +public class IgniteClusterHealthIndicator implements HealthIndicator { + +  @Setter +  protected IgniteInstanceInitializerSpecificCommunication igniteInstanceInitializerSpecificCommunication; + +  @Override +  public Health health() { +    final Ignite instance = igniteInstanceInitializerSpecificCommunication.getInstance(); + +    // check if Apache Ignite cluster is active +    if (!instance.cluster().active()) { +      return Health.outOfService().build(); + +    } + +    final Health.Builder healthBuilder; +    // Status UP requires more than 1 node because MS-Connector and eIDAS-Node operations as +    // micro-services +    if (instance.cluster().nodes().size() > 1) { +      healthBuilder = Health.up(); + +    } else { +      // Something looks wrong if only a single node was found because MS-Connector and eIDAS-Node +      // operations as micro-services +      healthBuilder = Health.outOfService(); + +    } + +    healthBuilder.withDetail("#Nodes", instance.cluster().nodes().size()); +    log.trace("Ignite state. #Nodes: {}", instance.cluster().nodes().size()); +    return healthBuilder.build(); + +  } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/health/Saml2MetadataHealthIndicator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/Saml2MetadataHealthIndicator.java new file mode 100644 index 00000000..592231b0 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/Saml2MetadataHealthIndicator.java @@ -0,0 +1,44 @@ +package at.asitplus.eidas.specific.connector.health; + +import javax.xml.transform.TransformerFactoryConfigurationError; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; + +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class Saml2MetadataHealthIndicator implements HealthIndicator { + +  @Autowired +  private PvpMetadataBuilder metadatabuilder; +  @Autowired +  private IPvpMetadataConfigurationFactory configFactory; +   +  @Setter +  private AbstractCredentialProvider pvpIdpCredentials; +   +  @Override +  public Health health() { +    try { +      // build metadata +      final IPvpMetadataBuilderConfiguration metadataConfig = +          configFactory.generateMetadataBuilderConfiguration( +              "http://localhost/monitoring", +              pvpIdpCredentials); +      metadatabuilder.buildPvpMetadata(metadataConfig); +      return Health.up().build(); + +    } catch (Exception | TransformerFactoryConfigurationError e) { +      return Health.down().down(e).build(); +       +    } +  } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java index 86808f01..d3b8116a 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java @@ -26,8 +26,6 @@ package at.asitplus.eidas.specific.connector.processes.tasks;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Component; @@ -39,7 +37,6 @@ import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder;  import at.gv.egiz.eaaf.core.api.idp.IConfiguration;  import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;  import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.core.exceptions.GuiBuildException;  import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;  import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; @@ -51,7 +48,6 @@ import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;   */  @Component("GenerateCountrySelectionFrameTask")  public class GenerateCountrySelectionFrameTask extends AbstractAuthServletTask { -  private static final Logger log = LoggerFactory.getLogger(GenerateCountrySelectionFrameTask.class);    @Autowired    ISpringMvcGuiFormBuilder guiBuilder; @@ -77,16 +73,11 @@ public class GenerateCountrySelectionFrameTask extends AbstractAuthServletTask {        guiBuilder.build(request, response, config, "BKU-Selection form"); -    } catch (final GuiBuildException e) { -      log.warn("Can not build GUI:'BKU-Selection'. Msg:" + e.getMessage()); +    } catch (final Exception e) {        throw new TaskExecutionException(pendingReq,            "Can not build GUI. Msg:" + e.getMessage(),            new EaafException("gui.00", new Object[] { e.getMessage() }, e)); -    } catch (final Exception e) { -      log.warn("FinalizeAuthenticationTask has an internal error", e); -      throw new TaskExecutionException(pendingReq, e.getMessage(), e); -      }    } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/StatusMessageProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/StatusMessageProvider.java index d38da6fe..073f7513 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/StatusMessageProvider.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/provider/StatusMessageProvider.java @@ -94,8 +94,8 @@ public class StatusMessageProvider implements IStatusMessenger {    public String getResponseErrorCode(Throwable throwable) {      String errorCode = IStatusMessenger.CODES_EXTERNAL_ERROR_GENERIC;      if (throwable instanceof EaafException) { -      errorCode = ((EaafException) throwable).getErrorId(); - +      errorCode = mapInternalErrorToExternalError(((EaafException) throwable).getErrorId()); +            }      // TODO: maybe more internal switches are required diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java index 557e245a..1ea5a280 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java @@ -30,18 +30,47 @@ import java.util.List;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator;  import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;  import at.gv.egiz.eaaf.core.exceptions.EaafException;  import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; +import at.gv.egiz.eaaf.core.impl.utils.Random; -public class EidasCacheTransactionStoreDecorator implements ITransactionStorage { +public class EidasCacheTransactionStoreDecorator implements ITransactionStorage, HealthIndicator {    private static final Logger log = LoggerFactory.getLogger(EidasCacheTransactionStoreDecorator.class);    @Autowired(required = true)    private CacheWithEidasBackend storage;    @Override +  public Health health() { +    try { +      final String key = Random.nextHexRandom16(); +      final String value = Random.nextHexRandom16(); + +      this.put(key, value, -1); +      final String result = this.get(key, String.class); +      this.remove(key); + +      if (result != null && result.equals(value)) { +        return Health.up().build(); +       +      } else { +        log.warn("Montioring: TestValue: " + value + " does NOT match in Storage test"); +        return Health.down().build(); +         +      } + +    } catch (final EaafException e) { +      log.warn("Montioring: Can not read/write to storage.", e); +      return Health.down().down(e).build(); +       +    } +  } +   +  @Override    public void changeKey(String oldKey, String newKey, Object value) throws EaafException {      if (containsKey(oldKey)) {        final TransactionStoreElement el = storage.get(oldKey); @@ -148,5 +177,4 @@ public class EidasCacheTransactionStoreDecorator implements ITransactionStorage      }    } -  } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java index 26d442cb..3bda2932 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java @@ -33,13 +33,11 @@ import java.util.concurrent.ConcurrentHashMap;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service;  import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;  import at.gv.egiz.eaaf.core.exceptions.EaafException;  import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; -@Service("SimpleInMemoryTransactionStorage")  public class SimpleInMemoryTransactionStorage implements ITransactionStorage {    private static final Logger log = LoggerFactory.getLogger(SimpleInMemoryTransactionStorage.class); diff --git a/connector/src/main/resources/SpringTest_connector.beans.xml b/connector/src/main/resources/SpringTest_connector.beans.xml deleted file mode 100644 index 5cf0d5b8..00000000 --- a/connector/src/main/resources/SpringTest_connector.beans.xml +++ /dev/null @@ -1,129 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<beans xmlns="http://www.springframework.org/schema/beans" -  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" -  xmlns:context="http://www.springframework.org/schema/context" -  xmlns:tx="http://www.springframework.org/schema/tx" -  xmlns:aop="http://www.springframework.org/schema/aop" -  xmlns:mvc="http://www.springframework.org/schema/mvc" -  xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd -    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd -    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd -    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd -    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> - -  <context:annotation-config /> -  <mvc:annotation-driven /> -  <mvc:default-servlet-handler /> - -  <bean id="WebResourceConfiguration" -    class="at.asitplus.eidas.specific.connector.config.StaticResourceConfiguration" /> - -  <bean id="ProcessEngineSignalController" -    class="at.asitplus.eidas.specific.connector.controller.ProcessEngineSignalController" /> - -  <bean id="MonitoringController" -    class="at.asitplus.eidas.specific.connector.controller.MonitoringController"> -    <property name="pvpIdpCredentials"> -      <ref bean="PVPEndPointCredentialProvider" /> -    </property> -  </bean> - -  <bean id="AuthenticationManager" -    class="at.asitplus.eidas.specific.connector.auth.AuthenticationManager" /> - -  <bean id="AuthenticationDataBuilder" -    class="at.asitplus.eidas.specific.connector.builder.AuthenticationDataBuilder" /> - -  <bean id="PVPEndPointConfiguration" -    class="at.asitplus.eidas.specific.connector.config.PvpEndPointConfiguration" /> - -  <bean id="PVPEndPointCredentialProvider" -    class="at.asitplus.eidas.specific.connector.provider.PvpEndPointCredentialProvider" /> - -  <bean id="PVPMetadataConfigurationFactory" -    class="at.asitplus.eidas.specific.connector.provider.PvpMetadataConfigurationFactory" /> - -  <bean id="PVP2XProtocol" -    class="at.asitplus.eidas.specific.connector.controller.Pvp2SProfileEndpoint"> -    <property name="pvpIdpCredentials"> -      <ref bean="PVPEndPointCredentialProvider" /> -    </property> -  </bean> - -  <bean id="AuthnRequestValidator" -    class="at.asitplus.eidas.specific.connector.verification.AuthnRequestValidator" /> - -  <bean id="SAMLVerificationEngine" -    class="at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine" /> - -  <bean id="pvpMetadataService" -    class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.MetadataAction"> -    <property name="pvpIdpCredentials"> -      <ref bean="PVPEndPointCredentialProvider" /> -    </property> -  </bean> - -  <bean id="PVPAuthenticationRequestAction" -    class="at.gv.egiz.eaaf.modules.pvp2.idp.impl.AuthenticationAction"> -    <property name="pvpIdpCredentials"> -      <ref bean="PVPEndPointCredentialProvider" /> -    </property> -  </bean> - -  <bean id="eaafProtocolAuthenticationService" -    class="at.gv.egiz.eaaf.core.impl.idp.auth.services.ProtocolAuthenticationService"> -    <property name="guiBuilder" ref="mvcGUIBuilderImpl" /> -  </bean> - -  <bean id="securePendingRequestIdGeneration" -    class="at.gv.egiz.eaaf.core.impl.utils.SecurePendingRequestIdGenerationStrategy" /> - -  <bean id="PVPMetadataProvider" -    class="at.asitplus.eidas.specific.connector.provider.PvpMetadataProvider" /> - -  <bean id="PVPSubjectNameGenerator" -    class="at.asitplus.eidas.specific.connector.builder.PvpSubjectNameGenerator" /> - -  <bean id="LoALevelMapper" -    class="at.asitplus.eidas.specific.connector.mapper.LoALevelMapper" /> - -  <bean id="GUIBuilderConfigurationFactory" -    class="at.asitplus.eidas.specific.connector.gui.GuiBuilderConfigurationFactory" /> - -  <bean id="velocityGUIBuilderImpl" -    class="at.asitplus.eidas.specific.connector.gui.DefaultVelocityGuiBuilderImpl" /> - -  <bean id="mvcGUIBuilderImpl" -    class="at.asitplus.eidas.specific.connector.gui.SpringMvcGuiFormBuilderImpl" /> - -  <bean id="templateEngine" -    class="org.thymeleaf.spring5.SpringTemplateEngine"> -    <property name="templateResolver" ref="templateResolver" /> -  </bean> - -  <bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> -    <property name="order" value="2" /> -    <property name="templateEngine" ref="templateEngine" /> -    <property name="characterEncoding" value="UTF-8" /> -  </bean> - -  <bean id="StatusMessageProvider" -    class="at.asitplus.eidas.specific.connector.provider.StatusMessageProvider" /> - -  <bean id="eidasRevisionLogger" -    class="at.asitplus.eidas.specific.connector.logger.RevisionLogger" /> - -  <bean id="eidasStatisticLogger" -    class="at.asitplus.eidas.specific.connector.logger.StatisticLogger" /> - - -  <!-- Tasks --> -  <bean id="GenerateCountrySelectionFrameTask" -    class="at.asitplus.eidas.specific.connector.processes.tasks.GenerateCountrySelectionFrameTask" -    scope="prototype" /> - -  <bean id="EvaluateCountrySelectionTask" -    class="at.asitplus.eidas.specific.connector.processes.tasks.EvaluateCountrySelectionTask" -    scope="prototype" /> - -</beans>
\ No newline at end of file diff --git a/connector/src/main/resources/application.properties b/connector/src/main/resources/application.properties new file mode 100644 index 00000000..b13b6c18 --- /dev/null +++ b/connector/src/main/resources/application.properties @@ -0,0 +1,148 @@ +## Set Spring-Boot profile-configuration to 2.3 style +spring.config.use-legacy-processing=true + +## ApplicationServer configuration  +server.servlet.contextPath=/ms_connector +#server.port=7080 + +app.build.artifactId=ms_connector + + +############################################################################# +## SpringBoot Admin client +spring.boot.admin.client.enabled=false + + + + +############################################################################# +## MS-speccific eIDAS-Connector configuration +#proxy.context.url.prefix= +eidas.ms.context.url.request.validation=false +#proxy.configRootDir=file:/.../config/ +eidas.ms.context.use.clustermode=true +eidas.ms.core.logging.level.info.errorcodes=auth.21 + +##Monitoring +eidas.ms.monitoring.eIDASNode.metadata.url= + + +##Specific logger configuration +eidas.ms.technicallog.write.MDS.into.techlog=true +eidas.ms.revisionlog.write.MDS.into.revisionlog=true +eidas.ms.revisionlog.logIPAddressOfUser=true + + +##Directory for static Web content +eidas.ms.webcontent.static.directory=webcontent/ +eidas.ms.webcontent.templates=templates/ +eidas.ms.webcontent.properties=properties/messages +eidas.ms.webcontent.templates.countryselection=countrySelection.html + + +## extended validation of pending-request Id's +eidas.ms.core.pendingrequestid.maxlifetime=300 +eidas.ms.core.pendingrequestid.digist.algorithm=HmacSHA256 +#eidas.ms.core.pendingrequestid.digist.secret=pendingReqIdSecret + + +## eIDAS Ref. Implementation connector ### +eidas.ms.auth.eIDAS.node_v2.entityId=ownSpecificConnector +#eidas.ms.auth.eIDAS.node_v2.forward.endpoint= +eidas.ms.auth.eIDAS.node_v2.forward.method=POST +eidas.ms.auth.eIDAS.node_v2.countrycode=AT +eidas.ms.auth.eIDAS.node_v2.publicSectorTargets=.* +eidas.ms.auth.eIDAS.node_v2.workarounds.addAlwaysProviderName=true +eidas.ms.auth.eIDAS.node_v2.workarounds.useRequestIdAsTransactionIdentifier=true +eidas.ms.auth.eIDAS.node_v2.workarounds.useStaticProviderNameForPublicSPs=true + +eidas.ms.auth.eIDAS.node_v2.loa.requested.minimum=http://eidas.europa.eu/LoA/high + +#eidas.ms.auth.eIDAS.szrclient.useTestService=true +#eidas.ms.auth.eIDAS.szrclient.endpoint.prod= +#eidas.ms.auth.eIDAS.szrclient.endpoint.test=http://localhost:1234/demoszr +#eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.path=keys/junit.jks +#eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.password=password +#eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.path= +#eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.password= +eidas.ms.auth.eIDAS.szrclient.timeout.connection=15 +eidas.ms.auth.eIDAS.szrclient.timeout.response=30 +eidas.ms.auth.eIDAS.szrclient.params.vkz= + +eidas.ms.auth.eIDAS.szrclient.params.useSZRForbPKCalculation=false +eidas.ms.auth.eIDAS.szrclient.eidasbind.mds.inject=false + + +# tech. AuthBlock signing for E-ID process +#eidas.ms.auth.eIDAS.authblock.keystore.password=f/+saJBc3a}*/T^s +#eidas.ms.auth.eIDAS.authblock.keystore.friendlyName=connectorkeypair +#eidas.ms.auth.eIDAS.authblock.keystore.path=keys/teststore.jks +#eidas.ms.auth.eIDAS.authblock.keystore.type=jks +#eidas.ms.auth.eIDAS.authblock.key.alias=connectorkeypair +#eidas.ms.auth.eIDAS.authblock.key.password=f/+saJBc3a}*/T^s + + +#Raw eIDAS Id data storage +eidas.ms.auth.eIDAS.szrclient.workarounds.eidmapping.revisionlog.active=true + + +eidas.ms.auth.eIDAS.szrclient.params.setPlaceOfBirthIfAvailable=true +eidas.ms.auth.eIDAS.szrclient.params.setBirthNameIfAvailable=true + +eidas.ms.auth.eIDAS.szrclient.debug.logfullmessages=false +eidas.ms.auth.eIDAS.szrclient.debug.useDummySolution=false + +##without mandates +eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.0=PersonIdentifier,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.1=FamilyName,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.2=FirstName,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.3=DateOfBirth,true + +eidas.ms.auth.eIDAS.node_v2.attributes.requested.de.onlynatural.4=PlaceOfBirth,false +eidas.ms.auth.eIDAS.node_v2.attributes.requested.de.onlynatural.5=BirthName,false +eidas.ms.auth.eIDAS.node_v2.attributes.requested.de.onlynatural.6=Gender,false +eidas.ms.auth.eIDAS.node_v2.attributes.requested.de.onlynatural.7=CurrentAddress,false + +##with mandates ---- NOT FULLY SUPPORTED AT THE MOMENT ----- +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.0=PersonIdentifier,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.1=FamilyName,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.2=FirstName,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.3=DateOfBirth,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.4=LegalPerson,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.5=LegalName,true + + +## PVP2 S-Profile end-point configuration +#eidas.ms.pvp2.keystore.type=jks +#eidas.ms.pvp2.keystore.path=keys/junit.jks +#eidas.ms.pvp2.keystore.password=password +#eidas.ms.pvp2.key.metadata.alias=meta +#eidas.ms.pvp2.key.metadata.password=password +#eidas.ms.pvp2.key.signing.alias=sig +#eidas.ms.pvp2.key.signing.password=password +#eidas.ms.pvp2.metadata.validity=24 + +#eidas.ms.pvp2.metadata.organisation.name=JUnit +#eidas.ms.pvp2.metadata.organisation.friendyname=For testing with jUnit +#eidas.ms.pvp2.metadata.organisation.url=http://junit.test +#eidas.ms.pvp2.metadata.contact.givenname=Max +#eidas.ms.pvp2.metadata.contact.surname=Mustermann +#eidas.ms.pvp2.metadata.contact.email=max@junit.test + + +## Service Provider configuration +#eidas.ms.sp.0.uniqueID=https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata +#eidas.ms.sp.0.pvp2.metadata.truststore=keys/junit.jks +#eidas.ms.sp.0.pvp2.metadata.truststore.password=password +#eidas.ms.sp.0.friendlyName=jUnit test +#eidas.ms.sp.0.pvp2.metadata.url= +#eidas.ms.sp.0.policy.allowed.requested.targets=.* +#eidas.ms.sp.0.policy.hasBaseIdTransferRestriction=false + + +##only for advanced config +eidas.ms.configuration.sp.disableRegistrationRequirement= +#eidas.ms.configuration.restrictions.baseID.spTransmission= +eidas.ms.configuration.auth.default.countrycode= +eidas.ms.configuration.pvp.scheme.validation= +eidas.ms.configuration.pvp.enable.entitycategories=
\ No newline at end of file diff --git a/connector/src/main/resources/applicationContext.xml b/connector/src/main/resources/applicationContext.xml index 76682a2e..15ce0a55 100644 --- a/connector/src/main/resources/applicationContext.xml +++ b/connector/src/main/resources/applicationContext.xml @@ -14,10 +14,14 @@      http://www.springframework.org/schema/tx/spring-tx.xsd">    <context:annotation-config /> -  <mvc:annotation-driven /> +  <context:component-scan base-package="at.gv.egiz.eaaf.utils.springboot.ajp"/> +<!-- +  <context:annotation-config /> +  <mvc:annotation-driven />    <mvc:default-servlet-handler /> - +--> +        <mvc:interceptors>      <bean        class="at.asitplus.eidas.specific.connector.interceptor.WebFrontEndSecurityInterceptor" /> @@ -27,13 +31,24 @@      </bean>    </mvc:interceptors> +  <bean id="springContextClosingHandler" +        class="at.asitplus.eidas.specific.connector.SpringContextCloseHandler" /> + +<!--     <context:property-placeholder      location="${eidas.ms.configuration}" /> +  --> +  <beans profile="deprecatedConfig">    <bean id="BasicMSSpecificNodeConfig"      class="at.asitplus.eidas.specific.connector.config.BasicConfigurationProvider"> -    <constructor-arg -      value="#{systemProperties['eidas.ms.configuration']}" /> +    <constructor-arg value="#{systemProperties['eidas.ms.configuration']}" />    </bean> +  </beans> +  <beans profile="!deprecatedConfig"> +    <bean id="springBootMsSpecificNodeConfig" +          class="at.asitplus.eidas.specific.connector.config.SpringBootBasicConfigurationProvider" /> +           +  </beans>  </beans> diff --git a/connector/src/main/resources/log4j.properties b/connector/src/main/resources/log4j.properties deleted file mode 100644 index 81e54aae..00000000 --- a/connector/src/main/resources/log4j.properties +++ /dev/null @@ -1,55 +0,0 @@ -# commons-logging setup -org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.Log4jFactory - -# define log4j root loggers -log4j.rootLogger=info,stdout, console - -log4j.logger.at.gv.egiz.eaaf=info, msnode -log4j.logger.at.gv.egiz.eidas.specific=info, msnode -log4j.logger.at.gv.egiz.eidas.specific.connector.logger.RevisionLogger=info, reversion -log4j.logger.at.gv.egiz.eidas.specific.connector.logger.StatisticLogger=info, statistic -log4j.logger.eu.eidas=info, EIDASNODE - -log4j.additivity.at.gv.egiz.eidas.specific=false -log4j.additivity.at.gv.egiz.eidas.specific.connector.logger.RevisionLogger=false -log4j.additivity.at.gv.egiz.eidas.specific.connector.logger.StatisticLogger=false -log4j.additivity.eu.eidas=false - -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %20c |  %10t | %m%n - -log4j.appender.stdout=org.apache.log4j.RollingFileAppender -log4j.appender.stdout.File=${catalina.base}/logs/console.log -log4j.appender.stdout.MaxFileSize=10000KB -log4j.appender.stdout.MaxBackupIndex=9999 -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n - -log4j.appender.msnode=org.apache.log4j.RollingFileAppender -log4j.appender.msnode.File=${catalina.base}/logs/eidas-ms-reversion.log -log4j.appender.msnode.MaxFileSize=10000KB -log4j.appender.msnode.MaxBackupIndex=9999 -log4j.appender.msnode.layout=org.apache.log4j.PatternLayout -log4j.appender.msnode.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n - -log4j.appender.reversion=org.apache.log4j.RollingFileAppender -log4j.appender.reversion.File=${catalina.base}/logs/eidas-ms-reversion.log -log4j.appender.reversion.MaxFileSize=10000KB -log4j.appender.reversion.MaxBackupIndex=9999 -log4j.appender.reversion.layout=org.apache.log4j.PatternLayout -log4j.appender.reversion.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n - -log4j.appender.statistic=org.apache.log4j.RollingFileAppender -log4j.appender.statistic.File=${catalina.base}/logs/eidas-ms-statistic.log -log4j.appender.statistic.MaxFileSize=10000KB -log4j.appender.statistic.MaxBackupIndex=9999 -log4j.appender.statistic.layout=org.apache.log4j.PatternLayout -log4j.appender.statistic.layout.ConversionPattern=%m%n - -log4j.appender.EIDASNODE=org.apache.log4j.RollingFileAppender -log4j.appender.EIDASNODE.File=${catalina.base}/logs/eIDAS_node.log -log4j.appender.EIDASNODE.MaxFileSize=10000KB -log4j.appender.EIDASNODE.MaxBackupIndex=9999 -log4j.appender.EIDASNODE.layout=org.apache.log4j.PatternLayout -log4j.appender.EIDASNODE.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n
\ No newline at end of file diff --git a/connector/src/main/resources/logback.xml b/connector/src/main/resources/logback.xml index a0a9995e..7aa2d0cc 100644 --- a/connector/src/main/resources/logback.xml +++ b/connector/src/main/resources/logback.xml @@ -11,14 +11,14 @@    <appender name="msnode"      class="ch.qos.logback.core.rolling.RollingFileAppender">      <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> -    <File>${catalina.base}/logs/eidas-ms-reversion.log</File> +    <File>logs/eidas-ms-specific.log</File>      <encoder>        <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>      </encoder>      <rollingPolicy        class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">        <maxIndex>9999</maxIndex> -      <FileNamePattern>${catalina.base}/logs/eidas-ms-reversion.log.%i +      <FileNamePattern>logs/eidas-ms-specific.log.%i        </FileNamePattern>      </rollingPolicy>      <triggeringPolicy @@ -29,14 +29,14 @@    <appender name="EIDASNODE"      class="ch.qos.logback.core.rolling.RollingFileAppender">      <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> -    <File>${catalina.base}/logs/eIDAS_node.log</File> +    <File>logs/eIDAS_node.log</File>      <encoder>        <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>      </encoder>      <rollingPolicy        class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">        <maxIndex>9999</maxIndex> -      <FileNamePattern>${catalina.base}/logs/eIDAS_node.log.%i +      <FileNamePattern>logs/eIDAS_node.log.%i        </FileNamePattern>      </rollingPolicy>      <triggeringPolicy @@ -47,14 +47,14 @@    <appender name="reversion"      class="ch.qos.logback.core.rolling.RollingFileAppender">      <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> -    <File>${catalina.base}/logs/eidas-ms-reversion.log</File> +    <File>logs/eidas-ms-reversion.log</File>      <encoder>        <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>      </encoder>      <rollingPolicy        class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">        <maxIndex>9999</maxIndex> -      <FileNamePattern>${catalina.base}/logs/eidas-ms-reversion.log.%i +      <FileNamePattern>logs/eidas-ms-reversion.log.%i        </FileNamePattern>      </rollingPolicy>      <triggeringPolicy @@ -65,14 +65,14 @@    <appender name="statistic"      class="ch.qos.logback.core.rolling.RollingFileAppender">      <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> -    <File>${catalina.base}/logs/eidas-ms-statistic.log</File> +    <File>logs/eidas-ms-statistic.log</File>      <encoder>        <pattern>%m%n</pattern>      </encoder>      <rollingPolicy        class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">        <maxIndex>9999</maxIndex> -      <FileNamePattern>${catalina.base}/logs/eidas-ms-statistic.log.%i +      <FileNamePattern>logs/eidas-ms-statistic.log.%i        </FileNamePattern>      </rollingPolicy>      <triggeringPolicy @@ -83,14 +83,14 @@    <appender name="stdout"      class="ch.qos.logback.core.rolling.RollingFileAppender">      <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> -    <File>${catalina.base}/logs/console.log</File> +    <File>logs/console.log</File>      <encoder>        <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern>      </encoder>      <rollingPolicy        class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">        <maxIndex>9999</maxIndex> -      <FileNamePattern>${catalina.base}/logs/console.log.%i +      <FileNamePattern>logs/console.log.%i        </FileNamePattern>      </rollingPolicy>      <triggeringPolicy diff --git a/connector/src/main/resources/specific_eIDAS_connector.beans.xml b/connector/src/main/resources/specific_eIDAS_connector.beans.xml index 5cf0d5b8..f6fdeefe 100644 --- a/connector/src/main/resources/specific_eIDAS_connector.beans.xml +++ b/connector/src/main/resources/specific_eIDAS_connector.beans.xml @@ -11,23 +11,24 @@      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd      http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> -  <context:annotation-config /> -  <mvc:annotation-driven /> -  <mvc:default-servlet-handler /> +  <import resource="common_gui.beans.xml"/>    <bean id="WebResourceConfiguration"      class="at.asitplus.eidas.specific.connector.config.StaticResourceConfiguration" /> -  <bean id="ProcessEngineSignalController" +  <bean id="processEngineSignalController"      class="at.asitplus.eidas.specific.connector.controller.ProcessEngineSignalController" /> -  <bean id="MonitoringController" -    class="at.asitplus.eidas.specific.connector.controller.MonitoringController"> +  <bean id="saml2MetadataGeneration" +        class="at.asitplus.eidas.specific.connector.health.Saml2MetadataHealthIndicator">      <property name="pvpIdpCredentials">        <ref bean="PVPEndPointCredentialProvider" />      </property>    </bean> +  <bean id="eidasNodeMetadata" +        class="at.asitplus.eidas.specific.connector.health.EidasNodeMetadataHealthIndicator" /> +    <bean id="AuthenticationManager"      class="at.asitplus.eidas.specific.connector.auth.AuthenticationManager" /> @@ -43,7 +44,7 @@    <bean id="PVPMetadataConfigurationFactory"      class="at.asitplus.eidas.specific.connector.provider.PvpMetadataConfigurationFactory" /> -  <bean id="PVP2XProtocol" +  <bean id="pvp2SProfileEndpoint"      class="at.asitplus.eidas.specific.connector.controller.Pvp2SProfileEndpoint">      <property name="pvpIdpCredentials">        <ref bean="PVPEndPointCredentialProvider" /> @@ -96,17 +97,6 @@    <bean id="mvcGUIBuilderImpl"      class="at.asitplus.eidas.specific.connector.gui.SpringMvcGuiFormBuilderImpl" /> -  <bean id="templateEngine" -    class="org.thymeleaf.spring5.SpringTemplateEngine"> -    <property name="templateResolver" ref="templateResolver" /> -  </bean> - -  <bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> -    <property name="order" value="2" /> -    <property name="templateEngine" ref="templateEngine" /> -    <property name="characterEncoding" value="UTF-8" /> -  </bean> -    <bean id="StatusMessageProvider"      class="at.asitplus.eidas.specific.connector.provider.StatusMessageProvider" /> diff --git a/connector/src/main/resources/specific_eIDAS_connector.storage.beans.xml b/connector/src/main/resources/specific_eIDAS_connector.storage.beans.xml index 08c7b672..2e4d1742 100644 --- a/connector/src/main/resources/specific_eIDAS_connector.storage.beans.xml +++ b/connector/src/main/resources/specific_eIDAS_connector.storage.beans.xml @@ -27,12 +27,15 @@    <bean id="msNodeCacheImpl"      class="eu.eidas.auth.cache.ConcurrentCacheServiceIgniteSpecificCommunicationImpl"> -    <property -      name="igniteInstanceInitializerSpecificCommunication" -      ref="eidasIgniteInstanceInitializerSpecificCommunication" /> +    <property name="igniteInstanceInitializerSpecificCommunication" ref="eidasIgniteInstanceInitializerSpecificCommunication" />      <property name="cacheName" value="msConnectorCache" />    </bean> +  <bean id="IgniteClusterState" +        class="at.asitplus.eidas.specific.connector.health.IgniteClusterHealthIndicator"> +    <property name="igniteInstanceInitializerSpecificCommunication" ref="eidasIgniteInstanceInitializerSpecificCommunication" />         +  </bean> +    <!-- bean id="defaultHazelcastInstance" class="java.lang.String"> <constructor-arg       value="eidasHazelcastInstance"/> </bean> <bean id="eidasHazelcastInstanceInitializer"  diff --git a/connector/src/main/resources/tomcat.properties b/connector/src/main/resources/tomcat.properties new file mode 100644 index 00000000..38ab5a64 --- /dev/null +++ b/connector/src/main/resources/tomcat.properties @@ -0,0 +1,15 @@ +tomcat.ajp.enabled=true +#tomcat.ajp.port=41009 +#tomcat.ajp.additionalAttributes.secretrequired=true +#tomcat.ajp.additionalAttributes.secret= + +server.tomcat.accesslog.buffered=false +server.tomcat.accesslog.prefix=tomcat-access_log +server.tomcat.accesslog.directory=logs/ +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.file-date-format=.yyyy-MM-dd +server.tomcat.accesslog.pattern=common +server.tomcat.accesslog.rename-on-rotate=false +server.tomcat.accesslog.request-attributes-enabled=true +server.tomcat.accesslog.rotate=true +server.tomcat.accesslog.suffix=.log
\ No newline at end of file | 
