eu.erasmuswithoutpaper.registryclient.DefaultCatalogueFetcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ewp-registry-client Show documentation
Show all versions of ewp-registry-client Show documentation
Allows to run queries on EWP (Erasmus Without Paper) Registry Service.
package eu.erasmuswithoutpaper.registryclient;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import javax.net.ssl.HttpsURLConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A {@link CatalogueFetcher} which retrieves its <catalogue>
response directly
* from the Registry Service.
*
*
* This default implementation will be used by the {@link ClientImpl} unless a custom implementation
* will be set via {@link ClientImplOptions#setCatalogueFetcher(CatalogueFetcher)} method.
*
*
* @since 1.0.0
*/
public class DefaultCatalogueFetcher implements CatalogueFetcher {
private static final Logger logger = LoggerFactory.getLogger(DefaultCatalogueFetcher.class);
private static byte[] readEntireStream(InputStream is) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nread;
byte[] data = new byte[16384];
while ((nread = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nread);
}
buffer.flush();
return buffer.toByteArray();
}
private final String registryDomain;
/**
* Initialize with the default (official) Registry Service (
* registry.erasmuswithoutpaper.eu
).
*/
public DefaultCatalogueFetcher() {
this.registryDomain = "registry.erasmuswithoutpaper.eu";
}
/**
* Allows you to use an alternate installation of the Registry Service.
*
*
* In particular, during the development you might want to use
* dev-registry.erasmuswithoutpaper.eu
.
*
*
* @param customRegistryDomain domain name at which an alternate Registry Service installation has
* been set up.
* @since 1.1.0
*/
public DefaultCatalogueFetcher(String customRegistryDomain) {
this.registryDomain = customRegistryDomain;
}
@Override
public RegistryResponse fetchCatalogue(String previousETag) throws IOException {
URL url;
try {
url = new URL("https://" + this.registryDomain + "/catalogue-v1.xml");
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
logger.debug("Opening HTTPS connection to " + url);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setAllowUserInteraction(false);
conn.setRequestProperty("If-None-Match", previousETag);
conn.connect();
int status = conn.getResponseCode();
logger.debug("Registry API responded with HTTP " + status);
/* Adjust the value of "Expires" for the difference in server and client times. */
long clientTimeNow = System.currentTimeMillis();
long serverTimeNow = conn.getHeaderFieldDate("Date", clientTimeNow);
long difference = serverTimeNow - clientTimeNow;
if (Math.abs(difference) > 60000) {
logger.debug("Difference in server-client time is " + difference + "ms");
}
long serverTimeExpires = conn.getHeaderFieldDate("Expires", clientTimeNow + 300000);
Date expires = new Date(clientTimeNow + (serverTimeExpires - serverTimeNow));
logger.debug("Effective expiry time: " + expires);
switch (status) {
case 200:
String newETag = conn.getHeaderField("ETag");
byte[] content = readEntireStream(conn.getInputStream());
logger.debug("Read " + content.length + " bytes with ETag " + newETag);
return new Http200RegistryResponse(content, newETag, expires);
case 304:
return new Http304RegistryResponse(expires);
default:
throw new IOException("Unexpected Registry API response status: " + status);
}
}
}