use of com.peterphi.std.guice.common.retry.annotation.Retry in project stdlib by petergeneric.
the class RetryMethodInterceptor method invoke.
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
Timer.Context timer = this.calls.time();
try {
final Retry options = invocation.getMethod().getAnnotation(Retry.class);
final RetryManager mgr = buildRetryManager(options);
if (log.isTraceEnabled())
log.trace("Attempting retryable invoke of " + invocation.getMethod().toGenericString() + " on " + invocation.getThis() + " with " + Arrays.asList(invocation.getArguments()));
return mgr.run(new InvocationRetryable(invocation, options.on(), options.exceptOn(), options.exceptOnCore(), options.exceptOnRestExceptionCodes()));
} catch (Throwable t) {
totalFailures.mark();
if (log.isTraceEnabled())
log.trace("Retrying invoke of " + invocation.getMethod().toGenericString() + " on " + invocation.getThis() + " with " + Arrays.asList(invocation.getArguments()) + " failed.", t);
throw t;
} finally {
timer.stop();
}
}
use of com.peterphi.std.guice.common.retry.annotation.Retry in project stdlib by petergeneric.
the class AzureLogStore method storeAsBatch.
@Retry
public void storeAsBatch(final List<LogLineTableEntity> lines) throws StorageException {
if (lines.isEmpty())
// nothing to do!
return;
TableBatchOperation operation = new TableBatchOperation();
for (LogLineTableEntity line : lines) {
if (log.isTraceEnabled())
log.trace("Storing entity with partition=" + line.getPartitionKey() + ", row=" + line.getRowKey());
operation.insertOrReplace(line);
}
logdata.execute(operation);
}
use of com.peterphi.std.guice.common.retry.annotation.Retry in project stdlib by petergeneric.
the class LetsEncryptService method proveOwnership.
@Retry
public void proveOwnership(final String domain) {
Registration registration = getRegistration();
final Authorization authorization;
try {
authorization = registration.authorizeDomain(domain);
} catch (AcmeException e) {
throw new RuntimeException("Error creating authorisation for " + domain, e);
}
Dns01Challenge challenge = authorization.findChallenge(Dns01Challenge.TYPE);
if (challenge == null)
throw new RuntimeException("DNS Challenge is not available! Cannot prove we own " + domain);
final String domainName = "_acme-challenge." + domain;
log.debug("Create TXT record " + domainName + " with value: " + challenge.getDigest());
// Create the TXT record
dns.createDNSRecord(domainName, RecordType.TXT, challenge.getDigest());
// Wait for a short time for the change to DNS records to propagate through Microsoft's system
// N.B. there's no docs suggesting this is needed or that this is the right value, but Let's Encrypt challenges
// seem to fail more regularly against the live API without this wait
new Timeout(5, TimeUnit.SECONDS).sleep();
// Allow the CA to start checking the TXT record
try {
log.trace("Challenge status " + challenge.getStatus());
challenge.trigger();
log.trace("Challenge status " + challenge.getStatus());
} catch (AcmeException e) {
throw new RuntimeException("Error triggering authorisation for " + domain, e);
}
// Poll waiting for the challenge to complete
int attempts = 10;
for (int attempt = 0; attempt < 10; attempt++) {
log.trace("Challenge status " + challenge.getStatus());
if (challenge.getStatus() == Status.INVALID)
break;
else if (challenge.getStatus() == Status.VALID)
break;
Timeout.TEN_SECONDS.sleep();
try {
challenge.update();
} catch (AcmeException e) {
log.warn("Error updating challenge", e);
}
}
log.trace("Challenge status " + challenge.getStatus());
dns.deleteDNSRecord(domainName, RecordType.TXT);
if (challenge.getStatus() != Status.VALID) {
throw new RuntimeException("Challenge " + challenge + " failed for " + domainName + "! Failed with state " + challenge.getStatus());
} else {
log.debug("Challenge " + challenge + " passed!");
}
}
use of com.peterphi.std.guice.common.retry.annotation.Retry in project stdlib by petergeneric.
the class UserManagerOAuthServiceImpl method getAuth.
@Override
@AuthConstraint(id = "oauth2server_auth", role = "authenticated", comment = "Must be logged in to the User Manager to initiate a service login")
@Retry
public Response getAuth(final String responseType, final String clientId, final String redirectUri, final String state, final String scope) {
// Has the current user approved this client+scope before? If so just redirect straight back
// Otherwise, bring up the authorisation UI
final Response response = createSessionAndRedirect(responseType, clientId, redirectUri, state, scope, autoGrantInteractiveAccessToAllServices);
if (response != null) {
return response;
} else {
final OAuthServiceEntity client = serviceDao.getByClientIdAndEndpoint(clientId, redirectUri);
if (client == null)
throw new IllegalArgumentException("Unknown client_id=" + clientId + " or invalid redirect uri for this service: " + redirectUri);
final TemplateCall call = templater.template("connect_to_service");
SessionNonceStore nonceStore = nonceStoreProvider.get();
// Provide additional client information
call.set("client", client);
call.set("nonce", nonceStore.allocate());
// Scopes as a list
if (StringUtils.isBlank(scope))
call.set("scopes", Collections.emptyList());
else
call.set("scopes", Arrays.asList(StringUtils.trimToEmpty(scope).split(" ")));
// Copy the request info
call.set("clientId", client.getId());
call.set("responseType", responseType);
call.set("redirectUri", redirectUri);
call.set("scope", scope);
call.set("state", state);
return call.process(Response.ok().type(MediaType.APPLICATION_XML).cacheControl(CacheControl.valueOf(NO_CACHE)));
}
}
Aggregations