/** * 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; } }