diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mllp.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mllp.json index 64e17075301f5..773c2686de4e6 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mllp.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mllp.json @@ -62,22 +62,27 @@ "headers": { "CamelMllpLocalAddress": { "index": 0, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The local TCP Address of the Socket", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_LOCAL_ADDRESS" }, "CamelMllpRemoteAddress": { "index": 1, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The remote TCP Address of the Socket", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_REMOTE_ADDRESS" }, - "CamelMllpAcknowledgement": { "index": 2, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "byte[]", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 Acknowledgment received in bytes", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT" }, - "CamelMllpAcknowledgementString": { "index": 3, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 Acknowledgment received, converted to a String", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT_STRING" }, - "CamelMllpAcknowledgementType": { "index": 4, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 acknowledgement type (AA, AE, AR, etc)", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT_TYPE" }, - "CamelMllpSendingApplication": { "index": 5, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-3 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SENDING_APPLICATION" }, - "CamelMllpSendingFacility": { "index": 6, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-4 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SENDING_FACILITY" }, - "CamelMllpReceivingApplication": { "index": 7, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-5 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_RECEIVING_APPLICATION" }, - "CamelMllpReceivingFacility": { "index": 8, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-6 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_RECEIVING_FACILITY" }, - "CamelMllpTimestamp": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-7 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_TIMESTAMP" }, - "CamelMllpSecurity": { "index": 10, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-8 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SECURITY" }, - "CamelMllpMessageType": { "index": 11, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_MESSAGE_TYPE" }, - "CamelMllpEventType": { "index": 12, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9.1 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_EVENT_TYPE" }, - "CamelMllpTriggerEvent": { "index": 13, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9.2 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_TRIGGER_EVENT" }, - "CamelMllpMessageControlId": { "index": 14, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-10 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_MESSAGE_CONTROL" }, - "CamelMllpProcessingId": { "index": 15, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-11 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_PROCESSING_ID" }, - "CamelMllpVersionId": { "index": 16, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-12 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_VERSION_ID" }, - "CamelMllpCharset": { "index": 17, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-18 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_CHARSET" } + "CamelMllpSslClientCertSubjectName": { "index": 2, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate subject name", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_SUBJECT_NAME" }, + "CamelMllpSslClientCertIssuerName": { "index": 3, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate issuer name", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_ISSUER_NAME" }, + "CamelMllpSslClientCertSerialNo": { "index": 4, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate serial number", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_SERIAL_NO" }, + "CamelMllpSslClientCertNotBefore": { "index": 5, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate not before.", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_NOT_BEFORE" }, + "CamelMllpSslClientCertNotAfter": { "index": 6, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate not after.", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_NOT_AFTER" }, + "CamelMllpAcknowledgement": { "index": 7, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "byte[]", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 Acknowledgment received in bytes", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT" }, + "CamelMllpAcknowledgementString": { "index": 8, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 Acknowledgment received, converted to a String", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT_STRING" }, + "CamelMllpAcknowledgementType": { "index": 9, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 acknowledgement type (AA, AE, AR, etc)", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT_TYPE" }, + "CamelMllpSendingApplication": { "index": 10, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-3 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SENDING_APPLICATION" }, + "CamelMllpSendingFacility": { "index": 11, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-4 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SENDING_FACILITY" }, + "CamelMllpReceivingApplication": { "index": 12, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-5 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_RECEIVING_APPLICATION" }, + "CamelMllpReceivingFacility": { "index": 13, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-6 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_RECEIVING_FACILITY" }, + "CamelMllpTimestamp": { "index": 14, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-7 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_TIMESTAMP" }, + "CamelMllpSecurity": { "index": 15, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-8 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SECURITY" }, + "CamelMllpMessageType": { "index": 16, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_MESSAGE_TYPE" }, + "CamelMllpEventType": { "index": 17, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9.1 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_EVENT_TYPE" }, + "CamelMllpTriggerEvent": { "index": 18, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9.2 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_TRIGGER_EVENT" }, + "CamelMllpMessageControlId": { "index": 19, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-10 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_MESSAGE_CONTROL" }, + "CamelMllpProcessingId": { "index": 20, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-11 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_PROCESSING_ID" }, + "CamelMllpVersionId": { "index": 21, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-12 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_VERSION_ID" }, + "CamelMllpCharset": { "index": 22, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-18 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_CHARSET" } }, "properties": { "hostname": { "index": 0, "kind": "path", "displayName": "Hostname", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Hostname or IP for connection for the TCP connection. The default value is null, which means any local IP address" }, diff --git a/components/camel-mllp/src/generated/resources/META-INF/org/apache/camel/component/mllp/mllp.json b/components/camel-mllp/src/generated/resources/META-INF/org/apache/camel/component/mllp/mllp.json index 64e17075301f5..773c2686de4e6 100644 --- a/components/camel-mllp/src/generated/resources/META-INF/org/apache/camel/component/mllp/mllp.json +++ b/components/camel-mllp/src/generated/resources/META-INF/org/apache/camel/component/mllp/mllp.json @@ -62,22 +62,27 @@ "headers": { "CamelMllpLocalAddress": { "index": 0, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The local TCP Address of the Socket", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_LOCAL_ADDRESS" }, "CamelMllpRemoteAddress": { "index": 1, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The remote TCP Address of the Socket", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_REMOTE_ADDRESS" }, - "CamelMllpAcknowledgement": { "index": 2, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "byte[]", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 Acknowledgment received in bytes", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT" }, - "CamelMllpAcknowledgementString": { "index": 3, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 Acknowledgment received, converted to a String", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT_STRING" }, - "CamelMllpAcknowledgementType": { "index": 4, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 acknowledgement type (AA, AE, AR, etc)", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT_TYPE" }, - "CamelMllpSendingApplication": { "index": 5, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-3 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SENDING_APPLICATION" }, - "CamelMllpSendingFacility": { "index": 6, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-4 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SENDING_FACILITY" }, - "CamelMllpReceivingApplication": { "index": 7, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-5 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_RECEIVING_APPLICATION" }, - "CamelMllpReceivingFacility": { "index": 8, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-6 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_RECEIVING_FACILITY" }, - "CamelMllpTimestamp": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-7 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_TIMESTAMP" }, - "CamelMllpSecurity": { "index": 10, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-8 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SECURITY" }, - "CamelMllpMessageType": { "index": 11, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_MESSAGE_TYPE" }, - "CamelMllpEventType": { "index": 12, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9.1 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_EVENT_TYPE" }, - "CamelMllpTriggerEvent": { "index": 13, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9.2 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_TRIGGER_EVENT" }, - "CamelMllpMessageControlId": { "index": 14, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-10 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_MESSAGE_CONTROL" }, - "CamelMllpProcessingId": { "index": 15, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-11 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_PROCESSING_ID" }, - "CamelMllpVersionId": { "index": 16, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-12 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_VERSION_ID" }, - "CamelMllpCharset": { "index": 17, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-18 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_CHARSET" } + "CamelMllpSslClientCertSubjectName": { "index": 2, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate subject name", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_SUBJECT_NAME" }, + "CamelMllpSslClientCertIssuerName": { "index": 3, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate issuer name", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_ISSUER_NAME" }, + "CamelMllpSslClientCertSerialNo": { "index": 4, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate serial number", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_SERIAL_NO" }, + "CamelMllpSslClientCertNotBefore": { "index": 5, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate not before.", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_NOT_BEFORE" }, + "CamelMllpSslClientCertNotAfter": { "index": 6, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The SSL client certificate not after.", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SSL_CLIENT_CERT_NOT_AFTER" }, + "CamelMllpAcknowledgement": { "index": 7, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "byte[]", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 Acknowledgment received in bytes", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT" }, + "CamelMllpAcknowledgementString": { "index": 8, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 Acknowledgment received, converted to a String", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT_STRING" }, + "CamelMllpAcknowledgementType": { "index": 9, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HL7 acknowledgement type (AA, AE, AR, etc)", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_ACKNOWLEDGEMENT_TYPE" }, + "CamelMllpSendingApplication": { "index": 10, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-3 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SENDING_APPLICATION" }, + "CamelMllpSendingFacility": { "index": 11, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-4 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SENDING_FACILITY" }, + "CamelMllpReceivingApplication": { "index": 12, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-5 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_RECEIVING_APPLICATION" }, + "CamelMllpReceivingFacility": { "index": 13, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-6 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_RECEIVING_FACILITY" }, + "CamelMllpTimestamp": { "index": 14, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-7 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_TIMESTAMP" }, + "CamelMllpSecurity": { "index": 15, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-8 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_SECURITY" }, + "CamelMllpMessageType": { "index": 16, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_MESSAGE_TYPE" }, + "CamelMllpEventType": { "index": 17, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9.1 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_EVENT_TYPE" }, + "CamelMllpTriggerEvent": { "index": 18, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-9.2 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_TRIGGER_EVENT" }, + "CamelMllpMessageControlId": { "index": 19, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-10 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_MESSAGE_CONTROL" }, + "CamelMllpProcessingId": { "index": 20, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-11 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_PROCESSING_ID" }, + "CamelMllpVersionId": { "index": 21, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-12 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_VERSION_ID" }, + "CamelMllpCharset": { "index": 22, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "MSH-18 value", "constantName": "org.apache.camel.component.mllp.MllpConstants#MLLP_CHARSET" } }, "properties": { "hostname": { "index": 0, "kind": "path", "displayName": "Hostname", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Hostname or IP for connection for the TCP connection. The default value is null, which means any local IP address" }, diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java index 00eede06d2cfa..00d8d11a3cedf 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java @@ -26,6 +26,17 @@ public final class MllpConstants { public static final String MLLP_LOCAL_ADDRESS = "CamelMllpLocalAddress"; @Metadata(description = "The remote TCP Address of the Socket", javaType = "String") public static final String MLLP_REMOTE_ADDRESS = "CamelMllpRemoteAddress"; + @Metadata(description = "The SSL client certificate subject name", label = "consumer", javaType = "String") + public static final String MLLP_SSL_CLIENT_CERT_SUBJECT_NAME = "CamelMllpSslClientCertSubjectName"; + @Metadata(description = "The SSL client certificate issuer name", label = "consumer", javaType = "String") + public static final String MLLP_SSL_CLIENT_CERT_ISSUER_NAME = "CamelMllpSslClientCertIssuerName"; + @Metadata(description = "The SSL client certificate serial number", label = "consumer", javaType = "String") + public static final String MLLP_SSL_CLIENT_CERT_SERIAL_NO = "CamelMllpSslClientCertSerialNo"; + @Metadata(description = "The SSL client certificate not before.", label = "consumer", javaType = "String") + public static final String MLLP_SSL_CLIENT_CERT_NOT_BEFORE = "CamelMllpSslClientCertNotBefore"; + @Metadata(description = "The SSL client certificate not after.", label = "consumer", javaType = "String") + public static final String MLLP_SSL_CLIENT_CERT_NOT_AFTER = "CamelMllpSslClientCertNotAfter"; + @Metadata(description = "The HL7 Acknowledgment received in bytes", javaType = "byte[]") public static final String MLLP_ACKNOWLEDGEMENT = "CamelMllpAcknowledgement"; @Metadata(description = "The HL7 Acknowledgment received, converted to a String", javaType = "String") diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java index 037b8e66be2d7..8ab1e9884137b 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java @@ -17,15 +17,15 @@ package org.apache.camel.component.mllp; import java.io.IOException; +import java.math.BigInteger; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.security.Principal; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -35,6 +35,10 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; + import org.apache.camel.Exchange; import org.apache.camel.ExchangePattern; import org.apache.camel.ExchangePropertyKey; @@ -255,6 +259,10 @@ public void processMessage(byte[] hl7MessageBytes, TcpSocketConsumerRunnable con Message message = exchange.getIn(); + if (consumerRunnable.getSocket() instanceof SSLSocket sslSocket) { + enrichWithClientCertInformation(sslSocket.getSession(), message); + } + if (consumerRunnable.hasLocalAddress()) { message.setHeader(MllpConstants.MLLP_LOCAL_ADDRESS, consumerRunnable.getLocalAddress()); } @@ -305,6 +313,46 @@ public void processMessage(byte[] hl7MessageBytes, TcpSocketConsumerRunnable con } } + /** + * Enriches the message with client certificate details such as subject name, serial number, etc. + *

+ * If the certificate is unverified then the headers is not enriched. + * + * @param sslSession the SSL session + * @param message the message to enrich + */ + protected void enrichWithClientCertInformation(SSLSession sslSession, Message message) { + if (sslSession == null || message == null) { + return; + } + + try { + Certificate[] certificates = sslSession.getPeerCertificates(); + if (certificates != null && certificates.length > 0) { + if (!(certificates[0] instanceof X509Certificate cert)) { + return; + } + + Principal subject = cert.getSubjectX500Principal(); + if (subject != null) { + message.setHeader(MllpConstants.MLLP_SSL_CLIENT_CERT_SUBJECT_NAME, subject.toString()); + } + Principal issuer = cert.getIssuerX500Principal(); + if (issuer != null) { + message.setHeader(MllpConstants.MLLP_SSL_CLIENT_CERT_ISSUER_NAME, issuer.toString()); + } + BigInteger serial = cert.getSerialNumber(); + if (serial != null) { + message.setHeader(MllpConstants.MLLP_SSL_CLIENT_CERT_SERIAL_NO, serial.toString()); + } + message.setHeader(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_BEFORE, cert.getNotBefore()); + message.setHeader(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_AFTER, cert.getNotAfter()); + } + } catch (SSLPeerUnverifiedException e) { + // ignore + } + } + void populateHl7DataHeaders(Exchange exchange, Message message, byte[] hl7MessageBytes) { if (getConfiguration().isHl7Headers() && exchange != null && exchange.getException() == null) { if (hl7MessageBytes == null || hl7MessageBytes.length < 8) { diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderBase.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderBase.java new file mode 100644 index 0000000000000..5289311b0c0da --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderBase.java @@ -0,0 +1,202 @@ +/* + * 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; + +import java.io.File; +import java.net.URI; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Date; + +import org.apache.camel.CamelContext; +import org.apache.camel.EndpointInject; +import org.apache.camel.LoggingLevel; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.support.jsse.*; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.junit.rule.mllp.MllpClientResource; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.extension.RegisterExtension; + +/** + * Does mTLS connection with MLLP and asserts that the headers are properly set. + */ +public class MllpMutualTlsConnectionAndHeaderBase extends CamelTestSupport { + + public static final String WANTS_CLIENT_AUTHENTICATION = "sslContextParametersWantsClientAuthentication"; + public static final String REQUIRES_CLIENT_AUTHENTICATION = "sslContextParametersRequiresClientAuthentication"; + public static final String NO_CLIENT_AUTHENTICATION = "sslContextParametersNoClientAuthentication"; + public static final String WITH_ONLY_TRUSTSTORE = "sslContextParametersWithOnlyTruststore"; + + public static final String TEST_PAYLOAD = "MSH|^~\\&|CLIENT|TEST|SERVER|ACK|20231118120000||ADT^A01|123456|T|2.6\r" + + "EVN|A01|20231118120000\r" + + "PID|1|12345|67890||DOE^JOHN||19800101|M|||123 Main St^^Springfield^IL^62704||(555)555-5555|||||S\r" + + + "PV1|1|O\r"; + + private final String sslContextParamtersUsedInTestRoute; + + protected String expectedCertSubjectName; + protected String expectedCertIssuerName; + protected String expectedCertSerialNo; + protected Date expectedCertNotBefore; + protected Date expectedCertNotAfter; + + @RegisterExtension + public MllpClientResource mllpClient = new MllpClientResource(); + + @EndpointInject("mock://result") + protected MockEndpoint result; + + protected MllpMutualTlsConnectionAndHeaderBase(String sslContextParametersUsedInTestRoute) { + this.sslContextParamtersUsedInTestRoute = sslContextParametersUsedInTestRoute; + } + + /** + * Creates test route. + * + * @return RouteBuilder. + */ + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + + public void configure() { + fromF(assembleEndpointUri(sslContextParamtersUsedInTestRoute)) + .log(LoggingLevel.INFO, "mllp-ssl-sender", "Received Message: ${body}") + .to(result); + } + }; + } + + /** + * Creates an SSLContextParameters object with a key and truststore so that mTLS is conducted. + * + * @return SSLContextParamters with both keystore and truststore paramters. + * @throws Exception if anything goes wrong and then should fail the test. + */ + private SSLContextParameters createSslContextParameters(ClientAuthentication clientAuthentication) throws Exception { + KeyStoreParameters ksp = new KeyStoreParameters(); + ksp.setResource(this.getClass().getClassLoader().getResource("keystore.jks").toString()); + ksp.setPassword("password"); + + KeyManagersParameters kmp = new KeyManagersParameters(); + kmp.setKeyPassword("password"); + kmp.setKeyStore(ksp); + + TrustManagersParameters tmp = new TrustManagersParameters(); + tmp.setKeyStore(ksp); + + SSLContextParameters sslContextParameters = new SSLContextParameters(); + sslContextParameters.setKeyManagers(kmp); + sslContextParameters.setTrustManagers(tmp); + + extractExpectedSSLCertHeaderValuesFromActualCertificate(ksp); + + sslContextParameters.setServerParameters(new SSLContextServerParameters()); + sslContextParameters.getServerParameters().setClientAuthentication(clientAuthentication.name()); + + return sslContextParameters; + } + + /** + * Extracts values from the certificate the client will use to be used for validation during the tests. + * + * @param ksp KeyStoreParameters object created from SSLContextParameters creation. Holds the certificate + * information. + * @throws Exception if anything goes wrong and then should fail the test. + */ + private void extractExpectedSSLCertHeaderValuesFromActualCertificate(KeyStoreParameters ksp) + throws Exception { + File certFile = new File(URI.create(ksp.getResource())); + char[] password = ksp.getPassword().toCharArray(); + + KeyStore ks = KeyStore.getInstance(certFile, password); + X509Certificate certificate = (X509Certificate) ks.getCertificate("testKey"); + + expectedCertIssuerName = certificate.getIssuerX500Principal().toString(); + expectedCertSubjectName = certificate.getSubjectX500Principal().toString(); + expectedCertSerialNo = certificate.getSerialNumber().toString(); + expectedCertNotBefore = certificate.getNotBefore(); + expectedCertNotAfter = certificate.getNotAfter(); + + // Be really sure the expected headers aren't null as expectedHeaderReceived can accept null values, + // which could cause false positive test results when the mocks use these for comparing with the actual values. + Assertions.assertNotNull(expectedCertIssuerName); + Assertions.assertNotNull(expectedCertSubjectName); + Assertions.assertNotNull(expectedCertSerialNo); + Assertions.assertNotNull(expectedCertNotBefore); + Assertions.assertNotNull(expectedCertNotAfter); + } + + /** + * Creates a SSLContextParameters object with only a truststore. With this, the client will only do TLS connection, + * it will not send its own certificate for validation. + * + * @return SSLContextParameter object with only a truststore configured. + * @throws Exception if anything goes wrong and then should fail the test. + */ + private SSLContextParameters createSslContextParametersWithOnlyTruststore() { + KeyStoreParameters ksp = new KeyStoreParameters(); + ksp.setResource(this.getClass().getClassLoader().getResource("keystore.jks").toString()); + ksp.setPassword("password"); + + TrustManagersParameters tmp = new TrustManagersParameters(); + tmp.setKeyStore(ksp); + + SSLContextParameters sslContextParameters = new SSLContextParameters(); + sslContextParameters.setTrustManagers(tmp); + + return sslContextParameters; + } + + /** + * Registers sslContextParametes, both of them, to camel context. + * + * @return camelContext. + * @throws Exception if anything goes wrong and then should fail the test. + */ + @Override + protected CamelContext createCamelContext() throws Exception { + mllpClient.setMllpHost("localhost"); + mllpClient.setMllpPort(AvailablePortFinder.getNextAvailable()); + + DefaultCamelContext context = (DefaultCamelContext) super.createCamelContext(); + + context.setUseMDCLogging(true); + context.getCamelContextExtension().setName(this.getClass().getSimpleName()); + + context.getRegistry().bind(WANTS_CLIENT_AUTHENTICATION, + createSslContextParameters(ClientAuthentication.WANT)); + context.getRegistry().bind(REQUIRES_CLIENT_AUTHENTICATION, + createSslContextParameters(ClientAuthentication.REQUIRE)); + context.getRegistry().bind(NO_CLIENT_AUTHENTICATION, + createSslContextParameters(ClientAuthentication.NONE)); + + SSLContextParameters sslContextParametersWithOnlyTruststore = createSslContextParametersWithOnlyTruststore(); + context.getRegistry().bind(WITH_ONLY_TRUSTSTORE, sslContextParametersWithOnlyTruststore); + return context; + } + + protected String assembleEndpointUri(String sslContextParameters) { + return String.format("mllp://%s:%d?sslContextParameters=#%s", mllpClient.getMllpHost(), mllpClient.getMllpPort(), + sslContextParameters); + } +} diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderNoClientAuthenticationTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderNoClientAuthenticationTest.java new file mode 100644 index 0000000000000..a592ce2ce80fa --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderNoClientAuthenticationTest.java @@ -0,0 +1,73 @@ +/* + * 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; + +import org.junit.jupiter.api.Test; + +/** + * Does mTLS connection with MLLP and asserts that the headers are properly set. + */ +class MllpMutualTlsConnectionAndHeaderNoClientAuthenticationTest extends MllpMutualTlsConnectionAndHeaderBase { + MllpMutualTlsConnectionAndHeaderNoClientAuthenticationTest() { + super(NO_CLIENT_AUTHENTICATION); + } + + /** + * This test does TLS connection without a client sending its certificate, that is, no mTLS. In this case, none of + * the MLLP_SSL_CLIENT_CERT* headers should exist as the client didn't provide a certificate. + * + * @throws Exception if anything goes wrong and then should fail the test. + */ + @Test + void testSendingTlsWithNoClientCertificateToMllpConsumerWithNoClientAuthentication() throws Exception { + result.expectedBodiesReceived(TEST_PAYLOAD); + + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SUBJECT_NAME, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_ISSUER_NAME, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SERIAL_NO, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_BEFORE, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_AFTER, null); + + template.sendBody(assembleEndpointUri(WITH_ONLY_TRUSTSTORE), TEST_PAYLOAD); + result.assertIsSatisfied(); + } + + /** + * As the server is configured to not do any client authentication, make sure the MLLP_SSL_CLIENT_CERT* headers are + * not present. + * + * @throws Exception if anything goes wrong and then should fail the test. + */ + @Test + void testCommunicationWithConfiguredClientCertificateWithMllpConsumerWhichDoesNotDoClientAuthentication() + throws Exception { + result.expectedBodiesReceived(TEST_PAYLOAD); + + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SUBJECT_NAME, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_ISSUER_NAME, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SERIAL_NO, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_BEFORE, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_AFTER, null); + + // Any sslContextParameter with a client certificate should be valid here, but the worst case scenario for this test + // should be the context with the server flag for requiring client authentication. That flag should not matter, + // and here is the proof it doesn't. + template.sendBody(assembleEndpointUri(REQUIRES_CLIENT_AUTHENTICATION), TEST_PAYLOAD); + result.assertIsSatisfied(); + + } +} diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest.java new file mode 100644 index 0000000000000..c84003b12cd91 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest.java @@ -0,0 +1,68 @@ +/* + * 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; + +import java.net.SocketException; + +import org.apache.camel.CamelExecutionException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Does mTLS connection with MLLP and asserts that the headers are properly set. + */ +class MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest extends MllpMutualTlsConnectionAndHeaderBase { + MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest() { + super(REQUIRES_CLIENT_AUTHENTICATION); + } + + /** + * This test does TLS connection without a client sending its certificate, i.e., no mTLS. As the server is + * configured to require client authentication, this should fail. + * + */ + @Test + void testSendingTlsWithNoClientCertificateToMllpConsumerWhichRequiresClientAuthentication() { + try { + template.sendBody(assembleEndpointUri(WITH_ONLY_TRUSTSTORE), TEST_PAYLOAD); + Assertions.fail("Should not be able to connect without a client certificate"); + } catch (CamelExecutionException e) { + Assertions.assertInstanceOf(SocketException.class, e.getCause().getCause().getCause()); + } + } + + /** + * This test does a proper mTLS connection with MLLP. Here the headers are asserted to be present and non-null, all + * the MLLP_SSL* headers. + * + * @throws Exception if anything goes wrong and then should fail the test. + */ + @Test + void testMutualTlsInOutWithMllpConsumer() throws Exception { + result.expectedBodiesReceived(TEST_PAYLOAD); + + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SUBJECT_NAME, expectedCertSubjectName); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_ISSUER_NAME, expectedCertIssuerName); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SERIAL_NO, expectedCertSerialNo); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_BEFORE, expectedCertNotBefore); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_AFTER, expectedCertNotAfter); + + template.sendBody(assembleEndpointUri(REQUIRES_CLIENT_AUTHENTICATION), TEST_PAYLOAD); + result.assertIsSatisfied(); + + } +} diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderWantsClientAuthenticationTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderWantsClientAuthenticationTest.java new file mode 100644 index 0000000000000..472ae5e5413e8 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderWantsClientAuthenticationTest.java @@ -0,0 +1,83 @@ +/* + * 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; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Does mTLS connection with MLLP and asserts that the headers are properly set. + */ +class MllpMutualTlsConnectionAndHeaderWantsClientAuthenticationTest extends MllpMutualTlsConnectionAndHeaderBase { + + MllpMutualTlsConnectionAndHeaderWantsClientAuthenticationTest() { + super(WANTS_CLIENT_AUTHENTICATION); + } + + /** + * This test does TLS connection without client sending its certificate i.e., no mTLS. In this case, none of the + * MLLP_SSL_CLIENT_CERT* headers should exist as the client didn't provide a certificate. + * + * @throws Exception if anything goes wrong and then should fail the test. + */ + @Test + void testTlsNoClientCertificateInOutWithMllpConsumer() throws Exception { + result.expectedBodiesReceived(TEST_PAYLOAD); + + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SUBJECT_NAME, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_ISSUER_NAME, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SERIAL_NO, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_BEFORE, null); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_AFTER, null); + + String endpointUri = String.format("mllp://%s:%d?sslContextParameters=#sslContextParametersWithOnlyTruststore", + mllpClient.getMllpHost(), mllpClient.getMllpPort()); + template.sendBody(endpointUri, TEST_PAYLOAD); + result.assertIsSatisfied(); + + } + + /** + * This test does a proper mTLS connection with MLLP. Here the headers are asserted to be present and non-null, all + * MLLP_SSL* headers. + * + * @throws Exception if anything goes wrong and then should fail the test. + */ + @Test + void testMutalTlsInOutWithMllpConsumer() throws Exception { + result.expectedBodiesReceived(TEST_PAYLOAD); + + // Be really sure the expected headers aren't null as expectedHeaderReceived can accept null values, + // which could create false positive test results. + Assertions.assertNotNull(expectedCertIssuerName); + Assertions.assertNotNull(expectedCertSubjectName); + Assertions.assertNotNull(expectedCertNotBefore); + Assertions.assertNotNull(expectedCertNotAfter); + Assertions.assertNotNull(expectedCertSerialNo); + + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SUBJECT_NAME, expectedCertSubjectName); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_ISSUER_NAME, expectedCertIssuerName); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_SERIAL_NO, expectedCertSerialNo); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_BEFORE, expectedCertNotBefore); + result.expectedHeaderReceived(MllpConstants.MLLP_SSL_CLIENT_CERT_NOT_AFTER, expectedCertNotAfter); + + String endpointUri = String.format("mllp://%s:%d?sslContextParameters=#sslContextParametersWantsClientAuthentication", + mllpClient.getMllpHost(), mllpClient.getMllpPort()); + template.sendBody(endpointUri, TEST_PAYLOAD); + result.assertIsSatisfied(); + } +} diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MllpEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MllpEndpointBuilderFactory.java index e2170af38eef3..7c78896d1ce6b 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MllpEndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MllpEndpointBuilderFactory.java @@ -2096,6 +2096,66 @@ public String mllpLocalAddress() { public String mllpRemoteAddress() { return "CamelMllpRemoteAddress"; } + /** + * The SSL client certificate subject name. + * + * The option is a: {@code String} type. + * + * Group: consumer + * + * @return the name of the header {@code MllpSslClientCertSubjectName}. + */ + public String mllpSslClientCertSubjectName() { + return "CamelMllpSslClientCertSubjectName"; + } + /** + * The SSL client certificate issuer name. + * + * The option is a: {@code String} type. + * + * Group: consumer + * + * @return the name of the header {@code MllpSslClientCertIssuerName}. + */ + public String mllpSslClientCertIssuerName() { + return "CamelMllpSslClientCertIssuerName"; + } + /** + * The SSL client certificate serial number. + * + * The option is a: {@code String} type. + * + * Group: consumer + * + * @return the name of the header {@code MllpSslClientCertSerialNo}. + */ + public String mllpSslClientCertSerialNo() { + return "CamelMllpSslClientCertSerialNo"; + } + /** + * The SSL client certificate not before. + * + * The option is a: {@code String} type. + * + * Group: consumer + * + * @return the name of the header {@code MllpSslClientCertNotBefore}. + */ + public String mllpSslClientCertNotBefore() { + return "CamelMllpSslClientCertNotBefore"; + } + /** + * The SSL client certificate not after. + * + * The option is a: {@code String} type. + * + * Group: consumer + * + * @return the name of the header {@code MllpSslClientCertNotAfter}. + */ + public String mllpSslClientCertNotAfter() { + return "CamelMllpSslClientCertNotAfter"; + } /** * The HL7 Acknowledgment received in bytes. *