no.difi.vefa.peppol.lookup.reader.BusdoxReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of peppol-lookup Show documentation
Show all versions of peppol-lookup Show documentation
Library for lookup in the PEPPOL infrastructure.
/*
* Copyright 2015-2017 Direktoratet for forvaltning og IKT
*
* This source code is subject to dual licensing:
*
*
* 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");
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*
* See the Licence for the specific language governing
* permissions and limitations under the Licence.
*/
package no.difi.vefa.peppol.lookup.reader;
import com.google.common.collect.Lists;
import no.difi.commons.busdox.jaxb.smp.*;
import no.difi.vefa.peppol.common.api.PerformAction;
import no.difi.vefa.peppol.common.api.PotentiallySigned;
import no.difi.vefa.peppol.common.lang.PeppolRuntimeException;
import no.difi.vefa.peppol.common.model.*;
import no.difi.vefa.peppol.common.util.ExceptionUtil;
import no.difi.vefa.peppol.lookup.api.FetcherResponse;
import no.difi.vefa.peppol.lookup.api.LookupException;
import no.difi.vefa.peppol.lookup.api.MetadataReader;
import no.difi.vefa.peppol.lookup.model.DocumentTypeIdentifierWithUri;
import no.difi.vefa.peppol.security.lang.PeppolSecurityException;
import no.difi.vefa.peppol.security.xmldsig.DomUtils;
import no.difi.vefa.peppol.security.xmldsig.XmldsigVerifier;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
public class BusdoxReader implements MetadataReader {
private static final Logger LOGGER = LoggerFactory.getLogger(BusdoxReader.class);
public static final String NAMESPACE = "http://busdox.org/serviceMetadata/publishing/1.0/";
private static JAXBContext jaxbContext;
private static CertificateFactory certificateFactory;
static {
ExceptionUtil.perform(PeppolRuntimeException.class, new PerformAction() {
@Override
public void action() throws Exception {
jaxbContext = JAXBContext.newInstance(ServiceGroupType.class, SignedServiceMetadataType.class,
ServiceMetadataType.class);
certificateFactory = CertificateFactory.getInstance("X.509");
}
});
}
@SuppressWarnings("all")
@Override
public List parseDocumentIdentifiers(FetcherResponse fetcherResponse)
throws LookupException {
try {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
ServiceGroupType serviceGroup = unmarshaller.unmarshal(
new StreamSource(fetcherResponse.getInputStream()), ServiceGroupType.class).getValue();
List documentTypeIdentifiers = new ArrayList<>();
for (ServiceMetadataReferenceType reference :
serviceGroup.getServiceMetadataReferenceCollection().getServiceMetadataReference()) {
String hrefDocumentTypeIdentifier =
URLDecoder.decode(reference.getHref(), "UTF-8").split("/services/")[1];
String[] parts = hrefDocumentTypeIdentifier.split("::", 2);
try {
documentTypeIdentifiers.add(DocumentTypeIdentifierWithUri.of(
parts[1], Scheme.of(parts[0]), URI.create(reference.getHref())));
} catch (ArrayIndexOutOfBoundsException e) {
LOGGER.warn("Unable to parse '{}'.", hrefDocumentTypeIdentifier);
}
}
return documentTypeIdentifiers;
} catch (JAXBException | UnsupportedEncodingException e) {
throw new LookupException(e.getMessage(), e);
}
}
@Override
public PotentiallySigned parseServiceMetadata(FetcherResponse fetcherResponse)
throws LookupException, PeppolSecurityException {
try {
Document doc = DomUtils.parse(fetcherResponse.getInputStream());
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement> result = (JAXBElement) unmarshaller.unmarshal(new DOMSource(doc));
Object o = result.getValue();
X509Certificate signer = null;
if (o instanceof SignedServiceMetadataType) {
signer = XmldsigVerifier.verify(doc);
o = ((SignedServiceMetadataType) o).getServiceMetadata();
}
if (!(o instanceof ServiceMetadataType))
throw new LookupException("ServiceMetadata element not found.");
ServiceInformationType serviceInformation = ((ServiceMetadataType) o).getServiceInformation();
List> processMetadatas = Lists.newArrayList();
for (ProcessType processType : serviceInformation.getProcessList().getProcess()) {
List endpoints = Lists.newArrayList();
for (EndpointType endpointType : processType.getServiceEndpointList().getEndpoint()) {
endpoints.add(Endpoint.of(
TransportProfile.of(endpointType.getTransportProfile()),
URI.create(endpointType.getEndpointReference().getAddress().getValue()),
certificateInstance(Base64.decodeBase64(endpointType.getCertificate()))
));
}
processMetadatas.add(ProcessMetadata.of(
ProcessIdentifier.of(
processType.getProcessIdentifier().getValue(),
Scheme.of(processType.getProcessIdentifier().getScheme())
),
endpoints
));
}
return Signed.of(ServiceMetadata.of(
ParticipantIdentifier.of(
serviceInformation.getParticipantIdentifier().getValue(),
Scheme.of(serviceInformation.getParticipantIdentifier().getScheme())
),
DocumentTypeIdentifier.of(
serviceInformation.getDocumentIdentifier().getValue(),
Scheme.of(serviceInformation.getDocumentIdentifier().getScheme())
),
processMetadatas
), signer);
} catch (JAXBException | CertificateException | IOException | SAXException | ParserConfigurationException e) {
throw new LookupException(e.getMessage(), e);
}
}
private X509Certificate certificateInstance(byte[] content) throws CertificateException {
return (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(content));
}
}