Skip to content
Snippets Groups Projects
Commit e1979acf authored by Michael Davis's avatar Michael Davis
Browse files

Merge branch 'cta_admin_stream_all'

parents 2f26a018 271211a4
Branches
Tags
No related merge requests found
......@@ -27,9 +27,14 @@
#include <cmdline/CtaAdminTextFormatter.hpp>
// global synchronisation flag between main thread and stream handler thread
// GLOBAL VARIABLES : used to pass information between main thread and stream handler thread
// global synchronisation flag
std::atomic<bool> isHeaderSent(false);
// initialise an output buffer of 1000 lines
cta::admin::TextFormatter formattedText(1000);
namespace XrdSsiPb {
......@@ -83,17 +88,17 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const
}
// Format results in a tabular format for a human
else switch(record.data_case()) {
case Data::kAflsItem: CtaAdminTextFormatter::print(record.afls_item()); break;
case Data::kAflsSummary: CtaAdminTextFormatter::print(record.afls_summary()); break;
case Data::kFrlsItem: CtaAdminTextFormatter::print(record.frls_item()); break;
case Data::kFrlsSummary: CtaAdminTextFormatter::print(record.frls_summary()); break;
case Data::kLpaItem: CtaAdminTextFormatter::print(record.lpa_item()); break;
case Data::kLpaSummary: CtaAdminTextFormatter::print(record.lpa_summary()); break;
case Data::kLprItem: CtaAdminTextFormatter::print(record.lpr_item()); break;
case Data::kLprSummary: CtaAdminTextFormatter::print(record.lpr_summary()); break;
case Data::kTplsItem: CtaAdminTextFormatter::print(record.tpls_item()); break;
case Data::kTalsItem: CtaAdminTextFormatter::print(record.tals_item()); break;
case Data::kRelsItem: CtaAdminTextFormatter::print(record.rels_item()); break;
case Data::kAflsItem: formattedText.print(record.afls_item()); break;
case Data::kAflsSummary: formattedText.print(record.afls_summary()); break;
case Data::kFrlsItem: formattedText.print(record.frls_item()); break;
case Data::kFrlsSummary: formattedText.print(record.frls_summary()); break;
case Data::kLpaItem: formattedText.print(record.lpa_item()); break;
case Data::kLpaSummary: formattedText.print(record.lpa_summary()); break;
case Data::kLprItem: formattedText.print(record.lpr_item()); break;
case Data::kLprSummary: formattedText.print(record.lpr_summary()); break;
case Data::kTplsItem: formattedText.print(record.tpls_item()); break;
case Data::kTalsItem: formattedText.print(record.tals_item()); break;
case Data::kRelsItem: formattedText.print(record.rels_item()); break;
default:
throw std::runtime_error("Received invalid stream data from CTA Frontend.");
}
......@@ -227,17 +232,17 @@ void CtaAdminCmd::send() const
std::cout << response.message_txt();
// Print streaming response header
if(!isJson()) switch(response.show_header()) {
case HeaderType::ARCHIVEFILE_LS: CtaAdminTextFormatter::printAfLsHeader(); break;
case HeaderType::ARCHIVEFILE_LS_SUMMARY: CtaAdminTextFormatter::printAfLsSummaryHeader(); break;
case HeaderType::FAILEDREQUEST_LS: CtaAdminTextFormatter::printFrLsHeader(); break;
case HeaderType::FAILEDREQUEST_LS_SUMMARY: CtaAdminTextFormatter::printFrLsSummaryHeader(); break;
case HeaderType::LISTPENDINGARCHIVES: CtaAdminTextFormatter::printLpaHeader(); break;
case HeaderType::LISTPENDINGARCHIVES_SUMMARY: CtaAdminTextFormatter::printLpaSummaryHeader(); break;
case HeaderType::LISTPENDINGRETRIEVES: CtaAdminTextFormatter::printLprHeader(); break;
case HeaderType::LISTPENDINGRETRIEVES_SUMMARY: CtaAdminTextFormatter::printLprSummaryHeader(); break;
case HeaderType::TAPEPOOL_LS: CtaAdminTextFormatter::printTpLsHeader(); break;
case HeaderType::TAPE_LS: CtaAdminTextFormatter::printTapeLsHeader(); break;
case HeaderType::REPACK_LS: CtaAdminTextFormatter::printRepackLsHeader(); break;
case HeaderType::ARCHIVEFILE_LS: formattedText.printAfLsHeader(); break;
case HeaderType::ARCHIVEFILE_LS_SUMMARY: formattedText.printAfLsSummaryHeader(); break;
case HeaderType::FAILEDREQUEST_LS: formattedText.printFrLsHeader(); break;
case HeaderType::FAILEDREQUEST_LS_SUMMARY: formattedText.printFrLsSummaryHeader(); break;
case HeaderType::LISTPENDINGARCHIVES: formattedText.printLpaHeader(); break;
case HeaderType::LISTPENDINGARCHIVES_SUMMARY: formattedText.printLpaSummaryHeader(); break;
case HeaderType::LISTPENDINGRETRIEVES: formattedText.printLprHeader(); break;
case HeaderType::LISTPENDINGRETRIEVES_SUMMARY: formattedText.printLprSummaryHeader(); break;
case HeaderType::TAPEPOOL_LS: formattedText.printTapePoolLsHeader(); break;
case HeaderType::TAPE_LS: formattedText.printTapeLsHeader(); break;
case HeaderType::REPACK_LS: formattedText.printRepackLsHeader(); break;
case HeaderType::NONE:
default: break;
}
......
This diff is collapsed.
......@@ -24,46 +24,109 @@
namespace cta {
namespace admin {
class CtaAdminTextFormatter
class TextFormatter
{
public:
// Output headers
static void printAfLsHeader();
static void printAfLsSummaryHeader();
static void printFrLsHeader();
static void printFrLsSummaryHeader();
static void printLpaHeader();
static void printLpaSummaryHeader();
static void printLprHeader();
static void printLprSummaryHeader();
static void printTpLsHeader();
static void printTapeLsHeader();
static void printRepackLsHeader();
/*!
* Constructor
*
* @param[in] bufLines Number of text lines to buffer before flushing formatted output
* (Not used for JSON output which does not need to be formatted
* so can be streamed directly)
*/
TextFormatter(unsigned int bufLines = 1000) :
m_bufLines(bufLines) {
m_outputBuffer.reserve(bufLines);
}
~TextFormatter() {
flush();
}
// Output headers
void printAfLsHeader();
void printAfLsSummaryHeader();
void printFrLsHeader();
void printFrLsSummaryHeader();
void printLpaHeader();
void printLpaSummaryHeader();
void printLprHeader();
void printLprSummaryHeader();
void printTapePoolLsHeader();
void printTapeLsHeader();
void printRepackLsHeader();
// Output records
static void print(const ArchiveFileLsItem &afls_item);
static void print(const ArchiveFileLsSummary &afls_summary);
static void print(const FailedRequestLsItem &frls_item);
static void print(const FailedRequestLsSummary &frls_summary);
static void print(const ListPendingArchivesItem &lpa_item);
static void print(const ListPendingArchivesSummary &lpa_summary);
static void print(const ListPendingRetrievesItem &lpr_item);
static void print(const ListPendingRetrievesSummary &lpr_summary);
static void print(const TapePoolLsItem &tpls_item);
static void print(const TapeLsItem &tals_item);
static void print(const RepackLsItem &rels_item);
// Output records
void print(const ArchiveFileLsItem &afls_item);
void print(const ArchiveFileLsSummary &afls_summary);
void print(const FailedRequestLsItem &frls_item);
void print(const FailedRequestLsSummary &frls_summary);
void print(const ListPendingArchivesItem &lpa_item);
void print(const ListPendingArchivesSummary &lpa_summary);
void print(const ListPendingRetrievesItem &lpr_item);
void print(const ListPendingRetrievesSummary &lpr_summary);
void print(const TapePoolLsItem &tpls_item);
void print(const TapeLsItem &tals_item);
void print(const RepackLsItem &rels_item);
private:
// Static method to convert time to string
static std::string timeToString(const time_t &time)
{
std::string timeString(ctime(&time));
timeString.resize(timeString.size()-1); //remove newline
return timeString;
}
static constexpr const char* const TEXT_RED = "\x1b[31;1m"; //!< Terminal formatting code for red text
static constexpr const char* const TEXT_NORMAL = "\x1b[0m"; //!< Terminal formatting code for normal text
//! Add a line to the buffer
template<typename... Args>
void push_back(Args... args) {
std::vector<std::string> line;
buildVector(line, args...);
m_outputBuffer.push_back(line);
if(m_outputBuffer.size() >= m_bufLines) flush();
}
//! Recursive variadic method to build a log string from an arbitrary number of items of arbitrary type
template<typename T, typename... Args>
static void buildVector(std::vector<std::string> &line, const T &item, Args... args) {
buildVector(line, item);
buildVector(line, args...);
}
//! Base case method to add one item to the log
static void buildVector(std::vector<std::string> &line, const std::string &item) {
line.push_back(item);
}
//! Base case method to add one item to the log, overloaded for char*
static void buildVector(std::vector<std::string> &line, const char *item) {
line.push_back(std::string(item));
}
//! Base case method to add one item to the log, overloaded for bool
static void buildVector(std::vector<std::string> &line, bool item) {
line.push_back(item ? "true" : "false");
}
/*!
* Base case method to add one item to the log, with partial specialisation
* (works for all integer and floating-point types)
*/
template<typename T>
static void buildVector(std::vector<std::string> &line, const T &item) {
line.push_back(std::to_string(item));
}
//! Convert double to string with one decimal place precision and a suffix
static std::string doubleToStr(double value, char unit);
//! Convert UNIX time to string
static std::string timeToStr(const time_t &unixtime);
//! Convert data size in bytes to abbreviated string with appropriate size suffix (K/M/G/T/P/E)
static std::string dataSizeToStr(uint64_t value);
//! Flush buffer to stdout
void flush();
unsigned int m_bufLines; //!< Number of text lines to buffer before flushing formatted output
std::vector<std::vector<std::string>> m_outputBuffer; //!< Buffer for text output (not used for JSON)
static constexpr const char* const TEXT_RED = "\x1b[31;1m"; //!< Terminal formatting code for red text
static constexpr const char* const TEXT_NORMAL = "\x1b[0m"; //!< Terminal formatting code for normal text
};
}}
......@@ -89,7 +89,7 @@ echo "Launching repack request for VID ${VID_TO_REPACK}, bufferURL = ${FULL_REPA
admin_cta re add --vid ${VID_TO_REPACK} --justmove --bufferurl ${FULL_REPACK_BUFFER_URL}
SECONDS_PASSED=0
while test 0 = `admin_cta repack ls --vid ${VID_TO_REPACK} | grep -E "Complete|Failed" | wc -l`; do
while test 0 = `admin_cta --json repack ls --vid ${VID_TO_REPACK} | jq -r '.[0] | select(.status == "Complete" or .status == "Failed")' | wc -l`; do
echo "Waiting for repack request on tape ${VID_TO_REPACK} to be complete: Seconds passed = $SECONDS_PASSED"
sleep 1
let SECONDS_PASSED=SECONDS_PASSED+1
......@@ -99,7 +99,7 @@ while test 0 = `admin_cta repack ls --vid ${VID_TO_REPACK} | grep -E "Complete|F
exit 1
fi
done
if test 1 = `admin_cta repack ls --vid ${VID_TO_REPACK} | grep -E "Failed" | wc -l`; then
if test 1 = `admin_cta --json repack ls --vid ${VID_TO_REPACK} | jq -r '.[0] | select(.status == "Failed")' | wc -l`; then
echo "Repack failed for tape ${VID_TO_REPACK}."
exit 1
fi
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment