All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.erasmuswithoutpaper.registryclient.CatalogueFetcher Maven / Gradle / Ivy

The newest version!
package eu.erasmuswithoutpaper.registryclient;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.Date;

/**
 * Provides a raw <catalogue> HTTP response, as specified in the
 * Registry API.
 *
 * 

* Classes implementing this interface are able to acquire the catalogue response from the Registry * Service. We provide a default implementation of this interface called * {@link DefaultCatalogueFetcher}, but sometimes you might want to provide your own implementation, * for example when running unit tests. *

* * @see DefaultCatalogueFetcher * @see ClientImplOptions#setCatalogueFetcher(CatalogueFetcher) * @since 1.0.0 */ public interface CatalogueFetcher { /** * Represents a HTTP 200 Registry catalogue response. * * @since 1.0.0 */ class Http200RegistryResponse extends RegistryResponse { /** * Thrown by {@link Http200RegistryResponse#deserialize(byte[])} when the raw data could not be * deserialized into a valid {@link Http200RegistryResponse} object. */ static class CouldNotDeserialize extends Exception { private static final long serialVersionUID = -3124583265761204268L; } /** * Deserialize an object from a raw byte array. (Used for persistent caching of the catalogue * response.) */ static Http200RegistryResponse deserialize(byte[] raw) throws CouldNotDeserialize { try { try { ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(raw)); int version = in.readInt(); if (version != 1) { throw new CouldNotDeserialize(); } Date expires = (Date) in.readObject(); byte[] content = (byte[]) in.readObject(); String etag = (String) in.readObject(); return new Http200RegistryResponse(content, etag, expires); } catch (StreamCorruptedException | ClassNotFoundException e) { throw new CouldNotDeserialize(); } } catch (IOException e) { throw new RuntimeException(e); } } private final byte[] content; private final String etag; /** * @param content The response body (raw XML data). * @param etag The value of the HTTP ETag header received with the response, or null if * no ETag was present. * @param expires The value of the HTTP Expires header received with the response, or * null if no Expires header was present. Implementations are allowed to "deduce" * a proper Expires value from other HTTP headers (i.e. Cache-Control header). */ public Http200RegistryResponse(byte[] content, String etag, Date expires) { super(expires); this.content = content.clone(); this.etag = etag; } byte[] getContent() { return content; } String getETag() { return etag; } /** * Serialize this object. (Used for persistent caching of the catalogue response.) */ byte[] serialize() { try { ByteArrayOutputStream data = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(data); out.writeInt(1); // version out.writeObject(this.getExpires()); out.writeObject(this.getContent()); out.writeObject(this.getETag()); return data.toByteArray(); } catch (IOException e) { throw new RuntimeException(e); } } } /** * Represents a HTTP 304 Registry catalogue response. * * @since 1.0.0 */ class Http304RegistryResponse extends RegistryResponse { /** * @param expires value of the HTTP Expires header received with the response. */ protected Http304RegistryResponse(Date expires) { super(expires); } } /** * A common base for both Registry catalogue responses. ({@link Http200RegistryResponse} and * {@link Http304RegistryResponse}.) * * @since 1.0.0 */ abstract class RegistryResponse { private final Date expires; /** * @param expires The value of the HTTP Expires header received with the response. */ RegistryResponse(Date expires) { this.expires = expires; } /** * @return as described in {@link #RegistryResponse(Date)}. */ Date getExpires() { if (this.expires != null) { return new Date(this.expires.getTime()); } else { return null; } } } /** * Fetch the catalogue from the Registry Service, or confirm that it didn't change. * *

* Implementations are strongly advised to include the attached ETag value in their * If-None-Match HTTP header when making the request to the Registry API. * {@link ClientImpl} is interested in just two types of Registry API responses: *

* *
    *
  • If HTTP 200 is received, then this method must return an {@link Http200RegistryResponse} * object.
  • *
  • If HTTP 304 is received, then this method must return an {@link Http304RegistryResponse} * object.
  • *
  • If any other type of response is received from the Registry API, or the Registry API cannot * be contacted, then this method must throw an {@link IOException}.
  • *
* * @param etag String or null. If not null, then it should contain the ETag value to * be used in the If-None-Match request header (the ETag representing the * version of the catalogue which we currently possess). If null, then this method * will not use the If-None-Match header (and will therefore be expected to * return an {@link Http200RegistryResponse}). * @return Either {@link Http200RegistryResponse} or {@link Http304RegistryResponse} object. * @throws IOException if Registry API could not be contacted, or it has responded with a HTTP * status different than 200 and 304. */ RegistryResponse fetchCatalogue(String etag) throws IOException; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy