Commit 67578530 authored by Volodymyr Yurchenko's avatar Volodymyr Yurchenko
Browse files

Sort out setting gGrid variables (fPort, fHost,...)

parent 18c9a9ad
......@@ -78,27 +78,23 @@ typedef char int8_t;
#define UNUSED(x) (void)(x)
using std::string;
class TJAlien : public TGrid {
public:
enum { kSTDOUT = 0, kSTDERR = 1 , kOUTPUT = 2, kENVIR = 3 };
enum CatalogType { kFailed = -1, kFile = 0, kDirectory, kCollection };
private:
TString fPwd; // working directory
static TString fPwd; // working directory
TString fHome; // home directory with alien:// prefix
std::string tmpdir; // tmp directory
Bool_t WriteTokenFile();
void Connect();
virtual TGridResult *OpenDataset(const char *lfn, const char *options = "");
const char* Whoami();
TJAlienConnectionManager connection;
public:
enum { kSTDOUT = 0, kSTDERR = 1 , kOUTPUT = 2, kENVIR = 3 };
enum CatalogType { kFailed = -1, kFile = 0, kDirectory, kCollection };
TJAlien(const char *gridUrl, const char *uId=0, const char *passwd=0,
const char *options=0);
virtual ~TJAlien();
......@@ -120,8 +116,9 @@ public:
//--- Catalogue Interface
virtual TGridResult *Ls(const char *ldn = "", Option_t *options = "", Bool_t verbose = kFALSE);
virtual Bool_t Cd(const char* ldn = "",Bool_t verbose = kFALSE);
virtual const char *Pwd(Bool_t verbose = kFALSE);
virtual const char *GetHomeDirectory() { return fHome.Data(); }
virtual const char *Pwd(Bool_t verbose = kFALSE);
virtual const char *GetHomeDirectory();
const char* Whoami();
virtual Int_t Mkdir(const char* ldn = "", Option_t* options = "", Bool_t verbose = kFALSE);
virtual Bool_t Rmdir(const char* ldn = "", Option_t* options = "", Bool_t verbose = kFALSE);
virtual Bool_t Register(const char *lfn, const char *turl, Long_t size=-1, const char *se=0, const char *guid=0, Bool_t verbose=kFALSE);
......
// @(#)root/net:$Id$
// Author: Volodymyr Yurchenko 27/06/2019
#ifndef ROOT_TJAlienConnectionManager
......@@ -41,6 +40,7 @@ private:
const int default_WSport = 8097;
const std::string default_server = DEFAULT_JCENTRAL_SERVER;
std::string fWSHost; // websocket port
int fWSPort; // websocket port
TString sUsercert; // location of user certificate
TString sUserkey; // location of user private key
......@@ -70,7 +70,7 @@ private:
public:
TJAlienConnectionManager();
~TJAlienConnectionManager();
void CreateConnection();
int CreateConnection();
void ConnectJBox();
void ConnectJCentral(TJAlienCredentialsObject c, string host = DEFAULT_JCENTRAL_SERVER);
void MakeWebsocketConnection(TJAlienCredentialsObject creds, string host, int WSPort);
......@@ -84,6 +84,7 @@ public:
json_object *CreateJsonCommand(TString *command, TList *options);
virtual Bool_t IsConnected() const { return connection_flag; }
void GetHostAndPort(TString &fHost, Int_t &fPort);
static std::string readBuffer;
ClassDef(TJAlienConnectionManager, 0)
......
......@@ -13,18 +13,16 @@
ClassImp(TJAlien)
using std::string;
TString TJAlien::fPwd = TString("");
//______________________________________________________________________________
TJAlien::TJAlien (const char* gridUrl, const char* uId, const char* passwd,
const char* options)
{
if (gDebug > 1) Info("TJAlien", "Connecting to JBox");
UNUSED(gridUrl);
UNUSED(uId);
UNUSED(passwd);
UNUSED(options);
fGridUrl = gridUrl;
fUser = uId;
fPw = passwd;
fOptions = options;
fGrid = "alien";
gGrid = this;
......@@ -38,13 +36,35 @@ TJAlien::TJAlien (const char* gridUrl, const char* uId, const char* passwd,
else
tmpdir = P_tmpdir;
connection.CreateConnection();
if (IsConnected()) {
Connect();
}
//______________________________________________________________________________
void TJAlien::Connect()
{
TString oldfPwd(fPwd);
int connection_flag = connection.CreateConnection();
if (connection_flag == -1)
{
// Failed to connect
// TJAlienConnectionManager will produce an error message
return;
}
else if (connection_flag == 1)
{
// Connected to JCentral with full grid certificate
// Immediately ask for the token
Token("", false);
fUser = Whoami();
}
}
// Run a command to initialize gGrid variables from the metadata
Cd("");
fHome = fPwd;
// Change to the last known location
if (oldfPwd.Length() != 0)
Cd(oldfPwd.Data());
}
//______________________________________________________________________________
TJAlien::~TJAlien()
......@@ -168,7 +188,7 @@ TGridResult *TJAlien::Command(const char *command, bool interactive, UInt_t stre
TObjString *sCommand = (TObjString *) tokens->At(0);
if (interactive) Info("Command", "Command = \"%s\"", sCommand->GetString().Data());
for(int i=1; i<tokens->GetEntries(); i++)
for (int i = 1; i < tokens->GetEntries(); i++)
{
TObjString *opt = (TObjString*) tokens->At(i);
if (interactive) Info("Command", "Option = \"%s\"", opt->GetString().Data());
......@@ -194,13 +214,19 @@ TGridResult *TJAlien::Command(const char *command, bool interactive, UInt_t stre
if (result)
{
// Extract the username immediately after each command,
// since it could change
// Extract the username, current directory, host and port
// immediately after each command, since it could change
TObjString p("user");
TObjString *sUserMetadata = result->GetMetaData(&p);
if (sUserMetadata) {
fUser = sUserMetadata->GetString().Data();
fUser = sUserMetadata->GetString();
}
TObjString k("currentdir");
TObjString *sPwdMetadata = result->GetMetaData(&k);
if (sPwdMetadata) {
fPwd = result->GetMetaData(&k)->GetString();
}
connection.GetHostAndPort(fHost, fPort);
}
return result;
......@@ -381,54 +407,6 @@ Bool_t TJAlien::Cd(const char* lfn, Bool_t verbose)
}
}
//______________________________________________________________________________
const char *TJAlien::Pwd(Bool_t verbose)
{
TString cmdline = TString("pwd");
TJAlienResult* result = (TJAlienResult*) Command(cmdline.Data(), kFALSE, kENVIR);
if (verbose)
{
Stdout();
Stderr();
}
if (result)
{
TObjString *errorMessage = 0;
Int_t exitcode = GetExitCode(result, errorMessage);
if (exitcode != 0)
{
Error("Pwd", "Pwd command failed with error message \"%s\"", errorMessage->GetString().Data());
delete result;
return nullptr;
}
if (result)
{
TMap* resultmap = ((TMap*)result->At(0));
if (resultmap) {
TObjString* pwd = (TObjString*)resultmap->GetValue("pwd");
if (pwd) {
fPwd = pwd->GetName();
delete resultmap;
return fPwd;
} else {
delete resultmap;
return 0;
}
}
}
delete result;
}
else
{
Error("Pwd", "Pwd: error while running command, no return result");
}
return nullptr;
}
//______________________________________________________________________________
Int_t TJAlien::Mkdir(const char* ldn, Option_t* option, Bool_t verbose)
{
......@@ -829,6 +807,15 @@ TGridJDL *TJAlien::GetJDLGenerator()
return new TJAlienJDL();
}
//______________________________________________________________________________
const char *TJAlien::GetHomeDirectory()
{
if (!IsConnected())
Connect();
return fHome.Data();
}
// TODO not implemented in java, TEST!!!!
//______________________________________________________________________________
Bool_t TJAlien::ResubmitById(TString jobid)
......@@ -947,6 +934,15 @@ TGridJobStatusList *TJAlien::Ps(const char* options, Bool_t verbose)
return joblist;
}
//______________________________________________________________________________
const char *TJAlien::Pwd(Bool_t verbose)
{
if (!IsConnected())
Connect();
return fPwd.Data();
};
//______________________________________________________________________________
TGridResult* TJAlien::GetCollection(const char* lfn, Option_t* option, Bool_t verbose)
{
......@@ -1125,21 +1121,13 @@ Int_t TJAlien::GetExitCode(TJAlienResult *result, TObjString* &message)
}
//______________________________________________________________________________
const char* TJAlien::Whoami() {
TJAlienResult* r = (TJAlienResult*)Command("whoami");
const char *username;
if (r && (username = r->GetKey(0, "message")))
{
TObjString k("currentdir");
fHome = r->GetMetaData(&k)->GetString();
return username;
}
else
{
Error("TJAlien", "Unable to determine username.");
return "";
}
}
const char* TJAlien::Whoami()
{
if (!IsConnected())
Connect();
return fUser.Data();
};
//______________________________________________________________________________
void TJAlien::NotImplemented(const char *func, const char *file, int line)
......
......@@ -5,13 +5,11 @@
ClassImp(TJAlienConnectionManager)
using std::string;
int TJAlienConnectionManager::destroy_flag = 0;
int TJAlienConnectionManager::connection_flag = 0;
int TJAlienConnectionManager::writeable_flag = 0;
int TJAlienConnectionManager::receive_flag = 0;
string TJAlienConnectionManager::readBuffer = "";
std::string TJAlienConnectionManager::readBuffer = "";
TJAlienConnectionManager::TJAlienConnectionManager() {
creds.loadCredentials();
......@@ -23,61 +21,66 @@ TJAlienConnectionManager::~TJAlienConnectionManager() {
}
//______________________________________________________________________________
void TJAlienConnectionManager::CreateConnection()
int TJAlienConnectionManager::CreateConnection()
{
TJAlienCredentialsObject co;
TJAlienDNSResolver dns_jcentral(default_server, default_WSport);
string current_host;
std::string current_host;
clearFlags();
while (creds.count() > 0) {
if (creds.has(cJOB_TOKEN)) {
co = creds.get(cJOB_TOKEN);
} else if (creds.has(cJBOX_TOKEN)) {
co = creds.get(cJBOX_TOKEN);
} else if (creds.has(cFULL_GRID_CERT)) {
co = creds.get(cFULL_GRID_CERT);
if (co.password.empty())
co.readPassword();
} else {
Error("TJAlienConnectionManager", "Failed to get any credentials");
return;
}
if (co.kind == cJBOX_TOKEN || co.kind == cJOB_TOKEN) {
ConnectJBox();
}
if (connection_flag) {
Info("TJAlienConnectionManager", "Successfully connected to JBox");
co.password = "";
return;
}
for (int i = 0; i < dns_jcentral.lenght(); i++)
{
current_host = dns_jcentral.get_next_host();
ConnectJCentral(co, current_host);
if (connection_flag)
{
// If connected directly to JCentral, immediately ask for token
Info("TJAlienConnectionManager", "Successfully connected to %s", current_host.c_str());
co.password = "";
return;
}
else
{
if (gDebug > 0) {
Error("TJAlienConnectionManager", "Failed to connect to %s - retrying...", current_host.c_str());
}
sleep(1);
}
}
creds.removeCredentials(co.kind);
}
while (creds.count() > 0) {
if (creds.has(cJOB_TOKEN)) {
co = creds.get(cJOB_TOKEN);
} else if (creds.has(cJBOX_TOKEN)) {
co = creds.get(cJBOX_TOKEN);
} else if (creds.has(cFULL_GRID_CERT)) {
co = creds.get(cFULL_GRID_CERT);
if (co.password.empty())
co.readPassword();
} else {
Error("TJAlienConnectionManager", "Failed to get any credentials");
return -1;
}
if (co.kind == cJBOX_TOKEN || co.kind == cJOB_TOKEN) {
ConnectJBox();
}
if (connection_flag) {
Info("TJAlienConnectionManager", "Successfully connected to JBox");
co.password = "";
fWSHost = "localhost";
return 0;
}
for (int i = 0; i < dns_jcentral.lenght(); i++)
{
current_host = dns_jcentral.get_next_host();
ConnectJCentral(co, current_host);
if (connection_flag)
{
Info("TJAlienConnectionManager", "Successfully connected to %s", current_host.c_str());
co.password = "";
fWSHost = default_server;
if (co.kind == cFULL_GRID_CERT)
return 1;
else
return 2;
}
else
{
if (gDebug > 0) {
Error("TJAlienConnectionManager", "Failed to connect to %s - retrying...", current_host.c_str());
}
sleep(1);
}
}
creds.removeCredentials(co.kind);
}
Error("TJAlienConnectionManager", "Failed to connect to any server! Giving up");
return -1;
}
void TJAlienConnectionManager::clearFlags()
......@@ -92,18 +95,18 @@ void TJAlienConnectionManager::clearFlags()
//______________________________________________________________________________
void TJAlienConnectionManager::ConnectJBox()
{
if(!creds.has(cJBOX_TOKEN)) {
return;
}
TJAlienCredentialsObject c = creds.get(cJBOX_TOKEN);
TJClientFile jcf;
if(jcf.isValid) {
MakeWebsocketConnection(c, (string)jcf.fHost, jcf.fWSPort);
} else {
if(gDebug >= 1) Info("TJAlienConnectionManager", "The JClient file is not valid - not connecting to JBox!");
}
if (!creds.has(cJBOX_TOKEN)) {
return;
}
TJAlienCredentialsObject c = creds.get(cJBOX_TOKEN);
TJClientFile jcf;
if (jcf.isValid) {
MakeWebsocketConnection(c, (std::string)jcf.fHost, jcf.fWSPort);
} else {
if (gDebug >= 1) Info("TJAlienConnectionManager", "The JClient file is not valid - not connecting to JBox!");
}
}
void TJAlienConnectionManager::ConnectJCentral(TJAlienCredentialsObject c, string host)
......@@ -118,7 +121,7 @@ void TJAlienConnectionManager::MakeWebsocketConnection(TJAlienCredentialsObject
// Create the connection to JBox using the parameters read from the token
// returns true if the connection was established
if(gDebug > 0) {
if (gDebug > 0) {
Info("TJAlienConnectionManager", "Connecting to Server %s:%d", host.c_str(), WSPort);
Info("TJAlienConnectionManager", "Using cert %s and %s", creds.certpath.c_str(), creds.keypath.c_str());
}
......@@ -135,7 +138,7 @@ void TJAlienConnectionManager::MakeWebsocketConnection(TJAlienCredentialsObject
// libwebsockets variables
struct lws_client_connect_info connect_info;
struct lws_context_creation_info creation_info; // Info to create logical connection
struct lws_context_creation_info creation_info; // Info to create logical connection
memset(&connect_info, 0, sizeof connect_info );
memset(&creation_info, 0, sizeof creation_info);
......@@ -165,15 +168,15 @@ void TJAlienConnectionManager::MakeWebsocketConnection(TJAlienCredentialsObject
creation_info.vhost_name = "tjalien-root";
creation_info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
// TODO (nhardi): switch to explicit key/cert contents
// see the context_creation_info
creation_info.client_ssl_cert_filepath = creds.certpath.c_str();
creation_info.client_ssl_private_key_filepath = creds.keypath.c_str();
//creation_info.client_ssl_cert_mem = creds.getCertificate().c_str();
//creation_info.client_ssl_cert_mem_len = creds.getCertificate().length();
// TODO (nhardi): switch to explicit key/cert contents
// see the context_creation_info
creation_info.client_ssl_cert_filepath = creds.certpath.c_str();
creation_info.client_ssl_private_key_filepath = creds.keypath.c_str();
//creation_info.client_ssl_cert_mem = creds.getCertificate().c_str();
//creation_info.client_ssl_cert_mem_len = creds.getCertificate().length();
// TODO (yuw): switch to client_ssl_private_key_password starting from libwebsockets 3.1.0 and onward
creation_info.ssl_private_key_password = creds.password.c_str();
// TODO (yuw): switch to client_ssl_private_key_password starting from libwebsockets 3.1.0 and onward
creation_info.ssl_private_key_password = creds.password.c_str();
// Create context - only logical connection, no real connection yet
context = lws_create_context(&creation_info);
......@@ -221,7 +224,8 @@ void TJAlienConnectionManager::MakeWebsocketConnection(TJAlienCredentialsObject
}
}
creation_info.ssl_private_key_password = "";
creation_info.ssl_private_key_password = "";
fWSPort = WSPort;
return;
}
......@@ -385,6 +389,7 @@ int TJAlienConnectionManager::ws_service_callback(struct lws *wsi, enum lws_call
return 0;
}
//______________________________________________________________________________
void TJAlienConnectionManager::ForceRestart()
{
// Immediately break previous connection and start a new one with user grid vertificate
......@@ -407,6 +412,13 @@ void TJAlienConnectionManager::ForceRestart()
}
}
//______________________________________________________________________________
void TJAlienConnectionManager::GetHostAndPort(TString &fHost, Int_t &fPort)
{
fHost = fWSHost;
fPort = fWSPort;
};
//______________________________________________________________________________
json_object *TJAlienConnectionManager::CreateJsonCommand(TString *command, TList *opt)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment