| /** |
| * |
| * 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. |
| */ |
| |
| #include "MainHelper.h" |
| |
| #include "utils/Environment.h" |
| #include "utils/StringUtils.h" |
| #include "utils/file/FileUtils.h" |
| |
| #ifdef WIN32 |
| FILE* __cdecl _imp____iob_func() { |
| struct _iobuf_VS2012 { // ...\Microsoft Visual Studio 11.0\VC\include\stdio.h #56 |
| char *_ptr; |
| int _cnt; |
| char *_base; |
| int _flag; |
| int _file; |
| int _charbuf; |
| int _bufsiz; |
| char *_tmpfname; |
| }; |
| // VS2015 has FILE = struct {void* _Placeholder} |
| |
| static struct _iobuf_VS2012 bufs[3]; |
| static char initialized = 0; |
| |
| if (!initialized) { |
| bufs[0]._ptr = (char*)stdin->_Placeholder; |
| bufs[1]._ptr = (char*)stdout->_Placeholder; |
| bufs[2]._ptr = (char*)stderr->_Placeholder; |
| initialized = 1; |
| } |
| |
| return (FILE*)&bufs; |
| } |
| |
| FILE* __cdecl __imp___iob_func() { |
| struct _iobuf_VS2012 { // ...\Microsoft Visual Studio 11.0\VC\include\stdio.h #56 |
| char *_ptr; |
| int _cnt; |
| char *_base; |
| int _flag; |
| int _file; |
| int _charbuf; |
| int _bufsiz; |
| char *_tmpfname; |
| }; |
| // VS2015 has FILE = struct {void* _Placeholder} |
| |
| static struct _iobuf_VS2012 bufs[3]; |
| static char initialized = 0; |
| |
| if (!initialized) { |
| bufs[0]._ptr = (char*)stdin->_Placeholder; |
| bufs[1]._ptr = (char*)stdout->_Placeholder; |
| bufs[2]._ptr = (char*)stderr->_Placeholder; |
| initialized = 1; |
| } |
| |
| return (FILE*)&bufs; |
| } |
| |
| #endif |
| |
| namespace minifi = org::apache::nifi::minifi; |
| namespace utils = minifi::utils; |
| namespace logging = minifi::core::logging; |
| |
| bool validHome(const std::string &home_path) { |
| const std::string properties_file_path = utils::file::FileUtils::concat_path(home_path, DEFAULT_NIFI_PROPERTIES_FILE); |
| return utils::file::exists(properties_file_path); |
| } |
| |
| void setSyslogLogger() { |
| std::shared_ptr<logging::LoggerProperties> service_logger = std::make_shared<logging::LoggerProperties>(); |
| service_logger->set("appender.syslog", "syslog"); |
| service_logger->set("logger.root", "INFO,syslog"); |
| logging::LoggerConfiguration::getConfiguration().initialize(service_logger); |
| } |
| |
| std::string determineMinifiHome(const std::shared_ptr<logging::Logger>& logger) { |
| /* Try to determine MINIFI_HOME */ |
| std::string minifiHome = [&logger]() -> std::string { |
| /* If MINIFI_HOME is set as an environment variable, we will use that */ |
| bool minifiHomeSet = false; |
| std::string minifiHome; |
| std::tie(minifiHomeSet, minifiHome) = utils::Environment::getEnvironmentVariable(MINIFI_HOME_ENV_KEY); |
| if (minifiHomeSet) { |
| logger->log_info("Found " MINIFI_HOME_ENV_KEY "=%s in environment", minifiHome); |
| return minifiHome; |
| } else { |
| logger->log_info(MINIFI_HOME_ENV_KEY " is not set; trying to infer it"); |
| } |
| |
| /* Try to determine MINIFI_HOME relative to the location of the minifi executable */ |
| std::string executablePath = utils::file::FileUtils::get_executable_path(); |
| if (executablePath.empty()) { |
| logger->log_error("Failed to determine location of the minifi executable"); |
| } else { |
| std::string minifiPath, minifiFileName; |
| std::tie(minifiPath, minifiFileName) = minifi::utils::file::FileUtils::split_path(executablePath); |
| logger->log_info("Inferred " MINIFI_HOME_ENV_KEY "=%s based on the minifi executable location %s", minifiPath, executablePath); |
| return minifiPath; |
| } |
| |
| #ifndef WIN32 |
| /* Try to determine MINIFI_HOME relative to the current working directory */ |
| std::string cwd = utils::Environment::getCurrentWorkingDirectory(); |
| if (cwd.empty()) { |
| logger->log_error("Failed to determine current working directory"); |
| } else { |
| logger->log_info("Inferred " MINIFI_HOME_ENV_KEY "=%s based on the current working directory %s", cwd, cwd); |
| return cwd; |
| } |
| #endif |
| |
| return ""; |
| }(); |
| |
| if (minifiHome.empty()) { |
| logger->log_error("No " MINIFI_HOME_ENV_KEY " could be inferred. " |
| "Please set " MINIFI_HOME_ENV_KEY " or run minifi from a valid location."); |
| return ""; |
| } |
| |
| /* Verify that MINIFI_HOME is valid */ |
| bool minifiHomeValid = false; |
| if (validHome(minifiHome)) { |
| minifiHomeValid = true; |
| } else { |
| logger->log_info("%s is not a valid " MINIFI_HOME_ENV_KEY ", because there is no " DEFAULT_NIFI_PROPERTIES_FILE " file in it.", minifiHome); |
| |
| std::string minifiHomeWithoutBin, binDir; |
| std::tie(minifiHomeWithoutBin, binDir) = minifi::utils::file::FileUtils::split_path(minifiHome); |
| if (minifiHomeWithoutBin != "" && (binDir == "bin" || binDir == std::string("bin") + minifi::utils::file::FileUtils::get_separator())) { |
| if (validHome(minifiHomeWithoutBin)) { |
| logger->log_info("%s is a valid " MINIFI_HOME_ENV_KEY ", falling back to it.", minifiHomeWithoutBin); |
| minifiHomeValid = true; |
| minifiHome = std::move(minifiHomeWithoutBin); |
| } else { |
| logger->log_info("%s is not a valid " MINIFI_HOME_ENV_KEY ", because there is no " DEFAULT_NIFI_PROPERTIES_FILE " file in it.", minifiHomeWithoutBin); |
| } |
| } |
| } |
| |
| /* Fail if not */ |
| if (!minifiHomeValid) { |
| logger->log_error("Cannot find a valid " MINIFI_HOME_ENV_KEY " containing a " DEFAULT_NIFI_PROPERTIES_FILE " file in it. " |
| "Please set " MINIFI_HOME_ENV_KEY " or run minifi from a valid location."); |
| return ""; |
| } |
| |
| /* Set the valid MINIFI_HOME in our environment */ |
| logger->log_info("Using " MINIFI_HOME_ENV_KEY "=%s", minifiHome); |
| utils::Environment::setEnvironmentVariable(MINIFI_HOME_ENV_KEY, minifiHome.c_str()); |
| |
| return minifiHome; |
| } |