cancel
Showing results for 
Search instead for 
Did you mean: 

Manage illegal XML characters from proxy

nicola_martella2
Participant
0 Kudos

Hi people.

I have a problem on an async scenario PROXY-to-FILE (PO 7.5 single stack).

In payload from ECC I can receive XML illegal characters that I must remove before they cause mapping failure.

I realized a java mapping that works for first in the Operation Mapping.

Testing the scenario by the feature Testing > Send Test Message in Configuration and Monitoring all works fine.

Instead, running the proxy by ECC the flow fails with this error:

Transmitting the message to endpoint <local> using connection SOAP_http://sap.com/xi/XI/System failed, due to: com.sap.aii.af.service.mapping.MappingException: Mapping failed in runtimeApplication mapping program com/nick4name/xi/javamapping/jmXmlCharsCleaning/JMStartup throws a stream transformation exception: [jmXmlCharsCleaning] org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 2112; Character reference "&#

Pay attention that the process has correctly identified the Operation Mapping, see "com/nick4name/xi/javamapping/jmXmlCharsCleaning/JMStartup", and then my jm, but, probably, is failed before run it.

Seems that, the testing tool, starting from the ICO manually setted, jumps a last XML parsing that the runtime process instead executes.

Now the hard question. Is it possible to intervene on this behaviour or the only approch is by a module custom in the proxy channel?

Thanks a lot for your support.

Nicola

Accepted Solutions (0)

Answers (6)

Answers (6)

JaySchwendemann
Active Contributor

You might also want to look into https://launchpad.support.sap.com/#/notes/2318945

nicola_martella2
Participant
0 Kudos

Hi Jens.

If I correctly understood, this solution applies to ECC side.

I need a solution that disable the check characters wrong on SAP PO (single-stack) side. Something like SPROXSET.

