| /** @file |
| |
| A brief file description |
| |
| @section license License |
| |
| 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. |
| */ |
| |
| /***************************************************************************** |
| * Filename: APITestCliRemote.cc |
| * Purpose: An interactive cli to test remote mgmt API; UNIT TEST for mgmtAPI |
| * Created: lant |
| * |
| ***************************************************************************/ |
| |
| /*************************************************************************** |
| * Possible Commands: |
| *************************************************************************** |
| * Control Operations: |
| * ------------------- |
| * state: returns ON (proxy is on) or OFF (proxy is off) |
| * start:<tsArgs> - turns Proxy on, the tsArgs is optional; |
| * it can either be "hostdb" or "all", |
| * eg. start, start:hostdb, start:all |
| * stop: turns Proxy off |
| * restart: restarts Traffic Manager (Traffic Cop must be running) |
| * |
| * File operations: |
| * --------------- |
| * read_file: reads hosting.config file |
| * proxy.config.xxx (a records.config variable): returns value of that record |
| * records: tests get/set/get a record of each different type |
| * (int, float, counter, string) |
| * err_recs: stress test record get/set functions by purposely entering |
| * invalid record names and/or values |
| * get_mlt: tests TSRecordGetMlt |
| * set_mlt: tests TSRecordSetMlt |
| * |
| * read_url: tests TSReadFromUrl works by retrieving two valid urls |
| * test_url: tests robustness of TSReadFromUrl using invalid urls |
| * |
| * Event Operations: |
| * ---------------- |
| * active_events: lists the names of all currently active events |
| * MGMT_ALARM_xxx (event_name specified in CoreAPIShared.h or Alarms.h): |
| * resolves the specified event |
| * register: registers a generic callback (=eventCallbackFn) which |
| * prints out the event name whenever an event is signalled |
| * unregister: unregisters the generic callback function eventCallbackFn |
| * |
| * Diags |
| * ---- |
| * diags - uses STATUS, NOTE, FATAL, ERROR diags |
| * |
| * Statistics |
| * ---------- |
| * set_stats - sets dummy values for selected group of NODE, PROCESS |
| * records |
| * print_stats - prints the values for the same selected group of records |
| * reset_stats - resets all statistics to default values |
| */ |
| |
| #include "tscore/ink_config.h" |
| #include "tscore/ink_defs.h" |
| #include "tscore/ink_memory.h" |
| #include <cstdlib> |
| #include <cstring> |
| #include <cstdio> |
| #include <strings.h> |
| #include "tscore/ink_string.h" |
| |
| #include "mgmtapi.h" |
| |
| // refer to test_records() function |
| #define TEST_STRING 1 |
| #define TEST_FLOAT 1 |
| #define TEST_INT 1 |
| #define TEST_COUNTER 1 |
| #define TEST_REC_SET 1 |
| #define TEST_REC_GET 0 |
| #define TEST_REC_GET_2 0 |
| |
| #define SET_INT 0 |
| |
| /*************************************************************************** |
| * Printing Helper Functions |
| ***************************************************************************/ |
| |
| /* ------------------------------------------------------------------------ |
| * print_err |
| * ------------------------------------------------------------------------ |
| * used to print the error description associated with the TSMgmtError err |
| */ |
| void |
| print_err(const char *module, TSMgmtError err) |
| { |
| char *err_msg; |
| |
| err_msg = TSGetErrorMessage(err); |
| printf("(%s) ERROR: %s\n", module, err_msg); |
| |
| if (err_msg) { |
| TSfree(err_msg); |
| } |
| } |
| |
| /*------------------------------------------------------------- |
| * print_string_list |
| *-------------------------------------------------------------*/ |
| void |
| print_string_list(TSStringList list) |
| { |
| int i, count, buf_pos = 0; |
| char buf[1000]; |
| |
| if (!list) { |
| return; |
| } |
| count = TSStringListLen(list); |
| for (i = 0; i < count; i++) { |
| char *str = TSStringListDequeue(list); |
| snprintf(buf + buf_pos, sizeof(buf) - buf_pos, "%s,", str); |
| buf_pos = strlen(buf); |
| TSStringListEnqueue(list, str); |
| } |
| printf("%s \n", buf); |
| } |
| |
| /*------------------------------------------------------------- |
| * print_int_list |
| *-------------------------------------------------------------*/ |
| void |
| print_int_list(TSIntList list) |
| { |
| int i, count, buf_pos = 0; |
| char buf[1000]; |
| |
| count = TSIntListLen(list); |
| for (i = 0; i < count; i++) { |
| int *elem = TSIntListDequeue(list); |
| snprintf(buf + buf_pos, sizeof(buf) - buf_pos, "%d:", *elem); |
| buf_pos = strlen(buf); |
| TSIntListEnqueue(list, elem); |
| } |
| printf("Int List: %s \n", buf); |
| } |
| |
| /*************************************************************************** |
| * Control Testing |
| ***************************************************************************/ |
| void |
| print_proxy_state() |
| { |
| TSProxyStateT state = TSProxyStateGet(); |
| |
| switch (state) { |
| case TS_PROXY_ON: |
| printf("Proxy State = ON\n"); |
| break; |
| case TS_PROXY_OFF: |
| printf("Proxy State = OFF\n"); |
| break; |
| default: |
| printf("ERROR: Proxy State Undefined!\n"); |
| break; |
| } |
| } |
| |
| // starts Traffic Server (turns proxy on) |
| void |
| start_TS(char *tsArgs) |
| { |
| TSMgmtError ret; |
| TSCacheClearT clear = TS_CACHE_CLEAR_NONE; |
| char *args; |
| |
| strtok(tsArgs, ":"); |
| args = strtok(nullptr, ":"); |
| if (args) { |
| if (strcmp(args, "all\n") == 0) { |
| clear = TS_CACHE_CLEAR_CACHE; |
| } else if (strcmp(args, "hostdb\n") == 0) { |
| clear = TS_CACHE_CLEAR_HOSTDB; |
| } |
| } else { |
| clear = TS_CACHE_CLEAR_NONE; |
| } |
| |
| printf("STARTING PROXY with cache: %d\n", clear); |
| if ((ret = TSProxyStateSet(TS_PROXY_ON, clear)) != TS_ERR_OKAY) { |
| printf("[TSProxyStateSet] turn on FAILED\n"); |
| } |
| print_err("start_TS", ret); |
| } |
| |
| // stops Traffic Server (turns proxy off) |
| void |
| stop_TS() |
| { |
| TSMgmtError ret; |
| |
| printf("STOPPING PROXY\n"); |
| if ((ret = TSProxyStateSet(TS_PROXY_OFF, TS_CACHE_CLEAR_NONE)) != TS_ERR_OKAY) { |
| printf("[TSProxyStateSet] turn off FAILED\n"); |
| } |
| print_err("stop_TS", ret); |
| } |
| |
| // restarts Traffic Manager (Traffic Cop must be running) |
| void |
| restart() |
| { |
| TSMgmtError ret; |
| |
| printf("RESTART\n"); |
| if ((ret = TSRestart(true)) != TS_ERR_OKAY) { |
| printf("[TSRestart] FAILED\n"); |
| } |
| |
| print_err("restart", ret); |
| } |
| |
| // rereads all the configuration files |
| void |
| reconfigure() |
| { |
| TSMgmtError ret; |
| |
| printf("RECONFIGURE\n"); |
| if ((ret = TSReconfigure()) != TS_ERR_OKAY) { |
| printf("[TSReconfigure] FAILED\n"); |
| } |
| |
| print_err("reconfigure", ret); |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * test_action_need |
| * ------------------------------------------------------------------------ |
| * tests if correct action need is returned when requested record is set |
| */ |
| void |
| test_action_need() |
| { |
| TSActionNeedT action; |
| |
| // RU_NULL record |
| TSRecordSetString("proxy.config.proxy_name", "proxy_dorky", &action); |
| printf("[TSRecordSetString] proxy.config.proxy_name \n\tAction Should: [%d]\n\tAction is : [%d]\n", TS_ACTION_UNDEFINED, |
| action); |
| } |
| |
| /* Bouncer the traffic_server process(es) */ |
| void |
| bounce() |
| { |
| TSMgmtError ret; |
| |
| printf("BOUNCER\n"); |
| if ((ret = TSBounce(true)) != TS_ERR_OKAY) { |
| printf("[TSBounce] FAILED\n"); |
| } |
| |
| print_err("bounce", ret); |
| } |
| |
| /*************************************************************************** |
| * Record Testing |
| ***************************************************************************/ |
| |
| /* ------------------------------------------------------------------------ |
| * test_error_records |
| * ------------------------------------------------------------------------ |
| * stress test error handling by purposely being dumb; send requests to |
| * get invalid record names |
| */ |
| void |
| test_error_records() |
| { |
| TSInt port1, new_port = 8080; |
| TSActionNeedT action; |
| TSMgmtError ret; |
| TSCounter ctr1; |
| |
| printf("\n"); |
| // test get integer |
| fprintf(stderr, "Test invalid record names\n"); |
| |
| ret = TSRecordGetInt("proy.config.cop.core_signal", &port1); |
| if (ret != TS_ERR_OKAY) { |
| print_err("TSRecordGetInt", ret); |
| } else { |
| printf("[TSRecordGetInt] proxy.config.cop.core_signal=%" PRId64 " \n", port1); |
| } |
| |
| // test set integer |
| ret = TSRecordSetInt("proy.config.cop.core_signal", new_port, &action); |
| print_err("TSRecordSetInt", ret); |
| |
| printf("\n"); |
| if (TSRecordGetCounter("proxy.press.socks.connections_successful", &ctr1) != TS_ERR_OKAY) { |
| printf("TSRecordGetCounter FAILED!\n"); |
| } else { |
| printf("[TSRecordGetCounter]proxy.process.socks.connections_successful=%" PRId64 " \n", ctr1); |
| } |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * test_records |
| * ------------------------------------------------------------------------ |
| * stress test record functionality by getting and setting different |
| * records types; use the #defines defined above to determine which |
| * type of tests you'd like turned on/off |
| */ |
| void |
| test_records() |
| { |
| TSActionNeedT action; |
| char *rec_value; |
| char new_str[] = "new_record_value"; |
| TSInt port1, port2, new_port = 52432; |
| TSCounter ctr1, ctr2, new_ctr = 6666; |
| TSMgmtError err; |
| |
| /********************* START TEST SECTION *****************/ |
| printf("\n\n"); |
| |
| #if SET_INT |
| // test set integer |
| if (TSRecordSetInt("proxy.config.cop.core_signal", new_port, &action) != TS_ERR_OKAY) |
| printf("TSRecordSetInt FAILED!\n"); |
| else |
| printf("[TSRecordSetInt] proxy.config.cop.core_signal=%" PRId64 " \n", new_port); |
| #endif |
| |
| #if TEST_REC_GET |
| TSRecordEle *rec_ele; |
| // retrieve a string value record using generic RecordGet |
| rec_ele = TSRecordEleCreate(); |
| if (TSRecordGet("proxy.config.http.cache.vary_default_other", rec_ele) != TS_ERR_OKAY) |
| printf("TSRecordGet FAILED!\n"); |
| else |
| printf("[TSRecordGet] proxy.config.http.cache.vary_default_other=%s\n", rec_ele->string_val); |
| |
| TSRecordEleDestroy(rec_ele); |
| printf("\n\n"); |
| #endif |
| |
| #if TEST_REC_GET_2 |
| // retrieve a string value record using generic RecordGet |
| rec_ele = TSRecordEleCreate(); |
| if (TSRecordGet("proxy.config.proxy_name", rec_ele) != TS_ERR_OKAY) |
| printf("TSRecordGet FAILED!\n"); |
| else |
| printf("[TSRecordGet] proxy.config.proxy_name=%s\n", rec_ele->string_val); |
| |
| TSRecordEleDestroy(rec_ele); |
| printf("\n\n"); |
| #endif |
| |
| #if TEST_STRING |
| // retrieve an string value record using GetString |
| err = TSRecordGetString("proxy.config.proxy_name", &rec_value); |
| if (err != TS_ERR_OKAY) { |
| print_err("TSRecordGetString", err); |
| } else { |
| printf("[TSRecordGetString] proxy.config.proxy_name=%s\n", rec_value); |
| } |
| TSfree(rec_value); |
| rec_value = nullptr; |
| |
| // test RecordSet |
| err = TSRecordSetString("proxy.config.proxy_name", (TSString)new_str, &action); |
| if (err != TS_ERR_OKAY) { |
| print_err("TSRecordSetString", err); |
| } else { |
| printf("[TSRecordSetString] proxy.config.proxy_name=%s\n", new_str); |
| } |
| |
| // get |
| err = TSRecordGetString("proxy.config.proxy_name", &rec_value); |
| if (err != TS_ERR_OKAY) { |
| print_err("TSRecordGetString", err); |
| } else { |
| printf("[TSRecordGetString] proxy.config.proxy_name=%s\n", rec_value); |
| } |
| printf("\n"); |
| TSfree(rec_value); |
| #endif |
| |
| #if TEST_INT |
| printf("\n"); |
| // test get integer |
| if (TSRecordGetInt("proxy.config.cop.core_signal", &port1) != TS_ERR_OKAY) { |
| printf("TSRecordGetInt FAILED!\n"); |
| } else { |
| printf("[TSRecordGetInt] proxy.config.cop.core_signal=%" PRId64 " \n", port1); |
| } |
| |
| // test set integer |
| if (TSRecordSetInt("proxy.config.cop.core_signal", new_port, &action) != TS_ERR_OKAY) { |
| printf("TSRecordSetInt FAILED!\n"); |
| } else { |
| printf("[TSRecordSetInt] proxy.config.cop.core_signal=%" PRId64 " \n", new_port); |
| } |
| |
| if (TSRecordGetInt("proxy.config.cop.core_signal", &port2) != TS_ERR_OKAY) { |
| printf("TSRecordGetInt FAILED!\n"); |
| } else { |
| printf("[TSRecordGetInt] proxy.config.cop.core_signal=%" PRId64 " \n", port2); |
| } |
| printf("\n"); |
| #endif |
| |
| #if TEST_COUNTER |
| printf("\n"); |
| |
| if (TSRecordGetCounter("proxy.process.socks.connections_successful", &ctr1) != TS_ERR_OKAY) { |
| printf("TSRecordGetCounter FAILED!\n"); |
| } else { |
| printf("[TSRecordGetCounter]proxy.process.socks.connections_successful=%" PRId64 " \n", ctr1); |
| } |
| |
| if (TSRecordSetCounter("proxy.process.socks.connections_successful", new_ctr, &action) != TS_ERR_OKAY) { |
| printf("TSRecordSetCounter FAILED!\n"); |
| } else { |
| printf("[TSRecordSetCounter] proxy.process.socks.connections_successful=%" PRId64 " \n", new_ctr); |
| } |
| |
| if (TSRecordGetCounter("proxy.process.socks.connections_successful", &ctr2) != TS_ERR_OKAY) { |
| printf("TSRecordGetCounter FAILED!\n"); |
| } else { |
| printf("[TSRecordGetCounter]proxy.process.socks.connections_successful=%" PRId64 " \n", ctr2); |
| } |
| printf("\n"); |
| #endif |
| } |
| |
| // retrieves the value of the "proxy.config.xxx" record requested at input |
| void |
| test_rec_get(char *rec_name) |
| { |
| TSRecordEle *rec_ele; |
| TSMgmtError ret; |
| char *name; |
| |
| name = ats_strdup(rec_name); |
| printf("[test_rec_get] Get Record: %s\n", name); |
| |
| // retrieve a string value record using generic RecordGet |
| rec_ele = TSRecordEleCreate(); |
| if ((ret = TSRecordGet(name, rec_ele)) != TS_ERR_OKAY) { |
| printf("TSRecordGet FAILED!\n"); |
| } else { |
| switch (rec_ele->rec_type) { |
| case TS_REC_INT: |
| printf("[TSRecordGet] %s=%" PRId64 "\n", name, rec_ele->valueT.int_val); |
| break; |
| case TS_REC_COUNTER: |
| printf("[TSRecordGet] %s=%" PRId64 "\n", name, rec_ele->valueT.counter_val); |
| break; |
| case TS_REC_FLOAT: |
| printf("[TSRecordGet] %s=%f\n", name, rec_ele->valueT.float_val); |
| break; |
| case TS_REC_STRING: |
| printf("[TSRecordGet] %s=%s\n", name, rec_ele->valueT.string_val); |
| break; |
| default: |
| // Handled here: |
| // TS_REC_UNDEFINED |
| break; |
| } |
| } |
| |
| print_err("TSRecordGet", ret); |
| |
| TSRecordEleDestroy(rec_ele); |
| TSfree(name); |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * test_record_get_mlt |
| * ------------------------------------------------------------------------ |
| * Creates a list of record names to retrieve, and then batch request to |
| * get list of records |
| */ |
| void |
| test_record_get_mlt() |
| { |
| TSStringList name_list; |
| TSList rec_list; |
| int i, num; |
| char *v1, *v2, *v3, *v6, *v7; |
| TSMgmtError ret; |
| |
| name_list = TSStringListCreate(); |
| rec_list = TSListCreate(); |
| |
| const size_t v1_size = (sizeof(char) * (strlen("proxy.config.proxy_name") + 1)); |
| v1 = static_cast<char *>(TSmalloc(v1_size)); |
| ink_strlcpy(v1, "proxy.config.proxy_name", v1_size); |
| const size_t v2_size = (sizeof(char) * (strlen("proxy.config.bin_path") + 1)); |
| v2 = static_cast<char *>(TSmalloc(v2_size)); |
| ink_strlcpy(v2, "proxy.config.bin_path", v2_size); |
| const size_t v3_size = (sizeof(char) * (strlen("proxy.config.manager_binary") + 1)); |
| v3 = static_cast<char *>(TSmalloc(v3_size)); |
| ink_strlcpy(v3, "proxy.config.manager_binary", v3_size); |
| const size_t v6_size = (sizeof(char) * (strlen("proxy.config.env_prep") + 1)); |
| v6 = static_cast<char *>(TSmalloc(v6_size)); |
| ink_strlcpy(v6, "proxy.config.env_prep", v6_size); |
| const size_t v7_size = (sizeof(char) * (strlen("proxy.config.cop.core_signal") + 1)); |
| v7 = static_cast<char *>(TSmalloc(v7_size)); |
| ink_strlcpy(v7, "proxy.config.cop.core_signal", v7_size); |
| |
| // add the names to the get_list |
| TSStringListEnqueue(name_list, v1); |
| TSStringListEnqueue(name_list, v2); |
| TSStringListEnqueue(name_list, v3); |
| TSStringListEnqueue(name_list, v6); |
| TSStringListEnqueue(name_list, v7); |
| |
| num = TSStringListLen(name_list); |
| printf("Num Records to Get: %d\n", num); |
| ret = TSRecordGetMlt(name_list, rec_list); |
| // free the string list |
| TSStringListDestroy(name_list); |
| if (ret != TS_ERR_OKAY) { |
| print_err("TSStringListDestroy", ret); |
| } |
| |
| for (i = 0; i < num; i++) { |
| TSRecordEle *rec_ele = static_cast<TSRecordEle *>(TSListDequeue(rec_list)); |
| if (!rec_ele) { |
| printf("ERROR\n"); |
| break; |
| } |
| printf("Record: %s = ", rec_ele->rec_name); |
| switch (rec_ele->rec_type) { |
| case TS_REC_INT: |
| printf("%" PRId64 "\n", rec_ele->valueT.int_val); |
| break; |
| case TS_REC_COUNTER: |
| printf("%" PRId64 "\n", rec_ele->valueT.counter_val); |
| break; |
| case TS_REC_FLOAT: |
| printf("%f\n", rec_ele->valueT.float_val); |
| break; |
| case TS_REC_STRING: |
| printf("%s\n", rec_ele->valueT.string_val); |
| break; |
| default: |
| // Handled here: |
| // TS_REC_UNDEFINED |
| break; |
| } |
| TSRecordEleDestroy(rec_ele); |
| } |
| |
| TSListDestroy(rec_list); // must dequeue and free each string individually |
| |
| return; |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * test_record_set_mlt |
| * ------------------------------------------------------------------------ |
| * Creates a list of TSRecordEle's, and then batch request to set records |
| * Also checks to make sure correct action_need type is set. |
| */ |
| void |
| test_record_set_mlt() |
| { |
| TSList list; |
| TSRecordEle *ele1, *ele2; |
| TSActionNeedT action = TS_ACTION_UNDEFINED; |
| TSMgmtError err; |
| |
| list = TSListCreate(); |
| |
| ele1 = TSRecordEleCreate(); // TS_TYPE_UNDEFINED action |
| ele1->rec_name = TSstrdup("proxy.config.cli_binary"); |
| ele1->rec_type = TS_REC_STRING; |
| ele1->valueT.string_val = TSstrdup(ele1->rec_name); |
| |
| ele2 = TSRecordEleCreate(); // undefined action |
| ele2->rec_name = TSstrdup("proxy.config.cop.core_signal"); |
| ele2->rec_type = TS_REC_INT; |
| ele2->valueT.int_val = -4; |
| |
| TSListEnqueue(list, ele1); |
| TSListEnqueue(list, ele2); |
| |
| err = TSRecordSetMlt(list, &action); |
| print_err("TSRecordSetMlt", err); |
| fprintf(stderr, "[TSRecordSetMlt] Action Required: %d\n", action); |
| |
| // cleanup: need to iterate through list and delete each ele |
| int count = TSListLen(list); |
| for (int i = 0; i < count; i++) { |
| TSRecordEle *ele = static_cast<TSRecordEle *>(TSListDequeue(list)); |
| TSRecordEleDestroy(ele); |
| } |
| TSListDestroy(list); |
| } |
| |
| /*************************************************************************** |
| * File I/O Testing |
| ***************************************************************************/ |
| |
| // if valid==true, then use a valid url to read |
| void |
| test_read_url(bool valid) |
| { |
| char *header = nullptr; |
| int headerSize; |
| char *body = nullptr; |
| int bodySize; |
| TSMgmtError err; |
| |
| if (!valid) { |
| // first try |
| |
| err = TSReadFromUrlEx("hsdfasdf.com:80/index.html", &header, &headerSize, &body, &bodySize, 50000); |
| if (err != TS_ERR_OKAY) { |
| print_err("TSReadFromUrlEx", err); |
| } else { |
| printf("--------------------------------------------------------------\n"); |
| // printf("The header...\n%s\n%d\n", *header, *headerSize); |
| printf("--------------------------------------------------------------\n"); |
| printf("The body...\n%s\n%d\n", body, bodySize); |
| } |
| if (body) { |
| TSfree(body); |
| } |
| if (header) { |
| TSfree(header); |
| } |
| |
| err = TSReadFromUrlEx("http://sadfasdfi.com:80/", &header, &headerSize, &body, &bodySize, 50000); |
| if (err != TS_ERR_OKAY) { |
| print_err("TSReadFromUrlEx", err); |
| } else { |
| printf("---------------------------------------------------------------\n"); |
| printf("The header...\n%s\n%d\n", header, headerSize); |
| printf("-------------------------------------------------------------\n"); |
| printf("The body...\n%s\n%d\n", body, bodySize); |
| } |
| if (header) { |
| TSfree(header); |
| } |
| if (body) { |
| TSfree(body); |
| } |
| |
| } else { // use valid urls |
| err = TSReadFromUrlEx("lakota.example.com:80/", &header, &headerSize, &body, &bodySize, 50000); |
| |
| if (err != TS_ERR_OKAY) { |
| print_err("TSReadFromUrlEx", err); |
| } else { |
| printf("---------------------------------------------------------------\n"); |
| printf("The header...\n%s\n%d\n", header, headerSize); |
| printf("-------------------------------------------------------------\n"); |
| printf("The body...\n%s\n%d\n", body, bodySize); |
| } |
| if (header) { |
| TSfree(header); |
| } |
| if (body) { |
| TSfree(body); |
| } |
| |
| // read second url |
| err = TSReadFromUrlEx("http://www.apache.org:80/index.html", &header, &headerSize, &body, &bodySize, 50000); |
| if (err != TS_ERR_OKAY) { |
| print_err("TSReadFromUrlEx", err); |
| } else { |
| printf("---------------------------------------------------------------\n"); |
| printf("The header...\n%s\n%d\n", header, headerSize); |
| printf("-------------------------------------------------------------\n"); |
| printf("The body...\n%s\n%d\n", body, bodySize); |
| } |
| if (header) { |
| TSfree(header); |
| } |
| if (body) { |
| TSfree(body); |
| } |
| } |
| } |
| |
| /*************************************************************************** |
| * Events Testing |
| ***************************************************************************/ |
| /* ------------------------------------------------------------------------ |
| * print_active_events |
| * ------------------------------------------------------------------------ |
| * retrieves a list of all active events and prints out each event name, |
| * one event per line |
| */ |
| void |
| print_active_events() |
| { |
| TSList events; |
| TSMgmtError ret; |
| int count, i; |
| char *name; |
| |
| printf("[print_active_events]\n"); |
| |
| events = TSListCreate(); |
| ret = TSActiveEventGetMlt(events); |
| if (ret != TS_ERR_OKAY) { |
| print_err("TSActiveEventGetMlt", ret); |
| goto END; |
| } else { // successful get |
| count = TSListLen(events); |
| for (i = 0; i < count; i++) { |
| name = static_cast<char *>(TSListDequeue(events)); |
| printf("\t%s\n", name); |
| TSfree(name); |
| } |
| } |
| |
| END: |
| TSListDestroy(events); |
| return; |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * check_active |
| * ------------------------------------------------------------------------ |
| * returns true if the event named event_name is currently active (unresolved) |
| * returns false otherwise |
| */ |
| bool |
| check_active(char *event_name) |
| { |
| bool active; |
| TSMgmtError ret; |
| |
| ret = TSEventIsActive(event_name, &active); |
| print_err("TSEventIsActive", ret); |
| |
| if (active) { |
| printf("%s is ACTIVE\n", event_name); |
| } else { |
| printf("%s is NOT-ACTIVE\n", event_name); |
| } |
| |
| return active; |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * try_resolve |
| * ------------------------------------------------------------------------ |
| * checks if the event_name is still unresolved; if it is, it then |
| * resolves it, and checks the status of the event again to make sure |
| * the event was actually resolved |
| * |
| * NOTE: all the special string manipulation is needed because the CLI |
| * appends extra newline character to end of the user input; normally |
| * do not have to do all this special string manipulation |
| */ |
| void |
| try_resolve(char *event_name) |
| { |
| TSMgmtError ret; |
| char *name; |
| |
| name = TSstrdup(event_name); |
| printf("[try_resolve] Resolving event: %s\n", name); |
| |
| if (check_active(name)) { // resolve events |
| ret = TSEventResolve(name); |
| print_err("TSEventResolve", ret); |
| check_active(name); // should be non-active now |
| } |
| |
| TSfree(name); |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * eventCallbackFn |
| * ------------------------------------------------------------------------ |
| * the callback function; when called, it just prints out the name |
| * of the event that was signalled |
| */ |
| void |
| eventCallbackFn(char *name, char *msg, int /* pri ATS_UNUSED */, void * /* data ATS_UNUSED */) |
| { |
| printf("[eventCallbackFn] EVENT: %s, %s\n", name, msg); |
| return; |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * register_event_callback |
| * ------------------------------------------------------------------------ |
| * registers the eventCallbackFn above for all events; this just means |
| * that for any event that's signalled, the callback fn will also be called |
| */ |
| void |
| register_event_callback() |
| { |
| TSMgmtError err; |
| |
| printf("\n[register_event_callback] \n"); |
| err = TSEventSignalCbRegister(nullptr, eventCallbackFn, nullptr); |
| print_err("TSEventSignalCbRegister", err); |
| } |
| |
| /* ------------------------------------------------------------------------ |
| * unregister_event_callback |
| * ------------------------------------------------------------------------ |
| * unregisters the eventCallbackFn above for all events; this just means |
| * that it will remove this eventCallbackFn entirely so that for any |
| * event called, the eventCallbackFn will NOT be called |
| */ |
| void |
| unregister_event_callback() |
| { |
| TSMgmtError err; |
| |
| printf("\n[unregister_event_callback]\n"); |
| err = TSEventSignalCbUnregister(nullptr, eventCallbackFn); |
| print_err("TSEventSignalCbUnregister", err); |
| } |
| |
| /*************************************************************************** |
| * Statistics |
| ***************************************************************************/ |
| |
| // generate dummy values for statistics |
| void |
| set_stats() |
| { |
| TSActionNeedT action; |
| |
| fprintf(stderr, "[set_stats] Set Dummy Stat Values\n"); |
| |
| TSRecordSetInt("proxy.process.http.user_agent_response_document_total_size", 100, &action); |
| TSRecordSetInt("proxy.process.http.user_agent_response_header_total_size", 100, &action); |
| TSRecordSetInt("proxy.process.http.current_client_connections", 100, &action); |
| TSRecordSetInt("proxy.process.http.current_client_transactions", 100, &action); |
| TSRecordSetInt("proxy.process.http.origin_server_response_document_total_size", 100, &action); |
| TSRecordSetInt("proxy.process.http.origin_server_response_header_total_size", 100, &action); |
| TSRecordSetInt("proxy.process.http.current_server_connections", 100, &action); |
| TSRecordSetInt("proxy.process.http.current_server_transactions", 100, &action); |
| |
| TSRecordSetInt("proxy.node.proxy_running", 110, &action); |
| TSRecordSetInt("proxy.node.proxy_running", 110, &action); |
| } |
| |
| void |
| print_stats() |
| { |
| TSInt i1, i2, i3, i4, i5, i6, i7, i8; |
| |
| fprintf(stderr, "[print_stats]\n"); |
| |
| TSRecordGetInt("proxy.process.http.user_agent_response_document_total_size", &i1); |
| TSRecordGetInt("proxy.process.http.user_agent_response_header_total_size", &i2); |
| TSRecordGetInt("proxy.process.http.current_client_connections", &i3); |
| TSRecordGetInt("proxy.process.http.current_client_transactions", &i4); |
| TSRecordGetInt("proxy.process.http.origin_server_response_document_total_size", &i5); |
| TSRecordGetInt("proxy.process.http.origin_server_response_header_total_size", &i6); |
| TSRecordGetInt("proxy.process.http.current_server_connections", &i7); |
| TSRecordGetInt("proxy.process.http.current_server_transactions", &i8); |
| |
| fprintf(stderr, "%" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 "\n", i1, |
| i2, i3, i4, i5, i6, i7, i8); |
| |
| TSRecordGetInt("proxy.node.proxy_running", &i4); |
| TSRecordGetInt("proxy.node.proxy_running", &i6); |
| |
| fprintf(stderr, "%" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 "\n", i1, i7, i2, i3, i4, |
| i5, i6); |
| |
| fprintf(stderr, "PROCESS stats: \n"); |
| fprintf(stderr, "%" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 "\n", i1, i2, i3, i4); |
| } |
| |
| void |
| reset_stats() |
| { |
| TSMgmtError err = TSStatsReset(nullptr); |
| print_err("TSStatsReset", err); |
| return; |
| } |
| |
| void |
| sync_test() |
| { |
| TSActionNeedT action; |
| |
| TSRecordSetString("proxy.config.proxy_name", "dorkface", &action); |
| printf("[TSRecordSetString] proxy.config.proxy_name \n\tAction Should: [%d]\n\tAction is : [%d]\n", TS_ACTION_UNDEFINED, |
| action); |
| |
| TSMgmtError ret; |
| if ((ret = TSProxyStateSet(TS_PROXY_OFF, TS_CACHE_CLEAR_NONE)) != TS_ERR_OKAY) { |
| printf("[TSProxyStateSet] turn off FAILED\n"); |
| } |
| print_err("stop_TS", ret); |
| } |
| |
| /* ########################################################################*/ |
| /* ------------------------------------------------------------------------ |
| * runInteractive |
| * ------------------------------------------------------------------------ |
| * the loop that processes the commands inputted by user |
| */ |
| static void |
| runInteractive() |
| { |
| char buf[512]; // holds request from interactive prompt |
| |
| // process input from command line |
| while (true) { |
| // Display a prompt |
| printf("api_cli-> "); |
| |
| // get input from command line |
| ATS_UNUSED_RETURN(fgets(buf, 512, stdin)); |
| |
| // check status of 'stdin' after reading |
| if (feof(stdin) != 0) { |
| printf("EXIT api_cli_remote\n"); |
| return; |
| } else if (ferror(stdin) != 0) { |
| printf("EXIT api_cli_remote\n"); |
| return; |
| } |
| // continue on newline |
| if (strcmp(buf, "\n") == 0) { |
| continue; |
| } |
| // exiting/quitting? |
| if (strcasecmp("quit\n", buf) == 0 || strcasecmp("exit\n", buf) == 0) { |
| // Don't wait for response LM |
| // exit(0); |
| return; |
| } |
| // check what operation user typed in |
| if (strstr(buf, "state")) { |
| print_proxy_state(); |
| } else if (strncmp(buf, "start", 5) == 0) { |
| start_TS(buf); |
| } else if (strstr(buf, "stop")) { |
| stop_TS(); |
| } else if (strstr(buf, "restart")) { |
| restart(); |
| } else if (strstr(buf, "reconfig")) { |
| reconfigure(); |
| } else if (strstr(buf, "records")) { |
| test_records(); |
| } else if (strstr(buf, "err_recs")) { |
| test_error_records(); |
| } else if (strstr(buf, "get_mlt")) { |
| test_record_get_mlt(); |
| } else if (strstr(buf, "set_mlt")) { |
| test_record_set_mlt(); |
| } else if (strstr(buf, "proxy.")) { |
| test_rec_get(buf); |
| } else if (strstr(buf, "active_events")) { |
| print_active_events(); |
| } else if (strstr(buf, "MGMT_ALARM_")) { |
| try_resolve(buf); |
| } else if (strncmp(buf, "register", 8) == 0) { |
| register_event_callback(); |
| } else if (strstr(buf, "unregister")) { |
| unregister_event_callback(); |
| } else if (strstr(buf, "read_url")) { |
| test_read_url(true); |
| } else if (strstr(buf, "test_url")) { |
| test_read_url(false); |
| } else if (strstr(buf, "reset_stats")) { |
| reset_stats(); |
| } else if (strstr(buf, "set_stats")) { |
| set_stats(); |
| } else if (strstr(buf, "print_stats")) { |
| print_stats(); |
| } else { |
| sync_test(); |
| } |
| |
| } // end while(1) |
| |
| } // end runInteractive |
| |
| /* ------------------------------------------------------------------------ |
| * main |
| * ------------------------------------------------------------------------ |
| * Main entry point which connects the client to the API, does any |
| * clean up on exit, and gets the interactive command-line running |
| */ |
| int |
| main(int /* argc ATS_UNUSED */, char ** /* argv ATS_UNUSED */) |
| { |
| TSMgmtError ret; |
| |
| if ((ret = TSInit(nullptr, TS_MGMT_OPT_DEFAULTS)) == TS_ERR_OKAY) { |
| runInteractive(); |
| TSTerminate(); |
| printf("END REMOTE API TEST\n"); |
| } else { |
| print_err("main", ret); |
| } |
| |
| return 0; |
| } // end main() |