NIFI-11220 Removed nifi-bootstrap-utils

- Replaced OSUtils.getProcessId() with java.lang.Process.pid() available on Java 9 and following

Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com>

This closes #6989.
This commit is contained in:
exceptionfactory 2023-02-25 14:09:35 -06:00 committed by Pierre Villard
parent 84047c135b
commit c8b5c0ce7b
No known key found for this signature in database
GPG Key ID: F92A93B30C07C6D5
21 changed files with 63 additions and 469 deletions

View File

@ -110,10 +110,6 @@ limitations under the License.
<scope>runtime</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap-utils</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi.minifi</groupId>
<artifactId>minifi-bootstrap</artifactId>

View File

@ -33,7 +33,6 @@
<fileMode>0660</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<excludes>
<exclude>*:nifi-bootstrap-utils</exclude>
<exclude>*:minifi-bootstrap</exclude>
<exclude>*:minifi-resources</exclude>
<!-- Filter items introduced via transitive dependencies that are provided in associated NARs -->
@ -50,7 +49,6 @@
<fileMode>0660</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<includes>
<include>*:nifi-bootstrap-utils</include>
<include>*:minifi-bootstrap</include>
<include>*:minifi-utils</include>
<include>*:nifi-utils</include>

View File

@ -33,7 +33,6 @@
<fileMode>0660</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<excludes>
<exclude>*:nifi-bootstrap-utils</exclude>
<exclude>*:minifi-bootstrap</exclude>
<exclude>*:minifi-resources</exclude>
<!-- Filter items introduced via transitive dependencies that are provided in associated NARs -->
@ -50,7 +49,6 @@
<fileMode>0660</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<includes>
<include>*:nifi-bootstrap-utils</include>
<include>*:minifi-bootstrap</include>
<include>*:minifi-utils</include>
<include>*:nifi-utils</include>

View File

@ -45,14 +45,6 @@ limitations under the License.
<artifactId>c2-client-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap-utils</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-deprecation-log</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-expression-language</artifactId>

View File

