Ejemplo n.º 1
0
  public NiFi(final NiFiProperties properties)
      throws ClassNotFoundException, IOException, NoSuchMethodException, InstantiationException,
          IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    Thread.setDefaultUncaughtExceptionHandler(
        new UncaughtExceptionHandler() {
          @Override
          public void uncaughtException(final Thread t, final Throwable e) {
            logger.error("An Unknown Error Occurred in Thread {}: {}", t, e.toString());
            logger.error("", e);
          }
        });

    // register the shutdown hook
    Runtime.getRuntime()
        .addShutdownHook(
            new Thread(
                new Runnable() {
                  @Override
                  public void run() {
                    // shutdown the jetty server
                    shutdownHook();
                  }
                }));

    final String bootstrapPort = System.getProperty(BOOTSTRAP_PORT_PROPERTY);
    if (bootstrapPort != null) {
      try {
        final int port = Integer.parseInt(bootstrapPort);

        if (port < 1 || port > 65535) {
          throw new RuntimeException(
              "Failed to start NiFi because system property '"
                  + BOOTSTRAP_PORT_PROPERTY
                  + "' is not a valid integer in the range 1 - 65535");
        }

        bootstrapListener = new BootstrapListener(this, port);
        bootstrapListener.start();
      } catch (final NumberFormatException nfe) {
        throw new RuntimeException(
            "Failed to start NiFi because system property '"
                + BOOTSTRAP_PORT_PROPERTY
                + "' is not a valid integer in the range 1 - 65535");
      }
    } else {
      logger.info(
          "NiFi started without Bootstrap Port information provided; will not listen for requests from Bootstrap");
      bootstrapListener = null;
    }

    // delete the web working dir - if the application does not start successfully
    // the web app directories might be in an invalid state. when this happens
    // jetty will not attempt to re-extract the war into the directory. by removing
    // the working directory, we can be assured that it will attempt to extract the
    // war every time the application starts.
    File webWorkingDir = properties.getWebWorkingDirectory();
    FileUtils.deleteFilesInDirectory(webWorkingDir, null, logger, true, true);
    FileUtils.deleteFile(webWorkingDir, logger, 3);

    detectTimingIssues();

    // redirect JUL log events
    SLF4JBridgeHandler.removeHandlersForRootLogger();
    SLF4JBridgeHandler.install();

    // expand the nars
    final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);

    // load the extensions classloaders
    NarClassLoaders.getInstance()
        .init(
            properties.getFrameworkWorkingDirectory(), properties.getExtensionsWorkingDirectory());

    // load the framework classloader
    final ClassLoader frameworkClassLoader =
        NarClassLoaders.getInstance().getFrameworkClassLoader();
    if (frameworkClassLoader == null) {
      throw new IllegalStateException("Unable to find the framework NAR ClassLoader.");
    }

    // discover the extensions
    ExtensionManager.discoverExtensions(NarClassLoaders.getInstance().getExtensionClassLoaders());
    ExtensionManager.logClassLoaderMapping();

    DocGenerator.generate(properties);

    // load the server from the framework classloader
    Thread.currentThread().setContextClassLoader(frameworkClassLoader);
    Class<?> jettyServer =
        Class.forName("org.apache.nifi.web.server.JettyServer", true, frameworkClassLoader);
    Constructor<?> jettyConstructor = jettyServer.getConstructor(NiFiProperties.class);

    final long startTime = System.nanoTime();
    nifiServer = (NiFiServer) jettyConstructor.newInstance(properties);
    nifiServer.setExtensionMapping(extensionMapping);

    if (shutdown) {
      logger.info("NiFi has been shutdown via NiFi Bootstrap. Will not start Controller");
    } else {
      nifiServer.start();

      if (bootstrapListener != null) {
        bootstrapListener.sendStartedStatus(true);
      }

      final long endTime = System.nanoTime();
      logger.info("Controller initialization took " + (endTime - startTime) + " nanoseconds.");
    }
  }
