An open API service indexing awesome lists of open source software.

https://github.com/dinochiesa/apigee-java-edit-xml-node

a custom policy for Apigee, implemented in Java, which edits an XML document: adds a Node (element or attribute) to a document, modifies a Node, or removes a node. This is offered as a possibly friendlier alternative to using XSLT.
https://github.com/dinochiesa/apigee-java-edit-xml-node

apigee java xml

Last synced: 4 months ago
JSON representation

a custom policy for Apigee, implemented in Java, which edits an XML document: adds a Node (element or attribute) to a document, modifies a Node, or removes a node. This is offered as a possibly friendlier alternative to using XSLT.

Awesome Lists containing this project

README

          

# Apigee Edit Xml Node

This directory contains the Java source code and pom.xml file required to
compile a simple custom policy for Apigee. The policy adds a node to an XML
document, replaces a node in a document, or removes a node from a document.

Suppose you have a document like this:
```xml





fokyCS2jrkE5s+bC25L1Aax5sK....08GXIpwlq3QBJuG7a4Xgm4Vk


```

And you'd like to replace the text node in the middle of that
document with something else, maybe the decrypted version of that
string. This policy lets you do that, allowing you to transform the
above into this:

```xml





decrypted-text-here


```

Today, in Apigee, you could do this with an XSLT policy and an XSLT module.
But many people don't want to write or maintain XSLT. This policy allows you to
accomplish the task with No coding required! [This policy does not perform decryption, just XML surgery.]

In addition to allowing you to replace a node in a document, this policy also
allows you to remove a single node (an attribute or element) from an XML document, or to insert a single
node into an XML document. Again, you could do this with XSLT, but ... then you'd have
to code XSLT. This callout is just an alternative.

## Disclaimer

This example is not an official Google product, nor is it part of an
official Google product.

## Using this policy

You do not need to build the source code in order to use the policy
in Apigee. All you need is the built JAR, and the appropriate
configuration for the policy. If you want to build it, feel free.
The instructions are at the bottom of this readme.

1. copy the jar file, available in target/apigee-custom-edit-xml-node-20240614.jar , if you have built the jar, or in [the repo](bundle/apiproxy/resources/java/apigee-custom-edit-xml-node-20240614.jar) if you have not, to your apiproxy/resources/java directory. You can do this offline, or using the graphical Proxy Editor in the Apigee Admin Portal.

2. include an XML file for the Java callout policy in your
apiproxy/resources/policies directory. It should look
like this:
```xml

...
com.google.apigee.callouts.EditXmlNode
java://apigee-custom-edit-xml-node-20240614.jar

```