Or something other :(.

Thanks a lot

Nicola

JaySchwendemann
Active Contributor
0 Kudos

Your initial post was...

I have a problem on an async scenario PROXY-to-FILE (PO 7.5 single stack).
In payload from ECC I can receive XML illegal characters that I must remove before they cause mapping failure.

==> Why not eliminating the illegal characters in ECC (proxy runtime) already using the parameters in the given note?

If you absolutely must, you ought to tap into java mapping, as you already did because probably there would no way to fix a non well formed XML with XSLT or graphical mapping. You even might end up writing a custom module to fix things before PI mapping runtime.

PriyankaAnagani
Active Contributor

Hi Nocila,

You can remove/replace the special characters in java mapping with the way you just did.

  • Make sure your java mapping in the first mapping in the operation mapping followed by any other mappings that you've.
  • When you test it end to end, get the source payload (before mapping) from message monitoring logs and using that payload test your operation mapping to see if its working.
  • You can also compare the difference between the source payloads when you test it end to end(Proxy) and when you trigger it from "Send Test Message".

--Priyanka

nicola_martella2
Participant
0 Kudos

Hi Priyanka,

thank you for your contribute. Remembering that I have to apply this solution on a SAP PO 7.5 Single-stack

  • Yes, my JM is the first in the OM stack
  • The test from OM's Test tab works fine and the test from Configuration and Monitoring, feature Testing > Send Test Message works fine too

The problem is at runtime, but you can see the same firing the payload with wrong chars by test feature in SPROXY from ECC.

Probably, the test from inside SAP PO works fine because I already provide the parameters to hook the operation mapping.

Insted, when the payload arrives from the outside, ECC in this case, the runtime must to open it to read namespace and root tag and so it fails.

I really don't want to develop a java module for the communication channel SOAP (from proxy), assuming it can be done, because this means a lot of problems for grants, ports to open, and probably it is not enough because I'm on VPN, and so on.

The question:

Is there some parameter in nwa to disable check characters wrong?

Thanks a lot.

Nicola

PriyankaAnagani
Active Contributor
0 Kudos

Hi Nicola,

What error you are getting in runtime? Can you share the error details to advise further.

--Priyanka

nicola_martella2
Participant
0 Kudos

The error is this

Mapping "http://mxnxaxoxi/hana_libri/CHRONOS/Outbound/OM_IF0447_MovimentiMagazzino" failed to execute: MappingException: Mapping failed in runtimeApplication mapping program com/nick4name/xi/javamapping/jmXmlCharsCleaning/JMStartup throws a stream transformation exception: [jmXmlCharsCleaning] org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 2112; Character reference "&#, ApplicationException: Application mapping program com/nick4name/xi/javamapping/jmXmlCharsCleaning/JMStartup throws a stream transformation exception: [jmXmlCharsCleaning] org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 2112; Character reference "&#, StreamTransformationException: [jmXmlCharsCleaning] org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 2112; Character reference "&#

com/nick4name/xi/javamapping/jmXmlCharsCleaning/JMStartup is my java mapping on top of operation mapping stack.

Ciao

Nicola

PriyankaAnagani
Active Contributor

If you are trying to test with the same payload that you see in SXMB_MONI of ECC, it should work in runtime if the same working in OM.

Also, check the encoding in XML declaration just in case if it's different. You might need to adjust your java code based on how it is in ECC payload. Something like below in your Javamap.

privatestaticbyte[] cleanChars(byte[]by){

String s =newString(by, "UTF-8");

by=null;

s = s.replaceAll("[\\x00-\\x08]", "").replaceAll("[\\x10-\\x1f]", "");

return s.getBytes();

}

--Priyanka

nicola_martella2
Participant
0 Kudos

Hi Priyanka.

I reached the same conclusion yesterday night after I downloaded in a file the inbound payload unconverted.

I believed that the illegal chars were in binary notation and not in escape character one and so I treated now as string.

But, I beleave che your solution String s =newString(by, "UTF-8") is better.

Thanks a lot Priyanka.

A great Ciao

Nicola

nicola_martella2
Participant
0 Kudos

Hi Jens.

For me could be ok a solution ECC side.

I tried to apply the 2318945 note with several options but without success.

The kernel version is currently 753 so I think the option is covered

Is there something wrong?

Ciao

Nicola

JaySchwendemann
Active Contributor
0 Kudos

Yeah...

  1. you probably should be using the SPROXY parameters instead of the ABAP constants.
  2. Also your username might be hindering, if you are unsure that you are the one actually calling the proxy.
  3. lastly the ILLEGAL_CHAR_REJECT parameter would result in proxy errors visible in SRT_UTIL or SXMB_MONI, not in the desired outcome of a "replaced" XML entering the PI.

nicola_martella2
Participant
0 Kudos

Hi Carlos.

The idea in jm is to convert in string the xml inbound in operation mapping, remove the illegal characters with regex and than return the converted string in xml.

The code is this

	private static byte[] cleanChars(byte[] by) {
		String s = new String(by);
		by = null;
		s = s.replaceAll("[\\x00-\\x08]", "").replaceAll("[\\x10-\\x1f]", "");
		return s.getBytes();
	}

	public static byte[] toByteArray(InputStream in) throws IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		byte[] buffer = new byte[2];
		int len;
		while ((len = in.read(buffer)) != -1) {
			os.write(buffer, 0, len);
		}
		return os.toByteArray();
	}

	public static String convDocumentToString(Document doc)
			throws ParserConfigurationException, SAXException, IOException, TransformerException {

		TransformerFactory xff = TransformerFactory.newInstance();
		Transformer xf = xff.newTransformer();
		xf.setOutputProperty(OutputKeys.INDENT, "yes");
		xf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
		StringWriter sw = new StringWriter();
		xf.transform(new DOMSource(doc), new StreamResult(sw));
		String retSW = sw.toString();

		return retSW;

	}

	@Override
	public void transform(TransformationInput in, TransformationOutput out) throws StreamTransformationException {

		String outStr = null;
		InputStream instr = in.getInputPayload().getInputStream();
		try {
			byte[] by = toByteArray(instr);
			by = cleanChars(by);
			instr = new ByteArrayInputStream(by);
			by = null;

		} catch (Exception ex) {
			ex.printStackTrace();
			return;
		}

		DocumentBuilder builder = null;
		Document inDoc = null;
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setNamespaceAware(true);
			factory.setValidating(false);
			builder = factory.newDocumentBuilder();
			inDoc = builder.parse(instr);

		} catch (TransformerFactoryConfigurationError | ParserConfigurationException | IOException | SAXException ex) {

			throw new StreamTransformationException(Application.JM_MODULE_NAME_FORMAT + ex.toString());

		}
		try {
			outStr = convDocumentToString(inDoc);
			OutputStream outstream = out.getOutputPayload().getOutputStream();
			outstream.write(outStr.getBytes());

		} catch (ParserConfigurationException | SAXException | IOException | TransformerException e) {
			throw new StreamTransformationException(Application.JM_MODULE_NAME_FORMAT + e.toString());
		}
	}
former_member608139
Active Participant
0 Kudos

what are you dong in the java ?