001/*
002 * acme4j - Java ACME client
003 *
004 * Copyright (C) 2015 Richard "Shred" Körber
005 *   http://acme4j.shredzone.org
006 *
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
013 */
014package org.shredzone.acme4j.exception;
015
016import java.net.URL;
017import java.time.Instant;
018import java.util.Collection;
019import java.util.Collections;
020import java.util.Optional;
021
022import edu.umd.cs.findbugs.annotations.Nullable;
023import org.shredzone.acme4j.Problem;
024
025/**
026 * A rate limit was exceeded. If provided by the server, it also includes the earliest
027 * time at which a new attempt will be accepted, and a reference to a document that
028 * further explains the rate limit that was exceeded.
029 */
030public class AcmeRateLimitedException extends AcmeServerException {
031    private static final long serialVersionUID = 4150484059796413069L;
032
033    private final @Nullable Instant retryAfter;
034    private final Collection<URL> documents;
035
036    /**
037     * Creates a new {@link AcmeRateLimitedException}.
038     *
039     * @param problem
040     *         {@link Problem} that caused the exception
041     * @param retryAfter
042     *         The instant of time that the request is expected to succeed again, may be
043     *         {@code null} if not known
044     * @param documents
045     *         URLs pointing to documents about the rate limit that was hit, may be
046     *         {@code null} if not known
047     */
048    public AcmeRateLimitedException(Problem problem, @Nullable Instant retryAfter,
049                @Nullable Collection<URL> documents) {
050        super(problem);
051        this.retryAfter = retryAfter;
052        this.documents =
053                documents != null ? Collections.unmodifiableCollection(documents) : Collections.emptyList();
054    }
055
056    /**
057     * Returns the instant of time the request is expected to succeed again. Empty
058     * if this moment is not known.
059     */
060    public Optional<Instant> getRetryAfter() {
061        return Optional.ofNullable(retryAfter);
062    }
063
064    /**
065     * Collection of URLs pointing to documents about the rate limit that was hit.
066     * Empty if the server did not provide such URLs.
067     */
068    public Collection<URL> getDocuments() {
069        return documents;
070    }
071
072}