GDS2Util.java
/*
* Copyright (C) 2017 B3Partners B.V.
*/
package nl.b3p.gds2;
import nl.kadaster.schemas.gds2.afgifte_bestandenlijstopvragenresultaat.v20170401.BestandenlijstOpvragenResultaatType;
import nl.kadaster.schemas.gds2.afgifte_bestandenlijstresultaat.afgifte.v20170401.AfgifteType;
import nl.kadaster.schemas.gds2.imgds.baseurl.v20170401.BaseURLType;
import nl.kadaster.schemas.gds2.service.afgifte.v20170401.Gds2AfgifteServiceV20170401;
import nl.kadaster.schemas.gds2.service.afgifte_bestandenlijstopvragen.v20170401.BestandenlijstOpvragenRequest;
import nl.kadaster.schemas.gds2.service.afgifte_bestandenlijstopvragen.v20170401.BestandenlijstOpvragenResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.GregorianCalendar;
/**
* @author mprins
*/
public class GDS2Util {
private static final Log LOG = LogFactory.getLog(GDS2Util.class);
private static final String PEM_KEY_START = "-----BEGIN PRIVATE KEY-----";
private static final String PEM_KEY_END = "-----END PRIVATE KEY-----";
private static final String PEM_CERT_START = "-----BEGIN CERTIFICATE-----";
private static final String PEM_CERT_END = "-----END CERTIFICATE-----";
public static Certificate getCertificateFromPEM(String pem) throws CertificateException, UnsupportedEncodingException {
if (!pem.startsWith(PEM_CERT_START)) {
throw new IllegalArgumentException("Certificaat moet beginnen met " + PEM_CERT_START);
}
if (!pem.endsWith(PEM_CERT_END)) {
throw new IllegalArgumentException("Certificaat moet eindigen met " + PEM_CERT_END);
}
return CertificateFactory.getInstance("X509").generateCertificate(new ByteArrayInputStream(pem.getBytes("US-ASCII")));
}
public static PrivateKey getPrivateKeyFromPEM(String pem) throws NoSuchAlgorithmException, InvalidKeySpecException {
if (!pem.startsWith(PEM_KEY_START)) {
throw new IllegalArgumentException("Private key moet beginnen met " + PEM_KEY_START);
}
while (pem.endsWith("\n")) {
pem = pem.substring(0, pem.length() - 1);
}
if (!pem.endsWith(PEM_KEY_END)) {
throw new IllegalArgumentException("Private key moet eindigen met " + PEM_KEY_END);
}
pem = pem.replace(PEM_KEY_START, "").replace(PEM_KEY_END, "");
byte[] decoded = Base64.getMimeDecoder().decode(pem);
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
return kf.generatePrivate(spec);
}
/**
* vraagt de bestandenlijst op in maximaal 2 pogingen met 10000 millisec pauze.
*
* @param gds2 afgifte service
* @param request geconfigureerd verzoek
* @return opgevraagde bestanden lijst
* @see #retryBestandenLijstOpvragen(Gds2AfgifteServiceV20170401, BestandenlijstOpvragenRequest, int, long)
*/
public static BestandenlijstOpvragenResponse retryBestandenLijstOpvragen(Gds2AfgifteServiceV20170401 gds2, BestandenlijstOpvragenRequest request) throws Exception {
return retryBestandenLijstOpvragen(gds2, request, 2, 10000L);
}
/**
* vraagt de bestandenlijst op.
*
* @param gds2 afgifte service
* @param request geconfigureerd verzoek
* @param retries aantal pogingen om verzoek uit te voeren
* @param retryWait te wachten milliseconden tussen retries, wordt vermenigvuldigd met retry poging (dus periode steeds langer)
* @return opgevraagde bestanden lijst
*/
public static BestandenlijstOpvragenResponse retryBestandenLijstOpvragen(Gds2AfgifteServiceV20170401 gds2, BestandenlijstOpvragenRequest request, int retries, long retryWait) throws Exception {
int attempt = 0;
while (true) {
try {
return gds2.bestandenlijstOpvragen(request);
} catch (Exception e) {
attempt++;
if (attempt == retries) {
LOG.error("Fout bij laatste poging ophalen bestandenlijst: " + e.getClass().getName() + ": " + e.getMessage());
throw e;
} else {
LOG.warn("Fout bij poging " + attempt + " om bestandenlijst op te halen: " + e.getClass().getName() + ": " + e.getMessage());
Thread.sleep(retryWait * attempt);
LOG.info("Uitvoeren poging " + (attempt + 1) + " om bestandenlijst op te halen...");
}
}
}
}
/**
* bepaal de "certificaat" url, nodig voor BRK download met PKI.
*
* @param antwoord de url
* @return type of {@code null}
*/
public static BaseURLType getCertificaatBaseURL(BestandenlijstOpvragenResultaatType antwoord) {
for (BaseURLType type : antwoord.getBaseURLSet().getBaseURL()) {
if (type.getType().equalsIgnoreCase("certificaat")) {
return type;
}
}
return null;
}
/**
* bepaal de "anoniem" url, nodig voor BAG download zonder PKI.
*
* @param antwoord de url
* @return type of {@code null}
*/
public static BaseURLType getAnoniemBaseURL(BestandenlijstOpvragenResultaatType antwoord) {
for (BaseURLType type : antwoord.getBaseURLSet().getBaseURL()) {
if (type.getType().equalsIgnoreCase("anoniem")) {
return type;
}
}
return null;
}
/**
* bepaal de afgifte url.
*
* @param afgifte de afgifte
* @param type de base url
* @return de afgifte url
*/
public static String getAfgifteURL(AfgifteType afgifte, BaseURLType type) {
return type.getValue() + "/" + afgifte.getAfgifteID();
}
/**
* parse datum uit string.
*
* @param dateStr datum in dd-MM-yyyy formaat (evt. {@code null}
* @return datum (of {@code null} in geval van een parse fout of {@code null} argument)
*/
public static GregorianCalendar getDatumTijd(String dateStr) {
if (dateStr == null) {
return null;
}
Date date;
final DateFormat format = new SimpleDateFormat("dd-MM-yyyy");
if (dateStr.equalsIgnoreCase("nu")) {
date = new Date();
} else {
try {
date = format.parse(dateStr);
} catch (ParseException ex) {
LOG.error(ex);
return null;
}
}
GregorianCalendar gregory = new GregorianCalendar();
gregory.setTime(date);
return gregory;
}
/**
* parse datum uit string en verschuif {@code dagen}.
*
* @param refDate datum in dd-MM-yyyy formaat (niet {@code null})
* @param before aantal dagen dat de datum verschoven moet worden, bijvoorbeeld -3 voor 3 dagen eerder
* @return datum (of null in geval van een parse fout)
*/
public static GregorianCalendar getDatumTijd(String refDate, int before) {
GregorianCalendar ref = getDatumTijd(refDate);
ref.add(GregorianCalendar.DAY_OF_YEAR, before);
return ref;
}
/**
* maakt een XML datum die te gebruiken is in een "van" of "tot" criterium, houdt rekening met de juiste maand.
*
* @param year jaartal (4 cijfers, > 2000)
* @param month maand (waarde van 0 t/m 12)
* @param day dag van de maand
* @return xml datum (of null ingeval van een DatatypeConfigurationException)
*/
public static XMLGregorianCalendar getXMLDatumTijd(int year, int month, int day) {
try {
return DatatypeFactory.newInstance().newXMLGregorianCalendar(
new GregorianCalendar(
year,
month - 1 /* GregorianCalendar heeft 0-based month */,
day)
);
} catch (DatatypeConfigurationException e) {
LOG.error(e);
return null;
}
}
/**
* maakt een XML datum die te gebruiken is in een "van" of "tot" criterium.
*
* @param date datum (niet {@code null})
* @return xml datum (of null ingeval van een DatatypeConfigurationException)
*/
public static XMLGregorianCalendar getXMLDatumTijd(Date date) {
final GregorianCalendar cal = new GregorianCalendar();
cal.setTime(date);
try {
return DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
} catch (DatatypeConfigurationException e) {
LOG.error(e);
return null;
}
}
/**
* maakt een XML datum die te gebruiken is in een "van" of "tot" criterium.
*
* @param date datum (niet {@code null})
* @return xml datum (of null ingeval van een DatatypeConfigurationException)
*/
public static XMLGregorianCalendar getXMLDatumTijd(GregorianCalendar date) {
try {
return DatatypeFactory.newInstance().newXMLGregorianCalendar(date);
} catch (DatatypeConfigurationException e) {
LOG.error(e);
return null;
}
}
private GDS2Util() {
}
}