This is an automated email from the ASF dual-hosted git repository.
phrocker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
The following commit(s) were added to refs/heads/master by this push:
new b8359e6 MINIFICPP-1006: minor updates for jni building using win
build & correct artifact naming (#630)
b8359e6 is described below
commit b8359e62521143215f4f82a513122bc06c6c70c6
Author: Marc <[email protected]>
AuthorDate: Wed Sep 4 07:28:32 2019 -0400
MINIFICPP-1006: minor updates for jni building using win build & correct
artifact naming (#630)
* MINIFICPP-1006: minor updates for jni building using win build
MINIFICPP-1006: Add service account settings to UI
MINIFICPP-1006: Rename artifact
MINIFICPP-1006: Rename artifacts in docker builds
MINIFICPP-1006: UI updates
MINIFICPP-1006: Fix typo and linter errors
MINIFICPP-1006: Remove win64, relying on extra sources
MINIFICPP-1006: Fix build script
MINIFICPP-1006: Remove skip tests
MINIFICPP-1006: fix compression reference
MINIFICPP-1016: Add MetadataWalker and change how metadata is evaluated.
MINIFICPP-1016: Address pr comments and add unit test
MINIFICPP-1006: Fix typo
* MINIFICPP-1006: Fix collision with INSTALLDIR
This closes #630.
Approved by @apiri
Signed-off-by: Marc Parisi <[email protected]>
---
CMakeLists.txt | 32 ++-
CMakeSettings.json | 10 +-
LICENSE | 27 ++
cmake/Compression.cmake | 19 +-
conf/minifi.properties | 2 +-
docker/ContainerBuild.sh | 2 +-
docker/Dockerfile | 4 +-
extensions/jni/JVMCreator.h | 3 +-
extensions/windows-event-log/CMakeLists.txt | 21 +-
.../windows-event-log/ConsumeWindowsEventLog.cpp | 185 +++----------
.../windows-event-log/ConsumeWindowsEventLog.h | 18 +-
extensions/windows-event-log/tests/CMakeLists.txt | 15 +-
.../tests/MetadataWalkerTests.cpp | 96 +++++++
.../tests/resources/invalidxml.xml | 17 ++
.../tests/resources/nobodysid.xml | 23 ++
.../windows-event-log/tests/resources/nodata.xml | 19 ++
.../tests/resources/unknownsid.xml | 23 ++
.../windows-event-log/tests/resources/withsids.xml | 23 ++
.../windows-event-log/wel/MetadataWalker.cpp | 135 ++++++++++
extensions/windows-event-log/wel/MetadataWalker.h | 94 +++++++
extensions/windows-event-log/wel/XMLString.h | 60 +++++
libminifi/include/core/ContentRepository.h | 2 +-
libminifi/src/c2/C2Agent.cpp | 10 +-
libminifi/src/utils/StringUtils.cpp | 14 +-
msi/WixWin.wsi | 291 +++++++++++++--------
msi/x64.wsi | 24 ++
msi/x86.wsi | 25 ++
win_build_vs.bat | 17 +-
28 files changed, 906 insertions(+), 305 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2023622..0906199 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -303,6 +303,7 @@ endif()
"-DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/thirdparty/curl-install"
-DBUILD_CURL_EXE=OFF
-DBUILD_TESTING=OFF
+ -DCMAKE_USE_OPENSSL=ON
-DBUILD_SHARED_LIBS=OFF
-DHTTP_ONLY=ON
-DCMAKE_USE_OPENSSL=ON
@@ -643,14 +644,22 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/conf/" DESTINATION
"${CMAKE_CURRENT_BINAR
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" DESTINATION
"${CMAKE_CURRENT_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/README.md" DESTINATION
"${CMAKE_CURRENT_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/NOTICE" DESTINATION
"${CMAKE_CURRENT_BINARY_DIR}")
-set(CPACK_WIX_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/msi/WixWin.wsi")
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(CPACK_WIX_EXTRA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/msi/x64.wsi")
+elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+set(CPACK_WIX_EXTRA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/msi/x86.wsi")
+endif()
+ set(CPACK_WIX_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/msi/WixWin.wsi")
+
else()
set(CPACK_SOURCE_GENERATOR "TGZ")
endif(WIN32)
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${ASSEMBLY_BASE_NAME}-source")
set(CPACK_SOURCE_IGNORE_FILES
"/docs/generated/;${CMAKE_SOURCE_DIR}/build/;~$;${CPACK_SOURCE_IGNORE_FILES};${CMAKE_SOURCE_DIR}/.git/;${CMAKE_SOURCE_DIR}/.idea/;${CMAKE_SOURCE_DIR}/cmake-build-debug/;${CMAKE_SOURCE_DIR}/extensions/expression-language/Scanner.h;${CMAKE_SOURCE_DIR}/extensions/expression-language/Scanner.cpp;${CMAKE_SOURCE_DIR}/extensions/expression-language/Parser.cpp;${CMAKE_SOURCE_DIR}/extensions/expression-language/Parser.hpp;${CMAKE_SOURCE_DIR}/extensions/expression-lan
[...]
-# Generate binary assembly
+# Generate binary assembly. Exclude conf for windows since we'll be doing the
work in the WiX template
+if (NOT WIN32)
install(FILES conf/minifi.properties conf/minifi-log.properties
conf/minifi-uid.properties conf/config.yml
DESTINATION conf
COMPONENT bin)
@@ -659,7 +668,7 @@ install(DIRECTORY extensions/pythonprocessors/
DESTINATION minifi-python
COMPONENT bin)
-if (NOT WIN32)
+
install(PROGRAMS bin/minifi.sh
DESTINATION bin
COMPONENT bin)
@@ -680,16 +689,14 @@ if(WIN32)
else()
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/main/minifi
DESTINATION bin
- COMPONENT bin)
-
+ COMPONENT bin)
endif()
-
+
if (WIN32)
set(CPACK_GENERATOR "WIX")
-
-set(CPACK_WIX_UPGRADE_GUID, "FE29F801-3486-4E9E-AFF9-838C1A5C8D59")
-set(CPACK_WIX_PRODUCT_ICON,"${CMAKE_CURRENT_SOURCE_DIR}/msi/minifi-logo-ico.ico")
+set(CPACK_WIX_UPGRADE_GUID "FE29F801-3486-4E9E-AFF9-838C1A5C8D59")
+set(CPACK_WIX_PRODUCT_ICON
"${CMAKE_CURRENT_SOURCE_DIR}/msi/minifi-logo-ico.ico")
else()
set(CPACK_GENERATOR "TGZ")
endif()
@@ -706,13 +713,14 @@ if(NOT WIN32)
set(CPACK_PACKAGE_FILE_NAME "${ASSEMBLY_BASE_NAME}")
set(CPACK_GENERATOR "TGZ")
set(CPACK_BINARY_TGZ, "ON")
+else()
+set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}")
endif()
-set(CPACK_PACKAGE_FILE_NAME
"minifi-agent-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
-set(CPACK_PACKAGE_INSTALL_DIRECTORY "ApacheNiFiMiNiFi/${CMAKE_PROJECT_NAME}")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "ApacheNiFiMiNiFi")
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_RDKAFKA_COMPONENT_INSTALL ON)
set(CPACK_MQTT_COMPONENT_INSTALL ON)
-set(CPACK_COMPONENTS_ALL bin conf)
+set(CPACK_COMPONENTS_ALL bin conf minifijni)
include(CPack)
diff --git a/CMakeSettings.json b/CMakeSettings.json
index 880052f..ea513ae 100644
--- a/CMakeSettings.json
+++ b/CMakeSettings.json
@@ -4,7 +4,7 @@
{
"name": "x64-Release",
"generator": "Visual Studio 15 2017",
- "configurationType": "Release",
+ "configurationType": "RelWithDebInfo",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot":
"${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot":
"${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
@@ -16,6 +16,14 @@
"value": "OFF"
},
{
+ "name": "CMAKE_BUILD_TYPE",
+ "value": "RelWithDebInfo"
+ },
+ {
+ "name": "USE_SYSTEM_OPENSSL",
+ "value": "OFF"
+ },
+ {
"name": "PORTABLE",
"value": "ON"
},
diff --git a/LICENSE b/LICENSE
index 8d8ed60..370b7e5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1770,3 +1770,30 @@ This product bundles 'libssh2' which is available under
a "3-clause BSD" license
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
+
+ This license bundles 'pugixml' which is available under an MIT license
+
+ MIT License
+
+Copyright (c) 2006-2019 Arseny Kapoulkine
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/cmake/Compression.cmake b/cmake/Compression.cmake
index 2d03733..498b974 100644
--- a/cmake/Compression.cmake
+++ b/cmake/Compression.cmake
@@ -17,15 +17,16 @@
function(use_bundled_zlib SOURCE_DIR BINARY_DIR)
message("Using bundled zlib")
- if (WIN32)
- if (CMAKE_BUILD_TYPE MATCHES RelWithDebInfo OR CMAKE_BUILD_TYPE MATCHES
Release)
- set(BYPRODUCT "thirdparty/zlib-install/lib/zlibstatic.lib")
- else()
- set(BYPRODUCT "thirdparty/zlib-install/lib/zlibstaticd.lib")
- endif()
- else()
- set(BYPRODUCT "thirdparty/zlib-install/lib/libz.a")
- endif()
+if (WIN32)
+ string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type)
+ if (build_type MATCHES relwithdebinfo OR build_type MATCHES release)
+ set(BYPRODUCT "thirdparty/zlib-install/lib/zlibstatic.lib")
+ else()
+ set(BYPRODUCT "thirdparty/zlib-install/lib/zlibstaticd.lib")
+ endif()
+ else()
+ set(BYPRODUCT "thirdparty/zlib-install/lib/libz.a")
+ endif()
ExternalProject_Add(
zlib-external
GIT_REPOSITORY "https://github.com/madler/zlib.git"
diff --git a/conf/minifi.properties b/conf/minifi.properties
index 50144c8..4f7166a 100644
--- a/conf/minifi.properties
+++ b/conf/minifi.properties
@@ -53,7 +53,7 @@
nifi.database.content.repository.directory.default=${MINIFI_HOME}/content_reposi
#nifi.c2.rest.url.ack=
nifi.c2.root.classes=DeviceInfoNode,AgentInformation,FlowInformation
## heartbeat 4 times a second
-nifi.c2.agent.heartbeat.period=250
+#nifi.c2.agent.heartbeat.period=250
## define parameters about your agent
#nifi.c2.agent.class=
#nifi.c2.agent.identifier=
diff --git a/docker/ContainerBuild.sh b/docker/ContainerBuild.sh
index 4ad7515..9164ba5 100755
--- a/docker/ContainerBuild.sh
+++ b/docker/ContainerBuild.sh
@@ -60,6 +60,6 @@ DOCKER_COMMAND="docker build --build-arg UID=$UID_ARG \
echo "Docker Command: '$DOCKER_COMMAND'"
${DOCKER_COMMAND}
-docker run --rm --entrypoint cat
apacheminificpp:${DISTRO_NAME}-$MINIFI_VERSION
/opt/minifi/build/minifi-agent-$MINIFI_VERSION-bin.tar.gz >
${DUMP_LOCATION}/nifi-minifi-cpp-${DISTRO_NAME}-$MINIFI_VERSION-bin.tar.gz
+docker run --rm --entrypoint cat
apacheminificpp:${DISTRO_NAME}-$MINIFI_VERSION
/opt/minifi/build/nifi-minifi-cpp-$MINIFI_VERSION-bin.tar.gz >
${DUMP_LOCATION}/nifi-minifi-cpp-${DISTRO_NAME}-$MINIFI_VERSION-bin.tar.gz
rm -rf $CMAKE_SOURCE_DIR/docker/${DISTRO_NAME}/minificppsource/
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 6b6edce..7b61c0c 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -78,7 +78,7 @@ RUN cd ${MINIFI_BASE_DIR} \
&& cd build \
&& cmake -DOPENSSL_FORCE_SHARED=true -DDISABLE_JEMALLOC=ON
-DSTATIC_BUILD= -DSKIP_TESTS=true -DENABLE_JNI=ON .. \
&& make -j8 package \
- && tar -xzvf
${MINIFI_BASE_DIR}/build/minifi-agent-${MINIFI_VERSION}-bin.tar.gz -C
${MINIFI_BASE_DIR}
+ && tar -xzvf
${MINIFI_BASE_DIR}/build/nifi-minifi-cpp-${MINIFI_VERSION}-bin.tar.gz -C
${MINIFI_BASE_DIR}
# Second stage: the runtime image
# Edge required for rocksdb
@@ -108,7 +108,7 @@ RUN apk --update --no-cache upgrade && apk add --update
--no-cache \
ENV USER minificpp
ENV MINIFI_BASE_DIR /opt/minifi
ENV MINIFI_HOME ${MINIFI_BASE_DIR}/minifi-current
-ENV MINIFI_VERSIONED_HOME ${MINIFI_BASE_DIR}/minifi-agent-${MINIFI_VERSION}
+ENV MINIFI_VERSIONED_HOME ${MINIFI_BASE_DIR}/nifi-minifi-cpp-${MINIFI_VERSION}
ENV JAVA_HOME /usr/lib/jvm/default-jvm
ENV PATH ${PATH}:/usr/lib/jvm/default-jvm/bin
diff --git a/extensions/jni/JVMCreator.h b/extensions/jni/JVMCreator.h
index e5346bc..5b3b479 100644
--- a/extensions/jni/JVMCreator.h
+++ b/extensions/jni/JVMCreator.h
@@ -56,7 +56,8 @@ class JVMCreator : public minifi::core::CoreComponent {
}
for (const auto &path : pathOrFiles) {
- minifi::utils::file::FileUtils::addFilesMatchingExtension(logger_, path,
".jar", classpaths_);
+ logger_->log_debug("Adding path %s", path);
+
minifi::utils::file::FileUtils::addFilesMatchingExtension(logger_, path,
".jar", classpaths_);
}
}
diff --git a/extensions/windows-event-log/CMakeLists.txt
b/extensions/windows-event-log/CMakeLists.txt
index 19e08a2..18a9ecf 100644
--- a/extensions/windows-event-log/CMakeLists.txt
+++ b/extensions/windows-event-log/CMakeLists.txt
@@ -19,7 +19,7 @@
include(${CMAKE_SOURCE_DIR}/extensions/ExtensionHeader.txt)
-file(GLOB SOURCES "*.cpp")
+file(GLOB SOURCES "*.cpp" "wel/*.cpp")
add_library(minifi-wel STATIC ${SOURCES})
set_property(TARGET minifi-wel PROPERTY POSITION_INDEPENDENT_CODE ON)
@@ -30,10 +30,27 @@ if(CMAKE_THREAD_LIBS_INIT)
target_link_libraries(minifi-wel "${CMAKE_THREAD_LIBS_INIT}")
endif()
+set(PUGI_BYPRODUCT_DIR
"${CMAKE_CURRENT_BINARY_DIR}/thirdparty/pugixml-install" CACHE STRING "PugiXML
install directory")
+set(BYPRODUCT "${PUGI_BYPRODUCT_DIR}/lib/pugixml.lib")
+ ExternalProject_Add(
+ pugixml-external
+ GIT_REPOSITORY "https://github.com/zeux/pugixml.git"
+ GIT_TAG "v1.9"
+ SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/thirdparty/pugixml-src"
+ CMAKE_ARGS ${PASSTHROUGH_CMAKE_ARGS}
+ "-DBUILD_TESTS=OFF"
+ "-DBUILD_SHARED_AND_STATIC_LIBS=OFF"
+ "-DBUILD_SHARED_LIBS=OFF"
+ "-DCMAKE_INSTALL_PREFIX=${PUGI_BYPRODUCT_DIR}"
+ BUILD_BYPRODUCTS ${BYPRODUCT}
+ )
+include_directories("${PUGI_BYPRODUCT_DIR}/include")
+add_dependencies(minifi-wel pugixml-external)
# Include UUID
find_package(UUID REQUIRED)
-target_link_libraries(minifi-wel ${LIBMINIFI} ${UUID_LIBRARIES})
+target_link_libraries(minifi-wel ${LIBMINIFI} ${BYPRODUCT} ${UUID_LIBRARIES})
+
target_link_libraries(minifi-wel ${CMAKE_DL_LIBS} )
find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIRS})
diff --git a/extensions/windows-event-log/ConsumeWindowsEventLog.cpp
b/extensions/windows-event-log/ConsumeWindowsEventLog.cpp
index 26ae3d9..b2d6114 100644
--- a/extensions/windows-event-log/ConsumeWindowsEventLog.cpp
+++ b/extensions/windows-event-log/ConsumeWindowsEventLog.cpp
@@ -28,13 +28,13 @@
#include <string>
#include <iostream>
#include <memory>
-#include <codecvt>
#include <regex>
+#include "wel/MetadataWalker.h"
+#include "wel/XMLString.h"
#include "io/DataStream.h"
#include "core/ProcessContext.h"
#include "core/ProcessSession.h"
-#include "utils/OsUtils.h"
#pragma comment(lib, "wevtapi.lib")
@@ -66,14 +66,6 @@ core::Property ConsumeWindowsEventLog::Query(
supportsExpressionLanguage(true)->
build());
-core::Property ConsumeWindowsEventLog::RenderFormatXML(
- core::PropertyBuilder::createProperty("Render Format XML?")->
- isRequired(true)->
- withDefaultValue<bool>(true)->
- withDescription("Render format XML or Text.)")->
- supportsExpressionLanguage(true)->
- build());
-
core::Property ConsumeWindowsEventLog::MaxBufferSize(
core::PropertyBuilder::createProperty("Max Buffer Size")->
isRequired(true)->
@@ -109,12 +101,17 @@ core::Property ConsumeWindowsEventLog::IdentifierFunction(
withDescription("If true it will resolve SIDs matched in the
'Identifier Match Regex' to the DOMAIN\\USERNAME associated with that ID")->
build());
+core::Property ConsumeWindowsEventLog::ResolveAsAttributes(
+ core::PropertyBuilder::createProperty("Resolve Metadata in
Attributes")->
+ isRequired(false)->
+ withDefaultValue<bool>(true)->
+ withDescription("If true, any metadata that is resolved ( such as IDs
or keyword metadata ) will be placed into attributes, otherwise it will be
replaced in the XML or text output")->
+ build());
+
core::Relationship ConsumeWindowsEventLog::Success("success", "Relationship
for successfully consumed events.");
ConsumeWindowsEventLog::ConsumeWindowsEventLog(const std::string& name,
utils::Identifier uuid)
: core::Processor(name, uuid),
logger_(logging::LoggerFactory<ConsumeWindowsEventLog>::getLogger()),
apply_identifier_function_(false) {
- // Initializes COM for current thread, it is needed to MSXML parser.
- CoInitializeEx(0, COINIT_APARTMENTTHREADED);
char buff[MAX_COMPUTERNAME_LENGTH + 1];
DWORD size = sizeof(buff);
@@ -126,15 +123,11 @@ ConsumeWindowsEventLog::ConsumeWindowsEventLog(const
std::string& name, utils::I
}
ConsumeWindowsEventLog::~ConsumeWindowsEventLog() {
- if (xmlDoc_) {
- xmlDoc_.Release();
- }
- CoUninitialize();
}
void ConsumeWindowsEventLog::initialize() {
//! Set the supported properties
- setSupportedProperties({Channel, Query, RenderFormatXML, MaxBufferSize,
InactiveDurationToReconnect, IdentifierMatcher, IdentifierFunction });
+ setSupportedProperties({Channel, Query, MaxBufferSize,
InactiveDurationToReconnect, IdentifierMatcher, IdentifierFunction,
ResolveAsAttributes });
//! Set the supported relationships
setSupportedRelationships({Success});
@@ -142,6 +135,7 @@ void ConsumeWindowsEventLog::initialize() {
void ConsumeWindowsEventLog::onSchedule(const
std::shared_ptr<core::ProcessContext> &context, const
std::shared_ptr<core::ProcessSessionFactory> &sessionFactory) {
context->getProperty(IdentifierMatcher.getName(), regex_);
+ context->getProperty(ResolveAsAttributes.getName(),
resolve_as_attributes_);
context->getProperty(IdentifierFunction.getName(),
apply_identifier_function_);
if (subscriptionHandle_) {
logger_->log_error("Processor already subscribed to Event Log, expected
cleanup to unsubscribe.");
@@ -175,103 +169,20 @@ void ConsumeWindowsEventLog::onTrigger(const
std::shared_ptr<core::ProcessContex
}
}
-void ConsumeWindowsEventLog::matchRegex(const MSXML2::IXMLDOMElementPtr pRoot,
std::map<std::string, std::string> &fieldsAndValues, std::wregex match) {
- const auto pNodeChildren = pRoot->childNodes;
- using convert_type = std::codecvt_utf8<wchar_t>;
- std::wstring_convert<convert_type, wchar_t> converter;
- for (long i = 0; i < pNodeChildren->length; i++) {
- const auto pNode = pNodeChildren->item[i];
- const auto nodeType = pNode->GetnodeType();
- if (DOMNodeType::NODE_ELEMENT == nodeType) {
- auto nodeName = pNode->nodeName;
-
- std::wstring wstringNodeName(nodeName,
SysStringLen(nodeName));
- bool matched = false;
- if (std::regex_match(wstringNodeName, match)) {
- matched = true;
- }
- else {
- const auto pAttributes = pNode->attributes;
- for (long iAttr = 0; iAttr <
pAttributes->length; iAttr++) {
- const auto pAttribute =
pAttributes->item[iAttr];
- if (pAttribute->nodeName ==
static_cast<_bstr_t>("Name")) {
- auto attributeNodeName =
static_cast<_bstr_t>(pAttribute->nodeValue);
- std::wstring
wAttributeNodeName(attributeNodeName, SysStringLen(attributeNodeName));
- if
(std::regex_match(wAttributeNodeName, match)) {
- wstringNodeName =
attributeNodeName;
- matched = true;
- }
- }
- }
-
- }
- if (matched) {
- auto value =
static_cast<_bstr_t>(pNode->Gettext());
- std::wstring wstringValue(value,
SysStringLen(value));
- auto matched_field_name =
converter.to_bytes(wstringNodeName);
- auto matched_field_value =
converter.to_bytes(wstringValue);
-
- fieldsAndValues[matched_field_name] =
apply_identifier_function_ ?
utils::OsUtils::userIdToUsername(matched_field_value) : matched_field_value;
- }
- matchRegex(pNode, fieldsAndValues, match);
- }
+EVT_HANDLE ConsumeWindowsEventLog::getProvider(const std::string & name) {
+ std::lock_guard<std::mutex> lock(cache_mutex_);
+ auto provider = providers_.find(name);
+ if (provider != std::end(providers_)) {
+ return provider->second;
}
-
-}
-
-void ConsumeWindowsEventLog::createTextOutput(const MSXML2::IXMLDOMElementPtr
pRoot, std::wstringstream& stream, std::vector<std::wstring>& ancestors) {
- const auto pNodeChildren = pRoot->childNodes;
-
- auto writeAncestors = [](const std::vector<std::wstring>& ancestors,
std::wstringstream& stream) {
- for (size_t j = 0; j < ancestors.size() - 1; j++) {
- stream << ancestors[j] + L'/';
- }
- stream << ancestors.back();
- };
- if (0 == pNodeChildren->length) {
- writeAncestors(ancestors, stream);
+ std::wstring temp_wstring = std::wstring(name.begin(), name.end());
+ LPCWSTR widechar = temp_wstring.c_str();
- stream << std::endl;
- } else {
- for (long i = 0; i < pNodeChildren->length; i++) {
- std::wstringstream curStream;
-
- const auto pNode = pNodeChildren->item[i];
-
- const auto nodeType = pNode->GetnodeType();
+ providers_[name] = EvtOpenPublisherMetadata(NULL, widechar, NULL, 0, 0);
- if (DOMNodeType::NODE_TEXT == nodeType) {
- const auto nodeValue = pNode->text;
- if (nodeValue.length()) {
- writeAncestors(ancestors, stream);
-
- std::wstring strNodeValue = static_cast<LPCWSTR>(nodeValue);
-
- // Remove '\n', '\r' - just substitute all whitespaces with ' '.
- strNodeValue = std::regex_replace(strNodeValue,
std::wregex(L"\\s+"), L" ");
-
- curStream << L" = " << strNodeValue;
- }
-
- stream << curStream.str() << std::endl;
- } else if (DOMNodeType::NODE_ELEMENT == nodeType) {
- curStream << pNode->nodeName;
-
- const auto pAttributes = pNode->attributes;
- for (long iAttr = 0; iAttr < pAttributes->length; iAttr++) {
- const auto pAttribute = pAttributes->item[iAttr];
-
- curStream << L" " << pAttribute->nodeName << L'(' <<
static_cast<_bstr_t>(pAttribute->nodeValue) << L')';
- }
-
- ancestors.emplace_back(curStream.str());
- createTextOutput(pNode, stream, ancestors);
- ancestors.pop_back();
- }
- }
- }
-}
+ return providers_[name];
+}
bool ConsumeWindowsEventLog::subscribe(const
std::shared_ptr<core::ProcessContext> &context) {
std::string channel;
@@ -280,23 +191,6 @@ bool ConsumeWindowsEventLog::subscribe(const
std::shared_ptr<core::ProcessContex
std::string query;
context->getProperty(Query.getName(), query);
- context->getProperty(RenderFormatXML.getName(), renderXML_);
-
- if (xmlDoc_) {
- xmlDoc_.Release();
- }
-
- HRESULT hr = xmlDoc_.CreateInstance(__uuidof(MSXML2::DOMDocument60));
- if (FAILED(hr)) {
- logger_->log_error("!xmlDoc_.CreateInstance %x", hr);
- return false;
- }
-
- xmlDoc_->async = VARIANT_FALSE;
- xmlDoc_->validateOnParse = VARIANT_FALSE;
- xmlDoc_->resolveExternals = VARIANT_FALSE;
-
-
context->getProperty(MaxBufferSize.getName(), maxBufferSize_);
logger_->log_debug("ConsumeWindowsEventLog: maxBufferSize_ %lld",
maxBufferSize_);
@@ -346,29 +240,36 @@ bool ConsumeWindowsEventLog::subscribe(const
std::shared_ptr<core::ProcessContex
size = used;
std::vector<wchar_t> buf(size/2 + 1);
if (EvtRender(NULL, hEvent, EvtRenderEventXml, size, &buf[0],
&used, &propertyCount)) {
- const auto xml = to_string(&buf[0]);
+ std::string xml = to_string(&buf[0]);
EventRender renderedData;
- if (VARIANT_FALSE ==
pConsumeWindowsEventLog->xmlDoc_->loadXML(_bstr_t(xml.c_str()))) {
+
+ pugi::xml_document doc;
+ pugi::xml_parse_result result =
doc.load_string(xml.c_str());
+
+
+
+ if (!result) {
logger->log_error("'loadXML' failed");
return 0UL;
}
- if (!pConsumeWindowsEventLog->regex_.empty()) {
- std::wstring wstring_regex_;
-
wstring_regex_.assign(pConsumeWindowsEventLog->regex_.begin(),
pConsumeWindowsEventLog->regex_.end());
- std::wregex regex(wstring_regex_);
-
pConsumeWindowsEventLog->matchRegex(pConsumeWindowsEventLog->xmlDoc_->documentElement,
renderedData.matched_fields_, regex);
+
+ std::string providerName =
doc.child("System").child("Provider").attribute("Name").value();
+
+ // resolve the event metadata
+ wel::MetadataWalker
walker(pConsumeWindowsEventLog->getProvider(providerName), hEvent,
!pConsumeWindowsEventLog->resolve_as_attributes_,
pConsumeWindowsEventLog->apply_identifier_function_,
pConsumeWindowsEventLog->regex_);
+ doc.traverse(walker);
+
+ if
(pConsumeWindowsEventLog->resolve_as_attributes_) {
+ renderedData.matched_fields_ =
walker.getFieldValues();
}
- if (pConsumeWindowsEventLog->renderXML_) {
- renderedData.text_ = std::move(xml);
- } else {
+ wel::XmlString writer;
+ doc.print(writer,"", pugi::format_raw); // no
indentation or formatting
+ xml = writer.xml_;
+
+ renderedData.text_ = std::move(xml);
- std::wstringstream stream;
- std::vector<std::wstring> ancestors;
-
pConsumeWindowsEventLog->createTextOutput(pConsumeWindowsEventLog->xmlDoc_->documentElement,
stream, ancestors);
- renderedData.text_ =
std::move(to_string(stream.str().c_str()));
- }
pConsumeWindowsEventLog->listRenderedData_.enqueue(std::move(renderedData));
} else {
logger->log_error("EvtRender returned the following error
code: %d.", GetLastError());
diff --git a/extensions/windows-event-log/ConsumeWindowsEventLog.h
b/extensions/windows-event-log/ConsumeWindowsEventLog.h
index 25d2322..4d6196d 100644
--- a/extensions/windows-event-log/ConsumeWindowsEventLog.h
+++ b/extensions/windows-event-log/ConsumeWindowsEventLog.h
@@ -25,11 +25,15 @@
#include "concurrentqueue.h"
#include "core/Processor.h"
#include "core/ProcessSession.h"
+#include "pugixml.hpp"
#include <winevt.h>
#include <sstream>
#include <regex>
+#include <codecvt>
+#include "utils/OsUtils.h"
-#import <msxml6.dll>
+
+//#import <msxml6.dll>
namespace org {
namespace apache {
@@ -43,6 +47,7 @@ struct EventRender {
};
+
//! ConsumeWindowsEventLog Class
class ConsumeWindowsEventLog : public core::Processor
{
@@ -67,6 +72,7 @@ public:
static core::Property InactiveDurationToReconnect;
static core::Property IdentifierMatcher;
static core::Property IdentifierFunction;
+ static core::Property ResolveAsAttributes;
//! Supported Relationships
static core::Relationship Success;
@@ -89,15 +95,15 @@ protected:
bool subscribe(const std::shared_ptr<core::ProcessContext> &context);
void unsubscribe();
int processQueue(const std::shared_ptr<core::ProcessSession> &session);
- void matchRegex(const MSXML2::IXMLDOMElementPtr pRoot,
std::map<std::string,std::string> &fieldsAndValues, std::wregex match);
-
- void createTextOutput(const MSXML2::IXMLDOMElementPtr pRoot,
std::wstringstream& stream, std::vector<std::wstring>& ancestors);
+
+ EVT_HANDLE getProvider(const std::string & name);
void LogWindowsError();
private:
// Logger
std::shared_ptr<logging::Logger> logger_;
std::string regex_;
+ bool resolve_as_attributes_;
bool apply_identifier_function_;
moodycamel::ConcurrentQueue<EventRender> listRenderedData_;
std::string provenanceUri_;
@@ -107,8 +113,8 @@ private:
uint64_t maxBufferSize_{};
DWORD lastActivityTimestamp_{};
std::shared_ptr<core::ProcessSessionFactory> sessionFactory_;
- bool renderXML_{};
- MSXML2::IXMLDOMDocumentPtr xmlDoc_;
+ std::mutex cache_mutex_;
+ std::map<std::string, EVT_HANDLE > providers_;
};
REGISTER_RESOURCE(ConsumeWindowsEventLog, "Windows Event Log Subscribe
Callback to receive FlowFiles from Events on Windows.");
diff --git a/extensions/windows-event-log/tests/CMakeLists.txt
b/extensions/windows-event-log/tests/CMakeLists.txt
index fc29e2a..7f798f1 100644
--- a/extensions/windows-event-log/tests/CMakeLists.txt
+++ b/extensions/windows-event-log/tests/CMakeLists.txt
@@ -22,14 +22,21 @@ SET(WEL_TEST_COUNT 0)
FOREACH(testfile ${WEL_INTEGRATION_TESTS})
get_filename_component(testfilename "${testfile}" NAME_WE)
add_executable("${testfilename}" "${testfile}")
- target_include_directories(${testfilename} PRIVATE BEFORE
"${CMAKE_SOURCE_DIR}/extensions/WEL/")
+ target_include_directories(${testfilename} PRIVATE BEFORE
"${CMAKE_SOURCE_DIR}/extensions/windows-event-log/")
+ target_include_directories(${testfilename} BEFORE PRIVATE
"${CMAKE_SOURCE_DIR}/libminifi/test/")
+ target_include_directories(${testfilename} BEFORE PRIVATE
"${CMAKE_SOURCE_DIR}/libminifi/include/")
+ target_include_directories(${testfilename} BEFORE PRIVATE
"${PUGI_BYPRODUCT_DIR}/include/")
createTests("${testfilename}")
+ target_link_libraries(${testfilename} ${LIBMINIFI} ${CATCH_MAIN_LIB})
if (APPLE)
- target_link_libraries (${testfilename} -Wl,-all_load minifi-WEL)
+ target_link_libraries (${testfilename} -Wl,-all_load minifi-wel)
+ elseif(WIN32)
+ target_link_libraries (${testfilename} minifi-wel)
+ set_target_properties(${testfilename} PROPERTIES LINK_FLAGS
"${LINK_FLAGS} /WHOLEARCHIVE:minifi-wel")
else ()
- target_link_libraries (${testfilename} -Wl,--whole-archive
minifi-WEL -Wl,--no-whole-archive)
+ target_link_libraries (${testfilename} -Wl,--whole-archive
minifi-wel -Wl,--no-whole-archive)
endif ()
MATH(EXPR WEL_TEST_COUNT "${WEL_TEST_COUNT}+1")
- add_test(NAME "${testfilename}" COMMAND "${testfilename}"
WORKING_DIRECTORY ${TEST_DIR})
+ add_test(NAME "${testfilename}" COMMAND "${testfilename}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
ENDFOREACH()
message("-- Finished building ${WEL_TEST_COUNT} WEL related test file(s)...")
diff --git a/extensions/windows-event-log/tests/MetadataWalkerTests.cpp
b/extensions/windows-event-log/tests/MetadataWalkerTests.cpp
new file mode 100644
index 0000000..aae70bf
--- /dev/null
+++ b/extensions/windows-event-log/tests/MetadataWalkerTests.cpp
@@ -0,0 +1,96 @@
+/**
+ *
+ * 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 <uuid/uuid.h>
+#include <fstream>
+#include <map>
+#include <memory>
+#include <utility>
+#include <string>
+#include <set>
+#include "TestBase.h"
+#include "core/Core.h"
+#include "wel/MetadataWalker.h"
+#include "wel/XMLString.h"
+#include "pugixml.hpp"
+
+using namespace org::apache::nifi::minifi::wel;
+
+
+static std::string formatXml(const std::string &xml) {
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load_string(xml.c_str());
+
+ if (result) {
+ XmlString writer;
+ doc.print(writer, "", pugi::format_raw); // no indentation or
formatting
+ return writer.xml_;
+ }
+ return xml;
+}
+
+TEST_CASE("TestResolutions", "[Resolutions]") {
+ std::ifstream file("resources/nobodysid.xml");
+ std::string xml((std::istreambuf_iterator<char>(file)),
+ std::istreambuf_iterator<char>());
+
+ SECTION("No resolution") {
+ REQUIRE(MetadataWalker::updateXmlMetadata(xml, 0x00, 0x00,
false, true) == formatXml(xml));
+ }
+
+ SECTION("Resolve nobody") {
+ std::ifstream resolvedfile("resources/withsids.xml");
+ std::string
nobody((std::istreambuf_iterator<char>(resolvedfile)),
+ std::istreambuf_iterator<char>());
+ REQUIRE(MetadataWalker::updateXmlMetadata(xml, 0x00, 0x00,
true, true, ".*Sid") == formatXml(nobody));
+ }
+
+}
+
+TEST_CASE("TestNoData", "[NoDataBlock]") {
+ std::ifstream resolvedfile("resources/nodata.xml");
+ std::string xml((std::istreambuf_iterator<char>(resolvedfile)),
+ std::istreambuf_iterator<char>());
+
+
+ REQUIRE(MetadataWalker::updateXmlMetadata(xml, 0x00, 0x00, false, true)
== formatXml(xml));
+
+
+}
+
+TEST_CASE("TestInvalidXml", "[InvalidSet]") {
+ std::ifstream resolvedfile("resources/invalidxml.xml");
+ std::string xml((std::istreambuf_iterator<char>(resolvedfile)),
+ std::istreambuf_iterator<char>());
+
+
+ REQUIRE_THROWS(MetadataWalker::updateXmlMetadata(xml, 0x00, 0x00,
false, true) == formatXml(xml));
+
+
+}
+
+TEST_CASE("TestUnknownSid", "[InvalidSet]") {
+ std::ifstream resolvedfile("resources/unknownsid.xml");
+ std::string xml((std::istreambuf_iterator<char>(resolvedfile)),
+ std::istreambuf_iterator<char>());
+
+
+ REQUIRE(MetadataWalker::updateXmlMetadata(xml, 0x00, 0x00, false, true)
== formatXml(xml));
+
+
+}
\ No newline at end of file
diff --git a/extensions/windows-event-log/tests/resources/invalidxml.xml
b/extensions/windows-event-log/tests/resources/invalidxml.xml
new file mode 100644
index 0000000..dbcba62
--- /dev/null
+++ b/extensions/windows-event-log/tests/resources/invalidxml.xml
@@ -0,0 +1,17 @@
+
+ <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
+ <System>
+ <Provider Name="Microsoft-Windows-Security-Auditing"
Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" />
+ <EventID>4672</EventID>
+ <Version>0</Version>
+ <Level>0</Level>
+ <Task>12548</Task>
+ <Opcode>0</Opcode>
+ <Keywords>0x8020000000000000</Keywords>
+ <TimeCreated SystemTime="2019-08-27T14:37:56.104234800Z" />
+ <EventRecordID>2575952</EventRecordID>
+ <Correlation ActivityID="{47aa1c15-3cc3-0006-e859-7fa1025cd501}" />
+ <Execution ProcessID="840" ThreadID="11544" />
+ <Channel>Security</Channel>
+ <Computer>TestComputer</Computer>
+ <Security /> >>>>>
\ No newline at end of file
diff --git a/extensions/windows-event-log/tests/resources/nobodysid.xml
b/extensions/windows-event-log/tests/resources/nobodysid.xml
new file mode 100644
index 0000000..a248989
--- /dev/null
+++ b/extensions/windows-event-log/tests/resources/nobodysid.xml
@@ -0,0 +1,23 @@
+
+ <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
+ <System>
+ <Provider Name="Microsoft-Windows-Security-Auditing"
Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" />
+ <EventID>4672</EventID>
+ <Version>0</Version>
+ <Level>0</Level>
+ <Task>12548</Task>
+ <Opcode>0</Opcode>
+ <Keywords>0x8020000000000000</Keywords>
+ <TimeCreated SystemTime="2019-08-27T14:37:56.104234800Z" />
+ <EventRecordID>2575952</EventRecordID>
+ <Correlation ActivityID="{47aa1c15-3cc3-0006-e859-7fa1025cd501}" />
+ <Execution ProcessID="840" ThreadID="11544" />
+ <Channel>Security</Channel>
+ <Computer>TestComputer</Computer>
+ <Security />
+ </System>
+ <EventData>
+ <Data Name="SubjectUserSid">S-1-0-0</Data>
+ <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege
SeSystemEnvironmentPrivilege SeImpersonatePrivilege
SeDelegateSessionUserImpersonatePrivilege</Data>
+ </EventData>
+ </Event>
\ No newline at end of file
diff --git a/extensions/windows-event-log/tests/resources/nodata.xml
b/extensions/windows-event-log/tests/resources/nodata.xml
new file mode 100644
index 0000000..790580b
--- /dev/null
+++ b/extensions/windows-event-log/tests/resources/nodata.xml
@@ -0,0 +1,19 @@
+
+ <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
+ <System>
+ <Provider Name="Microsoft-Windows-Security-Auditing"
Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" />
+ <EventID>4672</EventID>
+ <Version>0</Version>
+ <Level>0</Level>
+ <Task>12548</Task>
+ <Opcode>0</Opcode>
+ <Keywords>0x8020000000000000</Keywords>
+ <TimeCreated SystemTime="2019-08-27T14:37:56.104234800Z" />
+ <EventRecordID>2575952</EventRecordID>
+ <Correlation ActivityID="{47aa1c15-3cc3-0006-e859-7fa1025cd501}" />
+ <Execution ProcessID="840" ThreadID="11544" />
+ <Channel>Security</Channel>
+ <Computer>TestComputer</Computer>
+ <Security />
+ </System>
+ </Event>
\ No newline at end of file
diff --git a/extensions/windows-event-log/tests/resources/unknownsid.xml
b/extensions/windows-event-log/tests/resources/unknownsid.xml
new file mode 100644
index 0000000..169944e
--- /dev/null
+++ b/extensions/windows-event-log/tests/resources/unknownsid.xml
@@ -0,0 +1,23 @@
+
+ <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
+ <System>
+ <Provider Name="Microsoft-Windows-Security-Auditing"
Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" />
+ <EventID>4672</EventID>
+ <Version>0</Version>
+ <Level>0</Level>
+ <Task>12548</Task>
+ <Opcode>0</Opcode>
+ <Keywords>0x8020000000000000</Keywords>
+ <TimeCreated SystemTime="2019-08-27T14:37:56.104234800Z" />
+ <EventRecordID>2575952</EventRecordID>
+ <Correlation ActivityID="{47aa1c15-3cc3-0006-e859-7fa1025cd501}" />
+ <Execution ProcessID="840" ThreadID="11544" />
+ <Channel>Security</Channel>
+ <Computer>TestComputer</Computer>
+ <Security />
+ </System>
+ <EventData>
+ <Data Name="SubjectUserSid">S-1-8-6-5-3-0-9</Data>
+ <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege
SeSystemEnvironmentPrivilege SeImpersonatePrivilege
SeDelegateSessionUserImpersonatePrivilege</Data>
+ </EventData>
+ </Event>
\ No newline at end of file
diff --git a/extensions/windows-event-log/tests/resources/withsids.xml
b/extensions/windows-event-log/tests/resources/withsids.xml
new file mode 100644
index 0000000..29d3323
--- /dev/null
+++ b/extensions/windows-event-log/tests/resources/withsids.xml
@@ -0,0 +1,23 @@
+
+ <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
+ <System>
+ <Provider Name="Microsoft-Windows-Security-Auditing"
Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" />
+ <EventID>4672</EventID>
+ <Version>0</Version>
+ <Level>0</Level>
+ <Task>12548</Task>
+ <Opcode>0</Opcode>
+ <Keywords>0x8020000000000000</Keywords>
+ <TimeCreated SystemTime="2019-08-27T14:37:56.104234800Z" />
+ <EventRecordID>2575952</EventRecordID>
+ <Correlation ActivityID="{47aa1c15-3cc3-0006-e859-7fa1025cd501}" />
+ <Execution ProcessID="840" ThreadID="11544" />
+ <Channel>Security</Channel>
+ <Computer>TestComputer</Computer>
+ <Security />
+ </System>
+ <EventData>
+ <Data Name="SubjectUserSid">Nobody</Data>
+ <Data Name="PrivilegeList">SeAssignPrimaryTokenPrivilege SeTcbPrivilege
SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege
SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege
SeSystemEnvironmentPrivilege SeImpersonatePrivilege
SeDelegateSessionUserImpersonatePrivilege</Data>
+ </EventData>
+ </Event>
\ No newline at end of file
diff --git a/extensions/windows-event-log/wel/MetadataWalker.cpp
b/extensions/windows-event-log/wel/MetadataWalker.cpp
new file mode 100644
index 0000000..af57788
--- /dev/null
+++ b/extensions/windows-event-log/wel/MetadataWalker.cpp
@@ -0,0 +1,135 @@
+#include "MetadataWalker.h"
+#include "XMLString.h"
+
+namespace org {
+namespace apache {
+namespace nifi {
+namespace minifi {
+namespace wel {
+
+bool MetadataWalker::for_each(pugi::xml_node &node) {
+ // don't shortcut resolution here so that we can log attributes.
+ const std::string node_name = node.name();
+ if (node_name == "Data") {
+
+ for (pugi::xml_attribute attr : node.attributes())
+ {
+
+ if (std::regex_match(attr.name(), regex_)) {
+ std::function<std::string(const std::string &)>
idUpdate = [&](const std::string &input) -> std::string {
+ return resolve_ ?
utils::OsUtils::userIdToUsername(input) : input;
+ };
+ updateText(node, attr.name(),
std::move(idUpdate));
+
+ }
+ if (std::regex_match(attr.value(), regex_)) {
+ std::function<std::string(const std::string &)>
idUpdate = [&](const std::string &input) -> std::string {
+ return resolve_ ?
utils::OsUtils::userIdToUsername(input) : input;
+ };
+ updateText(node, attr.value(),
std::move(idUpdate));
+ }
+ }
+ }
+ else {
+ static std::map<std::string, EVT_FORMAT_MESSAGE_FLAGS>
formatFlagMap = { {"Channel", EvtFormatMessageChannel}, {"Keywords",
EvtFormatMessageKeyword}, {"Level", EvtFormatMessageLevel}, {"Opcode",
EvtFormatMessageOpcode} };
+ auto it = formatFlagMap.find(node_name);
+ if (it != formatFlagMap.end()) {
+ std::function<std::string(const std::string &)>
updateFunc = [&](const std::string &input) -> std::string {
+ if (resolve_) {
+ auto resolved =
getEventData(it->second);
+ if (!resolved.empty()) {
+ return resolved;
+ }
+ }
+ return input;
+ };
+ updateText(node, node.name(), std::move(updateFunc));
+ }
+ else {
+ // no conversion is required here, so let the node fall
through
+ }
+ }
+
+ return true;
+}
+
+std::map<std::string, std::string> MetadataWalker::getFieldValues() const {
+ return fields_values_;
+}
+
+
+std::string MetadataWalker::updateXmlMetadata(const std::string &xml,
EVT_HANDLE metadata_ptr, EVT_HANDLE event_ptr, bool update_xml, bool resolve,
const std::string ®ex) {
+ MetadataWalker walker(metadata_ptr, event_ptr, update_xml, resolve,
regex);
+
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load_string(xml.c_str());
+
+ if (result) {
+ doc.traverse(walker);
+ wel::XmlString writer;
+ doc.print(writer, "", pugi::format_raw); // no indentation or
formatting
+ return writer.xml_;
+ }
+ else {
+ throw std::runtime_error("Could not parse XML document");
+ }
+}
+
+std::string MetadataWalker::to_string(const wchar_t* pChar) {
+ return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(pChar);
+}
+
+void MetadataWalker::updateText(pugi::xml_node &node, const std::string
&field_name, std::function<std::string(const std::string &)> &&fn) {
+ std::string previous_value = node.text().get();
+ auto new_field_value = fn(previous_value);
+ if (new_field_value != previous_value) {
+
+ if (update_xml_) {
+ node.text().set(new_field_value.c_str());
+ } else {
+ fields_values_[field_name] = new_field_value;
+ }
+ }
+}
+
+std::string MetadataWalker::getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) {
+ LPWSTR string_buffer = NULL;
+ DWORD string_buffer_size = 0;
+ DWORD string_buffer_used = 0;
+ DWORD result = 0;
+
+ std::string event_data;
+
+ if (metadata_ptr_ == NULL | event_ptr_ == NULL) {
+ return event_data;
+ }
+ if (!EvtFormatMessage(metadata_ptr_, event_ptr_, 0, 0, NULL, flags,
string_buffer_size, string_buffer, &string_buffer_used)) {
+ result = GetLastError();
+ if (ERROR_INSUFFICIENT_BUFFER == result) {
+ string_buffer_size = string_buffer_used;
+
+ string_buffer = (LPWSTR) malloc(string_buffer_size * sizeof(WCHAR));
+
+ if (string_buffer) {
+
+ if ((EvtFormatMessageKeyword == flags))
+ string_buffer[string_buffer_size - 1] = L'\0';
+
+ EvtFormatMessage(metadata_ptr_, event_ptr_, 0, 0, NULL, flags,
string_buffer_size, string_buffer, &string_buffer_used);
+ if ((EvtFormatMessageKeyword == flags))
+ string_buffer[string_buffer_used - 1] = L'\0';
+ std::wstring str(string_buffer);
+ event_data = std::string(str.begin(), str.end());
+ free(string_buffer);
+ }
+
+ }
+ }
+ return event_data;
+}
+
+} /* namespace wel */
+} /* namespace minifi */
+} /* namespace nifi */
+} /* namespace apache */
+} /* namespace org */
diff --git a/extensions/windows-event-log/wel/MetadataWalker.h
b/extensions/windows-event-log/wel/MetadataWalker.h
new file mode 100644
index 0000000..984103a
--- /dev/null
+++ b/extensions/windows-event-log/wel/MetadataWalker.h
@@ -0,0 +1,94 @@
+/**
+ * @file ConsumeWindowsEventLog.h
+ * ConsumeWindowsEventLog class declaration
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include "core/Core.h"
+#include "FlowFileRecord.h"
+#include "concurrentqueue.h"
+#include "core/Processor.h"
+#include "core/ProcessSession.h"
+#include <pugixml.hpp>
+#include <winevt.h>
+#include <sstream>
+#include <regex>
+#include <codecvt>
+#include "utils/OsUtils.h"
+
+namespace org {
+namespace apache {
+namespace nifi {
+namespace minifi {
+namespace wel {
+
+/**
+ * Defines a tree walker for the XML input
+ *
+ */
+class MetadataWalker : public pugi::xml_tree_walker {
+ public:
+ MetadataWalker(EVT_HANDLE metadata_ptr, EVT_HANDLE event_ptr, bool
update_xml, bool resolve, const std::string ®ex = "")
+ : metadata_ptr_(metadata_ptr),
+ event_ptr_(event_ptr),
+ regex_(regex),
+ regex_str_(regex),
+ update_xml_(update_xml),
+ resolve_(resolve) {
+ }
+
+ /**
+ * Overloaded function to visit a node
+ * @param node Node that we are visiting.
+ */
+ virtual bool for_each(pugi::xml_node &node) override;
+
+ static std::string updateXmlMetadata(const std::string &xml, EVT_HANDLE
metadata_ptr, EVT_HANDLE event_ptr, bool update_xml, bool resolve, const
std::string ®ex = "");
+
+ std::map<std::string, std::string> getFieldValues() const;
+
+ private:
+
+ static std::string to_string(const wchar_t* pChar);
+
+ /**
+ * Updates text within the XML representation
+ */
+ void updateText(pugi::xml_node &node, const std::string &field_name,
std::function<std::string(const std::string &)> &&fn);
+
+ /**
+ * Gets event data.
+ */
+ std::string getEventData(EVT_FORMAT_MESSAGE_FLAGS flags);
+
+ EVT_HANDLE metadata_ptr_;
+ EVT_HANDLE event_ptr_;
+ std::regex regex_;
+ std::string regex_str_;
+ bool update_xml_;
+ bool resolve_;
+ std::map<std::string, std::string> fields_values_;
+
+};
+
+} /* namespace wel */
+} /* namespace minifi */
+} /* namespace nifi */
+} /* namespace apache */
+} /* namespace org */
diff --git a/extensions/windows-event-log/wel/XMLString.h
b/extensions/windows-event-log/wel/XMLString.h
new file mode 100644
index 0000000..0b0793a
--- /dev/null
+++ b/extensions/windows-event-log/wel/XMLString.h
@@ -0,0 +1,60 @@
+
+/**
+ * @file ConsumeWindowsEventLog.h
+ * ConsumeWindowsEventLog class declaration
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include "core/Core.h"
+#include "FlowFileRecord.h"
+#include "concurrentqueue.h"
+#include "core/Processor.h"
+#include "core/ProcessSession.h"
+#include <pugixml.hpp>
+#include <winevt.h>
+#include <sstream>
+#include <regex>
+#include <codecvt>
+#include "utils/OsUtils.h"
+
+
+
+namespace org {
+namespace apache {
+namespace nifi {
+namespace minifi {
+namespace wel {
+
+ class XmlString : public pugi::xml_writer
+ {
+ public:
+ std::string xml_;
+
+ virtual void write(const void* data, size_t size)
+ {
+ xml_.append(static_cast<const char*>(data), size);
+ }
+ };
+
+} /* namespace wel */
+} /* namespace minifi */
+} /* namespace nifi */
+} /* namespace apache */
+} /* namespace org */
+
diff --git a/libminifi/include/core/ContentRepository.h
b/libminifi/include/core/ContentRepository.h
index f42400a..348725e 100644
--- a/libminifi/include/core/ContentRepository.h
+++ b/libminifi/include/core/ContentRepository.h
@@ -104,7 +104,7 @@ class ContentRepository : public
StreamManager<minifi::ResourceClaim> {
if (count != count_map_.end() && count->second > 0) {
count_map_[str] = count->second - 1;
} else {
- count_map_[str] = 0;
+ count_map_.erase(str);
}
}
diff --git a/libminifi/src/c2/C2Agent.cpp b/libminifi/src/c2/C2Agent.cpp
index 5c3a0d0..544e752 100644
--- a/libminifi/src/c2/C2Agent.cpp
+++ b/libminifi/src/c2/C2Agent.cpp
@@ -178,8 +178,16 @@ void C2Agent::configure(const std::shared_ptr<Configure>
&configure, bool reconf
}
if (configure->get("nifi.c2.agent.heartbeat.period",
"c2.agent.heartbeat.period", heartbeat_period)) {
+ core::TimeUnit unit;
+
try {
- heart_beat_period_ = std::stoi(heartbeat_period);
+ int64_t schedulingPeriod = 0;
+ if (core::Property::StringToTime(heartbeat_period, schedulingPeriod,
unit) && core::Property::ConvertTimeUnitToMS(schedulingPeriod, unit,
schedulingPeriod)) {
+ heart_beat_period_ = schedulingPeriod;
+ logger_->log_debug("Using %u ms as the heartbeat period",
heart_beat_period_);
+ } else {
+ heart_beat_period_ = std::stoi(heartbeat_period);
+ }
} catch (const std::invalid_argument &ie) {
heart_beat_period_ = 3000;
}
diff --git a/libminifi/src/utils/StringUtils.cpp
b/libminifi/src/utils/StringUtils.cpp
index 788327b..af33fa0 100644
--- a/libminifi/src/utils/StringUtils.cpp
+++ b/libminifi/src/utils/StringUtils.cpp
@@ -17,6 +17,10 @@
#include "utils/StringUtils.h"
+#ifdef WIN32
+#include <Windows.h>
+#endif
+
namespace org {
namespace apache {
namespace nifi {
@@ -105,7 +109,15 @@ std::string
StringUtils::replaceEnvironmentVariables(std::string& original_strin
if (env_field.empty()) {
continue;
}
+#ifdef WIN32
+ DWORD buffSize = 65535;
+ std::vector<char> buffer;
+ buffer.resize(buffSize);
+ char *strVal = buffer.data();
+ GetEnvironmentVariableA(env_field.c_str(), strVal, buffSize);
+#else
const auto strVal = std::getenv(env_field.c_str());
+#endif
std::string env_value;
if (strVal != nullptr)
env_value = strVal;
@@ -141,7 +153,7 @@ std::string StringUtils::replaceMap(std::string
source_string, const std::map<st
}
std::sort(replacements.begin(), replacements.end(), [](const
std::pair<size_t, std::pair<size_t, std::string>> a,
- const
std::pair<size_t, std::pair<size_t, std::string>> &b) {
+ const std::pair<size_t, std::pair<size_t, std::string>> &b) {
return a.first > b.first;
});
diff --git a/msi/WixWin.wsi b/msi/WixWin.wsi
index d178eef..6b07237 100644
--- a/msi/WixWin.wsi
+++ b/msi/WixWin.wsi
@@ -1,4 +1,20 @@
<?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.
+-->
<?include "cpack_variables.wxi"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
@@ -7,7 +23,7 @@
<Product Id="$(var.CPACK_WIX_PRODUCT_GUID)"
Name="Apache NiFi MiNiFi"
Language="1033"
- UpgradeCode="87658309-9038-fec8-8633-f54ffaaa4921"
+ UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)"
Version="$(var.CPACK_PACKAGE_VERSION)"
Manufacturer="$(var.CPACK_PACKAGE_VENDOR)">
@@ -32,30 +48,22 @@
<Custom Action="UpdateConfig" After="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence> -->
- <DirectoryRef Id="TARGETDIR">
- <!-- <?if $(var.Platform) = x64 ?>
- <Merge Id="VCRedist" SourceFile="C:\Program Files (x86)\Common
Files\Merge Modules\Microsoft_VC140_CRT_x64.msm" DiskId="1"
Language="0" />
- <?else ?>-->
- <Merge Id="VCRedist" SourceFile="C:\Program Files (x86)\Common
Files\Merge Modules\Microsoft_VC140_CRT_x86.msm" DiskId="1"
Language="0" />
- <!-- <?endif ?>-->
- </DirectoryRef>
<Feature Id="VCRedist" Title="Visual C++ 14.0 Runtime"
AllowAdvertise="yes" Level="1">
<MergeRef Id="VCRedist"/>
</Feature>
+<!--
+ <Feature Id="VCRedist64" Title="Visual C++ 14.0 Runtime"
AllowAdvertise="yes" Level="1">
+ <MergeRef Id="VCRedist64"/>
+ <Condition
Level="1"><![CDATA[(var.CPACK_SYSTEM_NAME="win64")]]></Condition>
+ </Feature>-->
<Feature Id="InstallService" Title="Apache NiFi MiNiFi C++ Service"
AllowAdvertise="no" Display="hidden" Level="1">
<ComponentRef Id="minifiService"/>
- </Feature>
-
- <Feature Id="Install" Title="Apache NiFi MiNiFi C++ Runtimes"
AllowAdvertise="no" Display="hidden" Level="1">
- <ComponentRef Id="LICENSE"/>
- <ComponentRef Id="README"/>
- <ComponentRef Id="NOTICE"/>
+ <ComponentRef Id="minifiServiceNotLocal"/>
</Feature>
<Feature Id="InstallConf" Title="Apache NiFi MiNiFi C++ Configuration"
AllowAdvertise="yes" Level="1">
- <!-- <ComponentRef Id="MINIFIPROP"/> -->
<ComponentRef Id="LOGPROP"/>
<ComponentRef Id="UIDPROP"/>
<ComponentRef Id="CONFIGFILE"/>
@@ -63,72 +71,68 @@
<ComponentRef Id="UpdateConfigNotExist"/>
</Feature>
+ <FeatureRef Id="ProductFeature"/>
+
<?ifdef CPACK_WIX_UI_DIALOG?>
<WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/>
<?endif?>
- <UI Id="WixUI_HK">
- <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
- <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
- <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9"
Bold="yes" />
-
- <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
- <Property Id="WixUI_Mode" Value="InstallDir" />
-
- <DialogRef Id="BrowseDlg" />
- <DialogRef Id="DiskCostDlg" />
- <DialogRef Id="ErrorDlg" />
- <DialogRef Id="FatalError" />
- <DialogRef Id="FilesInUse" />
- <DialogRef Id="MsiRMFilesInUse" />
- <DialogRef Id="PrepareDlg" />
- <DialogRef Id="ProgressDlg" />
- <DialogRef Id="ResumeDlg" />
- <DialogRef Id="ResumeDlg" />
- <DialogRef Id="UserExit" />
-
- <!-- Make sure to include custom dialogs in the installer database
via a DialogRef command,
- especially if they are not included explicitly in the publish
chain below -->
- <DialogRef Id="ApacheLicenseDlg"/>
- <DialogRef Id="PropertiesDialog" />
-
- <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction"
Value="WixUIValidatePath" Order="3">1</Publish>
- <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog"
Value="InvalidDirDlg"
Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
-
- <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog"
Value="Return" Order="999">1</Publish>
-
- <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog"
Value="ApacheLicenseDlg">NOT Installed</Publish>
- <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog"
Value="VerifyReadyDlg">Installed AND PATCH</Publish>
-
- <Publish Dialog="ApacheLicenseDlg" Control="Back" Event="NewDialog"
Value="WelcomeDlg">1</Publish>
- <Publish Dialog="ApacheLicenseDlg" Control="Next" Event="NewDialog"
Value="PropertiesDialog">LicenseAccepted = "1"</Publish>
-<!--
- <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog"
Value="ApacheLicenseDlg">1</Publish>
- <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath"
Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
- <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction"
Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
- <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog"
Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND
WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
- <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog"
Value="PropertiesDialog" Order="4">WIXUI_DONTVALIDATEPATH OR
WIXUI_INSTALLDIR_VALID="1"</Publish>
- <Publish Dialog="InstallDirDlg" Control="ChangeFolder"
Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
- <Publish Dialog="InstallDirDlg" Control="ChangeFolder"
Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
--->
- <Publish Dialog="PropertiesDialog" Control="Back" Event="NewDialog"
Value="ApacheLicenseDlg">1</Publish>
- <Publish Dialog="PropertiesDialog" Control="Next" Event="NewDialog"
Value="VerifyReadyDlg">1</Publish>
+ <UI Id="WixUI_HK">
+ <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
+ <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
+ <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
+
+ <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
+ <Property Id="WixUI_Mode" Value="InstallDir" />
+
+ <DialogRef Id="BrowseDlg" />
+ <DialogRef Id="DiskCostDlg" />
+ <DialogRef Id="ErrorDlg" />
+ <DialogRef Id="FatalError" />
+ <DialogRef Id="FilesInUse" />
+ <DialogRef Id="MsiRMFilesInUse" />
+ <DialogRef Id="PrepareDlg" />
+ <DialogRef Id="ProgressDlg" />
+ <DialogRef Id="ResumeDlg" />
+ <DialogRef Id="ResumeDlg" />
+ <DialogRef Id="UserExit" />
+
+ <DialogRef Id="ApacheLicenseDlg"/>
+ <DialogRef Id="PropertiesDialog" />
+ <DialogRef Id="UserDialog" />
+
+ <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction"
Value="WixUIValidatePath" Order="3">1</Publish>
+ <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog"
Value="InvalidDirDlg"
Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
+
+ <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog"
Value="Return" Order="999">1</Publish>
+
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog"
Value="ApacheLicenseDlg">NOT Installed</Publish>
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog"
Value="VerifyReadyDlg">Installed AND PATCH</Publish>
+
+ <Publish Dialog="ApacheLicenseDlg" Control="Back" Event="NewDialog"
Value="WelcomeDlg">1</Publish>
+ <Publish Dialog="ApacheLicenseDlg" Control="Next" Event="NewDialog"
Value="UserDialog">LicenseAccepted = "1"</Publish>
+
+ <Publish Dialog="UserDialog" Control="Back" Event="NewDialog"
Value="ApacheLicenseDlg">1</Publish>
+ <Publish Dialog="UserDialog" Control="Next" Event="NewDialog"
Value="PropertiesDialog">1</Publish>
+
+ <Publish Dialog="PropertiesDialog" Control="Back" Event="NewDialog"
Value="UserDialog">1</Publish>
+ <Publish Dialog="PropertiesDialog" Control="Next" Event="NewDialog"
Value="VerifyReadyDlg">1</Publish>
- <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog"
Value="PropertiesDialog" Order="1">NOT Installed</Publish>
- <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog"
Value="MaintenanceTypeDlg" Order="2">Installed</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog"
Value="PropertiesDialog" Order="1">NOT Installed</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog"
Value="MaintenanceTypeDlg" Order="2">Installed</Publish>
- <Publish Dialog="MaintenanceWelcomeDlg" Control="Next"
Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
+ <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog"
Value="MaintenanceTypeDlg">1</Publish>
- <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton"
Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
- <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton"
Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
- <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog"
Value="MaintenanceWelcomeDlg">1</Publish>
- </UI>
+ <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton"
Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton"
Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog"
Value="MaintenanceWelcomeDlg">1</Publish>
+ </UI>
- <UIRef Id="WixUI_Common" />
+ <UIRef Id="WixUI_Common" />
<UI>
<!-- Define the installer UI -->
-
-
+
+
<Dialog Id="ApacheLicenseDlg" Width="370" Height="270" Title="Please
review our license">
<Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="207"
Width="330" Height="18" CheckBoxValue="1" Property="LicenseAccepted"
Text="Click here to accept this license" />
@@ -141,9 +145,9 @@
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56"
Height="17" Cancel="yes" Text="Cancel">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
- <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370"
Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370"
Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
<Control Id="LicenseText" Type="ScrollableText" X="20" Y="60"
Width="330" Height="140" Sunken="yes" TabSkip="no">
-
+
<Text SourceFile="$(var.CPACK_WIX_LICENSE_RTF)" />
</Control>
<Control Id="Print" Type="PushButton" X="112" Y="243" Width="56"
Height="17" Text="Print">
@@ -155,6 +159,28 @@
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15"
Transparent="yes" NoPrefix="yes" Text="Apache NiFi MiNiFi License" />
</Dialog>
+ <Dialog Id="UserDialog" Width="370" Height="270" Title="Service Account
Information">
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56"
Height="17" Default="yes" Text="Next" />
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56"
Height="17" Text="Back" />
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56"
Height="17" Cancel="yes" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280"
Height="15" Transparent="yes" NoPrefix="yes" Text="Please enter your service
account information. " />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15"
Transparent="yes" NoPrefix="yes" Text="Apache NiFi MiNiFi Properties" />
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370"
Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370"
Height="0" />
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370"
Height="0" />
+
+ <Control Id="AccountLabel" Type="Text" X="20" Y="60" Width="290"
Height="20" NoPrefix="yes" Text="Account" />
+ <Control Id="Account" Type="Edit" X="20" Y="80" Width="320"
Height="18" Property="SERVICEACCOUNT" Indirect="no" />
+
+ <Control Id="AccountPasswordLabel" Type="Text" X="20" Y="100"
Width="290" Height="20" NoPrefix="yes" Text="AccountPassword" />
+ <Control Id="AccountPassword" Type="Edit" X="20" Y="120" Width="320"
Height="18" Password="yes" Property="SERVICEACCOUNTPASSWORD" Indirect="no" />
+
+ </Dialog>
+
+
<Dialog Id="PropertiesDialog" Width="370" Height="320" Title="Agent
Properties">
<Control Id="Next" Type="PushButton" X="236" Y="290" Width="56"
Height="17" Default="yes" Text="Next" />
<Control Id="Back" Type="PushButton" X="180" Y="290" Width="56"
Height="17" Text="Back" />
@@ -164,7 +190,7 @@
<Control Id="Description" Type="Text" X="25" Y="23" Width="280"
Height="15" Transparent="yes" NoPrefix="yes" Text="Please enter values for
properties you wish to use. " />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15"
Transparent="yes" NoPrefix="yes" Text="Apache NiFi MiNiFi Properties" />
- <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370"
Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370"
Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370"
Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="283" Width="370"
Height="0" />
@@ -175,17 +201,18 @@
Text="Enable interactive Command and Control."
Default="no" />
<Control Id="AgentClassLabel" Type="Text" X="20" Y="80" Width="290"
Height="20" NoPrefix="yes" Text="Agent Class" />
- <Control Id="AgentClass" Type="Edit" X="20" Y="100" Width="320"
Height="18" Property="AGENT_CLASS" Indirect="no" ><Condition
Action="disable"><![CDATA[ENABLEC2<>1]]></Condition>
+ <Control Id="AgentClass" Type="Edit" X="20" Y="100" Width="320"
Height="18" Property="AGENT_CLASS" Indirect="no" >
+ <Condition Action="disable"><![CDATA[ENABLEC2<>1]]></Condition>
<Condition Action="enable">ENABLEC2="1"</Condition>
</Control>
- <Control Id="AgentIdentifierLabel" Type="Text" X="20" Y="120"
Width="60" Height="20" NoPrefix="yes" Text="Agent Identifier" />
- <Control Id="AgentIdentifier" Type="Edit" X="20" Y="140" Width="320"
Height="18" Property="AGENT_IDENTIFIER" Indirect="no" >
+ <Control Id="AgentIdentifierLabel" Type="Text" X="20" Y="120"
Width="60" Height="20" NoPrefix="yes" Text="Agent Identifier" />
+ <Control Id="AgentIdentifier" Type="Edit" X="20" Y="140" Width="320"
Height="18" Property="AGENT_IDENTIFIER" Indirect="no" >
<Condition Action="disable"><![CDATA[ENABLEC2<>1]]></Condition>
<Condition Action="enable">ENABLEC2="1"</Condition>
</Control>
- <Control Id="ServertHeartbeatIdentifierLabel" Type="Text" X="20"
Y="160" Width="60" Height="20" NoPrefix="yes" Text="Server Heartbeat URL" />
+ <Control Id="ServertHeartbeatIdentifierLabel" Type="Text" X="20"
Y="160" Width="80" Height="20" NoPrefix="yes" Text="Server Heartbeat URL" />
<Control Id="ServerHeartbeatIdentifier" Type="Edit" X="20" Y="180"
Width="320" Height="18" Property="SERVER_HEARTBEAT" Indirect="no" >
<Condition Action="disable"><![CDATA[ENABLEC2<>1]]></Condition>
<Condition Action="enable">ENABLEC2="1"</Condition>
@@ -197,18 +224,37 @@
<Condition Action="enable">ENABLEC2="1"</Condition>
</Control>
+ <Control Id="AgentHeartbeatLabel" Type="Text" X="20" Y="240"
Width="80" Height="20" NoPrefix="yes" Text="Agent Heartbeat" />
+ <Control Id="AgentHeartbeat" Type="ComboBox" X="20" Y="260"
Width="300" Height="17" Property="AGENT_HEARTBEAT" Sorted="yes" >
+ <ComboBox Property="AGENT_HEARTBEAT">
+ <ListItem Value="250 msec" />
+ <ListItem Value="1 sec" />
+ <ListItem Value="10 sec" />
+ <ListItem Value="30 sec" />
+ <ListItem Value="1 min" />
+ <ListItem Value="5 min" />
+ <ListItem Value="10 min" />
+ <ListItem Value="30 min" />
+ <ListItem Value="60 min" />
+ </ComboBox>
+ <Condition Action="disable"><![CDATA[ENABLEC2<>1]]></Condition>
+ <Condition Action="enable">ENABLEC2="1"</Condition>
+ </Control>
+ <!--
+ comment when available
<Control Id="AgentProtocolLabel" Type="Text" X="20" Y="240" Width="60"
Height="20" NoPrefix="yes" Text="Agent Protocol" />
<Control Id="AgentProtocolComboBreaker" Type="ComboBox" X="20" Y="260"
Width="300" Height="17" Property="AGENT_PROTOCOL" >
-
-
- <ComboBox Property="AGENT_PROTOCOL">
+
+
+
+ <ComboBox Property="AGENT_PROTOCOL">
<ListItem Value="RESTSender" />
<ListItem Value="COAPProtocol" />
</ComboBox>
<Condition Action="disable"><![CDATA[ENABLEC2<>1]]></Condition>
<Condition Action="enable">ENABLEC2="1"</Condition>
</Control>
-
+-->
</Dialog>
@@ -219,27 +265,27 @@
</UI>
<Property Id="AGENT_CLASS" Value="Your Agent Class" />
- <Property Id="AGENT_IDENTIFIER" Value="Your Agent Identifier" />
+ <Property Id="AGENT_IDENTIFIER" />
<Property Id="AGENT_PROTOCOL" Value="RESTSender" />
+ <Property Id="AGENT_HEARTBEAT" Value="250 msec" />
<Property Id="SERVER_HEARTBEAT" Value="http://localhost:8181/heartbeat" />
- <Property Id="SERVER_ACK" Value="http://localhost:8181/ack" />
+ <Property Id="SERVER_ACK" Value="http://localhost:8181/acknowledge" />
<Property Id="ENABLEC2" />
+
+ <Property Id="SERVICEACCOUNT" Value="LocalSystem" />
+ <Property Id="SERVICEACCOUNTPASSWORD" />
+
+ <SetProperty Id="AGENT_IDENTIFIER" After="AppSearch"
Value="[ComputerName]" Sequence="first" />
+
<SetProperty Id="ENABLEC2" After="AppSearch" Value="0" Sequence="first" >
<![CDATA[ENABLEC2 = 0]]>
</SetProperty>
</Product>
<Fragment>
- <DirectoryRef Id="ProgramFilesFolder">
- <Directory Id="RootMiNiFiDir" Name="ApacheNiFiMiNiFi">
+ <DirectoryRef Id="INSTALL_ROOT">
<Directory Id="RootInstallDir" Name="nifi-minifi-cpp">
- <Directory Id="AgentInstallDir" Name="minifi-agent-0.7.0">
<Directory Id="CONFIGDIR" Name="conf">
- <!--
- <Component Id="MINIFIPROP"
Guid="87658309-0339-425c-8633-f54ffaaa4941">
- <File Id="MINIFI" Source="conf/minifi.properties"
KeyPath="yes"/>
- </Component>-->
-
<Component Id="LOGPROP"
Guid="87658309-0339-425c-8633-f54ffaaa4942">
<File Id="LOG" Source="conf/minifi-log.properties"
KeyPath="yes"/>
</Component>
@@ -260,6 +306,7 @@
<IniFile Id="ConfigFileI" Action="addLine"
Name="minifi.properties" Directory="CONFIGDIR" Section="c2props"
Key="nifi.c2.agent.identifier" Value="[AGENT_IDENTIFIER]" />
<IniFile Id="ConfigFileE" Action="addLine"
Name="minifi.properties" Directory="CONFIGDIR" Section="c2props"
Key="nifi.c2.enable" Value="true" />
<IniFile Id="ConfigFileP" Action="addLine"
Name="minifi.properties" Directory="CONFIGDIR" Section="c2props"
Key="nifi.c2.agent.protocol.class" Value="[AGENT_PROTOCOL]" />
+ <IniFile Id="ConfigFileT" Action="addLine"
Name="minifi.properties" Directory="CONFIGDIR" Section="c2props"
Key="nifi.c2.agent.heartbeat.period" Value="[AGENT_HEARTBEAT]" />
<IniFile Id="ConfigFileH" Action="addLine"
Name="minifi.properties" Directory="CONFIGDIR" Section="c2props"
Key="c2.rest.url" Value="[SERVER_HEARTBEAT]" />
<IniFile Id="ConfigFileAck" Action="addLine"
Name="minifi.properties" Directory="CONFIGDIR" Section="c2props"
Key="c2.rest.url.ack" Value="[SERVER_ACK]" />
<Condition><![CDATA[ENABLEC2="1"]]></Condition>
@@ -270,19 +317,8 @@
<Condition><![CDATA[ENABLEC2<>"1"]]></Condition>
</Component>
</Directory>
- <Component Id="NOTICE" Guid="87658309-0339-425c-8633-f54ffaaa4931">
- <File Id="NOTICE" Source="NOTICE" KeyPath="yes"/>
- </Component>
-
- <Component Id="LICENSE"
Guid="87658309-0339-425c-8633-f54ffaaa4932">
- <File Id="LICENSE" Source="LICENSE" KeyPath="yes"/>
- </Component>
-
- <Component Id="README" Guid="87658309-0339-425c-8633-f54ffaaa4933">
- <File Id="README" Source="README.MD" KeyPath="yes"/>
- </Component>
- <Directory Id="INSTALLDIR" Name="bin">
+ <Directory Id="INSTALLBINDIR" Name="bin">
<Component Id="minifiService"
Guid="87658309-0339-425c-8633-f54ffaaa4921">
<File Id="MiNiFiExe"
Name="minifi.exe"
@@ -293,38 +329,61 @@
Vital="yes"
Name="Apache NiFi MiNiFi"
DisplayName="Apache NiFi MiNiFi"
- Description="Apache NiFi MiNifi Service"
+ Description="Apache NiFi MiNiFi Service"
ErrorControl="ignore"
Start="auto"
Interactive="no" />
-
+ <!--
<ServiceControl Id="ServiceControl_Start"
Name="Apache NiFi MiNiFi"
Start="install"
- Wait="no" />
+ Wait="no" />-->
<ServiceControl Id="ServiceControl_Stop"
Name="Apache NiFi MiNiFi"
Stop="both"
Remove="uninstall"
Wait="yes" />
+ <Condition><![CDATA[SERVICEACCOUNT="LocalSystem"]]></Condition>
+ </Component>
+ <Component Id="minifiServiceNotLocal"
Guid="87658309-0339-425c-8633-f54ffaaa4922">
+ <File Id="MiNiFiExeWithPassword"
+ Name="minifi.exe"
+ KeyPath="yes"
+ Source="main\minifi.exe"/>
+ <ServiceInstall Id="MiNiFiExeServiceWithPassword"
+ Type="ownProcess"
+ Vital="yes"
+ Name="Apache NiFi MiNiFi"
+ DisplayName="Apache NiFi MiNiFi"
+ Description="Apache NiFi MiNiFi Service"
+ ErrorControl="ignore"
+ Account="[SERVICEACCOUNT]"
+ Password="[SERVICEACCOUNTPASSWORD]"
+ Start="auto"
+ Interactive="no" />
+ <!--
+ <ServiceControl Id="ServiceControl_Start"
+ Name="Apache NiFi MiNiFi"
+ Start="install"
+ Wait="no" />-->
+ <ServiceControl Id="ServiceControl_Stop_WithPassword"
+ Name="Apache NiFi MiNiFi"
+ Stop="both"
+ Remove="uninstall"
+ Wait="yes" />
+
<Condition><![CDATA[SERVICEACCOUNT<>"LocalSystem"]]></Condition>
</Component>
</Directory>
</Directory>
- </Directory>
- </Directory>
</DirectoryRef>
</Fragment>
- <Fragment>
- <!-- i#1761: ideally we'd have a dialog where the user picks
- whether to do this and whether system or user, but for
- now we always do it for user (the zip file can be used
- instead of installer if this is undesirable).
- -->
+
+ <Fragment>
<ComponentGroup Id="CG_ADD_TO_PATH" Directory="INSTALL_ROOT">
<Component Id="CM_ADD_TO_PATH"
Guid="208034b8-7cc5-4718-9b99-ac50201c3f90"
KeyPath="yes">
- <Environment Id="ENV_PATH" Name="MINIFI_HOME"
Value="[INSTALL_ROOT]minifi-agent-0.7.0\"
+ <Environment Id="ENV_PATH" Name="MINIFI_HOME"
Value="[INSTALL_ROOT]minifi-agent\"
Permanent="no" Part="last" Action="set" System="no" />
</Component>
</ComponentGroup>
diff --git a/msi/x64.wsi b/msi/x64.wsi
new file mode 100644
index 0000000..56c3209
--- /dev/null
+++ b/msi/x64.wsi
@@ -0,0 +1,24 @@
+<?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.
+-->
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <DirectoryRef Id="TARGETDIR">
+ <Merge Id="VCRedist" SourceFile="C:\Program Files (x86)\Common
Files\Merge Modules\Microsoft_VC140_CRT_x64.msm" DiskId="1"
Language="0" />
+ </DirectoryRef>
+ </Fragment>
+</Wix>
\ No newline at end of file
diff --git a/msi/x86.wsi b/msi/x86.wsi
new file mode 100644
index 0000000..8136aac
--- /dev/null
+++ b/msi/x86.wsi
@@ -0,0 +1,25 @@
+<?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.
+-->
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <DirectoryRef Id="TARGETDIR">
+ <Merge Id="VCRedist" SourceFile="C:\Program Files (x86)\Common
Files\Merge Modules\Microsoft_VC140_CRT_x86.msm" DiskId="1"
Language="0" />
+ </DirectoryRef>
+ </Fragment>
+
+</Wix>
\ No newline at end of file
diff --git a/win_build_vs.bat b/win_build_vs.bat
index 9499b23..2eda497 100644
--- a/win_build_vs.bat
+++ b/win_build_vs.bat
@@ -17,8 +17,9 @@ rem limitations under the License.
TITLE Apache NiFi MiNiFi C++ Windows Build Helper
+if [%1]==[] goto usage
+
set builddir=%1
-set builddir=%builddir:"=%
set skiptests=OFF
set cmake_build_type=Release
set build_type=Release
@@ -44,9 +45,9 @@ for %%x in (%*) do (
if [%%~x] EQU [/J] (
set build_JNI=ON
)
- if [%%~x] EQU [/C] (
- set build_co=ON
- )
+ rem if [%%~x] EQU [/C] (
+ rem set build_coap=ON
+ rem )
if [%%~x] EQU [/64] (
set generator="Visual Studio 15 2017 Win64"
)
@@ -62,11 +63,17 @@ cd %builddir%\
-cmake -G %generator% -DCMAKE_BUILD_TYPE_INIT=%cmake_build_type%
-DCMAKE_BUILD_TYPE=%cmake_build_type% -DWIN32=WIN32
-DENABLE_LIBRDKAFKA=%build_kafka% -DENABLE_JNI=%build_jni% -DOPENSSL_OFF=OFF
-DENABLE_COAP=%build_coap% -DUSE_SHARED_LIBS=OFF -DDISABLE_CONTROLLER=ON
-DBUILD_ROCKSDB=ON -DFORCE_WINDOWS=ON -DUSE_SYSTEM_UUID=OFF
-DDISABLE_LIBARCHIVE=ON -DDISABLE_SCRIPTING=ON -DEXCLUDE_BOOST=ON
-DENABLE_WEL=TRUE -DSKIP_TESTS=ON -DFAIL_ON_WARNINGS=OFF
-DSKIP_TESTS=%skiptests% .. && msbuild /m [...]
+cmake -G %generator% -DCMAKE_BUILD_TYPE_INIT=%cmake_build_type%
-DCMAKE_BUILD_TYPE=%cmake_build_type% -DWIN32=WIN32
-DENABLE_LIBRDKAFKA=%build_kafka% -DENABLE_JNI=%build_jni% -DOPENSSL_OFF=OFF
-DENABLE_COAP=%build_coap% -DUSE_SHARED_LIBS=OFF -DDISABLE_CONTROLLER=ON
-DBUILD_ROCKSDB=ON -DFORCE_WINDOWS=ON -DUSE_SYSTEM_UUID=OFF
-DDISABLE_LIBARCHIVE=ON -DDISABLE_SCRIPTING=ON -DEXCLUDE_BOOST=ON
-DENABLE_WEL=TRUE -DFAIL_ON_WARNINGS=OFF -DSKIP_TESTS=%skiptests% .. && msbuild
/m nifi-minifi-cpp. [...]
if [cpack] EQU [ON] (
cpack
)
if [skiptests] NEQ [OFF] (
ctest -C %build_type%
+ IF %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
)
cd ..
+goto :eof
+
+:usage
+@echo "Usage: %0 <build_dir> options"
+exit /B 1
\ No newline at end of file