blob: 64d66ace240feaeb182e85b46d6e0602018a81d8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WIN32
#include "BBNamingContext.hpp"
#include <ace/ACE.h>
#include "fwklib/FwkBBServer.hpp"
#include "fwklib/FwkBBClient.hpp"
#include "fwklib/FwkStrCvt.hpp"
#include <fwklib/FwkException.hpp>
#define ERR_MAX 10
using namespace apache::geode::client::testframework;
static int hashcode(char* str) {
if (str == NULL) {
return 0;
}
int localHash = 0;
int prime = 31;
char* data = str;
for (int i = 0; i < 50 && (data[i] != '\0'); i++) {
localHash = prime * localHash + data[i];
}
if (localHash > 0) return localHash;
return -1 * localHash;
}
static int getRandomNum() {
char* testName = ACE_OS::getenv("TESTNAME");
int seed = hashcode(testName) + 11;
printf("seed for BBPort process %d\n", seed);
// The integration tests rely on the pseudo-random
// number generator being seeded with a very particular
// value specific to the test by way of the test name.
// Whilst this approach is pessimal, it can not be
// remedied as the test depend upon it.
ACE_OS::srand(seed);
return (ACE_OS::rand() % 49999) + 14000;
}
int G_BBPORT = getRandomNum();
class BBNamingContextClientImpl {
FwkBBClient* m_bbc;
uint32_t m_errCount;
bool checkValue(const std::string& k, const std::string& k1,
const std::string& value);
public:
BBNamingContextClientImpl();
~BBNamingContextClientImpl();
void open();
void close();
void dump();
int rebind(const char* key, const char* value, char* type);
int resolve(const char* key, char* value, char* type);
};
class BBNamingContextServerImpl {
FwkBBServer* m_bbServer;
UDPMessageQueues* m_shared;
STReceiver* m_recv;
BBProcessor* m_serv;
Responder* m_resp;
Service* m_farm;
public:
BBNamingContextServerImpl();
~BBNamingContextServerImpl();
};
//
// Impls:
//
BBNamingContextClientImpl::BBNamingContextClientImpl()
: m_bbc(NULL), m_errCount(0) {}
BBNamingContextClientImpl::~BBNamingContextClientImpl() { close(); }
void BBNamingContextClientImpl::open() {
try {
// char * bbPort = ACE_OS::getenv( "BB_PORT" );
char temp[8];
char* bbPort = ACE_OS::itoa(G_BBPORT, temp, 10);
char buf[1024];
ACE_OS::sprintf(buf, "localhost:%s", bbPort);
fprintf(stdout, "Blackboard client is talking on %s\n", buf);
fflush(stdout);
m_bbc = new FwkBBClient(buf);
} catch (FwkException& e) {
FWKEXCEPTION("create bb client encounted Exception: " << e.getMessage());
} catch (...) {
FWKEXCEPTION("create bb client unknow exception\n");
}
}
void BBNamingContextClientImpl::close() {
if (m_bbc != NULL) {
delete m_bbc;
m_bbc = NULL;
}
}
int BBNamingContextClientImpl::rebind(const char* key, const char* value,
char* type) {
// fprintf(stdout, "bind: key=%s, value=%s\n", key, value);
if (m_bbc == NULL) {
return -1;
}
if (m_errCount > ERR_MAX) {
close();
return -1;
}
try {
std::string k(key);
std::string k1("1");
std::string v(value);
m_bbc->set(k, k1, v);
if (false == checkValue(k, k1, value)) {
m_errCount++;
} else {
if (m_errCount > 0) {
m_errCount = 0;
}
return 0;
}
} catch (FwkException& e) {
FWKEXCEPTION(" rebind encounted Exception: " << e.getMessage());
m_errCount++;
} catch (...) {
FWKEXCEPTION("rebind unknown exception\n");
m_errCount++;
}
return -1;
}
void BBNamingContextClientImpl::dump() {
if (m_bbc == NULL) {
return;
}
if (m_errCount > ERR_MAX) {
close();
return;
}
try {
std::string bb = m_bbc->dump();
FWKINFO("Dump Blackboard " << bb);
if (m_errCount > 0) {
m_errCount = 0;
}
} catch (FwkException& e) {
FWKEXCEPTION("create dump encounted Exception: " << e.getMessage());
m_errCount++;
} catch (...) {
FWKEXCEPTION("dump unknown exception\n");
m_errCount++;
}
}
int BBNamingContextClientImpl::resolve(const char* key, char* value,
char* type) {
// fprintf(stdout, "resolve: key=%s\n", key);fflush(stdout);
if (m_bbc == NULL) {
return -1;
}
if (m_errCount > ERR_MAX) {
close();
return -1;
}
try {
std::string k(key);
std::string k1("1");
std::string v = m_bbc->getString(k, k1);
// fprintf(stdout, "resolve: got value %s for key=%s\n", v.c_str(),
// key);fflush(stdout);
ACE_OS::strcpy(value, v.c_str());
if (m_errCount > 0) {
m_errCount = 0;
}
return v.length() == 0 ? -1 : 0;
} catch (FwkException& e) {
FWKEXCEPTION("create resolve encounted Exception: " << e.getMessage());
m_errCount++;
} catch (...) {
FWKEXCEPTION("resolve unknown exception\n");
m_errCount++;
}
return -1;
}
bool BBNamingContextClientImpl::checkValue(const std::string& k,
const std::string& k1,
const std::string& value) {
bool valid = false;
try {
std::string v = m_bbc->getString(k, k1);
if (value == v) valid = true;
} catch (FwkException& e) {
FWKEXCEPTION("create resolve encounted Exception: " << e.getMessage());
} catch (...) {
FWKEXCEPTION("resolve unknown exception\n");
}
return valid;
}
BBNamingContextServerImpl::BBNamingContextServerImpl() {
try {
// char * bbPort = ACE_OS::getenv( "BB_PORT" );
char temp[8];
char* bbPort = ACE_OS::itoa(G_BBPORT, temp, 10);
FwkStrCvt bPort(bbPort);
uint32_t prt = bPort.toUInt32();
fprintf(stdout, "Blackboard server is on port:%u\n", prt);
fflush(stdout);
m_bbServer = new FwkBBServer();
m_shared = new UDPMessageQueues("BBQueues");
m_recv = new STReceiver(m_shared, prt);
m_serv = new BBProcessor(m_shared, m_bbServer);
m_resp = new Responder(m_shared, prt);
m_farm = new Service(3);
uint32_t thrds = m_farm->runThreaded(m_recv, 1);
thrds = m_farm->runThreaded(m_serv, 1);
thrds = m_farm->runThreaded(m_resp, 1);
} catch (FwkException& e) {
FWKEXCEPTION("create bb server encounted Exception: " << e.getMessage());
} catch (...) {
FWKSEVERE("create bb server unknown exception\n");
}
}
BBNamingContextServerImpl::~BBNamingContextServerImpl() {
delete m_farm;
delete m_bbServer;
delete m_shared;
delete m_recv;
delete m_serv;
delete m_resp;
}
//
// client
//
BBNamingContextClient::BBNamingContextClient() {
m_impl = new BBNamingContextClientImpl();
}
BBNamingContextClient::~BBNamingContextClient() {
if (m_impl) {
delete m_impl;
m_impl = NULL;
}
}
void BBNamingContextClient::open() { m_impl->open(); }
void BBNamingContextClient::close() { m_impl->close(); }
void BBNamingContextClient::dump() { m_impl->dump(); }
int BBNamingContextClient::rebind(const char* key, const char* value,
char* type) {
return m_impl->rebind(key, value, type);
}
int BBNamingContextClient::resolve(const char* key, char* value, char* type) {
return m_impl->resolve(key, value, type);
}
//
// server
//
BBNamingContextServer::BBNamingContextServer() {
m_impl = new BBNamingContextServerImpl();
}
BBNamingContextServer::~BBNamingContextServer() {
if (m_impl != NULL) {
delete m_impl;
m_impl = NULL;
}
}
#endif