esdlcmd_common.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2013 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef ESDLCMD_COMMON_HPP
  14. #define ESDLCMD_COMMON_HPP
  15. #include "jprop.hpp"
  16. #include "jargv.hpp"
  17. #include "common.hpp"
  18. #include "esdl_def.hpp"
  19. #include "esdl_def_helper.hpp"
  20. #include "ws_esdlconfig_esp.ipp"
  21. #include "esdl2xml.hpp"
  22. #include <algorithm>
  23. #include <list>
  24. #define COMPONENTS_DIR_NAME "componentfiles"
  25. #define HIGHER_DIR_RELATIVE ".."
  26. //=========================================================================================
  27. interface IEsdlCommand : extends IInterface
  28. {
  29. virtual bool parseCommandLineOptions(ArgvIterator &iter)=0;
  30. virtual bool finalizeOptions(IProperties *globals)=0;
  31. virtual int processCMD()=0;
  32. virtual void usage()=0;
  33. };
  34. typedef IEsdlCommand *(*EsdlCommandFactory)(const char *cmdname);
  35. #define ESDLOPT_HELP "--help"
  36. #define ESDLOPT_HELP_s "--?"
  37. #define ESDLARG_HELP "help"
  38. #define ESDL_OPTION_VERBOSE "--verbose"
  39. #define ESDL_OPT_VERBOSE "-v"
  40. #define ESDL_OPTION_TRACE_CATEGORY "--trace-category"
  41. #define ESDL_OPT_TRACE_CATEGORY "-tcat"
  42. #define ESDL_TRACE_CATEGORY_IERROR "ie"
  43. #define ESDL_TRACE_CATEGORY_OERROR "oe"
  44. #define ESDL_TRACE_CATEGORY_UERROR "ue"
  45. #define ESDL_TRACE_CATEGORY_IWARNING "iw"
  46. #define ESDL_TRACE_CATEGORY_OWARNING "ow"
  47. #define ESDL_TRACE_CATEGORY_UWARNING "uw"
  48. #define ESDL_TRACE_CATEGORY_DPROGRESS "dp"
  49. #define ESDL_TRACE_CATEGORY_OPROGRESS "op"
  50. #define ESDL_TRACE_CATEGORY_UPROGRESS "up"
  51. #define ESDL_TRACE_CATEGORY_DINFO "di"
  52. #define ESDL_TRACE_CATEGORY_OINFO "oi"
  53. #define ESDL_TRACE_CATEGORY_UINFO "ui"
  54. #define ESDL_TRACE_CATEGORY_DEVELOPER "dev"
  55. #define ESDL_TRACE_CATEGORY_OPERATOR "admin"
  56. #define ESDL_TRACE_CATEGORY_USER "user"
  57. #define ESDL_TRACE_CATEGORY_ERROR "err"
  58. #define ESDL_TRACE_CATEGORY_WARNING "warn"
  59. #define ESDL_TRACE_CATEGORY_PROGRESS "prog"
  60. #define ESDL_TRACE_CATEGORY_INFO "info"
  61. #define ESDL_CONVERT_SOURCE "--source"
  62. #define ESDL_CONVERT_OUTDIR "--outdir"
  63. #define ESDL_PROCESS_INCLUDES "--includes"
  64. #define ESDL_CONVERT_ALL "--all"
  65. #define ESDL_CONVERT_EXPANDEDXML "--expandedxml"
  66. #define ESDL_CONVERT_EXPANDEDXML_x "-x"
  67. #define HPCC_COMPONENT_FILES_DIR_CDE "-cde"
  68. #define ESDLOPT_XSLT_PATH "--xslt"
  69. #define ESDLOPT_VERSION "--version"
  70. #define ESDLOPT_INTERFACE_VERSION "--interface-version"
  71. #define ESDLOPT_INTERFACE_VERSION_S "-iv"
  72. #define ESDLOPT_SERVICE "--service"
  73. #define ESDLOPT_METHOD "--method"
  74. #define ESDLOPT_PREPROCESS_OUT "--preprocess-output"
  75. #define ESDLOPT_ANNOTATE "--annotate"
  76. #define ESDLOPT_NO_OPTIONAL_ATTRIBUTES "--noopt"
  77. #define ESDLOPT_OPT_PARAM_VAL "-opt"
  78. #define ESDLOPT_OPTIONAL_PARAM_VAL "--optional"
  79. #define ESDLOPT_TARGET_NS "-tns"
  80. #define ESDLOPT_TARGET_NAMESPACE "--target-namespace"
  81. #define ESDLOPT_NUMBER "-n"
  82. #define ESDLOPT_NO_COLLAPSE "--show-inheritance"
  83. #define ESDLOPT_NO_ARRAYOF "--no-arrayof"
  84. #define ESDLOPT_OUTPUT_CATEGORIES "--output-categories"
  85. #define ESDLOPT_USE_UTF8_STRINGS "--utf8"
  86. #define ESDLOPT_NO_EXPORT "--no-export"
  87. #define ESDLOPT_HIDE_GETDATAFROM "--hide-get-data-from"
  88. #define ESDLOPT_WSDL_ADDRESS "--wsdl-address"
  89. #define ESDLOPT_UNVERSIONED_NAMESPACE "--unversioned-ns"
  90. #define ESDLOPT_UNVERSIONED_NAMESPACE_S "-uvns"
  91. #define ESDLOPT_NO_EXCEPT_INLINE "--no-exceptions-inline"
  92. #define DEFAULT_NAMESPACE_BASE "urn:hpccsystems:ws"
  93. #define ESDLOPTLIST_DELIMITER ";"
  94. #define ESDL_OPT_SERVICE_SERVER "-s"
  95. #define ESDL_OPTION_SERVICE_SERVER "--server"
  96. #define ESDL_OPTION_SERVICE_PORT "--port"
  97. #define ESDL_OPT_SERVICE_USER "-u"
  98. #define ESDL_OPTION_SERVICE_USER "--username"
  99. #define ESDL_OPTION_SERVICE_PORT "--port"
  100. #define ESDL_OPT_SERVICE_PORT "-p"
  101. #define ESDL_OPT_SERVICE_PASS "-pw"
  102. #define ESDL_OPTION_SERVICE_PASS "--password"
  103. #define ESDL_OPTION_ESP_PROC_NAME "--esp-proc-name"
  104. #define ESDL_OPT_ESP_PROC_NAME "-epn"
  105. #define ESDL_OPTION_TARGET_ESP_ADDRESS "--esp-ip"
  106. #define ESDL_OPTION_TARGET_ESP_PORT "--esp-port"
  107. #define ESDL_OPTION_CONFIG "--config"
  108. #define ESDL_OPTION_OVERWRITE "--overwrite"
  109. #define ESDL_OPTION_ROLLUP "--rollup"
  110. #define ESDL_OPTION_ECL_INCLUDE_LIST "--ecl-imports"
  111. #define ESDL_OPTION_ECL_HEADER_BLOCK "--ecl-header"
  112. #define ESDL_OPTION_ENCODED "--encoded"
  113. #define ESDL_OPTION_USE_CASSANDRA "--use-cassandra"
  114. #define ESDL_OPTION_CASSANDRA_CONSISTENCY "--cassandra-consistency"
  115. #define ESDLOPT_INCLUDE_PATH "--include-path"
  116. #define ESDLOPT_INCLUDE_PATH_S "-I"
  117. #define ESDLOPT_INCLUDE_PATH_ENV "ESDL_INCLUDE_PATH"
  118. #define ESDLOPT_INCLUDE_PATH_INI "esdlIncludePath"
  119. #define ESDLOPT_INCLUDE_PATH_USAGE " -I, --include-path <include path> Locations to look for included esdl files\n"
  120. bool matchVariableOption(ArgvIterator &iter, const char prefix, IArrayOf<IEspNamedValue> &values);
  121. enum esdlCmdOptionMatchIndicator
  122. {
  123. EsdlCmdOptionNoMatch=0,
  124. EsdlCmdOptionMatch=1,
  125. EsdlCmdOptionCompletion=2
  126. };
  127. class EsdlCmdReporter : public EsdlDefReporter
  128. {
  129. protected:
  130. void reportSelf(Flags flag, const char* component, const char* level, const char* msg) const override
  131. {
  132. fprintf(stdout, "%s [%s]: %s\n", level, component, msg);
  133. }
  134. };
  135. class EsdlCmdCommon : public CInterface, implements IEsdlCommand
  136. {
  137. public:
  138. using TraceFlags = IEsdlDefReporter::Flags;
  139. enum : TraceFlags
  140. {
  141. defaultSuccinctTraceFlags = IEsdlDefReporter::ReportErrorClass | IEsdlDefReporter::ReportWarningClass,
  142. defaultVerboseTraceFlags = defaultSuccinctTraceFlags | IEsdlDefReporter::ReportProgressClass | IEsdlDefReporter::ReportInfoClass,
  143. };
  144. IMPLEMENT_IINTERFACE;
  145. EsdlCmdCommon() : optVerbose(false)
  146. {}
  147. virtual esdlCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt=false);
  148. virtual bool finalizeOptions(IProperties *globals);
  149. virtual void usage()
  150. {
  151. fprintf(stdout,
  152. " --help Display usage information for the given command\n"
  153. " -v,--verbose Output additional tracing information\n"
  154. " -tcat,--trace-category <flags> Control which debug messages are output; a case-insensitive comma-delimited combination of:\n"
  155. " " ESDL_TRACE_CATEGORY_DEVELOPER ": all output for the developer audience\n"
  156. " " ESDL_TRACE_CATEGORY_OPERATOR ": all output for the operator audience\n"
  157. " " ESDL_TRACE_CATEGORY_USER ": all output for the user audience\n"
  158. " " ESDL_TRACE_CATEGORY_ERROR ": all error output\n"
  159. " " ESDL_TRACE_CATEGORY_WARNING ": all warning output\n"
  160. " " ESDL_TRACE_CATEGORY_PROGRESS ": all progress output\n"
  161. " " ESDL_TRACE_CATEGORY_INFO ": all info output\n"
  162. " Errors and warnings are enabled by default if not verbose, and all are enabled when verbose."
  163. " Use an empty <flags> value to disable all."
  164. );
  165. }
  166. virtual void outputWsStatus(int code, const char * message)
  167. {
  168. fprintf(code == 0 ? stdout : stderr, "\n %s.\n", message);
  169. }
  170. public:
  171. inline TraceFlags optTraceFlags() { return (m_optTraceFlagsGiven ? m_actualTraceFlags : (optVerbose ? m_verboseTraceFlags : m_succinctTraceFlags)) | IEsdlDefReporter::ReportMethod; }
  172. bool optVerbose;
  173. protected:
  174. void parseTraceFlags(const char* traceCategories);
  175. TraceFlags m_succinctTraceFlags = defaultSuccinctTraceFlags;
  176. TraceFlags m_verboseTraceFlags = defaultVerboseTraceFlags;
  177. private:
  178. TraceFlags m_actualTraceFlags = 0;
  179. bool m_optTraceFlagsGiven = false;
  180. };
  181. class EsdlCmdHelper : public CInterface
  182. {
  183. static IEsdlDefReporter* makeCmdReporter() { return new EsdlCmdReporter(); }
  184. public:
  185. Owned<IEsdlDefinition> esdlDef;
  186. Owned<IEsdlDefinitionHelper> defHelper;
  187. Owned<IFile> serviceDefFile;
  188. bool verbose = false;
  189. public:
  190. EsdlCmdHelper()
  191. {
  192. esdlDef.set(createEsdlDefinition(nullptr, makeCmdReporter));
  193. defHelper.set(createEsdlDefinitionHelper());
  194. }
  195. IMPLEMENT_IINTERFACE;
  196. static EsdlCmdHelper * createEsdlHelper()
  197. {
  198. return new EsdlCmdHelper();
  199. }
  200. void loadDefinition(const char * sourceFileName, const char * serviceName, double version, const char* includePath, IEsdlDefReporter::Flags traceFlags)
  201. {
  202. if (!esdlDef.get())
  203. esdlDef.set(createEsdlDefinition(nullptr, makeCmdReporter));
  204. IEsdlDefReporter* reporter = esdlDef->queryReporter();
  205. reporter->setFlags(traceFlags, true);
  206. if(!esdlDef->hasFileLoaded(sourceFileName))
  207. {
  208. StringBuffer extension;
  209. StringBuffer filename;
  210. splitFilename(sourceFileName, NULL, NULL, &filename, &extension);
  211. if (stricmp(extension.str(),LEGACY_FILE_EXTENSION)==0 || stricmp(extension.str(),ESDL_FILE_EXTENSION)==0)
  212. {
  213. StringBuffer esxml;
  214. EsdlCmdHelper::convertECMtoESXDL(sourceFileName, filename.str(), esxml, true, verbose, false, true, includePath);
  215. esdlDef->addDefinitionFromXML(esxml, sourceFileName);
  216. }
  217. else
  218. {
  219. loadEXSDLFromFile(sourceFileName);
  220. }
  221. }
  222. }
  223. void getServiceESXDL(const char * sourceFileName, const char * serviceName, StringBuffer & xmlOut, double version, IProperties *opts=nullptr, unsigned flags=0, const char* includePath=nullptr, IEsdlDefReporter::Flags traceFlags = EsdlCmdCommon::defaultSuccinctTraceFlags)
  224. {
  225. loadDefinition(sourceFileName, serviceName, version, includePath, traceFlags);
  226. if (esdlDef)
  227. {
  228. IEsdlDefObjectIterator *deps = esdlDef->getDependencies(serviceName, "", version, opts, flags);
  229. if( deps )
  230. {
  231. if (serviceName)
  232. xmlOut.appendf("<esxdl name=\"%s\">", serviceName);
  233. else
  234. xmlOut.appendf("<esxdl>");
  235. defHelper->toXML( *deps, xmlOut, version, opts, flags );
  236. xmlOut.append("</esxdl>");
  237. }
  238. else
  239. throw( MakeStringException(0, "Could not get ESDL structure") );
  240. }
  241. }
  242. static void convertECMtoESXDL(const char * filepath, const char * esxdlname, StringBuffer & esxml, bool recursive, bool verbose, bool outputincludes, bool isIncludedESDL, const char* includePath)
  243. {
  244. if (verbose)
  245. fprintf(stdout,"Converting ESDL file %s to XML\n", filepath);
  246. Owned<Esdl2Esxdl> cmd = new Esdl2Esxdl(recursive, verbose);
  247. cmd->setIncluePath(includePath);
  248. esxml.setf( "<esxdl name=\"%s\">", esxdlname);
  249. cmd->transform(filepath, "", &esxml, outputincludes, isIncludedESDL); //output to buffer
  250. esxml.append("</esxdl>");
  251. }
  252. static void outputMultiExceptions(const IMultiException &me)
  253. {
  254. fprintf(stderr, "\nException(s):\n");
  255. aindex_t count = me.ordinality();
  256. for (aindex_t i=0; i<count; i++)
  257. {
  258. IException& e = me.item(i);
  259. StringBuffer msg;
  260. fprintf(stderr, "%d: %s\n", e.errorCode(), e.errorMessage(msg).str());
  261. }
  262. fprintf(stderr, "\n");
  263. }
  264. static IClientWsESDLConfig * getWsESDLConfigSoapService(const char *server, const char *port, const char *username, const char *password)
  265. {
  266. if(server == NULL)
  267. throw MakeStringException(-1, "Server url not specified");
  268. VStringBuffer url("http://%s:%s/WsESDLConfig/?ver_=%s", server, port, VERSION_FOR_ESDLCMD);
  269. IClientWsESDLConfig * esdlConfigClient = createWsESDLConfigClient();
  270. esdlConfigClient->addServiceUrl(url.str());
  271. esdlConfigClient->setUsernameToken(username, password, NULL);
  272. return esdlConfigClient;
  273. }
  274. protected:
  275. void loadEXSDLFromFile(const char * sourceFileName)
  276. {
  277. serviceDefFile.setown( createIFile(sourceFileName) );
  278. if( serviceDefFile->exists() )
  279. {
  280. if( serviceDefFile->isFile()==fileBool::foundYes )
  281. {
  282. if( serviceDefFile->size() > 0 )
  283. {
  284. // Realized a subtle source of potential problems. Because there
  285. // can be multiple EsdlStruct definitions with the same name
  286. // in multiple files, you need to be careful that only those files
  287. // explicitly included by your service are loaded to the
  288. // EsdlDefinition object that you'll getDependencies() on. If not,
  289. // you could inadvertently getDependencies() from a different structure
  290. // with the same name. This means we can only reliably process one
  291. // Web Service at a time, and must load files by explicitly loading
  292. // only the top-level ws_<service> definition file, and allowing the
  293. // load code to handle loading only the minimal set of required includes
  294. esdlDef->addDefinitionsFromFile( serviceDefFile->queryFilename() );
  295. }
  296. else
  297. {
  298. throw( MakeStringException(0, "ESDL definition file source %s is empty", sourceFileName) );
  299. }
  300. }
  301. else
  302. {
  303. throw( MakeStringException(0, "ESDL definition file source %s is not a file", sourceFileName) );
  304. }
  305. }
  306. else
  307. {
  308. throw( MakeStringException(0, "ESDL definition file source %s does not exist", sourceFileName) );
  309. }
  310. }
  311. };
  312. class EsdlConvertCmd : public EsdlCmdCommon
  313. {
  314. public:
  315. EsdlConvertCmd() {}
  316. virtual esdlCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt=false);
  317. virtual bool finalizeOptions(IProperties *globals);
  318. virtual bool parseCommandLineOptions(ArgvIterator&);
  319. virtual bool parseCommandLineOption(ArgvIterator&);
  320. virtual void usage()
  321. {
  322. EsdlCmdCommon::usage();
  323. puts(" --outdir=<out dir path> Location to generate output\n");
  324. }
  325. public:
  326. StringAttr optSource;
  327. StringAttr optOutDirPath;
  328. StringBuffer optIncludePath;
  329. };
  330. class EsdlHelperConvertCmd : public EsdlConvertCmd
  331. {
  332. protected:
  333. EsdlCmdHelper cmdHelper;
  334. public:
  335. EsdlHelperConvertCmd()
  336. {
  337. }
  338. virtual void usage()
  339. {
  340. EsdlConvertCmd::usage();
  341. }
  342. virtual void doTransform(IEsdlDefObjectIterator& objs, StringBuffer &target, double version=0, IProperties *opts=NULL, const char *ns=NULL, unsigned flags=0 )=0;
  343. virtual void loadTransform( StringBuffer &xsltpath, IProperties *params )=0;
  344. virtual void setTransformParams(IProperties *params )=0;
  345. };
  346. static bool getCurrentFolder(StringBuffer & path)
  347. {
  348. StringBuffer folder;
  349. splitDirTail(queryCurrentProcessPath(), folder);
  350. removeTrailingPathSepChar(folder);
  351. if (folder.length())
  352. {
  353. path = folder;
  354. return true;
  355. }
  356. return false;
  357. }
  358. static bool getComponentFilesRelPathFromBin(StringBuffer & path)
  359. {
  360. if (getCurrentFolder(path))
  361. return checkDirExists(path.appendf("%c%s%c%s", PATHSEPCHAR, HIGHER_DIR_RELATIVE,PATHSEPCHAR,COMPONENTS_DIR_NAME));
  362. return false;
  363. }
  364. void saveAsFile(const char * path, const char *filename, const char *text, const char *ext="");
  365. #endif