3. use the Apigee administrative UI, or a command-line tool like [importAndDeploy.js](https://github.com/DinoChiesa/apigee-edge-js/blob/master/examples/importAndDeploy.js) or similar to
import the proxy into an Apigee organization, and then deploy the proxy .
Eg,
```
node ./importAndDeploy.js -v -o $ORG -e $ENV -d ./bundle
```

4. Use a client to generate and send http requests to the proxy you just deployed . Eg,
```
curl -i -X POST -H content-type:text/xml \
'https://$ORG-$ENV.apigee.net/edit-xml-node/t1?texttoadd=seven&xpath=/root/a/text()' \
-d 'beta'
```

## Notes on Usage

There is one callout class, com.google.apigee.callouts.EditXmlNode.

The policy is configured via properties set in the XML. You can set these properties:

| property name | status | description |
| ----------------- |-----------|-------------------------------------------|
| action | Required | append, insert-before, replace, or remove |
| xpath | Required | the xpath to resolve to a single node in the source document. |
| source | Optional | the source xml document. This should be the name of a context variable. If you omit this property, the policy will use "message.content" as the source. |
| new-node-type | Required* | should be one of element, attribute, text. |
| new-node-text | Required* | Depending on the value of new-node-type, this must take a value that corresponds to an element, attribute, or text node. For an element, eg, `bar`. For an attribute, do not use any quotes. Eg, `attr1=value` Or, for a Text node, any text string. |
| output-variable | Optional | the name of a variable to hold the result. If not present, the result is placed into "message.content". |

*The new-node-type and new-node-text are not required if removing a node. When you do use new-node-type, the type of the node to which the `xpath` resolves must match the `new-node-type` you specify in the configuration. In other words, you can replace a text node with a text node. Or, you can replace an element with an element. Or you can use `insert-before` to insert an additional attribute before an existing attribute. You cannot use this policy to replace, for example, an element with a text node. Or to append a text node to an attribute. or to `insert-before` on an attribute if the result of the xpath reference is an element. All of this should make sense.

NB: There is no support for namespace-qualified attributes.

## Example Policy Configurations

### Appending an Element

```xml


request.content
element
text-value
{request.queryparam.xpath}
append

com.google.apigee.callouts.EditXmlNode
java://apigee-custom-edit-xml-node-20240614.jar

```

### Replacing a text node

```xml


request.content
text
{request.queryparam.texttoinsert}
{request.queryparam.xpath}
replace
my_variable

com.google.apigee.callouts.EditXmlNode
java://apigee-custom-edit-xml-node-20240614.jar

```

### Replacing a text node using XML namespaces

Any property name that begins with `xmlns:` is treated as an xml prefix and namespace by the custom policy. The policy can use any of these namespaces for xpath resolution. You must specify a prefix to apply an xpath to a document that uses namespaces. Of course the prefix you use in your xpath need not match the prefix used in the document, according to XML and XPath processing rules. Only the namepace is required to be the same.

```xml


http://schemas.xmlsoap.org/soap/envelope/
http://yyyy.com
request.content
text
{request.queryparam.texttoinsert}
/soap:Envelope/soap:Body/act:test/abc/act:demo/text()
replace

com.google.apigee.callouts.EditXmlNode
java://apigee-custom-edit-xml-node-20240614.jar

```

Applied against a source a document like this:
```xml





fokyCS2jrkE5s+bC25L1Aax5sK...J7nmd3OwHq/08GXIpwlq3QBJuG7a4Xgm4Vk


```

The above policy configuration would produce this output

```xml





THE VALUE OF request.queryparam.texttoinsert APPEARS HERE


```

Whether inserting, appending, or replacing an element, the `new-node-text` may
be a fragment that refers to XML namespaces that have been declared in the
policy configuration. The policy at runtime will inject the appropriate
namespace declarations into the toplevel element. For example, this is ok:

```xml



request.content
element

text-value]]>
{request.queryparam.xpath}
append

com.google.apigee.callouts.EditXmlNode
java://apigee-custom-edit-xml-node-20240614.jar

```

### Removing a SOAP Header

Using the "remove" action, you can also remove a node (which may have children) from an XML document.

```xml


http://schemas.xmlsoap.org/soap/envelope/
request.content
/soap:Envelope/soap:Header
remove

com.google.apigee.callouts.EditXmlNode
java://apigee-custom-edit-xml-node-20240614.jar

```

Applied against a source a document like this:
```xml


....
....




fokyCS2jrkE5s+bC25L1Aax5sK...J7nmd3OwHq/08GXIpwlq3QBJuG7a4Xgm4Vk


```

The above policy configuration would produce this output:

```xml




fokyCS2jrkE5s+bC25L1Aax5sK...J7nmd3OwHq/08GXIpwlq3QBJuG7a4Xgm4Vk


```

### Inserting a SOAP WS-Security Header

Using the "insert-before" action, you can insert a soap security header into a SOAP document that does not have a header.

```xml


http://schemas.xmlsoap.org/soap/envelope/
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd
request.content
/soap:Envelope/soap:Body
insert-before
element





{my.username}
{my.password}



]]>


com.google.apigee.callouts.EditXmlNode
java://apigee-custom-edit-xml-node-20240614.jar

```

Applied against a source a document like this:
```xml



xyz

```

The above policy configuration would produce this output:

```xml




username
password




xyz

```

### Removing an element depending on a text value

Here's another example using the "remove" action. This one uses an XPath that selects based on the text value of a child.

```xml


b
contrivedMessage.content
/b:Response/b:document/b:documentProperties[b:name/text()='Property2']
remove

com.google.apigee.callouts.EditXmlNode
java://apigee-custom-edit-xml-node-20240614.jar

```

Applied against a source a document like this:
```xml



Property1
Valule1


Property2
Value2

```

The above policy configuration would produce this output:

```xml



Property1
Valule1

```

## Example API Proxy

You can find an example proxy bundle that uses the policy, [here in
this repo](bundle/apiproxy).

## Building the Jar

If you are using Apigee X or hybrid, you do not need to build the Jar in order
to use the custom policy. The custom policy is ready to use, with policy
configuration. If you are using OPDK, which still relies on Java8, you will
need to re-build the JAR. The jar bundled here has been built with Java11. If
you try to use it with OPDK, you will receive an error message like the
following:

> Failed to load java class com.google.apigee.callouts.GenerateJwe definition
> due to - com/google/apigee/callouts/GenerateJwe has been compiled by a more
> recent version of the Java Runtime (class file version 55.0), this version of
> the Java Runtime only recognizes class file versions up to 52.0.

If using Apigee X or hybrid, you need to re-build the jar only if you want
to modify the behavior of the custom policy. Before you do that, be sure you understand
all the configuration options - the policy may be usable for you without modification.

If you do wish to build the jar, you can use
[maven](https://maven.apache.org/download.cgi) to do so, v3.9.0 or later.

### To Build

```
cd callout

# build with Java11
mvn clean package

# build with Java8
mvn -f pom-java8.xml clean package

```

The source code includes tests.

If you edit policies offline, copy [the jar file for the custom
policy](callout/target/apigee-custom-edit-xml-node-20240614.jar) and all the
dependencies to your apiproxy/resources/java directory. (The pom file does this
for you, automatically, for the sample bundle here.) If you don't edit proxy
bundles offline, upload that jar file into the API Proxy via the Apigee API
Proxy Editor.

## Build Dependencies

- Apigee expressions v1.0
- Apigee message-flow v1.0
- fasterxml jackson (needed only for building+running tests)
- testng v6.8.7 (needed only for building+running tests)
- jmockit v1.49 (needed only for building+running tests)

The pom file will take care of these Jars.

## Support

This callout is open-source software, and is not a supported part of Apigee. If
you need assistance, you can try inquiring on [the Google Cloud Community forum
dedicated to Apigee](https://goo.gle/apigee-community) There is no service-level
guarantee for responses to inquiries posted to that site.

## License

This material is [Copyright 2015, 2016 Apigee Corporation, 2017-2024 Google LLC](./NOTICE).
and is licensed under the [Apache 2.0 License](LICENSE). This includes the Java
code as well as the API Proxy configuration.

## Bugs

* when inserting elements, sometimes you get extraneous namespace declarations. This is annoying but harmless.