| /** |
| * @file ArchiveMetadata.cpp |
| * ArchiveMetadata class definition |
| * |
| * 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 "ArchiveMetadata.h" |
| |
| #include <archive_entry.h> |
| |
| #include <string> |
| #include <algorithm> |
| #include <iostream> |
| |
| #include "utils/file/FileManager.h" |
| #include "utils/gsl.h" |
| #include "Exception.h" |
| |
| #include "rapidjson/writer.h" |
| #include "rapidjson/error/en.h" |
| |
| using org::apache::nifi::minifi::Exception; |
| using org::apache::nifi::minifi::ExceptionType; |
| |
| rapidjson::Value ArchiveEntryMetadata::toJson(rapidjson::Document::AllocatorType &alloc) const { |
| rapidjson::Value entryVal(rapidjson::kObjectType); |
| |
| rapidjson::Value entryNameVal; |
| entryNameVal.SetString(entryName.c_str(), gsl::narrow<rapidjson::SizeType>(entryName.length())); |
| entryVal.AddMember("entry_name", entryNameVal, alloc); |
| |
| entryVal.AddMember("entry_type", entryType, alloc); |
| entryVal.AddMember("entry_perm", entryPerm, alloc); |
| entryVal.AddMember("entry_size", entrySize, alloc); |
| entryVal.AddMember("entry_uid", entryUID, alloc); |
| entryVal.AddMember("entry_gid", entryGID, alloc); |
| entryVal.AddMember("entry_mtime", entryMTime, alloc); |
| entryVal.AddMember("entry_mtime_nsec", entryMTimeNsec, alloc); |
| |
| if (entryType == AE_IFREG) { |
| rapidjson::Value stashKeyVal; |
| stashKeyVal.SetString(stashKey.c_str(), gsl::narrow<rapidjson::SizeType>(stashKey.length())); |
| entryVal.AddMember("stash_key", stashKeyVal, alloc); |
| } |
| |
| return entryVal; |
| } |
| |
| void ArchiveEntryMetadata::loadJson(const rapidjson::Value& entryVal) { |
| entryName.assign(entryVal["entry_name"].GetString()); |
| entryType = gsl::narrow<mode_t>(entryVal["entry_type"].GetUint64()); |
| entryPerm = gsl::narrow<mode_t>(entryVal["entry_perm"].GetUint64()); |
| entrySize = entryVal["entry_size"].GetUint64(); |
| entryUID = gsl::narrow<uid_t>(entryVal["entry_uid"].GetUint64()); |
| entryGID = entryVal["entry_gid"].GetUint64(); |
| entryMTime = entryVal["entry_mtime"].GetUint64(); |
| entryMTimeNsec = entryVal["entry_mtime_nsec"].GetInt64(); |
| |
| if (entryType == AE_IFREG) |
| stashKey.assign(entryVal["stash_key"].GetString()); |
| } |
| |
| ArchiveEntryMetadata ArchiveEntryMetadata::fromJson(const rapidjson::Value& entryVal) { |
| ArchiveEntryMetadata aem; |
| aem.loadJson(entryVal); |
| return aem; |
| } |
| |
| ArchiveEntryIterator ArchiveMetadata::find(const std::string& name) { |
| auto targetTest = [&](const ArchiveEntryMetadata& entry) -> bool { |
| return entry.entryName == name; |
| }; |
| |
| return std::find_if(entryMetadata.begin(), entryMetadata.end(), targetTest); |
| } |
| |
| ArchiveEntryIterator ArchiveMetadata::eraseEntry(ArchiveEntryIterator position) { |
| return entryMetadata.erase(position); |
| } |
| |
| ArchiveEntryIterator ArchiveMetadata::insertEntry( |
| ArchiveEntryIterator position, const ArchiveEntryMetadata& entry) { |
| return entryMetadata.insert(position, entry); |
| } |
| |
| rapidjson::Value ArchiveMetadata::toJson(rapidjson::Document::AllocatorType &alloc) const { |
| rapidjson::Value structVal(rapidjson::kArrayType); |
| |
| for (const auto &entry : entryMetadata) { |
| structVal.PushBack(entry.toJson(alloc), alloc); |
| } |
| |
| rapidjson::Value lensVal(rapidjson::kObjectType); |
| |
| rapidjson::Value archiveFormatNameVal; |
| archiveFormatNameVal.SetString(archiveFormatName.c_str(), gsl::narrow<rapidjson::SizeType>(archiveFormatName.length())); |
| lensVal.AddMember("archive_format_name", archiveFormatNameVal, alloc); |
| |
| lensVal.AddMember("archive_format", archiveFormat, alloc); |
| lensVal.AddMember("archive_structure", structVal, alloc); |
| |
| if (!archiveName.empty()) { |
| rapidjson::Value archiveNameVal; |
| archiveNameVal.SetString(archiveName.c_str(), gsl::narrow<rapidjson::SizeType>(archiveName.length())); |
| lensVal.AddMember("archive_name", archiveNameVal, alloc); |
| } |
| |
| rapidjson::Value focusedEntryVal; |
| focusedEntryVal.SetString(focusedEntry.c_str(), gsl::narrow<rapidjson::SizeType>(focusedEntry.length())); |
| lensVal.AddMember("focused_entry", focusedEntryVal, alloc); |
| |
| return lensVal; |
| } |
| |
| ArchiveMetadata ArchiveMetadata::fromJson(const rapidjson::Value& metadataDoc) { |
| ArchiveMetadata am; |
| am.loadJson(metadataDoc); |
| return am; |
| } |
| |
| void ArchiveMetadata::loadJson(const rapidjson::Value& metadataDoc) { |
| rapidjson::Value::ConstMemberIterator itr = metadataDoc.FindMember("archive_name"); |
| if (itr != metadataDoc.MemberEnd()) |
| archiveName.assign(itr->value.GetString()); |
| |
| archiveFormatName.assign(metadataDoc["archive_format_name"].GetString()); |
| archiveFormat = gsl::narrow<int>(metadataDoc["archive_format"].GetUint64()); |
| |
| focusedEntry = metadataDoc["focused_entry"].GetString(); |
| |
| for (const auto &entryVal : metadataDoc["archive_structure"].GetArray()) { |
| entryMetadata.push_back(ArchiveEntryMetadata::fromJson(entryVal)); |
| } |
| } |
| |
| void ArchiveMetadata::seedTempPaths(org::apache::nifi::minifi::utils::file::FileManager *file_man, bool keep = false) { |
| for (auto& entry : entryMetadata) |
| entry.tmpFileName.assign(file_man->unique_file(keep)); |
| } |
| |
| ArchiveStack ArchiveStack::fromJson(const rapidjson::Value& input) { |
| ArchiveStack as; |
| as.loadJson(input); |
| return as; |
| } |
| |
| ArchiveStack ArchiveStack::fromJsonString(const std::string& input) { |
| ArchiveStack as; |
| as.loadJsonString(input); |
| return as; |
| } |
| |
| void ArchiveStack::loadJson(const rapidjson::Value& lensStack) { |
| for (const auto& metadata : lensStack.GetArray()) { |
| stack_.push_back(ArchiveMetadata::fromJson(metadata)); |
| } |
| } |
| |
| void ArchiveStack::loadJsonString(const std::string& input) { |
| rapidjson::Document lensStack; |
| rapidjson::ParseResult ok = lensStack.Parse(input.c_str()); |
| |
| if (!ok) { |
| std::stringstream ss; |
| ss << "Failed to parse archive lens stack from JSON string with reason: " |
| << rapidjson::GetParseError_En(ok.Code()) |
| << " at offset " << ok.Offset(); |
| |
| throw Exception(ExceptionType::GENERAL_EXCEPTION, ss.str()); |
| } |
| |
| loadJson(lensStack); |
| } |
| |
| rapidjson::Document ArchiveStack::toJson() const { |
| rapidjson::Document lensStack(rapidjson::kArrayType); |
| rapidjson::Document::AllocatorType &alloc = lensStack.GetAllocator(); |
| |
| for (const auto& metadata : stack_) { |
| lensStack.PushBack(metadata.toJson(alloc), alloc); |
| } |
| |
| return lensStack; |
| } |
| |
| std::string ArchiveStack::toJsonString() const { |
| rapidjson::Document d = toJson(); |
| |
| rapidjson::StringBuffer buffer; |
| rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); |
| d.Accept(writer); |
| |
| std::string jsonString = buffer.GetString(); |
| return jsonString; |
| } |