C++

You are here:
< Back

The C++ Connector gives you the opportunity to access the OKAPI software from within your own C++ code. We provide you with a connector that includes all essential functions to communicate with the authentication at Auth0 and the calculation server at OKAPI. You can use it as a template for your own code, compile it as a library or embed the code in your software. The complete code is available on Github and will be updated there in the future. For this tutorial we will use CMake to build the code, but you can of course use it with any build-system you are comfortable with. The connector itself is on purpose kept very simple to keep the business logic on the side of your program. It basically only takes over the REST communication.

The following tutorial is divided in two parts:

  1. Setup of the code with an explanation of the general routine of the communication
  2. Step-by-step example of your first calculation

We recommend strongly to read through this page once to ensure that you do not miss any important information.

What is needed?

The connector (and this tutorial) are kept very concise. To be able to run it, you will need the following:

  • a C++ compiler: e.g. gcc or clang
  • CMake: we used verison 3.2
  • a text editor or IDE of your choice
  • a terminal
  • libraries: boost_system, boost_thread, boost_chrono, crypto, ssl and cpprest

So far, we tested the tutorial and connector on Ubuntu 18.04 and macOS 10.14.

Getting and compiling the code

To get the code, simply download it from Github. Inside the repository, you will find a readme, the license file, a CMakeLists file and a src folder, which contains the source folder and another CMakeLists file. To compile the library, create a new builddirectory and change into it. Then, run the following two commands:

cmake ../
make install

With the first command, cmake configures your build environment and looks for your compilers etc., the second one takes over the actual compilation. This will give you a shared object (.so) in in the lib folder, which contains all the functions needed to communicate with OKAPI. You can now go ahead and use the library.

Setting up your own code

Now, you probably want to use the library in your own code. For this, we first add a short description how it generally works. The complete connector is made off three routines: Init, SendRequest and GetResult. The routine basically do what their name says: Use the first one to log in to our server (or more correctly: receive a token to gain access), with the second one you can place requests for execution, and with the third you can retrieve the results from the server.

Most probably, you have your software ready and some idea of how you want to include the connector. Therefore, we will not focus on this here, but rather take the fast road. The first thing you need is a mainroutine from which you can call the connector. For this, create a tutorial.cpp file in the source folder. In here, you can write a little program to send a request to OKAPI and retreive the results. To be able to compile it correctly, you need to add the new executable to the cmake file in the src folder:

set(Casablanca_LIBRARIES "-lboost_system -lboost_thread -lboost_chrono -lcrypto -lssl -lcpprest")

# Build the neptune executable based on the given source files
add_library(cpp-connector SHARED okapiConnector.cpp)

# Build the executable based on the given source files
add_executable(tutorial tutorial.cpp)

# link all the libraries needed
target_link_libraries(tutorial cpp-connector ${Casablanca_LIBRARIES})

# Install the libraries into the lib directory and executrables to bin
install(TARGETS cpp-connector	tutorial
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib)

After writing your code (see below), run the following two commands from the build folder, as described above:

cmake ../
make install

To finally run the executable, run LD_LIBRARY_PATH ../lib ./tutorial.

As announced, find below an example for a small code which runs a pass prediction using OKAPI. For all possible services and requests, please refer to the API-Documentation. Note that we are currently introducing a "generic" API, which allows more flexible data types, which will be the standard in the future. Before compiling it, make sure to add your username and password to the code below.

#include "OkapiConnector.h"

#include "OkapiConnector.h"

// Tutorial to send service execution request and get result
int main() {

	// initializing communication
	OkapiConnector okapi;

  // USER INPUT SECTION

	// authentication
	string username = "sign";
	string password = "up";

  // url to OKAPI server
  std::string baseUrl = "http://okapi.ddns.net:34569";

	// user input PASS PREDICTION
	double altitude = 0.048;
	double longitude = 10.645;
	double latitude = 52.328;

	std::string start = "2018-08-07T19:01:00.000Z";
	std::string end = "2018-08-07T19:04:00.000Z";
	std::string tlePassPrediction = "1 25544U 98067A   18218.76369510  .00001449  00000-0  29472-4 0  9993\n2 25544  51.6423 126.6422 0005481  33.3092  62.9075 15.53806849126382";

  // ACTUAL WORK

	// Auth0 authentication
	OkapiConnector::completeResult okapiResult = okapi.init(methods::POST,username,password);

  // some user information
	std::cout << "Authentication completed" << std::endl;
	std::cout << okapi.accessToken << std::endl;	

  // Prepare the JSON for pass prediction  
  web::json::value simpleGroundLocation;
  simpleGroundLocation[U("altitude")] = web::json::value::number(altitude);
  simpleGroundLocation[U("longitude")] = web::json::value::number(longitude);
  simpleGroundLocation[U("latitude")] = web::json::value::number(latitude);
  web::json::value timeWindow;
  timeWindow[U("start")] = web::json::value::string(start);
  timeWindow[U("end")] = web::json::value::string(end);

  web::json::value passPredRequestBody;
  passPredRequestBody[U("simple_ground_location")] = simpleGroundLocation;
  passPredRequestBody[U("time_window")] = timeWindow;
  passPredRequestBody[U("tle")] = web::json::value::string(tlePassPrediction);

  // prepare urls etc. to send the request
  std::string overviewUrl = "/pass/prediction/requests";
  std::string overviewEndpoint = baseUrl + overviewUrl;
  http_client okapiRequest(overviewEndpoint);
  http_request requestOverview(methods::POST);
  requestOverview.set_body(passPredRequestBody);
  requestOverview.headers().add(U("access_token"), okapi.accessToken);

  // send the request
  okapiResult = okapi.sendRequest(okapiRequest, requestOverview);
  std::string requestIdOverview = okapi.requestId;

  // get results for overview creation and print them in the terminal
  std::string overviewUrlGet = "/pass/predictions/";
  std::string overviewGetEndpoint = baseUrl + overviewUrlGet + requestIdOverview;
  http_client okapiGetOverview(overviewGetEndpoint);
  http_request getOverview(methods::GET);
  getOverview.headers().add(U("access_token"), okapi.accessToken);
  okapiResult = okapi.getResult(okapiGetOverview, getOverview);
  while (okapiResult.error.code == 202) {
    okapiResult = okapi.getResult(okapiGetOverview, getOverview);
    std::cout << "Your request is not ready yet. The request was successful." << std::endl;
    sleep(1);
  }
  std::string resultsOverview = okapiResult.body.serialize();
  std::cout << resultsOverview << std::endl;

  return 0;

}
Last Updated On August 28, 2019