Ejemplo n.º 2
0
  /** Should be called at most once. */
  private InitContext load(final File frameworkWorkingDir, final File extensionsWorkingDir)
      throws IOException, ClassNotFoundException {
    // get the system classloader
    final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();

    // find all nar files and create class loaders for them.
    final Map<String, ClassLoader> extensionDirectoryClassLoaderLookup = new LinkedHashMap<>();
    final Map<String, ClassLoader> narIdClassLoaderLookup = new HashMap<>();

    // make sure the nar directory is there and accessible
    FileUtils.ensureDirectoryExistAndCanAccess(frameworkWorkingDir);
    FileUtils.ensureDirectoryExistAndCanAccess(extensionsWorkingDir);

    final List<File> narWorkingDirContents = new ArrayList<>();
    final File[] frameworkWorkingDirContents = frameworkWorkingDir.listFiles();
    if (frameworkWorkingDirContents != null) {
      narWorkingDirContents.addAll(Arrays.asList(frameworkWorkingDirContents));
    }
    final File[] extensionsWorkingDirContents = extensionsWorkingDir.listFiles();
    if (extensionsWorkingDirContents != null) {
      narWorkingDirContents.addAll(Arrays.asList(extensionsWorkingDirContents));
    }

    if (!narWorkingDirContents.isEmpty()) {
      final List<NarDetails> narDetails = new ArrayList<>();

      // load the nar details which includes and nar dependencies
      for (final File unpackedNar : narWorkingDirContents) {
        final NarDetails narDetail = getNarDetails(unpackedNar);

        // ensure the nar contained an identifier
        if (narDetail.getNarId() == null) {
          logger.warn("No NAR Id found. Skipping: " + unpackedNar.getAbsolutePath());
          continue;
        }

        // store the nar details
        narDetails.add(narDetail);
      }

      // attempt to locate the jetty nar
      ClassLoader jettyClassLoader = null;
      for (final Iterator<NarDetails> narDetailsIter = narDetails.iterator();
          narDetailsIter.hasNext(); ) {
        final NarDetails narDetail = narDetailsIter.next();

        // look for the jetty nar
        if (JETTY_NAR_ID.equals(narDetail.getNarId())) {
          // create the jetty classloader
          jettyClassLoader =
              createNarClassLoader(narDetail.getNarWorkingDirectory(), systemClassLoader);

          // remove the jetty nar since its already loaded
          narIdClassLoaderLookup.put(narDetail.getNarId(), jettyClassLoader);
          narDetailsIter.remove();
          break;
        }
      }

      // ensure the jetty nar was found
      if (jettyClassLoader == null) {
        throw new IllegalStateException("Unable to locate Jetty bundle.");
      }

      int narCount;
      do {
        // record the number of nars to be loaded
        narCount = narDetails.size();

        // attempt to create each nar class loader
        for (final Iterator<NarDetails> narDetailsIter = narDetails.iterator();
            narDetailsIter.hasNext(); ) {
          final NarDetails narDetail = narDetailsIter.next();
          final String narDependencies = narDetail.getNarDependencyId();

          // see if this class loader is eligible for loading
          ClassLoader narClassLoader = null;
          if (narDependencies == null) {
            narClassLoader =
                createNarClassLoader(narDetail.getNarWorkingDirectory(), jettyClassLoader);
          } else if (narIdClassLoaderLookup.containsKey(narDetail.getNarDependencyId())) {
            narClassLoader =
                createNarClassLoader(
                    narDetail.getNarWorkingDirectory(),
                    narIdClassLoaderLookup.get(narDetail.getNarDependencyId()));
          }

          // if we were able to create the nar class loader, store it and remove the details
          if (narClassLoader != null) {
            extensionDirectoryClassLoaderLookup.put(
                narDetail.getNarWorkingDirectory().getCanonicalPath(), narClassLoader);
            narIdClassLoaderLookup.put(narDetail.getNarId(), narClassLoader);
            narDetailsIter.remove();
          }
        }

        // attempt to load more if some were successfully loaded this iteration
      } while (narCount != narDetails.size());

      // see if any nars couldn't be loaded
      for (final NarDetails narDetail : narDetails) {
        logger.warn(
            String.format(
                "Unable to resolve required dependency '%s'. Skipping NAR %s",
                narDetail.getNarDependencyId(),
                narDetail.getNarWorkingDirectory().getAbsolutePath()));
      }
    }

    return new InitContext(
        frameworkWorkingDir,
        extensionsWorkingDir,
        narIdClassLoaderLookup.get(FRAMEWORK_NAR_ID),
        new LinkedHashMap<>(extensionDirectoryClassLoaderLookup));
  }