Skip to content

Exemple d'utilisation de l'API S3 en C++

Vous aurez besoin, outre le compilateur et les éléments standards, de la bibliothèque libs3 :

$ sudo apt-get install libs3-dev

Créez un fichier s3cpp.cpp contenant :

#include <libs3.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>

const char access_key[] = "MYACCESSKEY";
const char secret_key[] = "MYSECRETKEY";
const char host[] = "s3.mesocentre.uca.fr";
const char sample_bucket[] = "monbucket42";
const char sample_key[] = "formation/tutoriel.txt";

S3BucketContext bucketContext =
{
  host,
  sample_bucket,
  S3ProtocolHTTPS,
  S3UriStylePath,
  access_key,
  secret_key
};

S3Status responsePropertiesCallback(
  const S3ResponseProperties *properties,
  void *callbackData)
{
  std::cout << "responsePropertiesCallback" << std::endl;
  return S3StatusOK;
}

static void responseCompleteCallback(
  S3Status status,
  const S3ErrorDetails *error,
  void *callbackData)
{
  std::cout << "responseCompleteCallback : status = " << status
            << ", error = " << error << std::endl;
  if(status != S3StatusOK)
  {
    std::cout << "\tstatus = " << S3_get_status_name(status) << std::endl;
    if(error)
    {
      if(error->message) std::cout << "\terror message = " << error->message << std::endl;

      if(error->resource) std::cout << "\terror resource = " << error->resource << std::endl;

      if(error->furtherDetails) std::cout << "\terror furtherDetails = "
                                          << error->furtherDetails << std::endl;
    }
  }
  return;
}

S3ResponseHandler responseHandler =
{
  &responsePropertiesCallback,
  &responseCompleteCallback
};


// Called-back when requested object data is available
static S3Status getObjectDataCallback(int bufferSize, const char *buffer, void *callbackData)
{
  std::cout << "getObjectDataCallback" << std::endl;
  FILE *outfile = (FILE *) callbackData;
  size_t wrote = fwrite(buffer, 1, bufferSize, outfile);
  return ((wrote < (size_t) bufferSize) ? S3StatusAbortedByCallback : S3StatusOK);
}


//=============================================================================
int main(int argc, char ** argv)
{
  std::cout << "S3 Initializing..." << std::endl;
  S3_initialize("s3.mesocentre.uca.fr", S3_INIT_ALL, host);
  std::cout << "S3 Initialized OK." << std::endl;

  S3GetObjectHandler getObjectHandler =
  {
    responseHandler,
    &getObjectDataCallback
  };

  std::cout << "Requesting resource..." << std::endl;
  S3_get_object(&bucketContext, sample_key, NULL, 0, 0, NULL,
                &getObjectHandler, (void*)stdout);
  std::cout << "Request completed." << std::endl;

  S3_deinitialize();
}

Vous pouvez compiler ce fichier avec :

$ g++ -o s3cpp s3cpp.cpp -ls3

Et si tout est bien configuré, et que la ressource demandée existe, son exécution donne :

$ ./s3cpp
S3 Initializing...
S3 Initialized OK.
Requesting resource...
responsePropertiesCallback
getObjectDataCallback
La première ligne de ce fichier texte ne contient rien d'intéressant.
La seconde ligne non plus.
responseCompleteCallback : status = 0, error = 0x6f19b8
Request completed.

J'ai au préalable envoyé, sur un bucket nommé monbucket42, un fichier auquel je donne la clé formation/tutoriel.txt, contenant :

La première ligne de ce fichier texte ne contient rien d'intéressant.
La seconde ligne non plus.

Une documentation plus complète se trouve http://docs.ceph.com/docs/jewel/radosgw/s3/cpp/ .