This is an automated email from the ASF dual-hosted git repository. szaszm pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit dd99e2dbcefb6278483611d246e35a8657f1381b Author: Gabor Gyimesi <gamezb...@gmail.com> AuthorDate: Mon Jul 8 13:49:58 2024 +0200 MINIFICPP-2415 MINIFICPP-2417 Drop USB Camera and openwsman extensions Closes #1831 Signed-off-by: Marton Szasz <sza...@apache.org> --- .github/workflows/ci.yml | 14 +- .github/workflows/gcc13-compat.yml | 2 +- CMakeLists.txt | 2 +- PROCESSORS.md | 70 -- README.md | 12 - Windows.md | 4 +- aptitude.sh | 5 - arch.sh | 4 - bootstrap.sh | 6 - bootstrap/package_manager.py | 8 +- bootstrap/system_dependency.py | 3 - bstrp_functions.sh | 4 - centos.sh | 15 +- cmake/BundledOpenWSMAN.cmake | 115 --- cmake/DockerConfig.cmake | 2 - cmake/MiNiFiOptions.cmake | 2 - darwin.sh | 4 - debian.sh | 5 - docker/Dockerfile | 3 - docker/centos/Dockerfile | 1 - docker/rockylinux/Dockerfile | 3 +- extensions/openwsman/CMakeLists.txt | 37 - .../SourceInitiatedSubscriptionListener.cpp | 807 --------------------- .../SourceInitiatedSubscriptionListener.h | 255 ------- extensions/usb-camera/CMakeLists.txt | 65 -- extensions/usb-camera/GetUSBCamera.cpp | 427 ----------- extensions/usb-camera/GetUSBCamera.h | 167 ----- fedora.sh | 4 - rheldistro.sh | 12 +- suse.sh | 12 +- thirdparty/openwsman/openwsman.patch | 120 --- win_build_vs.bat | 8 +- 32 files changed, 13 insertions(+), 2185 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e6760327..419ff218e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,6 @@ jobs: -DENABLE_MQTT=ON -DENABLE_OPC=ON -DENABLE_OPENCV=ON - -DENABLE_OPENWSMAN=OFF -DENABLE_OPS=ON -DENABLE_PCAP=OFF -DENABLE_PROMETHEUS=ON @@ -50,7 +49,6 @@ jobs: -DENABLE_SPLUNK=ON -DENABLE_SQL=ON -DENABLE_TEST_PROCESSORS=OFF - -DENABLE_USB_CAMERA=OFF -DFORCE_COLORED_OUTPUT=OFF -DLIBC_STATIC=OFF -DMINIFI_ADVANCED_ASAN_BUILD=OFF @@ -151,7 +149,6 @@ jobs: -DENABLE_MQTT=ON -DENABLE_OPC=ON -DENABLE_OPENCV=OFF - -DENABLE_OPENWSMAN=OFF -DENABLE_OPS=ON -DENABLE_PCAP=OFF -DENABLE_PDH=ON @@ -164,7 +161,6 @@ jobs: -DENABLE_SPLUNK=ON -DENABLE_SQL=ON -DENABLE_TEST_PROCESSORS=OFF - -DENABLE_USB_CAMERA=OFF -DENABLE_WEL=ON -DFORCE_COLORED_OUTPUT=ON -DINSTALLER_MERGE_MODULES=OFF @@ -268,7 +264,6 @@ jobs: -DENABLE_MQTT=OFF -DENABLE_OPC=OFF -DENABLE_OPENCV=OFF - -DENABLE_OPENWSMAN=OFF -DENABLE_OPS=ON -DENABLE_PCAP=ON -DENABLE_PROCFS=OFF @@ -281,7 +276,6 @@ jobs: -DENABLE_SQL=OFF -DENABLE_SYSTEMD=ON -DENABLE_TEST_PROCESSORS=OFF - -DENABLE_USB_CAMERA=OFF -DFORCE_COLORED_OUTPUT=ON -DMINIFI_FAIL_ON_WARNINGS=ON -DPORTABLE=ON @@ -372,7 +366,6 @@ jobs: -DENABLE_MQTT=ON -DENABLE_OPC=ON -DENABLE_OPENCV=ON - -DENABLE_OPENWSMAN=ON -DENABLE_OPS=ON -DENABLE_PCAP=ON -DENABLE_PROCFS=ON @@ -385,7 +378,6 @@ jobs: -DENABLE_SQL=ON -DENABLE_SYSTEMD=ON -DENABLE_TEST_PROCESSORS=OFF - -DENABLE_USB_CAMERA=ON -DFORCE_COLORED_OUTPUT=ON -DMINIFI_FAIL_ON_WARNINGS=ON -DPORTABLE=ON @@ -411,7 +403,7 @@ jobs: echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main" | sudo tee -a /etc/apt/sources.list echo "deb-src http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main" | sudo tee -a /etc/apt/sources.list sudo apt update - sudo apt install -y ccache libfl-dev libpcap-dev libusb-1.0-0-dev libpng-dev libgps-dev clang-16 clang-tidy-16 libc++-16-dev libc++abi-16-dev libc++1-16 libc++abi1-16 libunwind-16 libsqliteodbc flake8 parallel + sudo apt install -y ccache libfl-dev libpcap-dev libgps-dev clang-16 clang-tidy-16 libc++-16-dev libc++abi-16-dev libc++1-16 libc++abi1-16 libunwind-16 libsqliteodbc flake8 parallel echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV echo -e "127.0.0.1\t$HOSTNAME" | sudo tee -a /etc/hosts > /dev/null - id: free_disk_space @@ -524,8 +516,8 @@ jobs: # rocky build can run out of the github runners' disk space if built with RelWithDebInfo so we keep the Release build here mkdir build && cd build && cmake -DUSE_SHARED_LIBS=ON -DCI_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DSTRICT_GSL_CHECKS=AUDIT -DMINIFI_FAIL_ON_WARNINGS=OFF -DENABLE_AWS=ON -DENABLE_AZURE=ON \ -DENABLE_ENCRYPT_CONFIG=ON -DENABLE_GPS=ON -DENABLE_LIBRDKAFKA=ON -DENABLE_MQTT=ON -DENABLE_OPC=ON \ - -DENABLE_OPENCV=ON -DENABLE_OPENWSMAN=ON -DENABLE_OPS=ON -DENABLE_SENSORS=ON -DENABLE_SQL=ON -DENABLE_SYSTEMD=ON \ - -DENABLE_USB_CAMERA=ON -DENABLE_PYTHON_SCRIPTING=ON -DENABLE_LUA_SCRIPTING=ON -DENABLE_KUBERNETES=ON -DENABLE_GCP=ON -DENABLE_PROCFS=ON -DENABLE_PROMETHEUS=ON \ + -DENABLE_OPENCV=ON -DENABLE_OPS=ON -DENABLE_SENSORS=ON -DENABLE_SQL=ON -DENABLE_SYSTEMD=ON \ + -DENABLE_PYTHON_SCRIPTING=ON -DENABLE_LUA_SCRIPTING=ON -DENABLE_KUBERNETES=ON -DENABLE_GCP=ON -DENABLE_PROCFS=ON -DENABLE_PROMETHEUS=ON \ -DENABLE_ELASTICSEARCH=ON -DENABLE_GRAFANA_LOKI=ON -DDOCKER_SKIP_TESTS=OFF -DDOCKER_BUILD_ONLY=ON -DDOCKER_CCACHE_DUMP_LOCATION=${{ env.CCACHE_DIR }} .. && make rocky-test - name: cache save uses: actions/cache/save@v4 diff --git a/.github/workflows/gcc13-compat.yml b/.github/workflows/gcc13-compat.yml index 639f8bade..82fcc32f5 100644 --- a/.github/workflows/gcc13-compat.yml +++ b/.github/workflows/gcc13-compat.yml @@ -22,7 +22,7 @@ jobs: run: | sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt update - sudo apt install -y ccache libfl-dev libpcap-dev libboost-all-dev openjdk-8-jdk maven libusb-1.0-0-dev libpng-dev libgps-dev libsqliteodbc flake8 parallel gcc-13 g++-13 + sudo apt install -y ccache libfl-dev libpcap-dev libboost-all-dev openjdk-8-jdk maven libgps-dev libsqliteodbc flake8 parallel gcc-13 g++-13 echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV echo -e "127.0.0.1\t$HOSTNAME" | sudo tee -a /etc/hosts > /dev/null - name: build diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e702c467..1699e95f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -339,7 +339,7 @@ include(Extensions) add_subdirectory(libminifi) -if ((ENABLE_OPENWSMAN AND ENABLE_CIVET) OR ENABLE_ALL OR ENABLE_AZURE) +if (ENABLE_ALL OR ENABLE_AZURE) include(BundledLibXml2) use_bundled_libxml2(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/libxml2/dummy") diff --git a/PROCESSORS.md b/PROCESSORS.md index 7a6ec6854..380547c2b 100644 --- a/PROCESSORS.md +++ b/PROCESSORS.md @@ -54,7 +54,6 @@ limitations under the License. - [GetGPS](#GetGPS) - [GetMovementSensors](#GetMovementSensors) - [GetTCP](#GetTCP) -- [GetUSBCamera](#GetUSBCamera) - [HashContent](#HashContent) - [InvokeHTTP](#InvokeHTTP) - [JoltTransformJSON](#JoltTransformJSON) @@ -98,7 +97,6 @@ limitations under the License. - [RetryFlowFile](#RetryFlowFile) - [RouteOnAttribute](#RouteOnAttribute) - [RouteText](#RouteText) -- [SourceInitiatedSubscriptionListener](#SourceInitiatedSubscriptionListener) - [SplitText](#SplitText) - [TailEventLog](#TailEventLog) - [TailFile](#TailFile) @@ -1255,34 +1253,6 @@ In the list below, the names of required properties appear in bold. Any other pr | source.endpoint | success, partial | The address of the source endpoint the message came from | -## GetUSBCamera - -### Description - -Gets images from USB Video Class (UVC)-compatible devices. Outputs one flow file per frame at the rate specified by the FPS property in the format specified by the Format property. - -### Properties - -In the list below, the names of required properties appear in bold. Any other properties (not in bold) are considered optional. The table also indicates any default values, and whether a property supports the NiFi Expression Language. - -| Name | Default Value | Allowable Values | Description | -|----------------|---------------|------------------|-----------------------------------------------------------------------------------------------------| -| FPS | 1 | | Frames per second to capture from USB camera | -| Width | | | Target width of image to capture from USB camera | -| Height | | | Target height of image to capture from USB camera | -| Format | PNG | | Frame format (currently only PNG and RAW are supported; RAW is a binary pixel buffer of RGB values) | -| USB Vendor ID | 0x0 | | USB Vendor ID of camera device, in hexadecimal format | -| USB Product ID | 0x0 | | USB Product ID of camera device, in hexadecimal format | -| USB Serial No. | | | USB Serial No. of camera device | - -### Relationships - -| Name | Description | -|---------|---------------------------------------| -| success | Sucessfully captured images sent here | -| failure | Failures sent here | - - ## HashContent ### Description @@ -2912,46 +2882,6 @@ In the list below, the names of required properties appear in bold. Any other pr | RouteText.Group | | The value captured by all capturing groups in the 'Grouping Regular Expression' property. If this property is not set, this attribute will not be added. | -## SourceInitiatedSubscriptionListener - -### Description - -This processor implements a Windows Event Forwarding Source Initiated Subscription server with the help of OpenWSMAN. Windows hosts can be set up to connect and forward Event Logs to this processor. - -### Properties - -In the list below, the names of required properties appear in bold. Any other properties (not in bold) are considered optional. The table also indicates any default values, and whether a property supports the NiFi Expression Language. - -| Name | Default Value | Allowable Values | Description | -|--------------------------------------|-------------------------------------------------------------------------------------------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **Listen Hostname** | | | The hostname or IP of this machine that will be advertised to event sources to connect to. It must be contained as a Subject Alternative Name in the server certificate, otherwise source machines will refuse to connect. | -| **Listen Port** | 5986 | | The port to listen on. | -| **Subscription Manager Path** | /wsman/SubscriptionManager/WEC | | The URI path that will be used for the WEC Subscription Manager endpoint. | -| **Subscriptions Base Path** | /wsman/subscriptions | | The URI path that will be used as the base for endpoints serving individual subscriptions. | -| **SSL Certificate** | | | File containing PEM-formatted file including TLS/SSL certificate and key. The root CA of the certificate must be the CA set in SSL Certificate Authority. | -| **SSL Certificate Authority** | | | File containing the PEM-formatted CA that is the root CA for both this server's certificate and the event source clients' certificates. | -| SSL Verify Peer | true | true<br/>false | Whether or not to verify the client's certificate | -| **XPath XML Query** | <QueryList> - <Query Id="0"> - <Select Path="Application">*</Select> - </Query> -</QueryList> - | | An XPath Query in structured XML format conforming to the Query Schema described in https://docs.microsoft.com/en-gb/windows/win32/wes/queryschema-schema, see an example here: https://docs.microsoft.com/en-gb/windows/win32/wes/consuming-events | -| **Initial Existing Events Strategy** | None | None<br/>All | Defines the behaviour of the Processor when a new event source connects.<br/>None: will not request existing events<br/>All: will request all existing events matching the query | -| **Subscription Expiration Interval** | 10 min | | The interval while a subscription is valid without renewal. Because in a source-initiated subscription, the collector can not cancel the subscription, setting this too large could cause unnecessary load on the source machine. Setting this too small causes frequent reenumeration and resubscription which is ineffective. | -| **Heartbeat Interval** | 30 sec | | The processor will ask the sources to send heartbeats with this interval. | -| **Max Elements** | 20 | | The maximum number of events a source will batch together and send at once. | -| **Max Latency** | 10 sec | | The maximum time a source will wait to send new events. | -| Connection Retry Interval | 10 sec | | The interval with which a source will try to reconnect to the server. | -| Connection Retry Count | 5 | | The number of connection retries after which a source will consider the subscription expired. | - -### Relationships - -| Name | Description | -|---------|----------------------------------| -| success | All Events are routed to success | - - ## TailEventLog ### Description diff --git a/README.md b/README.md index 31a07cb1f..ec682253c 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,6 @@ The next table outlines CMAKE flags that correspond with MiNiFi extensions. Exte | MQTT | [ConsumeMQTT](PROCESSORS.md#consumemqtt)<br/>[PublishMQTT](PROCESSORS.md#publishmqtt) [...] | OPC | [FetchOPCProcessor](PROCESSORS.md#fetchopcprocessor)<br/>[PutOPCProcessor](PROCESSORS.md#putopcprocessor) [...] | OpenCV | [CaptureRTSPFrame](PROCESSORS.md#capturertspframe)<br/>[MotionDetector](PROCESSORS.md#motiondetector) [...] -| OpenWSMAN | SourceInitiatedSubscriptionListener [...] | PCAP | [CapturePacket](PROCESSORS.md#capturepacket) [...] | PDH (Windows) | [PerformanceDataMonitor](PROCESSORS.md#performancedatamonitor) [...] | ProcFs (Linux) | [ProcFsMonitor](PROCESSORS.md#procfsmonitor) [...] @@ -97,7 +96,6 @@ The next table outlines CMAKE flags that correspond with MiNiFi extensions. Exte | SQL | [ExecuteSQL](PROCESSORS.md#executesql)<br/>[PutSQL](PROCESSORS.md#putsql)<br/>[QueryDatabaseTable](PROCESSORS.md#querydatabasetable)<br/> [...] | Splunk | [PutSplunkHTTP](PROCESSORS.md#putsplunkhttp)<br/>[QuerySplunkIndexingStatus](PROCESSORS.md#querysplunkindexingstatus) [...] | Systemd (Linux) | [ConsumeJournald](PROCESSORS.md#consumejournald) [...] -| USB Camera | [GetUSBCamera](PROCESSORS.md#getusbcamera) [...] | Windows Event Log (Windows) | [CollectorInitiatedSubscription](PROCESSORS.md#collectorinitiatedsubscription)<br/>[ConsumeWindowsEventLog](PROCESSORS.md#consumewindowseventlog)<br/>[TailEventLog](PROCESSORS.md#taileventlog) [...] Please see our [Python guide](extensions/python/PYTHON.md) on how to write Python processors and use them within MiNiFi C++. @@ -180,8 +178,6 @@ On all distributions please use -DUSE_SHARED_LIBS=OFF to statically link zlib, l #### System Libraries Required * Python 3 -- Required if Python support is enabled -* libusb -- Optional, unless USB Camera support is enabled -* libpng -- Optional, unless USB Camera support is enabled * libpcap -- Optional, unless ENABLE_PCAP specified The needed dependencies can be installed with the following commands for: @@ -209,8 +205,6 @@ dnf install cmake \ zlib-devel # (Optional) for building Python support dnf install python36-devel -# (Optional) for building USB Camera support -dnf install libusb-devel libpng-devel # (Optional) for building docker image dnf install docker # (Optional) for system integration tests @@ -242,8 +236,6 @@ apt install cmake \ zlib1g-dev # (Optional) for building Python support apt install libpython3-dev -# (Optional) for building USB Camera support -apt install libusb-1.0.0-0-dev libpng12-dev # (Optional) for building docker image apt install docker.io # (Optional) for system integration tests @@ -272,8 +264,6 @@ brew install cmake \ zlib brew install curl brew link curl --force -# (Optional) for building USB Camera support -brew install libusb libpng # (Optional) for building docker image/running system integration tests # Install docker using instructions at https://docs.docker.com/docker-for-mac/install/ sudo pip install virtualenv @@ -347,7 +337,6 @@ This will set up a virtual environment in the bootstrap folder, and guide you th E. Expression Language support .Enabled F. Kafka support ...............Enabled G. PCAP support ................Disabled - H. USB Camera support ..........Disabled I. GPS support .................Disabled K. Bustache Support ............Disabled L. Lua Scripting Support .......Enabled @@ -357,7 +346,6 @@ This will set up a virtual environment in the bootstrap folder, and guide you th T. OpenCV Support ..............Disabled U. OPC-UA Support...............Enabled V. SQL Support..................Enabled - W. Openwsman Support ...........Disabled X. Azure Support ...............Enabled Y. Systemd Support .............Enabled AA. Splunk Support .............Enabled diff --git a/Windows.md b/Windows.md index 616032c4c..c9ff74c1e 100644 --- a/Windows.md +++ b/Windows.md @@ -82,7 +82,6 @@ After the build directory it will take optional parameters modifying the CMake c | /NO_LUA_SCRIPTING | Disables Lua scripting extension | | /NO_PYTHON_SCRIPTING | Disables Python scripting extension | | /SENSORS | Enables the Sensors package | -| /USB_CAMERA | Enables USB camera support | | /O | Enables OpenCV | | /NO_PROMETHEUS | Disables Prometheus | | /RO | Use real ODBC driver in tests instead of mock SQL driver | @@ -97,7 +96,6 @@ After the build directory it will take optional parameters modifying the CMake c | /SCCACHE | Uses sccache build caching | | /BUSTACHE | Enables Bustache templating support | | /NO_OPC | Disables OPC extension | -| /OPENWSMAN | Enables OpenWSMAN extension | | /NO_OPS | Disables OPS extension | | /PCAP | Enables PCAP extension | | /LOKI | Enables Grafana Loki extension | @@ -126,7 +124,7 @@ A basic working CMake configuration can be inferred from the `win_build_vs.bat`. ``` mkdir build cd build -cmake -G "Visual Studio 17 2022" -A x64 -DMINIFI_INCLUDE_VC_REDIST_MERGE_MODULES=OFF -DTEST_CUSTOM_WEL_PROVIDER=OFF -DENABLE_SQL=OFF -DMINIFI_USE_REAL_ODBC_TEST_DRIVER=OFF -DCMAKE_BUILD_TYPE_INIT=Release -DCMAKE_BUILD_TYPE=Release -DWIN32=WIN32 -DENABLE_LIBRDKAFKA=OFF -DENABLE_AWS=OFF -DENABLE_PDH= -DENABLE_AZURE=OFF -DENABLE_SFTP=OFF -DENABLE_SPLUNK= -DENABLE_GCP= -DENABLE_OPENCV=OFF -DENABLE_PROMETHEUS=OFF -DENABLE_ELASTICSEARCH= -DUSE_SHARED_LIBS=OFF -DENABLE_CONTROLLER=ON -DENABLE_BU [...] +cmake -G "Visual Studio 17 2022" -A x64 -DMINIFI_INCLUDE_VC_REDIST_MERGE_MODULES=OFF -DTEST_CUSTOM_WEL_PROVIDER=OFF -DENABLE_SQL=OFF -DMINIFI_USE_REAL_ODBC_TEST_DRIVER=OFF -DCMAKE_BUILD_TYPE_INIT=Release -DCMAKE_BUILD_TYPE=Release -DWIN32=WIN32 -DENABLE_LIBRDKAFKA=OFF -DENABLE_AWS=OFF -DENABLE_PDH= -DENABLE_AZURE=OFF -DENABLE_SFTP=OFF -DENABLE_SPLUNK= -DENABLE_GCP= -DENABLE_OPENCV=OFF -DENABLE_PROMETHEUS=OFF -DENABLE_ELASTICSEARCH= -DUSE_SHARED_LIBS=OFF -DENABLE_CONTROLLER=ON -DENABLE_BU [...] msbuild /m nifi-minifi-cpp.sln /property:Configuration=Release /property:Platform=x64 copy minifi_main\Release\minifi.exe minifi_main\ cpack diff --git a/aptitude.sh b/aptitude.sh index 6d576e986..33e31638d 100644 --- a/aptitude.sh +++ b/aptitude.sh @@ -68,11 +68,6 @@ build_deps(){ INSTALLED+=("libpcap-dev") elif [ "$FOUND_VALUE" = "openssl" ]; then INSTALLED+=("openssl") - elif [ "$FOUND_VALUE" = "libusb" ]; then - INSTALLED+=("libusb-1.0-0-dev") - INSTALLED+=("libusb-dev") - elif [ "$FOUND_VALUE" = "libpng" ]; then - INSTALLED+=("libpng-dev") elif [ "$FOUND_VALUE" = "bison" ]; then INSTALLED+=("bison") elif [ "$FOUND_VALUE" = "flex" ]; then diff --git a/arch.sh b/arch.sh index 8020709fc..73ea3a453 100644 --- a/arch.sh +++ b/arch.sh @@ -48,10 +48,6 @@ build_deps(){ INSTALLED+=("libpcap") elif [ "$FOUND_VALUE" = "openssl" ]; then INSTALLED+=("openssl") - elif [ "$FOUND_VALUE" = "libusb" ]; then - INSTALLED+=("libusb") - elif [ "$FOUND_VALUE" = "libpng" ]; then - INSTALLED+=("libpng") elif [ "$FOUND_VALUE" = "bison" ]; then INSTALLED+=("bison") elif [ "$FOUND_VALUE" = "flex" ]; then diff --git a/bootstrap.sh b/bootstrap.sh index 8e53d3a0a..d45b0c924 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -276,10 +276,6 @@ add_dependency EXPRESSION_LANGUAGE_ENABLED "flex" add_option PCAP_ENABLED ${FALSE} "ENABLE_PCAP" add_dependency PCAP_ENABLED "libpcap" -add_option USB_ENABLED ${FALSE} "ENABLE_USB_CAMERA" -add_dependency USB_ENABLED "libusb" -add_dependency USB_ENABLED "libpng" - add_option GPS_ENABLED ${FALSE} "ENABLE_GPS" add_dependency GPS_ENABLED "gpsd" @@ -298,8 +294,6 @@ add_dependency SFTP_ENABLED "libssh2" add_option SQL_ENABLED ${TRUE} "ENABLE_SQL" -add_option OPENWSMAN_ENABLED ${FALSE} "ENABLE_OPENWSMAN" - # Since the following extensions have limitations on add_option BUSTACHE_ENABLED ${FALSE} "ENABLE_BUSTACHE" "2.6" ${TRUE} diff --git a/bootstrap/package_manager.py b/bootstrap/package_manager.py index 36740e06f..5bc0b2de3 100644 --- a/bootstrap/package_manager.py +++ b/bootstrap/package_manager.py @@ -119,8 +119,6 @@ class AptPackageManager(PackageManager): install_cmd="sudo apt install -y", replace_dict={"libarchive": {"liblzma-dev"}, "python": {"libpython3-dev"}, - "libusb": {"libusb-1.0-0-dev", "libusb-dev"}, - "libpng": {"libpng-dev"}, "libpcap": {"libpcap-dev"}, "gpsd": {"libgps-dev"}}) @@ -150,9 +148,7 @@ class DnfPackageManager(PackageManager): install_cmd="sudo dnf --enablerepo=crb install -y epel-release", replace_dict={"gpsd": {"gpsd-devel"}, "libpcap": {"libpcap-devel"}, - "python": {"python3-devel"}, - "libpng": {"libpng-devel"}, - "libusb": {"libusb-devel"}}) + "python": {"python3-devel"}}) def _get_installed_packages(self) -> Set[str]: result = subprocess.run(['dnf', 'list', 'installed'], text=True, capture_output=True, check=True) @@ -247,12 +243,10 @@ class ChocolateyPackageManager(PackageManager): "flex": set(), "libarchive": set(), "libpcap": set(), - "libpng": set(), "gpsd": set(), "automake": set(), "autoconf": set(), "libtool": set(), - "libusb": set(), "make": set(), "perl": {"strawberryperl", "NASM"}}) return True diff --git a/bootstrap/system_dependency.py b/bootstrap/system_dependency.py index 6ab92d5d5..84af92475 100644 --- a/bootstrap/system_dependency.py +++ b/bootstrap/system_dependency.py @@ -32,9 +32,6 @@ def _create_system_dependencies(minifi_options: MinifiOptions) -> Dict[str, Set[ system_dependencies['libarchive'] = {'libarchive'} if minifi_options.is_enabled("ENABLE_PCAP"): system_dependencies['libpcap'] = {'libpcap'} - if minifi_options.is_enabled("ENABLE_USB_CAMERA"): - system_dependencies['libusb'] = {'libusb'} - system_dependencies['libpng'] = {'libpng'} if minifi_options.is_enabled("ENABLE_GPS"): system_dependencies['gpsd'] = {'gpsd'} if minifi_options.is_enabled("ENABLE_SQL"): diff --git a/bstrp_functions.sh b/bstrp_functions.sh index ca95a6331..b51d9b6df 100755 --- a/bstrp_functions.sh +++ b/bstrp_functions.sh @@ -365,7 +365,6 @@ show_supported_features() { echo "E. Expression Language support .$(print_feature_status EXPRESSION_LANGUAGE_ENABLED)" echo "F. Kafka support ...............$(print_feature_status KAFKA_ENABLED)" echo "G. PCAP support ................$(print_feature_status PCAP_ENABLED)" - echo "H. USB Camera support ..........$(print_feature_status USB_ENABLED)" echo "I. GPS support .................$(print_feature_status GPS_ENABLED)" echo "K. Bustache Support ............$(print_feature_status BUSTACHE_ENABLED)" echo "L. Lua Scripting Support .......$(print_feature_status LUA_SCRIPTING_ENABLED)" @@ -375,7 +374,6 @@ show_supported_features() { echo "T. OpenCV Support ..............$(print_feature_status OPENCV_ENABLED)" echo "U. OPC-UA Support...............$(print_feature_status OPC_ENABLED)" echo "V. SQL Support..................$(print_feature_status SQL_ENABLED)" - echo "W. Openwsman Support ...........$(print_feature_status OPENWSMAN_ENABLED)" echo "X. Azure Support ...............$(print_feature_status AZURE_ENABLED)" if $LINUX; then echo "Y. Systemd Support .............$(print_feature_status SYSTEMD_ENABLED)" @@ -418,7 +416,6 @@ read_feature_options(){ e) ToggleFeature EXPRESSION_LANGUAGE_ENABLED ;; f) ToggleFeature KAFKA_ENABLED ;; g) ToggleFeature PCAP_ENABLED ;; - h) ToggleFeature USB_ENABLED ;; i) ToggleFeature GPS_ENABLED ;; k) ToggleFeature BUSTACHE_ENABLED ;; l) ToggleFeature LUA_SCRIPTING_ENABLED ;; @@ -428,7 +425,6 @@ read_feature_options(){ t) ToggleFeature OPENCV_ENABLED ;; u) ToggleFeature OPC_ENABLED ;; v) ToggleFeature SQL_ENABLED ;; - w) ToggleFeature OPENWSMAN_ENABLED ;; x) ToggleFeature AZURE_ENABLED ;; y) if $LINUX; then ToggleFeature SYSTEMD_ENABLED; fi ;; aa) ToggleFeature SPLUNK_ENABLED ;; diff --git a/centos.sh b/centos.sh index 5558a19bc..0e26ccd2f 100644 --- a/centos.sh +++ b/centos.sh @@ -35,11 +35,7 @@ install_pkgs() { verify_enable_platform() { feature="$1" if [ "$OS_MAJOR" -gt 6 ]; then - if [ "$feature" = "USB_ENABLED" ]; then - echo "false" - else - verify_gcc_enable "$feature" - fi + verify_gcc_enable "$feature" fi } @@ -51,11 +47,6 @@ install_bison() { INSTALLED+=("bison") } -install_libusb() { - INSTALLED+=("libusb-devel") -} - - bootstrap_cmake(){ install_cmake_from_binary } @@ -84,10 +75,6 @@ build_deps() { FOUND_VALUE="$VALUE" if [ "$FOUND_VALUE" = "libpcap" ]; then INSTALLED+=("libpcap-devel") - elif [ "$FOUND_VALUE" = "libusb" ]; then - install_libusb - elif [ "$FOUND_VALUE" = "libpng" ]; then - INSTALLED+=("libpng-devel") elif [ "$FOUND_VALUE" = "bison" ]; then install_bison elif [ "$FOUND_VALUE" = "flex" ]; then diff --git a/cmake/BundledOpenWSMAN.cmake b/cmake/BundledOpenWSMAN.cmake deleted file mode 100644 index 0392768b2..000000000 --- a/cmake/BundledOpenWSMAN.cmake +++ /dev/null @@ -1,115 +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. - -function(use_bundled_openwsman SOURCE_DIR BINARY_DIR) - message("Using bundled openwsman") - - # Define patch step - set(PC "${Patch_EXECUTABLE}" -p1 -i "${SOURCE_DIR}/thirdparty/openwsman/openwsman.patch") - - # Define byproducts - if (APPLE) - set(PREFIX "lib/lib") - set(POSTFIX ".a") - elseif(WIN32) - message(FATAL_ERROR "OpenWSMAN Windows build is not supported") - else() - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(PREFIX "lib64/lib") - else() - set(PREFIX "lib/lib") - endif() - set(POSTFIX ".a") - endif() - - set(BYPRODUCTS - "${PREFIX}wsman${POSTFIX}" - "${PREFIX}wsman_client${POSTFIX}" - "${PREFIX}wsman_curl_client_transport${POSTFIX}" - ) - - FOREACH(BYPRODUCT ${BYPRODUCTS}) - LIST(APPEND OPENWSMAN_LIBRARIES_LIST "${BINARY_DIR}/thirdparty/openwsman-install/${BYPRODUCT}") - ENDFOREACH(BYPRODUCT) - - # Set build options - set(OPENWSMAN_CMAKE_ARGS - ${PASSTHROUGH_CMAKE_ARGS} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - "-DCMAKE_INSTALL_PREFIX=${BINARY_DIR}/thirdparty/openwsman-install" - -DBUILD_PYTHON=NO - -DBUILD_PYTHON3=NO - -DBUILD_LIBCIM=NO - -DBUILD_EXAMPLES=NO - -DBUILD_BINDINGS=NO - -DBUILD_RUBY=NO - -DBUILD_PERL=NO - -DBUILD_JAVA=NO - -DBUILD_CSHARP=NO - -DBUILD_CUNIT_TESTS=NO - -DDISABLE_PLUGINS=YES - -DUSE_PAM=NO - -DBUILD_TESTS=NO - -DDISABLE_SERVER=YES - -DBUILD_SHARED_LIBS=NO) - - append_third_party_passthrough_args(OPENWSMAN_CMAKE_ARGS "${OPENWSMAN_CMAKE_ARGS}") - - # Build project - ExternalProject_Add( - openwsman-external - URL "https://github.com/Openwsman/openwsman/archive/v2.6.11.tar.gz" - URL_HASH "SHA256=895eaaae62925f9416766ea3e71a5368210e6cfe13b23e4e0422fa0e75c2541c" - SOURCE_DIR "${BINARY_DIR}/thirdparty/openwsman-src" - LIST_SEPARATOR % # This is needed for passing semicolon-separated lists - CMAKE_ARGS ${OPENWSMAN_CMAKE_ARGS} - PATCH_COMMAND ${PC} - BUILD_BYPRODUCTS "${OPENWSMAN_LIBRARIES_LIST}" - EXCLUDE_FROM_ALL TRUE - ) - - # Set dependencies - add_dependencies(openwsman-external LibXml2::LibXml2 OpenSSL::SSL OpenSSL::Crypto CURL::libcurl) - - # Set variables - set(OPENWSMAN_FOUND "YES" CACHE STRING "" FORCE) - set(OPENWSMAN_INCLUDE_DIR "${BINARY_DIR}/thirdparty/openwsman-src/include" CACHE STRING "" FORCE) - set(OPENWSMAN_LIBRARIES "${OPENWSMAN_LIBRARIES_LIST}" CACHE STRING "" FORCE) - - # Create imported targets - file(MAKE_DIRECTORY ${OPENWSMAN_INCLUDE_DIR}) - - add_library(OpenWSMAN::libwsman_curl_client_transport STATIC IMPORTED) - set_target_properties(OpenWSMAN::libwsman_curl_client_transport PROPERTIES IMPORTED_LOCATION "${BINARY_DIR}/thirdparty/openwsman-install/${PREFIX}wsman_curl_client_transport${POSTFIX}") - add_dependencies(OpenWSMAN::libwsman_curl_client_transport openwsman-external) - set_property(TARGET OpenWSMAN::libwsman_curl_client_transport APPEND PROPERTY INTERFACE_LINK_LIBRARIES LibXml2::LibXml2 OpenSSL::SSL OpenSSL::Crypto CURL::libcurl) - set_property(TARGET OpenWSMAN::libwsman_curl_client_transport APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENWSMAN_INCLUDE_DIR}) - - add_library(OpenWSMAN::libwsman_client STATIC IMPORTED) - set_target_properties(OpenWSMAN::libwsman_client PROPERTIES IMPORTED_LOCATION "${BINARY_DIR}/thirdparty/openwsman-install/${PREFIX}wsman_client${POSTFIX}") - add_dependencies(OpenWSMAN::libwsman_client openwsman-external) - set_property(TARGET OpenWSMAN::libwsman_client APPEND PROPERTY INTERFACE_LINK_LIBRARIES LibXml2::LibXml2) - set_property(TARGET OpenWSMAN::libwsman_client APPEND PROPERTY INTERFACE_LINK_LIBRARIES OpenWSMAN::libwsman_curl_client_transport) - set_property(TARGET OpenWSMAN::libwsman_client APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENWSMAN_INCLUDE_DIR}) - - add_library(OpenWSMAN::libwsman STATIC IMPORTED) - set_target_properties(OpenWSMAN::libwsman PROPERTIES IMPORTED_LOCATION "${BINARY_DIR}/thirdparty/openwsman-install/${PREFIX}wsman${POSTFIX}") - add_dependencies(OpenWSMAN::libwsman openwsman-external) - set_property(TARGET OpenWSMAN::libwsman APPEND PROPERTY INTERFACE_LINK_LIBRARIES LibXml2::LibXml2) - set_property(TARGET OpenWSMAN::libwsman APPEND PROPERTY INTERFACE_LINK_LIBRARIES OpenWSMAN::libwsman_client) - set_property(TARGET OpenWSMAN::libwsman APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${OPENWSMAN_INCLUDE_DIR}) -endfunction(use_bundled_openwsman) diff --git a/cmake/DockerConfig.cmake b/cmake/DockerConfig.cmake index f343ffb8a..0010b995c 100644 --- a/cmake/DockerConfig.cmake +++ b/cmake/DockerConfig.cmake @@ -67,11 +67,9 @@ add_custom_target( -DENABLE_GPS=OFF -DENABLE_PCAP=OFF -DENABLE_SENSORS=OFF - -DENABLE_USB_CAMERA=OFF -DENABLE_OPENCV=OFF -DENABLE_BUSTACHE=OFF -DENABLE_SFTP=OFF - -DENABLE_OPENWSMAN=OFF -DENABLE_TEST_PROCESSORS=OFF -DENABLE_ROCKSDB=ON -DENABLE_LIBARCHIVE=ON diff --git a/cmake/MiNiFiOptions.cmake b/cmake/MiNiFiOptions.cmake index 3c4c7fdb4..65ba1bcc9 100644 --- a/cmake/MiNiFiOptions.cmake +++ b/cmake/MiNiFiOptions.cmake @@ -102,12 +102,10 @@ add_minifi_option(ENABLE_LIBRDKAFKA "Enables the librdkafka extension." ON) add_minifi_option(ENABLE_LUA_SCRIPTING "Enables lua scripting" ON) add_minifi_option(ENABLE_PYTHON_SCRIPTING "Enables python scripting" ON) add_minifi_option(ENABLE_SENSORS "Enables the Sensors package." OFF) -add_minifi_option(ENABLE_USB_CAMERA "Enables USB camera support." OFF) add_minifi_option(ENABLE_AWS "Enables AWS support." ON) add_minifi_option(ENABLE_OPENCV "Enables the OpenCV extensions." OFF) add_minifi_option(ENABLE_BUSTACHE "Enables Bustache (ApplyTemplate) support." OFF) add_minifi_option(ENABLE_SFTP "Enables SFTP support." OFF) -add_minifi_option(ENABLE_OPENWSMAN "Enables the Openwsman extensions." OFF) add_minifi_option(ENABLE_AZURE "Enables Azure support." ON) add_minifi_option(ENABLE_ENCRYPT_CONFIG "Enables build of encrypt-config binary." ON) add_minifi_option(ENABLE_SPLUNK "Enable Splunk support" ON) diff --git a/darwin.sh b/darwin.sh index eb47c4403..1801d6914 100644 --- a/darwin.sh +++ b/darwin.sh @@ -80,10 +80,6 @@ build_deps(){ FOUND_VALUE="$VALUE" if [ "$FOUND_VALUE" = "libpcap" ]; then INSTALLED+=("libpcap") - elif [ "$FOUND_VALUE" = "libusb" ]; then - INSTALLED+=("libusb") - elif [ "$FOUND_VALUE" = "libpng" ]; then - INSTALLED+=("libpng") elif [ "$FOUND_VALUE" = "bison" ]; then install_bison elif [ "$FOUND_VALUE" = "flex" ]; then diff --git a/debian.sh b/debian.sh index b39425937..12a2e3173 100644 --- a/debian.sh +++ b/debian.sh @@ -59,11 +59,6 @@ build_deps(){ FOUND_VALUE="$VALUE" if [ "$FOUND_VALUE" = "libpcap" ]; then INSTALLED+=("libpcap-dev") - elif [ "$FOUND_VALUE" = "libusb" ]; then - INSTALLED+=("libusb-1.0-0-dev") - INSTALLED+=("libusb-dev") - elif [ "$FOUND_VALUE" = "libpng" ]; then - INSTALLED+=("libpng-dev") elif [ "$FOUND_VALUE" = "bison" ]; then INSTALLED+=("bison") elif [ "$FOUND_VALUE" = "flex" ]; then diff --git a/docker/Dockerfile b/docker/Dockerfile index 61e25e69c..0e83f0c12 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -49,8 +49,6 @@ RUN apk --no-cache add gcc \ git \ patch \ libpcap-dev \ - libpng-dev \ - libusb-dev \ gpsd-dev \ python3-dev \ doxygen \ @@ -99,7 +97,6 @@ RUN addgroup -g ${GID} ${USER} && adduser -u ${UID} -D -G ${USER} -g "" ${USER} apk add --no-cache libstdc++ tzdata alpine-conf && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_GPS=ON"; then apk add --no-cache gpsd; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_PCAP=ON"; then apk add --no-cache libpcap; fi && \ - if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_USB_CAMERA=ON"; then apk add --no-cache libpng libusb; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_PYTHON_SCRIPTING=ON"; then apk add --no-cache python3; fi # Copy built minifi distribution from builder diff --git a/docker/centos/Dockerfile b/docker/centos/Dockerfile index 455f24e8e..cbf95aa65 100644 --- a/docker/centos/Dockerfile +++ b/docker/centos/Dockerfile @@ -46,7 +46,6 @@ COPY . ${MINIFI_BASE_DIR} RUN ulimit -n 1024000 && yum -y install epel-release && yum -y install sudo git which make libarchive ccache ca-certificates perl-IPC-Cmd && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_GPS=ON"; then yum -y install gpsd-devel; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_PCAP=ON"; then yum -y install libpcap-devel; fi && \ - if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_USB_CAMERA=ON"; then yum -y install libpng-devel libusbx-devel; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_PYTHON_SCRIPTING=ON"; then yum -y install python36-devel; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_SFTP=ON" && [ "${DOCKER_SKIP_TESTS}" == "OFF" ]; then yum -y install java-1.8.0-openjdk maven; fi diff --git a/docker/rockylinux/Dockerfile b/docker/rockylinux/Dockerfile index 873dc341e..9d90552c6 100644 --- a/docker/rockylinux/Dockerfile +++ b/docker/rockylinux/Dockerfile @@ -41,10 +41,9 @@ COPY . ${MINIFI_BASE_DIR} # Install the system dependencies needed for a build # gpsd-devel and ccache are in EPEL RUN dnf -y install epel-release && dnf -y install gcc-toolset-12 sudo git which make libarchive ccache ca-certificates perl patch bison flex libtool cmake && \ - if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_ALL=ON"; then dnf -y --enablerepo=devel install gpsd-devel libpng-devel libusbx-devel python3-devel libpcap-devel; fi && \ + if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_ALL=ON"; then dnf -y --enablerepo=devel install gpsd-devel python3-devel libpcap-devel; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_GPS=ON"; then dnf -y install gpsd-devel; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_PCAP=ON"; then dnf -y --enablerepo=devel install libpcap-devel; fi && \ - if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_USB_CAMERA=ON"; then dnf -y install libpng-devel libusbx-devel; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_PYTHON_SCRIPTING=ON"; then dnf -y install python3-devel; fi && \ if echo "$MINIFI_OPTIONS" | grep -q "ENABLE_SFTP=ON" && [ "${DOCKER_SKIP_TESTS}" == "OFF" ]; then dnf -y install java-1.8.0-openjdk maven; fi diff --git a/extensions/openwsman/CMakeLists.txt b/extensions/openwsman/CMakeLists.txt deleted file mode 100644 index e97bc6a5b..000000000 --- a/extensions/openwsman/CMakeLists.txt +++ /dev/null @@ -1,37 +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. -# - -if (WIN32 OR NOT ((ENABLE_ALL OR ENABLE_OPENWSMAN) AND ENABLE_CIVET)) - return() -endif() - -include(BundledOpenWSMAN) -use_bundled_openwsman(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}) - -include(${CMAKE_SOURCE_DIR}/extensions/ExtensionHeader.txt) - -file(GLOB SOURCES "processors/*.cpp") - -add_minifi_library(minifi-openwsman SHARED ${SOURCES}) - -target_link_libraries(minifi-openwsman ${LIBMINIFI} Threads::Threads) -target_link_libraries(minifi-openwsman OpenWSMAN::libwsman civetweb::civetweb-cpp civetweb::c-library LibXml2::LibXml2) - -register_extension(minifi-openwsman "OPENWSMAN EXTENSIONS" OPENWSMAN-EXTENSIONS "This enables Openwsman support") -register_extension_linter(minifi-openwsman-linter) diff --git a/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.cpp b/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.cpp deleted file mode 100644 index 8f1b788dc..000000000 --- a/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.cpp +++ /dev/null @@ -1,807 +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. - */ - -#include "SourceInitiatedSubscriptionListener.h" -#include <openssl/x509.h> - -#include <memory> -#include <algorithm> -#include <cctype> -#include <cstdint> -#include <cstring> -#include <iostream> -#include <iterator> -#include <limits> -#include <unordered_map> -#include <string> -#include <utility> -#include <vector> -#include <tuple> - -extern "C" { -#include "wsman-api.h" -#include "wsman-xml-api.h" -#include "wsman-xml-serialize.h" -#include "wsman-xml-serializer.h" -#include "wsman-soap.h" -#include "wsman-soap-envelope.h" -} - -#include "utils/ByteArrayCallback.h" -#include "core/FlowFile.h" -#include "core/logging/Logger.h" -#include "core/ProcessContext.h" -#include "core/ProcessSessionFactory.h" -#include "core/Resource.h" -#include "io/BufferStream.h" -#include "ResourceClaim.h" -#include "utils/gsl.h" -#include "utils/StringUtils.h" -#include "utils/file/FileUtils.h" -#include "utils/tls/CertificateUtils.h" - -namespace { -constexpr const char* XML_NS_CUSTOM_SUBSCRIPTION = "http://schemas.microsoft.com/wbem/wsman/1/subscription"; -constexpr const char* XML_NS_CUSTOM_AUTHENTICATION = "http://schemas.microsoft.com/wbem/wsman/1/authentication"; -constexpr const char* XML_NS_CUSTOM_POLICY = "http://schemas.xmlsoap.org/ws/2002/12/policy"; -constexpr const char* XML_NS_CUSTOM_MACHINEID = "http://schemas.microsoft.com/wbem/wsman/1/machineid"; -constexpr const char* WSMAN_CUSTOM_ACTION_ACK = "http://schemas.dmtf.org/wbem/wsman/1/wsman/Ack"; -constexpr const char* WSMAN_CUSTOM_ACTION_HEARTBEAT = "http://schemas.dmtf.org/wbem/wsman/1/wsman/Heartbeat"; -constexpr const char* WSMAN_CUSTOM_ACTION_EVENTS = "http://schemas.dmtf.org/wbem/wsman/1/wsman/Events"; -} // namespace - -namespace org::apache::nifi::minifi::processors { - -SourceInitiatedSubscriptionListener::SourceInitiatedSubscriptionListener(std::string_view name, const utils::Identifier& uuid) - : Processor(name, uuid) - , session_factory_(nullptr) - , listen_port_(0U) - , subscription_expiration_interval_(0) - , heartbeat_interval_(0) - , max_elements_(0U) - , max_latency_(0) - , connection_retry_interval_(0) - , connection_retry_count_(0U) { -} - -SourceInitiatedSubscriptionListener::Handler::Handler(SourceInitiatedSubscriptionListener& processor) - : processor_(processor) { -} - -SourceInitiatedSubscriptionListener::SubscriberData::SubscriberData() - : bookmark_(nullptr) - , subscription_(nullptr) { -} - -SourceInitiatedSubscriptionListener::SubscriberData::~SubscriberData() { - clearSubscription(); - clearBookmark(); -} - -void SourceInitiatedSubscriptionListener::SubscriberData::setSubscription(const std::string& subscription_version, - WsXmlDocH subscription, - const std::string& subscription_endpoint, - const std::string& subscription_identifier) { - clearSubscription(); - subscription_version_ = subscription_version; - subscription_ = subscription; - subscription_endpoint_ = subscription_endpoint; - subscription_identifier_ = subscription_identifier; -} - -void SourceInitiatedSubscriptionListener::SubscriberData::clearSubscription() { - subscription_version_.clear(); - if (subscription_ != nullptr) { - ws_xml_destroy_doc(subscription_); - } - subscription_ = nullptr; -} - -void SourceInitiatedSubscriptionListener::SubscriberData::setBookmark(WsXmlDocH bookmark) { - clearBookmark(); - bookmark_ = bookmark; -} - -void SourceInitiatedSubscriptionListener::SubscriberData::clearBookmark() { - if (bookmark_ != nullptr) { - ws_xml_destroy_doc(bookmark_); - } - bookmark_ = nullptr; -} - -bool SourceInitiatedSubscriptionListener::persistState() const { - std::unordered_map<std::string, std::string> state_map; - size_t i = 0U; - for (const auto& subscriber : subscribers_) { - char* xml_buf = nullptr; - auto clean_up_xml_buf = gsl::finally([&]{ - ws_xml_free_memory(xml_buf); - }); - int xml_buf_size = 0; - ws_xml_dump_memory_enc(subscriber.second.bookmark_, &xml_buf, &xml_buf_size, "UTF-8"); - state_map.emplace("subscriber." + std::to_string(i) + ".machineid", subscriber.first); - state_map.emplace("subscriber." + std::to_string(i) + ".bookmark", std::string(xml_buf, xml_buf_size)); - i++; - } - return state_manager_->set(state_map); -} - -bool SourceInitiatedSubscriptionListener::loadState() { - std::unordered_map<std::string, std::string> state_map; - if (!state_manager_->get(state_map)) { - return false; - } - - for (size_t i = 0U;; i++) { - std::string machineId; - try { - machineId = state_map.at("subscriber." + std::to_string(i) + ".machineid"); - } catch (...) { - break; - } - - std::string bookmark; - try { - bookmark = state_map.at("subscriber." + std::to_string(i) + ".bookmark"); - } catch (...) { - logger_->log_error("Bookmark for subscriber \"{}\" is missing, skipping", machineId); - continue; - } - - WsXmlDocH doc = ws_xml_read_memory(bookmark.data(), bookmark.size(), "UTF-8", 0); - if (doc == nullptr) { - logger_->log_error("Failed to parse saved bookmark for subscriber \"{}\", skipping", machineId); - continue; - } - subscribers_[machineId].setBookmark(doc); - } - - return true; -} - -std::string SourceInitiatedSubscriptionListener::Handler::millisecondsToXsdDuration(std::chrono::milliseconds milliseconds) { - std::array<char, 1024> buf{}; - (void)snprintf(buf.data(), buf.size(), "PT%" PRId64 ".%03" PRId64 "S", int64_t{milliseconds.count() / 1000}, int64_t{milliseconds.count() % 1000}); - return buf.data(); -} - -bool SourceInitiatedSubscriptionListener::Handler::handlePost(CivetServer* /*server*/, struct mg_connection* conn) { - const struct mg_request_info* req_info = mg_get_request_info(conn); - if (req_info == nullptr) { - processor_.logger_->log_error("Failed to get request info"); - return false; - } - - const char* endpoint = req_info->local_uri; - if (endpoint == nullptr) { - processor_.logger_->log_error("Failed to get called endpoint (local_uri)"); - return false; - } - processor_.logger_->log_trace("Endpoint \"{}\" has been called", endpoint); - - for (int i = 0; i < req_info->num_headers; i++) { - processor_.logger_->log_trace("Received header \"{}: {}\"", req_info->http_headers[i].name, req_info->http_headers[i].value); - } - - const char* content_type = mg_get_header(conn, "Content-Type"); - if (content_type == nullptr) { - processor_.logger_->log_error("Content-Type header missing"); - return false; - } - - std::string charset; - const char* charset_begin = strstr(content_type, "charset="); - if (charset_begin == nullptr) { - processor_.logger_->log_warn("charset missing from Content-Type header, assuming UTF-8"); - charset = "UTF-8"; - } else { - charset_begin += strlen("charset="); - const char* charset_end = strchr(charset_begin, ';'); - if (charset_end == nullptr) { - charset = std::string(charset_begin); - } else { - charset = std::string(charset_begin, charset_end - charset_begin); - } - } - processor_.logger_->log_trace("charset is \"{}\"", charset.c_str()); - - std::vector<uint8_t> raw_data; - { - std::array<uint8_t, 16384U> buf{}; - int read_bytes = 0; - while ((read_bytes = mg_read(conn, buf.data(), buf.size())) > 0) { - size_t orig_size = raw_data.size(); - raw_data.resize(orig_size + read_bytes); - memcpy(raw_data.data() + orig_size, buf.data(), read_bytes); - } - } - - if (raw_data.empty()) { - processor_.logger_->log_error("POST body is empty"); - return false; - } - - WsXmlDocH doc = ws_xml_read_memory(reinterpret_cast<char*>(raw_data.data()), raw_data.size(), charset.c_str(), 0); - - if (doc == nullptr) { - processor_.logger_->log_error("Failed to parse POST body as XML"); - return false; - } - - { - WsXmlNodeH node = ws_xml_get_doc_root(doc); - char* xml_buf = nullptr; - auto clean_up_xml_buf = gsl::finally([&]{ - ws_xml_free_memory(xml_buf); - }); - int xml_buf_size = 0; - ws_xml_dump_memory_node_tree_enc(node, &xml_buf, &xml_buf_size, "UTF-8"); - if (xml_buf != nullptr) { - processor_.logger_->log_trace("Received request: \"{}\"", std::string_view(xml_buf, xml_buf_size)); - } - } - - if (endpoint == processor_.subscription_manager_path_) { - return this->handleSubscriptionManager(conn, endpoint, doc); - } else if (strncmp(endpoint, processor_.subscriptions_base_path_.c_str(), processor_.subscriptions_base_path_.length()) == 0) { - return this->handleSubscriptions(conn, endpoint, doc); - } else { - ws_xml_destroy_doc(doc); - return false; - } -} - -std::string SourceInitiatedSubscriptionListener::Handler::getSoapAction(WsXmlDocH doc) { - WsXmlNodeH header = ws_xml_get_soap_header(doc); - if (header == nullptr) { - return ""; - } - WsXmlNodeH action_node = ws_xml_get_child(header, 0 /*index*/, XML_NS_ADDRESSING, WSA_ACTION); - if (action_node == nullptr) { - return ""; - } - char* text = ws_xml_get_node_text(action_node); - if (text == nullptr) { - return ""; - } - - return text; -} - -std::string SourceInitiatedSubscriptionListener::Handler::getMachineId(WsXmlDocH doc) { - WsXmlNodeH header = ws_xml_get_soap_header(doc); - if (header == nullptr) { - return ""; - } - WsXmlNodeH machineid_node = ws_xml_get_child(header, 0 /*index*/, XML_NS_CUSTOM_MACHINEID, "MachineID"); - if (machineid_node == nullptr) { - return ""; - } - char* text = ws_xml_get_node_text(machineid_node); - if (text == nullptr) { - return ""; - } - - return text; -} - -bool SourceInitiatedSubscriptionListener::Handler::isAckRequested(WsXmlDocH doc) { - WsXmlNodeH header = ws_xml_get_soap_header(doc); - if (header == nullptr) { - return false; - } - WsXmlNodeH ack_requested_node = ws_xml_get_child(header, 0 /*index*/, XML_NS_WS_MAN, WSM_ACKREQUESTED); - return ack_requested_node != nullptr; -} - -void SourceInitiatedSubscriptionListener::Handler::sendResponse(struct mg_connection* conn, const std::string& machineId, const std::string& remoteIp, char* xml_buf, size_t xml_buf_size) { - processor_.logger_->log_trace("Sending response to {} ({}) \"{}\"", machineId, remoteIp, std::string_view(xml_buf, xml_buf_size)); - mg_printf(conn, "HTTP/1.1 200 OK\r\n"); - mg_printf(conn, "Content-Type: application/soap+xml;charset=UTF-8\r\n"); - mg_printf(conn, "Authorization: %s\r\n", WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL); - mg_printf(conn, "Content-Length: %zu\r\n", xml_buf_size); - mg_printf(conn, "\r\n"); - mg_printf(conn, "%.*s", static_cast<int>(xml_buf_size), xml_buf); -} - -bool SourceInitiatedSubscriptionListener::Handler::handleSubscriptionManager(struct mg_connection* conn, const std::string& endpoint, WsXmlDocH request) { - const auto request_guard = gsl::finally([&]() { - ws_xml_destroy_doc(request); - }); - - auto action = getSoapAction(request); - auto machine_id = getMachineId(request); - const struct mg_request_info* req_info = mg_get_request_info(conn); - std::string remote_ip = req_info->remote_addr; - if (action != ENUM_ACTION_ENUMERATE) { - processor_.logger_->log_error("{} called by {} ({}) with unknown Action \"{}\"", endpoint.c_str(), machine_id.c_str(), remote_ip.c_str(), action.c_str()); - return false; // TODO(bakaid): generate fault if possible - } - - // Create reponse envelope from request - WsXmlDocH response = wsman_create_response_envelope(request, nullptr); - const auto response_guard = gsl::finally([&]() { - ws_xml_destroy_doc(response); - }); - - // Header - WsXmlNodeH response_header = ws_xml_get_soap_header(response); - // Header/MessageID - utils::Identifier msg_id = utils::IdGenerator::getIdGenerator()->generate(); - ws_xml_add_child_format(response_header, XML_NS_ADDRESSING, WSA_MESSAGE_ID, "uuid:%s", msg_id.to_string().c_str()); - - // Body - WsXmlNodeH response_body = ws_xml_get_soap_body(response); - // Body/EnumerationResponse - WsXmlNodeH enumeration_response = ws_xml_add_child(response_body, XML_NS_ENUMERATION, WSENUM_ENUMERATE_RESP, nullptr); - // Body/EnumerationResponse/EnumerationContext - ws_xml_add_child(enumeration_response, XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT, nullptr); - // Body/EnumerationResponse/Items - WsXmlNodeH enumeration_items = ws_xml_add_child(enumeration_response, XML_NS_WS_MAN, WSENUM_ITEMS, nullptr); - // Body/EnumerationResponse/EndOfSequence - ws_xml_add_child(enumeration_response, XML_NS_WS_MAN, WSENUM_END_OF_SEQUENCE, nullptr); - - // Body/EnumerationResponse/Items/Subscription - WsXmlNodeH subscription = ws_xml_add_child(enumeration_items, nullptr, "Subscription", nullptr); - ws_xml_set_ns(subscription, XML_NS_CUSTOM_SUBSCRIPTION, "m"); - - // Body/EnumerationResponse/Items/Subscription/Version - std::lock_guard<std::mutex> lock(processor_.mutex_); - auto it = processor_.subscribers_.find(machine_id); - - std::string subscription_version; - if (it != processor_.subscribers_.end() && it->second.subscription_ != nullptr) { - subscription_version = it->second.subscription_version_; - } else { - utils::Identifier id = utils::IdGenerator::getIdGenerator()->generate(); - subscription_version = id.to_string(); - } - ws_xml_add_child_format(subscription, XML_NS_CUSTOM_SUBSCRIPTION, "Version", "uuid:%s", subscription_version.c_str()); - - // Body/EnumerationResponse/Items/Subscription/Envelope - std::string subscription_identifier; - std::string subscription_endpoint; - if (it != processor_.subscribers_.end() && it->second.subscription_ != nullptr) { - WsXmlNodeH subscription_node = ws_xml_get_doc_root(it->second.subscription_); - ws_xml_copy_node(subscription_node, subscription); - } else { - WsXmlDocH subscription_doc = ws_xml_create_envelope(); - - // Header - WsXmlNodeH header = ws_xml_get_soap_header(subscription_doc); - WsXmlNodeH node = nullptr; - - // Header/Action - node = ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_ACTION, EVT_ACTION_SUBSCRIBE); - ws_xml_add_node_attr(node, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND, "true"); - - // Header/MessageID - utils::Identifier msg_id = utils::IdGenerator::getIdGenerator()->generate(); - ws_xml_add_child_format(header, XML_NS_ADDRESSING, WSA_MESSAGE_ID, "uuid:%s", msg_id.to_string().c_str()); - - // Header/To - node = ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_TO, WSA_TO_ANONYMOUS); - ws_xml_add_node_attr(node, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND, "true"); - - // Header/ResourceURI - node = ws_xml_add_child(header, XML_NS_WS_MAN, WSM_RESOURCE_URI, "http://schemas.microsoft.com/wbem/wsman/1/windows/EventLog"); - ws_xml_add_node_attr(node, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND, "true"); - - // Header/ReplyTo - node = ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_REPLY_TO, nullptr); - node = ws_xml_add_child(node, XML_NS_ADDRESSING, WSA_ADDRESS, WSA_TO_ANONYMOUS); - ws_xml_add_node_attr(node, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND, "true"); - - // Header/OptionSet - WsXmlNodeH option_set = ws_xml_add_child(header, XML_NS_WS_MAN, WSM_OPTION_SET, nullptr); - ws_xml_ns_add(option_set, XML_NS_SCHEMA_INSTANCE, XML_NS_SCHEMA_INSTANCE_PREFIX); - - // Header/OptionSet/Option (CDATA) - node = ws_xml_add_child(option_set, XML_NS_WS_MAN, WSM_OPTION, nullptr); - ws_xml_add_node_attr(node, nullptr, WSM_NAME, "CDATA"); - ws_xml_add_node_attr(node, XML_NS_SCHEMA_INSTANCE, XML_SCHEMA_NIL, "true"); - - // Header/OptionSet/Option (IgnoreChannelError) - node = ws_xml_add_child(option_set, XML_NS_WS_MAN, WSM_OPTION, nullptr); - ws_xml_add_node_attr(node, nullptr, WSM_NAME, "IgnoreChannelError"); - ws_xml_add_node_attr(node, XML_NS_SCHEMA_INSTANCE, XML_SCHEMA_NIL, "true"); - - // Body - WsXmlNodeH body = ws_xml_get_soap_body(subscription_doc); - WsXmlNodeH subscribe_node = ws_xml_add_child(body, XML_NS_EVENTING, WSEVENT_SUBSCRIBE, nullptr); - - // Body/Delivery - { - utils::Identifier id = utils::IdGenerator::getIdGenerator()->generate(); - subscription_identifier = id.to_string(); - } - { - utils::Identifier id = utils::IdGenerator::getIdGenerator()->generate(); - subscription_endpoint = processor_.subscriptions_base_path_ + "/" + id.to_string(); - } - - WsXmlNodeH delivery_node = ws_xml_add_child(subscribe_node, XML_NS_EVENTING, WSEVENT_DELIVERY, nullptr); - ws_xml_add_node_attr(delivery_node, nullptr, WSEVENT_DELIVERY_MODE, WSEVENT_DELIVERY_MODE_EVENTS); - - // Body/Delivery/Heartbeats - ws_xml_add_child(delivery_node, XML_NS_WS_MAN, WSM_HEARTBEATS, millisecondsToXsdDuration(processor_.heartbeat_interval_).c_str()); - - // Body/Delivery/ConnectionRetry - auto connection_retry_node = ws_xml_add_child(delivery_node, XML_NS_WS_MAN, WSM_CONNECTIONRETRY, millisecondsToXsdDuration(processor_.connection_retry_interval_).c_str()); - ws_xml_add_node_attr(connection_retry_node, nullptr, "Total", std::to_string(processor_.connection_retry_count_).c_str()); - - // Body/Delivery/NotifyTo and Body/EndTo are the same, so we will use this lambda to recreate the same tree - auto apply_endpoint_nodes = [&](WsXmlNodeH target_node) { - // ${target_node}/NotifyTo/Address - ws_xml_add_child_format(target_node, XML_NS_ADDRESSING, WSA_ADDRESS, "https://%s:%hu%s", - processor_.listen_hostname_.c_str(), - processor_.listen_port_, - subscription_endpoint.c_str()); - // ${target_node}/ReferenceProperties - node = ws_xml_add_child(target_node, XML_NS_ADDRESSING, WSA_REFERENCE_PROPERTIES, nullptr); - // ${target_node}/ReferenceProperties/Identifier - ws_xml_add_child_format(node, XML_NS_EVENTING, WSEVENT_IDENTIFIER, "%s", subscription_identifier.c_str()); - // ${target_node}/Policy - WsXmlNodeH policy = ws_xml_add_child(target_node, nullptr, "Policy", nullptr); - ws_xml_set_ns(policy, XML_NS_CUSTOM_POLICY, "c"); - ws_xml_ns_add(policy, XML_NS_CUSTOM_AUTHENTICATION, "auth"); - // ${target_node}/Policy/ExactlyOne - WsXmlNodeH exactly_one = ws_xml_add_child(policy, XML_NS_CUSTOM_POLICY, "ExactlyOne", nullptr); - // ${target_node}/Policy/ExactlyOne/All - WsXmlNodeH all = ws_xml_add_child(exactly_one, XML_NS_CUSTOM_POLICY, "All", nullptr); - // ${target_node}/Policy/ExactlyOne/All/Authentication - WsXmlNodeH authentication = ws_xml_add_child(all, XML_NS_CUSTOM_AUTHENTICATION, "Authentication", nullptr); - ws_xml_add_node_attr(authentication, nullptr, "Profile", WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL); - // ${target_node}/Policy/ExactlyOne/All/Authentication/ClientCertificate - WsXmlNodeH client_certificate = ws_xml_add_child(authentication, XML_NS_CUSTOM_AUTHENTICATION, "ClientCertificate", nullptr); - // ${target_node}/Policy/ExactlyOne/All/Authentication/ClientCertificate/Thumbprint - WsXmlNodeH thumbprint = ws_xml_add_child_format(client_certificate, XML_NS_CUSTOM_AUTHENTICATION, "Thumbprint", "%s", processor_.ssl_ca_cert_thumbprint_.c_str()); - ws_xml_add_node_attr(thumbprint, nullptr, "Role", "issuer"); - }; - - // Body/Delivery/NotifyTo - WsXmlNodeH notifyto_node = ws_xml_add_child(delivery_node, XML_NS_EVENTING, WSEVENT_NOTIFY_TO, nullptr); - apply_endpoint_nodes(notifyto_node); - - // Body/EndTo - WsXmlNodeH endto_node = ws_xml_add_child(subscribe_node, XML_NS_EVENTING, WSEVENT_ENDTO, nullptr); - apply_endpoint_nodes(endto_node); - - // Body/MaxElements - ws_xml_add_child(delivery_node, XML_NS_WS_MAN, WSM_MAX_ELEMENTS, std::to_string(processor_.max_elements_).c_str()); - // Body/MaxTime - ws_xml_add_child(delivery_node, XML_NS_WS_MAN, WSENUM_MAX_TIME, millisecondsToXsdDuration(processor_.max_latency_).c_str()); - - // Body/Expires - ws_xml_add_child(subscribe_node, XML_NS_EVENTING, WSEVENT_EXPIRES, millisecondsToXsdDuration(processor_.subscription_expiration_interval_).c_str()); - - // Body/Filter - ws_xml_add_child(subscribe_node, XML_NS_WS_MAN, WSM_FILTER, processor_.xpath_xml_query_.c_str()); - // ws_xml_add_node_attr(filter_node, nullptr, "Dialect", "http://schemas.microsoft.com/win/2004/08/events/eventquery"); - - // Body/Bookmark - if (it != processor_.subscribers_.end() && it->second.bookmark_ != nullptr) { - WsXmlNodeH bookmark_node = ws_xml_get_doc_root(it->second.bookmark_); - ws_xml_copy_node(bookmark_node, subscribe_node); - } else if (processor_.initial_existing_events_strategy_ == INITIAL_EXISTING_EVENTS_STRATEGY_ALL) { - ws_xml_add_child(subscribe_node, XML_NS_WS_MAN, WSM_BOOKMARK, "http://schemas.dmtf.org/wbem/wsman/1/wsman/bookmark/earliest"); - } - - // Body/SendBookmarks - ws_xml_add_child(subscribe_node, XML_NS_WS_MAN, WSM_SENDBOOKMARKS, nullptr); - - // Copy the whole Subscription - WsXmlNodeH subscription_node = ws_xml_get_doc_root(subscription_doc); - ws_xml_copy_node(subscription_node, subscription); - - // Save subscription - if (it == processor_.subscribers_.end()) { - it = processor_.subscribers_.emplace(machine_id, SubscriberData()).first; - } - it->second.setSubscription(subscription_version, subscription_doc, subscription_endpoint, subscription_identifier); - } - - // Send response - char* xml_buf = nullptr; - auto clean_up_xml_buf = gsl::finally([&]{ - ws_xml_free_memory(xml_buf); - }); - int xml_buf_size = 0; - ws_xml_dump_memory_enc(response, &xml_buf, &xml_buf_size, "UTF-8"); - sendResponse(conn, machine_id, req_info->remote_addr, xml_buf, xml_buf_size); - - return true; -} - -int SourceInitiatedSubscriptionListener::Handler::enumerateEventCallback(WsXmlNodeH node, void* data) { - if (data == nullptr) { - return 1; - } - - std::shared_ptr<core::ProcessSession> session; - std::shared_ptr<core::logging::Logger> logger; - std::string machine_id; - std::string remote_ip; - std::tie(session, logger, machine_id, remote_ip) = *static_cast<std::tuple<std::shared_ptr<core::ProcessSession>, std::shared_ptr<core::logging::Logger>, std::string, std::string>*>(data); - - char* text = ws_xml_get_node_text(node); - if (text == nullptr) { - logger->log_error("Failed to get text for node"); - return 1; - } - - try { - logger->log_trace("Found Event"); - auto flow_file = session->create(); - if (flow_file == nullptr) { - logger->log_error("Failed to create FlowFile"); - return 1; - } - - session->writeBuffer(flow_file, std::string_view{text}); - - session->putAttribute(*flow_file, core::SpecialFlowAttribute::MIME_TYPE, "application/xml"); - flow_file->addAttribute(ATTRIBUTE_WEF_REMOTE_MACHINEID, machine_id); - flow_file->addAttribute(ATTRIBUTE_WEF_REMOTE_IP, remote_ip); - - session->transfer(flow_file, SourceInitiatedSubscriptionListener::Success); - } catch (const std::exception& e) { - logger->log_error("Caught exception while processing Events: {}", e.what()); - return 1; - } catch (...) { - logger->log_error("Caught exception while processing Events"); - return 1; - } - - return 0; -} - -bool SourceInitiatedSubscriptionListener::Handler::handleSubscriptions(struct mg_connection* conn, const std::string& endpoint, WsXmlDocH request) { - const auto guard = gsl::finally([&]() { - ws_xml_destroy_doc(request); - }); - auto action = getSoapAction(request); - auto machine_id = getMachineId(request); - const struct mg_request_info* req_info = mg_get_request_info(conn); - std::string remote_ip = req_info->remote_addr; - if (action == EVT_ACTION_SUBEND) { - std::lock_guard<std::mutex> lock(processor_.mutex_); - auto it = processor_.subscribers_.find(machine_id); - if (it != processor_.subscribers_.end()) { - processor_.subscribers_.erase(it); - } - // TODO(bakaid): make sure whether we really have to clean the bookmark as well (based on the fault) - } else if (action == WSMAN_CUSTOM_ACTION_HEARTBEAT) { - processor_.logger_->log_debug("Received Heartbeat on {} from {} ({})", endpoint.c_str(), machine_id.c_str(), remote_ip.c_str()); - } else if (action == WSMAN_CUSTOM_ACTION_EVENTS) { - processor_.logger_->log_debug("Received Events on {} from {} ({})", endpoint.c_str(), machine_id.c_str(), remote_ip.c_str()); - // Body - WsXmlNodeH body = ws_xml_get_soap_body(request); - if (body == nullptr) { - processor_.logger_->log_error("Received malformed Events request on {} from {} ({}), SOAP Body missing", endpoint.c_str(), machine_id.c_str(), remote_ip.c_str()); - return false; - } - // Body/Events - WsXmlNodeH events_node = ws_xml_get_child(body, 0 /*index*/, XML_NS_WS_MAN, WSM_EVENTS); - if (events_node == nullptr) { - processor_.logger_->log_error("Received malformed Events request on {} from {} ({}), Events missing", endpoint.c_str(), machine_id.c_str(), remote_ip.c_str()); - return false; - } - // Enumare Body/Events/Event nodes - auto session = processor_.session_factory_->createSession(); - std::tuple<std::shared_ptr<core::ProcessSession>, std::shared_ptr<core::logging::Logger>, std::string, std::string> callback_args = - std::forward_as_tuple(session, processor_.logger_, machine_id, remote_ip); - int ret = ws_xml_enum_children(events_node, &SourceInitiatedSubscriptionListener::Handler::enumerateEventCallback, &callback_args, 0 /*bRecursive*/); - if (ret != 0) { - processor_.logger_->log_error("Failed to parse events on {} from {} ({}), rolling back session", endpoint.c_str(), machine_id.c_str(), remote_ip.c_str()); - session->rollback(); - } - // Header - WsXmlNodeH header = ws_xml_get_soap_header(request); - // Header/Bookmark - WsXmlNodeH bookmark_node = ws_xml_get_child(header, 0 /*index*/, XML_NS_WS_MAN, WSM_BOOKMARK); - if (ret == 0 && bookmark_node != nullptr) { - WsXmlDocH bookmark_doc = ws_xml_create_doc(XML_NS_WS_MAN, WSM_BOOKMARK); - WsXmlNodeH temp = ws_xml_get_doc_root(bookmark_doc); - ws_xml_duplicate_children(temp, bookmark_node); - - std::lock_guard<std::mutex> lock(processor_.mutex_); - auto it = processor_.subscribers_.find(machine_id); - if (it != processor_.subscribers_.end()) { - it = processor_.subscribers_.emplace(machine_id, SubscriberData()).first; - } - it->second.setBookmark(bookmark_doc); - // Bookmark changed, invalidate stored subscription - it->second.clearSubscription(); - - // Persist state - processor_.persistState(); - - char* xml_buf = nullptr; - auto clean_up_xml_buf = gsl::finally([&]{ - ws_xml_free_memory(xml_buf); - }); - int xml_buf_size = 0; - ws_xml_dump_memory_enc(bookmark_doc, &xml_buf, &xml_buf_size, "UTF-8"); - processor_.logger_->log_debug("Saved new bookmark for {}: \"{:.{}}\"", machine_id.c_str(), xml_buf, xml_buf_size); - } - } else { - processor_.logger_->log_error("{} called by {} ({}) with unknown Action \"{}\"", endpoint.c_str(), machine_id.c_str(), remote_ip.c_str(), action.c_str()); - return false; // TODO(bakaid): generate fault if possible - } - - if (isAckRequested(request)) { - // Assemble ACK - WsXmlDocH ack = wsman_create_response_envelope(request, WSMAN_CUSTOM_ACTION_ACK); - // Header - WsXmlNodeH ack_header = ws_xml_get_soap_header(ack); - - // Header/MessageID - utils::Identifier msg_id = utils::IdGenerator::getIdGenerator()->generate(); - ws_xml_add_child_format(ack_header, XML_NS_ADDRESSING, WSA_MESSAGE_ID, "uuid:%s", msg_id.to_string().c_str()); - - // Send ACK - char* xml_buf = nullptr; - auto clean_up_xml_buf = gsl::finally([&]{ - ws_xml_free_memory(xml_buf); - }); - int xml_buf_size = 0; - ws_xml_dump_memory_enc(ack, &xml_buf, &xml_buf_size, "UTF-8"); - - sendResponse(conn, machine_id, remote_ip, xml_buf, xml_buf_size); - - ws_xml_destroy_doc(ack); - } - - return true; -} - -void SourceInitiatedSubscriptionListener::onTrigger(core::ProcessContext&, core::ProcessSession&) { - logger_->log_trace("SourceInitiatedSubscriptionListener onTrigger called"); -} - -void SourceInitiatedSubscriptionListener::initialize() { - logger_->log_trace("Initializing SourceInitiatedSubscriptionListener"); - - setSupportedProperties(Properties); - setSupportedRelationships(Relationships); -} - -void SourceInitiatedSubscriptionListener::onScheduleSharedPtr(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::ProcessSessionFactory> &sessionFactory) { - std::string ssl_certificate_file; - std::string ssl_ca_file; - - state_manager_ = context->getStateManager(); - if (state_manager_ == nullptr) { - throw Exception(PROCESSOR_EXCEPTION, "Failed to get StateManager"); - } - - std::string value; - context->getProperty(ListenHostname, listen_hostname_); - if (!context->getProperty(ListenPort, value)) { - throw Exception(PROCESSOR_EXCEPTION, "Listen Port attribute is missing or invalid"); - } else { - core::Property::StringToInt(value, listen_port_); - } - context->getProperty(SubscriptionManagerPath, subscription_manager_path_); - context->getProperty(SubscriptionsBasePath, subscriptions_base_path_); - if (!context->getProperty(SSLCertificate, ssl_certificate_file)) { - throw Exception(PROCESSOR_EXCEPTION, "SSL Certificate attribute is missing"); - } - if (!context->getProperty(SSLCertificateAuthority, ssl_ca_file)) { - throw Exception(PROCESSOR_EXCEPTION, "SSL Certificate Authority attribute is missing"); - } - if (!context->getProperty(SSLVerifyPeer, value)) { - throw Exception(PROCESSOR_EXCEPTION, "SSL Verify Peer attribute is missing"); - } - bool verify_peer = utils::string::toBool(value).value_or(true); - context->getProperty(XPathXmlQuery, xpath_xml_query_); - if (!context->getProperty(InitialExistingEventsStrategy, initial_existing_events_strategy_)) { - throw Exception(PROCESSOR_EXCEPTION, "Initial Existing Events Strategy attribute is missing or invalid"); - } - if (auto subscription_expiration_interval = context->getProperty<core::TimePeriodValue>(SubscriptionExpirationInterval)) { - subscription_expiration_interval_ = subscription_expiration_interval->getMilliseconds(); - } else { - throw Exception(PROCESSOR_EXCEPTION, "Subscription Expiration Interval attribute is missing or invalid"); - } - if (auto heartbeat_interval = context->getProperty<core::TimePeriodValue>(HeartbeatInterval)) { - heartbeat_interval_ = heartbeat_interval->getMilliseconds(); - } else { - throw Exception(PROCESSOR_EXCEPTION, "Heartbeat Interval attribute is missing or invalid"); - } - if (!context->getProperty(MaxElements, value)) { - throw Exception(PROCESSOR_EXCEPTION, "Max Elements attribute is missing or invalid"); - } else if (!core::Property::StringToInt(value, max_elements_)) { - throw Exception(PROCESSOR_EXCEPTION, "Max Elements attribute is invalid"); - } - if (auto max_latency = context->getProperty<core::TimePeriodValue>(MaxLatency)) { - max_latency_ = max_latency->getMilliseconds(); - } else { - throw Exception(PROCESSOR_EXCEPTION, "Max Latency attribute is missing or invalid"); - } - if (auto connection_retry_interval = context->getProperty<core::TimePeriodValue>(ConnectionRetryInterval)) { - connection_retry_interval_ = connection_retry_interval->getMilliseconds(); - } else { - throw Exception(PROCESSOR_EXCEPTION, "Connection Retry Interval attribute is missing or invalid"); - } - if (!context->getProperty(ConnectionRetryCount, value)) { - throw Exception(PROCESSOR_EXCEPTION, "Connection Retry Count attribute is missing or invalid"); - } else if (!core::Property::StringToInt(value, connection_retry_count_)) { - throw Exception(PROCESSOR_EXCEPTION, "Connection Retry Count attribute is invalid"); - } - - gsl::owner<FILE*> fp = fopen(ssl_ca_file.c_str(), "rb"); - if (fp == nullptr) { - throw Exception(PROCESSOR_EXCEPTION, "Failed to open file specified by SSL Certificate Authority attribute"); - } - X509* ca = nullptr; - PEM_read_X509(fp, &ca, nullptr, nullptr); - (void)fclose(fp); - if (ca == nullptr) { - throw Exception(PROCESSOR_EXCEPTION, "Failed to parse file specified by SSL Certificate Authority attribute"); - } - utils::tls::X509_unique_ptr ca_ptr{ca}; - - std::array<std::byte, 20U> hash_buf{}; - int ret = X509_digest(ca, EVP_sha1(), gsl::make_span(hash_buf).as_span<unsigned char>().data(), nullptr); - if (ret != 1) { - throw Exception(PROCESSOR_EXCEPTION, "Failed to get fingerprint for CA specified by SSL Certificate Authority attribute"); - } - ssl_ca_cert_thumbprint_ = utils::string::to_hex(hash_buf, true /*uppercase*/); - logger_->log_debug("{} SHA-1 thumbprint is {}", ssl_ca_file.c_str(), ssl_ca_cert_thumbprint_.c_str()); - - session_factory_ = sessionFactory; - - // Load state - loadState(); - - // Start server - std::vector<std::string> options; - options.emplace_back("enable_keep_alive"); - options.emplace_back("yes"); - options.emplace_back("keep_alive_timeout_ms"); - options.emplace_back("15000"); - options.emplace_back("num_threads"); - options.emplace_back("1"); - options.emplace_back("listening_ports"); - options.emplace_back(std::to_string(listen_port_) + "s"); - options.emplace_back("ssl_certificate"); - options.emplace_back(ssl_certificate_file); - options.emplace_back("ssl_ca_file"); - options.emplace_back(ssl_ca_file); - options.emplace_back("ssl_verify_peer"); - options.emplace_back(verify_peer ? "yes" : "no"); - - try { - server_ = std::make_unique<CivetServer>(options); - } catch (const std::exception& e) { - throw Exception(PROCESSOR_EXCEPTION, std::string("Failed to initialize server, error: ") + e.what()); - } catch (...) { - throw Exception(PROCESSOR_EXCEPTION, "Failed to initialize server"); - } - handler_ = std::make_unique<Handler>(*this); - server_->addHandler("**", *handler_); -} - -void SourceInitiatedSubscriptionListener::notifyStop() { - server_.reset(); -} - -REGISTER_RESOURCE(SourceInitiatedSubscriptionListener, Processor); - -} // namespace org::apache::nifi::minifi::processors diff --git a/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.h b/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.h deleted file mode 100644 index 4f3cec4f0..000000000 --- a/extensions/openwsman/processors/SourceInitiatedSubscriptionListener.h +++ /dev/null @@ -1,255 +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. - */ -#pragma once - -#include <memory> -#include <string> -#include <list> -#include <map> -#include <mutex> -#include <thread> - -#include <CivetServer.h> -extern "C" { -#include "wsman-xml.h" -} - -#include "utils/ByteArrayCallback.h" -#include "FlowFileRecord.h" -#include "core/Processor.h" -#include "core/ProcessSession.h" -#include "core/Core.h" -#include "core/PropertyDefinition.h" -#include "core/PropertyDefinitionBuilder.h" -#include "core/PropertyType.h" -#include "core/RelationshipDefinition.h" -#include "controllers/SSLContextService.h" -#include "core/logging/LoggerConfiguration.h" -#include "utils/Id.h" - -namespace org::apache::nifi::minifi::processors { - -class SourceInitiatedSubscriptionListener : public core::Processor { - public: - static constexpr char const *INITIAL_EXISTING_EVENTS_STRATEGY_NONE = "None"; - static constexpr char const *INITIAL_EXISTING_EVENTS_STRATEGY_ALL = "All"; - - explicit SourceInitiatedSubscriptionListener(std::string_view name, const utils::Identifier& uuid = {}); - - EXTENSIONAPI static constexpr const char* Description = "This processor implements a Windows Event Forwarding Source Initiated Subscription server with the help of OpenWSMAN. " - "Windows hosts can be set up to connect and forward Event Logs to this processor."; - - EXTENSIONAPI static constexpr auto ListenHostname = core::PropertyDefinitionBuilder<>::createProperty("Listen Hostname") - .withDescription("The hostname or IP of this machine that will be advertised to event sources to connect to. " - "It must be contained as a Subject Alternative Name in the server certificate, " - "otherwise source machines will refuse to connect.") - .isRequired(true) - .build(); - EXTENSIONAPI static constexpr auto ListenPort = core::PropertyDefinitionBuilder<>::createProperty("Listen Port") - .withDescription("The port to listen on.") - .isRequired(true) - .withPropertyType(core::StandardPropertyTypes::LISTEN_PORT_TYPE) - .withDefaultValue("5986") - .build(); - EXTENSIONAPI static constexpr auto SubscriptionManagerPath = core::PropertyDefinitionBuilder<>::createProperty("Subscription Manager Path") - .withDescription("The URI path that will be used for the WEC Subscription Manager endpoint.") - .isRequired(true) - .withDefaultValue("/wsman/SubscriptionManager/WEC") - .build(); - EXTENSIONAPI static constexpr auto SubscriptionsBasePath = core::PropertyDefinitionBuilder<>::createProperty("Subscriptions Base Path") - .withDescription("The URI path that will be used as the base for endpoints serving individual subscriptions.") - .isRequired(true) - .withDefaultValue("/wsman/subscriptions") - .build(); - EXTENSIONAPI static constexpr auto SSLCertificate = core::PropertyDefinitionBuilder<>::createProperty("SSL Certificate") - .withDescription("File containing PEM-formatted file including TLS/SSL certificate and key. " - "The root CA of the certificate must be the CA set in SSL Certificate Authority.") - .isRequired(true) - .build(); - EXTENSIONAPI static constexpr auto SSLCertificateAuthority = core::PropertyDefinitionBuilder<>::createProperty("SSL Certificate Authority") - .withDescription("File containing the PEM-formatted CA that is the root CA for both this server's certificate and the event source clients' certificates.") - .isRequired(true) - .build(); - EXTENSIONAPI static constexpr auto SSLVerifyPeer = core::PropertyDefinitionBuilder<>::createProperty("SSL Verify Peer") - .withDescription("Whether or not to verify the client's certificate") - .isRequired(false) - .withPropertyType(core::StandardPropertyTypes::BOOLEAN_TYPE) - .withDefaultValue("true") - .build(); - EXTENSIONAPI static constexpr auto XPathXmlQuery = core::PropertyDefinitionBuilder<>::createProperty("XPath XML Query") - .withDescription("An XPath Query in structured XML format conforming to the Query Schema described in " - "https://docs.microsoft.com/en-gb/windows/win32/wes/queryschema-schema, " - "see an example here: https://docs.microsoft.com/en-gb/windows/win32/wes/consuming-events") - .isRequired(true) - .withDefaultValue("<QueryList>\n" - " <Query Id=\"0\">\n" - " <Select Path=\"Application\">*</Select>\n" - " </Query>\n" - "</QueryList>\n") - .build(); - EXTENSIONAPI static constexpr auto InitialExistingEventsStrategy = core::PropertyDefinitionBuilder<2>::createProperty("Initial Existing Events Strategy") - .withDescription("Defines the behaviour of the Processor when a new event source connects.\n" - "None: will not request existing events\n" - "All: will request all existing events matching the query") - .isRequired(true) - .withAllowedValues({INITIAL_EXISTING_EVENTS_STRATEGY_NONE, INITIAL_EXISTING_EVENTS_STRATEGY_ALL}) - .withDefaultValue(INITIAL_EXISTING_EVENTS_STRATEGY_NONE) - .build(); - EXTENSIONAPI static constexpr auto SubscriptionExpirationInterval = core::PropertyDefinitionBuilder<>::createProperty("Subscription Expiration Interval") - .withDescription("The interval while a subscription is valid without renewal. " - "Because in a source-initiated subscription, the collector can not cancel the subscription, " - "setting this too large could cause unnecessary load on the source machine. " - "Setting this too small causes frequent reenumeration and resubscription which is ineffective.") - .isRequired(true) - .withPropertyType(core::StandardPropertyTypes::TIME_PERIOD_TYPE) - .withDefaultValue("10 min") - .build(); - EXTENSIONAPI static constexpr auto HeartbeatInterval = core::PropertyDefinitionBuilder<>::createProperty("Heartbeat Interval") - .withDescription("The processor will ask the sources to send heartbeats with this interval.") - .isRequired(true) - .withPropertyType(core::StandardPropertyTypes::TIME_PERIOD_TYPE) - .withDefaultValue("30 sec") - .build(); - EXTENSIONAPI static constexpr auto MaxElements = core::PropertyDefinitionBuilder<>::createProperty("Max Elements") - .withDescription("The maximum number of events a source will batch together and send at once.") - .isRequired(true) - .withPropertyType(core::StandardPropertyTypes::UNSIGNED_INT_TYPE) - .withDefaultValue("20") - .build(); - EXTENSIONAPI static constexpr auto MaxLatency = core::PropertyDefinitionBuilder<>::createProperty("Max Latency") - .withDescription("The maximum time a source will wait to send new events.") - .isRequired(true) - .withPropertyType(core::StandardPropertyTypes::TIME_PERIOD_TYPE) - .withDefaultValue("10 sec") - .build(); - EXTENSIONAPI static constexpr auto ConnectionRetryInterval = core::PropertyDefinitionBuilder<>::createProperty("Connection Retry Interval") - .withDescription("The interval with which a source will try to reconnect to the server.") - .withPropertyType(core::StandardPropertyTypes::TIME_PERIOD_TYPE) - .withDefaultValue("10 sec") - .build(); - EXTENSIONAPI static constexpr auto ConnectionRetryCount = core::PropertyDefinitionBuilder<>::createProperty("Connection Retry Count") - .withDescription("The number of connection retries after which a source will consider the subscription expired.") - .withPropertyType(core::StandardPropertyTypes::UNSIGNED_INT_TYPE) - .withDefaultValue("5") - .build(); - EXTENSIONAPI static constexpr auto Properties = std::array<core::PropertyReference, 15>{ - ListenHostname, - ListenPort, - SubscriptionManagerPath, - SubscriptionsBasePath, - SSLCertificate, - SSLCertificateAuthority, - SSLVerifyPeer, - XPathXmlQuery, - InitialExistingEventsStrategy, - SubscriptionExpirationInterval, - HeartbeatInterval, - MaxElements, - MaxLatency, - ConnectionRetryInterval, - ConnectionRetryCount - }; - - - EXTENSIONAPI static constexpr auto Success = core::RelationshipDefinition{"success", "All Events are routed to success"}; - EXTENSIONAPI static constexpr auto Relationships = std::array{Success}; - - EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - EXTENSIONAPI static constexpr bool SupportsDynamicRelationships = false; - EXTENSIONAPI static constexpr core::annotation::Input InputRequirement = core::annotation::Input::INPUT_ALLOWED; - EXTENSIONAPI static constexpr bool IsSingleThreaded = true; - - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_PROCESSORS - - // Writes Attributes - static constexpr char const* ATTRIBUTE_WEF_REMOTE_MACHINEID = "wef.remote.machineid"; - static constexpr char const* ATTRIBUTE_WEF_REMOTE_IP = "wef.remote.ip"; - - void onTrigger(core::ProcessContext& context, core::ProcessSession& session) override; - void initialize() override; - void onScheduleSharedPtr(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::ProcessSessionFactory> &sessionFactory) override; - void notifyStop() override; - - class Handler: public CivetHandler { - public: - explicit Handler(SourceInitiatedSubscriptionListener& processor); - bool handlePost(CivetServer* server, struct mg_connection* conn) override; - - private: - SourceInitiatedSubscriptionListener& processor_; - - bool handleSubscriptionManager(struct mg_connection* conn, const std::string& endpoint, WsXmlDocH request); - bool handleSubscriptions(struct mg_connection* conn, const std::string& endpoint, WsXmlDocH request); - - static int enumerateEventCallback(WsXmlNodeH node, void* data); - static std::string getSoapAction(WsXmlDocH doc); - static std::string getMachineId(WsXmlDocH doc); - static bool isAckRequested(WsXmlDocH doc); - void sendResponse(struct mg_connection* conn, const std::string& machineId, const std::string& remoteIp, char* xml_buf, size_t xml_buf_size); - - static std::string millisecondsToXsdDuration(std::chrono::milliseconds milliseconds); - }; - - protected: - std::shared_ptr<core::logging::Logger> logger_ = core::logging::LoggerFactory<SourceInitiatedSubscriptionListener>::getLogger(); - - core::StateManager* state_manager_ = nullptr; - - std::shared_ptr<core::ProcessSessionFactory> session_factory_; - - std::string listen_hostname_; - uint16_t listen_port_; - std::string subscription_manager_path_; - std::string subscriptions_base_path_; - std::string ssl_ca_cert_thumbprint_; - std::string xpath_xml_query_; - std::string initial_existing_events_strategy_; - std::chrono::milliseconds subscription_expiration_interval_; - std::chrono::milliseconds heartbeat_interval_; - uint32_t max_elements_; - std::chrono::milliseconds max_latency_; - std::chrono::milliseconds connection_retry_interval_; - uint32_t connection_retry_count_; - - std::unique_ptr<CivetServer> server_; - std::unique_ptr<Handler> handler_; - - struct SubscriberData { - WsXmlDocH bookmark_; - std::string subscription_version_; - WsXmlDocH subscription_; - std::string subscription_endpoint_; - std::string subscription_identifier_; - - SubscriberData(); - ~SubscriberData(); - - void setSubscription(const std::string& subscription_version, WsXmlDocH subscription, const std::string& subscription_endpoint, const std::string& subscription_identifier); - void clearSubscription(); - void setBookmark(WsXmlDocH bookmark); - void clearBookmark(); - }; - - std::mutex mutex_; - std::map<std::string /*machineId*/, SubscriberData> subscribers_; - - bool persistState() const; - bool loadState(); -}; - -} // namespace org::apache::nifi::minifi::processors diff --git a/extensions/usb-camera/CMakeLists.txt b/extensions/usb-camera/CMakeLists.txt deleted file mode 100644 index 13d027518..000000000 --- a/extensions/usb-camera/CMakeLists.txt +++ /dev/null @@ -1,65 +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. -# - -if (NOT (ENABLE_ALL OR ENABLE_USB_CAMERA)) - return() -endif() - -include(${CMAKE_SOURCE_DIR}/extensions/ExtensionHeader.txt) - -find_package(PNG) -if(PNG_FOUND) - set(PNG_LINK_FLAGS ${PNG_LIBRARIES}) -else() - pkg_check_modules(PNG libpng) - if(PNG_FOUND) - set(PNG_INCLUDE_DIR ${PNG_INCLUDE_DIRS}) - set(PNG_LINK_FLAGS ${PNG_LDFLAGS}) - else() - find_path(PNG_INCLUDE_DIR png.h) - if(PNG_INCLUDE_DIR) - set(PNG_FOUND ON) - set(PNG_LINK_FLAGS -lpng) - endif() - endif() -endif() - -if (NOT PNG_FOUND) - message(FATAL_ERROR "A compatible PNG library is required to build GetUSBCamera.") -endif() - -if(NOT TARGET PNG::PNG) - add_library(PNG::PNG UNKNOWN IMPORTED) - set_target_properties(PNG::PNG PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${PNG_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES ${PNG_LINK_FLAGS}) -endif() - -include(FetchUvc) -find_package(UVC REQUIRED) - -file(GLOB SOURCES "*.cpp") - -add_minifi_library(minifi-usb-camera-extensions SHARED ${SOURCES}) - -target_link_libraries(minifi-usb-camera-extensions ${LIBMINIFI} Threads::Threads) -target_link_libraries(minifi-usb-camera-extensions LibUVC::UVC PNG::PNG) - -register_extension(minifi-usb-camera-extensions "USB CAMERA EXTENSIONS" USB-CAMERA-EXTENSIONS "This enables USB camera support") -register_extension_linter(minifi-usb-camera-extensions-linter) diff --git a/extensions/usb-camera/GetUSBCamera.cpp b/extensions/usb-camera/GetUSBCamera.cpp deleted file mode 100644 index 6cdff9a0f..000000000 --- a/extensions/usb-camera/GetUSBCamera.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/** - * @file GetUSBCamera.cpp - * GetUSBCamera class implementation - * - * 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 "GetUSBCamera.h" - -#include <png.h> - -#include <utility> -#include <string> -#include <vector> -#include <algorithm> - -#include "utils/gsl.h" -#include "core/ProcessSessionFactory.h" -#include "core/Resource.h" - -namespace org::apache::nifi::minifi::processors { - -void GetUSBCamera::initialize() { - setSupportedProperties(Properties); - setSupportedRelationships(Relationships); -} - -void GetUSBCamera::onFrame(uvc_frame_t *frame, void *ptr) { - auto cb_data = reinterpret_cast<GetUSBCamera::CallbackData *>(ptr); - std::unique_lock<std::recursive_mutex> lock(*(cb_data->dev_access_mtx), std::try_to_lock); - - if (!lock.owns_lock()) { - return; - } - - auto now = std::chrono::steady_clock::now(); - - if (now - cb_data->last_frame_time < std::chrono::milliseconds(static_cast<int>(1000.0 / cb_data->target_fps))) { - return; - } - - cb_data->last_frame_time = now; - - try { - uvc_error_t ret; - cb_data->logger->log_debug("Got frame"); - - ret = uvc_any2rgb(frame, cb_data->frame_buffer); - - if (ret) { - cb_data->logger->log_error("Failed to convert frame to RGB: {}", uvc_strerror(ret)); - return; - } - - auto session = cb_data->session_factory->createSession(); - auto flow_file = session->create(); - - std::string flow_file_name; - flow_file->getAttribute("filename", flow_file_name); - cb_data->logger->log_info("Created flow file: {}", flow_file_name); - - if (cb_data->format == "RAW") { - session->writeBuffer(flow_file, gsl::make_span(static_cast<const std::byte*>(cb_data->frame_buffer->data), cb_data->frame_buffer->data_bytes)); - } else { - if (cb_data->format != "PNG") { - cb_data->logger->log_warn("Invalid format specified ({}); defaulting to PNG", cb_data->format); - } - session->write(flow_file, GetUSBCamera::PNGWriteCallback{ - cb_data->png_write_mtx, - cb_data->frame_buffer, - cb_data->device_width, - cb_data->device_height}); - } - session->transfer(flow_file, GetUSBCamera::Success); - session->commit(); - } catch (std::exception &exception) { - cb_data->logger->log_debug("GetUSBCamera Caught Exception {}", exception.what()); - } catch (...) { - cb_data->logger->log_debug("GetUSBCamera Caught Unknown Exception"); - } -} - -void GetUSBCamera::onSchedule(core::ProcessContext& context, core::ProcessSessionFactory& session_factory) { - std::lock_guard<std::recursive_mutex> lock(*dev_access_mtx_); - - double default_fps = 1; - double target_fps = default_fps; - std::string conf_fps_str; - context.getProperty("FPS", conf_fps_str); - - if (conf_fps_str.empty()) { - logger_->log_info("FPS property was not set; using default {}", default_fps); - } else { - try { - target_fps = std::stod(conf_fps_str); - } catch (std::invalid_argument &e) { - logger_->log_error("Could not parse configured FPS value (will use default {}): {}", default_fps, conf_fps_str); - } - } - - uint16_t target_width = 0; - uint16_t target_height = 0; - std::string conf_width_str; - context.getProperty("Width", conf_width_str); - - if (!conf_width_str.empty()) { - auto target_width_ul = std::stoul(conf_width_str); - if (target_width_ul > UINT16_MAX) { - logger_->log_error("Configured target width {} is out of range", conf_width_str); - } else { - target_width = static_cast<uint16_t>(target_width_ul); - } - logger_->log_info("Using configured target width: {}", target_width); - } - - std::string conf_height_str; - context.getProperty("Height", conf_height_str); - - if (!conf_height_str.empty()) { - auto target_height_ul = std::stoul(conf_height_str); - if (target_height_ul > UINT16_MAX) { - logger_->log_error("Configured target height {} is out of range", conf_height_str); - } else { - target_height = static_cast<uint16_t>(target_height_ul); - } - logger_->log_info("Using configured target height: {}", target_height); - } - - std::string conf_format_str; - context.getProperty("Format", conf_format_str); - - int usb_vendor_id; - std::string conf_vendor_id; - context.getProperty("USB Vendor ID", conf_vendor_id); - std::stringstream(conf_vendor_id) >> std::hex >> usb_vendor_id; - logger_->log_info("Using USB Vendor ID: {:#x}", usb_vendor_id); - - int usb_product_id; - std::string conf_product_id; - context.getProperty("USB Product ID", conf_product_id); - std::stringstream(conf_product_id) >> std::hex >> usb_product_id; - logger_->log_info("Using USB Product ID: {:#x}", usb_product_id); - - const char *usb_serial_no = nullptr; - std::string conf_serial; - context.getProperty("USB Serial No.", conf_serial); - - if (!conf_serial.empty()) { - usb_serial_no = conf_serial.c_str(); - logger_->log_info("Using USB Serial No.: {}", conf_serial); - } - - cleanupUvc(); - logger_->log_info("Beginning to capture frames from USB camera"); - - uvc_stream_ctrl_t ctrl{}; - uvc_error_t res; - res = uvc_init(&ctx_, nullptr); - - if (res < 0) { - logger_->log_error("Failed to initialize UVC service context"); - ctx_ = nullptr; - return; - } - - logger_->log_debug("UVC initialized"); - - // Locate device - res = uvc_find_device(ctx_, &dev_, usb_vendor_id, usb_product_id, usb_serial_no); - - if (res < 0) { - logger_->log_error("Unable to find device: {}", uvc_strerror(res)); - dev_ = nullptr; - } else { - logger_->log_info("Device found"); - - // Open the device - res = uvc_open(dev_, &devh_); - - if (res < 0) { - logger_->log_error("Unable to open device: {}", uvc_strerror(res)); - devh_ = nullptr; - } else { - logger_->log_info("Device opened"); - - // Iterate resolutions & framerates >= context fps, or nearest - uint16_t width = 0; - uint16_t height = 0; - uint32_t max_size = 0; - uint32_t fps = 0; - - double min_diff = -1; - double current_diff = -1; - double current_width_diff = -1; - double current_height_diff = -1; - - for (auto fmt_desc = uvc_get_format_descs(devh_); fmt_desc; fmt_desc = fmt_desc->next) { - uvc_frame_desc_t *frame_desc; - switch (fmt_desc->bDescriptorSubtype) { - case UVC_VS_FORMAT_UNCOMPRESSED: - case UVC_VS_FORMAT_FRAME_BASED: - for (frame_desc = fmt_desc->frame_descs; frame_desc; frame_desc = frame_desc->next) { - uint32_t frame_fps = 10000000 / frame_desc->dwDefaultFrameInterval; - logger_->log_info("Discovered supported format {}x{} @ {}", - frame_desc->wWidth, - frame_desc->wHeight, - frame_fps); - if (target_height > 0 && target_width > 0) { - if (frame_fps >= target_fps) { - current_width_diff = abs(frame_desc->wWidth - target_width) / static_cast<double>(target_width); - logger_->log_debug("Current frame format width difference is {}", current_width_diff); - current_height_diff = abs(frame_desc->wHeight - target_height) / static_cast<double>(target_height); - logger_->log_debug("Current frame format height difference is {}", current_height_diff); - current_diff = (current_width_diff + current_height_diff) / 2; - logger_->log_debug("Current frame format difference is {}", current_diff); - - if (min_diff < 0 || current_diff < min_diff) { - logger_->log_info("Format {}x{} @ {} is now closest to target", - frame_desc->wWidth, - frame_desc->wHeight, - frame_fps); - width = frame_desc->wWidth; - height = frame_desc->wHeight; - max_size = frame_desc->dwMaxVideoFrameBufferSize; - fps = frame_fps; - min_diff = current_diff; - } - } - - } else { - if (frame_desc->dwMaxVideoFrameBufferSize > max_size && frame_fps >= target_fps) { - width = frame_desc->wWidth; - height = frame_desc->wHeight; - max_size = frame_desc->dwMaxVideoFrameBufferSize; - fps = frame_fps; - } - } - } - break; - - case UVC_VS_FORMAT_MJPEG: - logger_->log_info("Skipping MJPEG frame formats"); - break; - - default:logger_->log_warn("Found unknown format"); - } - } - - if (fps == 0) { - logger_->log_error("Could not find suitable frame format from device. " - "Try changing configuration (lower FPS) or device."); - return; - } - - logger_->log_info("Negotiating stream profile (looking for {}x{} @ {})", width, height, fps); - - res = uvc_get_stream_ctrl_format_size(devh_, &ctrl, UVC_FRAME_FORMAT_UNCOMPRESSED, width, height, fps); - - if (res < 0) { - logger_->log_error("Failed to find a matching stream profile: {}", uvc_strerror(res)); - } else { - cb_data_.session_factory = &session_factory; - - if (frame_buffer_ != nullptr) { - uvc_free_frame(frame_buffer_); - } - - frame_buffer_ = uvc_allocate_frame(width * height * 3); - - if (!frame_buffer_) { - printf("unable to allocate bgr frame!"); - logger_->log_error("Unable to allocate RGB frame"); - return; - } - - cb_data_.frame_buffer = frame_buffer_; - cb_data_.context = &context; - cb_data_.png_write_mtx = png_write_mtx_; - cb_data_.dev_access_mtx = dev_access_mtx_; - cb_data_.logger = logger_; - cb_data_.format = conf_format_str; - cb_data_.device_width = width; - cb_data_.device_height = height; - cb_data_.device_fps = fps; - cb_data_.target_fps = target_fps; - cb_data_.last_frame_time = std::chrono::steady_clock::time_point(); - - res = uvc_start_streaming(devh_, &ctrl, onFrame, &cb_data_, 0); - - if (res < 0) { - logger_->log_error("Unable to start streaming: {}", uvc_strerror(res)); - } else { - logger_->log_info("Streaming..."); - - // Enable auto-exposure - uvc_set_ae_mode(devh_, 1); - } - } - } - } -} - -void GetUSBCamera::cleanupUvc() { - std::lock_guard<std::recursive_mutex> lock(*dev_access_mtx_); - - if (frame_buffer_ != nullptr) { - logger_->log_debug("Deallocating frame buffer"); - uvc_free_frame(frame_buffer_); - } - - if (devh_ != nullptr) { - logger_->log_debug("Stopping UVC streaming"); - uvc_stop_streaming(devh_); - logger_->log_debug("Closing UVC device handle"); - uvc_close(devh_); - } - - if (dev_ != nullptr) { - logger_->log_debug("Closing UVC device descriptor"); - uvc_unref_device(dev_); - } - - if (ctx_ != nullptr) { - logger_->log_debug("Closing UVC context"); - uvc_exit(ctx_); - } - - if (camera_thread_ != nullptr) { - camera_thread_->join(); - logger_->log_debug("UVC thread ended"); - } -} - -void GetUSBCamera::onTrigger(core::ProcessContext&, core::ProcessSession& session) { - auto flowFile = session.get(); - - if (flowFile) { - logger_->log_error("Received flowfile, but this processor does not support input flow files; routing to failure"); - session.transfer(flowFile, Failure); - } -} - -GetUSBCamera::PNGWriteCallback::PNGWriteCallback(std::shared_ptr<std::mutex> write_mtx, - uvc_frame_t *frame, - uint32_t width, - uint32_t height) - : png_write_mtx_(std::move(write_mtx)), - frame_(frame), - width_(width), - height_(height) { -} - -int64_t GetUSBCamera::PNGWriteCallback::operator()(const std::shared_ptr<io::OutputStream>& stream) { - std::lock_guard<std::mutex> lock(*png_write_mtx_); - logger_->log_info("Writing {} bytes of raw capture data to PNG output", frame_->data_bytes); - png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - - if (!png) { - logger_->log_error("Failed to create PNG write struct"); - return 0; - } - - png_infop info = png_create_info_struct(png); - - if (!info) { - logger_->log_error("Failed to create PNG info struct"); - return 0; - } - - if (setjmp(png_jmpbuf(png))) { // NOLINT(cert-err52-cpp) - logger_->log_error("Failed to set PNG jmpbuf"); - return 0; - } - - try { - png_set_write_fn(png, this, [](png_structp out_png, - png_bytep out_data, - png_size_t num_bytes) { - auto this_callback = reinterpret_cast<PNGWriteCallback *>(png_get_io_ptr(out_png)); - std::copy(out_data, out_data + num_bytes, std::back_inserter(this_callback->png_output_buf_)); - }, - [](png_structp /*flush_png*/) {}); - - png_set_IHDR(png, info, width_, height_, 8, - PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - std::vector<png_bytep> row_pointers; - row_pointers.resize(height_); - - for (uint32_t y = 0; y < height_; y++) { - row_pointers[y] = reinterpret_cast<png_byte *>(frame_->data) + width_ * y * 3; - } - - png_write_image(png, row_pointers.data()); - png_write_end(png, nullptr); - - png_destroy_write_struct(&png, &info); - } catch (...) { - if (png && info) { - png_destroy_write_struct(&png, &info); - } - throw; - } - - const auto write_ret = stream->write(png_output_buf_.data(), png_output_buf_.size()); - return io::isError(write_ret) ? -1 : gsl::narrow<int64_t>(write_ret); -} - -REGISTER_RESOURCE(GetUSBCamera, Processor); - -} // namespace org::apache::nifi::minifi::processors diff --git a/extensions/usb-camera/GetUSBCamera.h b/extensions/usb-camera/GetUSBCamera.h deleted file mode 100644 index cbea31d10..000000000 --- a/extensions/usb-camera/GetUSBCamera.h +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file GetUSBCamera.h - * GetUSBCamera 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 <list> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "libuvc/libuvc.h" - -#include "FlowFileRecord.h" -#include "core/Processor.h" -#include "core/ProcessSession.h" -#include "core/PropertyDefinition.h" -#include "core/PropertyDefinitionBuilder.h" -#include "core/RelationshipDefinition.h" -#include "core/Core.h" -#include "core/logging/LoggerConfiguration.h" - -namespace org::apache::nifi::minifi::processors { - -class GetUSBCamera : public core::Processor { - public: - explicit GetUSBCamera(std::string name, const utils::Identifier &uuid = {}) - : core::Processor(std::move(name), uuid) { - png_write_mtx_ = std::make_shared<std::mutex>(); - dev_access_mtx_ = std::make_shared<std::recursive_mutex>(); - } - - ~GetUSBCamera() override { - // We cannot interrupt the PNG write process - std::lock_guard<std::mutex> lock(*png_write_mtx_); - cleanupUvc(); - } - - void notifyStop() override { - // We cannot interrupt the PNG write process - std::lock_guard<std::mutex> lock(*png_write_mtx_); - cleanupUvc(); - } - - EXTENSIONAPI static constexpr const char* Description = "Gets images from USB Video Class (UVC)-compatible devices. " - "Outputs one flow file per frame at the rate specified by the FPS property in the format specified by the Format property."; - - EXTENSIONAPI static constexpr auto FPS = core::PropertyDefinitionBuilder<>::createProperty("FPS") - .withDescription("Frames per second to capture from USB camera") - .withDefaultValue("1") - .build(); - EXTENSIONAPI static constexpr auto Width = core::PropertyDefinitionBuilder<>::createProperty("Width") - .withDescription("Target width of image to capture from USB camera") - .build(); - EXTENSIONAPI static constexpr auto Height = core::PropertyDefinitionBuilder<>::createProperty("Height") - .withDescription("Target height of image to capture from USB camera") - .build(); - EXTENSIONAPI static constexpr auto Format = core::PropertyDefinitionBuilder<>::createProperty("Format") - .withDescription("Frame format (currently only PNG and RAW are supported; RAW is a binary pixel buffer of RGB values)") - .withDefaultValue("PNG") - .build(); - EXTENSIONAPI static constexpr auto VendorID = core::PropertyDefinitionBuilder<>::createProperty("USB Vendor ID") - .withDescription("USB Vendor ID of camera device, in hexadecimal format") - .withDefaultValue("0x0") - .build(); - EXTENSIONAPI static constexpr auto ProductID = core::PropertyDefinitionBuilder<>::createProperty("USB Product ID") - .withDescription("USB Product ID of camera device, in hexadecimal format") - .withDefaultValue("0x0") - .build(); - EXTENSIONAPI static constexpr auto SerialNo = core::PropertyDefinitionBuilder<>::createProperty("USB Serial No.") - .withDescription("USB Serial No. of camera device") - .build(); - EXTENSIONAPI static constexpr auto Properties = std::array<core::PropertyReference, 7>{ - FPS, - Width, - Height, - Format, - VendorID, - ProductID, - SerialNo - }; - - - EXTENSIONAPI static constexpr auto Success = core::RelationshipDefinition{"success", "Sucessfully captured images sent here"}; - EXTENSIONAPI static constexpr auto Failure = core::RelationshipDefinition{"failure", "Failures sent here"}; - EXTENSIONAPI static constexpr auto Relationships = std::array{Success, Failure}; - - EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false; - EXTENSIONAPI static constexpr bool SupportsDynamicRelationships = false; - EXTENSIONAPI static constexpr core::annotation::Input InputRequirement = core::annotation::Input::INPUT_ALLOWED; - EXTENSIONAPI static constexpr bool IsSingleThreaded = false; - - ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_PROCESSORS - - void onSchedule(core::ProcessContext& context, - core::ProcessSessionFactory& session_factory) override; - void onTrigger(core::ProcessContext& context, - core::ProcessSession& session) override; - void initialize() override; - - struct CallbackData { - core::ProcessContext *context; - core::ProcessSessionFactory *session_factory; - std::shared_ptr<core::logging::Logger> logger; - std::shared_ptr<std::mutex> png_write_mtx; - std::shared_ptr<std::recursive_mutex> dev_access_mtx; - std::string format; - uvc_frame_t *frame_buffer; - uint16_t device_width; - uint16_t device_height; - uint32_t device_fps; - double target_fps; - std::chrono::steady_clock::time_point last_frame_time; - }; - - static void onFrame(uvc_frame_t *frame, void *ptr); - - // Write callback for storing camera capture data in PNG format - class PNGWriteCallback { - public: - PNGWriteCallback(std::shared_ptr<std::mutex> write_mtx, uvc_frame_t *frame, uint32_t width, uint32_t height); - int64_t operator()(const std::shared_ptr<io::OutputStream>& stream); - - private: - std::shared_ptr<std::mutex> png_write_mtx_; - uvc_frame_t *frame_; - const uint32_t width_; - const uint32_t height_; - std::vector<uint8_t> png_output_buf_; - std::shared_ptr<core::logging::Logger> logger_ = core::logging::LoggerFactory<PNGWriteCallback>::getLogger(); - }; - - private: - std::shared_ptr<core::logging::Logger> logger_ = core::logging::LoggerFactory<GetUSBCamera>::getLogger(uuid_); - static std::shared_ptr<utils::IdGenerator> id_generator_; - - std::shared_ptr<std::thread> camera_thread_; - CallbackData cb_data_{}; - - std::shared_ptr<std::mutex> png_write_mtx_; - std::shared_ptr<std::recursive_mutex> dev_access_mtx_; - - uvc_frame_t *frame_buffer_ = nullptr; - uvc_context_t *ctx_ = nullptr; - uvc_device_t *dev_ = nullptr; - uvc_device_handle_t *devh_ = nullptr; - - void cleanupUvc(); -}; - -} // namespace org::apache::nifi::minifi::processors diff --git a/fedora.sh b/fedora.sh index 11abb5dc8..7734e72a1 100644 --- a/fedora.sh +++ b/fedora.sh @@ -53,10 +53,6 @@ build_deps(){ echo "$FOUND_VALUE" if [ "$FOUND_VALUE" = "libpcap" ]; then INSTALLED+=("libpcap-devel") - elif [ "$FOUND_VALUE" = "libusb" ]; then - INSTALLED+=("libusb1-devel") - elif [ "$FOUND_VALUE" = "libpng" ]; then - INSTALLED+=("libpng-devel") elif [ "$FOUND_VALUE" = "bison" ]; then INSTALLED+=("bison") elif [ "$FOUND_VALUE" = "flex" ]; then diff --git a/rheldistro.sh b/rheldistro.sh index aba5ce647..8c70d33a1 100644 --- a/rheldistro.sh +++ b/rheldistro.sh @@ -21,17 +21,11 @@ verify_enable_platform() { if [ "$OS_MAJOR" = "6" ]; then if [ "$feature" = "GPS_ENABLED" ]; then echo "false" - elif [ "$feature" = "USB_ENABLED" ]; then - echo "false" else verify_gcc_enable "$feature" fi else - if [ "$feature" = "USB_ENABLED" ]; then - echo "false" - else - verify_gcc_enable "$feature" - fi + verify_gcc_enable "$feature" fi } @@ -94,10 +88,6 @@ build_deps(){ FOUND_VALUE="$VALUE" if [ "$FOUND_VALUE" = "libpcap" ]; then INSTALLED+=("libpcap-devel") - elif [ "$FOUND_VALUE" = "libusb" ]; then - INSTALLED+=("libusb-devel") - elif [ "$FOUND_VALUE" = "libpng" ]; then - INSTALLED+=("libpng-devel") elif [ "$FOUND_VALUE" = "bison" ]; then install_bison elif [ "$FOUND_VALUE" = "flex" ]; then diff --git a/suse.sh b/suse.sh index ab24d3977..e9a95b197 100644 --- a/suse.sh +++ b/suse.sh @@ -21,17 +21,11 @@ verify_enable_platform() { if [ "$OS_MAJOR" = "6" ]; then if [ "${feature}" = "GPS_ENABLED" ]; then echo "false" - elif [ "${feature}" = "USB_ENABLED" ]; then - echo "false" else verify_gcc_enable "${feature}" fi else - if [ "${feature}" = "USB_ENABLED" ]; then - echo "false" - else - verify_gcc_enable "${feature}" - fi + verify_gcc_enable "${feature}" fi } @@ -80,10 +74,6 @@ build_deps(){ FOUND_VALUE="$VALUE" if [ "$FOUND_VALUE" = "libpcap" ]; then INSTALLED+=("libpcap-devel") - elif [ "$FOUND_VALUE" = "libusb" ]; then - INSTALLED+=("libusb-devel") - elif [ "$FOUND_VALUE" = "libpng" ]; then - INSTALLED+=("libpng-devel") elif [ "$FOUND_VALUE" = "bison" ]; then install_bison elif [ "$FOUND_VALUE" = "flex" ]; then diff --git a/thirdparty/openwsman/openwsman.patch b/thirdparty/openwsman/openwsman.patch deleted file mode 100644 index 20659721d..000000000 --- a/thirdparty/openwsman/openwsman.patch +++ /dev/null @@ -1,120 +0,0 @@ -PTHREAD_MUTEX_RECURSIVE_NP is a non-portable glibc mutex and our docker base distro alpine does not have glibc, only musl is available. -On these systems only PTHREAD_MUTEX_RECURSIVE mutex is available that's why we redefine the non-portable symbol. - -diff -rupN orig/CMakeLists.txt patched/CMakeLists.txt ---- orig/CMakeLists.txt 2019-09-17 11:38:38.000000000 +0200 -+++ patched/CMakeLists.txt 2020-04-16 23:43:22.000000000 +0200 -@@ -24,7 +24,7 @@ if(COMMAND cmake_policy) - endif(COMMAND cmake_policy) - - # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked --SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH}) -+LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) - - INCLUDE( ${CMAKE_SOURCE_DIR}/VERSION.cmake ) - SET(VERSION "${OPENWSMAN_MAJOR}.${OPENWSMAN_MINOR}.${OPENWSMAN_PATCH}") -@@ -168,8 +168,14 @@ ENDIF( USE_PAM ) - - INCLUDE(FindOpenSSL) - IF(OPENSSL_FOUND) -+ MESSAGE("OpenSSL found") -+ MESSAGE("OPENSSL_INCLUDE_DIR: ${OPENSSL_INCLUDE_DIR}") -+ MESSAGE("OPENSSL_LIBRARIES: ${OPENSSL_LIBRARIES}") - SET(HAVE_SSL 1) - SET(USE_OPENSSL 1) -+ INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) -+ELSE(OPENSSL_FOUND) -+ SET(HAVE_SSL 0) - ENDIF(OPENSSL_FOUND) - - IF( BUILD_RUBY ) -@@ -256,6 +262,9 @@ IF(UNIX) - IF ( NOT CURL_FOUND) - MESSAGE( FATAL_ERROR " curl not found" ) - ELSE ( NOT CURL_FOUND) -+ MESSAGE("cURL found") -+ MESSAGE("CURL_INCLUDE_DIR: ${CURL_INCLUDE_DIR}") -+ MESSAGE("CURL_LIBRARIES: ${CURL_LIBRARIES}") - INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR}) - IF(CURL_VERSION_STRING) - STRING(COMPARE LESS ${CURL_VERSION_STRING} "7.12.0" result) -@@ -272,6 +281,9 @@ INCLUDE(FindLibXml2) - IF ( NOT LIBXML2_FOUND) - MESSAGE( FATAL_ERROR " libxml2 not found" ) - ELSE ( NOT LIBXML2_FOUND) -+ MESSAGE("Libxml2 found") -+ MESSAGE("LIBXML2_INCLUDE_DIR: ${LIBXML2_INCLUDE_DIR}") -+ MESSAGE("LIBXML2_LIBRARIES: ${LIBXML2_LIBRARIES}") - INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) - ENDIF( NOT LIBXML2_FOUND) - -diff -rupN orig/src/lib/wsman-soap.c patched/src/lib/wsman-soap.c ---- orig/src/lib/wsman-soap.c 2019-09-17 11:38:38.000000000 +0200 -+++ patched/src/lib/wsman-soap.c 2020-04-16 23:21:49.000000000 +0200 -@@ -991,10 +991,12 @@ unsigned long get_total_enum_context(WsC - * preset, hence marking them as weak symbols and testing to see - * if they are resolved before using them. - */ -+#if 0 - #pragma weak wsmand_options_get_max_threads - extern int wsmand_options_get_max_threads(void); - #pragma weak wsmand_options_get_max_connections_per_thread - extern int wsmand_options_get_max_connections_per_thread(void); -+#endif - - /** - * Enumeration Stub for processing enumeration requests -@@ -1030,9 +1032,17 @@ wsenum_enumerate_stub(SoapOpH op, - int max_threads = 0; - int max_connections_per_thread = 0; - int(* fptr)(void); -+#if 0 - if((fptr = wsmand_options_get_max_threads) != 0){ -+#else -+ if(0){ -+#endif - max_threads = (* fptr)(); -+#if 0 - if((fptr = wsmand_options_get_max_connections_per_thread) != 0){ -+#else -+ if(0){ -+#endif - max_connections_per_thread = (* fptr)(); - } - else{ - -diff -rupN orig/src/lib/u/lock.c patched/src/lib/u/lock.c ---- orig/src/lib/u/lock.c 2021-05-31 13:44:43.992941115 +0200 -+++ patched/src/lib/u/lock.c 2021-05-31 12:00:21.972733061 +0200 -@@ -50,7 +50,7 @@ - extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); - #endif - --#if defined (__SVR4) && defined (__sun) -+#if (defined (__SVR4) && defined (__sun)) || !defined(__GLIBC__) - #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE - #endif - -@@ -94,7 +94,7 @@ void u_destroy_lock(void* data) - void u_unlock(void* data) - { - if ( data ) -- { -+ { - pthread_mutex_unlock((pthread_mutex_t*)data); - } - } - -diff -rupN orig/include/u/lock.h patched/include/u/lock.h ---- orig/include/u/lock.h 2021-05-31 13:44:43.992941115 +0200 -+++ patched/include/u/lock.h 2021-05-31 12:00:30.792726402 +0200 -@@ -2,7 +2,7 @@ - #ifndef LOCKING_H - #define LOCKING_H - --#if defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__) || defined (__APPLE__) -+#if defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__) || defined (__APPLE__) || !defined(__GLIBC__) - /* Provide the Linux initializers for MacOS X */ - #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE - #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { 0x4d555458, \ - diff --git a/win_build_vs.bat b/win_build_vs.bat index 2a56347cd..285d035b5 100644 --- a/win_build_vs.bat +++ b/win_build_vs.bat @@ -38,12 +38,10 @@ set enable_opc=ON set enable_pdh=OFF set enable_splunk=ON set enable_smb=ON -set enable_openwsman=OFF set enable_ops=ON set enable_pcap=OFF set enable_python_scripting=ON set enable_sensors=OFF -set enable_usb_camera=OFF set enable_opencv=OFF set enable_prometheus=ON set enable_gcp=ON @@ -84,12 +82,10 @@ for %%x in (%*) do ( if [%%~x] EQU [/NO_LUA_SCRIPTING] set enable_lua_scripting=OFF if [%%~x] EQU [/NO_MQTT] set enable_mqtt=OFF if [%%~x] EQU [/NO_OPC] set enable_opc=OFF - if [%%~x] EQU [/OPENWSMAN] set enable_openwsman=ON if [%%~x] EQU [/NO_OPS] set enable_ops=OFF if [%%~x] EQU [/PCAP] set enable_pcap=ON if [%%~x] EQU [/NO_PYTHON_SCRIPTING] set enable_python_scripting=OFF if [%%~x] EQU [/SENSORS] set enable_sensors=ON - if [%%~x] EQU [/USB_CAMERA] set enable_usb_camera=ON if [%%~x] EQU [/LOKI] set enable_grafana_loki=ON if [%%~x] EQU [/32] set build_platform=Win32 if [%%~x] EQU [/D] set cmake_build_type=RelWithDebInfo @@ -118,8 +114,8 @@ cmake -G %generator% %build_platform_cmd% -DMINIFI_INCLUDE_VC_REDIST_MERGE_MODUL -DENABLE_AWS=%enable_aws% -DENABLE_PDH=%enable_pdh% -DENABLE_AZURE=%enable_azure% -DENABLE_SFTP=%enable_sftp% -DENABLE_SPLUNK=%enable_splunk% -DENABLE_GCP=%enable_gcp% ^ -DENABLE_OPENCV=%enable_opencv% -DENABLE_PROMETHEUS=%enable_prometheus% -DENABLE_ELASTICSEARCH=%enable_elastic% -DUSE_SHARED_LIBS=OFF -DENABLE_CONTROLLER=OFF ^ -DENABLE_BUSTACHE=%enable_bustache% -DENABLE_ENCRYPT_CONFIG=%enable_encrypt_config% -DENABLE_LUA_SCRIPTING=%enable_lua_scripting% -DENABLE_SMB=%enable_smb% ^ - -DENABLE_MQTT=%enable_mqtt% -DENABLE_OPC=%enable_opc% -DENABLE_OPENWSMAN=%enable_openwsman% -DENABLE_OPS=%enable_ops% -DENABLE_PCAP=%enable_pcap% ^ - -DENABLE_PYTHON_SCRIPTING=%enable_python_scripting% -DENABLE_SENSORS=%enable_sensors% -DENABLE_USB_CAMERA=%enable_usb_camera% -DENABLE_GRAFANA_LOKI=%enable_grafana_loki% ^ + -DENABLE_MQTT=%enable_mqtt% -DENABLE_OPC=%enable_opc% -DENABLE_OPS=%enable_ops% -DENABLE_PCAP=%enable_pcap% ^ + -DENABLE_PYTHON_SCRIPTING=%enable_python_scripting% -DENABLE_SENSORS=%enable_sensors% -DENABLE_GRAFANA_LOKI=%enable_grafana_loki% ^ -DBUILD_ROCKSDB=ON -DUSE_SYSTEM_UUID=OFF -DENABLE_LIBARCHIVE=ON -DENABLE_WEL=ON -DMINIFI_FAIL_ON_WARNINGS=OFF -DSKIP_TESTS=%skiptests% -DMINIFI_INCLUDE_VC_REDIST_DLLS=%vc_redist% ^ %strict_gsl_checks% -DMINIFI_INCLUDE_UCRT_DLLS=%ucrt% %sccache_arg% %EXTRA_CMAKE_ARGUMENTS% "%scriptdir%" && %buildcmd% IF %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%