Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HPCC-24058 Add manifest command to esdl tool #16120

Merged

Conversation

asselitx
Copy link
Contributor

@asselitx asselitx commented May 23, 2022

The manifest command builds an ESDL service binding or bundle from an input
manifest file. The manifest contains the outline of the binding and can use
Include statements to load external files to include in the output. Supported
Include files are ESDL scripts, XSL transforms for logging and ESDL
definitions.

  • Add tests to to exercise the esdl manifest command.
  • Refactor the EsdlExample into separate independent examples, including one
    showing the use of the manifest tool.
  • Add a README explaining the use of the new command.

The bulk of the changes in this PR are related to updates to the EsdlExample.
So although there are many changed/deleted/moved files, the code changes
for implementing the new command are within the esdl tool project folder.

Signed-off-by: Terrence Asselin terrence.asselin@lexisnexisrisk.com

Type of change:

  • This change is a bug fix (non-breaking change which fixes an issue).
  • This change is a new feature (non-breaking change which adds functionality).
  • This change improves the code (refactor or other change that does not change the functionality)
  • This change fixes warnings (the fix does not alter the functionality or the generated code)
  • This change is a breaking change (fix or feature that will cause existing behavior to change).
  • This change alters the query API (existing queries will have to be recompiled)

Checklist:

  • My code follows the code style of this project.
    • My code does not create any new warnings from compiler, build system, or lint.
  • The commit message is properly formatted and free of typos.
    • The commit message title makes sense in a changelog, by itself.
    • The commit is signed.
  • My change requires a change to the documentation.
    • I have updated the documentation accordingly, or...
    • I have created a JIRA ticket to update the documentation.
    • Any new interfaces or exported functions are appropriately commented.
  • I have read the CONTRIBUTORS document.
  • The change has been fully tested:
    • I have added tests to cover my changes.
    • All new and existing tests passed.
    • I have checked that this change does not introduce memory leaks.
    • I have used Valgrind or similar tools to check for potential issues.
  • I have given due consideration to all of the following potential concerns:
    • Scalability
    • Performance
    • Security
    • Thread-safety
    • Cloud-compatibility
    • Premature optimization
    • Existing deployed queries will not be broken
    • This change fixes the problem, not just the symptom
    • The target branch of this pull request is appropriate for such a change.
  • There are no similar instances of the same problem that should be addressed
    • I have addressed them here
    • I have raised JIRA issues to address them separately
  • This is a user interface / front-end modification
    • I have tested my changes in multiple modern browsers
    • The component(s) render as expected

Smoketest:

  • Send notifications about my Pull Request position in Smoketest queue.
  • Test my draft Pull Request.

Testing:

Added new regression cases in the testing/esp/esdlcmd project.

@github-actions
Copy link

@afishbeck
Copy link
Member

I think initfiles/examples/EsdlExample/Manifest needs a copy of RoxieEchoPersonInfo.ecl for the walkthrough to work.


9. Test calling the roxie service
```
soapplus -url http://.:8088/EsdlExample -i cpprequest.xml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like above, should be: "../../cpprequest.xml"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok fixed

@@ -142,6 +142,13 @@ typedef IEsdlCommand *(*EsdlCommandFactory)(const char *cmdname);
#define ESDLOPT_INCLUDE_PATH_ENV "ESDL_INCLUDE_PATH"
#define ESDLOPT_INCLUDE_PATH_INI "esdlIncludePath"
#define ESDLOPT_INCLUDE_PATH_USAGE " -I, --include-path <include path> Locations to look for included esdl files\n"
#define ESDLOPT_RECURSIVE "--recursive"
#define ESDLOPT_RECURSIVE_S "--r"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short names have one dash, long names have two. So this should be simply "-r".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will fix

puts("Options:");
puts(" --rollup Output a single XML file containing all definitions used by");
puts(" <serviceName>");
puts(" -r, --recursive Process all includes. Implied when generating monolithic");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the help is correct for the short version with a single dash. The define must have been a typo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think so.

@@ -0,0 +1,884 @@
/*##############################################################################

HPCC SYSTEMS software Copyright (C) 2020 HPCC Systems®.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2022

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -0,0 +1,66 @@
```
HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New files need more recent copyright notices.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


## DynamicESDL

