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 ba1188d49f6fd75cb9423b8fdf1e2889530aa45b
Author: Ferenc Gerlits <[email protected]>
AuthorDate: Fri Oct 6 14:18:47 2023 +0200

    MINIFICPP-2185 Upgrade to Visual Studio 2022
    
    Closes #1635
    
    Signed-off-by: Marton Szasz <[email protected]>
---
 .github/workflows/ci.yml                           | 69 +++++++++++++++++++---
 CMakeLists.txt                                     |  2 +-
 cmake/BundledOSSPUUID.cmake                        |  8 ++-
 cmake/BundledOpenSSL.cmake                         |  2 +-
 extensions/aws/processors/S3Processor.cpp          |  2 +-
 extensions/aws/processors/S3Processor.h            |  1 +
 extensions/aws/s3/S3Wrapper.cpp                    |  4 +-
 .../azure/storage/AzureDataLakeStorageClient.cpp   |  4 +-
 extensions/elasticsearch/PostElasticsearch.cpp     |  8 +--
 extensions/expression-language/common/Value.h      |  4 +-
 extensions/libarchive/WriteArchiveStream.cpp       |  6 +-
 extensions/libarchive/tests/MergeFileTests.cpp     |  9 +--
 extensions/librdkafka/ConsumeKafka.cpp             | 12 ++--
 extensions/librdkafka/PublishKafka.cpp             |  2 +-
 extensions/mqtt/processors/PublishMQTT.cpp         |  2 +-
 extensions/pdh/PDHCounters.cpp                     |  4 +-
 extensions/python/tests/PythonManifestTests.cpp    |  3 +-
 .../tests/SmbConnectionControllerServiceTests.cpp  |  3 +-
 extensions/sql/data/JSONSQLWriter.cpp              | 14 +----
 extensions/sql/data/JSONSQLWriter.h                | 14 +----
 .../standard-processors/processors/PutTCP.cpp      |  2 +-
 extensions/windows-event-log/Bookmark.cpp          |  6 +-
 .../CollectorInitiatedSubscription.cpp             |  2 +-
 .../windows-event-log/ConsumeWindowsEventLog.cpp   |  8 +--
 extensions/windows-event-log/tests/CWELTestUtils.h |  5 +-
 extensions/windows-event-log/wel/EventPath.cpp     |  3 +-
 extensions/windows-event-log/wel/EventPath.h       | 14 +++--
 .../windows-event-log/wel/WindowsEventLog.cpp      | 13 ++--
 libminifi/include/core/PropertyType.h              |  4 +-
 .../include/utils/OpenTelemetryLogDataModelUtils.h | 10 ++--
 libminifi/include/utils/OsUtils.h                  |  4 --
 libminifi/include/utils/TestUtils.h                |  5 ++
 .../include/utils}/UnicodeConversion.h             | 27 ++++-----
 libminifi/src/core/logging/LoggerConfiguration.cpp |  2 +-
 libminifi/src/core/logging/alert/AlertSink.cpp     |  4 +-
 libminifi/src/io/InputStream.cpp                   |  2 +-
 libminifi/src/utils/BaseHTTPClient.cpp             |  8 +--
 libminifi/src/utils/Cron.cpp                       |  8 +--
 libminifi/src/utils/FileMutex.cpp                  |  6 +-
 libminifi/src/utils/NetworkInterfaceInfo.cpp       |  3 +-
 libminifi/src/utils/OsUtils.cpp                    | 30 ----------
 libminifi/src/utils/ProcessCpuUsageTracker.cpp     |  1 -
 libminifi/src/utils/TestUtils.cpp                  | 62 +++++++++++++++++++
 libminifi/src/utils/crypto/ciphers/Aes256Ecb.cpp   |  8 +--
 libminifi/test/unit/FileSystemRepositoryTests.cpp  | 29 ++-------
 libminifi/test/unit/OsUtilTests.cpp                | 20 -------
 libminifi/test/unit/StringUtilsTests.cpp           | 44 +++++++++++---
 47 files changed, 284 insertions(+), 219 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e891a6aa5..5b39dba81 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -67,10 +67,10 @@ jobs:
         with:
           name: macos-binaries
           path: build/bin
-  windows_VS2019:
-    name: "windows-2019"
-    runs-on: windows-2019
-    timeout-minutes: 180
+  windows_VS2022:
+    name: "windows-2022"
+    runs-on: windows-2022
+    timeout-minutes: 240
     steps:
       - name: Support longpaths
         run: git config --system core.longpaths true
@@ -80,11 +80,11 @@ jobs:
         uses: actions/cache/restore@v3
         with:
           path: ~/AppData/Local/Mozilla/sccache/cache
-          key: ${{ runner.os }}-sccache-${{ github.ref }}-${{ github.sha }}
+          key: ${{ runner.os }}-2022-sccache-${{ github.ref }}-${{ github.sha 
}}
           restore-keys: |
-            ${{ runner.os }}-sccache-${{ github.ref }}
-            ${{ runner.os }}-sccache-refs/heads/main
-            ${{ runner.os }}-sccache
+            ${{ runner.os }}-2022-sccache-${{ github.ref }}
+            ${{ runner.os }}-2022-sccache-refs/heads/main
+            ${{ runner.os }}-2022-sccache
       - name: Run sccache-cache
         uses: mozilla-actions/[email protected]
       - name: Install ninja-build tool
@@ -114,13 +114,64 @@ jobs:
         if: always()
         with:
           path: ~/AppData/Local/Mozilla/sccache/cache
-          key: ${{ runner.os }}-sccache-${{ github.ref }}-${{ github.sha }}
+          key: ${{ runner.os }}-2022-sccache-${{ github.ref }}-${{ github.sha 
}}
       - name: test
         run: cd ..\b && ctest --timeout 300 --parallel %NUMBER_OF_PROCESSORS% 
-C Release --output-on-failure
         shell: cmd
       - name: linter
         run: cd ..\b && cmake --build . --target linter --config Release -j 8
         shell: cmd
+  windows_VS2019:
+    name: "windows-2019"
+    runs-on: windows-2019
+    timeout-minutes: 240
+    steps:
+      - name: Support longpaths
+        run: git config --system core.longpaths true
+      - id: checkout
+        uses: actions/checkout@v3
+      - name: sccache cache restore
+        uses: actions/cache/restore@v3
+        with:
+          path: ~/AppData/Local/Mozilla/sccache/cache
+          key: ${{ runner.os }}-2019-sccache-${{ github.ref }}-${{ github.sha 
}}
+          restore-keys: |
+            ${{ runner.os }}-2019-sccache-${{ github.ref }}
+            ${{ runner.os }}-2019-sccache-refs/heads/main
+            ${{ runner.os }}-2019-sccache
+      - name: Run sccache-cache
+        uses: mozilla-actions/[email protected]
+      - name: Install ninja-build tool
+        uses: seanmiddleditch/gha-setup-ninja@v3
+      - name: Set up Python
+        uses: actions/setup-python@v4
+        with:
+          python-version: '3.11'
+      - name: Set up Lua
+        uses: xpol/[email protected]
+      - name: Set up NASM for OpenSSL
+        uses: ilammy/setup-nasm@v1
+      - id: install-sqliteodbc-driver
+        run: |
+          Invoke-WebRequest -Uri 
"http://www.ch-werner.de/sqliteodbc/sqliteodbc_w64.exe"; -OutFile 
"sqliteodbc_w64.exe"
+          if ((Get-FileHash 'sqliteodbc_w64.exe').Hash -ne 
"0df79be4a4412542839ebf405b20d95a7dfc803da0b0b6b0dc653d30dc82ee84") {Write 
"Hash mismatch"; Exit 1}
+          ./sqliteodbc_w64.exe /S
+        shell: powershell
+      - name: build
+        run: |
+          for /f "usebackq delims=" %%i in (`vswhere.exe -latest -property 
installationPath`) do if exist "%%i\Common7\Tools\vsdevcmd.bat" call 
"%%i\Common7\Tools\vsdevcmd.bat" -arch=x64 -host_arch=x64
+          win_build_vs.bat ..\b /64 /CI /S /A /PDH /SPLUNK /GCP /ELASTIC /K /L 
/R /Z /N /RO /PR /PYTHON_SCRIPTING /LUA_SCRIPTING /MQTT /SCCACHE /NINJA
+          sccache --show-stats
+        shell: cmd
+      - name: sccache cache save
+        uses: actions/cache/save@v3
+        if: always()
+        with:
+          path: ~/AppData/Local/Mozilla/sccache/cache
+          key: ${{ runner.os }}-2019-sccache-${{ github.ref }}-${{ github.sha 
}}
+      - name: test
+        run: cd ..\b && ctest --timeout 300 --parallel %NUMBER_OF_PROCESSORS% 
-C Release --output-on-failure
+        shell: cmd
   ubuntu_20_04:
     name: "ubuntu-20.04"
     runs-on: ubuntu-20.04
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 511aa0434..5ed19b7a7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,7 +106,7 @@ endif()
 # Enable usage of the VERSION specifier
 if (WIN32)
     add_compile_definitions(WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_WARNINGS 
NOMINMAX)
-    add_compile_options(/W3 /utf-8 /bigobj)
+    add_compile_options(/W3 /utf-8 /bigobj /MP)
 endif()
 
 if (NOT PORTABLE)
diff --git a/cmake/BundledOSSPUUID.cmake b/cmake/BundledOSSPUUID.cmake
index c4fa1523b..de9e99e98 100644
--- a/cmake/BundledOSSPUUID.cmake
+++ b/cmake/BundledOSSPUUID.cmake
@@ -39,7 +39,13 @@ function(use_bundled_osspuuid SOURCE_DIR BINARY_DIR)
     ENDFOREACH(BYPRODUCT)
 
     # Build project
-    set(CONFIGURE_COMMAND ./configure "CC=${CMAKE_C_COMPILER}" 
"CXX=${CMAKE_CXX_COMPILER}" "CFLAGS=${PASSTHROUGH_CMAKE_C_FLAGS} -fPIC" 
"CXXFLAGS=${PASSTHROUGH_CMAKE_CXX_FLAGS} -fPIC" --enable-shared=no --with-cxx 
--without-perl --without-php --without-pgsql 
"--prefix=${BINARY_DIR}/thirdparty/ossp-uuid-install")
+    if(WIN32)
+        set(ADDITIONAL_COMPILER_FLAGS "")
+    else()
+        set(ADDITIONAL_COMPILER_FLAGS "-fPIC")
+    endif()
+    set(CONFIGURE_COMMAND ./configure "CC=${CMAKE_C_COMPILER}" 
"CXX=${CMAKE_CXX_COMPILER}" "CFLAGS=${PASSTHROUGH_CMAKE_C_FLAGS} 
${ADDITIONAL_COMPILER_FLAGS}" "CXXFLAGS=${PASSTHROUGH_CMAKE_CXX_FLAGS} 
${ADDITIONAL_COMPILER_FLAGS}" --enable-shared=no --with-cxx --without-perl 
--without-php --without-pgsql 
"--prefix=${BINARY_DIR}/thirdparty/ossp-uuid-install")
+
     string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type)
     if(NOT build_type MATCHES debug)
         list(APPEND CONFIGURE_COMMAND --enable-debug=yes)
