public void run()

in ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java [318:617]


  public void run() throws Exception {
    setupJulLogging();


    performStaticInjection();
    initDB();
    // Client Jetty thread pool - widen the thread pool if needed !
    Integer clientAcceptors = configs.getClientApiAcceptors() != null ? configs
      .getClientApiAcceptors() : DEFAULT_ACCEPTORS_COUNT;

    server = configureJettyThreadPool(clientAcceptors, CLIENT_THREAD_POOL_NAME,
      configs.getClientThreadPoolSize());

    final SessionIdManager sessionIdManager = new DefaultSessionIdManager(server);
    sessionHandler.setSessionIdManager(sessionIdManager);
    server.setSessionIdManager(sessionIdManager);

    // Agent Jetty thread pool - widen the thread pool if needed !
    Integer agentAcceptors = configs.getAgentApiAcceptors() != null ?
      configs.getAgentApiAcceptors() : DEFAULT_ACCEPTORS_COUNT;

    Server serverForAgent = configureJettyThreadPool(agentAcceptors * 2,
      AGENT_THREAD_POOL_NAME, configs.getAgentThreadPoolSize());

    setSystemProperties(configs);

    runDatabaseConsistencyCheck();

    try {
      ClassPathXmlApplicationContext parentSpringAppContext =
          new ClassPathXmlApplicationContext();
      parentSpringAppContext.refresh();
      ConfigurableListableBeanFactory factory = parentSpringAppContext.
          getBeanFactory();

      factory.registerSingleton("injector", injector);
      //todo unable to register Users class as Spring @Bean since it tries to process @Inject annotations, investigate
      factory.registerSingleton("ambariUsers", injector.getInstance(Users.class));

      //create spring context for web api
      AnnotationConfigWebApplicationContext apiContext = new AnnotationConfigWebApplicationContext();
      apiContext.setParent(parentSpringAppContext);
      apiContext.register(ApiSecurityConfig.class);
      //refresh will be called in ContextLoaderListener

      AnnotationConfigWebApplicationContext apiDispatcherContext = new AnnotationConfigWebApplicationContext();
      apiDispatcherContext.register(ApiStompConfig.class);
      DispatcherServlet apiDispatcherServlet = new DispatcherServlet(apiDispatcherContext);

      AnnotationConfigWebApplicationContext agentDispatcherContext = new AnnotationConfigWebApplicationContext();
      agentDispatcherContext.register(AgentStompConfig.class);
      DispatcherServlet agentDispatcherServlet = new DispatcherServlet(agentDispatcherContext);

      ServletContextHandler root = new ServletContextHandler(
          ServletContextHandler.SECURITY | ServletContextHandler.SESSIONS);

      configureRootHandler(root);
      sessionHandlerConfigurer.configureSessionHandler(sessionHandler);
      root.setSessionHandler(sessionHandler);

      //ContextLoaderListener handles all work on registration in servlet container
      root.addEventListener(new ContextLoaderListener(apiContext));

      certMan.initRootCert();

      // the agent communication (heartbeats, registration, etc) is stateless
      // and does not use sessions.
      ServletContextHandler agentroot = new ServletContextHandler(
          serverForAgent, "/", ServletContextHandler.NO_SESSIONS);

      AnnotationConfigWebApplicationContext agentApiContext = new AnnotationConfigWebApplicationContext();
      agentApiContext.setParent(parentSpringAppContext);

      if (configs.isAgentApiGzipped()) {
        configureHandlerCompression(agentroot);
      }

      JettyWebSocketServletContainerInitializer initializerForAgentroot = new JettyWebSocketServletContainerInitializer((context, jettyContainer) -> {
        jettyContainer.setMaxTextMessageSize(configs.getStompMaxIncomingMessageSize());
        LOG.info("Configured WebSocket container max text message size: {}", configs.getStompMaxIncomingMessageSize());
      });

      agentroot.addEventListener(new ContextLoaderListener(agentApiContext));
      agentroot.addEventListener(new WebSocketInitializerListener(initializerForAgentroot));

      ServletHolder rootServlet = root.addServlet(DefaultServlet.class, "/");
      rootServlet.setInitParameter("dirAllowed", "false");
      rootServlet.setInitParameter("precompressed", "gzip=.gz");
      rootServlet.setInitOrder(1);

      /* Configure default servlet for agent server */
      rootServlet = agentroot.addServlet(DefaultServlet.class, "/");
      rootServlet.setInitOrder(1);

      // Conditionally adds security-related headers to all HTTP responses.
      root.addFilter(new FilterHolder(injector.getInstance(AmbariServerSecurityHeaderFilter.class)), "/*", DISPATCHER_TYPES);

      // The security header filter - conditionally adds security-related headers to the HTTP response for Ambari Views
      // requests.
      root.addFilter(new FilterHolder(injector.getInstance(AmbariViewsSecurityHeaderFilter.class)), VIEWS_URL_PATTERN,
          DISPATCHER_TYPES);

      // since views share the REST API threadpool, a misbehaving view could
      // consume all of the available threads and effectively cause a loss of
      // service for Ambari
      root.addFilter(new FilterHolder(injector.getInstance(ViewThrottleFilter.class)),
        VIEWS_URL_PATTERN, DISPATCHER_TYPES);

      // adds MDC info for views logging
      root.addFilter(new FilterHolder(injector.getInstance(AmbariViewsMDCLoggingFilter.class)),
        VIEWS_URL_PATTERN, DISPATCHER_TYPES);

      // session-per-request strategy for api
      root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/api/*", DISPATCHER_TYPES);
      root.addFilter(new FilterHolder(new MethodOverrideFilter()), "/api/*", DISPATCHER_TYPES);
      root.addFilter(new FilterHolder(new ContentTypeOverrideFilter()), "/api/*", DISPATCHER_TYPES);

      JettyWebSocketServletContainerInitializer initializerForRoot = new JettyWebSocketServletContainerInitializer((context, jettyContainer) -> {
        jettyContainer.setMaxTextMessageSize(configs.getStompMaxIncomingMessageSize());
        LOG.info("Configured WebSocket container max text message size: {}", configs.getStompMaxIncomingMessageSize());
      });

      // register listener to capture request context
      root.addEventListener(new RequestContextListener());
      root.addEventListener(new WebSocketInitializerListener(initializerForRoot));
      root.addFilter(new FilterHolder(springSecurityFilter), "/api/*", DISPATCHER_TYPES);
      root.addFilter(new FilterHolder(new UserNameOverrideFilter()), "/api/v1/users/*", DISPATCHER_TYPES);

      // session-per-request strategy for agents
      agentroot.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/agent/*", DISPATCHER_TYPES);
      agentroot.addFilter(SecurityFilter.class, "/*", DISPATCHER_TYPES);

      Map<String, String> configsMap = configs.getConfigsMap();

      // Agents download cert on on-way connector but always communicate on
      // two-way connector for server-agent communication
      ServerConnector agentOneWayConnector = createSelectChannelConnectorForAgent(serverForAgent, configs.getOneWayAuthPort(), false, agentAcceptors);
      ServerConnector agentTwoWayConnector = createSelectChannelConnectorForAgent(serverForAgent, configs.getTwoWayAuthPort(), configs.isTwoWaySsl(), agentAcceptors);

      serverForAgent.addConnector(agentOneWayConnector);
      serverForAgent.addConnector(agentTwoWayConnector);

      ServletHolder sh = new ServletHolder(new ServletContainer(new ResourceConfig().packages(
              "org.apache.ambari.server.api.rest",
              "org.apache.ambari.server.api.services",
              "org.apache.ambari.eventdb.webservice",
              "org.apache.ambari.server.api").register(org.glassfish.jersey.jackson.JacksonFeature.class)));
      root.addServlet(sh, "/api/v1/*");
      sh.setInitOrder(2);

      ServletHolder springDispatcherServlet = new ServletHolder("springDispatcherServlet", apiDispatcherServlet);
      springDispatcherServlet.setInitOrder(3);
      root.addServlet(springDispatcherServlet, "/api/stomp/*");

      ServletHolder agentSpringDispatcherServlet =
          new ServletHolder("agentSpringDispatcherServlet", agentDispatcherServlet);
      agentSpringDispatcherServlet.setInitOrder(2);
      agentroot.addServlet(agentSpringDispatcherServlet, "/agent/stomp/*");

      SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);

      viewRegistry.readViewArchives();

      //Check and load requestlog handler.
      loadRequestlogHandler(handlerList, serverForAgent, configsMap);

      enableLog4jMonitor(configsMap);

      if (configs.isGzipHandlerEnabledForJetty()) {
        GzipHandler gzipHandler = new GzipHandler();
        gzipHandler.setHandler(root);
        //TODO minimal set, perhaps is needed to add some other mime types
        gzipHandler.setIncludedMimeTypes("text/html", "text/plain", "text/xml", "text/css", "application/javascript",
          "application/x-javascript", "application/xml", "application/x-www-form-urlencoded", "application/json");
        handlerList.addHandler(gzipHandler);
      } else {
        handlerList.addHandler(root);
      }

      server.setHandler(handlerList);

      ServletHolder agent = new ServletHolder(new ServletContainer(new ResourceConfig()
              .packages("org.apache.ambari.server.agent.rest", "org.apache.ambari.server.api")
              .register(org.glassfish.jersey.jackson.JacksonFeature.class)));
      agentroot.addServlet(agent, "/agent/v1/*");
      agent.setInitOrder(3);

      injector.getInstance(HeartBeatHandler.class).start();
      LOG.info("********** Started Heartbeat handler **********");

      ServletHolder cert = new ServletHolder(new ServletContainer(new ResourceConfig()
              .packages("org.apache.ambari.server.security.unsecured.rest", "org.apache.ambari.server.api")
              .register(org.glassfish.jersey.jackson.JacksonFeature.class)));
      agentroot.addServlet(cert, "/*");
      cert.setInitOrder(4);

      File resourcesDirectory = new File(configs.getResourceDirPath());
      ServletHolder resources = new ServletHolder(DefaultServlet.class);
      resources.setInitParameter("resourceBase", resourcesDirectory.getParent());
      resources.setInitParameter("dirAllowed", "false");
      root.addServlet(resources, "/resources/*");
      resources.setInitOrder(5);

      if (configs.csrfProtectionEnabled()) {
        sh.setInitParameter("org.glassfish.jersey.server.ContainerRequestFilter",
            "org.apache.ambari.server.api.AmbariCsrfProtectionFilter");
      }

      /* Configure the API server to use the NIO connectors */
      ServerConnector apiConnector = createSelectChannelConnectorForClient(server, clientAcceptors);

      server.addConnector(apiConnector);

      server.setStopAtShutdown(true);
      serverForAgent.setStopAtShutdown(true);
//todo remove      springAppContext.start();

      String osType = getServerOsType();
      if (osType == null || osType.isEmpty()) {
        throw new RuntimeException(Configuration.OS_VERSION.getKey() + " is not "
            + " set in the ambari.properties file");
      }

      //Start action scheduler
      LOG.info("********* Initializing Clusters **********");
      Clusters clusters = injector.getInstance(Clusters.class);
      StringBuilder clusterDump = new StringBuilder();
      //TODO temporally commented because takes a lot of time on 5k cluster
      //clusters.debugDump(clusterDump);

      LOG.info("********* Current Clusters State *********");
      LOG.info(clusterDump.toString());

      LOG.info("********* Reconciling Alert Definitions **********");
      ambariMetaInfo.reconcileAlertDefinitions(clusters, false);

      LOG.info("********* Initializing ActionManager **********");
      ActionManager manager = injector.getInstance(ActionManager.class);

      LOG.info("********* Initializing Controller **********");
      AmbariManagementController controller = injector.getInstance(
          AmbariManagementController.class);

      LOG.info("********* Initializing Scheduled Request Manager **********");
      ExecutionScheduleManager executionScheduleManager = injector
          .getInstance(ExecutionScheduleManager.class);

      MetricsService metricsService = injector.getInstance(
        MetricsService.class);

      clusterController = controller;

      StateRecoveryManager recoveryManager = injector.getInstance(
          StateRecoveryManager.class);

      recoveryManager.doWork();
      /*
       * Start the server after controller state is recovered.
       */
      server.start();
      handlerList.shareSessionCacheToViews(sessionHandler.getSessionCache());

      //views initialization will reset inactive interval with default value, so we should set it after
      sessionHandlerConfigurer.configureMaxInactiveInterval(sessionHandler);

      serverForAgent.start();
      LOG.info("********* Started Server **********");

      if( !configs.isViewDirectoryWatcherServiceDisabled()) {
        LOG.info("Starting View Directory Watcher");
        viewDirectoryWatcher.start();
      }

      manager.start();
      LOG.info("********* Started ActionManager **********");

      executionScheduleManager.start();
      LOG.info("********* Started Scheduled Request Manager **********");

      serviceManager.startAsync();
      LOG.info("********* Started Services **********");

      if (!configs.isMetricsServiceDisabled()) {
        metricsService.start();
      } else {
        LOG.info("AmbariServer Metrics disabled.");
      }

      server.join();
      LOG.info("Joined the Server");
    } catch (BadPaddingException bpe) {
      LOG.error("Bad keystore or private key password. " +
          "HTTPS certificate re-importing may be required.");
      throw bpe;
    } catch (BindException bindException) {
      LOG.error("Could not bind to server port - instance may already be running. " +
          "Terminating this instance.", bindException);
      throw bindException;
    }
  }