void BAR(TPSVCINFO * svcinfo) #endif { test_req_t *req = (test_req_t *) svcinfo->data; test_req_t *resp = (test_req_t *) tpalloc((char*) "X_C_TYPE", (char*) "test_req", 0); product_t *p = products; btlogger_debug( "TxLog %s service %s running", __FUNCTION__, TXTEST_SVC_NAME); resp->status = -1; inject_fault(O_XA_COMMIT, req->txtype); for (p = products; p->id != -1; p++) { if (req->prod == p->id) { int rv; strncpy(req->db, p->dbname, sizeof(req->db)); btlogger_debug("TxLog Service %s %4d: prod=%8s (id=%d) op=%c tx=0x%x data=%s", TXTEST_SVC_NAME, req->id, p->pname, p->id, req->op, req->txtype, req->data); rv = p->access(req, resp); btlogger_debug("TxLog Service %s %4d: resp->status=%d rv=%d", TXTEST_SVC_NAME, req->id, resp->status, rv); break; } } tpreturn(TPSUCCESS, resp->status, (char *) resp, sizeof (test_req_t), 0); }
/* select test */ static int doSelect(OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, int empno, int *rcnt) { OCIBind *bndp = (OCIBind *) 0; text *sql = (text *) "SELECT ENAME,JOB FROM EMP WHERE EMPNO >= :1" ; char emp[20]; char job[20]; OCIDefine *stmtdef1 = (OCIDefine *) 0; OCIDefine *stmtdef2 = (OCIDefine *) 0; sword status = OCIStmtPrepare(stmthp, errhp, (text *) sql, (ub4) strlen((char *) sql), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT); // THIS IS A C FILE SO DECLARATIONS UP TOP btlogger_debug( "TxLog doSelect: :1=%d", empno); /* bind empno to the statement */ if (status == OCI_SUCCESS) status = OCIBindByPos(stmthp, &bndp, errhp, 1, (dvoid *) &empno, (sword) sizeof (empno), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT); /* define the output variables for the select */ if (status == OCI_SUCCESS) status = OCIDefineByPos(stmthp, &stmtdef1, errhp, 1, (dvoid *)&emp,(sword) sizeof (emp), SQLT_STR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) OCI_DEFAULT); if (status == OCI_SUCCESS) status = OCIDefineByPos(stmthp, &stmtdef2, errhp, 2, (dvoid *)&job,(sword) sizeof (job), SQLT_STR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) OCI_DEFAULT); /* exectute the select */ if (status == OCI_SUCCESS) status = OCIStmtExecute(svcCtx, stmthp, errhp, (ub4) 0, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT); btlogger_debug( "TxLog executing statement: %s :1=%d", sql, empno); *rcnt = 0; if (status != OCI_SUCCESS && status != OCI_NO_DATA) { show_error(errhp, status); return status; } else { while (1) { status = OCIStmtFetch(stmthp, errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT); if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) break; btlogger_debug( "TxLog Name: %s Job: %s", emp, job); (*rcnt) += 1; } btlogger_debug( "TxLog result: %d", *rcnt); return OCI_SUCCESS; } }
/* the test: insert some data, update it and finally delete it */ static sword doWork(char op, char *arg, OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, test_req_t *resp) { sword status = OCI_SUCCESS; int empno; btlogger_debug( "TxLog doWork op=%c arg=%s", op, arg); empno = (*arg ? atoi(arg) : 8000); (resp->data)[0] = 0; if (op == '0') { status = doInsert(svcCtx, stmthp, errhp, empno); } else if (op == '1') { int rcnt = 0; // no of matching records status = doSelect(svcCtx, stmthp, errhp, empno, &rcnt); btlogger_snprintf(resp->data, sizeof (resp->data), "%d", rcnt); } else if (op == '2') { status = doUpdate(svcCtx, stmthp, errhp, empno); } else if (op == '3') { status = doDelete(svcCtx, stmthp, errhp, empno); } if (status != OCI_SUCCESS) get_error(resp, errhp, status); return status; }
int db2_access(test_req_t *req, test_req_t *resp) { SQLHENV henv; /* environment handle */ SQLHDBC hdbc; /* connection handle */ SQLRETURN rc = SQL_ERROR; SQLHSTMT shdl; btlogger_debug("op=%c data=%s db=%s\n", req->op, req->data, req->db); if (init(req->db, &henv, &hdbc) != SQL_SUCCESS) return (int) rc; rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &shdl); if ( rc != SQL_SUCCESS ) { (void) check_error(SQL_HANDLE_STMT, shdl, rc, "SQLAllocHandle", (SQLCHAR *) "statement handle"); } else { rc = doWork(req->op, req->data, henv, hdbc, shdl, resp); (void) SQLFreeStmt(shdl, SQL_DROP); } fini(henv, hdbc); return (int) rc; }
apr_status_t stomp_disconnect(stomp_connection **connection_ref) { apr_status_t result, rc; stomp_connection *connection = *connection_ref; btlogger_trace("stomp_disconnect"); if( connection_ref == NULL || *connection_ref==NULL ) { btlogger_warn("stomp_disconnect no connection_ref APR_EGENERAL"); return APR_EGENERAL; } result = APR_SUCCESS; rc = apr_socket_shutdown(connection->socket, APR_SHUTDOWN_WRITE); if( result!=APR_SUCCESS ) result = rc; if( connection->socket != NULL ) { btlogger_debug("from stomp.c (2) closing socket"); rc = apr_socket_close(connection->socket); if( result!=APR_SUCCESS ) result = rc; connection->socket=NULL; } *connection_ref=NULL; return rc; }
int main(int argc, char **argv) { product_t prods[8]; int rv = -1; int i; int rmCnt = 0; btlogger_debug( "TxLog %s:%d", __FUNCTION__, __LINE__); if (argc > 1) { for (i = 1; i < argc; i++) { product_t *p = get_product(argv[i]); if (p == NULL) { btlogger_debug("TxLog product id %s not found", argv[i]); for (p = products; p->id != -1; p++) btlogger_debug("TxLog product id %d", p->id); //return fatal("Requested db is not supported\n"); } else { prods[rmCnt++] = *p; } } prods[rmCnt].id = -1; prods[rmCnt].access = 0; prods[rmCnt].xaflags = 0; } else { for (i = 0; products[i].id != -1; i++) prods[i] = products[i]; prods[i] = products[i]; } for (i = 0; prods[i].id != -1; i++) { btlogger_debug("TxLog INFO: %s (%s) id=%d flags=0x%x", prods[i].pname, prods[i].dbname, prods[i].id, prods[i].xaflags()); } rv = run_tests(prods); btlogger("TxLog Test %s (%d)\n", (rv ? "failed" : "passed"), rv); return rv; }
/******************************************************************************** * * Used to establish a connection * ********************************************************************************/ apr_status_t stomp_connect(stomp_connection **connection_ref, const char *hostname, int port, apr_pool_t *pool) { apr_status_t rc; int socket_family; stomp_connection *connection=NULL; btlogger_trace("stomp_connect"); // // Allocate the connection and a memory pool for the connection. // connection = apr_pcalloc(pool, sizeof(stomp_connection)); if( connection == NULL ) { btlogger_warn("stomp_connect cannot allocate for pool APR_ENOMEM"); return APR_ENOMEM; } #define CHECK_SUCCESS if( rc!=APR_SUCCESS ) { return rc; } // Look up the remote address rc = apr_sockaddr_info_get(&connection->remote_sa, hostname, APR_INET, port, 0, pool); CHECK_SUCCESS; // Create and Connect the socket. socket_family = connection->remote_sa->sa.sin.sin_family; rc = apr_socket_create(&connection->socket, socket_family, SOCK_STREAM, APR_PROTO_TCP, pool); CHECK_SUCCESS; rc = apr_socket_connect(connection->socket, connection->remote_sa); // CHECK_SUCCESS; if( rc != APR_SUCCESS ) { apr_status_t rc2 = apr_socket_shutdown(connection->socket, APR_SHUTDOWN_WRITE); btlogger_debug("from stomp.c (1) closing socket"); rc2 = apr_socket_close(connection->socket); return rc; } // Get the Socket Info rc = apr_socket_addr_get(&connection->remote_sa, APR_REMOTE, connection->socket); CHECK_SUCCESS; // rc = apr_sockaddr_ip_get(&connection->remote_ip, connection->remote_sa); // CHECK_SUCCESS; connection->remote_ip = connection->remote_sa->hostname; rc = apr_socket_addr_get(&connection->local_sa, APR_LOCAL, connection->socket); CHECK_SUCCESS; rc = apr_sockaddr_ip_get(&connection->local_ip, connection->local_sa); CHECK_SUCCESS; // Set socket options. // rc = apr_socket_timeout_set( connection->socket, 2*APR_USEC_PER_SEC); // CHECK_SUCCESS; #undef CHECK_SUCCESS *connection_ref = connection; return rc; }
static SQLRETURN doSql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT shdl, SQLCHAR sql[]) { SQLRETURN rc; btlogger_debug("doSql %s\n", sql); rc = SQLPrepare(shdl, sql, SQL_NTS); CHECK_HANDLE(SQL_HANDLE_STMT, shdl, rc, "SQLPrepare", sql); SQLExecDirect(shdl, sql, SQL_NTS); CHECK_HANDLE(SQL_HANDLE_STMT, shdl, rc, "SQLExecDirect", sql); return SQL_SUCCESS; }
/** * test that blacktie correctly drives oracle xa * Precondition: - there is an active transaction (implies that that there is open XA connection) * * arguments: * op - 0 for insert 1 for select 2 for update and 3 for delete (CRUD) * arg - used in selects to hold the expected number of records * rbuf - used to report error strings (except in a successful select it holds the number of matching records) * bufsz - the length of rbuf */ int ora_access(test_req_t *req, test_req_t *resp) { OCIStmt *stmthp; OCIError *errhp; OCIEnv *xaEnv; OCISvcCtx *svcCtx; sword status; btlogger_debug( "TxLog ora_access op=%c data=%s db=%s", req->op, req->data, req->db); /* opening an XA connection creates an environment and service context */ xaEnv = (struct OCIEnv *) xaoEnv((text *) req->db) ; svcCtx = (struct OCISvcCtx *) xaoSvcCtx((text *) req->db); btlogger("TxLog ora_access env=%p svc=%p\n", xaEnv, svcCtx); if (xaEnv == NULL) return fatal("TxLog ORA:- Unable to obtain env!"); if (svcCtx == NULL) return fatal("TxLog ORA:- Unable to obtain service context!"); /* initialise OCI handles */ if (OCI_SUCCESS != OCIHandleAlloc((dvoid *)xaEnv, (dvoid **)&errhp, OCI_HTYPE_ERROR, 0, (dvoid **)0)) return fatal("ORA:- Unable to allocate statement handle"); if (OCI_SUCCESS != OCIHandleAlloc((dvoid *)xaEnv, (dvoid **)&stmthp, OCI_HTYPE_STMT, 0, (dvoid **)0)) return fatal("ORA:- Unable to allocate error handle"); /* run the test */ status = doWork(req->op, req->data, svcCtx, stmthp, errhp, resp); btlogger_debug( "TxLog %d: doWork %c returned: %s", status, req->op, resp->data); // return status; // OCI_SUCCESS is 0 return (status != OCI_SUCCESS); // 0 means success }
/* execute an SQL statement for the given service context */ static int doSql(OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, text *sql, int empno) { OCIBind *bndp = (OCIBind *) 0; sword status = OCIStmtPrepare(stmthp, errhp, (text *) sql, (ub4) strlen((char *)sql), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT); btlogger_debug( "TxLog executing statement: %s :1=%d", sql, empno); /* bind empno to the statement */ if (empno > 0 && status == OCI_SUCCESS) status = OCIBindByPos(stmthp, &bndp, errhp, 1, (dvoid *) &empno, (sword) sizeof (empno), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT); if (status == OCI_SUCCESS) status = OCIStmtExecute(svcCtx, stmthp, errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT); if (status != OCI_SUCCESS) show_error(errhp, status); return status; }
apr_status_t stomp_read(stomp_connection *connection, stomp_frame **frame, apr_pool_t *pool) { apr_status_t rc; stomp_frame *f; btlogger_trace("stomp_read"); f = apr_pcalloc(pool, sizeof(stomp_frame)); if( f == NULL ) { btlogger_warn("stomp_read returning APR_ENONMEM"); return APR_ENOMEM; } f->headers = apr_hash_make(pool); if( f->headers == NULL ) { btlogger_warn("stomp_read returning 2nd APR_ENONMEM"); return APR_ENOMEM; } #define CHECK_SUCCESS if( rc!=APR_SUCCESS ) { return rc; } // Parse the frame out. { char *p; int length; // Parse the command. rc = stomp_read_line(connection, &p, &length, pool); CHECK_SUCCESS; btlogger_trace("Read the command %s", p); f->command = p; // Start parsing the headers. while( 1 ) { rc = stomp_read_line(connection, &p, &length, pool); CHECK_SUCCESS; btlogger_trace("Read a header: %s length: %d", p, length); // Done with headers if(length == 0) break; { // Parse the header line. char *p2; void *key; void *value; p2 = strstr(p,":"); if( p2 == NULL ) { // Expected at 1 : to delimit the key from the value. btlogger_warn("stomp_read returning APR_EGENERAL"); return APR_EGENERAL; } // Null terminate the key *p2=0; key = p; // The rest if the value. value = p2+1; // Insert key/value into hash table. btlogger_trace("Add key %s with value %s to stomp headers", key, value); apr_hash_set(f->headers, key, APR_HASH_KEY_STRING, value); } } // Check for content length { char* content_length = apr_hash_get(f->headers, "content-length", APR_HASH_KEY_STRING); if(content_length) { char endbuffer[2]; apr_size_t length = 2; apr_size_t bodysz; apr_size_t tlen = 0; // number of bytes read btlogger_debug("Content-length %s detected", content_length); bodysz = f->body_length = atoi(content_length); if ((f->body = apr_pcalloc(pool, f->body_length)) == NULL) { btlogger_warn("stomp_read insufficient memory for buffer"); return APR_ENOMEM; } /* * Cannot read the content in one go since network byte buffers are finite. * Keep reading from the socket until body_length bytes have been read. */ while (tlen < bodysz) { char *bp = f->body + tlen; apr_size_t len = bodysz - tlen; rc = apr_socket_recv(connection->socket, bp, &len); CHECK_SUCCESS; tlen += len; } // Expect a \n after the end rc = apr_socket_recv(connection->socket, endbuffer, &length); CHECK_SUCCESS; if(length != 2 || endbuffer[0] != '\0' || endbuffer[1] != '\n') { btlogger_warn("stomp_read returning 2nd APR_EGENERAL %d %c %c", length, endbuffer[0], endbuffer[1]); return APR_EGENERAL; } } else { btlogger_debug("No content-length detected"); // The remainder of the buffer (including the \n at the end) is the body) rc = stomp_read_buffer(connection, &f->body, pool); CHECK_SUCCESS; } } } #undef CHECK_SUCCESS *frame = f; return APR_SUCCESS; }