You must have configured at least one DynamicESDL ESP Service in this environment. Either through configmgr or by editing environment.xml. The instance can be bound on port 0, or on the same port as where you're planning to run your service, or both. The purpose of the instance is to provide the configuration needed for your service. If there's an instance configured on the same port, that instance's configuration will be used, otherwise the configuration of the instance on port 0 will be used. This document assumes you're planning to bind your service to esp process "myesp" and port 8088.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably too much emphasis on the old way of setting things up, and no mention of working with containers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that some newer examples including containers will be good, but I'd prefer not to include that in the scope of this ticket. When adding my manifest example to the directory it was difficult to understand how the examples worked, they were intermingled and they didn't have a consistent structure. I worried that just putting a new example in the mix would be unhelpful.

So I wanted to make them easier to run and understand without changing their basic nature. I will be explicit in the README that these are examples of bare-metal deployments, which I think is useful to have documented. If you'd like I'll also open a ticket to add container and/or esp app-based instructions as either separate examples or updates to these.


## EclWatch

An instance of EclWatch must be running, and you must have shell access to that node.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? Needing a running instance is understandable. Knowing that some commands accept options to redirect to remote instances, is the requirement to be local because a specific command does not support this or is it convenience?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point- trying to be too general is maybe just confusing here. I'll update the readmes to all use the assumption that you are running the stock-installed environment.xml on a single machine that you can access.


4. Create the binding from a manifest file
```
esdl manifest manifest_roxie.xml -I EsdlScripts --outfile manifest_example_binding.xml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

manifest_roxie.xml seems like an odd choice of name for a file used to define an ESP binding.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the examples are named in terms of how the 'backend' is implemented- I guess I was just running on that track. I'll rename it not referencing roxie.

esdl bind-service myesp 8088 esdlexample.1 EsdlExample --config manifest_example_binding.xml --overwrite
```

1. Test calling the roxie service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Number is wrong. Markdown viewers might fix, but it's out of place when all of the other numbers are sequential.

Is this testing the roxie or the ESP? If the ESP is on 8088, it seems like it's an ESP test. The roxie might be tested indirectly, but that's a function of the ESP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed numbering and adjusted wording, though in keeping with the idea that these examples largely differ by what the backend or implementation is for each.

