/*
* Copyright 2010-2017 Norwegian Agency for Public Management and eGovernment (Difi)
*
* Licensed under the EUPL, Version 1.1 or – as soon they
* will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
*
* You may not use this work except in compliance with the Licence.
*
* You may obtain a copy of the Licence at:
*
* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
*
* Unless required by applicable law or agreed to in
* writing, software distributed under the Licence is
* distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the Licence for the specific language governing
* permissions and limitations under the Licence.
*/
package eu.peppol.outbound;
import no.difi.oxalis.api.lang.OxalisException;
import no.difi.oxalis.api.lang.OxalisTransmissionException;
import no.difi.oxalis.api.outbound.TransmissionRequest;
import no.difi.oxalis.api.outbound.TransmissionResponse;
import no.difi.oxalis.api.outbound.Transmitter;
import no.difi.oxalis.commons.config.ConfigModule;
import no.difi.oxalis.commons.filesystem.FileSystemModule;
import no.difi.oxalis.commons.security.CertificateModule;
import no.difi.oxalis.outbound.OxalisOutboundComponent;
import no.difi.oxalis.outbound.transmission.TransmissionRequestBuilder;
import no.difi.oxalis.test.identifier.WellKnownParticipant;
import no.difi.vefa.peppol.common.model.Endpoint;
import no.difi.vefa.peppol.common.model.TransportProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Locale;
import static org.testng.Assert.*;
/**
* @author steinar
* @author thore
*/
@Guice(modules = {CertificateModule.class, ConfigModule.class, FileSystemModule.class})
public class SendSampleInvoiceTestIT {
public static final Logger log = LoggerFactory.getLogger(SendSampleInvoiceTestIT.class);
public static final String PEPPOL_BIS_INVOICE_SBDH_XML = "peppol-bis-invoice-sbdh.xml";
public static final String EHF_WITH_SBDH = "BII04_T10_EHF-v1.5_invoice_with_sbdh.xml";
private OxalisOutboundComponent oxalisOutboundComponent;
private TransmissionRequestBuilder builder;
private X509Certificate certificate;
@BeforeMethod
public void setUp() {
oxalisOutboundComponent = new OxalisOutboundComponent();
builder = oxalisOutboundComponent.getTransmissionRequestBuilder();
builder.setTransmissionBuilderOverride(true);
certificate = oxalisOutboundComponent.getInjector().getInstance(X509Certificate.class);
}
/**
* This test was written to recreate the SSL problems experienced by ESPAP in order to supply a more informative
* exception.
*
* @throws MalformedURLException
* @throws OxalisTransmissionException
*/
@Test(groups = {"manual"})
public void sendToEspapWithSSLProblems() throws MalformedURLException, OxalisException {
InputStream is = getClass().getClassLoader().getResourceAsStream(PEPPOL_BIS_INVOICE_SBDH_XML);
assertNotNull(is, "Unable to locate peppol-bis-invoice-sbdh.sml in class path");
assertNotNull(oxalisOutboundComponent);
assertNotNull(builder);
// Build the payload
builder.payLoad(is);
// Overrides the end point address, thus preventing a SMP lookup
builder.overrideAs2Endpoint(Endpoint.of(
TransportProfile.AS2_1_0, URI.create("https://ap1.espap.pt/oxalis/as2"), null));
// Builds our transmission request
TransmissionRequest transmissionRequest = builder.build();
// Gets a transmitter, which will be used to execute our transmission request
Transmitter transmitter = oxalisOutboundComponent.getTransmitter();
// Transmits our transmission request
transmitter.transmit(transmissionRequest);
}
@Test
public void sendSingleInvoiceToLocalEndPointUsingAS2() throws Exception {
InputStream is = getClass().getClassLoader().getResourceAsStream(PEPPOL_BIS_INVOICE_SBDH_XML);
assertNotNull(is, "Unable to locate peppol-bis-invoice-sbdh.sml in class path");
assertNotNull(oxalisOutboundComponent);
assertNotNull(builder);
// Build the payload
builder.payLoad(is);
// Overrides the end point address, thus preventing a SMP lookup
builder.overrideAs2Endpoint(Endpoint.of(
TransportProfile.AS2_1_0, URI.create(IntegrationTestConstant.OXALIS_AS2_URL), certificate));
// Builds our transmission request
TransmissionRequest transmissionRequest = builder.build();
// Gets a transmitter, which will be used to execute our transmission request
Transmitter transmitter = oxalisOutboundComponent.getTransmitter();
// Transmits our transmission request
TransmissionResponse transmissionResponse = transmitter.transmit(transmissionRequest);
assertNotNull(transmissionResponse);
assertNotNull(transmissionResponse.getTransmissionIdentifier());
assertNotNull(transmissionResponse.getHeader());
assertEquals(transmissionResponse.getHeader().getReceiver(), WellKnownParticipant.DIFI_TEST);
assertEquals(transmissionResponse.getEndpoint().getAddress().toString(),
IntegrationTestConstant.OXALIS_AS2_URL);
assertEquals(transmissionResponse.getProtocol(), TransportProfile.AS2_1_0);
}
/**
* Verify that we can deliver AS2 message with pre-wrapped SBDH.
*/
@Test()
public void sendSingleInvoiceWithSbdhToLocalEndPointUsingAS2() throws Exception {
InputStream is = SendSampleInvoiceTestIT.class.getClassLoader().getResourceAsStream(EHF_WITH_SBDH);
assertNotNull(is, "Unable to locate peppol-bis-invoice-sbdh.sml in class path");
assertNotNull(oxalisOutboundComponent);
assertNotNull(builder);
// Build the payload
builder.payLoad(is);
// Overrides the end point address, thus preventing a SMP lookup
builder.overrideAs2Endpoint(Endpoint.of(
TransportProfile.AS2_1_0, URI.create(IntegrationTestConstant.OXALIS_AS2_URL), certificate));
// Builds our transmission request
TransmissionRequest transmissionRequest = builder.build();
// Gets a transmitter, which will be used to execute our transmission request
Transmitter transmitter = oxalisOutboundComponent.getTransmitter();
// Transmits our transmission request
TransmissionResponse transmissionResponse = transmitter.transmit(transmissionRequest);
assertNotNull(transmissionResponse);
assertNotNull(transmissionResponse.getTransmissionIdentifier());
assertNotNull(transmissionResponse.getHeader());
assertEquals(transmissionResponse.getHeader().getReceiver(), WellKnownParticipant.DIFI_TEST);
assertEquals(transmissionResponse.getEndpoint().getAddress(),
URI.create(IntegrationTestConstant.OXALIS_AS2_URL));
assertEquals(transmissionResponse.getProtocol(), TransportProfile.AS2_1_0);
assertNotEquals(transmissionResponse.getHeader().getIdentifier(),
transmissionResponse.getTransmissionIdentifier().getIdentifier());
// Make sure we got the correct CreationDateAndTime from the SBDH : "2014-11-01T16:32:48.128+01:00"
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
assertEquals(sdf.format(transmissionResponse.getHeader().getCreationTimestamp()), "2014-11-01 16:32:48");
}
/**
* Verifies that we can run several transmission tasks in parallell.
*
* @throws Exception
*/
@Test
public void sendWithMultipleThreads() throws Exception {
final int MAX_THREADS = 5;
Thread[] threads = new Thread[MAX_THREADS];
SenderTask[] senderTasks = new SenderTask[MAX_THREADS];
for (int i = 0; i < MAX_THREADS; i++) {
senderTasks[i] = new SenderTask(i, certificate);
threads[i] = new Thread(senderTasks[i], "Thread " + i);
threads[i].start();
}
Thread.sleep(20 * 1000); // Wait for 10 seconds to allow worker threads to complete
for (int i = 0; i < MAX_THREADS; i++) {
boolean alive = threads[i].isAlive();
threads[i].isInterrupted();
threads[i].join(1000); // Allows transmissions to complete before we exit
boolean actual = senderTasks[i].hasCompletedTransmission();
assertTrue(actual, "SenderTask " + i + " has not completed");
}
long accumulatedElapsedTime = 0;
for (int i = 0; i < MAX_THREADS; i++) {
accumulatedElapsedTime += senderTasks[i].getElapsedTime();
}
long averageTime = accumulatedElapsedTime / MAX_THREADS;
log.debug("Average transmission time " + averageTime + "ms");
assertTrue(averageTime < 8000, "Average transmission time was " + averageTime +
" should be less than 2000ms. Do you have a slow machine?");
}
/**
* Class suitable for running several transmission threads in paralell.
*/
static class SenderTask implements Runnable {
private final int threadNumber;
private boolean transmissionCompleted = false;
private long elapsedTime;
private X509Certificate certificate;
private OxalisOutboundComponent oxalisOutboundComponent;
public SenderTask(int threadNumber, X509Certificate certificate) {
this.threadNumber = threadNumber;
this.certificate = certificate;
oxalisOutboundComponent = new OxalisOutboundComponent();
}
public long getElapsedTime() {
return elapsedTime;
}
public boolean hasCompletedTransmission() {
return transmissionCompleted;
}
@Override
public void run() {
try {
log.debug(threadNumber + " fetching resourcestream");
InputStream is = SendSampleInvoiceTestIT.class.getClassLoader().getResourceAsStream(EHF_WITH_SBDH);
assertNotNull(is, "Unable to locate peppol-bis-invoice-sbdh.sml in class path");
TransmissionRequestBuilder builder = oxalisOutboundComponent.getTransmissionRequestBuilder();
assertNotNull(builder);
log.debug(threadNumber + " loading inputdata..");
// Build the payload
builder.payLoad(is);
// Overrides the end point address, thus preventing a SMP lookup
builder.overrideAs2Endpoint(Endpoint.of(
TransportProfile.AS2_1_0, URI.create(IntegrationTestConstant.OXALIS_AS2_URL), certificate));
log.debug(threadNumber + " building transmission request...");
// Builds our transmission request
TransmissionRequest transmissionRequest = builder.build();
log.debug(threadNumber + " retrieving a transmitter....");
// Gets a transmitter, which will be used to execute our transmission request
Transmitter transmitter = oxalisOutboundComponent.getTransmitter();
log.debug(threadNumber + " performing transmission ...");
long transmissionStart = System.currentTimeMillis();
// Transmits our transmission request
TransmissionResponse transmissionResponse = null;
try {
transmissionResponse = transmitter.transmit(transmissionRequest);
} catch (OxalisTransmissionException e) {
throw new IllegalStateException(e);
}
long transmissionFinished = System.currentTimeMillis();
// Calculates the elapsed time
elapsedTime = transmissionFinished - transmissionStart;
// Report that transmission was completed OK
transmissionCompleted = true;
assertNotNull(transmissionResponse);
assertNotNull(transmissionResponse.getTransmissionIdentifier());
assertNotNull(transmissionResponse.getHeader());
assertEquals(transmissionResponse.getHeader().getReceiver(), WellKnownParticipant.DIFI_TEST);
assertEquals(transmissionResponse.getEndpoint().getAddress().toString(),
IntegrationTestConstant.OXALIS_AS2_URL);
assertEquals(transmissionResponse.getProtocol(), TransportProfile.AS2_1_0);
assertNotEquals(transmissionResponse.getHeader().getIdentifier().getIdentifier(),
transmissionResponse.getTransmissionIdentifier().getIdentifier());
// Make sure we got the correct CreationDateAndTime from the SBDH : "2014-11-01T16:32:48.128+01:00"
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
assertEquals(sdf.format(transmissionResponse.getHeader().getCreationTimestamp()),
"2014-11-01 16:32:48");
log.debug(threadNumber + " transmission complete...");
} catch (OxalisException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
}
}