diff --git a/.gitignore b/.gitignore
index 7c605f2..8af7002 100755
--- a/.gitignore
+++ b/.gitignore
@@ -39,4 +39,10 @@ CTestTestfile.cmake
.DS_Store
Testing
cmake-build-debug
-.idea
\ No newline at end of file
+.idea
+
+gnuplot*
+googletest*
+loguru*
+rapidjson*
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index f007c33..9f366f4 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,6 +5,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/INSTALL b/INSTALL
index 9b58ab0..134983f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -4,6 +4,8 @@ To build this set of utilities on linux, osx and windows platforms.
Note that running cmake will pull down dependencies.
+Then run make, make install
+
and to create a release package
>cpack3 --config CPackConfig.cmake
diff --git a/README.md b/README.md
index 722bd4c..b2f3d97 100644
--- a/README.md
+++ b/README.md
@@ -3,14 +3,15 @@
Small collection of home grown command line utilities for working with MarkLogic.
-* ml-log: retrieve server logs
-* ml-hist: retrieve resource metrics (requires gnuplot for graphing)
-* ml-status: retrieve resource status
-* ml-xq: evaluate xquery
-* ml-js: evaluate javascript
-* ml-load: load data
-* ml-config: manage MarkLogic
-* ml-browse: browse resources
+
+* [ml-log](#ml-log): retrieve server logs
+* [ml-hist](#ml-hist): retrieve resource metrics (requires gnuplot for graphing)
+* [ml-status](#ml-status): retrieve resource status
+* [ml-xq](#ml-xq): evaluate xquery
+* [ml-js](#ml-js): evaluate javascript
+* [ml-load](#ml-load): load data
+* [ml-config](#ml-config): manage MarkLogic
+* [ml-browse](#ml-browse): browse resources
__WARNING__- Use these utilities at your own risk they are not supported in any way.
@@ -31,7 +32,7 @@ pass=admin
port=8002
path=/manage/v2
```
-
+
2) copy bin/* to your bin directory or amend PATH
3) run utils
@@ -43,7 +44,7 @@ retrieve history metrics
retrieve server logs
```
-> ./ml-log -n ErrorLog.txt
+> ./ml-log -n ErrorLog.txt
```
retrieve resource status
@@ -86,7 +87,7 @@ option.
## Utilities
-### ml-hist
+### ml-hist
retrieve history metrics from cluster/server
__NOTE__ - To use graphing capabilities you must install gnuplot (ex. yum install gnuplot).
@@ -124,13 +125,13 @@ use custom gnuplot with start and end time range
> ./ml-hist -f json -s 2015-03-21T17:38:00 -e 2017-03-21T17:38:00 -g ../../etc/basic.gnuplot -r servers/Manage -m request-time -o test.png
```
-### ml-status
+### ml-status
retrieve resource statuses
```
> ./ml-status -h
-ml-status [options]
+ml-status [options]
-r : resources/{resource-name}
-c : config file (ex. /home/jfuller/.ml-utils)
-f : format (xml|json)
@@ -141,45 +142,45 @@ ml-status [options]
cluster status (specifying ml-utils config file with -c option)
```
-> ./ml-status -c etc/.ml-utils -f json
+> ./ml-status -c etc/.ml-utils -f json
```
all forest status
```
-> ./ml-status -r forests -c etc/.ml-utils -f json
+> ./ml-status -r forests -c etc/.ml-utils -f json
```
forest status
```
-> ./ml-status -r forests/Documents -c etc/.ml-utils -f json
+> ./ml-status -r forests/Documents -c etc/.ml-utils -f json
```
database status
```
-> ./ml-status -r databases/Documents -c etc/.ml-utils -f json
+> ./ml-status -r databases/Documents -c etc/.ml-utils -f json
```
all server status
```
-> ./ml-status -r servers -c etc/.ml-utils -f json
+> ./ml-status -r servers -c etc/.ml-utils -f json
```
all host status
```
-> ./ml-status -r hosts -c etc/.ml-utils -f json
+> ./ml-status -r hosts -c etc/.ml-utils -f json
```
```
-> ./ml-status -r groups/Default -c etc/.ml-utils -f json
+> ./ml-status -r groups/Default -c etc/.ml-utils -f json
```
-### ml-log
+### ml-log
retrieve MarkLogic logs
```
> ./ml-log -h
-ml-log
+ml-log
-c : config file (ex. /home/jfuller/.ml-utils)
-f : format(xml | json)
-t : host (ex. localhost)
@@ -193,7 +194,7 @@ ml-log
get log file list
```
-> ./ml-log
+> ./ml-log
```
retrieve log file
@@ -221,7 +222,7 @@ watch (like tail) a log
watch "ml-log -n 8002_ErrorLog.txt -t localhost"
```
-### ml-load
+### ml-load
load data into MarkLogic
```
@@ -244,10 +245,10 @@ load test.json to /mytest.json into Documents database
load test.xml to /test.xml into Documents database
```
->./ml-load -u /test.xml -d Documents -f ../../etc/test.xml
+>./ml-load -u /test.xml -d Documents -f ../../etc/test.xml
```
-### ml-js
+### ml-js
evaluate javascript
```
@@ -272,7 +273,7 @@ apply against database (specifying where config file resides with -c)
> ./ml-js -c etc/.ml-utils -j 1+1 -d Documents
```
-pipe in
+pipe in
```
> echo "1+1" | ./ml-js
```
@@ -282,7 +283,7 @@ evaluate file
> ./ml-js < text.js
```
-### ml-xq
+### ml-xq
evaluate xquery
```
@@ -308,7 +309,7 @@ apply against database
> ./ml-xq -x 1+1 -d Documents
```
-pipe in
+pipe in
```
> echo "1+1" | ./ml-xq
```
@@ -318,12 +319,12 @@ evaluate file
> ./ml-xq < text.xq
```
-managing sequence output
+managing sequence output
```
-> echo "(1,2,3,4)" | ./ml-xq -r
+> echo "(1,2,3,4)" | ./ml-xq -r
```
-### ml-config
+### ml-config
manage MarkLogic
@@ -352,7 +353,7 @@ get list of databases
create forest with name 'myForest'
```
->./ml-config create -r forests -n myForest
+>./ml-config create -r forests -n myForest
```
update forest
@@ -362,7 +363,7 @@ update forest
get forest 'myForest' properties
```
->./ml-config get-properties -r forests/myForest
+>./ml-config get-properties -r forests/myForest
```
install set of resources based on ml-config directory containing properties
@@ -370,7 +371,7 @@ install set of resources based on ml-config directory containing properties
>./ml-config install
```
-### ml-browse
+### ml-browse
TBD browse resources
```
@@ -387,6 +388,14 @@ TBD browse resources
```
## Build and deploy
+
+To build you may have to install some additional deps:
+```
+yum install epel-release
+yum install cmake3
+yum install curl-devel
+```
+
To build this set of utilities on linux, osx and windows platforms.
```
@@ -395,23 +404,19 @@ To build this set of utilities on linux, osx and windows platforms.
Note that running cmake will pull down dependencies.
+then run make, make install.
+
and to create a release package
```
>cpack3 --config CPackConfig.cmake
```
-To build you may have to install some additional deps:
-```
-yum install epel-release
-yum install cmake3
-yum install curl-devel
-```
-
### Dependencies
-This project uses the following libs:
+This project uses the following libs:
+* [MarkLogic](https://developer.marklogic.com): requires MarkLogic 8 or greater
* [curl](https://curl.haxx.se/): for http communication
-* [rapidjson](https://github.com/miloyip/rapidjson): for json munging
+* [rapidjson](https://github.com/miloyip/rapidjson): for json munging
* [loguru](https://github.com/emilk/loguru): for logging
* [gnuplot-cpp](https://github.com/orbitcowboy/gnuplot-cpp): for speaking to gnuplot
* [googletest](https://github.com/google/googletest): for testing
@@ -424,7 +429,7 @@ The [examples](examples) folder contains a sample configurations and shellscript
[Apache License v2.0](LICENSE)
## Background
-This project was originally an unofficial little prototype to put MarkLogic Management REST API through its paces, to
+This project was originally an unofficial little prototype to put MarkLogic Management REST API through its paces, to
see how easy it would be to leverage. As it has grown in usefulness (to me), I thought I would
release to wider world. All PR's reviewed and appreciated. Note to self - write more unit tests!
@@ -434,4 +439,4 @@ Additionally, I wanted to try out a few modern twists
to manage releases makes life easier and the DownloadProject pulling in dependencies for building is
a great tool. Cmake is sufficient for building cross platform apps in spite of my 'Makefile muscle memory'.
-* clion: instead of emacs I used clion ... it was 'ok'
\ No newline at end of file
+* clion: instead of emacs I used clion ... it was 'ok'
diff --git a/VERSION b/VERSION
index 8294c18..341cf11 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.2
\ No newline at end of file
+0.2.0
\ No newline at end of file
diff --git a/src/admin.cpp b/src/admin.cpp
index d700ead..ba7258b 100755
--- a/src/admin.cpp
+++ b/src/admin.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#include
#include
#include
@@ -11,142 +27,326 @@
#include "admin.hpp"
-Admin::Admin() {
-};
-
-Admin::~Admin() {
-};
-
-CommandLineArgs Admin::options(int n_opts, char *opts[]) {
- CommandLineArgs args;
-
- for (int i = 1; i < n_opts; ++i) {
- string optstr = opts[i];
- if(optstr == "--host"){
- ++i;
- args.chost = opts[i];
- }else if (optstr == "--port") {
- ++i;
- args.format = opts[i];
- }else if (optstr == "--user") {
- ++i;
- args.cuser = opts[i];
- }else if (optstr == "--pass") {
- ++i;
- args.cpass = opts[i];
- }else if (optstr == "--path") {
- ++i;
- args.cpath = opts[i];
- }else if (optstr == "--protocol") {
- ++i;
- args.cprotocol = opts[i];
- }else if (optstr == "--ml-config") {
- ++i;
- args.cmlconfig = opts[i];
- }else if (optstr == "-f") {
- ++i;
- args.format = opts[i];
- }else if (optstr == "-n") {
- ++i;
- args.name = opts[i];
- } else if (optstr == "-q") {
- args.quiet = true;
- } else if (optstr == "-r") {
- ++i;
- args.resource = opts[i];
- } else if (optstr == "-c") {
- ++i;
- args.config = opts[i];
- } else if (optstr == "-p") {
- ++i;
- args.payload = opts[i];
- } else if (optstr == "-v") {
- args.verbose = true;
- } else if (optstr == "-h") {
- usage(opts[0]);
- exit(1);
- } else {
- args.command= opts[i];
+namespace mlutil {
+
+ /*!
+ *
+ */
+ Admin::Admin() {
+ };
+
+ /*!
+ *
+ */
+ Admin::~Admin() {
+ };
+
+ /*! Admin::options
+ *
+ * @param n_opts
+ * @param opts
+ * @return
+ */
+ CommandLineArgs Admin::options(int n_opts, char *opts[]) {
+ CommandLineArgs args;
+
+ for (int i = 1; i < n_opts; ++i) {
+ string optstr = opts[i];
+ if (optstr == "--host") {
+ ++i;
+ args.chost = opts[i];
+ } else if (optstr == "--port") {
+ ++i;
+ args.format = opts[i];
+ } else if (optstr == "--user") {
+ ++i;
+ args.cuser = opts[i];
+ } else if (optstr == "--pass") {
+ ++i;
+ args.cpass = opts[i];
+ } else if (optstr == "--path") {
+ ++i;
+ args.cpath = opts[i];
+ } else if (optstr == "--protocol") {
+ ++i;
+ args.cprotocol = opts[i];
+ } else if (optstr == "--ml-config") {
+ ++i;
+ args.cmlconfig = opts[i];
+ } else if (optstr == "-f") {
+ ++i;
+ args.format = opts[i];
+ } else if (optstr == "-n") {
+ ++i;
+ args.name = opts[i];
+ } else if (optstr == "-q") {
+ args.quiet = true;
+ } else if (optstr == "-r") {
+ ++i;
+ args.resource = opts[i];
+ } else if (optstr == "-c") {
+ ++i;
+ args.config = opts[i];
+ } else if (optstr == "-p") {
+ ++i;
+ args.payload = opts[i];
+ } else if (optstr == "-v") {
+ args.verbose = true;
+ } else if (optstr == "-h") {
+ usage(opts[0]);
+ exit(1);
+ } else {
+ args.command = opts[i];
+ }
}
+ args.check(opts[0]);
+ return args;
+ }
+
+ /*! Admin::usage
+ *
+ * @param progname
+ * @return
+ */
+ int Admin::usage(const char *progname) {
+ const char *name = getprogname(progname);
+ cerr << "ml-utils: ml-config 1.0 | copyright (c)2015 Jim Fuller | see https://github.com/xquery/ml-utils\n"
+ << "configure MarkLogic\n"
+ << ">" << name << " command [options]\n"
+ << " [command] : restart | get | get-properties | create | update | delete | install\n"
+ << " --ml-config : ml-config directory (ex. etc/ml-config)\n"
+ << " -c : config file (ex. /home/jfuller/.ml-utils\n"
+ << " -p : payload path \n"
+ << " -n : name \n"
+ << " -r : {resources}/{resource-name} directory\n"
+ << " -v : verbose (show http call)\n"
+ << " -q : quiet (suppress banner)" << endl;
+ return EXIT_SUCCESS;
}
- args.check(opts[0]);
- return args;
-}
-
-int Admin::usage(const char *progname) {
- const char *name = getprogname(progname);
- cerr << "ml-utils: ml-config 1.0 | copyright (c)2015 Jim Fuller | see https://github.com/xquery/ml-utils\n"
- << "configure MarkLogic\n"
- << ">" << name << " command [options]\n"
- << " [command] : restart | get | get-properties | create | update | delete | install\n"
- << " --ml-config : ml-config directory (ex. etc/ml-config)\n"
- << " -c : config file (ex. /home/jfuller/.ml-utils\n"
- << " -p : payload path \n"
- << " -n : name \n"
- << " -r : {resources}/{resource-name} directory\n"
- << " -v : verbose (show http call)\n"
- << " -q : quiet (suppress banner)" << endl;
- return EXIT_SUCCESS;
-}
-
-int Admin::walkInstallConfig(Admin admin, Config config, string path){
- DIR *dir;
- struct dirent *ent;
- if ((dir = opendir (path.c_str())) != NULL) {
- while ((ent = readdir (dir)) != NULL) {
- string name = ent->d_name;
- string fullpath = path + "/" + name;
- if (name != "." && name != ".." && name != ".DS_Store") {
- if (name.find(".json") != std::string::npos) {
- if (fullpath.find("forests") != std::string::npos) {
- cout << "installing forest" << endl;
- admin.setResourceUrl(config.port, config.path, "forests");
- admin.executeInstallPost(fullpath, "json");
- } else if (fullpath.find("databases") != std::string::npos) {
- cout << "installing database" << endl;
- admin.setResourceUrl(config.port, config.path, "databases");
- admin.executeInstallPost(fullpath, "json");
- } else if (fullpath.find("servers") != std::string::npos) {
- cout << "installing server" << endl;
- admin.setResourceUrl(config.port, config.path, "servers");
- admin.executeInstallPost(fullpath, "json");
- }else if (fullpath.find("amps") != std::string::npos) {
- cout << "installing amps" << endl;
- admin.setResourceUrl(config.port, config.path, "amps");
- admin.executeInstallPost(fullpath, "json");
- }else if (fullpath.find("external-securities") != std::string::npos) {
- cout << "installing external-securities" << endl;
- admin.setResourceUrl(config.port, config.path, "external-security");
- admin.executeInstallPost(fullpath, "json");
- }else if (fullpath.find("privileges") != std::string::npos) {
- cout << "installing privileges" << endl;
- admin.setResourceUrl(config.port, config.path, "privileges");
- admin.executeInstallPost(fullpath, "json");
- }else if (fullpath.find("security/roles") != std::string::npos) {
- cout << "installing roles" << endl;
- admin.setResourceUrl(config.port, config.path, "roles");
- admin.executeInstallPost(fullpath, "json");
- }else if (fullpath.find("users") != std::string::npos) {
- cout << "installing users" << endl;
- admin.setResourceUrl(config.port, config.path, "users");
- admin.executeInstallPost(fullpath, "json");
- }else if (fullpath.find("protected-paths") != std::string::npos) {
- cout << "installing protected-paths" << endl;
- admin.setResourceUrl(config.port, config.path, "protected-paths");
- admin.executeInstallPost(fullpath, "json");
+
+ /*! Admin::walkInstallConfig
+ *
+ * @param admin
+ * @param config
+ * @param path
+ * @return
+ */
+ int Admin::walkInstallConfig(Admin admin, Config config, string path) {
+ DIR *dir;
+ struct dirent *ent;
+ if ((dir = opendir(path.c_str())) != NULL) {
+ while ((ent = readdir(dir)) != NULL) {
+ string name = ent->d_name;
+ string fullpath = path + "/" + name;
+ if (name != "." && name != ".." && name != ".DS_Store") {
+ if (name.find(".json") != std::string::npos) {
+ if (fullpath.find("forests") != std::string::npos) {
+ cout << "installing forest" << endl;
+ admin.setResourceUrl(config.port, config.path, "forests");
+ admin.executeInstallPost(fullpath, "json");
+ } else if (fullpath.find("databases") != std::string::npos) {
+ cout << "installing database" << endl;
+ admin.setResourceUrl(config.port, config.path, "databases");
+ admin.executeInstallPost(fullpath, "json");
+ } else if (fullpath.find("servers") != std::string::npos) {
+ cout << "installing server" << endl;
+ admin.setResourceUrl(config.port, config.path, "servers");
+ admin.executeInstallPost(fullpath, "json");
+ } else if (fullpath.find("amps") != std::string::npos) {
+ cout << "installing amps" << endl;
+ admin.setResourceUrl(config.port, config.path, "amps");
+ admin.executeInstallPost(fullpath, "json");
+ } else if (fullpath.find("external-securities") != std::string::npos) {
+ cout << "installing external-securities" << endl;
+ admin.setResourceUrl(config.port, config.path, "external-security");
+ admin.executeInstallPost(fullpath, "json");
+ } else if (fullpath.find("privileges") != std::string::npos) {
+ cout << "installing privileges" << endl;
+ admin.setResourceUrl(config.port, config.path, "privileges");
+ admin.executeInstallPost(fullpath, "json");
+ } else if (fullpath.find("security/roles") != std::string::npos) {
+ cout << "installing roles" << endl;
+ admin.setResourceUrl(config.port, config.path, "roles");
+ admin.executeInstallPost(fullpath, "json");
+ } else if (fullpath.find("users") != std::string::npos) {
+ cout << "installing users" << endl;
+ admin.setResourceUrl(config.port, config.path, "users");
+ admin.executeInstallPost(fullpath, "json");
+ } else if (fullpath.find("protected-paths") != std::string::npos) {
+ cout << "installing protected-paths" << endl;
+ admin.setResourceUrl(config.port, config.path, "protected-paths");
+ admin.executeInstallPost(fullpath, "json");
+ }
+ } else if (name.find(".xml") != std::string::npos) {
+ cout << "ignoring xml properties" << endl;
+ } else {
+ walkInstallConfig(admin, config, fullpath);
}
- }else if (name.find(".xml") != std::string::npos) {
- cout << "ignoring xml properties" << endl;
- }else{
- walkInstallConfig(admin, config, fullpath);
}
}
+ closedir(dir);
+ } else {
+ /* could not open directory */
+ LOG_S(ERROR) << "problem installing";
+ return EXIT_FAILURE;
}
- closedir (dir);
- } else {
- /* could not open directory */
- LOG_S(ERROR) << "problem installing";
- return EXIT_FAILURE;
+ return EXIT_SUCCESS;
}
- return EXIT_SUCCESS;
+
+ /*! executeResourcePut
+ *
+ * @param body
+ * @param format
+ * @return
+ */
+ int Admin::executeResourcePut(string body, string format) {
+
+ int handle_count;
+ curlm = curl_multi_init();
+
+ curl1 = curl_easy_init();
+
+ curl_multi_setopt(curlm, CURLMOPT_PIPELINING, 0L);
+
+ if (format == "xml") {
+ headers = curl_slist_append(headers, "Content-Type: application/xml");
+ } else {
+ headers = curl_slist_append(headers, "Content-Type: application/json");
+ }
+
+ if (curl1) {
+ curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
+
+ curl_easy_setopt(curl1, CURLOPT_USERNAME, config.user.c_str());
+ curl_easy_setopt(curl1, CURLOPT_PASSWORD, config.pass.c_str());
+
+ if (current.verbose) {
+ curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
+ } else {
+ curl_easy_setopt(curl1, CURLOPT_VERBOSE, 0L);
+ }
+
+ curl_easy_setopt(curl1, CURLOPT_USERAGENT, "ml-utils via curl");
+
+ curl_easy_setopt(curl1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+ curl_easy_setopt(curl1, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt(curl1, CURLOPT_DEBUGFUNCTION, log_trace);
+ curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
+
+ curl_easy_setopt(curl1, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt(curl1, CURLOPT_PUT, 1L);
+ curl_easy_setopt(curl1, CURLOPT_READDATA, body.c_str());
+
+ curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
+
+ curl_multi_add_handle(curlm, curl1);
+ CURLMcode code;
+ while (1) {
+ code = curl_multi_perform(curlm, &handle_count);
+
+ if (handle_count == 0) {
+ curl_global_cleanup();
+
+ break;
+ }
+ }
+ //std::cout << readBuffer << std::endl;
+ }
+
+ curl_global_cleanup();
+
+ return EXIT_SUCCESS;
+
+ };
+
+ /*! executeResourcePost
+ *
+ * @param body
+ * @param format
+ * @return
+ */
+ int Admin::executeResourcePost(string body, string format) {
+
+ long http_code = 0;
+
+ int handle_count;
+
+ if (format == "xml") {
+ curl_slist_append(headers, "Content-Type: application/xml");
+ } else {
+ curl_slist_append(headers, "Content-Type: application/json");
+ }
+ initCurl();
+
+ if (curl1) {
+
+ curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
+
+ curl_easy_setopt(curl1, CURLOPT_POSTFIELDS, body.c_str());
+ curl_easy_setopt(curl1, CURLOPT_POSTFIELDSIZE, body.length());
+ curl_easy_setopt(curl1, CURLOPT_POST, 1);
+
+ curl_easy_getinfo (curl1, CURLINFO_RESPONSE_CODE, &http_code);
+
+ curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
+
+ CURLMcode code;
+ while (1) {
+ code = curl_multi_perform(curlm, &handle_count);
+ if (handle_count == 0) {
+ curl_global_cleanup();
+ break;
+ }
+ }
+ }
+ return EXIT_SUCCESS;
+ };
+
+ /*! executeInstallPost
+ *
+ * @param filename
+ * @param format
+ * @return
+ */
+ int Admin::executeInstallPost(string filename, string format) {
+ std::ifstream ifs(filename);
+ string body = string((std::istreambuf_iterator(ifs)), std::istreambuf_iterator());
+
+ int handle_count;
+
+ struct curl_httppost *post = NULL;
+ struct curl_httppost *last = NULL;
+
+ if (current.verbose) {
+ curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
+ } else {
+ curl_easy_setopt(curl1, CURLOPT_VERBOSE, 0L);
+ }
+ if (format == "xml") {
+ headers = curl_slist_append(headers, "Content-Type: application/xml");
+ } else {
+ headers = curl_slist_append(headers, "Content-Type: application/json");
+ }
+
+ initCurl();
+
+ if (curl1) {
+ curl_easy_setopt(curl1, CURLOPT_POSTFIELDS, body.c_str());
+ curl_easy_setopt(curl1, CURLOPT_POST, 1L);
+ curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
+ curl_multi_add_handle(curlm, curl1);
+ CURLMcode code;
+ while (1) {
+ code = curl_multi_perform(curlm, &handle_count);
+ if (handle_count == 0) {
+ curl_global_cleanup();
+ break;
+ }
+ }
+ //std::cout << readBuffer << std::endl;
+ }
+ return EXIT_SUCCESS;
+ };
}
\ No newline at end of file
diff --git a/src/admin.hpp b/src/admin.hpp
index 6ef6d85..901387e 100755
--- a/src/admin.hpp
+++ b/src/admin.hpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#pragma once
#include
@@ -21,12 +37,24 @@
using namespace std;
-class Admin : public Command {
-public:
- Admin();
- virtual ~Admin();
- virtual CommandLineArgs options(int n_opts, char *opts[]);
- virtual int usage(const char *progname);
+namespace mlutil {
+
+ class Admin : public Command {
+ public:
+ Admin();
+
+ virtual ~Admin();
+
+ virtual CommandLineArgs options(int n_opts, char *opts[]);
+
+ virtual int usage(const char *progname);
+
+ virtual int walkInstallConfig(Admin admin, Config config, string path);
+
+ virtual int executeResourcePut(string body, string format);
+
+ virtual int executeResourcePost(string body, string format);
- virtual int walkInstallConfig(Admin admin, Config config, string path);
-};
+ virtual int executeInstallPost(string filename, string format);
+ };
+}
\ No newline at end of file
diff --git a/src/browse.cpp b/src/browse.cpp
index 765c2b9..e0bd11c 100755
--- a/src/browse.cpp
+++ b/src/browse.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#include
#include
#include
@@ -10,56 +26,76 @@
#include "browse.hpp"
-Browse::Browse() {
- //std::cout << "status constructor called\n";
-};
+namespace mlutil {
+
+ /*! Browse::Browse
+ *
+ */
+ Browse::Browse() {
+ //std::cout << "status constructor called\n";
+ };
-Browse::~Browse() {
- //std::cout << "status destructor called\n";
-};
+ /*! BRowse::~Browse
+ *
+ */
+ Browse::~Browse() {
+ //std::cout << "status destructor called\n";
+ };
-CommandLineArgs Browse::options(int n_opts, char *opts[]) {
- CommandLineArgs args;
+ /*! Browse::options
+ *
+ * @param n_opts
+ * @param opts
+ * @return
+ */
+ CommandLineArgs Browse::options(int n_opts, char *opts[]) {
+ CommandLineArgs args;
- args.group = "Default";
+ args.group = "Default";
- for (int i = 1; i < n_opts; ++i) {
- if (opts[i][1] == 'f') {
- ++i;
- args.format = opts[i];
- } else if (opts[i][1] == 'q') {
- args.quiet = true;
- } else if (opts[i][1] == 'v') {
- args.verbose = true;
- } else if (opts[i][1] == 'r') {
- ++i;
- args.resource = opts[i];
- } else if (opts[i][1] == 'g') {
- ++i;
- args.group = opts[i];
- } else if (opts[i][1] == 'h') {
- usage(opts[0]);
- exit(1);
- } else if (opts[i][1] == 'c') {
- ++i;
- args.config = opts[i];
- } else {
- //usage(opts[0]);
+ for (int i = 1; i < n_opts; ++i) {
+ if (opts[i][1] == 'f') {
+ ++i;
+ args.format = opts[i];
+ } else if (opts[i][1] == 'q') {
+ args.quiet = true;
+ } else if (opts[i][1] == 'v') {
+ args.verbose = true;
+ } else if (opts[i][1] == 'r') {
+ ++i;
+ args.resource = opts[i];
+ } else if (opts[i][1] == 'g') {
+ ++i;
+ args.group = opts[i];
+ } else if (opts[i][1] == 'h') {
+ usage(opts[0]);
+ exit(1);
+ } else if (opts[i][1] == 'c') {
+ ++i;
+ args.config = opts[i];
+ } else {
+ //usage(opts[0]);
+ }
}
+ args.check(opts[0]);
+ return args;
}
- args.check(opts[0]);
- return args;
-}
-int Browse::usage(const char *progname) {
- const char *name = getprogname(progname);
- cerr << "ml-utils: ml-browse 1.0 | copyright (c)2015 Jim Fuller | see https://github.com/xquery/ml-utils\n"
- << "browse resources\n"
- << ">" << name << " [options]\n"
- << " -c : config file (ex. /home/jfuller/.ml-utils)\n"
- << " -f : format (xml|json)\n"
- << " -d : resource (databases|forests|servers|hosts) / resource-name\n"
- << " -v : verbose (show http call)\n"
- << " -q : quiet (suppress banner)" << endl;
- return EXIT_SUCCESS;
+ /*! Browse::usagee
+ *
+ * @param progname
+ * @return
+ */
+ int Browse::usage(const char *progname) {
+ const char *name = getprogname(progname);
+ cerr << "ml-utils: ml-browse 1.0 | copyright (c)2015 Jim Fuller | see https://github.com/xquery/ml-utils\n"
+ << "browse resources\n"
+ << ">" << name << " [options]\n"
+ << " -c : config file (ex. /home/jfuller/.ml-utils)\n"
+ << " -f : format (xml|json)\n"
+ << " -d : resource (databases|forests|servers|hosts) / resource-name\n"
+ << " -v : verbose (show http call)\n"
+ << " -q : quiet (suppress banner)" << endl;
+ return EXIT_SUCCESS;
+ }
}
\ No newline at end of file
diff --git a/src/browse.hpp b/src/browse.hpp
index 284d896..0af9529 100755
--- a/src/browse.hpp
+++ b/src/browse.hpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#pragma once
#include
@@ -21,12 +37,17 @@
using namespace std;
-class Browse : public Command {
-public:
- Browse();
- virtual ~Browse();
- virtual CommandLineArgs options(int n_opts, char *opts[]);
- virtual int usage(const char *progname);
-};
+namespace mlutil {
+
+ class Browse : public Command {
+ public:
+ Browse();
+
+ virtual ~Browse();
+
+ virtual CommandLineArgs options(int n_opts, char *opts[]);
+ virtual int usage(const char *progname);
+ };
+}
diff --git a/src/command.hpp b/src/command.hpp
index 44fcbbb..7d987e1 100755
--- a/src/command.hpp
+++ b/src/command.hpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#pragma once
#include
@@ -44,799 +60,555 @@ void sleep(int i) { Sleep(i*1000); }
using namespace rapidjson;
using namespace std;
-struct CommandLineArgs {
- CommandLineArgs()
- : command(""),
- config(""),
- format(""),
- period(""),
- start(""),
- end(""),
- regex(""),
- metric(""),
- filename(""),
- name(""),
- resource(""),
- uri(""),
- database(""),
- group(""),
- host(""),
- xquery(""),
- js(""),
- payload(""),
- output(""),
- gnuplot(""),
- chost("localhost"),
- cport("8002"),
- cuser("admin"),
- cpass("admin"),
- cpath("/manage/v2"),
- cprotocol("http"),
- cmlconfig(""),
- cmllog("/var/log/ml-util.log"),
- quiet(false),
- verbose(false),
- raw(false) {
- }
-
- void check(const char *progname) {}
-
- // config overrides
- const char *chost, *cport, *cpath, *cprotocol, *cuser, *cpass, *cmlconfig, *cmllog;
-
- //comand
- const char *command, *payload, *name;
-
- //options
- const char *config, *format, *period, *filename, *uri, *start, *end, *regex, *metric, *resource, *database, *group, *host, *xquery, *js, *output, *gnuplot;
-
- //flags
- bool quiet, verbose, raw;
-};
-
-// interface for commands
-class Command {
-private:
- Config config;
- CommandLineArgs current;
- string readBuffer;
-
- struct curl_slist *headers = NULL;
-
-public:
- string url;
-
- Command() {
- // set defaults
- loadConfig(config, current.config);
- if(config.user.empty()) {
- config.user = current.cuser;
- }
- if(config.pass.empty()) {
- config.pass = current.cpass;
- }
- if(config.host.empty()) {
- config.host = current.chost;
- }
- if(config.protocol.empty()) {
- config.protocol = current.cprotocol;
- }
- if(config.path.empty()) {
- config.path = current.cpath;
- }
- if(config.port.empty()) {
- config.port = current.cport;
- }
- if(config.mlconfig.empty()){
- config.mlconfig = current.cmlconfig;
- }
- if(config.mllog.empty()){
- config.mllog = current.cmllog;
- }
- setheaders();
- };
-
- virtual ~Command() {
- //std::cout << "Default destructor called\n";
- };
-
- virtual int usage(const char *progname) =0;
-
- virtual CommandLineArgs options(int n_opts, char *opts[]) = 0;
-
- virtual string getReadBuffer() {
- return this->readBuffer;
- }
-
- virtual CommandLineArgs getCurrentArgs() {
- return this->current;
- }
-
- virtual void setCurrentArgs(CommandLineArgs args) {
- this->current = args;
- loadConfig(config, this->current.config);
- }
-
- virtual Config getConfig() {
- return this->config;
- }
-
- virtual void setConfig(Config config) {
- this->config = config;
- }
-
- virtual bool checkConfig() {
- if (config.host.empty()) {
- cerr << "undefined MarkLogic host." << endl;
- }
- if (config.pass.empty()) {
- cerr << "undefined MarkLogic password." << endl;
- }
- if (config.protocol.empty()) {
- cerr << "undefined MarkLogic protocol." << endl;
- }
- if (config.user.empty()) {
- cerr << "undefined MarkLogic user." << endl;
- }
- }
-
- virtual void setResourceUrl(string port,
- string root,
- string resource)
- {
- checkConfig();
- url = config.protocol + "://" + config.host + ":" + port + root+ "/" + resource +"" ;
- }
-
- virtual void setLoadUrl(string port,
- string root,
- string uri)
- {
- checkConfig();
-
- url = config.protocol + "://" + config.host + ":" + port + root+"?" ;
- if (!uri.empty()) {
- url += "uri=" + uri;
- }
- string database = current.database;
- if (!database.empty()) {
- url += "&database=" + database;
- }
- }
-
- virtual void setLogUrl(string port,
- string root,
- string filename,
- string start,
- string end,
- string regex,
- string host)
- {
- checkConfig();
-
- url = config.protocol + "://" + config.host + ":" + port + root+"?" ;
- if (!filename.empty() ) {
- url += "filename=" + filename;
- }
- if (!start.empty() ) {
- url += "&start=" + start;
- }
- if (!end.empty() ) {
- url += "&end=" + end;
- }
- if (!regex.empty() ) {
- url += "®ex=" + regex;
- }
- if (!host.empty() ) {
- url += "&host=" + host;
- }
- string format = current.format;
- if (format != "") {
- url += "&format=" + format;
- }
- }
-
- virtual void setUrl(string port,
- string root,
- string path,
- string view) {
- checkConfig();
- if (view == "metrics") {
- if (path.find("/") != string::npos) {
- string res1 = path.substr(0, path.find("/"));
- url = config.protocol + "://" + config.host + ":" + port + root + "/" + res1 + "?";
- } else {
- url = config.protocol + "://" + config.host + ":" + port + root + "/" + path + "?";
- }
- } else if (view == "status") {
- url = config.protocol + "://" + config.host + ":" + port + root + "/" + path + "?";
- } else {
- url = config.protocol + "://" + config.host + ":" + port + root + "/" + path + "?";
- }
-
- if (!view.empty()) {
-
- url += "view=" + view;
- }
-
- string group = current.group;
- if (!group.empty() && view != "status") {
- url += "&group-id=" + group;
- }
- string format = current.format;
- if (format != "") {
- url += "&format=" + format;
- }
- string start = current.start;
- if (start != "") {
- url += "&start=" + start;
- }
- string end = current.end;
- if (end != "") {
- url += "&end=" + end;
- }
- string period = current.period;
- if (period != "") {
- url += "&period=" + period;
- }
-
- string metric = current.metric;
- if (!metric.empty() && view == "metrics") {
- string resource = current.resource;
- string delimiter = "/";
- string res1 = resource.substr(0, resource.find("/"));
- string res2 = path.substr(path.find("/") + 1, path.size());
- if (res1 == "databases") {
- url += "&database-metrics=" + metric;
- if (resource.find("/") != string::npos) {
- url += "&database=" + res2;
- }
- } else if (res1 == "servers") {
- url += "&server-metrics=" + metric;
- if (resource.find("/") != string::npos) {
- url += "&group-id=Default&server=" + res2;
- }
- } else if (res1 == "hosts") {
- url += "&host-metrics=" + metric;
- if (resource.find("/") != string::npos) {
- url += "&host=" + res2;
- }
- } else if (res1 == "forests") {
- url += "&forest-metrics=" + metric;
- if (resource.find("/") != string::npos) {
- url += "&forest=" + res2;
- }
- }
- }
- }
-
- virtual void setQueryUrl(string port,
- string root,
- string path,
- string view) {
- checkConfig();
- url = config.protocol + "://" + config.host + ":" + port + root + "/" + path + "?";
-
- string database = current.database;
- if (!database.empty()) {
- url += "&database=" + database;
- }
- };
-
- void setheaders(){
- headers = curl_slist_append(headers, "Accept: text/plain");
- headers = curl_slist_append(headers, "Accept: text/html");
- headers = curl_slist_append(headers, "Accept: application/xml");
- headers = curl_slist_append(headers, "Accept: application/js");
- headers = curl_slist_append(headers, "Accept: application/x-www-form-urlencoded");
+namespace mlutil {
+
+ struct CommandLineArgs {
+ CommandLineArgs()
+ : command(""),
+ config(""),
+ format(""),
+ period(""),
+ start(""),
+ end(""),
+ regex(""),
+ metric(""),
+ filename(""),
+ name(""),
+ resource(""),
+ uri(""),
+ database(""),
+ group(""),
+ host(""),
+ xquery(""),
+ js(""),
+ payload(""),
+ output(""),
+ gnuplot(""),
+ chost("localhost"),
+ cport("8002"),
+ cuser("admin"),
+ cpass("admin"),
+ cpath("/manage/v2"),
+ cprotocol("http"),
+ cmlconfig(""),
+ cmllog("/var/log/ml-util.log"),
+ quiet(false),
+ verbose(false),
+ raw(false) {
+ }
+
+ void check(const char *progname) {}
+
+ // config overrides
+ const char *chost, *cport, *cpath, *cprotocol, *cuser, *cpass, *cmlconfig, *cmllog;
+
+ //comand
+ const char *command, *payload, *name;
+
+ //options
+ const char *config, *format, *period, *filename, *uri, *start, *end, *regex, *metric, *resource, *database, *group, *host, *xquery, *js, *output, *gnuplot;
+
+ //flags
+ bool quiet, verbose, raw;
};
- static
- int log_trace(CURL *handle, curl_infotype type,
- char *data, size_t size,
- void *userp) {
- const char *text;
- (void) handle; /* prevent compiler warning */
- (void) userp;
-
- switch (type) {
- case CURLINFO_TEXT:
- LOG_S(INFO) << data;
- default: /* in case a new one is introduced to shock us */
- return 0;
-
- case CURLINFO_HEADER_OUT:
- LOG_S(INFO) << "=> Send ";
- LOG_S(INFO) << data;
- break;
- case CURLINFO_DATA_OUT:
- LOG_S(INFO) << "=> Send data";
- LOG_S(INFO) << data;
- break;
- case CURLINFO_SSL_DATA_OUT:
- LOG_S(INFO) << "=> Send SSL data";
- LOG_S(INFO) << data;
- break;
- case CURLINFO_HEADER_IN:
- LOG_S(INFO) << "<= Recv header";
- LOG_S(INFO) << data;
- break;
- case CURLINFO_DATA_IN:
- LOG_S(INFO) << "<= Recv data";
- LOG_S(INFO) << data;
- break;
- case CURLINFO_SSL_DATA_IN:
- LOG_S(INFO) << "<= Recv SSL data";
- LOG_S(INFO) << data;
- break;
- }
- }
-
- virtual int execute() {
+ // interface for commands
+ class Command {
+ private:
+ protected:
+ CommandLineArgs current;
+ Config config;
+ struct curl_slist *headers = NULL;
+ string readBuffer;
CURLM *curlm;
- int handle_count;
- curlm = curl_multi_init();
- curl_multi_setopt(curlm, CURLMOPT_PIPELINING, 0L);
-
CURL *curl1 = NULL;
- curl1 = curl_easy_init();
-
- if (curl1) {
- curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
-
- curl_easy_setopt(curl1, CURLOPT_USERNAME, config.user.c_str());
- curl_easy_setopt(curl1, CURLOPT_PASSWORD, config.pass.c_str());
-
- if (current.verbose) {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
- } else {
- curl_easy_setopt(curl1, CURLOPT_HEADER, 0);
+ CURL *curl2 = NULL;
+ string url;
+ CURLM *cm;
+ CURLMsg *msg;
+
+ public:
+
+ /*! Command
+ *
+ */
+ Command() {
+ LOG_S(INFO) << "command constructor called";
+
+ // set defaults
+ loadConfig(config, current.config);
+ if (config.user.empty()) {
+ config.user = current.cuser;
}
-
- curl_easy_setopt(curl1, CURLOPT_USERAGENT, "ml-utils via curl/7.19.6");
- curl_easy_setopt(curl1, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(curl1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
- curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl1, CURLOPT_HTTPGET, 1L);
- curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
- curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, WriteCallback);
- curl_easy_setopt(curl1, CURLOPT_WRITEDATA, &readBuffer);
- curl_easy_setopt(curl1, CURLOPT_DEBUGFUNCTION, log_trace);
-
- curl_multi_add_handle(curlm, curl1);
-
- CURLMcode code;
- while (1) {
- code = curl_multi_perform(curlm, &handle_count);
- if (handle_count == 0) {
- curl_global_cleanup();
- break;
- }
+ if (config.pass.empty()) {
+ config.pass = current.cpass;
+ }
+ if (config.host.empty()) {
+ config.host = current.chost;
+ }
+ if (config.protocol.empty()) {
+ config.protocol = current.cprotocol;
+ }
+ if (config.path.empty()) {
+ config.path = current.cpath;
+ }
+ if (config.port.empty()) {
+ config.port = current.cport;
+ }
+ if (config.mlconfig.empty()) {
+ config.mlconfig = current.cmlconfig;
+ }
+ if (config.mllog.empty()) {
+ config.mllog = current.cmllog;
}
- }
-
- curl_global_cleanup();
- return EXIT_SUCCESS;
+ initCurl();
+ };
- };
+ /*! ~Command
+ *
+ */
+ virtual ~Command() {
+ LOG_S(INFO) << "command destructor called";
+ curl_easy_cleanup(curl1);
+ curl_easy_cleanup(curl2);
+ curl_multi_cleanup(curlm);
+ curl_multi_cleanup(cm);
+ curl_global_cleanup();
+ };
- static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
- ((std::string *) userp)->append((char *) contents, size * nmemb);
- return size * nmemb;
- }
+ virtual int usage(const char *progname) =0;
+ virtual void initCurl(){
- virtual int executeQueryPost(string type, string query) {
+ curl_global_init(CURL_GLOBAL_ALL);
- CURLM *curlm;
- int handle_count;
- curlm = curl_multi_init();
+ setheaders();
- CURL *curl1 = NULL;
- curl1 = curl_easy_init();
+ cm = curl_multi_init();
- curl_multi_setopt(curlm, CURLMOPT_PIPELINING, 0L);
+ curlm = curl_multi_init();
+ curl1 = curl_easy_init();
+ curl2 = curl_easy_init();
+ curl_multi_add_handle(curlm, curl1);
- if (curl1) {
- curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
+ curl_multi_setopt(cm, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
curl_easy_setopt(curl1, CURLOPT_USERNAME, config.user.c_str());
curl_easy_setopt(curl1, CURLOPT_PASSWORD, config.pass.c_str());
+ curl_easy_setopt(curl2, CURLOPT_USERNAME, config.user.c_str());
+ curl_easy_setopt(curl2, CURLOPT_PASSWORD, config.pass.c_str());
if (current.verbose) {
curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl2, CURLOPT_VERBOSE, 1L);
} else {
curl_easy_setopt(curl1, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(curl2, CURLOPT_VERBOSE, 0L);
}
curl_easy_setopt(curl1, CURLOPT_USERAGENT, "ml-utils via curl");
curl_easy_setopt(curl1, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(curl1, CURLOPT_DEBUGFUNCTION, log_trace);
+ curl_easy_setopt(curl2, CURLOPT_USERAGENT, "ml-utils via curl");
+ curl_easy_setopt(curl2, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
-
- char *data = curl_easy_escape(curl1, query.c_str(), strlen(query.c_str()));
- string xquery = type + "=" + data;
- curl_easy_setopt(curl1, CURLOPT_POST, 1);
- curl_easy_setopt(curl1, CURLOPT_POSTFIELDS, xquery.c_str());
- curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
-
- curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, WriteCallback);
- curl_easy_setopt(curl1, CURLOPT_WRITEDATA, &readBuffer);
-
- curl_multi_add_handle(curlm, curl1);
- CURLMcode code;
- while (1) {
- code = curl_multi_perform(curlm, &handle_count);
-
- if (handle_count == 0) {
- curl_global_cleanup();
-
- break;
- }
- }
- //std::cout << readBuffer << std::endl;
- }
-
- curl_global_cleanup();
-
- return EXIT_SUCCESS;
-
- };
-
- virtual int executeLoadPost(const char* file, string body) {
+ curl_easy_setopt(curl2, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+ curl_easy_setopt(curl2, CURLOPT_FOLLOWLOCATION, 1L);
- FILE *fd;
-
- fd = fopen(file, "rb"); /* open file to upload */
-
- CURLM *curlm;
- int handle_count;
- curlm = curl_multi_init();
-
- CURL *curl1 = NULL;
- curl1 = curl_easy_init();
-
- curl_multi_setopt(curlm, CURLMOPT_PIPELINING, 0L);
-
- if (curl1) {
curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
-
- curl_easy_setopt(curl1, CURLOPT_USERNAME, config.user.c_str());
- curl_easy_setopt(curl1, CURLOPT_PASSWORD, config.pass.c_str());
-
- if (current.verbose) {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
- } else {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 0L);
- }
-
- curl_easy_setopt(curl1, CURLOPT_USERAGENT, "ml-utils via curl");
-
- curl_easy_setopt(curl1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
- curl_easy_setopt(curl1, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl1, CURLOPT_DEBUGFUNCTION, log_trace);
- curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl2, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(curl2, CURLOPT_DEBUGFUNCTION, log_trace);
- curl_easy_setopt(curl1, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt(curl1, CURLOPT_READDATA, fd);
+ };
- curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
+ virtual CommandLineArgs options(int n_opts, char *opts[]) = 0;
- curl_multi_add_handle(curlm, curl1);
- CURLMcode code;
- while (1) {
- code = curl_multi_perform(curlm, &handle_count);
- if (handle_count == 0) {
- curl_global_cleanup();
- break;
- }
- }
+ virtual string getReadBuffer() {
+ return this->readBuffer;
}
- curl_global_cleanup();
- return EXIT_SUCCESS;
- };
-
- virtual int executeResourcePost(string body, string format) {
-
- long http_code = 0;
-
- CURLM *curlm;
- int handle_count;
- curlm = curl_multi_init();
-
- CURL *curl1 = NULL;
- curl1 = curl_easy_init();
- curl_multi_setopt(curlm, CURLMOPT_PIPELINING, 0L);
-
- if(format == "xml"){
- curl_slist_append(headers, "Content-Type: application/xml");
- }else{
- curl_slist_append(headers, "Content-Type: application/json");
+ virtual CommandLineArgs getCurrentArgs() {
+ return this->current;
}
- if (curl1) {
+ virtual void setCurrentArgs(CommandLineArgs args) {
+ this->current = args;
+ loadConfig(config, this->current.config);
+ }
- curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
+ virtual Config getConfig() {
+ return this->config;
+ }
- curl_easy_setopt(curl1, CURLOPT_USERNAME, config.user.c_str());
- curl_easy_setopt(curl1, CURLOPT_PASSWORD, config.pass.c_str());
+ virtual void setConfig(Config config) {
+ this->config = config;
+ }
- if (current.verbose) {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
- } else {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 0L);
+ /*! checkConfig
+ *
+ * @return
+ */
+ virtual bool checkConfig() {
+ if (config.host.empty()) {
+ cerr << "undefined MarkLogic host." << endl;
}
-
- curl_easy_setopt(curl1, CURLOPT_USERAGENT, "ml-utils via curl");
-
- curl_easy_setopt(curl1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
- curl_easy_setopt(curl1, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(curl1, CURLOPT_DEBUGFUNCTION, log_trace);
- curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
-
- curl_easy_setopt(curl1, CURLOPT_POSTFIELDS, body.c_str());
- curl_easy_setopt(curl1, CURLOPT_POSTFIELDSIZE, body.length());
- curl_easy_setopt(curl1, CURLOPT_POST, 1);
-
- curl_easy_getinfo (curl1, CURLINFO_RESPONSE_CODE, &http_code);
-
- curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
-
- curl_multi_add_handle(curlm, curl1);
- CURLMcode code;
- while (1) {
- code = curl_multi_perform(curlm, &handle_count);
- if (handle_count == 0) {
- curl_global_cleanup();
- break;
- }
+ if (config.pass.empty()) {
+ cerr << "undefined MarkLogic password." << endl;
+ }
+ if (config.protocol.empty()) {
+ cerr << "undefined MarkLogic protocol." << endl;
+ }
+ if (config.user.empty()) {
+ cerr << "undefined MarkLogic user." << endl;
}
}
- curl_global_cleanup();
- return EXIT_SUCCESS;
- };
-
- virtual int executeResourcePut(string body, string format) {
-
- CURLM *curlm;
- int handle_count;
- curlm = curl_multi_init();
-
- CURL *curl1 = NULL;
- curl1 = curl_easy_init();
-
- curl_multi_setopt(curlm, CURLMOPT_PIPELINING, 0L);
-
- if(format == "xml"){
- headers = curl_slist_append(headers, "Content-Type: application/xml");
- }else{
- headers = curl_slist_append(headers, "Content-Type: application/json");
- }
-
- if (curl1) {
- curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
-
- curl_easy_setopt(curl1, CURLOPT_USERNAME, config.user.c_str());
- curl_easy_setopt(curl1, CURLOPT_PASSWORD, config.pass.c_str());
- if (current.verbose) {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
+ /*! setResourceUrl
+ *
+ * @param port
+ * @param root
+ * @param resource
+ */
+ virtual void setResourceUrl(string port,
+ string root,
+ string resource) {
+ checkConfig();
+ url = config.protocol + "://" + config.host + ":" + port + root + "/" + resource + "";
+ }
+
+ /*! setUrl
+ *
+ * @param port
+ * @param root
+ * @param path
+ * @param view
+ */
+ virtual void setUrl(string port,
+ string root,
+ string path,
+ string view) {
+ checkConfig();
+ if (view == "metrics") {
+ if (path.find("/") != string::npos) {
+ string res1 = path.substr(0, path.find("/"));
+ url = config.protocol + "://" + config.host + ":" + port + root + "/" + res1 + "?";
+ } else {
+ url = config.protocol + "://" + config.host + ":" + port + root + "/" + path + "?";
+ }
+ } else if (view == "status") {
+ url = config.protocol + "://" + config.host + ":" + port + root + "/" + path + "?";
} else {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 0L);
+ // identical to status for now
+ url = config.protocol + "://" + config.host + ":" + port + root + "/" + path + "?";
}
- curl_easy_setopt(curl1, CURLOPT_USERAGENT, "ml-utils via curl");
-
- curl_easy_setopt(curl1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
- curl_easy_setopt(curl1, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(curl1, CURLOPT_DEBUGFUNCTION, log_trace);
- curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
-
- curl_easy_setopt(curl1, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt(curl1, CURLOPT_PUT, 1L);
- curl_easy_setopt(curl1, CURLOPT_READDATA, body.c_str());
+ if (!view.empty()) {
- curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
-
- curl_multi_add_handle(curlm, curl1);
- CURLMcode code;
- while (1) {
- code = curl_multi_perform(curlm, &handle_count);
+ url += "view=" + view;
+ }
- if (handle_count == 0) {
- curl_global_cleanup();
+ string group = current.group;
+ if (!group.empty() && view != "status") {
+ url += "&group-id=" + group;
+ }
+ string format = current.format;
+ if (format != "") {
+ url += "&format=" + format;
+ }
+ string start = current.start;
+ if (start != "") {
+ url += "&start=" + start;
+ }
+ string end = current.end;
+ if (end != "") {
+ url += "&end=" + end;
+ }
+ string period = current.period;
+ if (period != "") {
+ url += "&period=" + period;
+ }
- break;
+ string metric = current.metric;
+ if (!metric.empty() && view == "metrics") {
+ string resource = current.resource;
+ string delimiter = "/";
+ string res1 = resource.substr(0, resource.find("/"));
+ string res2 = path.substr(path.find("/") + 1, path.size());
+ if (res1 == "databases") {
+ url += "&database-metrics=" + metric;
+ if (resource.find("/") != string::npos) {
+ url += "&database=" + res2;
+ }
+ } else if (res1 == "servers") {
+ url += "&server-metrics=" + metric;
+ if (resource.find("/") != string::npos) {
+ url += "&group-id=Default&server=" + res2;
+ }
+ } else if (res1 == "hosts") {
+ url += "&host-metrics=" + metric;
+ if (resource.find("/") != string::npos) {
+ url += "&host=" + res2;
+ }
+ } else if (res1 == "forests") {
+ url += "&forest-metrics=" + metric;
+ if (resource.find("/") != string::npos) {
+ url += "&forest=" + res2;
+ }
}
}
- //std::cout << readBuffer << std::endl;
}
- curl_global_cleanup();
-
- return EXIT_SUCCESS;
-
- };
-
- virtual int executeInstallPost(string filename, string format) {
- std::ifstream ifs(filename);
- string body = string((std::istreambuf_iterator(ifs)), std::istreambuf_iterator());
-
- CURLM *curlm;
- int handle_count;
- curlm = curl_multi_init();
-
- CURL *curl1 = NULL;
- curl1 = curl_easy_init();
-
- struct curl_httppost *post = NULL;
- struct curl_httppost *last = NULL;
-
- if (current.verbose) {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
- } else {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 0L);
- }
- if(format == "xml"){
- headers = curl_slist_append(headers, "Content-Type: application/xml");
- }else{
- headers = curl_slist_append(headers, "Content-Type: application/json");
+ /*! setheaders
+ *
+ */
+ void setheaders() {
+ headers = curl_slist_append(headers, "Accept: text/plain");
+ headers = curl_slist_append(headers, "Accept: text/html");
+ headers = curl_slist_append(headers, "Accept: application/xml");
+ headers = curl_slist_append(headers, "Accept: application/js");
+ headers = curl_slist_append(headers, "Accept: application/x-www-form-urlencoded");
+ };
+
+ /*! log_trace
+ *
+ * @param handle
+ * @param type
+ * @param data
+ * @param size
+ * @param userp
+ * @return
+ */
+ static
+ int log_trace(CURL *handle, curl_infotype type,
+ char *data, size_t size,
+ void *userp) {
+ const char *text;
+ (void) handle; /* prevent compiler warning */
+ (void) userp;
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ LOG_S(INFO) << data;
+ default: /* in case a new one is introduced to shock us */
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ LOG_S(INFO) << "=> Send ";
+ LOG_S(INFO) << data;
+ break;
+ case CURLINFO_DATA_OUT:
+ LOG_S(INFO) << "=> Send data";
+ LOG_S(INFO) << data;
+ break;
+ case CURLINFO_SSL_DATA_OUT:
+ LOG_S(INFO) << "=> Send SSL data";
+ LOG_S(INFO) << data;
+ break;
+ case CURLINFO_HEADER_IN:
+ LOG_S(INFO) << "<= Recv header";
+ LOG_S(INFO) << data;
+ break;
+ case CURLINFO_DATA_IN:
+ LOG_S(INFO) << "<= Recv data";
+ LOG_S(INFO) << data;
+ break;
+ case CURLINFO_SSL_DATA_IN:
+ LOG_S(INFO) << "<= Recv SSL data";
+ LOG_S(INFO) << data;
+ break;
+ }
}
- curl_multi_setopt(curlm, CURLMOPT_PIPELINING, 0L);
+ /*! execute
+ *
+ * @return
+ */
+ virtual int execute() {
- if (curl1) {
- curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
-
- curl_easy_setopt(curl1, CURLOPT_USERNAME, config.user.c_str());
- curl_easy_setopt(curl1, CURLOPT_PASSWORD, config.pass.c_str());
+ int handle_count;
+ curlm = curl_multi_init();
+ curl_multi_setopt(curlm, CURLMOPT_PIPELINING, 0L);
- if (current.verbose) {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
- } else {
- curl_easy_setopt(curl1, CURLOPT_VERBOSE, 0L);
- }
+ CURL *curl1 = NULL;
+ curl1 = curl_easy_init();
- curl_easy_setopt(curl1, CURLOPT_USERAGENT, "ml-utils via curl");
- curl_easy_setopt(curl1, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(curl1, CURLOPT_DEBUGFUNCTION, log_trace);
- curl_easy_setopt(curl1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
- curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
+ if (curl1) {
+ curl_easy_setopt(curl1, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(curl1, CURLOPT_POSTFIELDS, body.c_str());
- curl_easy_setopt(curl1, CURLOPT_POST, 1L);
+ curl_easy_setopt(curl1, CURLOPT_USERNAME, config.user.c_str());
+ curl_easy_setopt(curl1, CURLOPT_PASSWORD, config.pass.c_str());
- curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
+ if (current.verbose) {
+ curl_easy_setopt(curl1, CURLOPT_VERBOSE, 1L);
+ } else {
+ curl_easy_setopt(curl1, CURLOPT_HEADER, 0);
+ }
- curl_multi_add_handle(curlm, curl1);
- CURLMcode code;
- while (1) {
- code = curl_multi_perform(curlm, &handle_count);
- if (handle_count == 0) {
- curl_global_cleanup();
- break;
+ curl_easy_setopt(curl1, CURLOPT_USERAGENT, "ml-utils via curl/7.19.6");
+ curl_easy_setopt(curl1, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt(curl1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+ curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl1, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl1, CURLOPT_HTTPGET, 1L);
+ curl_easy_setopt(curl1, CURLOPT_NOPROGRESS, 1L);
+ curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, WriteCallback);
+ curl_easy_setopt(curl1, CURLOPT_WRITEDATA, &readBuffer);
+ curl_easy_setopt(curl1, CURLOPT_DEBUGFUNCTION, log_trace);
+
+ curl_multi_add_handle(curlm, curl1);
+
+ CURLMcode code;
+ while (1) {
+ code = curl_multi_perform(curlm, &handle_count);
+ if (handle_count == 0) {
+ curl_global_cleanup();
+ break;
+ }
}
}
- //std::cout << readBuffer << std::endl;
- }
-
- curl_global_cleanup();
- return EXIT_SUCCESS;
-
- };
-
- int displayargs() {
- LOG_S(INFO) << "----------------";
- LOG_S(INFO) << "options" << endl;
- LOG_S(INFO) << "----------------";
-
- LOG_S(INFO) << "format: " << current.format;
- LOG_S(INFO) << "database: " << current.database;
- LOG_S(INFO) << "xquery: " << current.xquery;
- LOG_S(INFO) << "format: " << current.format;
- LOG_S(INFO) << "period: " << current.period;
- LOG_S(INFO) << "start: " << current.start;
- LOG_S(INFO) << "end: " << current.end;
- LOG_S(INFO) << "metric: " << current.metric;
- LOG_S(INFO) << "resource: " << current.resource;
- LOG_S(INFO) << "name: " << current.name;
- LOG_S(INFO) << "ml-config: " << current.config;
- LOG_S(INFO) << "output: " << current.output;
- LOG_S(INFO) << "gnuplot: " << current.gnuplot;
- return EXIT_SUCCESS;
- };
-
- int displayconfig() {
- LOG_S(INFO) << "----------------";
- LOG_S(INFO) << "config";
- LOG_S(INFO) << "----------------";
- LOG_S(INFO) << "user: " << config.user;
- LOG_S(INFO) << "pass: " << config.pass;
- LOG_S(INFO) << "host: " << config.host;
- return EXIT_SUCCESS;
- };
- const char* getprogname(const char *progname) {
- const char *name = progname;
- while (*progname != 0) {
- if (*progname == '/' || *progname == '\\') {
- ++progname;
- name = progname;
- } else {
- ++progname;
+ curl_global_cleanup();
+
+ return EXIT_SUCCESS;
+
+ };
+
+ /*! WriteCallback
+ *
+ * @param contents
+ * @param size
+ * @param nmemb
+ * @param userp
+ * @return
+ */
+ static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
+ ((std::string *) userp)->append((char *) contents, size * nmemb);
+ return size * nmemb;
+ }
+
+ /*! displayargs
+ *
+ * @return
+ */
+ int displayargs() {
+ LOG_S(INFO) << "----------------";
+ LOG_S(INFO) << "options" << endl;
+ LOG_S(INFO) << "----------------";
+
+ LOG_S(INFO) << "format: " << current.format;
+ LOG_S(INFO) << "database: " << current.database;
+ LOG_S(INFO) << "xquery: " << current.xquery;
+ LOG_S(INFO) << "format: " << current.format;
+ LOG_S(INFO) << "period: " << current.period;
+ LOG_S(INFO) << "start: " << current.start;
+ LOG_S(INFO) << "end: " << current.end;
+ LOG_S(INFO) << "metric: " << current.metric;
+ LOG_S(INFO) << "resource: " << current.resource;
+ LOG_S(INFO) << "name: " << current.name;
+ LOG_S(INFO) << "ml-config: " << current.config;
+ LOG_S(INFO) << "output: " << current.output;
+ LOG_S(INFO) << "gnuplot: " << current.gnuplot;
+ return EXIT_SUCCESS;
+ };
+
+ int displayconfig() {
+ LOG_S(INFO) << "----------------";
+ LOG_S(INFO) << "config";
+ LOG_S(INFO) << "----------------";
+ LOG_S(INFO) << "user: " << config.user;
+ LOG_S(INFO) << "pass: " << config.pass;
+ LOG_S(INFO) << "host: " << config.host;
+ return EXIT_SUCCESS;
+ };
+
+ /*! getprogname
+ *
+ * @param progname
+ * @return
+ */
+ const char *getprogname(const char *progname) {
+ const char *name = progname;
+ while (*progname != 0) {
+ if (*progname == '/' || *progname == '\\') {
+ ++progname;
+ name = progname;
+ } else {
+ ++progname;
+ }
}
- }
- return name;
- };
-
- void doPlot(string output, string plot, string units, string name, string resource, const Value &entries) {
-
- //Gnuplot::set_terminal_std("dumb");
- Gnuplot g1("linespoints");
- g1.remove_tmpfiles();
- g1.set_ylabel(units);
- g1.set_xlabel("time");
- g1.cmd("set xdata time");
- g1.cmd("set timefmt '%Y-%m-%dT%H:%M:%S'");
- g1.cmd("set timefmt '%Y-%m-%dT%H:%M:%S'");
-
- if (plot.empty()) {
- if (output.find(string("jpg")) != std::string::npos) {
- g1.cmd("set terminal 'jpeg' size 900,500 nocrop enhanced font 'Verdana,10' size 900,500 background '#FFFCF5'");
- } else if (output.find(string("jpeg")) != std::string::npos) {
- g1.cmd("set terminal 'jpeg' size 900,500 nocrop enhanced font 'Verdana,10' size 900,500 background '#FFFCF5'");
- } else if (output.find(string("png")) != std::string::npos) {
- g1.cmd("set terminal 'pngcairo' nocrop enhanced font 'Verdana,10' size 900,500 background '#FFFCF5'");
+ return name;
+ };
+
+ /*! doPlot
+ *
+ * @param output
+ * @param plot
+ * @param units
+ * @param name
+ * @param resource
+ * @param entries
+ */
+ void doPlot(string output, string plot, string units, string name, string resource, const Value &entries) {
+
+ //Gnuplot::set_terminal_std("dumb");
+ Gnuplot g1("linespoints");
+ g1.remove_tmpfiles();
+ g1.set_ylabel(units);
+ g1.set_xlabel("time");
+ g1.cmd("set xdata time");
+ g1.cmd("set timefmt '%Y-%m-%dT%H:%M:%S'");
+ g1.cmd("set timefmt '%Y-%m-%dT%H:%M:%S'");
+
+ if (plot.empty()) {
+ if (output.find(string("jpg")) != std::string::npos) {
+ g1.cmd("set terminal 'jpeg' size 900,500 nocrop enhanced font 'Verdana,10' size 900,500 background '#FFFCF5'");
+ } else if (output.find(string("jpeg")) != std::string::npos) {
+ g1.cmd("set terminal 'jpeg' size 900,500 nocrop enhanced font 'Verdana,10' size 900,500 background '#FFFCF5'");
+ } else if (output.find(string("png")) != std::string::npos) {
+ g1.cmd("set terminal 'pngcairo' nocrop enhanced font 'Verdana,10' size 900,500 background '#FFFCF5'");
+ } else {
+ g1.cmd("set terminal 'dumb'");
+ }
+ // default gnuplot settings
+ g1.cmd(
+ "unset key\n"
+ "set xlabel \"Time\" textcolor'#000000'\n"
+ "set ylabel \"" + units + "\" textcolor '#000000'\n"
+ "set label textcolor '#000000'\n"
+ "set border 10 lw 1 lc '#038DDD'\n"
+ "set grid lc '#038DDD'\n"
+ "set border 0 back ls 11\n"
+ "set grid\n"
+ "set autoscale y\n"
+ "set autoscale x\n"
+ "set xtics rotate by -45 offset -0.1,-0.1\n"
+ "set mxtics\n"
+ "set mytics\n");
+ g1.set_style("linespoints linetype 1 lw 1 lc '#025072' pt 7 ps .5");
} else {
- g1.cmd("set terminal 'dumb'");
+ // load custom gnuplot
+ g1.set_GNUPlotPath(plot);
}
- // default gnuplot settings
- g1.cmd(
- "unset key\n"
- "set xlabel \"Time\" textcolor'#000000'\n"
- "set ylabel \""+units+"\" textcolor '#000000'\n"
- "set label textcolor '#000000'\n"
- "set border 10 lw 1 lc '#038DDD'\n"
- "set grid lc '#038DDD'\n"
- "set border 0 back ls 11\n"
- "set grid\n"
- "set autoscale y\n"
- "set autoscale x\n"
- "set xtics rotate by -45 offset -0.1,-0.1\n"
- "set mxtics\n"
- "set mytics\n");
- g1.set_style("linespoints linetype 1 lw 1 lc '#025072' pt 7 ps .5");
- } else {
- // load custom gnuplot
- g1.set_GNUPlotPath(plot);
- }
- vector x;
- vector y;
- string firstDT, lastDT;
- for (SizeType i = 0; i < entries.Size(); i++) {
- const Value &entry = entries[i];
- if (i == 0) {
- firstDT = entry["dt"].GetString();
- }
- if (i == entries.Size() - 1) {
- lastDT = entry["dt"].GetString();
+ vector x;
+ vector y;
+ string firstDT, lastDT;
+ for (SizeType i = 0; i < entries.Size(); i++) {
+ const Value &entry = entries[i];
+ if (i == 0) {
+ firstDT = entry["dt"].GetString();
+ }
+ if (i == entries.Size() - 1) {
+ lastDT = entry["dt"].GetString();
+ }
+ x.push_back(entry["dt"].GetString());
+ y.push_back(entry["value"].GetDouble());
}
- x.push_back(entry["dt"].GetString());
- y.push_back(entry["value"].GetDouble());
- }
- g1.cmd("set xrange ['" + firstDT+ "':'" + lastDT + "']");
+ g1.cmd("set xrange ['" + firstDT + "':'" + lastDT + "']");
// auto maxY = std::max_element(std::begin(y), std::end(y));
// auto minY = std::max_element(std::begin(y), std::end(y));
@@ -844,14 +616,14 @@ class Command {
// minV << *minY;
// maxV << *maxY;
// g1.cmd("set yrange ['" + minV.str() + "':'" + maxV.str() + "']");
- g1.cmd("set title '{/Verdana " + resource + ":" + name + "}' ");
-
- if(!output.empty()){
- g1.cmd("set output '" + output + "'");
- }
+ g1.cmd("set title '{/Verdana " + resource + ":" + name + "}' ");
- g1.plot_xy(x, y);
- }
-};
+ if (!output.empty()) {
+ g1.cmd("set output '" + output + "'");
+ }
+ g1.plot_xy(x, y);
+ }
+ };
+}
diff --git a/src/config.hpp b/src/config.hpp
index 2aa828f..410542a 100755
--- a/src/config.hpp
+++ b/src/config.hpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#pragma once
#include
@@ -27,62 +43,66 @@
#define GetCurrentDir getcwd
#endif
-char pPath[FILENAME_MAX];
+namespace mlutil {
-using namespace std;
+ char pPath[FILENAME_MAX];
-bool is_file_exist(string fileName) {
- std::ifstream infile(fileName);
- return infile.good();
-}
+ using namespace std;
-struct Config {
- string user;
- string pass;
- string host;
- string protocol;
- string port;
- string path;
- string mlconfig;
- string mllog;
-};
+ bool is_file_exist(string fileName) {
+ std::ifstream infile(fileName);
+ return infile.good();
+ }
-void loadConfig(Config &config, string path) {
- std::string homepath = getenv("HOME");
- GetCurrentDir(pPath, sizeof(pPath));
- std::string currentpath = pPath;
- std::string mlutils;
+ struct Config {
+ string user;
+ string pass;
+ string host;
+ string protocol;
+ string port;
+ string path;
+ string mlconfig;
+ string mllog;
+ };
- if (is_file_exist(path)) {
- mlutils = (path).c_str();
- } else if (is_file_exist(currentpath + "/.ml-utils")) {
- mlutils = (currentpath + "/.ml-utils").c_str();
- } else if (is_file_exist(homepath + "/.ml-utils")) {
- mlutils = (homepath + "/.ml-utils").c_str();
- } else {
- mlutils = (path).c_str();
- }
+ void loadConfig(Config &config, string path) {
+ std::string homepath = getenv("HOME");
+ GetCurrentDir(pPath, sizeof(pPath));
+ std::string currentpath = pPath;
+ std::string mlutils;
- ifstream fin(mlutils);
- std:
- string line;
+ if (is_file_exist(path)) {
+ mlutils = (path).c_str();
+ } else if (is_file_exist(currentpath + "/.ml-utils")) {
+ mlutils = (currentpath + "/.ml-utils").c_str();
+ } else if (is_file_exist(homepath + "/.ml-utils")) {
+ mlutils = (homepath + "/.ml-utils").c_str();
+ } else {
+ mlutils = (path).c_str();
+ }
- while (getline(fin, line)) {
- istringstream sin(line.substr(line.find("=") + 1));
- if (line.find("user") != -1)
- sin >> config.user;
- else if (line.find("pass") != -1)
- sin >> config.pass;
- else if (line.find("host") != -1)
- sin >> config.host;
- else if (line.find("protocol") != -1)
- sin >> config.protocol;
- else if (line.find("port") != -1)
- sin >> config.port;
- else if (line.find("ml-config") != -1)
- sin >> config.mlconfig;
- else if (line.find("ml-log") != -1)
- sin >> config.mllog;
- else if (line.find("path") != -1)
- sin >> config.path; }
-}
+ ifstream fin(mlutils);
+ std:
+ string line;
+
+ while (getline(fin, line)) {
+ istringstream sin(line.substr(line.find("=") + 1));
+ if (line.find("user") != -1)
+ sin >> config.user;
+ else if (line.find("pass") != -1)
+ sin >> config.pass;
+ else if (line.find("host") != -1)
+ sin >> config.host;
+ else if (line.find("protocol") != -1)
+ sin >> config.protocol;
+ else if (line.find("port") != -1)
+ sin >> config.port;
+ else if (line.find("ml-config") != -1)
+ sin >> config.mlconfig;
+ else if (line.find("ml-log") != -1)
+ sin >> config.mllog;
+ else if (line.find("path") != -1)
+ sin >> config.path;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/history.cpp b/src/history.cpp
index 14433f3..e0b9a13 100755
--- a/src/history.cpp
+++ b/src/history.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#include
#include
#include
@@ -13,79 +29,99 @@
using namespace std;
-History::History() {
- //std::cout << "history constructor called\n";
-};
+namespace mlutil {
+
+ /* History::History
+ *
+ */
+ History::History() {
+ //std::cout << "history constructor called\n";
+ };
-History::~History() {
- //std::cout << "history destructor called\n";
-};
+ /* History::~History
+ *
+ */
+ History::~History() {
+ //std::cout << "history destructor called\n";
+ };
-CommandLineArgs History::options(int n_opts, char *opts[]) {
- CommandLineArgs args;
+ /*! History::options
+ *
+ * @param n_opts
+ * @param opts
+ * @return
+ */
+ CommandLineArgs History::options(int n_opts, char *opts[]) {
+ CommandLineArgs args;
- args.period = "hour";
- args.start = "";
- args.end = "";
+ args.period = "hour";
+ args.start = "";
+ args.end = "";
- for (int i = 1; i < n_opts; ++i) {
- if (opts[i][1] == 'f') {
- ++i;
- args.format = opts[i];
- } else if (opts[i][1] == 'p') {
- ++i;
- args.period = opts[i];
- } else if (opts[i][1] == 's') {
- ++i;
- args.start = opts[i];
- } else if (opts[i][1] == 'e') {
- ++i;
- args.end = opts[i];
- } else if (opts[i][1] == 'm') {
- ++i;
- args.metric = opts[i];
- } else if (opts[i][1] == 'r') {
- ++i;
- args.resource = opts[i];
- } else if (opts[i][1] == 'o') {
- ++i;
- args.output = opts[i];
- } else if (opts[i][1] == 'g') {
- ++i;
- args.gnuplot = opts[i];
- } else if (opts[i][1] == 'q') {
- args.quiet = true;
- } else if (opts[i][1] == 'v') {
- args.verbose = true;
- } else if (opts[i][1] == 'h') {
- usage(opts[0]);
- exit(1);
- } else if (opts[i][1] == 'c') {
- ++i;
- args.config = opts[i];
- } else {
- //usage(opts[0]);
+ for (int i = 1; i < n_opts; ++i) {
+ if (opts[i][1] == 'f') {
+ ++i;
+ args.format = opts[i];
+ } else if (opts[i][1] == 'p') {
+ ++i;
+ args.period = opts[i];
+ } else if (opts[i][1] == 's') {
+ ++i;
+ args.start = opts[i];
+ } else if (opts[i][1] == 'e') {
+ ++i;
+ args.end = opts[i];
+ } else if (opts[i][1] == 'm') {
+ ++i;
+ args.metric = opts[i];
+ } else if (opts[i][1] == 'r') {
+ ++i;
+ args.resource = opts[i];
+ } else if (opts[i][1] == 'o') {
+ ++i;
+ args.output = opts[i];
+ } else if (opts[i][1] == 'g') {
+ ++i;
+ args.gnuplot = opts[i];
+ } else if (opts[i][1] == 'q') {
+ args.quiet = true;
+ } else if (opts[i][1] == 'v') {
+ args.verbose = true;
+ } else if (opts[i][1] == 'h') {
+ usage(opts[0]);
+ exit(1);
+ } else if (opts[i][1] == 'c') {
+ ++i;
+ args.config = opts[i];
+ } else {
+ //usage(opts[0]);
+ }
}
+ args.check(opts[0]);
+ return args;
}
- args.check(opts[0]);
- return args;
-}
-int History::usage(const char *progname) {
- const char *name = getprogname(progname);
- cerr << "ml-utils: ml-hist 1.0 | copyright (c)2015 Jim Fuller | see https://github.com/xquery/ml-utils\n"
- << "retrieve MarkLogic history metrics\n"
- << ">" << name << " resources/{resource-name} [options]\n"
- << " -c : config file (ex. /home/jfuller/.ml-utils)\n"
- << " -f : format (xml|json)\n"
- << " -p : period (raw|hour|day)\n"
- << " -s : start date (ex. 2015-03-21T17:38:00)\n"
- << " -e : end date (ex. 2015-03-22T17:58:00)\n"
- << " -m : meter (resource specific)\n"
- << " -r : resource (databases|forests|servers|hosts) / resource-name\n"
- << " -o : graph output\n"
- << " -g : custom gnuplot script\n"
- << " -v : verbose (show http call)\n"
- << " -q : quiet (suppress banner)" << endl;
- return EXIT_SUCCESS;
+ /*! History::usage
+ *
+ * @param progname
+ * @return
+ */
+ int History::usage(const char *progname) {
+ const char *name = getprogname(progname);
+ cerr << "ml-utils: ml-hist 1.0 | copyright (c)2015 Jim Fuller | see https://github.com/xquery/ml-utils\n"
+ << "retrieve MarkLogic history metrics\n"
+ << ">" << name << " resources/{resource-name} [options]\n"
+ << " -c : config file (ex. /home/jfuller/.ml-utils)\n"
+ << " -f : format (xml|json)\n"
+ << " -p : period (raw|hour|day)\n"
+ << " -s : start date (ex. 2015-03-21T17:38:00)\n"
+ << " -e : end date (ex. 2015-03-22T17:58:00)\n"
+ << " -m : meter (resource specific)\n"
+ << " -r : resource (databases|forests|servers|hosts) / resource-name\n"
+ << " -o : graph output\n"
+ << " -g : custom gnuplot script\n"
+ << " -v : verbose (show http call)\n"
+ << " -q : quiet (suppress banner)" << endl;
+ return EXIT_SUCCESS;
+ }
}
\ No newline at end of file
diff --git a/src/history.hpp b/src/history.hpp
index b83595f..4baf810 100755
--- a/src/history.hpp
+++ b/src/history.hpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#pragma once
#include
@@ -19,10 +35,16 @@
#include "command.hpp"
-class History : public Command {
-public:
- History();
- virtual ~History();
- virtual int usage(const char *progname);
- virtual CommandLineArgs options(int n_opts, char *opts[]);
-};
+namespace mlutil {
+
+ class History : public Command {
+ public:
+ History();
+
+ virtual ~History();
+
+ virtual int usage(const char *progname);
+
+ virtual CommandLineArgs options(int n_opts, char *opts[]);
+ };
+}
\ No newline at end of file
diff --git a/src/load.cpp b/src/load.cpp
index 84d678c..efea4a9 100755
--- a/src/load.cpp
+++ b/src/load.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017 James Fuller
+ *
+ * Licensed 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.
+ */
+
#include
#include
#include
@@ -7,56 +23,236 @@
#include
#include
#include