/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.camel.component.mllp.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_BLOCK;
import static org.apache.camel.component.mllp.MllpEndpoint.MESSAGE_TERMINATOR;
import static org.apache.camel.component.mllp.MllpEndpoint.SEGMENT_DELIMITER;
import static org.apache.camel.component.mllp.MllpEndpoint.START_OF_BLOCK;
public final class Hl7Util {
static final Logger LOG = LoggerFactory.getLogger(Hl7Util.class);
private Hl7Util() {
}
public static String generateInvalidPayloadExceptionMessage(final byte[] hl7Bytes) {
if (hl7Bytes == null) {
return "HL7 payload is null";
}
return generateInvalidPayloadExceptionMessage(hl7Bytes, hl7Bytes.length);
}
/**
* Verifies that the HL7 payload array
* <p>
* The MLLP protocol does not allow embedded START_OF_BLOCK or END_OF_BLOCK characters. The END_OF_DATA character
* is allowed (and expected) because it is also the segment delimiter for an HL7 message
*
* @param hl7Bytes the HL7 payload to validate
* @return If the payload is invalid, an error message suitable for inclusion in an exception is returned. If
* the payload is valid, null is returned;
*/
public static String generateInvalidPayloadExceptionMessage(final byte[] hl7Bytes, final int length) {
if (hl7Bytes == null) {
return "HL7 payload is null";
}
if (hl7Bytes.length <= 0) {
return "HL7 payload is empty";
}
if (length > hl7Bytes.length) {
LOG.warn("The length specified for the HL7 payload array <{}> is greater than the actual length of the array <{}> - only validating {} bytes", length, hl7Bytes.length, length);
}
if (hl7Bytes.length < 3 || hl7Bytes[0] != 'M' || hl7Bytes[1] != 'S' || hl7Bytes[2] != 'H') {
return String.format("The first segment of the HL7 payload {%s} is not an MSH segment", new String(hl7Bytes, 0, Math.min(3, hl7Bytes.length)));
}
int validationLength = Math.min(length, hl7Bytes.length);
if (hl7Bytes[validationLength - 2] != SEGMENT_DELIMITER || hl7Bytes[validationLength - 1] != MESSAGE_TERMINATOR) {
String format = "The HL7 payload terminating bytes [%#x, %#x] are incorrect - expected [%#x, %#x] {ASCII [<CR>, <LF>]}";
return String.format(format, hl7Bytes[validationLength - 2], hl7Bytes[validationLength - 1], (byte) SEGMENT_DELIMITER, (byte) MESSAGE_TERMINATOR);
}
for (int i = 0; i < validationLength; ++i) {
switch (hl7Bytes[i]) {
case START_OF_BLOCK:
return String.format("HL7 payload contains an embedded START_OF_BLOCK {%#x, ASCII <VT>} at index %d", hl7Bytes[i], i);
case END_OF_BLOCK:
return String.format("HL7 payload contains an embedded END_OF_BLOCK {%#x, ASCII <FS>} at index %d", hl7Bytes[i], i);
default:
// continue on
}
}
return null;
}
}