@ -46,10 +46,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.nifi.bootstrap.util.OSUtils;
import org.apache.nifi.bootstrap.util.RuntimeVersionProvider;
import org.apache.nifi.deprecation.log.DeprecationLogger;
import org.apache.nifi.deprecation.log.DeprecationLoggerFactory;
import org.apache.nifi.minifi.bootstrap.MiNiFiParameters;
import org.apache.nifi.minifi.bootstrap.RunMiNiFi;
import org.apache.nifi.minifi.bootstrap.ShutdownHook;
@ -66,8 +62,6 @@ import org.apache.nifi.minifi.bootstrap.service.PeriodicStatusReporterManager;
public class StartRunner implements CommandRunner {
private static final int STARTUP_WAIT_SECONDS = 60;
private static final DeprecationLogger deprecationLogger = DeprecationLoggerFactory.getLogger(StartRunner.class);
private final CurrentPortProvider currentPortProvider;
private final BootstrapFileProvider bootstrapFileProvider;
private final PeriodicStatusReporterManager periodicStatusReporterManager;
@ -120,11 +114,6 @@ public class StartRunner implements CommandRunner {
return;
}
final int javaMajorVersion = RuntimeVersionProvider.getMajorVersion();
if (RuntimeVersionProvider.isMajorVersionDeprecated(javaMajorVersion)) {
deprecationLogger.warn("Support for Java {} is deprecated. Java {} is the minimum recommended version", javaMajorVersion, RuntimeVersionProvider.getMinimumMajorVersion());
}
File prevLockFile = bootstrapFileProvider.getLockFile();
if (prevLockFile.exists() && !prevLockFile.delete()) {
CMD_LOGGER.warn("Failed to delete previous lock file {}; this file should be cleaned up manually", prevLockFile);
@ -203,12 +192,12 @@ public class StartRunner implements CommandRunner {
boolean started = waitForStart();
final long pid = process.pid();
if (started) {
runMiNiFi.sendAcknowledgeToMiNiFi(configChangeSuccessful ? FULLY_APPLIED : NOT_APPLIED_WITH_RESTART);
Long pid = OSUtils.getProcessId(process, DEFAULT_LOGGER);
DEFAULT_LOGGER.info("Successfully spawned the thread to start Apache MiNiFi{}", (pid == null ? "" : " with PID " + pid));
DEFAULT_LOGGER.info("Application Process [{}] started", pid);
} else {
DEFAULT_LOGGER.error("Apache MiNiFi does not appear to have started");
DEFAULT_LOGGER.info("Application Process [{}] not started", pid);
}
return process;
}
@ -333,18 +322,16 @@ public class StartRunner implements CommandRunner {
return builder;
}
private Process startMiNiFiProcess(ProcessBuilder builder) throws IOException {
Process process = builder.start();
private Process startMiNiFiProcess(final ProcessBuilder builder) throws IOException {
final Process process = builder.start();
miNiFiStdLogHandler.initLogging(process);
miNiFiParameters.setMiNiFiPort(UNINITIALIZED);
miNiFiParameters.setMinifiPid(UNINITIALIZED);
Long pid = OSUtils.getProcessId(process, CMD_LOGGER);
if (pid != null) {
final long pid = process.pid();
miNiFiParameters.setMinifiPid(pid);
Properties minifiProps = new Properties();
final Properties minifiProps = new Properties();
minifiProps.setProperty(STATUS_FILE_PID_KEY, String.valueOf(pid));
bootstrapFileProvider.saveStatusProperties(minifiProps);
}
shutdownHook = new ShutdownHook(runMiNiFi, miNiFiStdLogHandler);
Runtime.getRuntime().addShutdownHook(shutdownHook);

View File

@ -46,16 +46,6 @@ limitations under the License.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap-utils</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-deprecation-log</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi.minifi</groupId>
<artifactId>minifi-bootstrap</artifactId>

View File

@ -163,11 +163,6 @@ language governing permissions and limitations under the License. -->
<artifactId>nifi-bootstrap</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap-utils</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-utils</artifactId>

View File

@ -24,7 +24,6 @@
<fileMode>0664</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<includes>
<include>*:nifi-bootstrap-utils</include>
<include>*:nifi-bootstrap</include>
<include>*:slf4j-api</include>
<include>*:logback-classic</include>

View File

@ -32,7 +32,6 @@
<fileMode>0664</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<excludes>
<exclude>*:nifi-bootstrap-utils</exclude>
<exclude>*:nifi-bootstrap</exclude>
<exclude>*:nifi-property-protection-api</exclude>
<exclude>*:nifi-property-protection-factory</exclude>

View File

@ -37,7 +37,6 @@
<fileMode>0660</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<excludes>
<exclude>*:nifi-bootstrap-utils</exclude>
<exclude>*:nifi-bootstrap</exclude>
<exclude>*:nifi-property-protection-api</exclude>
<exclude>*:nifi-property-protection-factory</exclude>

View File

@ -30,16 +30,6 @@ language governing permissions and limitations under the License. -->
<version>2.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-deprecation-log</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap-utils</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-utils</artifactId>

View File

@ -19,7 +19,6 @@ package org.apache.nifi.bootstrap;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.bootstrap.notification.NotificationType;
import org.apache.nifi.bootstrap.util.DumpFileValidator;
import org.apache.nifi.bootstrap.util.OSUtils;
import org.apache.nifi.bootstrap.util.SecureNiFiConfigUtil;
import org.apache.nifi.util.file.FileUtils;
import org.slf4j.Logger;
@ -51,9 +50,8 @@ import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -188,11 +186,7 @@ public class RunNiFi {
System.out.println();
}
private static String[] shift(final String[] orig) {
return Arrays.copyOfRange(orig, 1, orig.length);
}
public static void main(String[] args) throws IOException, InterruptedException {
public static void main(String[] args) throws IOException {
if (args.length < 1 || args.length > 3) {
printUsage();
return;
@ -517,7 +511,7 @@ public class RunNiFi {
fos.getFD().sync();
}
logger.debug("Saved Properties {} to {}", new Object[]{pidProperties, statusFile});
logger.debug("Saved Properties {} to {}", pidProperties, statusFile);
}
private synchronized void writePidFile(final String pid, final Logger logger) throws IOException {
@ -548,7 +542,7 @@ public class RunNiFi {
fos.getFD().sync();
}
logger.debug("Saved Pid {} to {}", new Object[]{pid, pidFile});
logger.debug("Saved PID [{}] to [{}]", pid, pidFile);
}
private boolean isPingSuccessful(final int port, final String secretKey, final Logger logger) {
@ -684,13 +678,12 @@ public class RunNiFi {
final Logger logger = cmdLogger;
final Status status = getStatus(logger);
if (status.isRespondingToPing()) {
logger.info("Apache NiFi is currently running, listening to Bootstrap on port {}, PID={}",
new Object[]{status.getPort(), status.getPid() == null ? "unknown" : status.getPid()});
logger.info("Apache NiFi PID [{}] running with Bootstrap Port [{}]", status.getPid(), status.getPort());
return 0;
}
if (status.isProcessRunning()) {
logger.info("Apache NiFi is running at PID {} but is not responding to ping requests", status.getPid());
logger.info("Apache NiFi PID [{}] running but not responding with Bootstrap Port [{}]", status.getPid(), status.getPort());
return 4;
}
@ -866,8 +859,7 @@ public class RunNiFi {
public void notifyStop() {
final String hostname = getHostname();
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
final String now = sdf.format(System.currentTimeMillis());
final String now = Instant.now().toString();
String user = System.getProperty("user.name");
if (user == null || user.trim().isEmpty()) {
user = "Unknown User";
@ -982,9 +974,9 @@ public class RunNiFi {
} catch (final IOException ioe) {
if (pid == null) {
logger.error("Failed to send shutdown command to port {} due to {}. No PID found for the NiFi process, so unable to kill process; "
+ "the process should be killed manually.", new Object[]{port, ioe.toString()});
+ "the process should be killed manually.", port, ioe.toString());
} else {
logger.error("Failed to send shutdown command to port {} due to {}. Will kill the NiFi Process with PID {}.", port, ioe.toString(), pid);
logger.error("Failed to send shutdown command to port {} due to {}. Will kill the NiFi Process with PID {}.", port, ioe, pid);
notifyStop();
killProcessTree(pid, logger);
if (statusFile.exists() && !statusFile.delete()) {
@ -1076,7 +1068,7 @@ public class RunNiFi {
logger.debug("Killing Process Tree for PID {}", pid);
final List<String> children = getChildProcesses(pid);
logger.debug("Children of PID {}: {}", new Object[]{pid, children});
logger.debug("Children of PID {}: {}", pid, children);
for (final String childPid : children) {
killProcessTree(childPid, logger);
@ -1273,7 +1265,7 @@ public class RunNiFi {
cmdLogger.info("Starting Apache NiFi...");
cmdLogger.info("Working Directory: {}", workingDir.getAbsolutePath());
cmdLogger.info("Command: {}", cmdBuilder.toString());
cmdLogger.info("Command: {}", cmdBuilder);
String gracefulShutdown = props.get(GRACEFUL_SHUTDOWN_PROP);
if (gracefulShutdown == null) {
@ -1295,22 +1287,16 @@ public class RunNiFi {
Process process = builder.start();
handleLogging(process);
Long pid = OSUtils.getProcessId(process, cmdLogger);
if (pid == null) {
cmdLogger.warn("Launched Apache NiFi but could not determined the Process ID");
} else {
nifiPid = pid;
nifiPid = process.pid();
final Properties pidProperties = new Properties();
pidProperties.setProperty(PID_KEY, String.valueOf(nifiPid));
savePidProperties(pidProperties, cmdLogger);
cmdLogger.info("Launched Apache NiFi with Process ID " + pid);
}
cmdLogger.info("Application Process [{}] launched", nifiPid);
shutdownHook = new ShutdownHook(process, pid, this, secretKey, gracefulShutdownSeconds, loggingExecutor);
shutdownHook = new ShutdownHook(process, nifiPid, this, secretKey, gracefulShutdownSeconds, loggingExecutor);
final String hostname = getHostname();
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
String now = sdf.format(System.currentTimeMillis());
String now = Instant.now().toString();
String user = System.getProperty("user.name");
if (user == null || user.trim().isEmpty()) {
user = "Unknown User";
@ -1336,7 +1322,6 @@ public class RunNiFi {
// happens when already shutting down
}
now = sdf.format(System.currentTimeMillis());
if (autoRestartNiFi) {
final File statusFile = getStatusFile(defaultLogger);
if (!statusFile.exists()) {
@ -1368,30 +1353,25 @@ public class RunNiFi {
process = builder.start();
handleLogging(process);
pid = OSUtils.getProcessId(process, defaultLogger);
if (pid == null) {
cmdLogger.warn("Launched Apache NiFi but could not obtain the Process ID");
} else {
nifiPid = pid;
final Properties pidProperties = new Properties();
nifiPid = process.pid();
now = Instant.now().toString();
pidProperties.setProperty(PID_KEY, String.valueOf(nifiPid));
savePidProperties(pidProperties, defaultLogger);
cmdLogger.info("Launched Apache NiFi with Process ID " + pid);
}
cmdLogger.info("Application Process [{}] launched", nifiPid);
shutdownHook = new ShutdownHook(process, pid, this, secretKey, gracefulShutdownSeconds, loggingExecutor);
shutdownHook = new ShutdownHook(process, nifiPid, this, secretKey, gracefulShutdownSeconds, loggingExecutor);
runtime.addShutdownHook(shutdownHook);
final boolean started = waitForStart();
if (started) {
defaultLogger.info("Successfully started Apache NiFi{}", (pid == null ? "" : " with PID " + pid));
cmdLogger.info("Application Process [{}] started", nifiPid);
// We are expected to restart nifi, so send a notification that it died. If we are not restarting nifi,
// then this means that we are intentionally stopping the service.
serviceManager.notify(NotificationType.NIFI_DIED, "NiFi Died on Host " + hostname,
"Hello,\n\nIt appears that Apache NiFi has died on host " + hostname + " at " + now + "; automatically restarting NiFi");
} else {
defaultLogger.error("Apache NiFi does not appear to have started");
defaultLogger.error("Application Process [{}] not started", nifiPid);
// We are expected to restart nifi, so send a notification that it died. If we are not restarting nifi,
// then this means that we are intentionally stopping the service.
serviceManager.notify(NotificationType.NIFI_DIED, "NiFi Died on Host " + hostname,
@ -1569,7 +1549,7 @@ public class RunNiFi {
try {
savePidProperties(nifiProps, defaultLogger);
} catch (final IOException ioe) {
defaultLogger.warn("Apache NiFi has started but failed to persist NiFi Port information to {} due to {}", new Object[]{statusFile.getAbsolutePath(), ioe});
defaultLogger.warn("Apache NiFi has started but failed to persist NiFi Port information to {} due to {}", statusFile.getAbsolutePath(), ioe);
}
defaultLogger.info("Apache NiFi now running and listening for Bootstrap requests on port {}", port);

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-commons</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<artifactId>nifi-bootstrap-utils</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,119 +0,0 @@
/*
* 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.nifi.bootstrap.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
/**
* OS specific utilities with generic method interfaces
*/
public final class OSUtils {
/**
* @param process NiFi Process Reference
* @param logger Logger Reference for Debug
* @return Returns pid or null in-case pid could not be determined
* This method takes {@link Process} and {@link Logger} and returns
* the platform specific ProcessId for Unix like systems or Handle for Win32 Systems, a.k.a <b>pid</b>
* In-case it fails to determine the pid, it will return Null.
* Purpose for the Logger is to log any interaction for debugging.
*/
public static Long getProcessId(final Process process, final Logger logger) {
/*
* NIFI-5175: NiFi built with Java 1.8 and running on Java 9. Reflectively invoke Process.pid() on
* the given process instance to get the PID of this Java process. Reflection is required in this scenario
* due to NiFi being compiled on Java 1.8, which does not have the Process API improvements available in
* Java 9.
*
* Otherwise, if NiFi is running on Java 1.8, attempt to get PID using capabilities available on Java 1.8.
*
* TODO: When minimum Java version updated to Java 9+, this class should be removed with the addition
* of the pid method to the Process API.
*/
Long pid = null;
try {
// Get Process.pid() interface method to avoid illegal reflective access
final Method pidMethod = Process.class.getDeclaredMethod("pid");
final Object pidNumber = pidMethod.invoke(process);
if (pidNumber instanceof Long) {
pid = (Long) pidNumber;
}
} catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
final String processClassName = process.getClass().getName();
if (processClassName.equals("java.lang.UNIXProcess")) {
pid = getUnixPid(process, logger);
} else {
logger.info("Failed to determine Process ID from [{}]: {}", processClassName, e.getMessage());
}
}
return pid;
}
/**
* Returns the major version parsed from the provided Java version string (e.g. {@code "1.8.0.231"} -> {@code 8}).
*
* @param version the Java version string
* @return the major version as an int
*/
static int parseJavaVersion(final String version) {
String majorVersion;
if (version.startsWith("1.")) {
majorVersion = version.substring(2, 3);
} else {
Pattern majorVersion9PlusPattern = Pattern.compile("(\\d+).*");
Matcher m = majorVersion9PlusPattern.matcher(version);
if (m.find()) {
majorVersion = m.group(1);
} else {
throw new IllegalArgumentException("Could not detect major version of " + version);
}
}
return Integer.parseInt(majorVersion);
}
/**
* @param process NiFi Process Reference
* @param logger Logger Reference for Debug
* @return Returns pid or null in-case pid could not be determined
* This method takes {@link Process} and {@link Logger} and returns
* the platform specific ProcessId for Unix like systems, a.k.a <b>pid</b>
* In-case it fails to determine the pid, it will return Null.
* Purpose for the Logger is to log any interaction for debugging.
*/
private static Long getUnixPid(final Process process, final Logger logger) {
try {
final Class<?> procClass = process.getClass();
final Field pidField = procClass.getDeclaredField("pid");
pidField.setAccessible(true);
final Object pidObject = pidField.get(process);
if (pidObject instanceof Number) {
return ((Number) pidObject).longValue();
}
return null;
} catch (final IllegalAccessException | NoSuchFieldException e) {
logger.debug("Could not find Unix PID", e);
return null;
}
}
}

View File

@ -1,58 +0,0 @@
/*
* 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.nifi.bootstrap.util;
/**
* Java Runtime Version Provider with information on supported and deprecated versions
*/
public class RuntimeVersionProvider {
private static final String JAVA_VERSION_PROPERTY = "java.version";
private static final int DEPRECATED_JAVA_VERSION = 8;
private static final int MINIMUM_JAVA_VERSION = 11;
/**
* Get major version from java.version System property
*
* @return Major Version
*/
public static int getMajorVersion() {
final String javaVersion = System.getProperty(JAVA_VERSION_PROPERTY);
return OSUtils.parseJavaVersion(javaVersion);
}
/**
* Get minimum supported major version
*
* @return Minimum Major Version
*/
public static int getMinimumMajorVersion() {
return MINIMUM_JAVA_VERSION;
}
/**
* Is major version deprecated
*
* @param majorVersion Java major version
* @return Deprecated status
*/
public static boolean isMajorVersionDeprecated(final int majorVersion) {
return majorVersion == DEPRECATED_JAVA_VERSION;
}
}

View File

@ -1,58 +0,0 @@
/*
* 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.nifi.bootstrap.util;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class OSUtilsTest {
@DisabledOnOs(OS.WINDOWS)
@Test
public void testGetPid() throws IOException {
final ProcessBuilder builder = new ProcessBuilder();
final Process process = builder.command("java").start();
final Logger logger = LoggerFactory.getLogger("testing");
final Long pid = OSUtils.getProcessId(process, logger);
process.destroy();
assertNotNull(pid, "Process ID not found");
}
@Test
public void testParseJavaVersion8() {
final String[] versions = new String[] { "1.8", "1.8.0", "1.8.0_100" };
for (final String version : versions) {
assertEquals(8, OSUtils.parseJavaVersion(version));
}
}
@Test
public void testParseJavaVersion11() {
final String[] versions = new String[] { "11", "11.0", "11.0.11" };
for (final String version : versions) {
assertEquals(11, OSUtils.parseJavaVersion(version));
}
}
}

View File

@ -23,7 +23,6 @@
<artifactId>nifi-commons</artifactId>
<packaging>pom</packaging>
<modules>
<module>nifi-bootstrap-utils</module>
<module>nifi-build</module>
<module>nifi-data-provenance-utils</module>
<module>nifi-deprecation-log</module>

View File

@ -30,15 +30,5 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap-utils</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-deprecation-log</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -17,9 +17,6 @@
package org.apache.nifi.registry.bootstrap;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.bootstrap.util.OSUtils;
import org.apache.nifi.deprecation.log.DeprecationLogger;
import org.apache.nifi.deprecation.log.DeprecationLoggerFactory;
import org.apache.nifi.registry.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -36,13 +33,11 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -91,7 +86,6 @@ public class RunNiFiRegistry {
public static final String NIFI_REGISTRY_PID_FILE_NAME = "nifi-registry.pid";
public static final String NIFI_REGISTRY_STATUS_FILE_NAME = "nifi-registry.status";
public static final String NIFI_REGISTRY_LOCK_FILE_NAME = "nifi-registry.lock";
public static final String NIFI_REGISTRY_BOOTSTRAP_SENSITIVE_KEY = "nifi.registry.bootstrap.sensitive.key";
public static final String PID_KEY = "pid";
@ -120,12 +114,11 @@ public class RunNiFiRegistry {
private final Logger cmdLogger = LoggerFactory.getLogger("org.apache.nifi.registry.bootstrap.Command");
// used for logging all info. These by default will be written to the log file
private final Logger defaultLogger = LoggerFactory.getLogger(RunNiFiRegistry.class);
private final DeprecationLogger deprecationLogger = DeprecationLoggerFactory.getLogger(RunNiFiRegistry.class);
private final ExecutorService loggingExecutor;
private volatile Set<Future<?>> loggingFutures = new HashSet<>(2);
public RunNiFiRegistry(final File bootstrapConfigFile, final boolean verbose) throws IOException {
public RunNiFiRegistry(final File bootstrapConfigFile, final boolean verbose) {
this.bootstrapConfigFile = bootstrapConfigFile;
loggingExecutor = Executors.newFixedThreadPool(2, new ThreadFactory() {
@ -145,7 +138,7 @@ public class RunNiFiRegistry {
System.out.println("java org.apache.nifi.bootstrap.RunNiFiRegistry [<-verbose>] <command> [options]");
System.out.println();
System.out.println("Valid commands include:");
System.out.println("");
System.out.println();
System.out.println("Start : Start a new instance of Apache NiFi Registry");
System.out.println("Stop : Stop a running instance of Apache NiFi Registry");
System.out.println("Restart : Stop Apache NiFi Registry, if it is running, and then start a new instance");
@ -159,7 +152,7 @@ public class RunNiFiRegistry {
return Arrays.copyOfRange(orig, 1, orig.length);
}
public static void main(String[] args) throws IOException, InterruptedException {
public static void main(String[] args) throws IOException {
if (args.length < 1 || args.length > 3) {
printUsage();
return;
@ -335,7 +328,7 @@ public class RunNiFiRegistry {
fos.getFD().sync();
}
logger.debug("Saved Properties {} to {}", new Object[]{pidProperties, statusFile});
logger.debug("Saved Properties {} to {}", pidProperties, statusFile);
}
private synchronized void writePidFile(final String pid, final Logger logger) throws IOException {
@ -366,7 +359,7 @@ public class RunNiFiRegistry {
fos.getFD().sync();
}
logger.debug("Saved Pid {} to {}", new Object[]{pid, pidFile});
logger.debug("Saved PID [{}] to [{}]", pid, pidFile);
}
private boolean isPingSuccessful(final int port, final String secretKey, final Logger logger) {
@ -498,17 +491,16 @@ public class RunNiFiRegistry {
return new Status(port, pid, pingSuccess, alive);
}
public int status() throws IOException {
public int status() {
final Logger logger = cmdLogger;
final Status status = getStatus(logger);
if (status.isRespondingToPing()) {
logger.info("Apache NiFi Registry is currently running, listening to Bootstrap on port {}, PID={}",
new Object[]{status.getPort(), status.getPid() == null ? "unknown" : status.getPid()});
logger.info("Apache NiFi Registry PID [{}] running with Bootstrap Port [{}]", status.getPid(), status.getPort());
return 0;
}
if (status.isProcessRunning()) {
logger.info("Apache NiFi Registry is running at PID {} but is not responding to ping requests", status.getPid());
logger.info("Apache NiFi Registry PID [{}] running but not responding with Bootstrap Port [{}]", status.getPid(), status.getPort());
return 4;
}
@ -629,13 +621,7 @@ public class RunNiFiRegistry {
}
public void notifyStop() {
final String hostname = getHostname();
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
final String now = sdf.format(System.currentTimeMillis());
String user = System.getProperty("user.name");
if (user == null || user.trim().isEmpty()) {
user = "Unknown User";
}
}
public void stop() throws IOException {
@ -738,9 +724,9 @@ public class RunNiFiRegistry {
} catch (final IOException ioe) {
if (pid == null) {
logger.error("Failed to send shutdown command to port {} due to {}. No PID found for the NiFi Registry process, so unable to kill process; "
+ "the process should be killed manually.", new Object[]{port, ioe.toString()});
+ "the process should be killed manually.", port, ioe);
} else {
logger.error("Failed to send shutdown command to port {} due to {}. Will kill the NiFi Registry Process with PID {}.", port, ioe.toString(), pid);
logger.error("Failed to send shutdown command to port {} due to {}. Will kill the NiFi Registry Process with PID {}.", port, ioe, pid);
notifyStop();
killProcessTree(pid, logger);
if (statusFile.exists() && !statusFile.delete()) {
@ -773,7 +759,7 @@ public class RunNiFiRegistry {
logger.debug("Killing Process Tree for PID {}", pid);
final List<String> children = getChildProcesses(pid);
logger.debug("Children of PID {}: {}", new Object[]{pid, children});
logger.debug("Children of PID {}: {}", pid, children);
for (final String childPid : children) {
killProcessTree(childPid, logger);
@ -791,22 +777,8 @@ public class RunNiFiRegistry {
}
}
private String getHostname() {
String hostname = "Unknown Host";
String ip = "Unknown IP Address";
try {
final InetAddress localhost = InetAddress.getLocalHost();
hostname = localhost.getHostName();
ip = localhost.getHostAddress();
} catch (final Exception e) {
defaultLogger.warn("Failed to obtain hostname for notification due to:", e);
}
return hostname + " (" + ip + ")";
}
@SuppressWarnings({"rawtypes", "unchecked"})
public void start() throws IOException, InterruptedException {
public void start() throws IOException {
final Integer port = getCurrentPort(cmdLogger);
if (port != null) {
cmdLogger.info("Apache NiFi Registry is already running, listening to Bootstrap on port " + port);
@ -975,7 +947,7 @@ public class RunNiFiRegistry {
cmdLogger.info("Starting Apache NiFi Registry...");
cmdLogger.info("Working Directory: {}", workingDir.getAbsolutePath());
cmdLogger.info("Command: {}", cmdBuilder.toString());
cmdLogger.info("Command: {}", cmdBuilder);
String gracefulShutdown = props.get(GRACEFUL_SHUTDOWN_PROP);
if (gracefulShutdown == null) {
@ -997,29 +969,16 @@ public class RunNiFiRegistry {
Process process = builder.start();
handleLogging(process);
Long pid = OSUtils.getProcessId(process, cmdLogger);
if (pid == null) {
cmdLogger.warn("Launched Apache NiFi Registry but could not determined the Process ID");
} else {
nifiRegistryPid = pid;
nifiRegistryPid = process.pid();
final Properties pidProperties = new Properties();
pidProperties.setProperty(PID_KEY, String.valueOf(nifiRegistryPid));
savePidProperties(pidProperties, cmdLogger);
cmdLogger.info("Launched Apache NiFi Registry with Process ID {}", pid);
}
cmdLogger.info("Application Process [{}] launched", nifiRegistryPid);
shutdownHook = new ShutdownHook(process, this, secretKey, gracefulShutdownSeconds, loggingExecutor);
final Runtime runtime = Runtime.getRuntime();
runtime.addShutdownHook(shutdownHook);
final String hostname = getHostname();
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
String now = sdf.format(System.currentTimeMillis());
String user = System.getProperty("user.name");
if (user == null || user.trim().isEmpty()) {
user = "Unknown User";
}
while (true) {
final boolean alive = isAlive(process);
@ -1035,7 +994,6 @@ public class RunNiFiRegistry {
// happens when already shutting down
}
now = sdf.format(System.currentTimeMillis());
if (autoRestartNiFiRegistry) {
final File statusFile = getStatusFile(defaultLogger);
if (!statusFile.exists()) {
@ -1062,16 +1020,10 @@ public class RunNiFiRegistry {
process = builder.start();
handleLogging(process);
pid = OSUtils.getProcessId(process, defaultLogger);
if (pid == null) {
cmdLogger.warn("Launched Apache NiFi Registry but could not obtain the Process ID");
} else {
nifiRegistryPid = pid;
final Properties pidProperties = new Properties();
nifiRegistryPid = process.pid();
pidProperties.setProperty(PID_KEY, String.valueOf(nifiRegistryPid));
savePidProperties(pidProperties, defaultLogger);
cmdLogger.info("Launched Apache NiFi Registry with Process ID " + pid);
}
cmdLogger.info("Application Process [{}] launched", nifiRegistryPid);
shutdownHook = new ShutdownHook(process, this, secretKey, gracefulShutdownSeconds, loggingExecutor);
runtime.addShutdownHook(shutdownHook);
@ -1079,9 +1031,9 @@ public class RunNiFiRegistry {
final boolean started = waitForStart();
if (started) {
defaultLogger.info("Successfully started Apache NiFi Registry {}", (pid == null ? "" : " with PID " + pid));
defaultLogger.info("Application Process [{}] started", nifiRegistryPid);
} else {
defaultLogger.error("Apache NiFi Registry does not appear to have started");
defaultLogger.error("Application Process [{}] not started", nifiRegistryPid);
}
} else {
return;
@ -1209,7 +1161,7 @@ public class RunNiFiRegistry {
try {
savePidProperties(nifiProps, defaultLogger);
} catch (final IOException ioe) {
defaultLogger.warn("Apache NiFi Registry has started but failed to persist NiFi Registry Port information to {} due to {}", new Object[]{statusFile.getAbsolutePath(), ioe});
defaultLogger.warn("Apache NiFi Registry has started but failed to persist NiFi Registry Port information to {} due to {}", statusFile.getAbsolutePath(), ioe);
}
defaultLogger.info("Apache NiFi Registry now running and listening for Bootstrap requests on port {}", port);

View File

@ -172,11 +172,6 @@
<artifactId>nifi-runtime</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap-utils</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-bootstrap</artifactId>

View File

@ -29,7 +29,6 @@
<fileMode>0664</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<includes>
<include>*:nifi-bootstrap-utils</include>
<include>*:nifi-bootstrap</include>
<include>*:bcprov-jdk15on</include>
<include>*:commons-lang3</include>
@ -47,7 +46,6 @@
<fileMode>0664</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<excludes>
<exclude>*:nifi-bootstrap-utils</exclude>
<exclude>*:nifi-bootstrap</exclude>
<exclude>*:nifi-toolkit-cli</exclude>
<exclude>*:bcprov-jdk15on</exclude>