001/* 002 * acme4j - Java ACME client 003 * 004 * Copyright (C) 2017 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.it.pebble; 015 016import static org.assertj.core.api.Assertions.assertThat; 017 018import java.net.URI; 019import java.net.URL; 020import java.security.KeyPair; 021import java.util.ArrayList; 022import java.util.List; 023 024import org.junit.jupiter.api.AfterEach; 025import org.shredzone.acme4j.Authorization; 026import org.shredzone.acme4j.Order; 027import org.shredzone.acme4j.exception.AcmeException; 028import org.shredzone.acme4j.exception.AcmeLazyLoadingException; 029import org.shredzone.acme4j.it.BammBammClient; 030import org.shredzone.acme4j.util.KeyPairUtils; 031 032/** 033 * Superclass for all Pebble related integration tests. 034 * <p> 035 * These tests require a running 036 * <a href="https://github.com/letsencrypt/pebble">Pebble</a> ACME test server at 037 * localhost port 14000. The host and port can be changed via the system property 038 * {@code pebbleHost} and {@code pebblePort} respectively. 039 * <p> 040 * Also, a running pebble-challtestsrv is required to listen on localhost port 8055. The 041 * server's base URL can be changed via the system property {@code bammbammUrl}. 042 */ 043public abstract class PebbleITBase { 044 private final String pebbleHost = System.getProperty("pebbleHost", "localhost"); 045 private final int pebblePort = Integer.parseInt(System.getProperty("pebblePort", "14000")); 046 047 private final String bammbammUrl = System.getProperty("bammbammUrl", "http://localhost:8055"); 048 049 private BammBammClient bammBammClient; 050 051 private final List<CleanupCallback> cleanup = new ArrayList<>(); 052 053 @AfterEach 054 public void performCleanup() throws Exception { 055 for (var callback : cleanup) { 056 callback.cleanup(); 057 } 058 cleanup.clear(); 059 } 060 061 protected void cleanup(CleanupCallback callback) { 062 cleanup.add(callback); 063 } 064 065 /** 066 * @return The {@link URI} of the pebble server to test against. 067 */ 068 protected URI pebbleURI() { 069 return URI.create("acme://pebble/" + pebbleHost + ":" + pebblePort); 070 } 071 072 /** 073 * @return {@link BammBammClient} singleton instance. 074 */ 075 protected BammBammClient getBammBammClient() { 076 if (bammBammClient == null) { 077 bammBammClient = new BammBammClient(bammbammUrl); 078 } 079 return bammBammClient; 080 } 081 082 /** 083 * Creates a fresh key pair. 084 * 085 * @return Created {@link KeyPair}, guaranteed to be unknown to the Pebble server 086 */ 087 protected KeyPair createKeyPair() { 088 return KeyPairUtils.createKeyPair(2048); 089 } 090 091 /** 092 * Asserts that the given {@link URL} is not {@code null} and refers to the Pebble 093 * server. 094 * 095 * @param url 096 * {@link URL} to assert 097 */ 098 protected void assertIsPebbleUrl(URL url) { 099 assertThat(url).isNotNull(); 100 assertThat(url.getProtocol()).isEqualTo("https"); 101 assertThat(url.getHost()).isEqualTo(pebbleHost); 102 assertThat(url.getPort()).isEqualTo(pebblePort); 103 assertThat(url.getPath()).isNotEmpty(); 104 } 105 106 /** 107 * Safely updates the authorization, catching checked exceptions. 108 * 109 * @param auth 110 * {@link Authorization} to update 111 */ 112 protected void updateAuth(Authorization auth) { 113 try { 114 auth.update(); 115 } catch (AcmeException ex) { 116 throw new AcmeLazyLoadingException(auth, ex); 117 } 118 } 119 120 /** 121 * Safely updates the order, catching checked exceptions. 122 * 123 * @param order 124 * {@link Order} to update 125 */ 126 protected void updateOrder(Order order) { 127 try { 128 order.update(); 129 } catch (AcmeException ex) { 130 throw new AcmeLazyLoadingException(order, ex); 131 } 132 } 133 134 @FunctionalInterface 135 public interface CleanupCallback { 136 void cleanup() throws Exception; 137 } 138 139}