/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. */ package org.apache.usergrid.launcher; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; public class Server implements org.springframework.context.ApplicationContextAware { public static final boolean INSTALL_JSP_SERVLETS = true; private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger( Server.class ); public static Server instance = null; org.apache.commons.cli.CommandLine line = null; boolean initializeDatabaseOnStart = false; boolean startDatabaseWithServer = false; org.glassfish.grizzly.http.server.HttpServer httpServer; org.glassfish.grizzly.servlet.ServletHandler handler; EmbeddedServerHelper embeddedCassandra = null; protected org.apache.usergrid.persistence.EntityManagerFactory emf; protected org.apache.usergrid.services.ServiceManagerFactory smf; protected org.apache.usergrid.management.ManagementService management; protected java.util.Properties properties; protected org.apache.usergrid.mq.QueueManagerFactory qmf; int port = org.glassfish.grizzly.http.server.NetworkListener.DEFAULT_NETWORK_PORT; boolean daemon = true; public Server() { instance = this; } public static void main( String[] args ) { instance = new Server(); instance.startServerFromCommandLine( args ); } public static Server getInstance() { return instance; } public void startServerFromCommandLine( String[] args ) { org.apache.commons.cli.CommandLineParser parser = new org.apache.commons.cli.GnuParser(); line = null; try { line = parser.parse( createOptions(), args ); } catch ( org.apache.commons.cli.ParseException exp ) { printCliHelp( "Parsing failed. Reason: " + exp.getMessage() ); } if ( line == null ) { return; } startDatabaseWithServer = line.hasOption( "db" ); initializeDatabaseOnStart = line.hasOption( "init" ); if ( line.hasOption( "port" ) ) { try { port = ( ( Number ) line.getParsedOptionValue( "port" ) ).intValue(); } catch ( org.apache.commons.cli.ParseException exp ) { printCliHelp( "Parsing failed. Reason: " + exp.getMessage() ); return; } } startServer(); } @SuppressWarnings("InfiniteLoopStatement") public synchronized void startServer() { if ( startDatabaseWithServer ) { startCassandra(); } httpServer = org.glassfish.grizzly.http.server.HttpServer.createSimpleServer( ".", port ); handler = new org.glassfish.grizzly.servlet.ServletHandler(); handler.addContextParameter( com.sun.jersey.spi.spring.container.servlet.SpringServlet.CONTEXT_CONFIG_LOCATION, "classpath:/usergrid-standalone-context.xml" ); handler.addServletListener( org.springframework.web.context.ContextLoaderListener.class.getName() ); handler.addServletListener( org.springframework.web.context.request.RequestContextListener.class.getName() ); com.sun.jersey.api.json.JSONConfiguration.badgerFish(); handler.addInitParameter( com.sun.jersey.api.core.PackagesResourceConfig.PROPERTY_PACKAGES, "org.apache.usergrid" ); handler.addInitParameter( com.sun.jersey.api.json.JSONConfiguration.FEATURE_POJO_MAPPING, "true" ); handler.addInitParameter( com.sun.jersey.api.core.ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, "org.apache.usergrid.rest.filters.MeteringFilter,org.apache.usergrid.rest.filters.JSONPCallbackFilter," + "org.apache.usergrid.rest.security.shiro.filters.OAuth2AccessTokenSecurityFilter," + "org.apache.usergrid.rest.security.shiro.filters.BasicAuthSecurityFilter," + "org.apache.usergrid.rest.security.shiro.filters.ClientCredentialsSecurityFilter" ); handler.addInitParameter( com.sun.jersey.api.core.ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, "org.apache.usergrid.rest.security.CrossOriginRequestFilter,org.apache.usergrid.rest.filters.MeteringFilter" ); handler.addInitParameter( com.sun.jersey.api.core.ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, "org.apache.usergrid.rest.security.SecuredResourceFilterFactory,com.sun.jersey.api.container.filter" + ".RolesAllowedResourceFilterFactory" ); handler.addInitParameter( com.sun.jersey.api.core.ResourceConfig.FEATURE_DISABLE_WADL, "true" ); handler.addInitParameter( com.sun.jersey.spi.container.servlet.ServletContainer.JSP_TEMPLATES_BASE_PATH, "/WEB-INF/jsp" ); handler.addInitParameter( com.sun.jersey.spi.container.servlet.ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX, "/(((images|css|js|jsp|WEB-INF/jsp)/.*)|(favicon\\.ico))" ); handler.setServletInstance( new com.sun.jersey.spi.spring.container.servlet.SpringServlet() ); // handler.setServletPath("/ROOT"); // handler.setContextPath("/ROOT"); handler.setProperty( "load-on-startup", 1 ); java.util.Map<String, String> initParameters = new java.util.HashMap<String, String>(); initParameters.put( "targetFilterLifecycle", "true" ); handler.addFilter( new org.apache.usergrid.rest.filters.ContentTypeFilter(), "contentTypeFilter", java.util.Collections.EMPTY_MAP ); handler.addFilter( new org.springframework.web.filter.DelegatingFilterProxy(), "shiroFilter", initParameters ); handler.addFilter( new org.apache.usergrid.rest.SwaggerServlet(), "swagger", null ); // handler.addFilter(new SpringServlet(), "spring", null); setupJspMappings(); httpServer.getServerConfiguration().addHttpHandler( handler, "/*" ); // TODO: find replacement ClasspathStaticHandler, because we had to remove it for ASF policy reasons // ClasspathStaticHttpHandler static_handler = new ClasspathStaticHttpHandler( "/html/css/" ); // httpServer.getServerConfiguration().addHttpHandler( static_handler, "/css/*" ); httpServer.getServerConfiguration().setJmxEnabled( true ); setThreadSize(); try { httpServer.start(); } catch ( java.io.IOException e ) { e.printStackTrace(); } if ( daemon ) { while ( true ) { try { Thread.sleep( Long.MAX_VALUE ); } catch ( InterruptedException e ) { logger.warn( "Interrupted" ); } } } } private int getThreadSizeFromSystemProperties() { // the default value is number of cpu core * 2. // see org.glassfich.grizzly.strategies.AbstractIOStrategy.createDefaultWorkerPoolconfig() int threadSize = Runtime.getRuntime().availableProcessors() * 2; String threadSizeString = System.getProperty( "server.threadSize" ); if ( threadSizeString != null ) { try { threadSize = Integer.parseInt( threadSizeString ); } catch ( Exception e ) { // ignore all Exception } } else { try { threadSize = Integer.parseInt( System.getProperty( "server.threadSizeScale" ) ) * Runtime.getRuntime() .availableProcessors(); } catch ( Exception e ) { // ignore all Exception } } return threadSize; } private void setThreadSize() { int threadSize = getThreadSizeFromSystemProperties(); java.util.Collection<org.glassfish.grizzly.http.server.NetworkListener> listeners = httpServer.getListeners(); for ( org.glassfish.grizzly.http.server.NetworkListener listener : listeners ) { listener.getTransport().getKernelThreadPoolConfig(); org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder builder = org.glassfish.grizzly.nio.transport .TCPNIOTransportBuilder.newInstance(); org.glassfish.grizzly.threadpool.ThreadPoolConfig config = builder.getWorkerThreadPoolConfig(); config.setCorePoolSize( threadSize ); config.setMaxPoolSize( threadSize ); org.glassfish.grizzly.nio.transport.TCPNIOTransport transport = builder.build(); listener.setTransport( transport ); } logger.info( "thread size set as {}", threadSize ); } private void setupJspMappings() { if ( !INSTALL_JSP_SERVLETS ) { return; } org.apache.jasper.runtime.JspFactoryImpl factory = new org.apache.jasper.runtime.JspFactoryImpl(); javax.servlet.jsp.JspFactory.setDefaultFactory( factory ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.TestResource.error_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/TestResource/error.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.TestResource.test_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/TestResource/test.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UsersResource.error_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UsersResource/error.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UsersResource.resetpw_005femail_005fform_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UsersResource/resetpw_email_form.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UsersResource" + ".resetpw_005femail_005fsuccess_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UsersResource/resetpw_email_success.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UserResource.activate_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UserResource/activate.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UserResource.confirm_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UserResource/confirm.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UserResource.error_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UserResource/error.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UserResource.resetpw_005femail_005fform_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UserResource/resetpw_email_form.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UserResource.resetpw_005femail_005fsuccess_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UserResource/resetpw_email_success.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UserResource.resetpw_005fset_005fform_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UserResource/resetpw_set_form.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.users.UserResource.resetpw_005fset_005fsuccess_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/users/UserResource/resetpw_set_success.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.organizations.OrganizationResource.activate_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/organizations/OrganizationResource/activate.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.organizations.OrganizationResource.confirm_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/organizations/OrganizationResource/confirm.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.organizations.OrganizationResource.error_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/organizations/OrganizationResource/error.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.ManagementResource.authorize_005fform_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/ManagementResource/authorize_form.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.management.ManagementResource.error_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/management/ManagementResource/error.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UsersResource.error_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UsersResource/error.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UsersResource.resetpw_005femail_005fform_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UsersResource/resetpw_email_form.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UsersResource" + ".resetpw_005femail_005fsuccess_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UsersResource/resetpw_email_success.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UserResource.activate_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UserResource/activate.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UserResource.confirm_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UserResource/confirm.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UserResource.error_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UserResource/error.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UserResource.resetpw_005femail_005fform_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UserResource/resetpw_email_form.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UserResource" + ".resetpw_005femail_005fsuccess_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UserResource/resetpw_email_success.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UserResource.resetpw_005fset_005fform_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UserResource/resetpw_set_form.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.users.UserResource.resetpw_005fset_005fsuccess_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/users/UserResource/resetpw_set_success.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.ApplicationResource.authorize_005fform_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/ApplicationResource/authorize_form.jsp" ); mapServlet( "jsp.WEB_002dINF.jsp.org.apache.usergrid.rest.applications.ApplicationResource.error_jsp", "/WEB-INF/jsp/org/apache/usergrid/rest/applications/ApplicationResource/error.jsp" ); } private void mapServlet( String cls, String mapping ) { try { javax.servlet.Servlet servlet = ( javax.servlet.Servlet ) org.glassfish.grizzly.http.server.util .ClassLoaderUtil.load( cls ); if ( servlet != null ) { org.glassfish.grizzly.servlet.ServletHandler handler = new org.glassfish.grizzly.servlet.ServletHandler( servlet ); handler.setServletPath( mapping ); httpServer.getServerConfiguration().addHttpHandler( handler, mapping ); } } catch ( Exception e ) { logger.error( "Unable to add JSP page: " + mapping ); } logger.info( "jsp: " + javax.servlet.jsp.JspFactory.getDefaultFactory() ); } public synchronized void stopServer() { java.util.Collection<org.glassfish.grizzly.http.server.NetworkListener> listeners = httpServer.getListeners(); for ( org.glassfish.grizzly.http.server.NetworkListener listener : listeners ) { try { listener.stop(); } catch ( java.io.IOException e ) { e.printStackTrace(); } } if ( httpServer != null ) { httpServer.stop(); httpServer = null; } if ( embeddedCassandra != null ) { stopCassandra(); embeddedCassandra = null; } if ( ctx instanceof org.springframework.web.context.support.XmlWebApplicationContext ) { ( ( org.springframework.web.context.support.XmlWebApplicationContext ) ctx ).close(); } } public void setDaemon( boolean daemon ) { this.daemon = daemon; } public boolean isRunning() { return ( httpServer != null ); } static void printCliHelp( String message ) { System.out.println( message ); org.apache.commons.cli.HelpFormatter formatter = new org.apache.commons.cli.HelpFormatter(); formatter.printHelp( "java -jar usergrid-standalone-0.0.1-SNAPSHOT.jar ", createOptions() ); System.exit( -1 ); } static Options createOptions() { // the nogui option will be required due to combining the graphical // launcher with this standalone CLI based server Options options = new Options(); OptionBuilder.withDescription( "Start launcher without UI" ); OptionBuilder.isRequired( true ); Option noguiOption = OptionBuilder.create( "nogui" ); OptionBuilder.isRequired( false ); OptionBuilder.withDescription( "Initialize database" ); Option initOption = OptionBuilder.create( "init" ); OptionBuilder.withDescription( "Start database" ); Option dbOption = OptionBuilder.create( "db" ); OptionBuilder.withDescription( "Http port (without UI)" ); OptionBuilder.hasArg(); OptionBuilder.withArgName( "PORT" ); OptionBuilder.withLongOpt( "port" ); OptionBuilder.withType( Number.class ); Option portOption = OptionBuilder.create( 'p' ); options.addOption( initOption ); options.addOption( dbOption ); options.addOption( portOption ); options.addOption( noguiOption ); return options; } public synchronized void startCassandra() { if ( embeddedCassandra == null ) { embeddedCassandra = new EmbeddedServerHelper(); if ( initializeDatabaseOnStart ) { logger.info( "Initializing Cassandra" ); try { embeddedCassandra.setup(); } catch ( Exception e ) { logger.error( "Unable to initialize Cassandra", e ); System.exit( 0 ); } } } logger.info( "Starting Cassandra" ); try { embeddedCassandra.start(); } catch ( Exception e ) { logger.error( "Unable to start Cassandra", e ); System.exit( 0 ); } } public synchronized void stopCassandra() { logger.info( "Stopping Cassandra" ); embeddedCassandra.stop(); } public org.apache.usergrid.persistence.EntityManagerFactory getEntityManagerFactory() { return emf; } @org.springframework.beans.factory.annotation.Autowired public void setEntityManagerFactory( org.apache.usergrid.persistence.EntityManagerFactory emf ) { this.emf = emf; } public org.apache.usergrid.services.ServiceManagerFactory getServiceManagerFactory() { return smf; } @org.springframework.beans.factory.annotation.Autowired public void setServiceManagerFactory( org.apache.usergrid.services.ServiceManagerFactory smf ) { this.smf = smf; } public org.apache.usergrid.management.ManagementService getManagementService() { return management; } @org.springframework.beans.factory.annotation.Autowired public void setManagementService( org.apache.usergrid.management.ManagementService management ) { this.management = management; } public java.util.Properties getProperties() { return properties; } @org.springframework.beans.factory.annotation.Autowired public void setProperties( java.util.Properties properties ) { this.properties = properties; } public org.apache.usergrid.mq.QueueManagerFactory getQueueManagerFactory() { return qmf; } @org.springframework.beans.factory.annotation.Autowired public void setQueueManagerFactory( org.apache.usergrid.mq.QueueManagerFactory qmf ) { this.qmf = qmf; } public boolean isInitializeDatabaseOnStart() { return initializeDatabaseOnStart; } public void setInitializeDatabaseOnStart( boolean initializeDatabaseOnStart ) { this.initializeDatabaseOnStart = initializeDatabaseOnStart; } public boolean isStartDatabaseWithServer() { return startDatabaseWithServer; } public void setStartDatabaseWithServer( boolean startDatabaseWithServer ) { this.startDatabaseWithServer = startDatabaseWithServer; } boolean databaseInitializationPerformed = false; public void springInit() { logger.info( "Initializing server with Spring" ); // If we're running an embedded Cassandra, we always need to initialize // it since Hector wipes the data on startup. // if ( initializeDatabaseOnStart ) { if ( databaseInitializationPerformed ) { logger.info( "Can only attempt to initialized database once per JVM process" ); return; } databaseInitializationPerformed = true; logger.info( "Initializing Cassandra database" ); java.util.Map<String, String> properties = emf.getServiceProperties(); if ( properties != null ) { logger.error( "System properties are initialized, database is set up already." ); return; } try { emf.setup(); } catch ( Exception e ) { logger.error( "Unable to complete core database setup, possibly due to it being setup already", e ); } try { management.setup(); } catch ( Exception e ) { logger.error( "Unable to complete management database setup, possibly due to it being setup already", e ); } logger.info( "Usergrid schema setup" ); } } org.springframework.context.ApplicationContext ctx; @Override public void setApplicationContext( org.springframework.context.ApplicationContext ctx ) throws org.springframework.beans.BeansException { this.ctx = ctx; } public String getAccessTokenForAdminUser( String email ) { try { org.apache.usergrid.management.UserInfo user = management.getAdminUserByEmail( email ); return management.getAccessTokenForAdminUser( user.getUuid(), 0 ); } catch ( Exception e ) { logger.error( "Unable to get user: " + email ); } return null; } public java.util.UUID getAdminUUID( String email ) { try { org.apache.usergrid.management.UserInfo user = management.getAdminUserByEmail( email ); return user.getUuid(); } catch ( Exception e ) { logger.error( "Unable to get user: " + email ); } return null; } }