void C2Agent::handle_describe()

in libminifi/src/c2/C2Agent.cpp [478:578]


void C2Agent::handle_describe(const C2ContentResponse &resp) {
  DescribeOperand operand = DescribeOperand::metrics;
  try {
    operand = utils::enumCast<DescribeOperand>(resp.name, true);
  } catch(const std::runtime_error&) {
    C2Payload response(Operation::acknowledge, resp.ident, true);
    enqueue_c2_response(std::move(response));
    return;
  }

  switch (operand) {
    case DescribeOperand::metrics: {
      C2Payload response(Operation::acknowledge, resp.ident, true);
      auto iter = resp.operation_arguments.find("metricsClass");
      std::string metricsClass;
      if (iter != resp.operation_arguments.end()) {
        metricsClass = iter->second.to_string();
      }
      std::optional<state::response::NodeReporter::ReportedNode> metricsNode;
      if (auto node_reporter = node_reporter_.lock()) {
        metricsNode = node_reporter->getMetricsNode(metricsClass);
      }
      C2Payload metrics(Operation::acknowledge);
      metricsClass.empty() ? metrics.setLabel("metrics") : metrics.setLabel(metricsClass);
      if (metricsNode) {
        serializeMetrics(metrics, metricsNode->name, metricsNode->serialized_nodes, metricsNode->is_array);
      }
      response.addPayload(std::move(metrics));
      enqueue_c2_response(std::move(response));
      break;
    }
    case DescribeOperand::configuration: {
      auto configOptions = prepareConfigurationOptions(resp);
      enqueue_c2_response(std::move(configOptions));
      break;
    }
    case DescribeOperand::manifest: {
      C2Payload response(prepareConfigurationOptions(resp));
      C2Payload agentInfo(Operation::acknowledge, resp.ident, true);
      agentInfo.setLabel("agentInfo");

      if (auto node_reporter = node_reporter_.lock()) {
        auto manifest = node_reporter->getAgentManifest();
        serializeMetrics(agentInfo, manifest.name, manifest.serialized_nodes);
      }
      response.addPayload(std::move(agentInfo));
      enqueue_c2_response(std::move(response));
      break;
    }
    case DescribeOperand::jstack: {
      if (update_sink_->isRunning()) {
        const std::vector<BackTrace> traces = update_sink_->getTraces();
        for (const auto &trace : traces) {
          for (const auto & line : trace.getTraces()) {
            logger_->log_trace("{} -- {}", trace.getName(), line);
          }
        }
        auto keys = configuration_->getConfiguredKeys();
        C2Payload response(Operation::acknowledge, resp.ident, true);
        for (const auto &trace : traces) {
          C2Payload options(Operation::acknowledge, resp.ident, true);
          options.setLabel(trace.getName());
          std::string value;
          for (const auto &line : trace.getTraces()) {
            C2ContentResponse option(Operation::acknowledge);
            option.name = line;
            option.operation_arguments[line] = C2Value{line};
            options.addContent(std::move(option));
          }
          response.addPayload(std::move(options));
        }
        enqueue_c2_response(std::move(response));
      }
      break;
    }
    case DescribeOperand::corecomponentstate: {
      C2Payload response(Operation::acknowledge, resp.ident, true);
      response.setLabel("corecomponentstate");
      C2Payload states(Operation::acknowledge, resp.ident, true);
      states.setLabel("corecomponentstate");
      auto state_storage = core::ProcessContextImpl::getStateStorage(logger_, controller_, configuration_);
      if (state_storage != nullptr) {
        auto core_component_states = state_storage->getAllStates();
        for (const auto& core_component_state : core_component_states) {
          C2Payload state(Operation::acknowledge, resp.ident, true);
          state.setLabel(core_component_state.first.to_string());
          for (const auto& kv : core_component_state.second) {
            C2ContentResponse entry(Operation::acknowledge);
            entry.name = kv.first;
            entry.operation_arguments[kv.first] = C2Value{kv.second};
            state.addContent(std::move(entry));
          }
          states.addPayload(std::move(state));
        }
      }
      response.addPayload(std::move(states));
      enqueue_c2_response(std::move(response));
      break;
    }
  }
}