| 109 | } |
| 110 | |
| 111 | void PutFile::onTrigger(core::ProcessContext *context, core::ProcessSession *session) { |
| 112 | if (IsNullOrEmpty(conflict_resolution_)) { |
| 113 | logger_->log_error("Conflict resolution value is invalid"); |
| 114 | context->yield(); |
| 115 | return; |
| 116 | } |
| 117 | |
| 118 | std::shared_ptr<core::FlowFile> flowFile = session->get(); |
| 119 | |
| 120 | // Do nothing if there are no incoming files |
| 121 | if (!flowFile) { |
| 122 | return; |
| 123 | } |
| 124 | |
| 125 | session->remove(flowFile); |
| 126 | |
| 127 | std::string directory; |
| 128 | |
| 129 | if (!context->getProperty(Directory, directory, flowFile)) { |
| 130 | logger_->log_error("Directory attribute is missing or invalid"); |
| 131 | } |
| 132 | |
| 133 | if (IsNullOrEmpty(directory)) { |
| 134 | logger_->log_error("Directory attribute evaluated to invalid value"); |
| 135 | session->transfer(flowFile, Failure); |
| 136 | return; |
| 137 | } |
| 138 | |
| 139 | std::string filename; |
| 140 | flowFile->getAttribute(core::SpecialFlowAttribute::FILENAME, filename); |
| 141 | std::string tmpFile = tmpWritePath(filename, directory); |
| 142 | |
| 143 | logger_->log_debug("PutFile using temporary file %s", tmpFile); |
| 144 | |
| 145 | // Determine dest full file paths |
| 146 | std::stringstream destFileSs; |
| 147 | destFileSs << directory << utils::file::FileUtils::get_separator() << filename; |
| 148 | std::string destFile = destFileSs.str(); |
| 149 | |
| 150 | logger_->log_debug("PutFile writing file %s into directory %s", filename, directory); |
| 151 | |
| 152 | // If file exists, apply conflict resolution strategy |
| 153 | struct stat statResult; |
| 154 | |
| 155 | if ((max_dest_files_ != -1) && utils::file::FileUtils::is_directory(directory.c_str())) { |
| 156 | int64_t count = 0; |
| 157 | |
| 158 | // Callback, called for each file entry in the listed directory |
| 159 | // Return value is used to break (false) or continue (true) listing |
| 160 | auto lambda = [&count, this](const std::string&, const std::string&) -> bool { |
| 161 | return ++count < max_dest_files_; |
| 162 | }; |
| 163 | |
| 164 | utils::file::FileUtils::list_dir(directory, lambda, logger_, false); |
| 165 | |
| 166 | if (count >= max_dest_files_) { |
| 167 | logger_->log_warn("Routing to failure because the output directory %s has at least %u files, which exceeds the " |
| 168 | "configured max number of files", directory, max_dest_files_); |
nothing calls this directly
no test coverage detected