WS++  v0.5.0-1152
Workflow/Spaces - C++ Library
fc::WS Class Referencefinal

Objects of this class lets C++ applications easily communicate with Unlimi-Tech's FileCatalyst Workflow/Spaces servers. More...

#include <FCWS.hpp>

Collaboration diagram for fc::WS:

Public Types

enum  EState {
  EState::kUnknown = 0,
  EState::kLoginDone,
  EState::kJobCreated,
  EState::kFileQueue,
  EState::kUploading,
  EState::kUploadDone,
  EState::kLogDone,
  EState::kFinalizeDone,
  EState::kFinished
}
 Internal state of the WS object is only exposed for debugging or logging purposes. More...
 

Public Member Functions

 WS ()
 Empty constructor. Nothing happens until login() is called. More...
 
 ~WS ()
 Destructor. More...
 
EState get_state () const
 Get an enum that represents the internal state of the WS object. More...
 
WSlogin (const std::string &url, const std::string &name, const std::string &pass)
 Login to the Workflow/Spaces server using the given base URL, username, and password. More...
 
WSlogout ()
 The Workflow/Spaces server does not have the concept of logout, but calling this method will drop the session cookie and reset the internal state of the WS object (blanking out the username, password, URL, etc) effectively doing what would be expected when a user logs out. More...
 
WScreateJob (const std::string &name, const StrMap &fields)
 Create the hot folder job. More...
 
WSqueueSingleFile (const std::string &filename)
 Queue a single file to be uploaded. More...
 
WSqueueRecursiveDirectory (const std::string &directory)
 Recursively traverse the specified directory and queue all files to be uploaded. More...
 
fc::GlobalStateAndStats uploadQueuedFiles (fc::StatisticsCallback callback=nullptr, void *ptr=nullptr)
 Upload all the files that were previously queued with queueSingleFile() or queueRecursiveDirectory(). More...
 
WSdoNothing ()
 Prevent idle timeout or firewall timeout by sending a "do nothing" command to the server. More...
 

Static Public Member Functions

static void initialize_third_party_libs ()
 Initialize 3rd-party libs. More...
 
static StrMap library_info ()
 Returns a map of strings with information on both Workflow/Spaces and the support libraries that it is using internally. More...
 

Public Attributes

std::string recent_url
 The full URL where WS most recently performed a GET or a POST request. More...
 
std::string server_xml
 The XML the server sent back from the previous command. More...
 
std::string server_reply
 Full output received from the server for the last command. More...
 
long server_response_code
 HTTP response code (e.g., "200") received from the server for the last command. More...
 
bool status_success
 The XML replies from the server contain a "status" node with an attribute named "success". More...
 
std::string message
 When a problem is detected, additional details may be stored in this string. More...
 

Detailed Description

Objects of this class lets C++ applications easily communicate with Unlimi-Tech's FileCatalyst Workflow/Spaces servers.

Jobs can be created and individual or recursive directory uploads can be completed in just a few lines of C++.

For example:

// create one of these objects on the stack
fc::WS ws;
// login to the server with the usual credentials
ws.login("https://demo1.filecatalystspaces.com", "bob", "secret");
// create a job by specifying all the required fields (2 fields in this example)
fc::StrMap m;
m["ShootDate"] = "08/31/2019";
m["location"] = "office";
ws.createJob("default", m);
// queue up as many files needed for the job
ws.queueSingleFile("backup.zip");
ws.queueSingleFile("backup_results.txt");
// perform the actual upload and finalize the job

Methods of interest:

When uploading files, an optional callback can be specified to uploadQueuedFiles() to receive transfer statistics once per second.

For example:

void my_custom_callback(const fc::GlobalStateAndStats & state_and_stats, void * ptr)
{
// This function will be called once per second.
//
// Normally in the upload callback, we want to copy the stats and
// immediately return to the caller so the upload can continue.
// Another thread would then take the copied stats and display them
// as a progress bar, or provide some sort of feedback to the user.
//
// In this example code, we don't hand off the stats to another
// thread, but instead we'll calculate a percentage and display
// them using std::cout.
//
// This isn't what we should be doing since the (relatively slow)
// console I/O will temporarily interrupt the file transfer. But
// the purpose of this example code is to show what can be done
// using the callback and the transfer stats.
const auto bytes_left = state_and_stats.stats.remainingNumberOfPayloadBytesToTransfer;
const auto bytes_sent = state_and_stats.stats.totalNumberOfPayloadBytesTransferred;
const auto bytes_total = bytes_left + bytes_sent;
const auto files_left = state_and_stats.stats.remainingNumberOfFilesToSend;
const auto files_sent = state_and_stats.stats.totalNumberOfFilesSent;
const auto files_total = files_left + files_sent;
std::cout
<< "File #" << state_and_stats.fileStatsIdx << " of " << files_total << ": "
<< std::round(100.0 * bytes_sent / bytes_total) << "%" << std::endl;
return;
}

The callback is specified when the files are uploaded. For example:

fc::WS ws;
// ...
ws.uploadQueuedFiles(my_custom_callback);
See also
Using WS++

Member Enumeration Documentation

◆ EState

enum fc::WS::EState
strong

Internal state of the WS object is only exposed for debugging or logging purposes.

This state is not intended for users of the WS++ API, and may change or be removed in future versions.

See also
fc::WS::get_state()
fc::to_string()
Enumerator
kUnknown 

Invalid or unknown state.

kLoginDone 

Login was successful.

See also
login()
kJobCreated 

Job creation was successful.

See also
createJob()
kFileQueue 

Ready to queue files.

See also
queueSingleFile()
queueRecursiveDirectory()
kUploading 

Upload in progress.

See also
uploadQueuedFiles()
kUploadDone 

Upload was successful.

See also
uploadQueuedFiles()
kLogDone 

Summary log was successful.

kFinalizeDone 

Finalize was successful.

kFinished 

Job has finished.

Constructor & Destructor Documentation

◆ WS()

fc::WS::WS ( )

Empty constructor. Nothing happens until login() is called.

◆ ~WS()

fc::WS::~WS ( )

Destructor.

Member Function Documentation

◆ initialize_third_party_libs()

void fc::WS::initialize_third_party_libs ( )
static

Initialize 3rd-party libs.

This will initialize both libcurl and libxml2. If your application already uses and initializes these two libraries, then this call is not necessary. Otherwise, call this static function prior to instantiating the first WS object.

For example:

Calling fs::WS::initialize_third_party_libs() is equivalent to:

curlpp::initialize(); // libcurlpp
xmlInitParser(); // libxml2
// ...and several other minor libxml2 support calls

◆ library_info()

fc::StrMap fc::WS::library_info ( )
static

Returns a map of strings with information on both Workflow/Spaces and the support libraries that it is using internally.

Mostly version strings for libraries. Useful for debug and logging purposes.

For example, the map returned could contain the following:

{
{"Boost library" , "1.65.1" },
{"Build date" , "Jun 22 2019 16:06:43" },
{"Build type" , "Linux-64-release" },
{"FC++ library" , "0.7.2-1130" },
{"OpenSSL library", "OpenSSL 1.1.1 11 Sep 2018"},
{"Workflow/Spaces", "0.5.0-1138" },
{"XML2 library" , "2.9.4" },
{"cURL library" , "libcurl/7.58.0 OpenSSL/1.1.1 zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3"},
{"cURLpp wrapper" , "0.8.1" }
};

◆ get_state()

fc::WS::EState fc::WS::get_state ( ) const

Get an enum that represents the internal state of the WS object.

For example:

fc::WS ws;
ws.login(url, username, password);
std::cout << "state: " << fc::to_string(ws.get_state()) << std::endl;

The above code might display the state as "login done".

See also
fc::to_string()

◆ login()

fc::WS & fc::WS::login ( const std::string &  url,
const std::string &  name,
const std::string &  pass 
)

Login to the Workflow/Spaces server using the given base URL, username, and password.

All of the available forms and required fields should be listed in the resulting XML output.

See also
server_xml

For example:

fc::WS ws;
ws.login("https://demo1.filecatalystspaces.com", "bob", "secret");
std::cout << ws.server_xml << std::endl;
Exceptions
fc::ExceptionThis method will throw a C++ exception if the login process fails. See FC++ Exceptions for details.

◆ logout()

fc::WS & fc::WS::logout ( )

The Workflow/Spaces server does not have the concept of logout, but calling this method will drop the session cookie and reset the internal state of the WS object (blanking out the username, password, URL, etc) effectively doing what would be expected when a user logs out.

It is valid to call logout() even when the WS object is not logged in.

◆ createJob()

fc::WS & fc::WS::createJob ( const std::string &  name,
const StrMap &  fields 
)

Create the hot folder job.

The fields required are in the XML obtained after calling login().

For example:

fc::WS ws;
ws.login("https://demo1.filecatalystspaces.com", "bob", "secret");
// examine the XML in ws.server_xml and populate the necessary fields
std::cout << ws.server_xml << std::endl;
fc::StrMap m;
m["ShootDate"] = "08/31/2019";
m["location"] = "office";
ws.createJob("default", m);
Exceptions
fc::ExceptionThis method will throw a C++ exception if the create job process fails. See FC++ Exceptions for details.

◆ queueSingleFile()

fc::WS & fc::WS::queueSingleFile ( const std::string &  filename)

Queue a single file to be uploaded.

Exceptions
fc::ExceptionThis method will throw a C++ exception if the local file cannot be queued. See FC++ Exceptions for details.

◆ queueRecursiveDirectory()

fc::WS & fc::WS::queueRecursiveDirectory ( const std::string &  directory)

Recursively traverse the specified directory and queue all files to be uploaded.

Exceptions
fc::ExceptionThis method will throw a C++ exception if the local directory cannot be queued. See FC++ Exceptions for details.

◆ uploadQueuedFiles()

fc::GlobalStateAndStats fc::WS::uploadQueuedFiles ( fc::StatisticsCallback  callback = nullptr,
void *  ptr = nullptr 
)

Upload all the files that were previously queued with queueSingleFile() or queueRecursiveDirectory().

Parameters
[in]callbackA C-style function can be specified to receive a callback once per second when the transfer stats are updated during the upload. This callback interrupts the file transfer, so it must complete quickly. Additional details are available at fc::StatisticsCallback .
[in]ptrA C-style "void *" user pointer that will also be passed to the callback.
Returns
Returns a copy of the global and per-file transfer statistics for every file uploaded to the server. Additional details are available at fc::GlobalStateAndStats .

For example:

fc::WS ws;
// [skipping login, create job, and queueing up files for upload]
// upload the queued files and get a copy of both the global and per-file statistics
const fc::GlobalStateAndStats state_and_stats = ws.uploadQueuedFiles();
const fc::GlobalStats & global_stats = state_and_stats.stats;
const fc::TransferStatsMap & file_stats_map = state_and_stats.fileStatsMap;
// display all of the per-file statistics for each file uploaded
for (const auto & [index, file_stats] : file_stats_map)
{
std::cout
<< "Individual file stats for index #" << index << ":" << std::endl
<< file_stats.getStr("-> ", true) << std::endl;
}
// display the global statistics for the combination of all files uploaded
std::cout
<< "Global stats:" << std::endl
<< "-> Files sent: " << global_stats.totalNumberOfFilesSent << std::endl
<< "-> Files received: " << global_stats.totalNumberOfFilesReceived << std::endl
<< "-> Files remaining to send: " << global_stats.remainingNumberOfFilesToSend << std::endl
<< "-> Files remaining to receive: " << global_stats.remainingNumberOfFilesToReceive << std::endl
<< "-> Total bytes transferred: " << fc::formatBytesIEC (global_stats.totalNumberOfPayloadBytesTransferred) << std::endl
<< "-> Total bytes skipped: " << fc::formatBytesIEC (global_stats.totalNumberOfPayloadBytesSkipped) << std::endl
<< "-> Bytes remaining: " << fc::formatBytesIEC (global_stats.remainingNumberOfPayloadBytesToTransfer) << std::endl
<< "-> Transfer rate: " << fc::formatTransferRate (global_stats.bitsPerSecondAverageTransferRate) << std::endl
<< "-> Time started: " << fc::formatTimeRecent (global_stats.timeStarted) << std::endl
<< "-> Time reamining: " << fc::formatTimeDuration2(global_stats.timeRemaining) << std::endl
<< "" << std::endl;

