Sample Code for the Synchronize Action
The following sample code demonstrates a complete synchronize
action.
The synchronize action in this example generates documents for integers from 2
up to a configured limit IntegerLimit
. Each document contains some properties of the integer as metadata.
The connector.hpp
header file defines the MyConnector
class, but does not provide the implementations of the functions. This example does not require the full <autonomy/connector/connector.hpp>
include, and instead only includes the header <autonomy/connector/cppsdk/connectorBase.hpp>
.
// Source File: connector.hpp #include <autonomy/connector/cppsdk/connectorBase.hpp> namespace myconnectornamespace { using namespace autonomy::connector::cppsdk; class MyConnector : public ConnectorBase { public: MyConnector(); Features::feature_type features(); void synchronize(const SynchronizeTask& task); }; } //namespace myconnectornamespace
The implementation of the functions in the MyConnector
class is in the connector.cpp
source file. This file also includes the full <autonomy/connector/connector.hpp>
and uses the
CONNECTOR_LIBRARY_CLASS
macro to specify the connector class to use.
The implementation of the synchronize function is directed to a new MySynchronize
class.
// Source File: connector.cpp #include "connector.hpp" #include "synchronize.hpp" #include <autonomy/connector/connector.hpp> namespace myconnectornamespace { using namespace autonomy::connector::cppsdk; MyConnector::MyConnector() : ConnectorBase("My Connector") {} Features::feature_type MyConnector::features() { return Features::synchronize; } void MyConnector::synchronize(const SynchronizeTask& task) { MySynchronize mySynchronize(task); mySynchronize.synchronize(); } } //namespace myconnectornamespace CONNECTOR_LIBRARY_CLASS(myconnectornamespace::MyConnector)
The synchronize.hpp
header file defines the MySynchronize
class. This class performs the synchronization. Only the header <autonomy/connector/cppsdk/tasks/synchronizeTask.hpp>
is included, and this includes all the classes that might be required for a synchronize action.
An instance of this class holds the SynchronizeTask
object m_task
and, for convenience, an instance of the DocInfoBuilder
m_builder
along with some additional data used during a call to the action.
The synchronize()
function is called to begin the synchronization.
// Source File: synchronize.hpp #include <autonomy/connector/cppsdk/tasks/synchronizeTask.hpp> namespace myconnectornamespace { using namespace autonomy::connector::cppsdk; class MySynchronize {
SynchronizeTask m_task; DocInfoBuilder m_builder; int m_limit; std::vector<int> m_largestFactor; public: MySynchronize(const SynchronizeTask& task); void synchronize(); DocInfo buildDocInfo(int n); }; } //namespace myconnectornamespace
The final source file synchronize.cpp
contains the implementation of the action.
The implementation of parts of the functions is omitted here but can be found in full in the code samples provided in the SDK.
This code shows use of an IngestResultHandler
to perform logging. It demonstrates the use of the shouldStop()
function that is present to check whether the user has requested the action or the connector to stop. It also shows various ways to add data to a document.
// Source File: synchronize.cpp #include "synchronize.hpp" #include <map> #include <set> namespace myconnectornamespace { using namespace autonomy::connector::cppsdk; class IngestResultHandler : public Ingester::ResultHandler { Log m_log; public: IngestResultHandler(const Log& log) : m_log(log) {} void operator()(const IngestTask& ingestTask) { if (ingestTask.status() == IngestTaskStatus::Done) { m_log.full("Document " + ingestTask.document().reference() + ", ingest " + ingestTask.typeString() + " succeeded!"); } else { m_log.full("Ingestion failed for " + ingestTask.document().reference()); } } }; // static std::string intToStr(int value) ... MySynchronize::MySynchronize(const SynchronizeTask& task) : m_task(task), m_builder(task.docInfoBuilder()), m_limit(task.taskConfig().getInt("IntegerLimit", 1000)), m_largestFactor(m_limit + 1, 0) { IngestResultHandler resultHandler(task.log()); task.ingester().addResultHandler(resultHandler); // Perform some initialization ... } void MySynchronize::synchronize() { for (int n = 2; n <= m_limit; ++n) { if (m_task.shouldStop()) break; DocInfo docInfo = buildDocInfo(n); m_task.ingester().add(docInfo); } } DocInfo MySynchronize::buildDocInfo(int n) { DocInfo docInfo = m_builder.createDocInfo(intToStr(n)); Metadata metadata = docInfo.doc().metadata(); metadata.addField("IS_PRIME", m_largestFactor[n] == n ? "TRUE" : "FALSE"); Field factorsField = metadata.addField("FACTORS"); // Local variables ... for (std::map<int, int>::const_iterator it = primeFactors.begin(); it != primeFactors.end(); ++it) { // Various calculations ... Field factorField = factorsField.addField("FACTOR"); factorField.setAttribute("PRIME", intToStr(p)); factorField.setAttribute("EXPONENT", intToStr(e)); } // Construct additional field values ... docInfo.doc().appendContent(divs.str()); return docInfo; } } //namespace myconnectornamespace
An example document produced by this code is shown below. To see the documents that are produced in the connector's temporary directory, set the parameter IngestWriteXML=TRUE
in the [Ingestion]
section of the configuration file.
<DOCUMENT> <DREREFERENCE>840</DREREFERENCE> <AUTN_GROUP>Connector</AUTN_GROUP> <AUTN_IDENTIFIER>PGlkIHM9Ik1ZVEFTSzEiIHI9Ijg0MCIvPg==</AUTN_IDENTIFIER> <DIVISORS>32</DIVISORS> <DocTrackingId>fa83a11a198d5a7f0bf77a1987bcd006</DocTrackingId> <FACTORIZATION>2^3 3^1 5^1 7^1</FACTORIZATION> <FACTORS> <FACTOR PRIME="2" EXPONENT="3"/> <FACTOR PRIME="3" EXPONENT="1"/> <FACTOR PRIME="5" EXPONENT="1"/> <FACTOR PRIME="7" EXPONENT="1"/> </FACTORS> <IS_PRIME>FALSE</IS_PRIME> <IS_SQUAREFREE>FALSE</IS_SQUAREFREE> <TOTIENT>192</TOTIENT> <DRECONTENT>1 2 3 4 5 6 7 8 10 12 14 15 20 21 24 28 30 35 40 42 56 60 70 84 105 120 140 168 210 280 420 840</DRECONTENT> </DOCUMENT>