if (!content.length())
throw makeStringExceptionV(ESDL_MANIFEST_ERR, "Unable to load <Include>, file='%s' on line #%d column #%d", filename, xpp->getLineNumber(), xpp->getColumnNumber());
}
else if (INCLUDE_LOG_TRANSFORM == includeType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of the named symbol. Perhaps INCLUDE_XSLT would be better, since we may end up supporting XSLTs that are not specific to logging.

A name for this case is required as long as arbitrary includes are not supported. If arbitrary includes are supported, a name for this case is not required unless it is used to control handling of the file content (e.g., whitespace preservation instead of pretty-printing).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the symbol name as suggested. Future update for arbitrary includes may include a refactoring of this method, so I'll address possible removal of the symbol all together at that time.


void appendStartTag(IXmlPullParser* xpp, StartTag& stag, bool writeNsAttr = false)
{
// Attributes don't have their ns prefixes copied
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't read this comment as I think it is intended. Based on the code, I think you're saying that namespace declarations are not included in stag, so you are manually adding them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

while (it != xpp->getNsEnd())
{
if (it->first.compare("xml")!=0)
binding.appendf(" xmlns:%s=\"%s\"", it->first.c_str(), it->second);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this handle the default namespace, which should be xmlns=... instead of xmlns:=...?

Copy link
Contributor Author

@asselitx asselitx Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that the xpp namespace iterator does not include the default namespace. That can only be inferred by interrogating the uri of a start tag. To see if the default namespace was defined, you must compare a start tag's uri to a list of already seen uris. If it is new then this node is the first to use the default, though it may have been defined in a parent. There is no way to determine which node defined the default. Updated to handle default namespaces given these constraints.

return false;
}

void appendStartTag(IXmlPullParser* xpp, StartTag& stag, bool writeNsAttr = false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Default parameters are frowned upon.
  2. Are we artificially limiting users by conditionally handling namespace declarations? I would not want to see every start tag redeclare every namespace, but it shouldn't be too difficult to identify when a start tag has declared a new namespace by maintaining some state locally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed default parameter and generalized handling of namespaces.

Comment on lines 490 to 843
case XmlPullParser::END_DOCUMENT:
level = 0;
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems logically incorrect. If this case can be reached, the XML is invalid and we should object. If the case cannot be reached, because the parser throws an exception, it is extraneous and misleading.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed all occurrences except at the root level to throw an exception.

@ghalliday
Copy link
Member

@asselitx this looks like it has stalled. Please can you either close, or respond to the comments.

@asselitx
Copy link
Contributor Author

@ghalliday I will resume work on this PR later this week.

@HPCCSmoketest
Copy link
Contributor

This PR (16120) is in the 11/56 position of the queue. Estimated start time is after ~5.10 hour(s)

@ghalliday
Copy link
Member

@asselitx still stalled...

@asselitx asselitx marked this pull request as draft November 14, 2022 23:52
@asselitx asselitx force-pushed the manifest-hpcc-24058 branch from a43f6a7 to 0c9afa5 Compare December 30, 2022 21:09
@asselitx
Copy link
Contributor Author

@afishbeck and @timothyklemm could you please review the updates? I didn't rebase to latest or squash yet to help keep the diffs clean. The follow-up ticket for requested changed not addressed now is HPCC-28740.

Copy link
Contributor

@timothyklemm timothyklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review only covers esdlcmd_manifest.cpp.


EsdlManifestCmd() {}

int processCMD() override
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing virtual keyword

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this style? I thought an override of a virtual method was implicitly virtual in all derived classes where its overridden. Core cpp guidelines suggest to use one or the other: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#c128-virtual-functions-should-specify-exactly-one-of-virtual-override-or-final

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed to conform to HPCC guidelines

EsdlManifestCmd() {}

int processCMD() override
{ bool result = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing newline?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

if (iter.done())
{
usage();
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inconsistent formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment on lines 203 to 207
puts(" --output-format <format>");
puts(" Specify the format of the output. Allowed values are");
puts(" 'binding' or 'bundle'. The default is 'bundle' which");
puts(" includes the ESDL Service Definition (if provided). This");
puts(" option overrides Manifest[@outputFormat] in the file.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I probably commented on this before, but this still bothers me. I read it as Manifest[@outputFormat] is always irrelevant. A default of bundle should only be applied if neither the manifest itself nor the command line specifies something different.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried to clear up the language.

* @param root reference to the 'ServiceDefinition' node read
* @return int type of the last node read
*/
int processServiceDefinition(IXmlPullParser* xpp, StartTag& root)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be renamed to something like processEsdlServiceDefinition?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure- or perhaps EsdlDefinition? Either way if I change it should I change the element name to match?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a bundle is viewed as a superset of a binding, maybe processBundleDefinitions versus processBindingDefinition. I wouldn't complain about consistency between the markup and function name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tony said he'd prefer EsdlDefinition, so I'll change that name for the function and for the manifest namespace element.

{
bindingFileIO->write(0, binding.length(), binding.str());
} else {
UERRLOG("Error writing to binding file (%s).", optOutputPath.str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignoring the potential of other artifact types, not all output files are binding files. Better to keep it generic and omit "binding".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}
return result;
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EOLN

@asselitx asselitx force-pushed the manifest-hpcc-24058 branch from 0c9afa5 to 0a572f9 Compare February 14, 2023 00:07
@asselitx asselitx changed the base branch from candidate-8.6.x to candidate-8.12.x February 14, 2023 15:15
Copy link
Contributor

@timothyklemm timothyklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments on tools/esdlcmd/README.md only.


### Manifest File

A manifest file is an XML-formatted template combining elements in and outside of the manifest's `urn:hpcc:esdl:manifest` namespace. Elements of this namespace control the tool while all other markup is copied to the output. The goal of using a manifest file with the tool is to make configuring and deploying services easier:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second sentence is misleading assuming a previously stated intention to pass unrecognized manifest namespace markup to the output. I read this sentence as "no manifest elements are copied to the output".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clarified

</em:EsdlDefinition>
</em:Manifest>
```
Because the tool is permissive and flexible, copying through all markup not in the manifest namespace, the manifest elements are only required in order to take advantage of the automated processing and simplified format of the manifest file. This example highlights the recommended usage of manifest elements to use the tool's capabilities. Although you could replace some of the elements below with verbatim `bundle` or `binding` output elements we won't cover that usage here.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sentence one again suggests no manifest namespace markup will be copied to the output.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clarified

```
Because the tool is permissive and flexible, copying through all markup not in the manifest namespace, the manifest elements are only required in order to take advantage of the automated processing and simplified format of the manifest file. This example highlights the recommended usage of manifest elements to use the tool's capabilities. Although you could replace some of the elements below with verbatim `bundle` or `binding` output elements we won't cover that usage here.

* `<em:Manifest>` Is the required root element. By default the tool outputs a `bundle`, though you may explicitly override that on the command line or by providing an `@outputType=binding` attribute.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should Is be capitalized? It doesn't match the rest of the list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lowercased

```
Because the tool is permissive and flexible, copying through all markup not in the manifest namespace, the manifest elements are only required in order to take advantage of the automated processing and simplified format of the manifest file. This example highlights the recommended usage of manifest elements to use the tool's capabilities. Although you could replace some of the elements below with verbatim `bundle` or `binding` output elements we won't cover that usage here.

* `<em:Manifest>` Is the required root element. By default the tool outputs a `bundle`, though you may explicitly override that on the command line or by providing an `@outputType=binding` attribute.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@outputType=binding is incorrect when presented as markup. binding should be quoted for the markup to be correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Because the tool is permissive and flexible, copying through all markup not in the manifest namespace, the manifest elements are only required in order to take advantage of the automated processing and simplified format of the manifest file. This example highlights the recommended usage of manifest elements to use the tool's capabilities. Although you could replace some of the elements below with verbatim `bundle` or `binding` output elements we won't cover that usage here.

* `<em:Manifest>` Is the required root element. By default the tool outputs a `bundle`, though you may explicitly override that on the command line or by providing an `@outputType=binding` attribute.
* `em:ServiceBinding>` is valid for both `bundle` and `binding` output. It is necessary to enable recognition of `<em:Scripts>`, and `<em:Transform>` elements.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing opening <.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


| Attribute | Required? | Value | Usage |
| - | :-: | - | - |
| `@auth_feature` | No | string | Used declare authorization settings if they aren't present in the ESDL Definition, or override them if they are. Additional documentation on this attribute is forthcoming. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Used to declare ..."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

The element is not required since it is possible to embed a complete `Definitions` element hierarchy in the manifest.

#### Include
Optional element that imports the contents of another file into the output, in place of the itself. The outcome of the import depends on the context in which this element is used. See [EsdlDefinition](#esdldefinition), [Scripts](@scripts), and [Transform](#transform) for more information.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"... in place of the itself." Remove "the"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

| - | :-: | - | - |
| `@file` | Yes | file path | Full or partial path to an external file to be imported. If a partial path is outside of the tool's working directory, the tool's command line must specify the appropriate root directory using either `-I` or `--include-path`. |

>Any XSLTs or ESDL Scripts written inline in a manifest file will have XML escaping applied where required to generate valid XML. If an XLST contains any text content or markup that needs to be preserved as-is (no XML escaping applied) then be sure to use an `<em:Include>` operation. Included files are inserted into the output as-is, with the exception of preventing nested CDATA. If the included file will be inside a CDATA section on output, then any CDATA end markup in the file will be encoded as `]]]]><![CDATA[>` to prevent nested CDATA sections or a prematurely ending a CDATA section.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XLST -> XSLT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Optional repeatable element appearing within an `<em:ServiceBinding>` element that processes child elements and creates output expected for an ESDL binding:

- The `<em:Scripts>` element is replaced on output with `<Scripts>`. Then all content is enclosed in a CDATA section after wrapping it with a new `Scripts` element. That new `<Scripts>` element contains namespaces declared by the input `<em:Scripts>` element. The input `<em:Scripts foo="..." xmlns:bar="..."><!-- content --></em:Scripts>` becomes `<Scripts><![CDATA[<Scripts xmlns:bar="..."><!-- content --></Scripts>]]></Scripts>`.
- The manifest `<em:Include>` element is recognized to import scripts from external files. The entire file, minus leading and trailing whitespace, is imported.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If sentence two is correct, perhaps a warning against including files that include XML declarations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Optional repeatable element appearing within an `<em:ServiceBinding>` element that processes child elements and creates output expected for an ESDL binding:

- All content is enclosed in a CDATA section. The input `<em:Transform> <!-- content --> </em:Transform>` becomes `<Transform><![CDATA[<!-- content -->]]></Transform>`.
- The manifest `<em:Include>` element is recognized to import transforms from external files. The entire file, minus leading and trailing whitespace, is imported.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Copy link
Contributor

@timothyklemm timothyklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just esdlcmd_manifest.cpp ...

if (isAbsolutePath(filePath))
return false;

for (std::string include : includes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use reference to avoid the copy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}
while(type != XmlPullParser::END_TAG && type != XmlPullParser::END_DOCUMENT);
EndTag etag;
xpp->readEndTag(etag);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we exited the loop with END_DOCUMENT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably some undefined behavior. Fixed.

case XmlPullParser::END_TAG:
xpp->readEndTag(etag);

if (isRootEndTagNamed(etag, "Scripts", level))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still see "Scripts".

@asselitx asselitx force-pushed the manifest-hpcc-24058 branch from 0a572f9 to 2098b0d Compare April 24, 2023 18:19
@asselitx asselitx changed the base branch from candidate-8.12.x to candidate-9.0.x April 24, 2023 18:37
@@ -0,0 +1,1310 @@
/*##############################################################################

HPCC SYSTEMS software Copyright (C) 2022 HPCC Systems®.
Copy link
Member

@afishbeck afishbeck May 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now 2023, I see a comment from a year ago, was this draft around that long?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in today's commit.

if (ManifestType::bundle == outputType)
appendEndTag(MANIFEST_TAG_BUNDLE);
if (ManifestType::bundle == outputType && !foundEsdlDefn)
UWARNLOG("Generating EsdlBundle output without ESDL Definition. This may cause runtime issues.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should be an error? I think all bundles should have interfaces defined? If in the future we wanted to make it a warning we could. Sometimes starting out strict is good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with that. I'll plan to throw an exception to prevent the creation of a bundle without the interface- unless you meant just to use UERRLOG?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throw an exception, we can always relax it later if it is really needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in today's commit.

@asselitx asselitx marked this pull request as ready for review July 13, 2023 19:50
@asselitx
Copy link
Contributor Author

@timothyklemm and @afishbeck I believe I've addressed all outstanding comments. Please check latest commit. I'll rebase and squash onto 9.2.x when you think it looks good.

@asselitx asselitx force-pushed the manifest-hpcc-24058 branch from da16522 to 0908aa0 Compare July 21, 2023 16:27
@asselitx asselitx changed the base branch from candidate-9.0.x to candidate-9.2.x July 21, 2023 16:27
@asselitx
Copy link
Contributor Author

@timothyklemm and @afishbeck I've rebased to candidate-9.2.x and fixed the README error in grammar I'd missed. I feel the changes are safe in 9.2 because they're limited to

  1. The initfiles/examples
  2. esdl command tests
  3. new manifest esdl command
  4. adding support for esdl xml to run directly from the esdl app instead of a separate executable


| Attribute | Required? | Value | Usage |
| - | :-: | - | - |
| `@auth_feature` | No | string | Used declare authorization settings if they aren't present in the ESDL Definition, or override them if they are. Additional documentation on this attribute is forthcoming. |
| `@returnSchemaLocationOnOK` | No | Boolean | When true, a successful SOAP response (non SOAP-Fault) will include the schema location property. False by default. |
| `@namespace` | No | string | String specifying the namespace for all methods in the binding. May contain variables that are replaced with their values: <br/>- `${service}` : lowercase service name <br/>- `${esdl-service}` : service name, possibly mixed case <br/>- `${method}` : lowercase method name <br/>- `${esdl-method}` : method name, possibly mixed case <br/>- `${optionals}` : comma-delimited list of all optional URL parameters included in the method request, enclosed in parenthesis <br/>- `${version}` : client version number |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should "parenthesis" be "parentheses" (plural instead of singular)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense, fixed

| - | :-: | - | - |
| `@auth_feature` | No | string | Used to declare authorization settings if they aren't present in the ESDL Definition, or override them if they are. Additional documentation on this attribute is forthcoming. |
| `@returnSchemaLocationOnOK` | No | Boolean | When true, a successful SOAP response (non SOAP-Fault) will include the schema location property. False by default. |
| `@namespace` | No | string | String specifying the namespace for all methods in the binding. May contain variables that are replaced with their values: <br/>- `${service}` : lowercase service name <br/>- `${esdl-service}` : service name, possibly mixed case <br/>- `${method}` : lowercase method name <br/>- `${esdl-method}` : method name, possibly mixed case <br/>- `${optionals}` : comma-delimited list of all optional URL parameters included in the method request, enclosed in parenthesis <br/>- `${version}` : client version number |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When does the variable replacement happen? I couldn't fault someone for expecting the manifest tool to replace the values. I also couldn't fault someone for thinking the variables are retained for the ESP to replace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarified the ESP replaces them during runtime.

| `@port` | No | string | Port on the ESP Process listening for connections to the binding. |
| `@publishedBy` | No | string | Userid of the person publishing the binding |

The `<em:ServiceBinding>` element is not required since it is possible to embed a complete `Binding` element hierarchy in the manifest.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving before line 122. It clarifies line 115's reference to "recommended", a meaning which might be lost this far away.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah seems like that got shuffled during edits. I've reworded slightly and moved up.

| - | :-: | - | - |
| `@file` | Yes | file path | Full or partial path to an external file to be imported. If a partial path is outside of the tool's working directory, the tool's command line must specify the appropriate root directory using either `-I` or `--include-path`. |

>Any XSLTs or ESDL Scripts written inline in a manifest file will have XML escaping applied where required to generate valid XML. If an XSLT contains any text content or markup that needs to be preserved as-is (no XML escaping applied) then be sure to use an `<em:Include>` operation. Included files are inserted into the output as-is, with the exception of preventing nested CDATA. If the included file will be inside a CDATA section on output, then any CDATA end markup in the file will be encoded as `]]]]><![CDATA[>` to prevent nested CDATA sections or a prematurely ending a CDATA section.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"preventing nested CDATA" seems wrong. The action taken properly encodes nested CDATA rather than preventing it.


#### Bundle

The bundle includes all the components of the service binding in addition to the ESDL definition.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider rephrasing. Between this and 426, seems somewhat circular.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed that wording and instead called back to the usage for binding/bundle around line 45.

@asselitx asselitx force-pushed the manifest-hpcc-24058 branch from 0908aa0 to 2f09b52 Compare August 30, 2023 15:13
@asselitx asselitx requested a review from timothyklemm August 30, 2023 15:13
@asselitx asselitx force-pushed the manifest-hpcc-24058 branch from 2f09b52 to c1c5231 Compare December 12, 2023 16:06
@asselitx asselitx changed the base branch from candidate-9.2.x to candidate-9.4.x December 12, 2023 16:07
@asselitx
Copy link
Contributor Author

@ghalliday approved for merge and squashed

@asselitx asselitx assigned ghalliday and unassigned afishbeck and timothyklemm Dec 12, 2023
The manifest command builds an ESDL service binding or bundle from an input
manifest file. The manifest contains the outline of the binding and can use
'Include' statements to load external files to include in the output. Supported
Include files are ESDL scripts, XSL transforms for logging and ESDL
definitions.

- Add tests to to exercise the esdl manifest command.
- Refactor the EsdlExample into separate independent examples, including one
  showing the use of the manifest tool.
- Add a README explaining the use of the new command.

Signed-off-by: Terrence Asselin <terrence.asselin@lexisnexisrisk.com>
@asselitx asselitx force-pushed the manifest-hpcc-24058 branch from c1c5231 to 6731d8c Compare January 4, 2024 22:07
@asselitx
Copy link
Contributor Author

asselitx commented Jan 4, 2024

Rebased to target branch again in an attempt to re-trigger the checks that had stalled out.

@asselitx asselitx requested a review from ghalliday January 17, 2024 17:22
@asselitx
Copy link
Contributor Author

@ghalliday this should be ready now for your final approval and merge. Let me know if I need to do anything else.

@ghalliday ghalliday merged commit 8e68842 into hpcc-systems:candidate-9.4.x Jan 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants