/** * MailArchiver is an application that provides services for storing and managing e-mail messages through a Web Services SOAP interface. * Copyright (C) 2012 Marcio Andre Scholl Levien and Fernando Alberto Reuter Wendt and Jose Ronaldo Nogueira Fonseca Junior * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ /******************************************************************************\ * * This product was developed by * * SERVIÇO FEDERAL DE PROCESSAMENTO DE DADOS (SERPRO), * * a government company established under Brazilian law (5.615/70), * at Department of Development of Porto Alegre. * \******************************************************************************/ package serpro.mailarchiver.config; import java.io.IOException; import java.io.Writer; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.URISyntaxException; import java.net.URL; import java.net.UnknownHostException; import java.sql.SQLException; import java.util.*; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.aspectj.lang.Aspects; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.rewrite.handler.RewriteHandler; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlets.CrossOriginFilter; import org.eclipse.jetty.util.resource.FileResource; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.webapp.WebAppContext; import org.springframework.context.Lifecycle; import org.springframework.context.annotation.*; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.orm.jdo.JdoTransactionManager; import org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy; import com.eventrouter.DispatchContext; import com.eventrouter.SubscriptionRegistry; import com.jolbox.bonecp.BoneCPDataSource; import serpro.mailarchiver.MailArchiver; import serpro.mailarchiver.util.*; import serpro.mailarchiver.util.jdo.DNJdoDialect; import serpro.mailarchiver.util.jdo.DNPersistenceManagerFactory; import serpro.mailarchiver.util.jdo.InstanceLifecycleListener; import serpro.mailarchiver.util.transaction.AnnotationTransactionAspect; @Configuration public class InfrastructureConfig { private static final Logger log = Logger.getLocalLogger(); //SSL data parameters //private static final String TRUST_STORE_PASSWORD = "OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"; //private static final String KEY_STORE_PASSWORD = "OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"; //private static final String KEY_MANAGER_PASSWORD = "OBF:1u2u1wml1z7s1z7a1wnl1u2g"; private static final String TRUST_STORE_PASSWORD = "serpromailarchiver"; private static final String KEY_STORE_PASSWORD = "serpromailarchiver"; private static final String KEY_MANAGER_PASSWORD = "serpromailarchiver"; public InfrastructureConfig() { log.debug("Instanciando configuration bean InfrastructureConfig"); } @Bean(destroyMethod = "destroy") public MailArchiver mailArchiver() throws UnknownHostException, URISyntaxException, IOException { log.debug("Instanciando bean mailArchiver"); MailArchiver mailArchiver = new MailArchiver(); log.debug("Bean mailArchiver configurado"); return mailArchiver; } @Bean public Resource webRoot() throws IOException { log.debug("Instanciando bean webRoot"); Resource webRoot = new ClassPathResource("/serpro/mailarchiver/config/webroot"); log.debug("Bean webRoot configurado"); return webRoot; } @Bean(initMethod = "start", destroyMethod = "stop") public org.h2.tools.Server h2TcpServer() throws SQLException { log.debug("Instanciando bean h2TcpServer"); List options = new ArrayList(); options.add("-ifExists"); options.add("-trace"); options.add("-baseDir"); options.add(userAppConfig().SERVER.getArchiveDir().toString()); options.add("-tcpPort"); options.add(String.valueOf(userAppConfig().META_ARCHIVE.getTcpPort())); if(userAppConfig().META_ARCHIVE.getTcpAllowOthers()) { options.add("-tcpAllowOthers"); } org.h2.tools.Server h2TcpServer = org.h2.tools.Server.createTcpServer(options.toArray(new String[options.size()])); log.debug("Bean h2TcpServer configurado"); return h2TcpServer; } @Bean(initMethod = "start", destroyMethod = "stop") public Lifecycle h2WebServer() throws SQLException { return new Lifecycle() { org.h2.tools.Server h2WebServer; { if(userAppConfig().META_ARCHIVE.getWebPort() > 0) { log.debug("Instanciando bean h2WebServer"); List options = new ArrayList(); options.add("-ifExists"); //options.add("-trace"); options.add("-baseDir"); options.add(userAppConfig().SERVER.getArchiveDir().toString()); options.add("-webPort"); options.add(String.valueOf(userAppConfig().META_ARCHIVE.getWebPort())); if(userAppConfig().META_ARCHIVE.getWebAllowOthers()) { options.add("-webAllowOthers"); } h2WebServer = org.h2.tools.Server.createWebServer(options.toArray(new String[options.size()])); log.debug("Bean h2WebServer configurado"); } } @Override public void start() { if(h2WebServer != null) { try { h2WebServer.start(); } catch(SQLException ex) { throw new RuntimeException(ex); } } } @Override public void stop() { if(isRunning()) { h2WebServer.stop(); } } @Override public boolean isRunning() { if(h2WebServer != null) { return h2WebServer.isRunning(false); } return false; } }; } @Bean(destroyMethod="close") @DependsOn({"h2TcpServer", "h2WebServer"}) public BoneCPDataSource h2ConnectionPool() { log.debug("Instanciando bean h2ConnectionPool"); BoneCPDataSource h2ConnectionPool = new BoneCPDataSource(); h2ConnectionPool.setDriverClass("org.h2.Driver"); h2ConnectionPool.setJdbcUrl( "jdbc:h2:metaarchive;" + "MVCC=TRUE;" + "TRACE_LEVEL_FILE=1;" + //0:OFF, 1:ERROR, 2:INFO, 3:DEBUG, 4:SLF4J "TRACE_LEVEL_SYSTEM_OUT=1;" + "CACHE_SIZE=131072;" + "DB_CLOSE_ON_EXIT=FALSE"); h2ConnectionPool.setUsername("mail"); h2ConnectionPool.setPassword("archiver"); h2ConnectionPool.setMinConnectionsPerPartition(10); h2ConnectionPool.setMaxConnectionsPerPartition(30); h2ConnectionPool.setPartitionCount(3); h2ConnectionPool.setAcquireIncrement(5); h2ConnectionPool.setStatementsCacheSize(100); h2ConnectionPool.setReleaseHelperThreads(3); log.debug("Bean h2ConnectionPool configurado"); return h2ConnectionPool; } private void CustomErrorPageHandler(String jettyContext, Writer writer) throws IOException{ try{ StringBuilder pageContent = new StringBuilder(""); pageContent.append("\n"); pageContent.append("\n"); pageContent.append("\n"); pageContent.append("\n"); pageContent.append("\n"); pageContent.append("\n"); pageContent.append("MailArchiver\n"); pageContent.append("\n"); pageContent.append("\n"); pageContent.append("
\n"); pageContent.append("\n"); pageContent.append("

MailArchiver

\n"); pageContent.append("

Serviços de arquivamento local de mensagens

\n"); pageContent.append("

Acesse o console de administração

\n"); pageContent.append("

\n"); pageContent.append("

Serviço Federal de Processamento de Dados - SERPRO

\n"); pageContent.append("   \n"); pageContent.append("\n"); pageContent.append("
\n"); pageContent.append("\n"); pageContent.append("\n"); writer.write(pageContent.toString()); log.debug("ErrorHandler adicionado com sucesso ao contexto jetty \"" + jettyContext + "\""); } catch (IOException ex){ log.error("Erro ao adicionar ErrorHandler ao contexto jetty \"" + jettyContext + "\""); } } @Bean(destroyMethod = "stop") public org.eclipse.jetty.server.Server jetty() throws UnknownHostException, URISyntaxException, IOException { log.debug("Instanciando bean jetty"); org.eclipse.jetty.server.Server jetty = new org.eclipse.jetty.server.Server(); //thread pool QueuedThreadPool threadPool = new QueuedThreadPool(); threadPool.setMinThreads(10); threadPool.setMaxThreads(200); //threadPool.setDetailedDump(true); log.debug("threadPool configurado"); //connector SelectChannelConnector connector = new SelectChannelConnector(); connector.setPort(userAppConfig().SERVER.getPort()); connector.setAcceptors(2 * Runtime.getRuntime().availableProcessors()); connector.setStatsOn(false); connector.setLowResourcesConnections(20000); log.debug("connector configurado"); //ssl connector //String keyStorePath = new ClassPathResource("/serpro/mailarchiver/config").getURI().toString() + "/keystore"; String keyStorePath = new ClassPathResource("/serpro/mailarchiver/config").getURI().toString() + "/mailarchiver"; SslContextFactory sslContextFactory = new SslContextFactory(keyStorePath); sslContextFactory.setTrustStore(keyStorePath); sslContextFactory.setTrustStorePassword(TRUST_STORE_PASSWORD); sslContextFactory.setKeyStorePassword(KEY_STORE_PASSWORD); sslContextFactory.setKeyManagerPassword(KEY_MANAGER_PASSWORD); SslSelectChannelConnector sslConnector = new SslSelectChannelConnector(sslContextFactory); sslConnector.setPort(userAppConfig().SERVER.getConfidentialPort()); sslConnector.setAcceptors(2 * Runtime.getRuntime().availableProcessors()); sslConnector.setStatsOn(false); sslConnector.setLowResourcesConnections(20000); log.debug("ssl connector configurado com URL keystore = " + keyStorePath); //virtual hosts Set hosts = new HashSet(); log.debug("Virtual Hosts: iniciando mapeamento local de hosts..."); /*for(InetAddress internetAddress : environment().getInternetAddresses()) { hosts.add(internetAddress.getHostAddress()); //log.debug("Adicionando Host -> inetAddress.getHostAddress = : %s", internetAddress.getHostAddress().toString()); hosts.add(internetAddress.getHostName()); //log.debug("Adicionando Host -> inetAddress.getHostName = : %s", internetAddress.getHostName().toString()); hosts.add(internetAddress.getCanonicalHostName()); //log.debug("Adicionando Host -> inetAddress.getCanonicalHostName = : %s", internetAddress.getCanonicalHostName().toString()); }*/ //Limitar acesso somente ao local host hosts.add("0:0:0:0:0:0:0:1%1"); hosts.add("localhost"); hosts.add("127.0.0.1"); log.debug("Virtual Hosts: mapeamento local de hosts da estação encerrado."); String[] virtualHosts = hosts.toArray(new String[hosts.size()]); log.debug("Virtual Hosts: %s", hosts.toString()); //handlers Handler arcservHandler = null; { WebAppContext webAppContext = new WebAppContext(); webAppContext.setServer(jetty); webAppContext.setContextPath("/arcserv"); String war = webRoot().getURI().toString() + "/arcserv"; webAppContext.setWar(war); webAppContext.setExtractWAR(false); webAppContext.setVirtualHosts(virtualHosts); webAppContext.setErrorHandler(new ErrorHandler() { @Override protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks) throws IOException { CustomErrorPageHandler("arcser", writer); } }); arcservHandler = webAppContext; log.debug("Contexto arcserv configurado. War: %s", war); } Handler adminHandler = null; { WebAppContext webAppContext = new WebAppContext(); webAppContext.setServer(jetty); webAppContext.setContextPath("/admin"); String war = webRoot().getURI().toString() + "/admin"; webAppContext.setWar(war); webAppContext.setExtractWAR(true); webAppContext.setVirtualHosts(virtualHosts); adminHandler = webAppContext; log.debug("Contexto admin configurado. War: %s", war); } Handler arcservutilHandler = null; { WebAppContext webAppContext = new WebAppContext(); webAppContext.setServer(jetty); webAppContext.setContextPath("/arcservutil"); String war = webRoot().getURI().toString() + "/arcservutil"; webAppContext.setWar(war); webAppContext.setExtractWAR(true); webAppContext.setVirtualHosts(virtualHosts); webAppContext.setErrorHandler(new ErrorHandler() { @Override protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks) throws IOException { CustomErrorPageHandler("arcservutil", writer); } }); webAppContext.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false"); //webAppContext.setInitParameter("xpoweredBy", "false"); log.debug("Parâmetros de inicialização aplicados ao contexto arcservutil"); arcservutilHandler = webAppContext; log.debug("Contexto arcservutil configurado. War: %s", war); } Handler mailHandler = null; { CrossOriginFilter crossOriginFilter = new CrossOriginFilter(); FilterHolder filterHolder = new FilterHolder(); filterHolder.setFilter(crossOriginFilter); filterHolder.setInitParameter("allowedOrigins", "*"); filterHolder.setInitParameter("allowedMethods", "GET,POST,OPTIONS"); filterHolder.setInitParameter("allowedHeaders", "Content-Type,MessageType,SOAPAction,X-Requested-With"); filterHolder.setInitParameter("preflightMaxAge", "1800"); filterHolder.setInitParameter("allowCredentials", "true"); DefaultServlet defaultServlet = new DefaultServlet(); ServletHolder servletHolder = new ServletHolder(); servletHolder.setServlet(defaultServlet); //TODO: true somente para teste //servletHolder.setInitParameter("dirAllowed", "true"); servletHolder.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false"); MimeTypes mimeTypes = new MimeTypes(); mimeTypes.addMimeMapping("txt", MimeTypes.TEXT_PLAIN); mimeTypes.addMimeMapping("eml", MimeTypes.TEXT_PLAIN); mimeTypes.addMimeMapping("msg", MimeTypes.TEXT_PLAIN); mimeTypes.addMimeMapping("rfc822", MimeTypes.TEXT_PLAIN); URL url = userAppConfig().SERVER.getArchiveDir().resolve("mail").toUri().toURL(); RewriteHandler rewriteHandler = new RewriteHandler(); rewriteHandler.setServer(jetty); rewriteHandler.setRewritePathInfo(true); rewriteHandler.setRewriteRequestURI(true); MailAccessRule mailAccessRule = new MailAccessRule(); rewriteHandler.addRule(mailAccessRule); ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); servletContextHandler.setServer(jetty); servletContextHandler.setContextPath("/mail"); servletContextHandler.setHandler(rewriteHandler); servletContextHandler.addServlet(servletHolder,"/*"); servletContextHandler.addFilter(filterHolder, "/*", EnumSet.of(DispatcherType.REQUEST)); servletContextHandler.setVirtualHosts(virtualHosts); servletContextHandler.setBaseResource(new FileResource(url)); servletContextHandler.setMimeTypes(mimeTypes); servletContextHandler.setErrorHandler(new ErrorHandler() { @Override protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks) throws IOException { CustomErrorPageHandler("arcservutil", writer); } }); mailHandler = servletContextHandler; log.debug("Contexto mail configurado"); } Handler tempHandler = null; { CrossOriginFilter crossOriginFilter = new CrossOriginFilter(); FilterHolder filterHolder = new FilterHolder(); filterHolder.setFilter(crossOriginFilter); filterHolder.setInitParameter("allowedOrigins", "*"); filterHolder.setInitParameter("allowedMethods", "GET,POST,OPTIONS"); filterHolder.setInitParameter("allowedHeaders", "Content-Type,MessageType,SOAPAction,X-Requested-With"); filterHolder.setInitParameter("preflightMaxAge", "1800"); filterHolder.setInitParameter("allowCredentials", "true"); DefaultServlet defaultServlet = new DefaultServlet(); ServletHolder servletHolder = new ServletHolder(); servletHolder.setServlet(defaultServlet); //TODO: true somente para teste //servletHolder.setInitParameter("dirAllowed", "true"); MimeTypes mimeTypes = new MimeTypes(); mimeTypes.addMimeMapping("txt", MimeTypes.TEXT_PLAIN); mimeTypes.addMimeMapping("eml", MimeTypes.TEXT_PLAIN); mimeTypes.addMimeMapping("msg", MimeTypes.TEXT_PLAIN); mimeTypes.addMimeMapping("rfc822", MimeTypes.TEXT_PLAIN); URL url = userAppConfig().SERVER.getArchiveDir().resolve("temp").toUri().toURL(); RewriteHandler rewriteHandler = new RewriteHandler(); rewriteHandler.setServer(jetty); rewriteHandler.setRewritePathInfo(true); rewriteHandler.setRewriteRequestURI(true); TempPublishRule tempPublishRule = new TempPublishRule(); rewriteHandler.addRule(tempPublishRule); ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); servletContextHandler.setServer(jetty); servletContextHandler.setContextPath("/temp"); servletContextHandler.setHandler(rewriteHandler); servletContextHandler.addServlet(servletHolder,"/*"); servletContextHandler.addFilter(filterHolder, "/*", EnumSet.of(DispatcherType.REQUEST)); servletContextHandler.setVirtualHosts(virtualHosts); servletContextHandler.setBaseResource(new FileResource(url)); servletContextHandler.setMimeTypes(mimeTypes); servletContextHandler.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false"); //webAppContext.setInitParameter("xpoweredBy", "false"); log.debug("Parâmetros de inicialização aplicados ao contexto temp"); // servletContextHandler.setErrorHandler(createErrorHandler()); servletContextHandler.setErrorHandler(new ErrorHandler() { @Override protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks) throws IOException { CustomErrorPageHandler("arcservutil", writer); } }); HandlerWrapper handlerWrapper = new HandlerWrapper() { @Override public void handle( String target, Request baseRequest, HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { HttpServletResponse responseProxy = (HttpServletResponse) Proxy.newProxyInstance( response.getClass().getClassLoader(), response.getClass().getInterfaces(), new InvocationHandler() { private boolean redirected = false; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); if(methodName.equals("sendError") && redirected) { int statusCode = ((Integer)args[0]).intValue(); if(statusCode == HttpServletResponse.SC_NOT_FOUND) { return null; } } Object result = method.invoke(response, args); if(methodName.equals("sendRedirect")) { redirected = true; } return result; } }); super.handle(target, baseRequest, request, responseProxy); } }; handlerWrapper.setServer(jetty); handlerWrapper.setHandler(servletContextHandler); tempHandler = handlerWrapper; log.debug("Contexto temp configurado"); } HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[] { arcservHandler, adminHandler, arcservutilHandler, mailHandler, tempHandler }); log.debug("handlerList configurado"); jetty.setThreadPool(threadPool); jetty.addConnector(connector); jetty.addConnector(sslConnector); jetty.setHandler(handlers); jetty.setStopAtShutdown(true); jetty.setSendServerVersion(true); jetty.setSendDateHeader(true); jetty.setGracefulShutdown(5000); // jetty.setDumpAfterStart(true); String dump = jetty.dump(); System.out.println(dump); log.debug("Jetty dump:%n%n%s", dump); log.debug("Bean jetty configurado"); return jetty; } @Bean(destroyMethod = "close") public DNPersistenceManagerFactory pmf() { log.debug("Instanciando bean pmf"); Map props = new HashMap(); props.put("datanucleus.storeManagerType", "rdbms"); props.put("datanucleus.manageRelationships", "false"); props.put("datanucleus.persistenceByReachabilityAtCommit", "false"); props.put("datanucleus.findObject.validateWhenCached", "false"); props.put("datanucleus.autoCreateSchema", "false"); props.put("datanucleus.autoCreateTables", "false"); props.put("datanucleus.autoCreateColumns", "false"); props.put("datanucleus.autoCreateConstraints", "false"); props.put("datanucleus.validateTables", "true"); props.put("datanucleus.validateColumns", "true"); props.put("datanucleus.validateConstraints", "true"); DNPersistenceManagerFactory pmf = new DNPersistenceManagerFactory(props); pmf.setConnectionFactory(h2ConnectionPool()); pmf.setNontransactionalRead(true); pmf.addInstanceLifecycleListener(lifecycleListener(), null); log.debug("Bean pmf configurado"); return pmf; } @Bean public InstanceLifecycleListener lifecycleListener() { log.debug("Instanciando bean lifecycleListener"); InstanceLifecycleListener lifecycleListener = new InstanceLifecycleListener(); log.debug("Bean lifecycleListener configurado"); return lifecycleListener; } @Bean public TransactionAwarePersistenceManagerFactoryProxy pmfProxy() { log.debug("Instanciando bean pmfProxy"); TransactionAwarePersistenceManagerFactoryProxy pmfProxy = new TransactionAwarePersistenceManagerFactoryProxy(); pmfProxy.setTargetPersistenceManagerFactory(pmf()); pmfProxy.setAllowCreate(false); log.debug("Bean pmfProxy configurado"); return pmfProxy; } @Bean @DependsOn({"transactionAspect"}) public JdoTransactionManager txManager() { log.debug("Instanciando bean txManager"); JdoTransactionManager txManager = new JdoTransactionManager(); txManager.setJdoDialect(jdoDialect()); txManager.setPersistenceManagerFactory(pmf()); Aspects.aspectOf(AnnotationTransactionAspect.class).setTransactionManager(txManager); log.debug("Bean txManager configurado"); return txManager; } @Bean public AnnotationTransactionAspect transactionAspect() { log.debug("Instanciando bean transactionAspect"); AnnotationTransactionAspect transactionAspect = new AnnotationTransactionAspect(); log.debug("Bean transactionAspect configurado"); return transactionAspect; } @Bean public DNJdoDialect jdoDialect() { log.debug("Instanciando bean jdoDialect"); DNJdoDialect jdoDialect = new DNJdoDialect(); log.debug("Bean jdoDialect configurado"); return jdoDialect; } @Bean @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public SubscriptionRegistry subscriptionRegistry() { log.debug("Instanciando bean subscriptionRegistry"); SubscriptionRegistry subscriptionRegistry = new SubscriptionRegistry(); log.debug("Bean subscriptionRegistry configurado"); return subscriptionRegistry; } @Bean @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public DispatchContext dispatchContext() { log.debug("Instanciando bean dispatchContext"); DispatchContext dispatchContext = DispatchContext.synchronousUnsafe(subscriptionRegistry()); log.debug("Bean dispatchContext configurado"); return dispatchContext; } @Bean public ArchiveServicesProxyFactory archiveServicesProxyFactory() { log.debug("Instanciando bean archiveServicesProxyFactory"); ArchiveServicesProxyFactory archiveServicesProxyFactory = new ArchiveServicesProxyFactory(); log.debug("Bean archiveServicesProxyFactory configurado"); return archiveServicesProxyFactory; } @Bean public SystemAuthenticator systemAuthenticator() { log.debug("Instanciando bean systemAuthenticator"); SystemAuthenticator systemAuthenticator = new SystemAuthenticator(); log.debug("Bean systemAuthenticator configurado"); return systemAuthenticator; } @Bean public TrayIconAdapter trayIcon() { log.debug("Instanciando bean trayIcon"); TrayIconAdapter trayIcon = new TrayIconAdapter(); log.debug("Bean trayIcon configurado"); return trayIcon; } @Bean public UserAppConfig userAppConfig() { log.debug("Adquirindo bean userAppConfig"); UserAppConfig userAppConfig = UserAppConfig.getInstance(); log.debug("Bean userAppConfig configurado"); return userAppConfig; } @Bean public Environment environment() { log.debug("Adquirindo bean environment"); Environment environment = Environment.getInstance(); log.debug("Bean environment configurado"); return environment; } }