513 lines
17 KiB
C++
513 lines
17 KiB
C++
#define MD_AUSREG
|
|
#include "cliever-md.h"
|
|
#include "session/SessionFactory.hpp"
|
|
#include "session/SessionManagerProperties.hpp"
|
|
#include "session/Transaction.hpp"
|
|
#include "common/SystemProperties.hpp"
|
|
#include "session/Session.hpp"
|
|
#include "session/StatsManager.hpp"
|
|
#include "se/DomainCheckCommand.hpp"
|
|
#include "se/DomainCheckResponse.hpp"
|
|
#include "se/LPE/LPChkCmdExtension.hpp"
|
|
#include "se/LPE/LPChkRespExtension.hpp"
|
|
#include "se/LPE/LPCrtCmdExtension.hpp"
|
|
#include "se/LPE/LPCrtRespExtension.hpp"
|
|
#include "se/TransferOp.hpp"
|
|
#include "se/IntPostalInfo.hpp"
|
|
#include "se/ContactCreateCommand.hpp"
|
|
#include "se/ContactCreateResponse.hpp"
|
|
#include "se/DomainCreateCommand.hpp"
|
|
#include "se/DomainCreateResponse.hpp"
|
|
#include "se/DomainTransferApproveCommand.hpp"
|
|
#include "se/DomainTransferRequestCommand.hpp"
|
|
#include "se/DomainTransferResponse.hpp"
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <sys/inotify.h>
|
|
#include <sys/stat.h>
|
|
#include <json/json.h>
|
|
#include <type_traits>
|
|
#include <boost/static_assert.hpp>
|
|
#include <boost/type_traits.hpp>
|
|
#include "mdJSON.hpp"
|
|
|
|
typedef struct CMDFRAME { bool thisDryRun;
|
|
|
|
std::string ctc;
|
|
std::string ctcPW;
|
|
std::string ctcEmail;
|
|
std::string ctcName;
|
|
std::string ctcCity;
|
|
std::vector<std::string>
|
|
ctcCrib;
|
|
std::string ctcProv;
|
|
std::string ctcPC;
|
|
std::string ctcGuo;
|
|
std::string ctcOrg;
|
|
|
|
std::string pw;
|
|
std::string RID;
|
|
|
|
std::vector<std::string> admin;
|
|
std::vector<std::string> billing;
|
|
std::vector<std::string> ns;
|
|
std::vector<std::string> tech;
|
|
|
|
const IntPostalInfo ctcPO;
|
|
|
|
string noticeID, notAfter, acceptedDate , thisLaunchPhase, thisDesc, shitName ; // i mean string name
|
|
string smdFileName, smdPath, smdData;
|
|
|
|
CMDFRAME() : ctcPO(IntPostalInfo(std::string("Ren Ren-Juan"),std::string("Niagara Falls"),std::string("US"))) {
|
|
thisDryRun=false; smdPath = "./smd/";}
|
|
}
|
|
commandFrame;
|
|
|
|
|
|
const char *parms[MAX_OTE_CASE];
|
|
|
|
bool bindDone,JSONBatchInProgress = false;
|
|
|
|
static TestEnvironment props;
|
|
|
|
static std::string TEST_SE =
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><epp xmlns=\"urn:ietf:params:xml:ns:epp-1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd\"><hello/></epp>";
|
|
|
|
static std::string nil("nil");
|
|
|
|
namespace ACPRODINOTE {
|
|
|
|
bool dryRun;
|
|
typedef auto_ptr<SessionManager> AC_SESSMGR;
|
|
typedef auto_ptr<Session> AC_SESSION;
|
|
|
|
static AC_SESSION ac_sess;
|
|
|
|
class ACTx
|
|
{
|
|
const char *m;
|
|
AC_SESSMGR ac_mgr;
|
|
|
|
public:
|
|
commandFrame *ctx;
|
|
void (*finisher)(void);
|
|
Transaction *tx;
|
|
// void setSess(std::auto_ptr<SessionManager>& sp) {mgr = sp;}
|
|
ACTx(const char *msg)
|
|
{m=msg;
|
|
finisher = NULL;
|
|
}
|
|
void setSession(AC_SESSMGR p) { ac_mgr = p; }
|
|
void setm(const char *toWhat) { m = toWhat; }
|
|
ACTx(){tx = NULL;finisher =NULL;m=NULL;ctx=NULL;}
|
|
virtual void doIt() {
|
|
AC_ASSERTIONP((tx && ctx))
|
|
theseLogs->logN(1,"{ %s",m ? m : "");
|
|
theseLogs->logN(1," '%s'",ctx->thisDesc.c_str());
|
|
if (!dryRun && !ctx->thisDryRun)
|
|
ac_mgr->execute(*tx);
|
|
if (finisher)
|
|
finisher();
|
|
delete tx;
|
|
delete ctx;
|
|
theseLogs->logN(0,"}");
|
|
}
|
|
};
|
|
|
|
template <class CT,class RT,class CET,class RET>
|
|
class TxQ : public ACTx {
|
|
private:
|
|
std::string name;
|
|
public:
|
|
CT *c; RT *r; CET *ce; RET *re;
|
|
TxQ(const char *msg) : ACTx(msg) {
|
|
c = new CT();
|
|
r = new RT();
|
|
ce = new CET();
|
|
re = new RET();
|
|
finisher = NULL;
|
|
}
|
|
TxQ(std::string ctc,std::string ctcpw, const PostalInfo *poi,
|
|
std::string cemail) : ACTx("<nameless>") {
|
|
c = new CT(ctc, ctcpw, poi, cemail );
|
|
r = new RT();
|
|
ce = NULL;
|
|
re = NULL;
|
|
finisher = NULL;
|
|
}
|
|
TxQ(const std::string& nom,
|
|
const std::string& pw,
|
|
const std::string* registrantID,
|
|
const std::vector<std::string>* techContacts = NULL,
|
|
const std::vector<std::string>* nameservers = NULL,
|
|
const std::vector<std::string>* adminContacts = NULL,
|
|
const std::vector<std::string>* billingContacts = NULL,
|
|
const Period* period = NULL) : ACTx("default create") {
|
|
name = string(nom);
|
|
c = new CT(nom,pw,registrantID);
|
|
r = new RT();
|
|
ce = NULL;
|
|
re = NULL;
|
|
finisher = NULL;
|
|
}
|
|
TxQ(const char *nom,const char *msg) : ACTx(msg) {
|
|
name = string(nom);
|
|
c = new CT(name);
|
|
r = new RT();
|
|
ce = NULL;
|
|
re = NULL;
|
|
setm(msg);
|
|
finisher = NULL;
|
|
}
|
|
TxQ(const std::string nom,const std::string pw,const char *msg) : ACTx(msg) {
|
|
name = nom;
|
|
c = new CT(name,pw);
|
|
r = new RT();
|
|
ce = NULL;
|
|
re = NULL;
|
|
finisher = NULL;
|
|
}
|
|
TxQ(const std::string nom,const char *msg) : ACTx(msg) {
|
|
name = nom;
|
|
c = new CT(name);
|
|
r = new RT();
|
|
ce = NULL;
|
|
re = NULL;
|
|
finisher = NULL;
|
|
}
|
|
TxQ(const std::string *lpe,const char *nom,const char *msg) : ACTx(msg) {
|
|
name = string(nom);
|
|
c = new CT(name);
|
|
r = new RT();
|
|
ce = new CET(lpe);
|
|
re = NULL;
|
|
finisher = NULL;
|
|
}
|
|
TxQ (const std::string& nom,
|
|
const std::string& pw,
|
|
const std::string* registrantID,
|
|
const std::vector<std::string>* techContacts,
|
|
const std::vector<std::string>* nameservers,
|
|
const std::vector<std::string>* adminContacts,
|
|
const std::vector<std::string>* billingContacts,
|
|
const Period*,
|
|
const std::string* lpe) : ACTx("create ") {
|
|
name = nom;
|
|
c = new CT(nom,pw,registrantID,techContacts,nameservers,adminContacts,billingContacts);
|
|
r = new RT();
|
|
ce = new CET(lpe);
|
|
re = NULL;
|
|
finisher = NULL;
|
|
}
|
|
TxQ(const std::string &name,const std::string pw, const std::string &RID,
|
|
std::vector<std::string>&tech, std::vector<std::string>&ns, std::vector<std::string>&admin, std::vector<std::string>&billing) {}
|
|
TxQ(CT *c1, RT *r1, CET *ce1, RET *re1, const char *msg)
|
|
: c(c1), r(r1), ce(ce1), re(re1), ACTx(msg) {}
|
|
void operator=(TxQ *t2) {c = t2->c; r = t2->r; ce = t2->ce; re = t2->re; }
|
|
~TxQ() {delete c; delete r; if (ce) delete ce; if (re) delete re;}
|
|
Transaction operator=(Transaction &t) {t = Transaction(c,r);}
|
|
void set(commandFrame *cmdF,const char *casebe="unknown backend") {
|
|
// Guard the transaction. The Boost stuff is compile-time/static, the AC fail-safe.
|
|
finisher = NULL;
|
|
ctx = cmdF;
|
|
setm(casebe);
|
|
BOOST_STATIC_ASSERT( (boost::is_base_of<Command,CT>::value) );
|
|
BOOST_STATIC_ASSERT( (boost::is_base_of<Response,RT>::value) );
|
|
BOOST_STATIC_ASSERT( (boost::is_base_of<CommandExtension,CET>::value) );
|
|
BOOST_STATIC_ASSERT( (boost::is_base_of<ResponseExtension,RET>::value) );
|
|
bool p1 = std::is_base_of<Command,CT>::value;
|
|
bool p2 = std::is_base_of<Response,RT>::value;
|
|
bool p3 = ce == NULL ? false : std::is_base_of<CommandExtension,CET>::value;
|
|
bool p4 = re == NULL ? false : std::is_base_of<ResponseExtension,RET>::value;
|
|
AC_ASSERTIONP(p1)
|
|
AC_ASSERTIONP(p2)
|
|
if (ce)
|
|
AC_ASSERTIONP(p3)
|
|
if (re)
|
|
AC_ASSERTIONP(p4)
|
|
ACTx::tx = new Transaction(c,r);}
|
|
};
|
|
|
|
|
|
typedef boost::heap::priority_queue<ACTx *> ACWQ;
|
|
|
|
ACWQ acq;
|
|
|
|
using namespace std;
|
|
|
|
#define PRODINOTESLEEP 1 // seconds
|
|
#define EODMARGIN 3 // minutes
|
|
|
|
#define EVENT_SIZE ( sizeof (struct inotify_event) )
|
|
#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
|
|
|
|
#include "AC_OTE.h"
|
|
|
|
// static void testExecuteParallelTransactions() throw (EPPException);
|
|
|
|
bool ausRegEPPTK::doNothing(const std::string propertiesFilePath) { // Just verify load
|
|
|
|
bool did=false;
|
|
|
|
try {
|
|
scenario( 0, propertiesFilePath ); // tkScenario 0 assumed
|
|
did = true;
|
|
}
|
|
catch(std::exception &e) {
|
|
theseLogs->logN(2,"Scenario %d TK Exception: %s .",tkScenario,e.what());
|
|
}
|
|
return did;
|
|
|
|
}
|
|
void ausRegEPPTK::doOTEA()
|
|
{
|
|
int hours,hoops;
|
|
string op("newInstance");
|
|
|
|
scenario(tkScenario,thisConfig->cfg_path);
|
|
|
|
try {
|
|
Timer::setTime("20140101.010101");
|
|
auto_ptr<SessionManager> manager(SessionManagerFactory::newInstance(&props));
|
|
auto_ptr<Session> sess(SessionFactory::newInstance(&props));
|
|
op = "startup";
|
|
manager->startup();
|
|
op = "run (keep-alive)";
|
|
manager->run();
|
|
sess->open();
|
|
|
|
for (hours=0;hours < 24;hours++) {
|
|
// Spawn the keep alive thread.
|
|
theseLogs->logN(1,"Send Test SEs on or about start OTE Test Hour %d.",hours);
|
|
|
|
for (hoops=0;hoops<7;hoops++) {
|
|
sess->writeXML(TEST_SE);
|
|
sess->read();
|
|
sleep(REGISTRY_HANDSHAKE);
|
|
}
|
|
|
|
}
|
|
sess->close();
|
|
manager->shutdown();
|
|
|
|
}
|
|
catch (EPPException& e)
|
|
{ const char *eMsg = e.getMessage().c_str();
|
|
const char *opNow = op.c_str();
|
|
theseLogs->logN(2,"EPP Exception during OTE A (%s): %s .",opNow,eMsg);
|
|
throw e;
|
|
}
|
|
catch (...)
|
|
{
|
|
theseLogs->logN(2,"General Exception during OTE A (%s).",op.c_str());
|
|
}
|
|
|
|
}
|
|
#include "donutsOTEB.h"
|
|
void ausRegEPPTK::registryXOTE() { // PROD in OTE
|
|
// This scenario generalizes OTEB so that its operations can be performed
|
|
// by json scripting. This is a quick and clean which is meant to allow
|
|
// a Registrar to begin quasi-production ops from the established OTE
|
|
// baseline. It's main use case is scripted OTE ops however, it's not
|
|
// meant to be actual production.
|
|
|
|
bool actionableFileEvent,monitoring=true;
|
|
int length, i = 0, j, mSleeps=0, nSleeps=0,debug=10000;
|
|
int fd, wd;
|
|
char buffer[BUF_LEN];
|
|
|
|
theseLogs->logN(0,"Begin RegistryXOTE Session.");
|
|
|
|
ACPRODINOTE::setFuncs();
|
|
|
|
fd = inotify_init();
|
|
|
|
if ( fd < 0 ) {
|
|
theseLogs->logN(0,"Fatal error, couldn't init inotify.");
|
|
return;
|
|
}
|
|
|
|
theseLogs->logN(0,"Monitoring /json for changes.");
|
|
|
|
wd = inotify_add_watch( fd, "/json", IN_MODIFY | IN_CREATE | IN_DELETE );
|
|
length = read( fd, buffer, BUF_LEN );
|
|
|
|
if ( length < 0 ) {
|
|
theseLogs->logN(0,"Fatal error, initial inotify read failed.");
|
|
goto done;
|
|
}
|
|
|
|
|
|
while ( length >= 0 && (BUF_LEN - i) >= length && monitoring )
|
|
{ actionableFileEvent = false;
|
|
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
|
|
|
|
if ( event->len ) {
|
|
if ( event->mask & IN_CREATE ) {
|
|
if ( event->mask & IN_ISDIR ) {
|
|
theseLogs->logN(1,"The directory %s was created.", event->name );
|
|
}
|
|
else {
|
|
theseLogs->logN(1,"The file %s was created.", event->name );
|
|
actionableFileEvent = true;
|
|
}
|
|
}
|
|
else if ( event->mask & IN_DELETE ) {
|
|
if ( event->mask & IN_ISDIR ) {
|
|
theseLogs->logN(1,"The directory %s was deleted.", event->name );
|
|
}
|
|
else {
|
|
theseLogs->logN(1,"The file %s was deleted.", event->name );
|
|
}
|
|
}
|
|
else if ( event->mask & IN_MODIFY ) {
|
|
if ( event->mask & IN_ISDIR ) {
|
|
theseLogs->logN(1, "The directory %s was modified.", event->name );
|
|
}
|
|
else {
|
|
theseLogs->logN(1, "The file %s was modified.", event->name );
|
|
theseLogs->logN(0, "Modifications are ignored." );
|
|
}
|
|
}
|
|
|
|
if (actionableFileEvent) { char wxyz[100]; sprintf(wxyz,"/json/%s",event->name);
|
|
|
|
while (JSONBatchInProgress) {
|
|
theseLogs->logN(0, "Waiting for pending batch to complete." );
|
|
sleep(2);
|
|
}
|
|
JSONBatchInProgress = true;
|
|
|
|
mdJSON scriptor;
|
|
scriptor.setPath(wxyz);
|
|
if (!scriptor.parse()) { didDie = false;
|
|
if (scriptor.run()) {
|
|
if (didDie) {
|
|
monitoring = false;
|
|
theseLogs->logN(1, "Run of %s fatal error. /json monitoring stops.", event->name );
|
|
theseLogs->logN(0, "Restart process to resume JSON monitoring operations." );
|
|
} else {
|
|
theseLogs->logN(1, "Run of %s has errors /json monitoring continues.", event->name );
|
|
JSONBatchInProgress = false;
|
|
}
|
|
} else
|
|
theseLogs->logN(1, " %s preprocessed OK. /json monitoring continues.", event->name );
|
|
}
|
|
else {
|
|
theseLogs->logN(1, "Parse of %s failed. /json monitoring continues.", event->name );
|
|
JSONBatchInProgress = false;
|
|
}
|
|
}
|
|
}
|
|
j = i;
|
|
if (i >= (BUF_LEN - (EVENT_SIZE + event->len)))
|
|
i = 0;
|
|
else
|
|
i += EVENT_SIZE + event->len;
|
|
length = read( fd, &buffer[i], (BUF_LEN - j) );
|
|
}
|
|
if (monitoring)
|
|
theseLogs->logN(2,"JSON monitoring unexpected end: %d %d.",i,length);
|
|
done:
|
|
( void ) inotify_rm_watch( fd, wd );
|
|
( void ) close( fd );
|
|
theseLogs->logN(0,"End RegistryXOTE Session.");
|
|
}
|
|
void ausRegEPPTK::doPROD()
|
|
{ char *endTransMsg;
|
|
int debug=1000000,hours=0,hoops,minutes=0,seconds=0,idleSeconds=0,lastPolicyHandshake=0,
|
|
lastSeconds=0,lastMinutes,iqSize=acq.max_size();
|
|
string op("newInstance");
|
|
|
|
scenario(thisConfig->tkScenario,thisConfig->cfg_path);
|
|
|
|
if (iqSize < MIN_TRANSQ_POLICY) {
|
|
acq.reserve(MIN_TRANSQ_POLICY - iqSize);
|
|
iqSize=acq.max_size();
|
|
theseLogs->logN(1,"Workq size: %d",iqSize);
|
|
}
|
|
|
|
try {
|
|
Timer::setTime("20140101.010101");
|
|
auto_ptr<SessionManager> manager(SessionManagerFactory::newInstance(&props));
|
|
auto_ptr<Session> sess(SessionFactory::newInstance(&props));
|
|
op = "startup";
|
|
manager->startup();
|
|
op = "run (keep-alive)";
|
|
manager->run();
|
|
sess->open();
|
|
|
|
while ((1440 - minutes) > EODMARGIN) {
|
|
|
|
if (!acq.empty() && bindDone ) {
|
|
|
|
if (bindError) {
|
|
theseLogs->logN(3,"Flushing %d transactions",acq.size()-1);
|
|
acq.clear();
|
|
goto postTrans;
|
|
}
|
|
|
|
if (debug > 999)
|
|
theseLogs->logN(3,"Tx dequeued @ minute %d second %d (%d waiting).",(minutes % 60),(seconds % 60),acq.size()-1);
|
|
|
|
inProgress = acq.top();
|
|
inProgress->setSession(manager);
|
|
inProgress->doIt();
|
|
|
|
postTrans:
|
|
if (debug > 999)
|
|
theseLogs->logN(2,"Tx completed @ minute %d second %d.",(minutes % 60),(seconds % 60));
|
|
|
|
idleSeconds = 0;
|
|
if (!bindError)
|
|
acq.pop();
|
|
if (!acq.size())
|
|
JSONBatchInProgress = false;
|
|
|
|
}
|
|
|
|
if (!lastPolicyHandshake || (seconds - lastPolicyHandshake >= (REGISTRY_HANDSHAKE - 5)))
|
|
{if (!lastPolicyHandshake) lastPolicyHandshake = 1; goto skipHandshake;
|
|
idleSeconds = 0;
|
|
if (debug > 99)
|
|
theseLogs->logN(3,"AC-Registry Policy Handshake %d:%d:%d.",hours-1,(minutes % 60),(seconds % 60));
|
|
lastPolicyHandshake = seconds;
|
|
sess->writeXML(TEST_SE);
|
|
sess->read();
|
|
skipHandshake: ;
|
|
}
|
|
|
|
sleep(PRODINOTESLEEP);
|
|
seconds += PRODINOTESLEEP;
|
|
idleSeconds += PRODINOTESLEEP;
|
|
if ((seconds - lastSeconds) == 60) {
|
|
minutes++; lastSeconds = seconds;
|
|
}
|
|
|
|
if (!hours || ((minutes - lastMinutes) >= 59)) {
|
|
theseLogs->logN(1,"AC Production Hour %d.",hours++);
|
|
lastMinutes = minutes;
|
|
}
|
|
|
|
if (debug > 9999 && !(seconds % 120))
|
|
theseLogs->logN(3,"AC Production %d:%d:%d.",hours-1,(minutes % 60),(seconds %60));
|
|
}
|
|
|
|
sess->close();
|
|
manager->shutdown();
|
|
|
|
}
|
|
catch (EPPException& e)
|
|
{ const char *eMsg = e.getMessage().c_str();
|
|
const char *opNow = op.c_str();
|
|
theseLogs->logN(2,"EPP Exception in Production (%s): %s .",opNow,eMsg);
|
|
throw e;
|
|
}
|
|
catch (...)
|
|
{
|
|
theseLogs->logN(2,"General Exception Production (%s).",op.c_str());
|
|
}
|
|
|
|
}
|
|
}
|