diff --git a/pom.xml b/pom.xml
index 11e4132..a9b84f9 100755
--- a/pom.xml
+++ b/pom.xml
@@ -28,11 +28,11 @@
no.difi.oxalis
oxalis
- 4.1.1
+ 4.1.2
oxalis-as4
- 4.1.7
+ 4.1.8-SNAPSHOT
jar
diff --git a/src/main/java/no/difi/oxalis/as4/common/As4CommonModule.java b/src/main/java/no/difi/oxalis/as4/common/As4CommonModule.java
index a8c7fe0..7161519 100644
--- a/src/main/java/no/difi/oxalis/as4/common/As4CommonModule.java
+++ b/src/main/java/no/difi/oxalis/as4/common/As4CommonModule.java
@@ -42,9 +42,7 @@
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.wss4j.dom.engine.WSSConfig;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import java.security.Provider;
import java.security.Security;
import static no.difi.oxalis.as4.common.AS4Constants.*;
@@ -64,14 +62,8 @@ protected void configure() {
new OxalisAlgorithmSuiteLoader(bus);
BusFactory.setThreadDefaultBus(bus);
+ Security.setProperty("jdk.security.provider.preferred", "AES/GCM/NoPadding:BC");
WSSConfig.init();
-
- // Make sure that BouncyCastle is the preferred security provider
- final Provider[] providers = Security.getProviders();
- if (providers != null && providers.length > 0)
- Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
- log.debug("Registering BouncyCastle as preferred Java security provider");
- Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
@Provides
diff --git a/src/main/java/no/difi/oxalis/as4/inbound/SetPolicyInInterceptor.java b/src/main/java/no/difi/oxalis/as4/inbound/SetPolicyInInterceptor.java
index c5fad4a..62c8f89 100644
--- a/src/main/java/no/difi/oxalis/as4/inbound/SetPolicyInInterceptor.java
+++ b/src/main/java/no/difi/oxalis/as4/inbound/SetPolicyInInterceptor.java
@@ -6,7 +6,6 @@
import no.difi.oxalis.as4.util.PolicyService;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.ws.policy.PolicyInInterceptor;
-import org.apache.cxf.ws.policy.PolicyOutInterceptor;
@Slf4j
@Singleton
diff --git a/src/main/java/no/difi/oxalis/as4/outbound/As4MessageSender.java b/src/main/java/no/difi/oxalis/as4/outbound/As4MessageSender.java
index e481215..694a5b7 100644
--- a/src/main/java/no/difi/oxalis/as4/outbound/As4MessageSender.java
+++ b/src/main/java/no/difi/oxalis/as4/outbound/As4MessageSender.java
@@ -1,6 +1,7 @@
package no.difi.oxalis.as4.outbound;
import com.google.inject.Inject;
+import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import no.difi.oxalis.api.outbound.TransmissionRequest;
import no.difi.oxalis.api.outbound.TransmissionResponse;
@@ -37,6 +38,7 @@
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import java.io.IOException;
+import java.io.InputStream;
import java.util.*;
import static no.difi.oxalis.as4.common.AS4Constants.CEF_CONFORMANCE;
@@ -75,8 +77,10 @@ public As4MessageSender(MessagingProvider messagingProvider, MessageIdGenerator
}
public TransmissionResponse send(TransmissionRequest request) throws OxalisAs4TransmissionException {
+ AttachmentHolder attachmentHolder = null;
try (DispatchImpl dispatch = createDispatch(request)) {
- Collection attachments = prepareAttachments(request);
+ attachmentHolder = prepareAttachment(request);
+ ArrayList attachments = new ArrayList<>(Collections.singletonList(attachmentHolder.attachment));
dispatch.getRequestContext().put(Message.ATTACHMENTS, attachments);
Messaging messaging = messagingProvider.createMessagingHeader(request, attachments);
@@ -85,6 +89,14 @@ public TransmissionResponse send(TransmissionRequest request) throws OxalisAs4Tr
return invoke(request, dispatch);
} catch (IOException e) {
throw new OxalisAs4TransmissionException("Failed to send message", e);
+ } finally {
+ if (attachmentHolder != null) {
+ try {
+ attachmentHolder.inputStream.close();
+ } catch (IOException e) {
+ log.error("Couldn't close attachment input stream", e);
+ }
+ }
}
}
@@ -119,7 +131,7 @@ private void configureSecurity(TransmissionRequest request, Dispatch prepareAttachments(TransmissionRequest request) throws OxalisAs4TransmissionException {
+ public AttachmentHolder prepareAttachment(TransmissionRequest request) throws OxalisAs4TransmissionException {
Map> headers = new HashMap<>();
headers.put("Content-ID", Collections.singletonList(getContentID(request)));
@@ -127,8 +139,10 @@ public Collection prepareAttachments(TransmissionRequest request) th
headers.put("MimeType", Collections.singletonList("application/xml"));
try {
- Attachment attachment = AttachmentUtil.createAttachment(compressionUtil.getCompressedStream(request.getPayload()), headers);
- return new ArrayList<>(Collections.singletonList(attachment));
+ InputStream compressedStream = compressionUtil.getCompressedStream(request.getPayload());
+ Attachment attachment = AttachmentUtil.createAttachment(compressedStream, headers);
+
+ return new AttachmentHolder(compressedStream, attachment);
} catch (IOException e) {
throw new OxalisAs4TransmissionException("Unable to compress payload", e);
}
@@ -179,4 +193,10 @@ private Service getService(TransmissionRequest request) throws OxalisAs4Transmis
service.addPort(PORT_NAME, SOAPBinding.SOAP12HTTP_BINDING, request.getEndpoint().getAddress().toString());
return service;
}
+
+ @RequiredArgsConstructor
+ private static class AttachmentHolder {
+ private final InputStream inputStream;
+ private final Attachment attachment;
+ }
}
diff --git a/src/main/java/no/difi/oxalis/as4/util/CompressionUtil.java b/src/main/java/no/difi/oxalis/as4/util/CompressionUtil.java
index 6a000ed..0f85a26 100644
--- a/src/main/java/no/difi/oxalis/as4/util/CompressionUtil.java
+++ b/src/main/java/no/difi/oxalis/as4/util/CompressionUtil.java
@@ -1,21 +1,14 @@
package no.difi.oxalis.as4.util;
-import com.google.inject.Inject;
-import org.apache.commons.io.IOUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.io.CacheSizeExceededException;
+import org.apache.cxf.io.CachedOutputStream;
-import javax.inject.Named;
-import java.io.*;
-import java.util.concurrent.ExecutorService;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.zip.GZIPOutputStream;
-// https://stackoverflow.com/a/24673254
public class CompressionUtil {
- private final ExecutorService pool;
-
- @Inject
- public CompressionUtil(@Named("compression-pool") ExecutorService executorService) {
- this.pool = executorService;
- }
/**
* Gets Compressed Stream for given input Stream
@@ -30,27 +23,16 @@ public InputStream getCompressedStream(final InputStream sourceStream) throws IO
throw new IllegalArgumentException("Source Stream cannot be NULL");
}
- final PipedInputStream resultStream = new PipedInputStream();
- final PipedOutputStream intermediateStream = new PipedOutputStream(resultStream);
- final OutputStream zipperOutStream = new GZIPOutputStream(intermediateStream);
-
- Runnable copyTask = () -> {
- try {
- IOUtils.copy(sourceStream, zipperOutStream);
- zipperOutStream.flush();
- } catch (IOException e) {
- IOUtils.closeQuietly(resultStream); // close it on error case only
- throw new RuntimeException(e);
- } finally {
- // close source stream and intermediate streams
- IOUtils.closeQuietly(sourceStream);
- IOUtils.closeQuietly(zipperOutStream);
- IOUtils.closeQuietly(intermediateStream);
- }
- };
+ CachedOutputStream cache = new CachedOutputStream();
- pool.submit(copyTask);
-
- return resultStream;
+ try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(cache)) {
+ IOUtils.copyAndCloseInput(sourceStream, gzipOutputStream);
+ gzipOutputStream.flush();
+ gzipOutputStream.finish();
+ return cache.getInputStream();
+ } catch (CacheSizeExceededException | IOException cee) {
+ sourceStream.close();
+ throw cee;
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/no/difi/oxalis/as4/util/Constants.java b/src/main/java/no/difi/oxalis/as4/util/Constants.java
index f37b839..e8182dd 100755
--- a/src/main/java/no/difi/oxalis/as4/util/Constants.java
+++ b/src/main/java/no/difi/oxalis/as4/util/Constants.java
@@ -1,18 +1,20 @@
package no.difi.oxalis.as4.util;
+import lombok.experimental.UtilityClass;
+
import javax.xml.namespace.QName;
-public interface Constants {
+@UtilityClass
+public class Constants {
- String EBMS_NAMESPACE = "http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/";
+ public static final String EBMS_NAMESPACE = "http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/";
- QName MESSAGING_QNAME = new QName(EBMS_NAMESPACE, "Messaging", "eb");
- QName USER_MESSAGE_QNAME = new QName(EBMS_NAMESPACE, "UserMessage");
- QName SIGNAL_MESSAGE_QNAME = new QName(EBMS_NAMESPACE, "SignalMessage");
+ public static final QName MESSAGING_QNAME = new QName(EBMS_NAMESPACE, "Messaging", "eb");
+ public static final QName USER_MESSAGE_QNAME = new QName(EBMS_NAMESPACE, "UserMessage");
+ public static final QName SIGNAL_MESSAGE_QNAME = new QName(EBMS_NAMESPACE, "SignalMessage");
- String RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
- String DIGEST_ALGORITHM_SHA256 = "sha256";
+ public static final String DIGEST_ALGORITHM_SHA256 = "sha256";
- String TEST_SERVICE = "http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/service";
- String TEST_ACTION = "http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/test";
+ public static final String TEST_SERVICE = "http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/service";
+ public static final String TEST_ACTION = "http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/test";
}
diff --git a/src/main/java/no/difi/oxalis/as4/util/GeneralUtils.java b/src/main/java/no/difi/oxalis/as4/util/GeneralUtils.java
index f99a18c..1d3a36f 100644
--- a/src/main/java/no/difi/oxalis/as4/util/GeneralUtils.java
+++ b/src/main/java/no/difi/oxalis/as4/util/GeneralUtils.java
@@ -1,13 +1,16 @@
package no.difi.oxalis.as4.util;
+import lombok.experimental.UtilityClass;
+
import java.util.Iterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+@UtilityClass
public class GeneralUtils {
- public static Stream iteratorToStreamOfUnknownSize(Iterator iterator, int characteristics, boolean parallel){
+ public static Stream iteratorToStreamOfUnknownSize(Iterator iterator, int characteristics, boolean parallel) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iterator, characteristics),
parallel);
diff --git a/src/main/java/no/difi/oxalis/as4/util/PeppolConfiguration.java b/src/main/java/no/difi/oxalis/as4/util/PeppolConfiguration.java
index 629448f..f4bc793 100644
--- a/src/main/java/no/difi/oxalis/as4/util/PeppolConfiguration.java
+++ b/src/main/java/no/difi/oxalis/as4/util/PeppolConfiguration.java
@@ -2,16 +2,18 @@
import lombok.Getter;
import no.difi.oxalis.api.tag.Tag;
-import org.apache.wss4j.dom.handler.WSHandlerConstants;
import java.util.Arrays;
import java.util.List;
+import static org.apache.wss4j.dom.handler.WSHandlerConstants.ENCRYPT;
+import static org.apache.wss4j.dom.handler.WSHandlerConstants.SIGNATURE;
+
@Getter
public class PeppolConfiguration implements Tag {
public static final String IDENTIFIER = "AS4.OUTBOUND.PEPPOL";
- private List actions = Arrays.asList(WSHandlerConstants.SIGNATURE, WSHandlerConstants.ENCRYPT);
+ private List actions = Arrays.asList(SIGNATURE, ENCRYPT);
private String partyIDType = "urn:fdc:peppol.eu:2017:identifiers:ap";
private String agreementRef = "urn:fdc:peppol.eu:2017:agreements:tia:ap_provider";
diff --git a/src/main/java/no/difi/oxalis/as4/util/SOAPHeaderParser.java b/src/main/java/no/difi/oxalis/as4/util/SOAPHeaderParser.java
index ceffdc8..22569a9 100644
--- a/src/main/java/no/difi/oxalis/as4/util/SOAPHeaderParser.java
+++ b/src/main/java/no/difi/oxalis/as4/util/SOAPHeaderParser.java
@@ -1,6 +1,7 @@
package no.difi.oxalis.as4.util;
import com.google.common.collect.Lists;
+import lombok.experimental.UtilityClass;
import no.difi.oxalis.as4.lang.OxalisAs4Exception;
import org.oasis_open.docs.ebxml_msg.ebms.v3_0.ns.core._200704.Messaging;
import org.oasis_open.docs.ebxml_msg.ebms.v3_0.ns.core._200704.UserMessage;
@@ -22,6 +23,7 @@
import java.util.Collections;
import java.util.List;
+@UtilityClass
public class SOAPHeaderParser {
private static final String NS_ALL = "*";
diff --git a/src/main/java/no/difi/oxalis/as4/util/XMLUtil.java b/src/main/java/no/difi/oxalis/as4/util/XMLUtil.java
index bddcfc0..9997a18 100644
--- a/src/main/java/no/difi/oxalis/as4/util/XMLUtil.java
+++ b/src/main/java/no/difi/oxalis/as4/util/XMLUtil.java
@@ -1,5 +1,6 @@
package no.difi.oxalis.as4.util;
+import lombok.experimental.UtilityClass;
import no.difi.oxalis.as4.lang.OxalisAs4Exception;
import javax.xml.datatype.DatatypeConfigurationException;
@@ -8,15 +9,16 @@
import java.util.Date;
import java.util.GregorianCalendar;
+@UtilityClass
public class XMLUtil {
- public static XMLGregorianCalendar dateToXMLGeorgianCalendar(Date date) throws OxalisAs4Exception{
+ public static XMLGregorianCalendar dateToXMLGeorgianCalendar(Date date) throws OxalisAs4Exception {
try {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(date);
return DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
- }catch (DatatypeConfigurationException e){
+ } catch (DatatypeConfigurationException e) {
throw new OxalisAs4Exception("Unable to convert timestamp to XML", e);
}
}
diff --git a/src/test/java/no/difi/oxalis/as4/util/CompressionUtilTest.java b/src/test/java/no/difi/oxalis/as4/util/CompressionUtilTest.java
index 7e9659f..d1b2c60 100644
--- a/src/test/java/no/difi/oxalis/as4/util/CompressionUtilTest.java
+++ b/src/test/java/no/difi/oxalis/as4/util/CompressionUtilTest.java
@@ -6,26 +6,30 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import java.util.Random;
import java.util.zip.GZIPInputStream;
public class CompressionUtilTest {
- static final String DATA = "Lorem ipsum dolor sit amet";
-
@Test
- public void simple() throws Exception{
- InputStream sourceStream = new ByteArrayInputStream(DATA.getBytes());
- ExecutorService executor = Executors.newSingleThreadExecutor();
-
- InputStream compressedStream = new CompressionUtil(executor).getCompressedStream(sourceStream);
-
- GZIPInputStream decompressedStream = new GZIPInputStream(compressedStream);
- List lines = IOUtils.readLines(decompressedStream, Charset.defaultCharset());
+ public void simple() throws Exception {
+ byte[] before = "Lorem ipsum dolor sit amet".getBytes();
+ InputStream sourceStream = new ByteArrayInputStream(before);
+ InputStream compressedStream = new CompressionUtil().getCompressedStream(sourceStream);
+ try (GZIPInputStream decompressedStream = new GZIPInputStream(compressedStream)) {
+ byte[] after = IOUtils.toByteArray(decompressedStream);
+ Assert.assertEquals(before, after);
+ }
+ }
- Assert.assertEquals(1, lines.size());
- Assert.assertEquals(DATA, lines.get(0));
+ @Test
+ public void cachedInTempFile() throws Exception {
+ byte[] before = new byte[1024 * 1024];
+ new Random().nextBytes(before);
+ InputStream sourceStream = new ByteArrayInputStream(before);
+ InputStream compressedStream = new CompressionUtil().getCompressedStream(sourceStream);
+ try (GZIPInputStream decompressedStream = new GZIPInputStream(compressedStream)) {
+ byte[] after = IOUtils.toByteArray(decompressedStream);
+ Assert.assertEquals(before, after);
+ }
}
}