From 7d7ea833846b5993c29f4dd4a603eb44941268c3 Mon Sep 17 00:00:00 2001 From: akanzler Date: Mon, 28 Jan 2019 16:11:54 -0600 Subject: [PATCH 01/16] exposed R function that allow users to authenticate a bpipe application with an application name --- NAMESPACE | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index 39ed8bd..6b492df 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,8 +4,10 @@ import("Rcpp") importFrom("utils", "object.size", "packageVersion") export("blpConnect", "blpDisconnect", + "blpConnectWithApp", "defaultConnection", "blpAuthenticate", + "authenticateWithApp", "bdp", "bdh", "bds", From a49b2778def93b5b1444c06c5dc525946cc7a297 Mon Sep 17 00:00:00 2001 From: akanzler Date: Mon, 28 Jan 2019 16:18:03 -0600 Subject: [PATCH 02/16] This have been added or modified to allow the user to authenticate a bpipe connection with an application name. Description of authenticating a bpipe connection with an app is described in the "Bloomberg API Version 3.x Developers Guide" in section 6.4 --- R/RcppExports.R | 8 +++ R/authenticateWithApp.R | 39 +++++++++++ R/blpConnectWithApp.R | 70 +++++++++++++++++++ man/authenticateWithApp.Rd | 30 ++++++++ man/blpConnectWithApp.Rd | 59 ++++++++++++++++ src/RcppExports.cpp | 26 +++++++ src/authenticateWithApp.cpp | 135 ++++++++++++++++++++++++++++++++++++ src/blpConnectWithApp.cpp | 63 +++++++++++++++++ 8 files changed, 430 insertions(+) create mode 100644 R/authenticateWithApp.R create mode 100644 R/blpConnectWithApp.R create mode 100644 man/authenticateWithApp.Rd create mode 100644 man/blpConnectWithApp.Rd create mode 100644 src/authenticateWithApp.cpp create mode 100644 src/blpConnectWithApp.cpp diff --git a/R/RcppExports.R b/R/RcppExports.R index 93f7298..7699ef8 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -5,6 +5,10 @@ authenticate_Impl <- function(con_, uuid_, ip_address_) { .Call(`_Rblpapi_authenticate_Impl`, con_, uuid_, ip_address_) } +authenticateWithApp_Impl <- function(con_) { + .Call(`_Rblpapi_authenticateWithApp_Impl`, con_) +} + bdh_Impl <- function(con_, securities, fields, start_date_, end_date_, options_, overrides_, verbose, identity_, int_as_double) { .Call(`_Rblpapi_bdh_Impl`, con_, securities, fields, start_date_, end_date_, options_, overrides_, verbose, identity_, int_as_double) } @@ -29,6 +33,10 @@ blpConnect_Impl <- function(host, port) { .Call(`_Rblpapi_blpConnect_Impl`, host, port) } +blpConnectWithApp_Impl <- function(host, port, app_name) { + .Call(`_Rblpapi_blpConnectWithApp_Impl`, host, port, app_name) +} + #' This function retrieves the version of Bloomberg API headers. #' #' @title Get Bloomberg library header version diff --git a/R/authenticateWithApp.R b/R/authenticateWithApp.R new file mode 100644 index 0000000..e41806c --- /dev/null +++ b/R/authenticateWithApp.R @@ -0,0 +1,39 @@ + +## +## Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel and John Laing +## +## This file is part of Rblpapi +## +## Rblpapi is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 2 of the License, or +## (at your option) any later version. +## +## Rblpapi is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Rblpapi. If not, see . + + +##' This function authenticates against the the Bloomberg API +##' +##' @title Authenticate Bloomberg API access +##' @param con A connection object as created by a \code{blpConnect} +##' call, and retrieved via the internal function +##' \code{defaultConnection}. +##' @return The returned bloomberg identity object should be passed to subsequent data +##' calls via bdp(), bds(), etc. +##' @author Alfred Kanzler +##' @examples +##' \dontrun{ +##' blpConnect(host=blpHost, port=blpPort, app_name=blpAppName) +##' blpid <- blpAuthenticate(con) +##' bdp("IBM US Equity", "NAME", identity=blpid) +##' } + +authenticateWithApp <- function(con=defaultConnection()) { + authenticateWithApp_Impl(con) +} diff --git a/R/blpConnectWithApp.R b/R/blpConnectWithApp.R new file mode 100644 index 0000000..d9cbc2d --- /dev/null +++ b/R/blpConnectWithApp.R @@ -0,0 +1,70 @@ + +## +## Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel and John Laing +## +## This file is part of Rblpapi +## +## Rblpapi is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 2 of the License, or +## (at your option) any later version. +## +## Rblpapi is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Rblpapi. If not, see . +## +## This file connects using an application name to authorize the connection +## See Bloomberg API section 6.3 for information on connecting to bpipe with an +## application name. + + +##' This function connects to the Bloomberg API +##' +##' @title Establish connection to Bloomberg service +##' @param port An integer variable with the connection port. Default +##' to \code{8194L}. +##' @param host A character option with either a machine name that is +##' resolvable by DNS, or an IP address. Defaults to +##' \sQuote{localhost}. +##' @param app_name the name of the application that is authorized +##' to connect to bpipe +##' @param default A logical indicating whether this connection should +##' be saved as the default, as opposed to returned to the +##' user. Default to \code{TRUE}. +##' @return In the \code{default=TRUE} case nothing is returned, and +##' this connection is automatically used for all future calls which +##' omit the \code{con} argument. Otherwise a connection object is +##' returned which is required by all the accessor functions in the +##' package. +##' @details For both \code{host} and \code{port} argument, default +##' values can also be specified via \code{\link{options}} using, +##' respectively, the named entries \code{blpHost} and +##' \code{blpConnectWithApp}. +##' +##' If an additional option \code{blpAutoConnect} is set to +##' \sQuote{TRUE}, a connection is established in the +##' \code{.onAttach()} function and stored in the package +##' environment. This effectively frees users from having to +##' explicitly create such an object. +##' @author Alfred Kanzler +##' @seealso bPipe connections using an application name require authentication +##' via \code{blpAuthenticateWithApp} after \code{blpConnectWithApp}. +##' @examples +##' \dontrun{ +##' con <- blpConnectWithApp() # adjust as needed +##' } +blpConnectWithApp <- function(host=getOption("blpHost", "localhost"), + port=getOption("blpPort", 8194L), + app_name=getOption("blpAppName", "None"), + default=TRUE) { + if (storage.mode(port) != "integer") port <- as.integer(port) + if (storage.mode(host) != "character") stop("Host argument must be character.", call.=FALSE) + if (storage.mode(app_name) != "character") stop("App name argument must be character.", call.=FALSE) + con <- blpConnectWithApp_Impl(host, port, app_name) + + if (default) .pkgenv$con <- con else return(con) +} diff --git a/man/authenticateWithApp.Rd b/man/authenticateWithApp.Rd new file mode 100644 index 0000000..d933a60 --- /dev/null +++ b/man/authenticateWithApp.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/authenticateWithApp.R +\name{authenticateWithApp} +\alias{authenticateWithApp} +\title{Authenticate Bloomberg API access} +\usage{ +authenticateWithApp(con = defaultConnection()) +} +\arguments{ +\item{con}{A connection object as created by a \code{blpConnect} +call, and retrieved via the internal function +\code{defaultConnection}.} +} +\value{ +The returned bloomberg identity object should be passed to subsequent data +calls via bdp(), bds(), etc. +} +\description{ +This function authenticates against the the Bloomberg API +} +\examples{ +\dontrun{ +blpConnect(host=blpHost, port=blpPort, app_name=blpAppName) +blpid <- blpAuthenticate(con) +bdp("IBM US Equity", "NAME", identity=blpid) +} +} +\author{ +Alfred Kanzler +} diff --git a/man/blpConnectWithApp.Rd b/man/blpConnectWithApp.Rd new file mode 100644 index 0000000..cbe27eb --- /dev/null +++ b/man/blpConnectWithApp.Rd @@ -0,0 +1,59 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/blpConnectWithApp.R +\name{blpConnectWithApp} +\alias{blpConnectWithApp} +\title{Establish connection to Bloomberg service} +\usage{ +blpConnectWithApp(host = getOption("blpHost", "localhost"), + port = getOption("blpPort", 8194L), app_name = getOption("blpAppName", + "None"), default = TRUE) +} +\arguments{ +\item{host}{A character option with either a machine name that is +resolvable by DNS, or an IP address. Defaults to +\sQuote{localhost}.} + +\item{port}{An integer variable with the connection port. Default +to \code{8194L}.} + +\item{app_name}{the name of the application that is authorized +to connect to bpipe} + +\item{default}{A logical indicating whether this connection should +be saved as the default, as opposed to returned to the +user. Default to \code{TRUE}.} +} +\value{ +In the \code{default=TRUE} case nothing is returned, and +this connection is automatically used for all future calls which +omit the \code{con} argument. Otherwise a connection object is +returned which is required by all the accessor functions in the +package. +} +\description{ +This function connects to the Bloomberg API +} +\details{ +For both \code{host} and \code{port} argument, default +values can also be specified via \code{\link{options}} using, +respectively, the named entries \code{blpHost} and +\code{blpConnectWithApp}. + +If an additional option \code{blpAutoConnect} is set to +\sQuote{TRUE}, a connection is established in the +\code{.onAttach()} function and stored in the package +environment. This effectively frees users from having to +explicitly create such an object. +} +\examples{ +\dontrun{ + con <- blpConnectWithApp() # adjust as needed +} +} +\seealso{ +bPipe connections using an application name require authentication +via \code{blpAuthenticateWithApp} after \code{blpConnectWithApp}. +} +\author{ +Alfred Kanzler +} diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 43099ae..c1ff6ac 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -19,6 +19,17 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } +// authenticateWithApp_Impl +SEXP authenticateWithApp_Impl(SEXP con_); +RcppExport SEXP _Rblpapi_authenticateWithApp_Impl(SEXP con_SEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< SEXP >::type con_(con_SEXP); + rcpp_result_gen = Rcpp::wrap(authenticateWithApp_Impl(con_)); + return rcpp_result_gen; +END_RCPP +} // bdh_Impl Rcpp::List bdh_Impl(SEXP con_, std::vector securities, std::vector fields, std::string start_date_, SEXP end_date_, SEXP options_, SEXP overrides_, bool verbose, SEXP identity_, bool int_as_double); RcppExport SEXP _Rblpapi_bdh_Impl(SEXP con_SEXP, SEXP securitiesSEXP, SEXP fieldsSEXP, SEXP start_date_SEXP, SEXP end_date_SEXP, SEXP options_SEXP, SEXP overrides_SEXP, SEXP verboseSEXP, SEXP identity_SEXP, SEXP int_as_doubleSEXP) { @@ -119,6 +130,19 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } +// blpConnectWithApp_Impl +SEXP blpConnectWithApp_Impl(const std::string host, const int port, const std::string app_name); +RcppExport SEXP _Rblpapi_blpConnectWithApp_Impl(SEXP hostSEXP, SEXP portSEXP, SEXP app_nameSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< const std::string >::type host(hostSEXP); + Rcpp::traits::input_parameter< const int >::type port(portSEXP); + Rcpp::traits::input_parameter< const std::string >::type app_name(app_nameSEXP); + rcpp_result_gen = Rcpp::wrap(blpConnectWithApp_Impl(host, port, app_name)); + return rcpp_result_gen; +END_RCPP +} // getHeaderVersion std::string getHeaderVersion(); RcppExport SEXP _Rblpapi_getHeaderVersion() { @@ -248,12 +272,14 @@ END_RCPP static const R_CallMethodDef CallEntries[] = { {"_Rblpapi_authenticate_Impl", (DL_FUNC) &_Rblpapi_authenticate_Impl, 3}, + {"_Rblpapi_authenticateWithApp_Impl", (DL_FUNC) &_Rblpapi_authenticateWithApp_Impl, 1}, {"_Rblpapi_bdh_Impl", (DL_FUNC) &_Rblpapi_bdh_Impl, 10}, {"_Rblpapi_bdp_Impl", (DL_FUNC) &_Rblpapi_bdp_Impl, 7}, {"_Rblpapi_bds_Impl", (DL_FUNC) &_Rblpapi_bds_Impl, 7}, {"_Rblpapi_getPortfolio_Impl", (DL_FUNC) &_Rblpapi_getPortfolio_Impl, 7}, {"_Rblpapi_beqs_Impl", (DL_FUNC) &_Rblpapi_beqs_Impl, 7}, {"_Rblpapi_blpConnect_Impl", (DL_FUNC) &_Rblpapi_blpConnect_Impl, 2}, + {"_Rblpapi_blpConnectWithApp_Impl", (DL_FUNC) &_Rblpapi_blpConnectWithApp_Impl, 3}, {"_Rblpapi_getHeaderVersion", (DL_FUNC) &_Rblpapi_getHeaderVersion, 0}, {"_Rblpapi_getRuntimeVersion", (DL_FUNC) &_Rblpapi_getRuntimeVersion, 0}, {"_Rblpapi_bsrch_Impl", (DL_FUNC) &_Rblpapi_bsrch_Impl, 4}, diff --git a/src/authenticateWithApp.cpp b/src/authenticateWithApp.cpp new file mode 100644 index 0000000..237d4ce --- /dev/null +++ b/src/authenticateWithApp.cpp @@ -0,0 +1,135 @@ +// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- +// +// authenticateWithApp.cpp -- Function to authenticate to bpipe with an application name +// +// Copyright (C) 2013 Whit Armstrong +// Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel +// +// This file is part of Rblpapi +// +// Rblpapi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// Rblpapi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Rblpapi. If not, see . +// +// Added 2019 to allow server authentication with an application name. +// Authorization by application is described on page 63 of the guide +// "Bloomberg API" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using BloombergLP::blpapi::Session; +using BloombergLP::blpapi::Identity; +using BloombergLP::blpapi::Service; +using BloombergLP::blpapi::Request; +using BloombergLP::blpapi::Event; +using BloombergLP::blpapi::EventQueue; +using BloombergLP::blpapi::Message; +using BloombergLP::blpapi::MessageIterator; +using BloombergLP::blpapi::CorrelationId; + +static void identityFinalizer(SEXP identity_) { + Identity* identity = reinterpret_cast(R_ExternalPtrAddr(identity_)); + if (identity) { + delete identity; + R_ClearExternalPtr(identity_); + } +} + +// Simpler interface +// +// [[Rcpp::export]] +SEXP authenticateWithApp_Impl(SEXP con_) { + Identity* identity_p; + + // via Rcpp Attributes we get a try/catch block with error propagation to R "for free" + Session* session = + reinterpret_cast(checkExternalPointer(con_, "blpapi::Session*")); + + // setup authorization service + std::string service("//blp/apiauth"); + + // authorize + if (session->openService(service.c_str())) { + Service authService = session->getService(service.c_str()); + CorrelationId correlation_id(10); + std::string token; + EventQueue tokenEventQueue; + session->generateToken(correlation_id, &tokenEventQueue); + Event event = tokenEventQueue.nextEvent(); + // + // get token for session + // + if(event.eventType() == Event::TOKEN_STATUS || + event.eventType() == Event::REQUEST_STATUS) { + MessageIterator msgIter(event); + while(msgIter.next()) { + Message msg = msgIter.message(); + if(msg.messageType() == "TokenGenerationSuccess") { + token = msg.getElementAsString("token"); + } + else if(msg.messageType() == "TokenGenerationFailure") { + Rcpp::stop("Failed to generate token"); + } + } + } + + // + // begin authorization + // + if(!token.empty()) { + Request authRequest = authService.createAuthorizationRequest(); + authRequest.set("token", token.c_str()); + identity_p = new Identity(session->createIdentity()); + session->sendAuthorizationRequest(authRequest, identity_p); + // parse messages + bool message_found = false; + while(!message_found) { + Event event = session->nextEvent(100000); + if(event.eventType() == Event::RESPONSE || + event.eventType() == Event::REQUEST_STATUS || + event.eventType() == Event::PARTIAL_RESPONSE) { + MessageIterator msgIter(event); + while(msgIter.next()) { + Message msg = msgIter.message(); + if(msg.messageType() == "AuthorizationSuccess") { + message_found = true; + } + else { + Rcpp::stop(">>> Failed to Authorize"); + } + } + } + else if(event.eventType() == Event::TIMEOUT) { + Rcpp::stop("Timed out trying to authorize"); + } + } + } + else { + Rcpp::stop("Generated token was empty"); + } + } + return createExternalPointer(identity_p,identityFinalizer,"blpapi::Identity*"); +} + diff --git a/src/blpConnectWithApp.cpp b/src/blpConnectWithApp.cpp new file mode 100644 index 0000000..37b0a05 --- /dev/null +++ b/src/blpConnectWithApp.cpp @@ -0,0 +1,63 @@ +// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- +// +// blpConnectWithApp.cpp -- Function to establish Bloomberg connection to bpipe with +// an app name. +// +// Copyright (C) 2013 Whit Armstrong +// Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel +// +// This file is part of Rblpapi +// +// Rblpapi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// Rblpapi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Rblpapi. If not, see . +// +// Added 2019 to allow server authentication with an application name. +// Authorization by application is described on page 63 of the guide +// "Bloomberg API" + +#include +#include +#include +#include + +using BloombergLP::blpapi::Session; +using BloombergLP::blpapi::SessionOptions; + +const std::string APP_PREFIX("AuthenticationMode=APPLICATION_ONLY;" + "ApplicationAuthenticationType=APPNAME_AND_KEY;" + "ApplicationName="); + +static void sessionFinalizer(SEXP session_) { + Session* session = reinterpret_cast(R_ExternalPtrAddr(session_)); + if (session) { + delete session; + R_ClearExternalPtr(session_); + } +} + +// [[Rcpp::export]] +SEXP blpConnectWithApp_Impl(const std::string host, const int port, const std::string app_name) { + SessionOptions sessionOptions; + sessionOptions.setServerHost(host.c_str()); + sessionOptions.setServerPort(port); + std::string app(app_name); + std::string authentication_string = APP_PREFIX + app; + sessionOptions.setAuthenticationOptions(authentication_string.c_str()); + Session* sp = new Session(sessionOptions); + + if (!sp->start()) { + Rcpp::stop("Failed to start session.\n"); + } + + return createExternalPointer(sp, sessionFinalizer, "blpapi::Session*"); +} From ef151965c199ead4b4329a2fe7e3cdca1ce9e931 Mon Sep 17 00:00:00 2001 From: akanzler Date: Tue, 12 Feb 2019 09:37:00 -0600 Subject: [PATCH 03/16] fixed some documentation --- R/authenticateWithApp.R | 4 ++-- R/blpConnectWithApp.R | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/authenticateWithApp.R b/R/authenticateWithApp.R index e41806c..28ec86b 100644 --- a/R/authenticateWithApp.R +++ b/R/authenticateWithApp.R @@ -29,8 +29,8 @@ ##' @author Alfred Kanzler ##' @examples ##' \dontrun{ -##' blpConnect(host=blpHost, port=blpPort, app_name=blpAppName) -##' blpid <- blpAuthenticate(con) +##' blpConnectWithApp(host=blpHost, port=blpPort, app_name=blpAppName) +##' blpid <- blpAuthenticateWithApp(con) ##' bdp("IBM US Equity", "NAME", identity=blpid) ##' } diff --git a/R/blpConnectWithApp.R b/R/blpConnectWithApp.R index d9cbc2d..e156c0a 100644 --- a/R/blpConnectWithApp.R +++ b/R/blpConnectWithApp.R @@ -55,7 +55,7 @@ ##' via \code{blpAuthenticateWithApp} after \code{blpConnectWithApp}. ##' @examples ##' \dontrun{ -##' con <- blpConnectWithApp() # adjust as needed +##' con <- blpConnectWithApp(host = blpHost, port=blpPort app_name=blpAppName) # adjust as needed ##' } blpConnectWithApp <- function(host=getOption("blpHost", "localhost"), port=getOption("blpPort", 8194L), From a0ac28938d90ba27d505c25c95439eb656f3822d Mon Sep 17 00:00:00 2001 From: akanzler Date: Fri, 15 Mar 2019 11:09:49 -0500 Subject: [PATCH 04/16] bpipe access was added to the blpConnect method. The new method was removed --- NAMESPACE | 2 -- R/RcppExports.R | 12 ++---------- R/blpAuthenticate.R | 17 ++++++++++++----- R/blpConnect.R | 13 ++++++++++--- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 6b492df..39ed8bd 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,10 +4,8 @@ import("Rcpp") importFrom("utils", "object.size", "packageVersion") export("blpConnect", "blpDisconnect", - "blpConnectWithApp", "defaultConnection", "blpAuthenticate", - "authenticateWithApp", "bdp", "bdh", "bds", diff --git a/R/RcppExports.R b/R/RcppExports.R index 7699ef8..edd71c5 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -5,10 +5,6 @@ authenticate_Impl <- function(con_, uuid_, ip_address_) { .Call(`_Rblpapi_authenticate_Impl`, con_, uuid_, ip_address_) } -authenticateWithApp_Impl <- function(con_) { - .Call(`_Rblpapi_authenticateWithApp_Impl`, con_) -} - bdh_Impl <- function(con_, securities, fields, start_date_, end_date_, options_, overrides_, verbose, identity_, int_as_double) { .Call(`_Rblpapi_bdh_Impl`, con_, securities, fields, start_date_, end_date_, options_, overrides_, verbose, identity_, int_as_double) } @@ -29,12 +25,8 @@ beqs_Impl <- function(con, screenName, screenType, group, pitdate, languageId, v .Call(`_Rblpapi_beqs_Impl`, con, screenName, screenType, group, pitdate, languageId, verbose) } -blpConnect_Impl <- function(host, port) { - .Call(`_Rblpapi_blpConnect_Impl`, host, port) -} - -blpConnectWithApp_Impl <- function(host, port, app_name) { - .Call(`_Rblpapi_blpConnectWithApp_Impl`, host, port, app_name) +blpConnect_Impl <- function(host, port, app_name_) { + .Call(`_Rblpapi_blpConnect_Impl`, host, port, app_name_) } #' This function retrieves the version of Bloomberg API headers. diff --git a/R/blpAuthenticate.R b/R/blpAuthenticate.R index fbc01d5..f522882 100644 --- a/R/blpAuthenticate.R +++ b/R/blpAuthenticate.R @@ -21,14 +21,17 @@ ##' This function authenticates against the the Bloomberg API ##' ##' @title Authenticate Bloomberg API access -##' @param uuid A character variable with a unique user id token +##' @param uuid A character variable with a unique user id token. If this +##' is missing the function will attempt to connect to bpipe using the connection. It +##' is assumed that an app_name was set. See blpConnect() for app_name information ##' @param host A character variable with a hostname, defaults to 'localhost' ##' @param ip.address An optional character variable with an IP address ##' @param con A connection object as created by a \code{blpConnect} -##' call, and retrieved via the internal function +##' call, and retrieved via the internal function. This is the only required +##' argument to authenticate a bpipe connection with a app_name. ##' \code{defaultConnection}. -##' @return The returned object should be passed to subsequent data -##' calls via bdp(), bds(), etc. +##' @return The returned object should be passed to subsequent data +##' calls via bdp(), bds(), etc. ##' @author Whit Armstrong and Dirk Eddelbuettel ##' @examples ##' \dontrun{ @@ -44,7 +47,11 @@ blpAuthenticate <- function(uuid, host="localhost", ip.address, con=defaultConne ignore.stdout=FALSE, ignore.stderr=FALSE,wait=TRUE) ip.address <- strsplit(cmd.res,"address ")[[1]][2] } - authenticate_Impl(con, as.character(uuid), ip.address) + if(missing(uuid)) { + authenticate_Impl(con, NULL, NULL) + } else { + authenticate_Impl(con, as.character(uuid), ip.address) + } } #### TODO: rename to just 'authenticate' ? diff --git a/R/blpConnect.R b/R/blpConnect.R index 559eee4..8465cd8 100644 --- a/R/blpConnect.R +++ b/R/blpConnect.R @@ -29,6 +29,8 @@ ##' @param host A character option with either a machine name that is ##' resolvable by DNS, or an IP address. Defaults to ##' \sQuote{localhost}. +##' @param app_name the name of an application that is authorized +##' to connect to bpipe ##' @return In the \code{default=TRUE} case nothing is returned, and ##' this connection is automatically used for all future calls which ##' omit the \code{con} argument. Otherwise a connection object is @@ -45,7 +47,7 @@ ##' environment. This effectively frees users from having to ##' explicitly create such an object. ##' @author Whit Armstrong and Dirk Eddelbuettel -##' @seealso Many SAPI and bPipe connections require authentication +##' @seealso Many SAPI and bPipe connections require authentication ##' via \code{blpAuthenticate} after \code{blpConnect}. ##' @examples ##' \dontrun{ @@ -53,10 +55,15 @@ ##' } blpConnect <- function(host=getOption("blpHost", "localhost"), port=getOption("blpPort", 8194L), - default=TRUE) { + default=TRUE, + app_name = getOption("blpAppName", NULL)) { if (storage.mode(port) != "integer") port <- as.integer(port) if (storage.mode(host) != "character") stop("Host argument must be character.", call.=FALSE) - con <- blpConnect_Impl(host, port) + if(is.null(app_name)) { + con <- blpConnect_Impl(host, port, NULL) + } else { + con <- blpConnect_Impl(host, port, app_name) + } if (default) .pkgenv$con <- con else return(con) } From 55298bb26245058c10e093ae668185609607b015 Mon Sep 17 00:00:00 2001 From: akanzler Date: Fri, 15 Mar 2019 11:12:56 -0500 Subject: [PATCH 05/16] bpipe access was added to blpConnect and blpAuthenticate. New access functions were removed. --- R/authenticateWithApp.R | 39 ----------- R/blpConnectWithApp.R | 70 ------------------- man/authenticateWithApp.Rd | 30 -------- man/blpAuthenticate.Rd | 9 ++- man/blpConnect.Rd | 8 ++- man/blpConnectWithApp.Rd | 59 ---------------- src/RcppExports.cpp | 35 ++-------- src/authenticate.cpp | 106 ++++++++++++++++++++++++++-- src/authenticateWithApp.cpp | 135 ------------------------------------ src/blpConnect.cpp | 41 ++++++++++- src/blpConnectWithApp.cpp | 63 ----------------- 11 files changed, 154 insertions(+), 441 deletions(-) delete mode 100644 R/authenticateWithApp.R delete mode 100644 R/blpConnectWithApp.R delete mode 100644 man/authenticateWithApp.Rd delete mode 100644 man/blpConnectWithApp.Rd delete mode 100644 src/authenticateWithApp.cpp delete mode 100644 src/blpConnectWithApp.cpp diff --git a/R/authenticateWithApp.R b/R/authenticateWithApp.R deleted file mode 100644 index 28ec86b..0000000 --- a/R/authenticateWithApp.R +++ /dev/null @@ -1,39 +0,0 @@ - -## -## Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel and John Laing -## -## This file is part of Rblpapi -## -## Rblpapi is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 2 of the License, or -## (at your option) any later version. -## -## Rblpapi is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Rblpapi. If not, see . - - -##' This function authenticates against the the Bloomberg API -##' -##' @title Authenticate Bloomberg API access -##' @param con A connection object as created by a \code{blpConnect} -##' call, and retrieved via the internal function -##' \code{defaultConnection}. -##' @return The returned bloomberg identity object should be passed to subsequent data -##' calls via bdp(), bds(), etc. -##' @author Alfred Kanzler -##' @examples -##' \dontrun{ -##' blpConnectWithApp(host=blpHost, port=blpPort, app_name=blpAppName) -##' blpid <- blpAuthenticateWithApp(con) -##' bdp("IBM US Equity", "NAME", identity=blpid) -##' } - -authenticateWithApp <- function(con=defaultConnection()) { - authenticateWithApp_Impl(con) -} diff --git a/R/blpConnectWithApp.R b/R/blpConnectWithApp.R deleted file mode 100644 index e156c0a..0000000 --- a/R/blpConnectWithApp.R +++ /dev/null @@ -1,70 +0,0 @@ - -## -## Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel and John Laing -## -## This file is part of Rblpapi -## -## Rblpapi is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 2 of the License, or -## (at your option) any later version. -## -## Rblpapi is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Rblpapi. If not, see . -## -## This file connects using an application name to authorize the connection -## See Bloomberg API section 6.3 for information on connecting to bpipe with an -## application name. - - -##' This function connects to the Bloomberg API -##' -##' @title Establish connection to Bloomberg service -##' @param port An integer variable with the connection port. Default -##' to \code{8194L}. -##' @param host A character option with either a machine name that is -##' resolvable by DNS, or an IP address. Defaults to -##' \sQuote{localhost}. -##' @param app_name the name of the application that is authorized -##' to connect to bpipe -##' @param default A logical indicating whether this connection should -##' be saved as the default, as opposed to returned to the -##' user. Default to \code{TRUE}. -##' @return In the \code{default=TRUE} case nothing is returned, and -##' this connection is automatically used for all future calls which -##' omit the \code{con} argument. Otherwise a connection object is -##' returned which is required by all the accessor functions in the -##' package. -##' @details For both \code{host} and \code{port} argument, default -##' values can also be specified via \code{\link{options}} using, -##' respectively, the named entries \code{blpHost} and -##' \code{blpConnectWithApp}. -##' -##' If an additional option \code{blpAutoConnect} is set to -##' \sQuote{TRUE}, a connection is established in the -##' \code{.onAttach()} function and stored in the package -##' environment. This effectively frees users from having to -##' explicitly create such an object. -##' @author Alfred Kanzler -##' @seealso bPipe connections using an application name require authentication -##' via \code{blpAuthenticateWithApp} after \code{blpConnectWithApp}. -##' @examples -##' \dontrun{ -##' con <- blpConnectWithApp(host = blpHost, port=blpPort app_name=blpAppName) # adjust as needed -##' } -blpConnectWithApp <- function(host=getOption("blpHost", "localhost"), - port=getOption("blpPort", 8194L), - app_name=getOption("blpAppName", "None"), - default=TRUE) { - if (storage.mode(port) != "integer") port <- as.integer(port) - if (storage.mode(host) != "character") stop("Host argument must be character.", call.=FALSE) - if (storage.mode(app_name) != "character") stop("App name argument must be character.", call.=FALSE) - con <- blpConnectWithApp_Impl(host, port, app_name) - - if (default) .pkgenv$con <- con else return(con) -} diff --git a/man/authenticateWithApp.Rd b/man/authenticateWithApp.Rd deleted file mode 100644 index d933a60..0000000 --- a/man/authenticateWithApp.Rd +++ /dev/null @@ -1,30 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/authenticateWithApp.R -\name{authenticateWithApp} -\alias{authenticateWithApp} -\title{Authenticate Bloomberg API access} -\usage{ -authenticateWithApp(con = defaultConnection()) -} -\arguments{ -\item{con}{A connection object as created by a \code{blpConnect} -call, and retrieved via the internal function -\code{defaultConnection}.} -} -\value{ -The returned bloomberg identity object should be passed to subsequent data -calls via bdp(), bds(), etc. -} -\description{ -This function authenticates against the the Bloomberg API -} -\examples{ -\dontrun{ -blpConnect(host=blpHost, port=blpPort, app_name=blpAppName) -blpid <- blpAuthenticate(con) -bdp("IBM US Equity", "NAME", identity=blpid) -} -} -\author{ -Alfred Kanzler -} diff --git a/man/blpAuthenticate.Rd b/man/blpAuthenticate.Rd index c84cc84..1f55597 100644 --- a/man/blpAuthenticate.Rd +++ b/man/blpAuthenticate.Rd @@ -8,18 +8,21 @@ blpAuthenticate(uuid, host = "localhost", ip.address, con = defaultConnection()) } \arguments{ -\item{uuid}{A character variable with a unique user id token} +\item{uuid}{A character variable with a unique user id token. If this +is missing the function will attempt to connect to bpipe using the connection. It +is assumed that an app_name was set. See blpConnect() for app_name information} \item{host}{A character variable with a hostname, defaults to 'localhost'} \item{ip.address}{An optional character variable with an IP address} \item{con}{A connection object as created by a \code{blpConnect} -call, and retrieved via the internal function +call, and retrieved via the internal function. This is the only required +argument to authenticate a bpipe connection with a app_name. \code{defaultConnection}.} } \value{ -The returned object should be passed to subsequent data +The returned object should be passed to subsequent data calls via bdp(), bds(), etc. } \description{ diff --git a/man/blpConnect.Rd b/man/blpConnect.Rd index 0e20c57..2713775 100644 --- a/man/blpConnect.Rd +++ b/man/blpConnect.Rd @@ -5,7 +5,8 @@ \title{Establish connection to Bloomberg service} \usage{ blpConnect(host = getOption("blpHost", "localhost"), - port = getOption("blpPort", 8194L), default = TRUE) + port = getOption("blpPort", 8194L), default = TRUE, + app_name = getOption("blpAppName", NULL)) } \arguments{ \item{host}{A character option with either a machine name that is @@ -18,6 +19,9 @@ to \code{8194L}.} \item{default}{A logical indicating whether this connection should be saved as the default, as opposed to returned to the user. Default to \code{TRUE}.} + +\item{app_name}{the name of an application that is authorized +to connect to bpipe} } \value{ In the \code{default=TRUE} case nothing is returned, and @@ -47,7 +51,7 @@ explicitly create such an object. } } \seealso{ -Many SAPI and bPipe connections require authentication +Many SAPI and bPipe connections require authentication via \code{blpAuthenticate} after \code{blpConnect}. } \author{ diff --git a/man/blpConnectWithApp.Rd b/man/blpConnectWithApp.Rd deleted file mode 100644 index cbe27eb..0000000 --- a/man/blpConnectWithApp.Rd +++ /dev/null @@ -1,59 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/blpConnectWithApp.R -\name{blpConnectWithApp} -\alias{blpConnectWithApp} -\title{Establish connection to Bloomberg service} -\usage{ -blpConnectWithApp(host = getOption("blpHost", "localhost"), - port = getOption("blpPort", 8194L), app_name = getOption("blpAppName", - "None"), default = TRUE) -} -\arguments{ -\item{host}{A character option with either a machine name that is -resolvable by DNS, or an IP address. Defaults to -\sQuote{localhost}.} - -\item{port}{An integer variable with the connection port. Default -to \code{8194L}.} - -\item{app_name}{the name of the application that is authorized -to connect to bpipe} - -\item{default}{A logical indicating whether this connection should -be saved as the default, as opposed to returned to the -user. Default to \code{TRUE}.} -} -\value{ -In the \code{default=TRUE} case nothing is returned, and -this connection is automatically used for all future calls which -omit the \code{con} argument. Otherwise a connection object is -returned which is required by all the accessor functions in the -package. -} -\description{ -This function connects to the Bloomberg API -} -\details{ -For both \code{host} and \code{port} argument, default -values can also be specified via \code{\link{options}} using, -respectively, the named entries \code{blpHost} and -\code{blpConnectWithApp}. - -If an additional option \code{blpAutoConnect} is set to -\sQuote{TRUE}, a connection is established in the -\code{.onAttach()} function and stored in the package -environment. This effectively frees users from having to -explicitly create such an object. -} -\examples{ -\dontrun{ - con <- blpConnectWithApp() # adjust as needed -} -} -\seealso{ -bPipe connections using an application name require authentication -via \code{blpAuthenticateWithApp} after \code{blpConnectWithApp}. -} -\author{ -Alfred Kanzler -} diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index c1ff6ac..1ffb6a8 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -19,17 +19,6 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } -// authenticateWithApp_Impl -SEXP authenticateWithApp_Impl(SEXP con_); -RcppExport SEXP _Rblpapi_authenticateWithApp_Impl(SEXP con_SEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< SEXP >::type con_(con_SEXP); - rcpp_result_gen = Rcpp::wrap(authenticateWithApp_Impl(con_)); - return rcpp_result_gen; -END_RCPP -} // bdh_Impl Rcpp::List bdh_Impl(SEXP con_, std::vector securities, std::vector fields, std::string start_date_, SEXP end_date_, SEXP options_, SEXP overrides_, bool verbose, SEXP identity_, bool int_as_double); RcppExport SEXP _Rblpapi_bdh_Impl(SEXP con_SEXP, SEXP securitiesSEXP, SEXP fieldsSEXP, SEXP start_date_SEXP, SEXP end_date_SEXP, SEXP options_SEXP, SEXP overrides_SEXP, SEXP verboseSEXP, SEXP identity_SEXP, SEXP int_as_doubleSEXP) { @@ -119,27 +108,15 @@ BEGIN_RCPP END_RCPP } // blpConnect_Impl -SEXP blpConnect_Impl(const std::string host, const int port); -RcppExport SEXP _Rblpapi_blpConnect_Impl(SEXP hostSEXP, SEXP portSEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< const std::string >::type host(hostSEXP); - Rcpp::traits::input_parameter< const int >::type port(portSEXP); - rcpp_result_gen = Rcpp::wrap(blpConnect_Impl(host, port)); - return rcpp_result_gen; -END_RCPP -} -// blpConnectWithApp_Impl -SEXP blpConnectWithApp_Impl(const std::string host, const int port, const std::string app_name); -RcppExport SEXP _Rblpapi_blpConnectWithApp_Impl(SEXP hostSEXP, SEXP portSEXP, SEXP app_nameSEXP) { +SEXP blpConnect_Impl(const std::string host, const int port, SEXP app_name_); +RcppExport SEXP _Rblpapi_blpConnect_Impl(SEXP hostSEXP, SEXP portSEXP, SEXP app_name_SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const std::string >::type host(hostSEXP); Rcpp::traits::input_parameter< const int >::type port(portSEXP); - Rcpp::traits::input_parameter< const std::string >::type app_name(app_nameSEXP); - rcpp_result_gen = Rcpp::wrap(blpConnectWithApp_Impl(host, port, app_name)); + Rcpp::traits::input_parameter< SEXP >::type app_name_(app_name_SEXP); + rcpp_result_gen = Rcpp::wrap(blpConnect_Impl(host, port, app_name_)); return rcpp_result_gen; END_RCPP } @@ -272,14 +249,12 @@ END_RCPP static const R_CallMethodDef CallEntries[] = { {"_Rblpapi_authenticate_Impl", (DL_FUNC) &_Rblpapi_authenticate_Impl, 3}, - {"_Rblpapi_authenticateWithApp_Impl", (DL_FUNC) &_Rblpapi_authenticateWithApp_Impl, 1}, {"_Rblpapi_bdh_Impl", (DL_FUNC) &_Rblpapi_bdh_Impl, 10}, {"_Rblpapi_bdp_Impl", (DL_FUNC) &_Rblpapi_bdp_Impl, 7}, {"_Rblpapi_bds_Impl", (DL_FUNC) &_Rblpapi_bds_Impl, 7}, {"_Rblpapi_getPortfolio_Impl", (DL_FUNC) &_Rblpapi_getPortfolio_Impl, 7}, {"_Rblpapi_beqs_Impl", (DL_FUNC) &_Rblpapi_beqs_Impl, 7}, - {"_Rblpapi_blpConnect_Impl", (DL_FUNC) &_Rblpapi_blpConnect_Impl, 2}, - {"_Rblpapi_blpConnectWithApp_Impl", (DL_FUNC) &_Rblpapi_blpConnectWithApp_Impl, 3}, + {"_Rblpapi_blpConnect_Impl", (DL_FUNC) &_Rblpapi_blpConnect_Impl, 3}, {"_Rblpapi_getHeaderVersion", (DL_FUNC) &_Rblpapi_getHeaderVersion, 0}, {"_Rblpapi_getRuntimeVersion", (DL_FUNC) &_Rblpapi_getRuntimeVersion, 0}, {"_Rblpapi_bsrch_Impl", (DL_FUNC) &_Rblpapi_bsrch_Impl, 4}, diff --git a/src/authenticate.cpp b/src/authenticate.cpp index 2675785..dea69ef 100644 --- a/src/authenticate.cpp +++ b/src/authenticate.cpp @@ -3,7 +3,7 @@ // authenticate.cpp -- Function to authenticate to Bloomberg backend // // Copyright (C) 2013 Whit Armstrong -// Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel +// Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettelp // // This file is part of Rblpapi // @@ -22,6 +22,12 @@ #include +#include +#include +#include +#include +#include +#include #include #include #include @@ -36,6 +42,8 @@ using BloombergLP::blpapi::Request; using BloombergLP::blpapi::Event; using BloombergLP::blpapi::Message; using BloombergLP::blpapi::MessageIterator; +using BloombergLP::blpapi::CorrelationId; +using BloombergLP::blpapi::EventQueue; static void identityFinalizer(SEXP identity_) { Identity* identity = reinterpret_cast(R_ExternalPtrAddr(identity_)); @@ -45,11 +53,7 @@ static void identityFinalizer(SEXP identity_) { } } -// Simpler interface -// -// [[Rcpp::export]] -SEXP authenticate_Impl(SEXP con_, SEXP uuid_, SEXP ip_address_) { - +Identity* authenticateWithId(SEXP con_, SEXP uuid_, SEXP ip_address_) { // via Rcpp Attributes we get a try/catch block with error propagation to R "for free" Session* session = reinterpret_cast(checkExternalPointer(con_, "blpapi::Session*")); @@ -93,5 +97,93 @@ SEXP authenticate_Impl(SEXP con_, SEXP uuid_, SEXP ip_address_) { } if (event.eventType() == Event::RESPONSE) { break; } } - return createExternalPointer(identity_p,identityFinalizer,"blpapi::Identity*"); + return identity_p; +} + +Identity* authenticateWithApp(SEXP con_) { + Identity* identity_p = 0; + + // via Rcpp Attributes we get a try/catch block with error propagation to R "for free" + Session* session = + reinterpret_cast(checkExternalPointer(con_, "blpapi::Session*")); + + // setup authorization service + std::string service("//blp/apiauth"); + + // authorize + if (session->openService(service.c_str())) { + Service authService = session->getService(service.c_str()); + CorrelationId correlation_id(10); + std::string token; + EventQueue tokenEventQueue; + session->generateToken(correlation_id, &tokenEventQueue); + Event event = tokenEventQueue.nextEvent(); + // + // get token for session + // + if(event.eventType() == Event::TOKEN_STATUS || + event.eventType() == Event::REQUEST_STATUS) { + MessageIterator msgIter(event); + while(msgIter.next()) { + Message msg = msgIter.message(); + if(msg.messageType() == "TokenGenerationSuccess") { + token = msg.getElementAsString("token"); + } + else if(msg.messageType() == "TokenGenerationFailure") { + Rcpp::stop("Failed to generate token"); + } + } + } + + // + // begin authorization + // + if(!token.empty()) { + Request authRequest = authService.createAuthorizationRequest(); + authRequest.set("token", token.c_str()); + identity_p = new Identity(session->createIdentity()); + session->sendAuthorizationRequest(authRequest, identity_p); + // parse messages + bool message_found = false; + while(!message_found) { + Event event = session->nextEvent(100000); + if(event.eventType() == Event::RESPONSE || + event.eventType() == Event::REQUEST_STATUS || + event.eventType() == Event::PARTIAL_RESPONSE) { + MessageIterator msgIter(event); + while(msgIter.next()) { + Message msg = msgIter.message(); + if(msg.messageType() == "AuthorizationSuccess") { + message_found = true; + } + else { + Rcpp::stop(">>> Failed to Authorize"); + } + } + } + else if(event.eventType() == Event::TIMEOUT) { + Rcpp::stop("Timed out trying to authorize"); + } + } + } + else { + Rcpp::stop("Generated token was empty"); + } + } + return identity_p; +} + +// Simpler interface +// +// [[Rcpp::export]] +SEXP authenticate_Impl(SEXP con_, SEXP uuid_, SEXP ip_address_) { + Identity* identity_p = NULL; + if(uuid_ == R_NilValue) { + identity_p = authenticateWithApp(con_); + } + else { + identity_p = authenticateWithId(con_, uuid_, ip_address_); + } + if(identity_p == NULL) { Rcpp::stop("Identity pointer is null\n"); } + return createExternalPointer(identity_p, identityFinalizer, "blpapi::Identity*"); } diff --git a/src/authenticateWithApp.cpp b/src/authenticateWithApp.cpp deleted file mode 100644 index 237d4ce..0000000 --- a/src/authenticateWithApp.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- -// -// authenticateWithApp.cpp -- Function to authenticate to bpipe with an application name -// -// Copyright (C) 2013 Whit Armstrong -// Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel -// -// This file is part of Rblpapi -// -// Rblpapi is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// Rblpapi is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Rblpapi. If not, see . -// -// Added 2019 to allow server authentication with an application name. -// Authorization by application is described on page 63 of the guide -// "Bloomberg API" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using BloombergLP::blpapi::Session; -using BloombergLP::blpapi::Identity; -using BloombergLP::blpapi::Service; -using BloombergLP::blpapi::Request; -using BloombergLP::blpapi::Event; -using BloombergLP::blpapi::EventQueue; -using BloombergLP::blpapi::Message; -using BloombergLP::blpapi::MessageIterator; -using BloombergLP::blpapi::CorrelationId; - -static void identityFinalizer(SEXP identity_) { - Identity* identity = reinterpret_cast(R_ExternalPtrAddr(identity_)); - if (identity) { - delete identity; - R_ClearExternalPtr(identity_); - } -} - -// Simpler interface -// -// [[Rcpp::export]] -SEXP authenticateWithApp_Impl(SEXP con_) { - Identity* identity_p; - - // via Rcpp Attributes we get a try/catch block with error propagation to R "for free" - Session* session = - reinterpret_cast(checkExternalPointer(con_, "blpapi::Session*")); - - // setup authorization service - std::string service("//blp/apiauth"); - - // authorize - if (session->openService(service.c_str())) { - Service authService = session->getService(service.c_str()); - CorrelationId correlation_id(10); - std::string token; - EventQueue tokenEventQueue; - session->generateToken(correlation_id, &tokenEventQueue); - Event event = tokenEventQueue.nextEvent(); - // - // get token for session - // - if(event.eventType() == Event::TOKEN_STATUS || - event.eventType() == Event::REQUEST_STATUS) { - MessageIterator msgIter(event); - while(msgIter.next()) { - Message msg = msgIter.message(); - if(msg.messageType() == "TokenGenerationSuccess") { - token = msg.getElementAsString("token"); - } - else if(msg.messageType() == "TokenGenerationFailure") { - Rcpp::stop("Failed to generate token"); - } - } - } - - // - // begin authorization - // - if(!token.empty()) { - Request authRequest = authService.createAuthorizationRequest(); - authRequest.set("token", token.c_str()); - identity_p = new Identity(session->createIdentity()); - session->sendAuthorizationRequest(authRequest, identity_p); - // parse messages - bool message_found = false; - while(!message_found) { - Event event = session->nextEvent(100000); - if(event.eventType() == Event::RESPONSE || - event.eventType() == Event::REQUEST_STATUS || - event.eventType() == Event::PARTIAL_RESPONSE) { - MessageIterator msgIter(event); - while(msgIter.next()) { - Message msg = msgIter.message(); - if(msg.messageType() == "AuthorizationSuccess") { - message_found = true; - } - else { - Rcpp::stop(">>> Failed to Authorize"); - } - } - } - else if(event.eventType() == Event::TIMEOUT) { - Rcpp::stop("Timed out trying to authorize"); - } - } - } - else { - Rcpp::stop("Generated token was empty"); - } - } - return createExternalPointer(identity_p,identityFinalizer,"blpapi::Identity*"); -} - diff --git a/src/blpConnect.cpp b/src/blpConnect.cpp index 8f5049d..2e1082a 100644 --- a/src/blpConnect.cpp +++ b/src/blpConnect.cpp @@ -28,6 +28,10 @@ using BloombergLP::blpapi::Session; using BloombergLP::blpapi::SessionOptions; +const std::string APP_PREFIX("AuthenticationMode=APPLICATION_ONLY;" + "ApplicationAuthenticationType=APPNAME_AND_KEY;" + "ApplicationName="); + static void sessionFinalizer(SEXP session_) { Session* session = reinterpret_cast(R_ExternalPtrAddr(session_)); if (session) { @@ -36,16 +40,47 @@ static void sessionFinalizer(SEXP session_) { } } -// [[Rcpp::export]] -SEXP blpConnect_Impl(const std::string host, const int port) { +Session* blpConnectWithApp(const std::string host, const int port, const std::string app_name) { + SessionOptions sessionOptions; + sessionOptions.setServerHost(host.c_str()); + sessionOptions.setServerPort(port); + std::string app(app_name); + std::string authentication_string = APP_PREFIX + app; + sessionOptions.setAuthenticationOptions(authentication_string.c_str()); + Session* sp = new Session(sessionOptions); + + if (!sp->start()) { + Rcpp::stop("Failed to start session with bpipe app name.\n"); + } + + return sp; +} +Session* blpConnectNoApp(const std::string host, const int port) { SessionOptions sessionOptions; sessionOptions.setServerHost(host.c_str()); sessionOptions.setServerPort(port); Session* sp = new Session(sessionOptions); if (!sp->start()) { - Rcpp::stop("Failed to start session.\n"); + Rcpp::stop("Failed to start session without an app.\n"); } + return sp; +} + +// [[Rcpp::export]] +SEXP blpConnect_Impl(const std::string host, const int port, SEXP app_name_) { + Session* sp = NULL; + if(app_name_ == NULL) { + sp = blpConnectNoApp(host, port); + } + else { + std::string app_name = Rcpp::as(app_name_); + sp = blpConnectWithApp(host, port, app_name); + } + if(sp == NULL) { + Rcpp::stop("Session pointer is NULL\n"); + } return createExternalPointer(sp, sessionFinalizer, "blpapi::Session*"); } + diff --git a/src/blpConnectWithApp.cpp b/src/blpConnectWithApp.cpp deleted file mode 100644 index 37b0a05..0000000 --- a/src/blpConnectWithApp.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- -// -// blpConnectWithApp.cpp -- Function to establish Bloomberg connection to bpipe with -// an app name. -// -// Copyright (C) 2013 Whit Armstrong -// Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel -// -// This file is part of Rblpapi -// -// Rblpapi is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// Rblpapi is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Rblpapi. If not, see . -// -// Added 2019 to allow server authentication with an application name. -// Authorization by application is described on page 63 of the guide -// "Bloomberg API" - -#include -#include -#include -#include - -using BloombergLP::blpapi::Session; -using BloombergLP::blpapi::SessionOptions; - -const std::string APP_PREFIX("AuthenticationMode=APPLICATION_ONLY;" - "ApplicationAuthenticationType=APPNAME_AND_KEY;" - "ApplicationName="); - -static void sessionFinalizer(SEXP session_) { - Session* session = reinterpret_cast(R_ExternalPtrAddr(session_)); - if (session) { - delete session; - R_ClearExternalPtr(session_); - } -} - -// [[Rcpp::export]] -SEXP blpConnectWithApp_Impl(const std::string host, const int port, const std::string app_name) { - SessionOptions sessionOptions; - sessionOptions.setServerHost(host.c_str()); - sessionOptions.setServerPort(port); - std::string app(app_name); - std::string authentication_string = APP_PREFIX + app; - sessionOptions.setAuthenticationOptions(authentication_string.c_str()); - Session* sp = new Session(sessionOptions); - - if (!sp->start()) { - Rcpp::stop("Failed to start session.\n"); - } - - return createExternalPointer(sp, sessionFinalizer, "blpapi::Session*"); -} From 4d8136460b3e2cf02c225128787cc399ff65f2cf Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Thu, 21 Feb 2019 07:38:08 -0600 Subject: [PATCH 06/16] release 0.3.9 (closes #290) (#291) * release 0.3.9 * more URL updates needed bloomberglags no longer documents API --- .Rbuildignore | 1 + ChangeLog | 19 ++++++++++++++++++- DESCRIPTION | 16 +++++++++------- README.md | 4 ++-- configure | 2 +- inst/NEWS.Rd | 18 ++++++++++++++---- vignettes/rblpapi-intro.Rmd | 4 ++-- 7 files changed, 47 insertions(+), 17 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 34d3224..3b98032 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,3 +7,4 @@ ^inst/blp src/Makevars$ .Rhistory +^.*\.tar\.gz$ diff --git a/ChangeLog b/ChangeLog index 0461884..848856a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2019-02-21 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): New release 0.3.9 + + * vignettes/rblpapi-intro.Rmd (vignette): Updated (old) API download + URL to new location + * DESCRIPTION: Idem + * README.md: Idem + * configure: Idem + +2019-02-20 Dirk Eddelbuettel + + * DESCRIPTION: Set 'StagedInstall: no' to accomidate R 3.6.0 + + * inst/NEWS.Rd: Updated (old) API download URL to new location + 2018-10-25 John Laing * DESCRIPTION (Date): Roll date @@ -39,7 +55,8 @@ 2018-01-20 Dirk Eddelbuettel - * DESCRIPTION (Version, Date): New release 0.3.7 + * DESCRIPTION (Version, Date): New release 0.3.8 + (which should have been named 0.3.7) 2018-01-19 Whit Armstrong diff --git a/DESCRIPTION b/DESCRIPTION index 3182f10..72a4eaf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,21 +1,23 @@ Package: Rblpapi Title: R Interface to 'Bloomberg' -Version: 0.3.8.1 -Date: 2018-10-25 +Version: 0.3.9.1 +Date: 2019-02-20 Maintainer: Dirk Eddelbuettel Author: Whit Armstrong, Dirk Eddelbuettel and John Laing Imports: Rcpp (>= 0.11.0), utils Suggests: fts, xts, zoo, data.table, knitr, RUnit VignetteBuilder: knitr LazyLoad: yes +StagedInstall: no LinkingTo: Rcpp, BH Description: An R Interface to 'Bloomberg' is provided via the 'Blp API'. SystemRequirements: A valid Bloomberg installation. The API headers and - dynamic library are downloaded from during - the build step. See as - well as for API documentation. A - compiler recent enough for (at least partial) C++11 support; g++-4.6.* - or later should be sufficient and g++-4.9.* or later is preferred. + dynamic library are downloaded from during the + build step. See as well as + for API + documentation. A compiler recent enough for (at least partial) C++11 + support is required; g++-4.6.* or later should be sufficient and g++-4.9.* + or later is preferred. URL: http://dirk.eddelbuettel.com/code/rblpapi.html, https://github.com/Rblp/Rblpapi BugReports: https://github.com/Rblp/Rblpapi/issues License: file LICENSE diff --git a/README.md b/README.md index 02fe0c9..a0c404d 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ R Access to Bloomberg API ### Background Rblpapi provides R with access to data and calculations from Bloomberg -Finance L.P. via the [API libraries](https://www.bloomberglabs.com/api/libraries/) provided by -Bloomberg at [Bloomberg Labs](https://www.bloomberglabs.com). +Finance L.P. via the [API libraries](https://www.bloomberg.com/professional/support/api-library/) provided by +Bloomberg. ### Requirements diff --git a/configure b/configure index 360ca84..35e654e 100755 --- a/configure +++ b/configure @@ -36,7 +36,7 @@ elif [ ${sysname} == "Darwin" ]; then platform="osx" else echo "Unsupported platform: $sysname" - echo "Check http://www.bloomberglabs.com/api/libraries/ for possible support first." + echo "Check https://www.bloomberg.com/professional/support/api-library/ for possible support first." echo "Contributions welcome, see https://github.com/Rblp/blp for integration with Rblapi." exit -1 fi diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 49860ea..e138717 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -4,7 +4,7 @@ \newcommand{\ghpr}{\href{https://github.com/Rblp/Rblpapi/pull/#1}{##1}} \newcommand{\ghit}{\href{https://github.com/Rblp/Rblpapi/issues/#1}{##1}} -\section{Changes in Rblpapi version 0.3.8 (2018-xx-yy)}{ +\section{Changes in Rblpapi version 0.3.10 (2019-xx-yy)}{ \itemize{ \item The \code{start.date} format for \code{bdh} now allows character values with relative date expressions (John in \ghpr{267}) fixing @@ -19,12 +19,21 @@ } } -\section{Changes in Rblpapi version 0.3.7 (2018-01-20)}{ +\section{Changes in Rblpapi version 0.3.9 (2019-02-20)}{ \itemize{ + \item Add 'StagedInstall: no' to DESCRIPTION to accomodate R 3.6.0. + } +} + +\section{Changes in Rblpapi version 0.3.8 (2018-01-20)}{ + \itemize{ + \item This release should have been 0.3.7 but was accidentally + tagged as 0.3.8 in the DESCRIPTION file so we skipped 0.3.7. \item The 140 day limit for intra-day data histories is now mentioned in the \code{getTicks} help (Dirk in \ghpr{226} addressing \ghit{215} and \ghit{225}). - \item The Travis CI script was updated to use \code{run.sh} (Dirk in \ghpr{226}). + \item The Travis CI script was updated to use \code{run.sh} (Dirk in + \ghpr{226}). \item The \code{install_name_tool} invocation under macOS was corrected (@spennihana in \ghit{232}) \item The \code{blpAuthenticate} help page has additional examples @@ -156,6 +165,7 @@ \item Build procedures rewritten so that required headers and libraries are downloaded during installation from corresponding GitHub repo \ghrepo{Rblp/blp} which contains custom tarballs derived from the - corresponding upstream releases at \url{http://www.bloomberglabs.com/api}. + corresponding upstream releases at + \url{https://www.bloomberg.com/professional/support/api-library/ }. } } diff --git a/vignettes/rblpapi-intro.Rmd b/vignettes/rblpapi-intro.Rmd index d58182c..7a28efc 100644 --- a/vignettes/rblpapi-intro.Rmd +++ b/vignettes/rblpapi-intro.Rmd @@ -14,7 +14,7 @@ vignette: > The [Rblpapi package](https://github.com/Rblp/Rblpapi) connects the [R language and environment for statistical computing](https://www.r-project.org) to the [Bloomberg](https://www.bloomberg.com) services supported by the -[official Bloomberg APIs](https://www.bloomberglabs.com/api/). +[official Bloomberg APIs](https://www.bloomberg.com/professional/support/api-library/). The [Rblpapi package](https://github.com/Rblp/Rblpapi) is provided in both source and binary (for Windows and OS X) via the @@ -146,7 +146,7 @@ directories `src/`, `R/`, ...) is released under the All code retrieved from the [blp](https://github.com/Rblp/blp) repository during build is released by Bloomberg, available at the -[BloombergLabs API](http://www.bloomberglabs.com/api/libraries/) site +[Bloomberg API](https://www.bloomberg.com/professional/support/api-library/) site and released under the license included below. ``` From d1d5e4ab56a344b250502c704d2f9c77455a2ffb Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Sat, 16 Mar 2019 08:06:10 -0500 Subject: [PATCH 07/16] minor whitespace edits, roll minor version --- DESCRIPTION | 4 ++-- src/authenticate.cpp | 30 +++++++++++++----------------- src/blpConnect.cpp | 11 +++++------ 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 72a4eaf..341e15f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: Rblpapi Title: R Interface to 'Bloomberg' -Version: 0.3.9.1 -Date: 2019-02-20 +Version: 0.3.9.2 +Date: 2019-03-16 Maintainer: Dirk Eddelbuettel Author: Whit Armstrong, Dirk Eddelbuettel and John Laing Imports: Rcpp (>= 0.11.0), utils diff --git a/src/authenticate.cpp b/src/authenticate.cpp index dea69ef..f90a025 100644 --- a/src/authenticate.cpp +++ b/src/authenticate.cpp @@ -4,6 +4,7 @@ // // Copyright (C) 2013 Whit Armstrong // Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettelp +// Copyright (C) 2019 Whit Armstrong, Dirk Eddelbuettel and Alfred Kanzler // // This file is part of Rblpapi // @@ -55,7 +56,7 @@ static void identityFinalizer(SEXP identity_) { Identity* authenticateWithId(SEXP con_, SEXP uuid_, SEXP ip_address_) { // via Rcpp Attributes we get a try/catch block with error propagation to R "for free" - Session* session = + Session* session = reinterpret_cast(checkExternalPointer(con_, "blpapi::Session*")); if (uuid_ == R_NilValue || ip_address_ == R_NilValue) { @@ -126,10 +127,9 @@ Identity* authenticateWithApp(SEXP con_) { MessageIterator msgIter(event); while(msgIter.next()) { Message msg = msgIter.message(); - if(msg.messageType() == "TokenGenerationSuccess") { + if (msg.messageType() == "TokenGenerationSuccess") { token = msg.getElementAsString("token"); - } - else if(msg.messageType() == "TokenGenerationFailure") { + } else if(msg.messageType() == "TokenGenerationFailure") { Rcpp::stop("Failed to generate token"); } } @@ -147,41 +147,37 @@ Identity* authenticateWithApp(SEXP con_) { bool message_found = false; while(!message_found) { Event event = session->nextEvent(100000); - if(event.eventType() == Event::RESPONSE || + if (event.eventType() == Event::RESPONSE || event.eventType() == Event::REQUEST_STATUS || event.eventType() == Event::PARTIAL_RESPONSE) { MessageIterator msgIter(event); - while(msgIter.next()) { + while (msgIter.next()) { Message msg = msgIter.message(); - if(msg.messageType() == "AuthorizationSuccess") { + if (msg.messageType() == "AuthorizationSuccess") { message_found = true; - } - else { + } else { Rcpp::stop(">>> Failed to Authorize"); } } - } - else if(event.eventType() == Event::TIMEOUT) { + } else if(event.eventType() == Event::TIMEOUT) { Rcpp::stop("Timed out trying to authorize"); } } - } - else { + } else { Rcpp::stop("Generated token was empty"); } } return identity_p; } -// Simpler interface +// Simpler interface // // [[Rcpp::export]] SEXP authenticate_Impl(SEXP con_, SEXP uuid_, SEXP ip_address_) { Identity* identity_p = NULL; - if(uuid_ == R_NilValue) { + if (uuid_ == R_NilValue) { identity_p = authenticateWithApp(con_); - } - else { + } else { identity_p = authenticateWithId(con_, uuid_, ip_address_); } if(identity_p == NULL) { Rcpp::stop("Identity pointer is null\n"); } diff --git a/src/blpConnect.cpp b/src/blpConnect.cpp index 2e1082a..28d8201 100644 --- a/src/blpConnect.cpp +++ b/src/blpConnect.cpp @@ -4,6 +4,7 @@ // // Copyright (C) 2013 Whit Armstrong // Copyright (C) 2015 Whit Armstrong and Dirk Eddelbuettel +// Copyright (C) 2019 Whit Armstrong, Dirk Eddelbuettel and Alfred Kanzler // // This file is part of Rblpapi // @@ -64,23 +65,21 @@ Session* blpConnectNoApp(const std::string host, const int port) { if (!sp->start()) { Rcpp::stop("Failed to start session without an app.\n"); } - + return sp; } // [[Rcpp::export]] SEXP blpConnect_Impl(const std::string host, const int port, SEXP app_name_) { Session* sp = NULL; - if(app_name_ == NULL) { + if (app_name_ == NULL) { sp = blpConnectNoApp(host, port); - } - else { + } else { std::string app_name = Rcpp::as(app_name_); sp = blpConnectWithApp(host, port, app_name); } - if(sp == NULL) { + if (sp == NULL) { Rcpp::stop("Session pointer is NULL\n"); } return createExternalPointer(sp, sessionFinalizer, "blpapi::Session*"); } - From 4c6289fc356ae13374052a4dbe31b35419695d3d Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Sat, 16 Mar 2019 08:10:00 -0500 Subject: [PATCH 08/16] revert roll minor version --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 341e15f..72a4eaf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: Rblpapi Title: R Interface to 'Bloomberg' -Version: 0.3.9.2 -Date: 2019-03-16 +Version: 0.3.9.1 +Date: 2019-02-20 Maintainer: Dirk Eddelbuettel Author: Whit Armstrong, Dirk Eddelbuettel and John Laing Imports: Rcpp (>= 0.11.0), utils From 97b7942e2fe0674eff7a44ec073b1b0d69e3415a Mon Sep 17 00:00:00 2001 From: akanzler Date: Tue, 19 Mar 2019 15:53:10 -0500 Subject: [PATCH 09/16] changed naming case to match original authors conventions. updated documentation and removed redundant code --- R/blpConnect.R | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/R/blpConnect.R b/R/blpConnect.R index 8465cd8..b73c190 100644 --- a/R/blpConnect.R +++ b/R/blpConnect.R @@ -29,8 +29,10 @@ ##' @param host A character option with either a machine name that is ##' resolvable by DNS, or an IP address. Defaults to ##' \sQuote{localhost}. -##' @param app_name the name of an application that is authorized -##' to connect to bpipe +##' @param appName the name of an application that is authorized +##' to connect to bpipe. If this is NULL Rblpapi connects to the +##' Bloomberg API but cannot authenticate with an app name. This requires +##' the user to authenticate with a user uuid. ##' @return In the \code{default=TRUE} case nothing is returned, and ##' this connection is automatically used for all future calls which ##' omit the \code{con} argument. Otherwise a connection object is @@ -56,14 +58,10 @@ blpConnect <- function(host=getOption("blpHost", "localhost"), port=getOption("blpPort", 8194L), default=TRUE, - app_name = getOption("blpAppName", NULL)) { + appName = getOption("blpAppName", NULL)) { if (storage.mode(port) != "integer") port <- as.integer(port) if (storage.mode(host) != "character") stop("Host argument must be character.", call.=FALSE) - if(is.null(app_name)) { - con <- blpConnect_Impl(host, port, NULL) - } else { - con <- blpConnect_Impl(host, port, app_name) - } + con <- blpConnect_Impl(host, port, appName) if (default) .pkgenv$con <- con else return(con) } From 8b38f80e8d06de110688794f7ec8be5ed130a79c Mon Sep 17 00:00:00 2001 From: akanzler Date: Tue, 19 Mar 2019 15:55:48 -0500 Subject: [PATCH 10/16] comment changes to reflect change in naming conventions and some clarification of appName usage. --- R/blpAuthenticate.R | 2 +- man/blpAuthenticate.Rd | 2 +- man/blpConnect.Rd | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/R/blpAuthenticate.R b/R/blpAuthenticate.R index f522882..413755f 100644 --- a/R/blpAuthenticate.R +++ b/R/blpAuthenticate.R @@ -28,7 +28,7 @@ ##' @param ip.address An optional character variable with an IP address ##' @param con A connection object as created by a \code{blpConnect} ##' call, and retrieved via the internal function. This is the only required -##' argument to authenticate a bpipe connection with a app_name. +##' argument to authenticate a bpipe connection with a appName. ##' \code{defaultConnection}. ##' @return The returned object should be passed to subsequent data ##' calls via bdp(), bds(), etc. diff --git a/man/blpAuthenticate.Rd b/man/blpAuthenticate.Rd index 1f55597..009110d 100644 --- a/man/blpAuthenticate.Rd +++ b/man/blpAuthenticate.Rd @@ -18,7 +18,7 @@ is assumed that an app_name was set. See blpConnect() for app_name information} \item{con}{A connection object as created by a \code{blpConnect} call, and retrieved via the internal function. This is the only required -argument to authenticate a bpipe connection with a app_name. +argument to authenticate a bpipe connection with a appName. \code{defaultConnection}.} } \value{ diff --git a/man/blpConnect.Rd b/man/blpConnect.Rd index 2713775..defd1c8 100644 --- a/man/blpConnect.Rd +++ b/man/blpConnect.Rd @@ -6,7 +6,7 @@ \usage{ blpConnect(host = getOption("blpHost", "localhost"), port = getOption("blpPort", 8194L), default = TRUE, - app_name = getOption("blpAppName", NULL)) + appName = getOption("blpAppName", NULL)) } \arguments{ \item{host}{A character option with either a machine name that is @@ -20,8 +20,10 @@ to \code{8194L}.} be saved as the default, as opposed to returned to the user. Default to \code{TRUE}.} -\item{app_name}{the name of an application that is authorized -to connect to bpipe} +\item{appName}{the name of an application that is authorized +to connect to bpipe. If this is NULL Rblpapi connects to the +Bloomberg API but cannot authenticate with an app name. This requires +the user to authenticate with a user uuid.} } \value{ In the \code{default=TRUE} case nothing is returned, and From 6350cc2b021acbdf911db881e0944ea23694f159 Mon Sep 17 00:00:00 2001 From: akanzler Date: Tue, 19 Mar 2019 15:56:45 -0500 Subject: [PATCH 11/16] updated version number to 3.9.2 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 72a4eaf..9952d75 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: Rblpapi Title: R Interface to 'Bloomberg' -Version: 0.3.9.1 +Version: 0.3.9.2 Date: 2019-02-20 Maintainer: Dirk Eddelbuettel Author: Whit Armstrong, Dirk Eddelbuettel and John Laing From d86f4fef0ff651fdbd51ef652b6e8001c9c0282a Mon Sep 17 00:00:00 2001 From: akanzler Date: Tue, 19 Mar 2019 15:57:43 -0500 Subject: [PATCH 12/16] fixed bug where R based NULL is tested in C++ with == R_NilValue. Previously tested this with == NULL. --- src/blpConnect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blpConnect.cpp b/src/blpConnect.cpp index 28d8201..595150d 100644 --- a/src/blpConnect.cpp +++ b/src/blpConnect.cpp @@ -72,7 +72,7 @@ Session* blpConnectNoApp(const std::string host, const int port) { // [[Rcpp::export]] SEXP blpConnect_Impl(const std::string host, const int port, SEXP app_name_) { Session* sp = NULL; - if (app_name_ == NULL) { + if (app_name_ == R_NilValue) { sp = blpConnectNoApp(host, port); } else { std::string app_name = Rcpp::as(app_name_); From b77f89ccc46590a78a545514c415e46be870f647 Mon Sep 17 00:00:00 2001 From: akanzler Date: Tue, 19 Mar 2019 16:44:23 -0500 Subject: [PATCH 13/16] documented changes --- ChangeLog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 848856a..0b86a6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2019-03-19 Alfred Kanzler + + * DESCRIPTION(Version) updated minor version + + * src/blpConnect.cpp added function to connect to bpipe with an appName + * src/blpAuthenticate.cpp authenticate a bpipe connection + * R/blpConnect.R added appName to argument list + * R/blpAutheticate.R if the uuid is missing tries to connect to bpipe + 2019-02-21 Dirk Eddelbuettel * DESCRIPTION (Version, Date): New release 0.3.9 From 1f294213e316ebb8251ca95a9580b1a6c2cbd492 Mon Sep 17 00:00:00 2001 From: John Laing Date: Thu, 21 Mar 2019 07:38:54 -0400 Subject: [PATCH 14/16] only do IP resolution on SAPI path --- R/blpAuthenticate.R | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/R/blpAuthenticate.R b/R/blpAuthenticate.R index 413755f..b4fd7a4 100644 --- a/R/blpAuthenticate.R +++ b/R/blpAuthenticate.R @@ -41,18 +41,17 @@ ##' } blpAuthenticate <- function(uuid, host="localhost", ip.address, con=defaultConnection()) { - if (missing(ip.address)) { - ## Linux only ? - cmd.res <- system(paste("host",host), intern=TRUE, - ignore.stdout=FALSE, ignore.stderr=FALSE,wait=TRUE) - ip.address <- strsplit(cmd.res,"address ")[[1]][2] - } if(missing(uuid)) { + ## no UUID, assume BPIPE authenticate_Impl(con, NULL, NULL) } else { + ## have UUID, assume SAPI + if (missing(ip.address)) { + ## Linux only ? + cmd.res <- system(paste("host",host), intern=TRUE, + ignore.stdout=FALSE, ignore.stderr=FALSE,wait=TRUE) + ip.address <- strsplit(cmd.res,"address ")[[1]][2] + } authenticate_Impl(con, as.character(uuid), ip.address) } } - -#### TODO: rename to just 'authenticate' ? - From 42c656e049af1c3f0c616f4985587c80cfde8f96 Mon Sep 17 00:00:00 2001 From: John Laing Date: Thu, 21 Mar 2019 07:52:02 -0400 Subject: [PATCH 15/16] streamline connection code --- src/blpConnect.cpp | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/src/blpConnect.cpp b/src/blpConnect.cpp index 595150d..19fb094 100644 --- a/src/blpConnect.cpp +++ b/src/blpConnect.cpp @@ -41,45 +41,25 @@ static void sessionFinalizer(SEXP session_) { } } -Session* blpConnectWithApp(const std::string host, const int port, const std::string app_name) { +// [[Rcpp::export]] +SEXP blpConnect_Impl(const std::string host, const int port, SEXP app_name_) { SessionOptions sessionOptions; sessionOptions.setServerHost(host.c_str()); sessionOptions.setServerPort(port); - std::string app(app_name); - std::string authentication_string = APP_PREFIX + app; - sessionOptions.setAuthenticationOptions(authentication_string.c_str()); - Session* sp = new Session(sessionOptions); - if (!sp->start()) { - Rcpp::stop("Failed to start session with bpipe app name.\n"); + if (app_name_ != R_NilValue) { + std::string app_name = Rcpp::as(app_name_); + std::string authentication_string = APP_PREFIX + app_name; + sessionOptions.setAuthenticationOptions(authentication_string.c_str()); } - - return sp; -} -Session* blpConnectNoApp(const std::string host, const int port) { - SessionOptions sessionOptions; - sessionOptions.setServerHost(host.c_str()); - sessionOptions.setServerPort(port); Session* sp = new Session(sessionOptions); if (!sp->start()) { - Rcpp::stop("Failed to start session without an app.\n"); - } - - return sp; -} - -// [[Rcpp::export]] -SEXP blpConnect_Impl(const std::string host, const int port, SEXP app_name_) { - Session* sp = NULL; - if (app_name_ == R_NilValue) { - sp = blpConnectNoApp(host, port); - } else { - std::string app_name = Rcpp::as(app_name_); - sp = blpConnectWithApp(host, port, app_name); + Rcpp::stop("Failed to start session.\n"); } if (sp == NULL) { Rcpp::stop("Session pointer is NULL\n"); } + return createExternalPointer(sp, sessionFinalizer, "blpapi::Session*"); } From f932bd1e5db678a403cade39c1dbaf7111aed48d Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Fri, 22 Mar 2019 05:42:54 -0500 Subject: [PATCH 16/16] edits to ChangeLog --- ChangeLog | 17 +++++++++++------ DESCRIPTION | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b86a6e..4e326b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,16 @@ -2019-03-19 Alfred Kanzler +2019-03-21 John Laing + + * R/blpConnect.R: Only resolve IP address in SAPI + * src/blpConnect.cpp: Streamlined connection code + +2019-03-19 Alfred Kanzler - * DESCRIPTION(Version) updated minor version + * DESCRIPTION (Version, Date): Updated minor version - * src/blpConnect.cpp added function to connect to bpipe with an appName - * src/blpAuthenticate.cpp authenticate a bpipe connection - * R/blpConnect.R added appName to argument list - * R/blpAutheticate.R if the uuid is missing tries to connect to bpipe + * src/blpConnect.cpp: Added function to connect to bpipe with an appName + * src/blpAuthenticate.cpp: Authenticate a bpipe connection + * R/blpConnect.R: Added appName to argument list + * R/blpAutheticate.R: If the uuid is missing tries to connect to bpipe 2019-02-21 Dirk Eddelbuettel diff --git a/DESCRIPTION b/DESCRIPTION index 9952d75..a9f0a57 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: Rblpapi Title: R Interface to 'Bloomberg' Version: 0.3.9.2 -Date: 2019-02-20 +Date: 2019-03-21 Maintainer: Dirk Eddelbuettel Author: Whit Armstrong, Dirk Eddelbuettel and John Laing Imports: Rcpp (>= 0.11.0), utils