diff --git a/cmake/BundledOpenSSL.cmake b/cmake/BundledOpenSSL.cmake
index 35e26d2f6..9ec3ddee5 100644
--- a/cmake/BundledOpenSSL.cmake
+++ b/cmake/BundledOpenSSL.cmake
@@ -75,7 +75,7 @@ function(use_openssl SOURCE_DIR BINARY_DIR)
                 URL_HASH 
"SHA256=b3aa61334233b852b63ddb048df181177c2c659eb9d4376008118f9c08d07674"
                 SOURCE_DIR "${BINARY_DIR}/thirdparty/openssl-src"
                 BUILD_IN_SOURCE true
-                CONFIGURE_COMMAND perl Configure 
"CFLAGS=${PASSTHROUGH_CMAKE_C_FLAGS} -fPIC" 
"CXXFLAGS=${PASSTHROUGH_CMAKE_CXX_FLAGS} -fPIC" ${OPENSSL_SHARED_FLAG} no-tests 
"--prefix=${OPENSSL_BIN_DIR}" "--openssldir=${OPENSSL_BIN_DIR}"
+                CONFIGURE_COMMAND perl Configure 
"CFLAGS=${PASSTHROUGH_CMAKE_C_FLAGS}" "CXXFLAGS=${PASSTHROUGH_CMAKE_CXX_FLAGS}" 
${OPENSSL_SHARED_FLAG} no-tests "--prefix=${OPENSSL_BIN_DIR}" 
"--openssldir=${OPENSSL_BIN_DIR}"
                 BUILD_BYPRODUCTS ${OPENSSL_LIBRARIES_LIST}
                 PATCH_COMMAND ${PC}
                 EXCLUDE_FROM_ALL TRUE
