Remove new resources when exception is thrown on creation

feature/mock
Richard Körber 2019-11-03 23:18:09 +01:00
parent 8aa7e4ad8e
commit b9b7bda342
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
11 changed files with 181 additions and 0 deletions

View File

@ -247,6 +247,17 @@ public class MockAcmeServer {
.findFirst();
}
/**
* Removes a {@link MockAccount}.
*
* @param account
* {@link MockAccount} to remove
*/
public void removeAccount(MockAccount account) {
account.detach(repository);
accounts.remove(account);
}
/**
* Creates a new {@link MockAuthorization} for the given {@link Identifier}. If there
* is already a {@link MockAuthorization} for that {@link Identifier}, it is returned
@ -272,6 +283,17 @@ public class MockAcmeServer {
return Optional.ofNullable(authorizations.get(identifier));
}
/**
* Removes a {@link MockAuthorization}.
*
* @param authorization
* {@link MockAuthorization} to remove
*/
public void removeAuthorization(MockAuthorization authorization) {
authorization.detach(repository);
authorizations.remove(authorization.getIdentifier());
}
/**
* Creates a new {@link MockChallenge} instance of the given type.
*
@ -284,6 +306,16 @@ public class MockAcmeServer {
return MockChallenge.create(repository, type);
}
/**
* Removes a {@link MockChallenge}.
*
* @param challenge
* {@link MockChallenge} to remove
*/
public void removeChallenge(MockChallenge challenge) {
challenge.detach(repository);
}
/**
* Creates a new {@link MockOrder} for the given {@link Identifier}.
* <p>
@ -343,6 +375,16 @@ public class MockAcmeServer {
return MockOrder.create(repository, identifiers, authorizations, ca);
}
/**
* Removes a {@link MockOrder}.
*
* @param order
* {@link MockOrder} to remove
*/
public void removeOrder(MockOrder order) {
order.detach(repository);
}
/**
* Returns the {@link MockAccount} that corresponds to the given {@link Account}.
*

View File

@ -87,6 +87,21 @@ public class Repository {
resourceMap.put(uri, wrapperFactory.apply(receiver));
}
/**
* Removes a controller {@link URL}.
*
* @param url
* {@link URL} of the controller to be removed
*/
public void removeController(URL url) {
URI uri = safeToURI(url);
Controller receiver = resourceMap.get(uri);
if (receiver == null) {
throw new IllegalArgumentException("No controller is registered for " + url);
}
resourceMap.remove(uri);
}
/**
* Adds a {@link MockResource} to this repository.
*
@ -115,6 +130,21 @@ public class Repository {
.map(type::cast);
}
/**
* Removes a {@link MockResource} from this repository. Also removes the controller.
*
* @param resource
* {@link MockResource} to remove
*/
public void removeResource(MockResource resource) {
URI uri = safeToURI(resource.getLocation());
if (!resources.containsKey(uri)) {
throw new IllegalArgumentException("Unknown resource " + resource.getLocation());
}
removeController(resource.getLocation());
resources.remove(uri);
}
/**
* Safely converts an {@link URL} to an {@link URI}.
*

View File

@ -182,6 +182,17 @@ public class MockAccount extends MockResource {
return buildUrl("account", getUniqueId(), "orders");
}
/**
* Detaches this {@link MockAccount} from the {@link Repository}.
*
* @param repository
* {@link Repository} to remove the account from.
*/
public void detach(Repository repository) {
repository.removeController(getOrdersLocation());
repository.removeResource(this);
}
@Override
public JSON toJSON() {
JSONBuilder jb = new JSONBuilder();

View File

@ -164,6 +164,16 @@ public class MockAuthorization extends MockResource {
return buildUrl("authz", getUniqueId());
}
/**
* Detaches this {@link MockAuthorization} from the {@link Repository}.
*
* @param repository
* {@link Repository} to remove the authorization from.
*/
public void detach(Repository repository) {
repository.removeResource(this);
}
@Override
public JSON toJSON() {
JSONBuilder jb = new JSONBuilder();

View File

@ -193,6 +193,16 @@ public class MockChallenge extends MockResource {
return buildUrl("challenge", getUniqueId());
}
/**
* Detaches this {@link MockChallenge} from the {@link Repository}.
*
* @param repository
* {@link Repository} to remove the challenge from.
*/
public void detach(Repository repository) {
repository.removeResource(this);
}
@Override
public JSON toJSON() {
JSONBuilder jb = new JSONBuilder();

View File

@ -319,6 +319,18 @@ public class MockOrder extends MockResource {
return buildUrl("certificate", getUniqueId());
}
/**
* Detaches this {@link MockOrder} from the {@link Repository}.
*
* @param repository
* {@link Repository} to remove the order from.
*/
public void detach(Repository repository) {
repository.removeController(getFinalizeLocation());
repository.removeController(getCertificateLocation());
repository.removeResource(this);
}
@Override
public JSON toJSON() {
JSONBuilder jb = new JSONBuilder();

View File

@ -20,6 +20,7 @@ import static org.junit.Assert.fail;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.KeyPair;
import java.util.NoSuchElementException;
import java.util.Optional;
import org.junit.Test;
@ -184,6 +185,12 @@ public class MockAcmeServerTest {
assertThat(server.getAccounts().size(), is(2));
assertThat(server.findAccount(keyPair1.getPublic()).isPresent(), is(false));
assertThat(server.findAccount(keyPair2.getPublic()).isPresent(), is(false));
server.removeAccount(account1);
assertThat(server.getAccounts().size(), is(1));
server.removeAccount(account2);
assertThat(server.getAccounts().size(), is(0));
}
/**
@ -213,6 +220,9 @@ public class MockAcmeServerTest {
Optional<MockAuthorization> missingAuth = server.findAuthorization(Identifier.dns("example.com"));
assertThat(missingAuth.isPresent(), is(false));
server.removeAuthorization(auth);
assertThat(server.findAuthorization(identifier).isPresent(), is(false));
}
/**
@ -268,6 +278,14 @@ public class MockAcmeServerTest {
MockChallenge mockChallenge = server.getMockOf(challenge);
assertThat(mockChallenge, sameInstance(createdChallenge));
server.removeChallenge(createdChallenge);
try {
server.getMockOf(challenge);
fail("Challenge is still there");
} catch (NoSuchElementException ex) {
// expected
}
}
/**
@ -284,6 +302,14 @@ public class MockAcmeServerTest {
Order order = login.bindOrder(createdOrder.getLocation());
MockOrder mockOrder = server.getMockOf(order);
assertThat(mockOrder, sameInstance(createdOrder));
server.removeOrder(createdOrder);
try {
server.getMockOf(order);
fail("Order is still there");
} catch (NoSuchElementException ex) {
// expected
}
}
/**

View File

@ -68,6 +68,15 @@ public class MockAccountTest {
assertThat(account.getPublicKey(), is(PUBLIC_KEY));
assertThat(account.getStatus(), is(Status.VALID));
assertThat(account.getTermsOfServiceAgreed(), is(nullValue()));
// Detach from repository
account.detach(repository);
assertThat(repository.getController(account.getLocation()).isPresent(),
is(false));
assertThat(repository.getController(account.getOrdersLocation()).isPresent(),
is(false));
assertThat(repository.getResourceOfType(account.getLocation(), MockAccount.class).isPresent(),
is(false));
}
/**

View File

@ -59,6 +59,13 @@ public class MockAuthorizationTest {
assertThat(auth.getIdentifier(), is(IDENTIFIER));
assertThat(auth.getStatus(), is(Status.PENDING));
assertThat(auth.getWildcard(), is(nullValue()));
// Detach from repository
auth.detach(repository);
assertThat(repository.getController(auth.getLocation()).isPresent(),
is(false));
assertThat(repository.getResourceOfType(auth.getLocation(), MockAuthorization.class).isPresent(),
is(false));
}
/**

View File

@ -59,6 +59,13 @@ public class MockChallengeTest {
assertThat(challenge.getToken(), is(nullValue()));
assertThat(challenge.getType(), is(Http01Challenge.TYPE));
assertThat(challenge.getValidated(), is(nullValue()));
// Detach from repository
challenge.detach(repository);
assertThat(repository.getController(challenge.getLocation()).isPresent(),
is(false));
assertThat(repository.getResourceOfType(challenge.getLocation(), MockChallenge.class).isPresent(),
is(false));
}
/**

View File

@ -32,6 +32,8 @@ import org.shredzone.acme4j.Status;
import org.shredzone.acme4j.mock.connection.MockCertificateAuthority;
import org.shredzone.acme4j.mock.connection.ProblemBuilder;
import org.shredzone.acme4j.mock.connection.Repository;
import org.shredzone.acme4j.mock.controller.CertificateController;
import org.shredzone.acme4j.mock.controller.FinalizeController;
import org.shredzone.acme4j.mock.controller.OrderController;
import org.shredzone.acme4j.toolbox.JSONBuilder;
@ -64,6 +66,10 @@ public class MockOrderTest {
// Controllers were added to the repository?
assertThat(repository.getController(order.getLocation()).get(),
is(instanceOf(OrderController.class)));
assertThat(repository.getController(order.getFinalizeLocation()).get(),
is(instanceOf(FinalizeController.class)));
assertThat(repository.getController(order.getCertificateLocation()).get(),
is(instanceOf(CertificateController.class)));
assertThat(repository.getResourceOfType(order.getLocation(), MockOrder.class).get(),
is(sameInstance(order)));
@ -76,6 +82,17 @@ public class MockOrderTest {
assertThat(order.getNotBefore(), is(nullValue()));
assertThat(order.getNotAfter(), is(nullValue()));
assertThat(order.getStatus(), is(Status.PENDING));
// Detach from repository
order.detach(repository);
assertThat(repository.getController(order.getLocation()).isPresent(),
is(false));
assertThat(repository.getController(order.getFinalizeLocation()).isPresent(),
is(false));
assertThat(repository.getController(order.getCertificateLocation()).isPresent(),
is(false));
assertThat(repository.getResourceOfType(order.getLocation(), MockOrder.class).isPresent(),
is(false));
}
/**