dca_interface  6.3.4
customdb_samples/createdbsample/main.cpp
1 /* IBM Source Code */
2 /* (C) Copyright IBM Corp. 2012 */
3 /* Licensed Materials - Property of IBM */
4 /* US Government Users Restricted Rights - Use duplication or disclosure restricted by GSA Schedule Contract with IBM Corp. */
5 
36 #include <string>
37 #include <set>
38 #include <iostream>
39 #include <fstream>
40 #include <sstream>
41 #include <ctime>
42 
43 #include "dca/dca_base.h"
46 #include "dca/dca_callbacks.h"
47 
48 using namespace dca;
49 
50 const std::string S_ToolName = "createdbsample";
51 const std::string S_ToolVersion = "1.0";
52 
53 std::string custom_db_folder;
54 
55 // URL sample string
56 const std::string S_UrlString( "www.an_example_custom_url.com" );
57 
62 const std::string S_UsageString =
63  "<redist-folder> <ticket> <product> <custom-db-folder>\n"
64  " redist-folder - the folder where the DCA is installed to\n"
65  " ticket - a valid ticket\n"
66  " product - the product associated with your ticket\n"
67  " custom-db-folder - the folder where the Custom Database should be created in\n\n"
68  ;
69 
74 #ifdef WIN32
75 # define DCA_BINDIR "bin/Win32"
76 #else
77 # define DCA_BINDIR "bin/linux"
78 #endif
79 
84 #define DCA_INITDIR "init"
85 
89 #define DCA_LOGDIR "./logs"
90 
101 static void SetupInitData( const std::string& redist_folder, InitData& initData )
102 {
103  initData.binDir = redist_folder + DCA_BINDIR;
104  initData.initDir = redist_folder + DCA_INITDIR;
105  initData.logDir = DCA_LOGDIR;
106 }
107 
116 static void SetupLicense( const std::string& ticket, const std::string& product,
117  LicenseData& licenseData )
118 {
119  licenseData.ticket = ticket;
120  licenseData.product = product;
121 }
122 
131 static void SetupConnectionData( const std::string& custom_db_folder,
132  DbConnectionData& cData )
133 {
134  cData.useLocalDatabase = true;
135  cData.dbType = DBT_Custom;
136  cData.customData.configDir = custom_db_folder;
137 }
138 
143 static void PrintToolHeader()
144 {
145  std::cout << "IBM DCA Sample: " << S_ToolName << " (" << S_ToolVersion <<
146  ")" << std::endl;
147 }
148 
154 static void PrintUsage( const char *name )
155 {
156  std::cout << " usage:" << std::endl;
157  std::cout << name << " " << S_UsageString << std::endl;
158 }
159 
166 static void PrintLicenseInfo( const License& aLicense )
167 {
168  const time_t expirationDate = aLicense.getExpirationDate();
169  struct tm *expirationTime = localtime( &expirationDate );
170 
171  std::cout << "License Info:" << std::endl;
172  std::cout << " DCA is " << ( aLicense.isLicensed() ? "licensed." :
173  "not licensed." ) << std::endl;
174  std::cout << " MaxUsers:" << aLicense.getMaxUsers() <<
175  std::endl;
176  std::cout << " MaxSessions:" << aLicense.getMaxSessions() <<
177  std::endl;
178  std::cout << " Ticket:" << aLicense.getTicket() <<
179  std::endl;
180  std::cout << " Session:" << aLicense.getSession() <<
181  std::endl;
182  std::cout << " Last Message:" << aLicense.getLastMessage() <<
183  std::endl;
184  std::cout << " Expiration Date:" << asctime( expirationTime ) <<
185  std::endl;
186 }
187 
195 void AddUrlAndCategories( UrlCustomDb& aUrlCustomDb, const std::string& aUrlString,
196  const CategorySet& aCategories )
197 {
198  std::ostringstream log;
199  log << " Added URL '" << aUrlString << "'";
200 
201  int added_cnt = 0;
202 
203  for( CategorySet::const_iterator I = aCategories.begin(),
204  IEnd = aCategories.end(); I != IEnd; ++I )
205  {
206  if( added_cnt == 0 )
207  log << " with categories [";
208 
209  log << (*I);
210 
211  if( ( added_cnt == 0 ) || ( added_cnt < (int)aCategories.size() - 1 ) )
212  log << ", ";
213 
214  ++added_cnt;
215  }
216  if( added_cnt )
217  log << "]";
218 
219  log << " to the custom database";
220 
221  // add the URL to the custom database with the given categories
222  aUrlCustomDb.setUrl( aUrlString, aCategories );
223  std::cout << log.str() << std::endl;
224 }
225 
232 void RemoveUrl( UrlCustomDb& aUrlCustomDb, const std::string& aUrlString )
233 {
234  aUrlCustomDb.removeUrl( aUrlString );
235  std::cout << " Removed URL '" << aUrlString <<
236  "' from the custom database" << std::endl;
237 }
238 
249 bool LookupUrl( const DcaInstance& theDca, const UrlDbClassifier& aUrlDbClassifier,
250  const std::string& aUrlString, UrlClassificationResults&
251  aUrlClassificationResults )
252 {
253  Url myUrl = Url::create( theDca, aUrlString );
254 
255  FunctionResult myFR = aUrlDbClassifier.classify( myUrl, aUrlClassificationResults );
256  if( !myFR ) {
257  std::cerr << "Error occured while calling UrlDbClassifier::classify() RC:" <<
258  myFR.getReturnCode() << ", Details:" << myFR.getDescription() <<
259  std::endl;
260  return false;
261  }
262 
263  return true;
264 }
265 
277 bool CreateCustomDbFile( UrlCustomDbModule& aUrlCustomDbModule,
278  const std::string& dbfolder )
279 {
280  FunctionResult fr = aUrlCustomDbModule.createCustomDb(
281  dbfolder );
282 
283  if( !fr ) {
285  std::cerr << "Error: Database already exists" <<
286  std::endl;
287  }
288  else {
289  std::cerr << "Creation of custom database failed: RC:" <<
290  fr.getReturnCode() << ", Details:" <<
291  fr.getDescription() << std::endl;
292  }
293  return false;
294  }
295 
296  return true;
297 }
298 
316 bool CreateCustomDbInstances( const DcaInstance& theDca, const License& aLicense,
317  UrlCustomDbModule& aUrlCustomDbModule, DbConnection& aDbConnection,
318  const std::string& dbfolder, UrlCustomDb& aUrlCustomDb )
319 {
320  try {
321  // set up a the database connection to the custom database
322  DbConnectionData myDbConnectionData;
323  SetupConnectionData( dbfolder, myDbConnectionData );
324 
325  // Create a database connect to the custom database file. On error
326  // this will throw a ExDca exception
327  aDbConnection = theDca.createDbConnection( aLicense, myDbConnectionData );
328 
329  // create the CustomDb instance. On error this will throw a ExDca exception
330  aUrlCustomDb = aUrlCustomDbModule.openCustomDb( aDbConnection );
331 
332  return true;
333  }
334  catch( const ExDca& ex ) {
335  std::cerr << "EcDca Exception caught. Details: " << ex.getDescription()
336  << " (" << ex.getReturnCode() << ")" << std::endl;
337  return false;
338  }
339  catch( const std::exception& stdex ) {
340  std::cerr << "std::exception caught. Details: " << stdex.what() <<
341  std::endl;
342  return false;
343  }
344 }
345 
359 bool CreateUrlClassificationInstances( const DcaInstance& theDca, const License& aLicense,
360  const DbConnection& aDbConnection, UrlClassification& aUrlClassification,
361  UrlDbClassifier& aUrlDbClassifier )
362 {
363  try {
364  // create the url classification module itself
365  aUrlClassification = UrlClassification::create( theDca, aLicense );
366 
367  // create an UrlDbClassifier
368  aUrlDbClassifier = aUrlClassification.createDbClassifier( aDbConnection );
369 
370  return true;
371  }
372  catch( const ExDca& ex ) {
373  std::cerr << "EcDca Exception caught. Details: " << ex.getDescription()
374  << " (" << ex.getReturnCode() << ")" << std::endl;
375  return false;
376  }
377  catch( const std::exception& stdex ) {
378  std::cerr << "std::exception caught. Details: " << stdex.what() <<
379  std::endl;
380  return false;
381  }
382  catch(...) {
383  std::cerr << "Unknown exception caught" << std::endl;
384  return false;
385  }
386 }
387 
404 bool ProcessCustomDatabase( const DcaInstance& theDca, const License& aLicense )
405 {
406  std::cout << "Started ProcessCustomDatabase" << std::endl;
407 
408  std::cout << "* Initializing custom database module" << std::endl;
409 
410  // initialize the UrlCustomModule
411  UrlCustomDbModule myUrlCustomDbModule =
412  UrlCustomDbModule::create( theDca, aLicense );
413 
414  std::cout << "* Creating new custom database file in folder '" <<
415  custom_db_folder << "'" << std::endl;
416 
417  // create the custom database file physically
418  if( !CreateCustomDbFile( myUrlCustomDbModule, custom_db_folder ) ) {
419  return false;
420  }
421 
422  // create a database connection and a UrlCustomDb instance and connect then to
423  // the custom database file
424  std::cout << "* Creating DbConnection and UrlCustomDb instance"
425  << std::endl;
426 
427  DbConnection myDbConnection;
428  UrlCustomDb myUrlCustomDb;
429 
430  if( !CreateCustomDbInstances( theDca, aLicense, myUrlCustomDbModule,
431  myDbConnection, custom_db_folder, myUrlCustomDb ) ) {
432  return false;
433  }
434 
435  std::cout << "* Starting Test by adding an URL and Categories to the custom database"
436  << std::endl;
437 
438  // Add an URL (S_UrlString) to the custom database, categorized as 0 and 1
439  CategorySet myCategories;
440  myCategories.insert( 0 );
441  myCategories.insert( 1 );
442 
443  AddUrlAndCategories( myUrlCustomDb, S_UrlString, myCategories );
444 
445  std::cout << "* Try to retrieve added URL and Categories from the custom database"
446  << std::endl;
447 
448  // Retrieve the URL and its categories by using the UrlCustomDb instance
449  CategorySet myResultCategories;
450  if( !myUrlCustomDb.getUrl( S_UrlString, myResultCategories ) ) {
451  std::cerr << "Could not retrieve URL '" << S_UrlString <<
452  "' from UrlCustomDb instance" << std::endl;
453  return false;
454  }
455 
456  if( myResultCategories.size() != 2 ) {
457  std::cerr << "Could not retrieve the correct categories for URL '" <<
458  S_UrlString << "' using UrlCustomDb instance" << std::endl;
459  return false;
460  }
461 
462  CategorySet::const_iterator IEnd = myResultCategories.end();
463  if( myResultCategories.find( 0 ) != IEnd &&
464  myResultCategories.find( 1 ) != IEnd )
465  std::cout << " Lookup URL '" << S_UrlString <<
466  "' returned category 0 and 1" << std::endl;
467 
468  std::cout << "* Removing previously added URL from the custom database"
469  << std::endl;
470 
471  // Remove the URL S_UrlStirng from custom database
472  RemoveUrl( myUrlCustomDb, S_UrlString );
473 
474  std::cout << "* Verifying that it isn't in the custom database anymore"
475  << std::endl;
476 
477  // Verify that it's not in the custom database anymore
478  if( myUrlCustomDb.getUrl( S_UrlString, myResultCategories ) ) {
479  std::cerr << "URL '" << S_UrlString << "' is still in the " <<
480  "custom database." << std::endl;
481  return false;
482  }
483 
484  std::cout << "* Re-adding URL and Categories to the custom database for the next test"
485  << std::endl;
486 
487  // Add URL again
488  AddUrlAndCategories( myUrlCustomDb, S_UrlString, myCategories );
489 
490  // Now testing URL Classification with the custom database connection
491  // This is the common way how clients will use the custom database for lookups
492 
493  UrlClassification myUrlClassification;
494  UrlDbClassifier myUrlDbClassifier;
495 
496  std::cout << "* Creating UrlClassification and UrlDbClassifier instance"
497  << std::endl;
498 
499  if( !CreateUrlClassificationInstances( theDca, aLicense, myDbConnection,
500  myUrlClassification, myUrlDbClassifier ) )
501  {
502  // error logging is done in CreateUrlClassificationInstances
503  return false;
504  }
505 
506  // Retrieve the URL and its categories by using the UrlClassification
507  std::cout << "* Retrieving URL and Categories by using the UrlClassification instances"
508  << std::endl;
509 
510  UrlClassificationResults myResults;
511  if( !LookupUrl( theDca, myUrlDbClassifier, S_UrlString, myResults ) ) {
512  std::cerr << "Could not retrieve URL '" << S_UrlString <<
513  "' from UrlDbClassifier instance" << std::endl;
514  return false;
515  }
516 
517  if( myResults.size() != 2 ) {
518  std::cerr << "Could not retrieve the correct categories for URL '" <<
519  S_UrlString << "' using UrlDbClassifier instance" << std::endl;
520  return false;
521  }
522 
523  if( myResults.contains( 0 ) && myResults.contains( 1 ) ) {
524  std::cout << " Lookup URL '" << S_UrlString <<
525  "' returned category 0 and 1" << std::endl;
526  }
527 
528  std::cout << "* Done, leaving test function, cleanup of local instances " <<
529  "is done automatically by going out-of-scope" << std::endl;
530 
531  return true;
532 }
533 
545 int main( int argc, char *argv[] )
546 {
547  PrintToolHeader();
548 
549  int rc = 5;
550 
551  try {
552  if( argc < 5 ) {
553  PrintUsage( argv[0] );
554  return rc;
555  }
556 
557  std::string myRedistFolder = argv[ 1 ];
558  const std::string myTicket = argv[ 2 ];
559  const std::string myProduct = argv[ 3 ];
560  custom_db_folder = argv[ 4 ];
561 
562  if( myRedistFolder.empty() || myTicket.empty() ||
563  myProduct.empty() || custom_db_folder.empty() ) {
564  PrintUsage( argv[0] );
565  return rc;
566  }
567 
568  // check for trailing fileslash on directories - and add if necessary
569  char c = *(myRedistFolder.rbegin());
570  if( c != '/' && c != '\\' )
571  myRedistFolder += "/";
572 
573  c = *(custom_db_folder.rbegin());
574  if( c != '/' && c != '\\' )
575  custom_db_folder += "/";
576 
577  // init the 3rd party libraries
578  InitCUrl();
580 
581  { // scope for DcaInstance and License
582 
583  // setup DCA directories
584  InitData myInitData;
585  SetupInitData( myRedistFolder, myInitData );
586 
587  // instantiate the DCA API
588  DcaInstance myDca;
589  myDca = DcaInstance::create( myInitData );
590 
591  // setup license data
592  LicenseData myLicenseData;
593  SetupLicense( myTicket, myProduct, myLicenseData );
594  const License myLicense = myDca.createLicense( myLicenseData );
595 
596  // print out all information about the created License object
597  PrintLicenseInfo( myLicense );
598 
599  if( myLicense.isLicensed( UrlCustomDbModule::ID ) ) {
600  // Call the main test routine
601  if( ProcessCustomDatabase( myDca, myLicense ) )
602  rc = 0;
603  }
604  }
605  }
606  catch( const ExDca& ex ) {
607  std::cerr << "DCA Exception occured. Details: " << ex.getDescription()
608  << " (" << ex.getReturnCode() << ")" << std::endl;
609  rc = 10;
610  }
611  catch( const std::exception& s ) {
612  std::cerr << "std::exception occured. Details: " << s.what() <<
613  std::endl;
614  rc = 10;
615  }
616 
617  // deinit the 3rd party libraries
619  DeinitCUrl();
620 
621  return rc;
622 }
The Custom Database module, used to create new custom databases or open existing custom databases.
Is used to create a License object. A license first must be created with DcaInstance::createLicense t...
Definition: base_classes.h:547
Exception class used in the DCA.
Definition: base_classes.h:237
UrlCustomDb openCustomDb(const DbConnection &aDbConnection) const
Creates a UrlCustomDb instance that is connected to the database defined by the given DbConnection.
static Url create(const DcaInstance &aDcaInstance, const std::string &urlString)
Standard Url creation function.
void InitCUrl()
Initializes libcurl. Do not use any DCA function before initializing libcurl.
std::string initDir
the directory in which the DCA init files are stored
Definition: base_classes.h:266
int getMaxSessions() const
Returns the maximum allowed sessions associated with your ticket/license.
static UrlCustomDbModule create(const DcaInstance &aDcaInstance, const License &aLicense)
Loads and initializes the custom database module.
time_t getExpirationDate() const
Returns the expiration date of the license in UTC.
std::string getDescription() const
Returns a description of the error.
std::string configDir
Specifies the complete folder path where the custom database is located, or the folder in which it sh...
Definition: base_classes.h:754
DbConnectionCustomData customData
Fill out this structure only if you are using a custom database.
Definition: base_classes.h:823
const int ERR_DATABASE_ALREADY_EXISTING
Error code: The specified database already exists.
DCA_RESULT_TYPE getReturnCode() const
Returns the last error code (if any).
FunctionResult classify(const Url &aUrl, UrlClassificationResults &urlResults) const
Performs the URL classification and returns the results.
static void SetupInitData(const std::string &redist_folder, InitData &initData)
Sets up the given initData by substituting the given redist_folder with DCA subdirectories.
std::string binDir
the directory in which the DCA binary (*.dca) files are stored
Definition: base_classes.h:265
void removeUrl(const std::string &aUrlString)
Removes the given URL string from the database, if present.
This header includes initialization/deinitialization support functions for the 3rd party libraries us...
Encapsulates the Custom Database maintenance interface.
void SetOpenSslCallbacks()
Initializes the required callbacks for OpenSSL when using HTTPS or SSL connections in a multi-threade...
Stores the connection data for a database.
Definition: base_classes.h:815
void UnsetOpenSslCallbacks()
Unsets the openssl callbacks. Do not call any DCA function after you have called this function.
int getMaxUsers() const
Returns the maximum allowed users associated with your ticket/license.
void DeinitCUrl()
Deinitializes libcurl. Do not call any DCA function after you have called this function.
Database connection class for a local or remote database.
Definition: base_classes.h:859
void setUrl(const std::string &aUrlString, const CategorySet &categories)
Updates or creates categories for the given URL string.
This header includes all header files of the URL Classification Package.
#define DCA_LOGDIR
Relative directory for logfile(s).
Main class for the URL classification.
#define DCA_INITDIR
DCA subdirectory of the DCA initialization data.
DCA_RESULT_TYPE getReturnCode() const
Gets the code of the error.
Results of an URL classification.
URL database classifier class.
static void PrintToolHeader()
Prints out the name and the version of this sample.
bool contains(DCA_CATEGORY_ID_TYPE catid) const
Fast method to see whether the results contain a given category or not.
Use a License to initialize a classification package or a toolbox package.
Definition: base_classes.h:560
FunctionResult createCustomDb(const std::string &aDatabaseFolder) const
Creates a new custom database file in the given folder.
const DbType DBT_Custom
Used for DbConnection classes of custom databases.
bool isLicensed(DCA_MODULE_ID_TYPE id=0, bool force=false) const
Checks whether the given License is valid for the given module id.
static void PrintLicenseInfo(const License &aLicense)
Prints out the information about the provided License.
std::string ticket
The ticket as provided in the license.
Definition: base_classes.h:548
This header includes all header files of the DCA Base Package.
bool useLocalDatabase
Set to true to connect to a local or custom database, set to false to use a remote database.
Definition: base_classes.h:821
Encapsulates the init and deinit of the DCA API.
Definition: base_classes.h:315
std::string product
The product code used with the license.
Definition: base_classes.h:549
static UrlClassification create(const DcaInstance &aDcaInstance, const License &aLicense)
Creates the URL classification module by using the given DcaInstance and License.
std::string logDir
the directory in which the DCA log file should be created
Definition: base_classes.h:267
static void PrintUsage(const char *name)
Prints out the syntax of the sample.
std::string getLastMessage() const
Returns the last message received from our license server or if none available the last available mes...
DbType dbType
The type of the database.
Definition: base_classes.h:820
std::string getDescription() const
Returns the description for the error or warning.
std::set< int > CategorySet
Basic container used for categorizations of URLs. This represents a set of category ids.
bool getUrl(const std::string &aUrlString, CategorySet &foundCategories) const
Retrieves the categories of URL string (if found).
std::string getTicket() const
Returns the ticket of the license as string.
#define DCA_BINDIR
DCA subdirectory of the DCA binaries.
Standard function result.
Definition: base_classes.h:148
std::string getSession() const
Returns the session of the license as string.
Encapsulates a URL object.
Definition: base_url.h:44
UrlDbClassifier createDbClassifier(const DbConnection &aDbConnection, const UrlDbClassifierOptions &options=UrlDbClassifierOptions()) const
Create a URL database classifier. The classifier is created by using the provided database connection...
const std::string S_UsageString
Usage string, displayed if a parameter is missing.
DbConnection createDbConnection(const License &aLicense, const DbConnectionData &dbcData, const ProxySettings &proxySettings=ProxySettings(), LogLevel aLogLevel=LOG_Initial) const
Creates a DbConnection object using the given DbConnectionData.
This structure is used to initialize the DcaInstance.
Definition: base_classes.h:264
This header includes all header files of the Custom Database Module Toolbox.
static DcaInstance create(const InitData &initData)
Creates a DcaInstance, starts up the DCA API and initializes the required main module.
static void SetupLicense(const std::string &ticket, const std::string &product, LicenseData &licenseData)
Sets up the given licenseData by copying the given ticket and product strings.
static DCA_MODULE_ID_TYPE ID
The unique ID of the Custom DB module.
License createLicense(const LicenseData &licData, const ProxySettings &proxySettings=ProxySettings(), LogLevel aLogLevel=LOG_Initial) const
Creates a License object using the given LicenseData.
DCA_SIZE_TYPE size() const
Returns the number of results in the container.
int main(int argc, char *argv[])
The main routine.