diff --git a/extensions/aws/processors/S3Processor.cpp 
b/extensions/aws/processors/S3Processor.cpp
index 960b4de17..ee2aa2e05 100644
--- a/extensions/aws/processors/S3Processor.cpp
+++ b/extensions/aws/processors/S3Processor.cpp
@@ -121,7 +121,7 @@ void S3Processor::onSchedule(const 
std::shared_ptr<core::ProcessContext>& contex
 
   if (auto communications_timeout = 
context->getProperty<core::TimePeriodValue>(CommunicationsTimeout)) {
     logger_->log_debug("S3Processor: Communications Timeout %" PRId64 " ms", 
communications_timeout->getMilliseconds().count());
-    client_config_->connectTimeoutMs = 
gsl::narrow<int64_t>(communications_timeout->getMilliseconds().count());
+    client_config_->connectTimeoutMs = 
gsl::narrow<long>(communications_timeout->getMilliseconds().count());  // 
NOLINT(runtime/int)
   } else {
     throw Exception(PROCESS_SCHEDULE_EXCEPTION, "Communications Timeout 
missing or invalid");
   }
diff --git a/extensions/aws/processors/S3Processor.h 
b/extensions/aws/processors/S3Processor.h
index 86cd84fea..d6ce8f848 100644
--- a/extensions/aws/processors/S3Processor.h
+++ b/extensions/aws/processors/S3Processor.h
@@ -25,6 +25,7 @@
 #include <optional>
 #include <set>
 #include <string>
+#include <string_view>
 #include <utility>
 
 #include "aws/core/auth/AWSCredentialsProvider.h"
diff --git a/extensions/aws/s3/S3Wrapper.cpp b/extensions/aws/s3/S3Wrapper.cpp
index 059332233..2e9e27ace 100644
--- a/extensions/aws/s3/S3Wrapper.cpp
+++ b/extensions/aws/s3/S3Wrapper.cpp
@@ -129,7 +129,7 @@ std::optional<S3Wrapper::UploadPartsResult> 
S3Wrapper::uploadParts(const PutObje
     auto upload_part_request = Aws::S3::Model::UploadPartRequest{}
       .WithBucket(put_object_params.bucket)
       .WithKey(put_object_params.object_key)
-      .WithPartNumber(part_number)
+      .WithPartNumber(gsl::narrow<int>(part_number))
       .WithUploadId(upload_state.upload_id);
     upload_part_request.SetBody(stream_ptr);
 
@@ -164,7 +164,7 @@ 
std::optional<Aws::S3::Model::CompleteMultipartUploadResult> S3Wrapper::complete
   for (size_t i = 0; i < upload_parts_result.part_etags.size(); ++i) {
     auto part = Aws::S3::Model::CompletedPart{}
       .WithETag(upload_parts_result.part_etags[i])
-      .WithPartNumber(i + 1);
+      .WithPartNumber(gsl::narrow<int>(i + 1));
     completed_multipart_upload.AddParts(part);
   }
 
diff --git a/extensions/azure/storage/AzureDataLakeStorageClient.cpp 
b/extensions/azure/storage/AzureDataLakeStorageClient.cpp
index 0b5e97079..7f588139f 100644
--- a/extensions/azure/storage/AzureDataLakeStorageClient.cpp
+++ b/extensions/azure/storage/AzureDataLakeStorageClient.cpp
@@ -39,7 +39,7 @@ 
std::unique_ptr<Azure::Storage::Files::DataLake::DataLakeFileSystemClient> Azure
     const AzureStorageCredentials& credentials, const std::string& 
file_system_name, std::optional<uint64_t> number_of_retries) {
   Azure::Storage::Files::DataLake::DataLakeClientOptions options;
   if (number_of_retries) {
-    options.Retry.MaxRetries = *number_of_retries;
+    options.Retry.MaxRetries = gsl::narrow<int32_t>(*number_of_retries);
   }
 
   if (credentials.getUseManagedIdentityCredentials()) {
@@ -89,7 +89,7 @@ std::unique_ptr<io::InputStream> 
AzureDataLakeStorageClient::fetchFile(const Fet
   if (params.range_start || params.range_length) {
     Azure::Core::Http::HttpRange range;
     if (params.range_start) {
-      range.Offset = *params.range_start;
+      range.Offset = gsl::narrow<int64_t>(*params.range_start);
     }
 
     if (params.range_length) {
diff --git a/extensions/elasticsearch/PostElasticsearch.cpp 
b/extensions/elasticsearch/PostElasticsearch.cpp
index a0f0f3740..62202b974 100644
--- a/extensions/elasticsearch/PostElasticsearch.cpp
+++ b/extensions/elasticsearch/PostElasticsearch.cpp
@@ -142,15 +142,15 @@ class ElasticPayload {
   [[nodiscard]] std::string headerString() const {
     rapidjson::Document first_line = 
rapidjson::Document(rapidjson::kObjectType);
 
-    auto operation_index_key = rapidjson::Value(operation_.data(), 
operation_.size());
+    auto operation_index_key = rapidjson::Value(operation_.data(), 
gsl::narrow<rapidjson::SizeType>(operation_.size()));
     first_line.AddMember(operation_index_key, 
rapidjson::Value{rapidjson::kObjectType}, first_line.GetAllocator());
     auto& operation_request = first_line[operation_.c_str()];
 
-    auto index_json = rapidjson::Value(index_.data(), index_.size());
+    auto index_json = rapidjson::Value(index_.data(), 
gsl::narrow<rapidjson::SizeType>(index_.size()));
     operation_request.AddMember("_index", index_json, 
first_line.GetAllocator());
 
     if (id_) {
-      auto id_json = rapidjson::Value(id_->data(), id_->size());
+      auto id_json = rapidjson::Value(id_->data(), 
gsl::narrow<rapidjson::SizeType>(id_->size()));
       operation_request.AddMember("_id", id_json, first_line.GetAllocator());
     }
 
@@ -211,7 +211,7 @@ void processResponseFromElastic(const rapidjson::Document& 
response, core::Proce
   auto& items = response["items"];
   gsl_Expects(items.IsArray());
   gsl_Expects(items.Size() == flowfiles_sent.size());
-  for (size_t i = 0; i < items.Size(); ++i) {
+  for (rapidjson::SizeType i = 0; i < items.Size(); ++i) {
     gsl_Expects(items[i].IsObject());
     for (auto it = items[i].MemberBegin(); it != items[i].MemberEnd(); ++it) {
       addAttributesFromResponse("elasticsearch", it, *flowfiles_sent[i]);
diff --git a/extensions/expression-language/common/Value.h 
b/extensions/expression-language/common/Value.h
index ea524b77c..69b232fd4 100644
--- a/extensions/expression-language/common/Value.h
+++ b/extensions/expression-language/common/Value.h
@@ -142,9 +142,9 @@ class Value {
     if (value.empty()) return default_value;
     try {
       return std::invoke(conversion_function, value);
-    } catch (const std::invalid_argument& ex) {
+    } catch (const std::invalid_argument&) {
       throw std::invalid_argument{utils::StringUtils::join_pack(context, " 
failed to parse \"", value, "\": invalid argument")};
-    } catch (const std::out_of_range& ex) {
+    } catch (const std::out_of_range&) {
       throw std::out_of_range{utils::StringUtils::join_pack(context, " failed 
to parse \"", value, "\": out of range")};
     }
   }
diff --git a/extensions/libarchive/WriteArchiveStream.cpp 
b/extensions/libarchive/WriteArchiveStream.cpp
index 4c60233d8..98b9122d1 100644
--- a/extensions/libarchive/WriteArchiveStream.cpp
+++ b/extensions/libarchive/WriteArchiveStream.cpp
@@ -30,7 +30,7 @@ WriteArchiveStreamImpl::archive_ptr 
WriteArchiveStreamImpl::createWriteArchive()
     return nullptr;
   }
 
-  int result;
+  int result = 0;
 
   result = archive_write_set_format_ustar(arch.get());
   if (result != ARCHIVE_OK) {
@@ -94,7 +94,7 @@ bool WriteArchiveStreamImpl::newEntry(const EntryInfo& info) {
     return false;
   }
   archive_entry_set_pathname(arch_entry_.get(), info.filename.c_str());
-  archive_entry_set_size(arch_entry_.get(), info.size);
+  archive_entry_set_size(arch_entry_.get(), 
gsl::narrow<la_int64_t>(info.size));
   archive_entry_set_mode(arch_entry_.get(), S_IFREG | 0755);
 
   int result = archive_write_header(arch_.get(), arch_entry_.get());
@@ -115,7 +115,7 @@ size_t WriteArchiveStreamImpl::write(const uint8_t* data, 
size_t len) {
   }
   gsl_Expects(data);
 
-  int result = archive_write_data(arch_.get(), data, len);
+  int result = gsl::narrow<int>(archive_write_data(arch_.get(), data, len));
   if (result < 0) {
     logger_->log_error("Archive write data error %s", 
archive_error_string(arch_.get()));
     arch_entry_.reset();
diff --git a/extensions/libarchive/tests/MergeFileTests.cpp 
b/extensions/libarchive/tests/MergeFileTests.cpp
index af43a801b..d2699799e 100644
--- a/extensions/libarchive/tests/MergeFileTests.cpp
+++ b/extensions/libarchive/tests/MergeFileTests.cpp
@@ -90,9 +90,9 @@ class FixedBuffer {
   }
 
   template<class Input>
-  int write(Input& input, std::size_t len) {
+  int64_t write(Input& input, std::size_t len) {
     REQUIRE(size_ + len <= capacity_);
-    int total_read = 0;
+    size_t total_read = 0;
     do {
       const size_t ret{input.read(as_writable_bytes(std::span(end(), len)))};
       if (ret == 0) break;
@@ -101,8 +101,9 @@ class FixedBuffer {
       len -= ret;
       total_read += ret;
     } while (size_ != capacity_);
-    return total_read;
+    return gsl::narrow<int64_t>(total_read);
   }
+
   int64_t operator()(const std::shared_ptr<minifi::io::InputStream>& stream) {
     return write(*stream, capacity_);
   }
@@ -132,7 +133,7 @@ std::vector<FixedBuffer> read_archives(const FixedBuffer& 
input) {
   struct archive_entry *ae = nullptr;
 
   while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
-    int size = gsl::narrow<int>(archive_entry_size(ae));
+    int64_t size{archive_entry_size(ae)};
     FixedBuffer buf(size);
     ArchiveEntryReader reader(a);
     auto ret = buf.write(reader, buf.capacity());
diff --git a/extensions/librdkafka/ConsumeKafka.cpp 
b/extensions/librdkafka/ConsumeKafka.cpp
index dfab503a3..a2823488f 100644
--- a/extensions/librdkafka/ConsumeKafka.cpp
+++ b/extensions/librdkafka/ConsumeKafka.cpp
@@ -113,7 +113,7 @@ void rebalance_cb(rd_kafka_t* rk, rd_kafka_resp_err_t 
trigger, rd_kafka_topic_pa
 }  // namespace
 
 void ConsumeKafka::create_topic_partition_list() {
-  kf_topic_partition_list_ = { 
rd_kafka_topic_partition_list_new(topic_names_.size()), 
utils::rd_kafka_topic_partition_list_deleter() };
+  kf_topic_partition_list_ = { 
rd_kafka_topic_partition_list_new(gsl::narrow<int>(topic_names_.size())), 
utils::rd_kafka_topic_partition_list_deleter() };
 
   // On subscriptions any topics prefixed with ^ will be regex matched
   if (utils::StringUtils::equalsIgnoreCase(TOPIC_FORMAT_PATTERNS, 
topic_name_format_)) {
@@ -229,8 +229,8 @@ std::vector<std::unique_ptr<rd_kafka_message_t, 
utils::rd_kafka_message_deleter>
   auto elapsed = std::chrono::steady_clock::now() - start;
   while (messages.size() < max_poll_records_ && elapsed < 
max_poll_time_milliseconds_) {
     logger_->log_debug("Polling for new messages for %d milliseconds...", 
max_poll_time_milliseconds_.count());
-    std::unique_ptr<rd_kafka_message_t, utils::rd_kafka_message_deleter>
-      message { rd_kafka_consumer_poll(consumer_.get(), 
std::chrono::duration_cast<std::chrono::milliseconds>(max_poll_time_milliseconds_
 - elapsed).count()), utils::rd_kafka_message_deleter() };
+    const auto timeout_ms = 
gsl::narrow<int>(std::chrono::duration_cast<std::chrono::milliseconds>(max_poll_time_milliseconds_
 - elapsed).count());
+    std::unique_ptr<rd_kafka_message_t, utils::rd_kafka_message_deleter> 
message{rd_kafka_consumer_poll(consumer_.get(), timeout_ms)};
     if (!message) {
       break;
     }
@@ -281,7 +281,7 @@ std::string ConsumeKafka::resolve_duplicate_headers(const 
std::vector<std::strin
 std::vector<std::string> ConsumeKafka::get_matching_headers(const 
rd_kafka_message_t& message, const std::string& header_name) const {
   // Headers fetched this way are freed when rd_kafka_message_destroy is called
   // Detaching them using rd_kafka_message_detach_headers does not seem to work
-  rd_kafka_headers_t* headers_raw;
+  rd_kafka_headers_t* headers_raw = nullptr;
   const rd_kafka_resp_err_t get_header_response = 
rd_kafka_message_headers(&message, &headers_raw);
   if (RD_KAFKA_RESP_ERR__NOENT == get_header_response) {
     return {};
@@ -291,8 +291,8 @@ std::vector<std::string> 
ConsumeKafka::get_matching_headers(const rd_kafka_messa
   }
   std::vector<std::string> matching_headers;
   for (std::size_t header_idx = 0;; ++header_idx) {
-    const char* value;  // Not to be freed
-    std::size_t size;
+    const char* value = nullptr;  // Not to be freed
+    std::size_t size = 0;
     if (RD_KAFKA_RESP_ERR_NO_ERROR != rd_kafka_header_get(headers_raw, 
header_idx, header_name.c_str(), (const void**)(&value), &size)) {
       break;
     }
diff --git a/extensions/librdkafka/PublishKafka.cpp 
b/extensions/librdkafka/PublishKafka.cpp
index 626feb784..d5dd5b758 100644
--- a/extensions/librdkafka/PublishKafka.cpp
+++ b/extensions/librdkafka/PublishKafka.cpp
@@ -306,7 +306,7 @@ class ReadCallback {
         error_ = rd_kafka_err2str(err);
         return read_size_;
       }
-      read_size_ += readRet;
+      read_size_ += gsl::narrow<uint32_t>(readRet);
     }
     return read_size_;
   }
diff --git a/extensions/mqtt/processors/PublishMQTT.cpp 
b/extensions/mqtt/processors/PublishMQTT.cpp
index 03fe3ab95..9ede561fa 100644
--- a/extensions/mqtt/processors/PublishMQTT.cpp
+++ b/extensions/mqtt/processors/PublishMQTT.cpp
@@ -216,7 +216,7 @@ void PublishMQTT::setMqtt5Properties(MQTTAsync_message& 
message, const std::stri
   if (message_expiry_interval_.has_value()) {
     MQTTProperty property;
     property.identifier = MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL;
-    property.value.integer4 = message_expiry_interval_->count();  // 
NOLINT(cppcoreguidelines-pro-type-union-access)
+    property.value.integer4 = 
gsl::narrow<int>(message_expiry_interval_->count());  // 
NOLINT(cppcoreguidelines-pro-type-union-access)
     MQTTProperties_add(&message.properties, &property);
   }
 
diff --git a/extensions/pdh/PDHCounters.cpp b/extensions/pdh/PDHCounters.cpp
index 1b880a091..d9a003b25 100644
--- a/extensions/pdh/PDHCounters.cpp
+++ b/extensions/pdh/PDHCounters.cpp
@@ -55,7 +55,7 @@ std::string PDHCounter::getCounterName() const {
 }
 
 void SinglePDHCounter::addToJson(rapidjson::Value& body, 
rapidjson::Document::AllocatorType& alloc) const {
-  rapidjson::Value key(getCounterName().c_str(), getCounterName().length(), 
alloc);
+  rapidjson::Value key(getCounterName().c_str(), 
gsl::narrow<rapidjson::SizeType>(getCounterName().length()), alloc);
   rapidjson::Value& group_node = acquireNode(getObjectName(), body, alloc);
   group_node.AddMember(key, getValue(), alloc);
 }
@@ -91,7 +91,7 @@ void PDHCounterArray::addToJson(rapidjson::Value& body, 
rapidjson::Document::All
     rapidjson::Value& counter_node = acquireNode(node_name, group_node, alloc);
     rapidjson::Value value = getValue(i);
     rapidjson::Value key;
-    key.SetString(getCounterName().c_str(), getCounterName().length(), alloc);
+    key.SetString(getCounterName().c_str(), 
gsl::narrow<rapidjson::SizeType>(getCounterName().length()), alloc);
     counter_node.AddMember(key, value, alloc);
   }
 }
diff --git a/extensions/python/tests/PythonManifestTests.cpp 
b/extensions/python/tests/PythonManifestTests.cpp
index 2867f125b..5ec989ae9 100644
--- a/extensions/python/tests/PythonManifestTests.cpp
+++ b/extensions/python/tests/PythonManifestTests.cpp
@@ -25,6 +25,7 @@
 #include "flow-tests/TestControllerWithFlow.h"
 #include "EmptyFlow.h"
 #include "c2/C2MetricsPublisher.h"
+#include "utils/gsl.h"
 
 using minifi::state::response::SerializedResponseNode;
 
@@ -40,7 +41,7 @@ const SerializedResponseNode& getNode(const 
std::vector<SerializedResponseNode>&
   for (auto& node : nodes) {
     if (node.name == name) return node;
   }
-  assert(false);
+  gsl_FailFast();
 }
 
 TEST_CASE("Python processor's description is part of the manifest") {
diff --git a/extensions/smb/tests/SmbConnectionControllerServiceTests.cpp 
b/extensions/smb/tests/SmbConnectionControllerServiceTests.cpp
index d0aadd451..3ac0b4f63 100644
--- a/extensions/smb/tests/SmbConnectionControllerServiceTests.cpp
+++ b/extensions/smb/tests/SmbConnectionControllerServiceTests.cpp
@@ -20,6 +20,7 @@
 #include "Catch.h"
 #include "SmbConnectionControllerService.h"
 #include "utils/TempSmbShare.h"
+#include "utils/UnicodeConversion.h"
 
 namespace org::apache::nifi::minifi::extensions::smb::test {
 
@@ -49,7 +50,7 @@ TEST_CASE_METHOD(SmbConnectionControllerServiceFixture, 
"SmbConnectionController
 
   SECTION("Valid share") {
     plan_->setProperty(smb_connection_node_, 
SmbConnectionControllerService::Hostname, "localhost");
-    plan_->setProperty(smb_connection_node_, 
SmbConnectionControllerService::Share, 
minifi::utils::OsUtils::wideStringToString(share_local_name));
+    plan_->setProperty(smb_connection_node_, 
SmbConnectionControllerService::Share, 
minifi::utils::to_string(share_local_name));
 
     REQUIRE_NOTHROW(plan_->finalize());
 
diff --git a/extensions/sql/data/JSONSQLWriter.cpp 
b/extensions/sql/data/JSONSQLWriter.cpp
index 1c61a7b83..d77ff2741 100644
--- a/extensions/sql/data/JSONSQLWriter.cpp
+++ b/extensions/sql/data/JSONSQLWriter.cpp
@@ -22,11 +22,7 @@
 #include "rapidjson/prettywriter.h"
 #include "Exception.h"
 
-namespace org {
-namespace apache {
-namespace nifi {
-namespace minifi {
-namespace sql {
+namespace org::apache::nifi::minifi::sql {
 
 JSONSQLWriter::JSONSQLWriter(bool pretty, ColumnFilter column_filter)
   : pretty_(pretty), current_batch_(rapidjson::kArrayType), 
column_filter_(std::move(column_filter)) {
@@ -83,7 +79,7 @@ void JSONSQLWriter::addToJSONRow(const std::string& 
column_name, rapidjson::Valu
 
 rapidjson::Value JSONSQLWriter::toJSONString(const std::string& s) {
   rapidjson::Value jsonValue;
-  jsonValue.SetString(s.c_str(), s.size(), current_batch_.GetAllocator());
+  jsonValue.SetString(s.c_str(), gsl::narrow<rapidjson::SizeType>(s.size()), 
current_batch_.GetAllocator());
 
   return jsonValue;
 }
@@ -102,8 +98,4 @@ std::string JSONSQLWriter::toString() {
   return {buffer.GetString(), buffer.GetSize()};
 }
 
-}  // namespace sql
-}  // namespace minifi
-}  // namespace nifi
-}  // namespace apache
-}  // namespace org
+}  // namespace org::apache::nifi::minifi::sql
diff --git a/extensions/sql/data/JSONSQLWriter.h 
b/extensions/sql/data/JSONSQLWriter.h
index e4e9af433..966c1b8f7 100644
--- a/extensions/sql/data/JSONSQLWriter.h
+++ b/extensions/sql/data/JSONSQLWriter.h
@@ -24,11 +24,7 @@
 
 #include "SQLWriter.h"
 
-namespace org {
-namespace apache {
-namespace nifi {
-namespace minifi {
-namespace sql {
+namespace org::apache::nifi::minifi::sql {
 
 class JSONSQLWriter: public SQLWriter {
  public:
@@ -63,10 +59,4 @@ private:
   ColumnFilter column_filter_;
 };
 
-} /* namespace sql */
-} /* namespace minifi */
-} /* namespace nifi */
-} /* namespace apache */
-} /* namespace org */
-
-
+}  // namespace org::apache::nifi::minifi::sql
diff --git a/extensions/standard-processors/processors/PutTCP.cpp 
b/extensions/standard-processors/processors/PutTCP.cpp
index 4c80721c5..8bef0e0ac 100644
--- a/extensions/standard-processors/processors/PutTCP.cpp
+++ b/extensions/standard-processors/processors/PutTCP.cpp
@@ -215,7 +215,7 @@ asio::awaitable<std::error_code> 
ConnectionHandler<SocketType>::establishNewConn
       continue;
     }
     if (max_size_of_socket_send_buffer_)
-      
socket.lowest_layer().set_option(TcpSocket::send_buffer_size(*max_size_of_socket_send_buffer_));
+      
socket.lowest_layer().set_option(TcpSocket::send_buffer_size(gsl::narrow<int>(*max_size_of_socket_send_buffer_)));
     socket_.emplace(std::move(socket));
     co_return std::error_code();
   }
diff --git a/extensions/windows-event-log/Bookmark.cpp 
b/extensions/windows-event-log/Bookmark.cpp
index dcdaadde5..dc75fac65 100644
--- a/extensions/windows-event-log/Bookmark.cpp
+++ b/extensions/windows-event-log/Bookmark.cpp
@@ -23,9 +23,9 @@
 #include <utility>
 #include <fstream>
 
-#include "wel/UnicodeConversion.h"
 #include "utils/file/FileUtils.h"
 #include "utils/OsUtils.h"
+#include "utils/UnicodeConversion.h"
 
 namespace org::apache::nifi::minifi::processors {
 static const std::string BOOKMARK_KEY = "bookmark";
@@ -41,7 +41,7 @@ Bookmark::Bookmark(const wel::EventPath& path,
       state_manager_(state_manager) {
   std::unordered_map<std::string, std::string> state_map;
   if (state_manager_->get(state_map) && state_map.count(BOOKMARK_KEY) == 1U) {
-    bookmarkXml_ = wel::to_wstring(state_map[BOOKMARK_KEY].c_str());
+    bookmarkXml_ = utils::to_wstring(state_map[BOOKMARK_KEY]);
   } else if (!bookmarkRootDir.empty()) {
     filePath_ = bookmarkRootDir / "uuid" / uuid.to_string().view() / 
"Bookmark.txt";
 
@@ -122,7 +122,7 @@ bool Bookmark::saveBookmarkXml(const std::wstring& 
bookmarkXml) {
   bookmarkXml_ = bookmarkXml;
 
   std::unordered_map<std::string, std::string> state_map;
-  state_map[BOOKMARK_KEY] = wel::to_string(bookmarkXml_.c_str());
+  state_map[BOOKMARK_KEY] = utils::to_string(bookmarkXml_);
 
   return state_manager_->set(state_map);
 }
diff --git a/extensions/windows-event-log/CollectorInitiatedSubscription.cpp 
b/extensions/windows-event-log/CollectorInitiatedSubscription.cpp
index 036fbcb8b..6088332d8 100644
--- a/extensions/windows-event-log/CollectorInitiatedSubscription.cpp
+++ b/extensions/windows-event-log/CollectorInitiatedSubscription.cpp
@@ -112,7 +112,7 @@ void CollectorInitiatedSubscription::onTrigger(const 
std::shared_ptr<core::Proce
   } else if (auto inactive_duration_to_reconnect_ms = 
context->getProperty<core::TimePeriodValue>(InactiveDurationToReconnect)
              | utils::transform([](const auto& time_period_value) { return 
time_period_value.getMilliseconds().count(); });
              inactive_duration_to_reconnect_ms && 
*inactive_duration_to_reconnect_ms > 0) {
-    if ((now - lastActivityTimestamp_) > *inactive_duration_to_reconnect_ms) {
+    if ((now - lastActivityTimestamp_) > 
gsl::narrow<uint64_t>(*inactive_duration_to_reconnect_ms)) {
       logger_->log_info("Exceeds configured 'inactive duration to reconnect' 
%lld ms. Unsubscribe to reconnect..", *inactive_duration_to_reconnect_ms);
       unsubscribe();
     }
diff --git a/extensions/windows-event-log/ConsumeWindowsEventLog.cpp 
b/extensions/windows-event-log/ConsumeWindowsEventLog.cpp
index 927c72542..6fc0c5ff5 100644
--- a/extensions/windows-event-log/ConsumeWindowsEventLog.cpp
+++ b/extensions/windows-event-log/ConsumeWindowsEventLog.cpp
@@ -36,16 +36,16 @@
 #include "wel/LookupCacher.h"
 #include "wel/MetadataWalker.h"
 #include "wel/XMLString.h"
-#include "wel/UnicodeConversion.h"
 #include "wel/JSONUtils.h"
+#include "wel/UniqueEvtHandle.h"
 
 #include "io/BufferStream.h"
 #include "core/ProcessContext.h"
 #include "core/ProcessSession.h"
 #include "core/Resource.h"
 #include "Bookmark.h"
-#include "wel/UniqueEvtHandle.h"
 #include "utils/Deleters.h"
+#include "utils/UnicodeConversion.h"
 #include "logging/LoggerConfiguration.h"
 
 #include "utils/gsl.h"
@@ -445,7 +445,7 @@ nonstd::expected<std::string, std::string> 
ConsumeWindowsEventLog::renderEventAs
     }
   }
   logger_->log_trace("Event rendered with size %" PRIu32, used);
-  return wel::to_string(buf.get());
+  return utils::to_string(std::wstring{buf.get()});
 }
 
 nonstd::expected<cwel::EventRender, std::string> 
ConsumeWindowsEventLog::createEventRender(EVT_HANDLE hEvent) {
@@ -573,7 +573,7 @@ void ConsumeWindowsEventLog::refreshTimeZoneData() {
   tzoffset << (tzbias >= 0 ? '+' : '-') << std::setfill('0') << std::setw(2) 
<< std::abs(tzbias) / 60
       << ":" << std::setfill('0') << std::setw(2) << std::abs(tzbias) % 60;
 
-  timezone_name_ = wel::to_string(tzstr.c_str());
+  timezone_name_ = utils::to_string(tzstr);
   timezone_offset_ = tzoffset.str();
 
   logger_->log_trace("Timezone name: %s, offset: %s", timezone_name_, 
timezone_offset_);
diff --git a/extensions/windows-event-log/tests/CWELTestUtils.h 
b/extensions/windows-event-log/tests/CWELTestUtils.h
index 01d3effad..d3aa867af 100644
--- a/extensions/windows-event-log/tests/CWELTestUtils.h
+++ b/extensions/windows-event-log/tests/CWELTestUtils.h
@@ -28,7 +28,9 @@
 #include "processors/PutFile.h"
 #include "TestBase.h"
 #include "Catch.h"
+#include "utils/StringUtils.h"
 #include "utils/TestUtils.h"
+#include "utils/UnicodeConversion.h"
 #include "utils/file/FileUtils.h"
 #include "utils/gsl.h"
 
@@ -97,7 +99,8 @@ class OutputFormatTestController : public TestController {
 };
 
 void generateLogFile(const std::wstring& channel, const std::filesystem::path& 
path) {
-  HANDLE event_log = OpenEventLog(NULL, std::string(channel.begin(), 
channel.end()).c_str());
+  const auto channel_as_string = utils::to_string(channel);
+  HANDLE event_log = OpenEventLog(NULL, channel_as_string.c_str());
   auto guard = gsl::finally([&] {CloseEventLog(event_log);});
 
   if (!EvtExportLog(NULL, channel.c_str(), L"*", path.wstring().c_str(), 
EvtExportLogChannelPath)) {
diff --git a/extensions/windows-event-log/wel/EventPath.cpp 
b/extensions/windows-event-log/wel/EventPath.cpp
index adc4d9ad1..b190b20f5 100644
--- a/extensions/windows-event-log/wel/EventPath.cpp
+++ b/extensions/windows-event-log/wel/EventPath.cpp
@@ -19,10 +19,11 @@
 #include "EventPath.h"
 #include <utility>
 #include "utils/StringUtils.h"
+#include "utils/UnicodeConversion.h"
 
 namespace org::apache::nifi::minifi::wel {
 
-EventPath::EventPath(std::wstring wstr) : EventPath(std::string(wstr.begin(), 
wstr.end())) {}
+EventPath::EventPath(const std::wstring& wstr) : 
EventPath(utils::to_string(wstr)) {}
 
 EventPath::EventPath(std::string str) {
   constexpr std::string_view saved_log_prefix = "SavedLog:";
diff --git a/extensions/windows-event-log/wel/EventPath.h 
b/extensions/windows-event-log/wel/EventPath.h
index 5b4c295d6..dea8d60dc 100644
--- a/extensions/windows-event-log/wel/EventPath.h
+++ b/extensions/windows-event-log/wel/EventPath.h
@@ -20,8 +20,11 @@
 
 #include <windows.h>
 #include <winevt.h>
+
 #include <string>
 
+#include "utils/gsl.h"
+
 namespace org::apache::nifi::minifi::wel {
 
 class EventPath {
@@ -32,26 +35,27 @@ class EventPath {
   };
 
   EventPath() = default;
-  explicit EventPath(std::wstring wstr);
+  explicit EventPath(const std::wstring& wstr);
   explicit EventPath(std::string str);
 
-  constexpr const std::wstring& wstr() const noexcept {
+  [[nodiscard]] constexpr const std::wstring& wstr() const noexcept {
     return wstr_;
   }
 
-  constexpr const std::string& str() const noexcept {
+  [[nodiscard]] constexpr const std::string& str() const noexcept {
     return str_;
   }
 
-  constexpr EventPath::Kind kind() const noexcept {
+  [[nodiscard]] constexpr EventPath::Kind kind() const noexcept {
     return kind_;
   }
 
-  constexpr EVT_QUERY_FLAGS getQueryFlags() const noexcept {
+  [[nodiscard]] constexpr EVT_QUERY_FLAGS getQueryFlags() const noexcept {
     switch (kind_) {
       case Kind::CHANNEL: return EvtQueryChannelPath;
       case Kind::FILE: return EvtQueryFilePath;
     }
+    gsl_FailFast();
   }
 
  private:
diff --git a/extensions/windows-event-log/wel/WindowsEventLog.cpp 
b/extensions/windows-event-log/wel/WindowsEventLog.cpp
index ce10b91d0..0140ee707 100644
--- a/extensions/windows-event-log/wel/WindowsEventLog.cpp
+++ b/extensions/windows-event-log/wel/WindowsEventLog.cpp
@@ -15,6 +15,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include "WindowsEventLog.h"
+
 #include <winmeta.h>
 
 #include <algorithm>
@@ -22,10 +24,9 @@
 #include <memory>
 #include <string>
 
-#include "WindowsEventLog.h"
-#include "UnicodeConversion.h"
 #include "utils/Deleters.h"
 #include "utils/gsl.h"
+#include "utils/UnicodeConversion.h"
 #include "UniqueEvtHandle.h"
 
 namespace org::apache::nifi::minifi::wel {
@@ -141,9 +142,7 @@ std::string 
WindowsEventLogMetadataImpl::getEventData(EVT_FORMAT_MESSAGE_FLAGS f
   if (EvtFormatMessageKeyword == flags) {
     buffer.get()[num_chars_used - 1] = L'\0';
   }
-  std::wstring str(buffer.get());
-  event_data = std::string(str.begin(), str.end());
-  return event_data;
+  return utils::to_string(std::wstring{buffer.get()});
 }
 
 nonstd::expected<std::string, std::error_code> 
WindowsEventLogHandler::getEventMessage(EVT_HANDLE eventHandle) const {
@@ -156,7 +155,7 @@ nonstd::expected<std::string, std::error_code> 
WindowsEventLogHandler::getEventM
 
   bool evt_format_succeeded = EvtFormatMessage(metadata_provider_.get(), 
eventHandle, 0, 0, nullptr, EvtFormatMessageEvent, num_chars_in_buffer, 
buffer.get(), &num_chars_used);
   if (evt_format_succeeded)
-    return to_string(buffer.get());
+    return utils::to_string(std::wstring{buffer.get()});
 
   DWORD status = GetLastError();
 
@@ -170,7 +169,7 @@ nonstd::expected<std::string, std::error_code> 
WindowsEventLogHandler::getEventM
   if (EvtFormatMessage(metadata_provider_.get(), eventHandle, 0, 0, nullptr,
                        EvtFormatMessageEvent, num_chars_in_buffer,
                        buffer.get(), &num_chars_used))
-    return to_string(buffer.get());
+    return utils::to_string(std::wstring{buffer.get()});
   return 
nonstd::make_unexpected(utils::OsUtils::windowsErrorToErrorCode(GetLastError()));
 }
 
diff --git a/libminifi/include/core/PropertyType.h 
b/libminifi/include/core/PropertyType.h
index 880e35fdf..e7c86f222 100644
--- a/libminifi/include/core/PropertyType.h
+++ b/libminifi/include/core/PropertyType.h
@@ -138,7 +138,7 @@ class IntegerPropertyType : public PropertyType {
 
   [[nodiscard]] ValidationResult validate(const std::string &subject, const 
std::string &input) const override {
     try {
-      std::stoi(input);
+      (void) std::stoi(input);
       return ValidationResult{.valid = true, .subject = subject, .input = 
input};
     } catch (...) {
     }
@@ -164,7 +164,7 @@ class UnsignedIntPropertyType : public PropertyType {
       if (negative) {
         throw std::out_of_range("non negative expected");
       }
-      std::stoul(input);
+      (void) std::stoul(input);
       return ValidationResult{.valid = true, .subject = subject, .input = 
input};
     } catch (...) {
     }
diff --git a/libminifi/include/utils/OpenTelemetryLogDataModelUtils.h 
b/libminifi/include/utils/OpenTelemetryLogDataModelUtils.h
index 5385e9e6f..c9c639116 100644
--- a/libminifi/include/utils/OpenTelemetryLogDataModelUtils.h
+++ b/libminifi/include/utils/OpenTelemetryLogDataModelUtils.h
@@ -29,7 +29,7 @@ class OpenTelemetryLogDataModel {
  public:
   static void appendEventInformation(rapidjson::Document& root, const 
std::string& event_identifier) {
     rapidjson::Value name;
-    name.SetString(event_identifier.c_str(), event_identifier.length(), 
root.GetAllocator());
+    name.SetString(event_identifier.c_str(), 
gsl::narrow<rapidjson::SizeType>(event_identifier.length()), 
root.GetAllocator());
     root.AddMember("Name", name, root.GetAllocator());
     root.AddMember("Timestamp", rapidjson::Value().SetInt64(std::time(0)), 
root.GetAllocator());
   }
@@ -48,7 +48,7 @@ class OpenTelemetryLogDataModel {
   static void appendHostName(rapidjson::Value& resource, 
rapidjson::Document::AllocatorType& allocator) {
     std::string hostname = utils::net::getMyHostName();
     rapidjson::Value hostname_value;
-    hostname_value.SetString(hostname.c_str(), hostname.length(), allocator);
+    hostname_value.SetString(hostname.c_str(), 
gsl::narrow<rapidjson::SizeType>(hostname.length()), allocator);
     resource.AddMember("host.hostname", hostname_value, allocator);
   }
 
@@ -57,14 +57,14 @@ class OpenTelemetryLogDataModel {
     rapidjson::Value& ip = resource["host.ip"];
     auto network_interface_infos = 
utils::NetworkInterfaceInfo::getNetworkInterfaceInfos();
     for (const auto& network_interface_info : network_interface_infos) {
-      rapidjson::Value 
interface_name(network_interface_info.getName().c_str(), 
network_interface_info.getName().length(), alloc);
+      rapidjson::Value 
interface_name(network_interface_info.getName().c_str(), 
gsl::narrow<rapidjson::SizeType>(network_interface_info.getName().length()), 
alloc);
       rapidjson::Value interface_address_array(rapidjson::kArrayType);
       for (auto& ip_v4_address : network_interface_info.getIpV4Addresses()) {
-        rapidjson::Value address_value(ip_v4_address.c_str(), 
ip_v4_address.length(), alloc);
+        rapidjson::Value address_value(ip_v4_address.c_str(), 
gsl::narrow<rapidjson::SizeType>(ip_v4_address.length()), alloc);
         interface_address_array.PushBack(address_value.Move(), alloc);
       }
       for (auto& ip_v6_address : network_interface_info.getIpV6Addresses()) {
-        rapidjson::Value address_value(ip_v6_address.c_str(), 
ip_v6_address.length(), alloc);
+        rapidjson::Value address_value(ip_v6_address.c_str(), 
gsl::narrow<rapidjson::SizeType>(ip_v6_address.length()), alloc);
         interface_address_array.PushBack(address_value.Move(), alloc);
       }
       ip.AddMember(interface_name, interface_address_array, alloc);
diff --git a/libminifi/include/utils/OsUtils.h 
b/libminifi/include/utils/OsUtils.h
index 0f7305279..837806749 100644
--- a/libminifi/include/utils/OsUtils.h
+++ b/libminifi/include/utils/OsUtils.h
@@ -51,10 +51,6 @@ std::string getMachineArchitecture();
 #ifdef WIN32
 /// Resolves common identifiers
 extern std::string resolve_common_identifiers(const std::string &id);
-
-std::wstring stringToWideString(const std::string& string);
-
-std::string wideStringToString(const std::wstring& wide_string);
 #endif
 
 std::optional<std::string> getHostName();
diff --git a/libminifi/include/utils/TestUtils.h 
b/libminifi/include/utils/TestUtils.h
index 367bdf2da..35431164e 100644
--- a/libminifi/include/utils/TestUtils.h
+++ b/libminifi/include/utils/TestUtils.h
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <chrono>
+#include <filesystem>
 #include <fstream>
 #include <memory>
 #include <string>
@@ -51,6 +52,10 @@ std::string getFileContent(const std::filesystem::path& 
file_name) {
   return file_content;
 }
 
+void makeFileOrDirectoryNotWritable(const std::filesystem::path& file_name);
+
+void makeFileOrDirectoryWritable(const std::filesystem::path& file_name);
+
 Identifier generateUUID() {
   // TODO(hunyadi): Will make the Id generator manage lifetime using a 
unique_ptr and return a raw ptr on access
   static std::shared_ptr<utils::IdGenerator> id_generator = 
utils::IdGenerator::getIdGenerator();
diff --git a/extensions/windows-event-log/wel/UnicodeConversion.h 
b/libminifi/include/utils/UnicodeConversion.h
similarity index 68%
rename from extensions/windows-event-log/wel/UnicodeConversion.h
rename to libminifi/include/utils/UnicodeConversion.h
index b382774fc..dfd0e26ef 100644
--- a/extensions/windows-event-log/wel/UnicodeConversion.h
+++ b/libminifi/include/utils/UnicodeConversion.h
@@ -22,25 +22,18 @@
 
 #include <atlbase.h>
 #include <atlconv.h>
-
 #include <string>
 
-namespace org {
-namespace apache {
-namespace nifi {
-namespace minifi {
-namespace wel {
-inline std::string to_string(const wchar_t* pChar) {
-  ATL::CW2A aString(pChar, CP_UTF8);
-  return std::string(aString);
+namespace org::apache::nifi::minifi::utils {
+
+inline std::string to_string(const std::wstring& utf16_string) {
+  ATL::CW2A utf8_string(utf16_string.c_str(), CP_UTF8);
+  return {LPSTR{utf8_string}};
 }
 
-inline std::wstring to_wstring(const char* pChar) {
-  ATL::CA2W wString(pChar, CP_UTF8);
-  return std::wstring(wString);
+inline std::wstring to_wstring(const std::string& utf8_string) {
+  ATL::CA2W utf16_string(utf8_string.c_str(), CP_UTF8);
+  return {LPWSTR{utf16_string}};
 }
-} /* namespace wel */
-} /* namespace minifi */
-} /* namespace nifi */
-} /* namespace apache */
-} /* namespace org */
+
+}  // namespace org::apache::nifi::minifi::utils
diff --git a/libminifi/src/core/logging/LoggerConfiguration.cpp 
b/libminifi/src/core/logging/LoggerConfiguration.cpp
index 87d74ff58..1dac379b5 100644
--- a/libminifi/src/core/logging/LoggerConfiguration.cpp
+++ b/libminifi/src/core/logging/LoggerConfiguration.cpp
@@ -391,7 +391,7 @@ std::shared_ptr<spdlog::sinks::rotating_file_sink_mt> 
LoggerConfiguration::getRo
     }
   }
 
-  int max_file_size = 5_MiB;
+  size_t max_file_size = 5_MiB;
   std::string max_file_size_str;
   if (properties->getString(appender_key + ".max_file_size", 
max_file_size_str)) {
     core::DataSizeValue::StringToInt(max_file_size_str, max_file_size);
diff --git a/libminifi/src/core/logging/alert/AlertSink.cpp 
b/libminifi/src/core/logging/alert/AlertSink.cpp
index 130ec15da..eb97dcaec 100644
--- a/libminifi/src/core/logging/alert/AlertSink.cpp
+++ b/libminifi/src/core/logging/alert/AlertSink.cpp
@@ -203,10 +203,10 @@ void AlertSink::send(Services& services) {
 
   rapidjson::Document doc(rapidjson::kObjectType);
   std::string agent_id = services.agent_id->getAgentIdentifier();
-  doc.AddMember("agentId", rapidjson::Value(agent_id.data(), 
agent_id.length()), doc.GetAllocator());
+  doc.AddMember("agentId", rapidjson::Value(agent_id.data(), 
gsl::narrow<rapidjson::SizeType>(agent_id.length())), doc.GetAllocator());
   doc.AddMember("alerts", rapidjson::Value(rapidjson::kArrayType), 
doc.GetAllocator());
   for (const auto& [log, _] : logs.data_) {
-    doc["alerts"].PushBack(rapidjson::Value(log.data(), log.size()), 
doc.GetAllocator());
+    doc["alerts"].PushBack(rapidjson::Value(log.data(), 
gsl::narrow<rapidjson::SizeType>(log.size())), doc.GetAllocator());
   }
   rapidjson::StringBuffer buffer;
   rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
diff --git a/libminifi/src/io/InputStream.cpp b/libminifi/src/io/InputStream.cpp
index 03aacc389..accb58009 100644
--- a/libminifi/src/io/InputStream.cpp
+++ b/libminifi/src/io/InputStream.cpp
@@ -70,7 +70,7 @@ size_t InputStream::read(std::string &str, bool widen) {
   str.clear();
   str.reserve(string_length);
 
-  auto bytes_to_read = string_length;
+  size_t bytes_to_read{string_length};
   auto zero_return_retry_count = 0;
   while (bytes_to_read > 0) {
     std::vector<std::byte> buffer(bytes_to_read);
diff --git a/libminifi/src/utils/BaseHTTPClient.cpp 
b/libminifi/src/utils/BaseHTTPClient.cpp
index ab2f9eb8c..f53470e35 100644
--- a/libminifi/src/utils/BaseHTTPClient.cpp
+++ b/libminifi/src/utils/BaseHTTPClient.cpp
@@ -41,7 +41,7 @@ std::optional<std::string> parseProtocol(const std::string& 
url_input) {
 
 std::optional<int> parsePortNumber(const std::string& port_string) {
   try {
-    size_t pos;
+    size_t pos = 0;
     int port = std::stoi(port_string, &pos);
     if (pos == port_string.size()) {
       return port;
@@ -94,7 +94,7 @@ URL::URL(const std::string& url_input) {
   std::string::const_iterator current_pos = url_input.begin();
   std::advance(current_pos, protocol_.size());
 
-  constexpr const char HOST_TERMINATORS[] = ":/?#";
+  static constexpr std::string_view HOST_TERMINATORS = ":/?#";
   std::string::const_iterator end_of_host = std::find_first_of(current_pos, 
url_input.end(), std::begin(HOST_TERMINATORS), std::end(HOST_TERMINATORS));
   host_ = std::string{current_pos, end_of_host};
   if (host_.empty()) {
@@ -104,7 +104,7 @@ URL::URL(const std::string& url_input) {
   current_pos = end_of_host;
 
   if (current_pos != url_input.end() && *current_pos == ':') {
-    constexpr const char PORT_TERMINATORS[] = "/?#";
+    static constexpr std::string_view PORT_TERMINATORS = "/?#";
     ++current_pos;
     std::string::const_iterator end_of_port = std::find_first_of(current_pos, 
url_input.end(), std::begin(PORT_TERMINATORS), std::end(PORT_TERMINATORS));
     const auto port_number = parsePortNumber(std::string{current_pos, 
end_of_port});
@@ -204,7 +204,7 @@ int HTTPRequestResponse::seek_callback(void *p, int64_t 
offset, int) {
       return SEEKFUNC_FAIL;
     }
     auto *callback = reinterpret_cast<HTTPUploadCallback *>(p);
-    return callback->setPosition(offset);
+    return gsl::narrow<int>(callback->setPosition(offset));
   } catch (...) {
     return SEEKFUNC_FAIL;
   }
diff --git a/libminifi/src/utils/Cron.cpp b/libminifi/src/utils/Cron.cpp
index 677423a00..5fa8d9ecd 100644
--- a/libminifi/src/utils/Cron.cpp
+++ b/libminifi/src/utils/Cron.cpp
@@ -109,7 +109,7 @@ days parse<days>(const std::string& days_str) {
 
 template <>
 day parse<day>(const std::string& day_str) {
-  if (auto day_int = fromChars<uint64_t>(day_str); day_int && day_int >= 1 && 
day_int <= 31)
+  if (auto day_int = fromChars<unsigned int>(day_str); day_int && day_int >= 1 
&& day_int <= 31)
     return day(*day_int);
   throw BadCronExpression("Invalid day " + day_str);
 }
@@ -142,7 +142,7 @@ weekday parse<weekday>(const std::string& weekday_str) {
     if (!stream.fail() && parsed_weekday.ok() && stream.peek() == EOF)
       return parsed_weekday;
   } else {
-    unsigned weekday_num;
+    unsigned weekday_num = 0;
     stream >> weekday_num;
     if (!stream.fail() && weekday_num < 7 && stream.peek() == EOF)
       return weekday(weekday_num-1);
@@ -152,7 +152,7 @@ weekday parse<weekday>(const std::string& weekday_str) {
 
 template <>
 year parse<year>(const std::string& year_str) {
-  if (auto year_int = fromChars<uint64_t>(year_str); year_int && *year_int >= 
1970 && *year_int <= 2999)
+  if (auto year_int = fromChars<int>(year_str); year_int && *year_int >= 1970 
&& *year_int <= 2999)
     return year(*year_int);
   throw BadCronExpression("Invalid year: " + year_str);
 }
@@ -394,7 +394,7 @@ std::unique_ptr<CronField> parseCronField(const 
std::string& field_str) {
       if (operands.size() != 2)
         throw BadCronExpression("Invalid field " + field_str);
 
-      if (auto second_operand = fromChars<uint64_t>(operands[1]))
+      if (auto second_operand = fromChars<uint8_t>(operands[1]))
         return std::make_unique<NthWeekdayField>(parse<weekday>(operands[0]), 
*second_operand);
     }
 
diff --git a/libminifi/src/utils/FileMutex.cpp 
b/libminifi/src/utils/FileMutex.cpp
index 8d357243d..758f1d248 100644
--- a/libminifi/src/utils/FileMutex.cpp
+++ b/libminifi/src/utils/FileMutex.cpp
@@ -43,10 +43,10 @@ void FileMutex::lock() {
     if (handle == INVALID_HANDLE_VALUE) {
       std::cerr << "Failed to open file to read pid: " << 
utils::getLastError().message() << std::endl;
     } else {
-      std::array<char, 16> buffer;
+      std::array<char, 16> buffer = {};
       size_t pid_str_size = 0;
       DWORD read_size;
-      while (ReadFile(handle, buffer.data() + pid_str_size, buffer.size() - 
pid_str_size, &read_size, NULL) && read_size != 0) {
+      while (ReadFile(handle, buffer.data() + pid_str_size, 
gsl::narrow<DWORD>(buffer.size() - pid_str_size), &read_size, NULL) && 
read_size != 0) {
         pid_str_size += read_size;
       }
       pid_str = "'" + std::string(buffer.data(), pid_str_size) + "'";
@@ -62,7 +62,7 @@ void FileMutex::lock() {
   std::span<const char> buffer = pidstr;
   while (!buffer.empty()) {
     DWORD written;
-    if (!WriteFile(handle, buffer.data(), buffer.size(), &written, NULL)) {
+    if (!WriteFile(handle, buffer.data(), gsl::narrow<DWORD>(buffer.size()), 
&written, NULL)) {
       const auto err = utils::getLastError();
       if (!CloseHandle(file_handle_.value())) {
         std::cerr << "Failed to close file: " << 
utils::getLastError().message() << std::endl;
diff --git a/libminifi/src/utils/NetworkInterfaceInfo.cpp 
b/libminifi/src/utils/NetworkInterfaceInfo.cpp
index 60e96db66..9db31bfc6 100644
--- a/libminifi/src/utils/NetworkInterfaceInfo.cpp
+++ b/libminifi/src/utils/NetworkInterfaceInfo.cpp
@@ -21,6 +21,7 @@
 #include <iphlpapi.h>
 #pragma comment(lib, "IPHLPAPI.lib")
 #include "utils/OsUtils.h"
+#include "utils/UnicodeConversion.h"
 #else
 #include <unistd.h>
 #include <netinet/in.h>
@@ -37,7 +38,7 @@ std::shared_ptr<core::logging::Logger> 
NetworkInterfaceInfo::logger_ = core::log
 #ifdef WIN32
 
 NetworkInterfaceInfo::NetworkInterfaceInfo(const IP_ADAPTER_ADDRESSES* adapter)
-    : name_(OsUtils::wideStringToString(adapter->FriendlyName)),
+    : name_(to_string(adapter->FriendlyName)),
       running_(adapter->OperStatus == IfOperStatusUp),
       loopback_(adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
   for (auto unicast_address = adapter->FirstUnicastAddress; unicast_address != 
nullptr; unicast_address = unicast_address->Next) {
diff --git a/libminifi/src/utils/OsUtils.cpp b/libminifi/src/utils/OsUtils.cpp
index 3abe4f2a7..f1ac8b67c 100644
--- a/libminifi/src/utils/OsUtils.cpp
+++ b/libminifi/src/utils/OsUtils.cpp
@@ -338,36 +338,6 @@ std::optional<std::string> OsUtils::getHostName() {
   return {hostname.data()};
 }
 
-#ifdef WIN32
-std::wstring OsUtils::stringToWideString(const std::string& string) {
-  if (string.empty())
-    return {};
-
-  const auto size_needed = MultiByteToWideChar(CP_UTF8, 0, &string.at(0), 
gsl::narrow<int>(string.size()), nullptr, 0);
-  if (size_needed <= 0) {
-    throw std::runtime_error(fmt::format("MultiByteToWideChar() returned: {}, 
due to {}", std::to_string(size_needed), 
utils::OsUtils::windowsErrorToErrorCode(GetLastError()).message()));
-  }
-
-  std::wstring result(size_needed, L'\0');
-  MultiByteToWideChar(CP_UTF8, 0, &string.at(0), 
gsl::narrow<int>(string.size()), &result.at(0), size_needed);
-  return result;
-}
-
-std::string OsUtils::wideStringToString(const std::wstring& wide_string) {
-  if (wide_string.empty())
-    return {};
-
-  const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), 
gsl::narrow<int>(wide_string.size()), nullptr, 0, nullptr, nullptr);
-  if (size_needed <= 0) {
-    throw std::runtime_error(fmt::format("WideCharToMultiByte() returned: {}, 
due to {}", std::to_string(size_needed), 
utils::OsUtils::windowsErrorToErrorCode(GetLastError()).message()));
-  }
-
-  std::string result(size_needed, 0);
-  WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), 
gsl::narrow<int>(wide_string.size()), &result.at(0), size_needed, nullptr, 
nullptr);
-  return result;
-}
-#endif
-
 std::optional<double> OsUtils::getSystemLoadAverage() {
 #ifndef WIN32
   std::array<double, 1> load_avg{};
diff --git a/libminifi/src/utils/ProcessCpuUsageTracker.cpp 
b/libminifi/src/utils/ProcessCpuUsageTracker.cpp
index f738f17b3..7a2e360fc 100644
--- a/libminifi/src/utils/ProcessCpuUsageTracker.cpp
+++ b/libminifi/src/utils/ProcessCpuUsageTracker.cpp
@@ -115,7 +115,6 @@ void ProcessCpuUsageTracker::queryCpuTimes() {
   previous_cpu_times_ = cpu_times_;
   previous_sys_cpu_times_ = sys_cpu_times_;
   previous_user_cpu_times_ = user_cpu_times_;
-  SYSTEM_INFO sysInfo;
   FILETIME ftime, fsys, fuser;
   GetSystemTimeAsFileTime(&ftime);
 
diff --git a/libminifi/src/utils/TestUtils.cpp 
b/libminifi/src/utils/TestUtils.cpp
index 6d3021be7..ebf63d1d9 100644
--- a/libminifi/src/utils/TestUtils.cpp
+++ b/libminifi/src/utils/TestUtils.cpp
@@ -17,7 +17,52 @@
 
 #include "utils/TestUtils.h"
 
+#include <type_traits>
+
+#ifdef WIN32
+#include <windows.h>
+#include <aclapi.h>
+#endif
+
+#include "utils/gsl.h"
+
+#ifdef WIN32
+namespace {
+
+void setAclOnFileOrDirectory(std::string file_name, DWORD perms, ACCESS_MODE 
perm_options) {
+  PSECURITY_DESCRIPTOR security_descriptor = nullptr;
+  const auto security_descriptor_deleter = gsl::finally([&security_descriptor] 
{ if (security_descriptor) { LocalFree((HLOCAL) security_descriptor); } });
+
+  PACL old_acl = nullptr;  // GetNamedSecurityInfo will set this to a 
non-owning pointer to a field inside security_descriptor: no need to free it
+  if (GetNamedSecurityInfo(file_name.c_str(), SE_FILE_OBJECT, 
DACL_SECURITY_INFORMATION, NULL, NULL, &old_acl, NULL, &security_descriptor) != 
ERROR_SUCCESS) {
+    throw std::runtime_error("Could not get security info for file: " + 
file_name);
+  }
+
+  char trustee_name[] = "Everyone";
+  EXPLICIT_ACCESS explicit_access = {
+    .grfAccessPermissions = perms,
+    .grfAccessMode = perm_options,
+    .grfInheritance = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
+    .Trustee = { .TrusteeForm = TRUSTEE_IS_NAME, .ptstrName = trustee_name }
+  };
+
+  PACL new_acl = nullptr;
+  const auto new_acl_deleter = gsl::finally([&new_acl] { if (new_acl) { 
LocalFree((HLOCAL) new_acl); } });
+
+  if (SetEntriesInAcl(1, &explicit_access, old_acl, &new_acl) != 
ERROR_SUCCESS) {
+    throw std::runtime_error("Could not create new ACL for file: " + 
file_name);
+  }
+
+  if (SetNamedSecurityInfo(file_name.data(), SE_FILE_OBJECT, 
DACL_SECURITY_INFORMATION, NULL, NULL, new_acl, NULL) != ERROR_SUCCESS) {
+    throw std::runtime_error("Could not set the new ACL for file: " + 
file_name);
+  }
+}
+
+}  // namespace
+#endif
+
 namespace org::apache::nifi::minifi::utils {
+
 #ifdef WIN32
 // If minifi is not installed through the MSI installer, then TZDATA might be 
missing
 // date::set_install can point to the TZDATA location, but it has to be called 
from each library/executable that wants to use timezones
@@ -25,4 +70,21 @@ void dateSetInstall(const std::string& install) {
   date::set_install(install);
 }
 #endif
+
+void makeFileOrDirectoryNotWritable(const std::filesystem::path& file_name) {
+#ifdef WIN32
+  setAclOnFileOrDirectory(file_name.string(), FILE_GENERIC_WRITE, DENY_ACCESS);
+#else
+  std::filesystem::permissions(file_name, std::filesystem::perms::owner_write, 
std::filesystem::perm_options::remove);
+#endif
+}
+
+void makeFileOrDirectoryWritable(const std::filesystem::path& file_name) {
+#ifdef WIN32
+  setAclOnFileOrDirectory(file_name.string(), FILE_GENERIC_WRITE, 
GRANT_ACCESS);
+#else
+  std::filesystem::permissions(file_name, std::filesystem::perms::owner_write, 
std::filesystem::perm_options::add);
+#endif
+}
+
 }  // namespace org::apache::nifi::minifi::utils
diff --git a/libminifi/src/utils/crypto/ciphers/Aes256Ecb.cpp 
b/libminifi/src/utils/crypto/ciphers/Aes256Ecb.cpp
index ccc8571b4..482719342 100644
--- a/libminifi/src/utils/crypto/ciphers/Aes256Ecb.cpp
+++ b/libminifi/src/utils/crypto/ciphers/Aes256Ecb.cpp
@@ -67,9 +67,9 @@ void Aes256EcbCipher::encrypt(std::span<unsigned char, 
BLOCK_SIZE> data) const {
   }
 
   int ciphertext_len = 0;
-  int len;
+  int len = 0;
 
-  if (1 != EVP_EncryptUpdate(ctx.get(), data.data(), &len, data.data(), 
data.size())) {
+  if (1 != EVP_EncryptUpdate(ctx.get(), data.data(), &len, data.data(), 
gsl::narrow<int>(data.size()))) {
     handleOpenSSLError("Could not update cipher content");
   }
   ciphertext_len += len;
@@ -99,9 +99,9 @@ void Aes256EcbCipher::decrypt(std::span<unsigned char, 
BLOCK_SIZE> data) const {
   }
 
   int plaintext_len = 0;
-  int len;
+  int len = 0;
 
-  if (1 != EVP_DecryptUpdate(ctx.get(), data.data(), &len, data.data(), 
data.size())) {
+  if (1 != EVP_DecryptUpdate(ctx.get(), data.data(), &len, data.data(), 
gsl::narrow<int>(data.size()))) {
     handleOpenSSLError("Could not update cipher content");
   }
   plaintext_len += len;
diff --git a/libminifi/test/unit/FileSystemRepositoryTests.cpp 
b/libminifi/test/unit/FileSystemRepositoryTests.cpp
index 6613e977d..94b0a5c21 100644
--- a/libminifi/test/unit/FileSystemRepositoryTests.cpp
+++ b/libminifi/test/unit/FileSystemRepositoryTests.cpp
@@ -20,14 +20,11 @@
 // as we measure the absolute memory usage that would fail this test
 #define EXTENSION_LIST ""  // NOLINT(cppcoreguidelines-macro-usage)
 
-#ifdef WIN32
-#include <Windows.h>
-#endif
-#include <cstring>
 #include <list>
 
 #include "utils/gsl.h"
 #include "utils/OsUtils.h"
+#include "utils/TestUtils.h"
 #include "../TestBase.h"
 #include "../Catch.h"
 #include "utils/Literals.h"
@@ -114,18 +111,10 @@ TEST_CASE("FileSystemRepository can retry removing entry 
that previously failed
     REQUIRE(files.size() == 1);
     // ensure that the content is not deleted during resource claim destruction
     filename = (files[0].first / files[0].second).string();
-#ifdef WIN32
-    REQUIRE(SetFileAttributes(filename.c_str(), FILE_ATTRIBUTE_READONLY));
-#else
-    minifi::utils::file::set_permissions(dir, 0555);
-#endif
+    utils::makeFileOrDirectoryNotWritable(dir);
   }
 
-#ifdef WIN32
-  REQUIRE(SetFileAttributes(filename.c_str(), 
GetFileAttributes(filename.c_str()) & ~FILE_ATTRIBUTE_READONLY));
-#else
-  minifi::utils::file::set_permissions(dir, 0777);
-#endif
+  utils::makeFileOrDirectoryWritable(dir);
   REQUIRE(minifi::utils::file::list_dir_all(dir, 
testController.getLogger()).size() == 1);
   {
     minifi::ResourceClaim claim(content_repo);
@@ -153,18 +142,10 @@ TEST_CASE("FileSystemRepository removes non-existing 
resource file from purge li
     REQUIRE(files.size() == 1);
     // ensure that the content is not deleted during resource claim destruction
     filename = (files[0].first / files[0].second).string();
-#ifdef WIN32
-    REQUIRE(SetFileAttributes(filename.c_str(), FILE_ATTRIBUTE_READONLY));
-#else
-    minifi::utils::file::set_permissions(dir, 0555);
-#endif
+    utils::makeFileOrDirectoryNotWritable(dir);
   }
 
-#ifdef WIN32
-  REQUIRE(SetFileAttributes(filename.c_str(), 
GetFileAttributes(filename.c_str()) & ~FILE_ATTRIBUTE_READONLY));
-#else
-  minifi::utils::file::set_permissions(dir, 0777);
-#endif
+  utils::makeFileOrDirectoryWritable(dir);
   REQUIRE(std::filesystem::remove(filename));
   REQUIRE(minifi::utils::file::list_dir_all(dir, 
testController.getLogger()).empty());
   {
diff --git a/libminifi/test/unit/OsUtilTests.cpp 
b/libminifi/test/unit/OsUtilTests.cpp
index 15c4628cc..a7777d177 100644
--- a/libminifi/test/unit/OsUtilTests.cpp
+++ b/libminifi/test/unit/OsUtilTests.cpp
@@ -39,26 +39,6 @@ TEST_CASE("Test userIdToUsername for well-known SIDs", 
"[OsUtils]") {
   CHECK_FALSE(minifi::utils::OsUtils::userIdToUsername("S-1-3-4").empty());
   CHECK_FALSE(minifi::utils::OsUtils::userIdToUsername("S-1-5-80-0").empty());
 }
-
-TEST_CASE("OsUtils::stringToWideString tests") {
-  using org::apache::nifi::minifi::utils::OsUtils::stringToWideString;
-
-  CHECK(stringToWideString("árvíztűrő tükörfúrógép") == L"árvíztűrő 
tükörfúrógép");
-  CHECK(stringToWideString("Falsches Üben von Xylophonmusik quält jeden 
größeren Zwerg.") == L"Falsches Üben von Xylophonmusik quält jeden größeren 
Zwerg.");
-  CHECK(stringToWideString("가나다라마바사아자차카타파하") == L"가나다라마바사아자차카타파하");
-  CHECK(stringToWideString("العربية تجربة") == L"العربية تجربة");
-  CHECK(stringToWideString("פטכןצימסעואבגדהוזחטייכלמנסעפצקרשת") == 
L"פטכןצימסעואבגדהוזחטייכלמנסעפצקרשת");
-}
-
-TEST_CASE("OsUtils::wideStringToString tests") {
-  using org::apache::nifi::minifi::utils::OsUtils::wideStringToString;
-
-  CHECK(wideStringToString(L"árvíztűrő tükörfúrógép") == "árvíztűrő 
tükörfúrógép");
-  CHECK(wideStringToString(L"Falsches Üben von Xylophonmusik quält jeden 
größeren Zwerg.") == "Falsches Üben von Xylophonmusik quält jeden größeren 
Zwerg.");
-  CHECK(wideStringToString(L"가나다라마바사아자차카타파하") == "가나다라마바사아자차카타파하");
-  CHECK(wideStringToString(L"العربية تجربة") == "العربية تجربة");
-  CHECK(wideStringToString(L"פטכןצימסעואבגדהוזחטייכלמנסעפצקרשת") == 
"פטכןצימסעואבגדהוזחטייכלמנסעפצקרשת");
-}
 #endif
 
 TEST_CASE("Machine architecture is supported") {
diff --git a/libminifi/test/unit/StringUtilsTests.cpp 
b/libminifi/test/unit/StringUtilsTests.cpp
index 11b44d7cd..a7a3b9b7f 100644
--- a/libminifi/test/unit/StringUtilsTests.cpp
+++ b/libminifi/test/unit/StringUtilsTests.cpp
@@ -28,6 +28,10 @@
 #include "utils/StringUtils.h"
 #include "utils/Environment.h"
 
+#ifdef WIN32
+#include "utils/UnicodeConversion.h"
+#endif
+
 namespace org::apache::nifi::minifi::utils {
 
 // NOLINTBEGIN(readability-container-size-empty)
@@ -449,18 +453,20 @@ TEST_CASE("test string::testBase64EncodeDecode", "[test 
base64 encode decode]")
 
 TEST_CASE("test string::testJoinPack", "[test join_pack]") {
   std::string stdstr = "std::string";
+  std::string_view strview = "std::string_view";
   const char* cstr = "c string";
-  const char carr[] = "char array";
-  REQUIRE(string::join_pack("rvalue c string, ", cstr, std::string{", rval 
std::string, "}, stdstr, ", ", carr)
-      == "rvalue c string, c string, rval std::string, std::string, char 
array");
+  const char carr[] = "char array";  // 
NOLINT(cppcoreguidelines-avoid-c-arrays): testing const char[] on purpose
+  REQUIRE(string::join_pack("rvalue c string, ", cstr, std::string{", rval 
std::string, "}, stdstr, ", ", strview, ", ", carr)
+      == "rvalue c string, c string, rval std::string, std::string, 
std::string_view, char array");
 }
 
 TEST_CASE("test string::testJoinPackWstring", "[test join_pack wstring]") {
   std::wstring stdstr = L"std::string";
+  std::wstring_view strview = L"std::string_view";
   const wchar_t* cstr = L"c string";
-  const wchar_t carr[] = L"char array";
-  REQUIRE(string::join_pack(L"rvalue c string, ", cstr, std::wstring{L", rval 
std::string, "}, stdstr, L", ", carr)
-      == L"rvalue c string, c string, rval std::string, std::string, char 
array");
+  const wchar_t carr[] = L"char array";  // 
NOLINT(cppcoreguidelines-avoid-c-arrays): testing const wchar_t[] on purpose
+  REQUIRE(string::join_pack(L"rvalue c string, ", cstr, std::wstring{L", rval 
std::string, "}, stdstr, L", ", strview, L", ", carr)
+      == L"rvalue c string, c string, rval std::string, std::string, 
std::string_view, char array");
 }
 
 /* doesn't and shouldn't compile
@@ -525,7 +531,7 @@ TEST_CASE("string::removeFramingCharacters works 
correctly", "[removeFramingChar
 
 // ignore terminating \0 character
 template<size_t N>
-std::span<const std::byte> from_cstring(const char (& str)[N]) {
+std::span<const std::byte> from_cstring(const char (& str)[N]) {  // 
NOLINT(cppcoreguidelines-avoid-c-arrays)
   return as_bytes(std::span<const char>(str, N - 1));
 }
 
@@ -554,7 +560,7 @@ TEST_CASE("string::toLower and toUpper tests") {
 }
 
 TEST_CASE("string::splitToValueAndUnit tests") {
-  int64_t value;
+  int64_t value = 0;
   std::string unit_str;
   SECTION("Simple case") {
     CHECK(string::splitToValueAndUnit("1 horse", value, unit_str));
@@ -598,6 +604,28 @@ TEST_CASE("string::parseCharacter tests") {
   CHECK(string::parseCharacter("") == std::nullopt);
 }
 
+#ifdef WIN32
+TEST_CASE("Conversion from UTF-8 strings to UTF-16 strings works") {
+  using org::apache::nifi::minifi::utils::to_wstring;
+
+  CHECK(to_wstring("árvíztűrő tükörfúrógép") == L"árvíztűrő tükörfúrógép");
+  CHECK(to_wstring("Falsches Üben von Xylophonmusik quält jeden größeren 
Zwerg.") == L"Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.");
+  CHECK(to_wstring("가나다라마바사아자차카타파하") == L"가나다라마바사아자차카타파하");
+  CHECK(to_wstring("العربية تجربة") == L"العربية تجربة");
+  CHECK(to_wstring("פטכןצימסעואבגדהוזחטייכלמנסעפצקרשת") == 
L"פטכןצימסעואבגדהוזחטייכלמנסעפצקרשת");
+}
+
+TEST_CASE("Conversion from UTF-16 strings to UTF-8 strings works") {
+  using org::apache::nifi::minifi::utils::to_string;
+
+  CHECK(to_string(L"árvíztűrő tükörfúrógép") == "árvíztűrő tükörfúrógép");
+  CHECK(to_string(L"Falsches Üben von Xylophonmusik quält jeden größeren 
Zwerg.") == "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.");
+  CHECK(to_string(L"가나다라마바사아자차카타파하") == "가나다라마바사아자차카타파하");
+  CHECK(to_string(L"العربية تجربة") == "العربية تجربة");
+  CHECK(to_string(L"פטכןצימסעואבגדהוזחטייכלמנסעפצקרשת") == 
"פטכןצימסעואבגדהוזחטייכלמנסעפצקרשת");
+}
+#endif
+
 }  // namespace org::apache::nifi::minifi::utils
 
 // NOLINTEND(readability-container-size-empty)

Reply via email to