This should produce output similar to this:

...
Individual file stats for index #3:
-> Average transfer rate: 120.57 Kbps
-> Block size: 9.35 KiB
-> Blocks completed: 1
-> Bytes expected: 9.34 KiB
-> Bytes transferred: 9.35 KiB
-> DATA packets received: 10
-> Duplicate packets: 2
-> ECHO packets received: 3
-> Encrypted: false
-> File transfer state: fc::TransferStats::kTransferFinished [22]
-> Immediate transfer rate: 0 bps
-> Local filename: ./test.zip
-> MD5 state: fc::TransferStats::kMd5Skipped [13]
-> Metrics packets received: 1
-> Metrics packets sent: 2
-> Packets received: 6
-> Packets sent: 17
-> Remote filename: /test.zip
-> Sock writer starved: 5
-> Temporary filenames: disabled
-> Timestamp begin: 4 seconds ago
-> Timestamp block finish: 4 seconds ago
-> Timestamp finish: 4 seconds ago
-> Transfer type: upload
-> Type: fc::TransferStats::kFull [30]
-> Unit size: 0.93 KiB
Global stats:
-> Files sent: 3
-> Files received: 0
-> Files remaining to send: 0
-> Files remaining to receive: 0
-> Total bytes transferred: 25.47 KiB
-> Total bytes skipped: 0 B
-> Bytes remaining: 0 B
-> Transfer rate: 19.76 Kbps
-> Time started: 11 seconds ago
-> Time reamining: 0:00
Exceptions
fc::ExceptionThis method will throw a C++ exception if the queued files cannot be uploaded. See FC++ Exceptions for details.

◆ doNothing()

fc::WS & fc::WS::doNothing ( )

Prevent idle timeout or firewall timeout by sending a "do nothing" command to the server.

It is the user's responsability to call this periodically from a secondary thread during long file transfers to prevent firewall timeouts of the Workflow/Spaces session.

Note
This command does not return any XML output.
Exceptions
fc::ExceptionThis method will throw a C++ exception if the "do nothing" request fails. See FC++ Exceptions for details.

Member Data Documentation

◆ recent_url

std::string fc::WS::recent_url

The full URL where WS most recently performed a GET or a POST request.

This is mostly for debug or logging purposes.

◆ server_xml

std::string fc::WS::server_xml

The XML the server sent back from the previous command.

This is guaranteed to be either XML or an empty string. There are some commands – such as doNothing() – which return plain text versus XML, in which case this string will be blank.

See also
server_reply
server_response_code

◆ server_reply

std::string fc::WS::server_reply

Full output received from the server for the last command.

This may be plain text or XML, depending on the previous command.

See also
server_xml
server_response_code

◆ server_response_code

long fc::WS::server_response_code

HTTP response code (e.g., "200") received from the server for the last command.

See also
server_xml
server_reply

◆ status_success

bool fc::WS::status_success

The XML replies from the server contain a "status" node with an attribute named "success".

For example:

<result>
<status success="true" comments=" " version="2.1"/>
<job id="308" uploadPath="/"/>
<securityTag isSecure="true"/>
</result>

The value in the "success" attribute is stored in this boolean flag. Callers can then quickly determine if the previous command was successful.

For example:

fc::WS ws;
ws.login("https://demo1.filecatalystspaces.com", "bob", "secret");
{
// login was successful
// ...
}
Note
With normal use of the WS++ library, it is unecessary to check the status_success flag since WS++ throws a C++ exception when an error is detected, such as when the "success" attribute is set to "false". See FC++ Exceptions for details.

◆ message

std::string fc::WS::message

When a problem is detected, additional details may be stored in this string.

If a C++ exception is thrown from within WS++, then the first line of the exception will also be stored in this text string for debug or logging purposes.


The documentation for this class was generated from the following files: