use of org.forgerock.openam.rest.fluent.AuditFilter in project OpenAM by OpenRock.
the class RestSTSInstancePublisherImpl method publishInstance.
/**
* Publishes the rest STS instance at the specified relative path. This method will be invoked when the Rest STS instance
* is initially published, and to re-constitute previously-published instances following a server restart.
* Note on transaction semantics: publishing a rest-sts instance means modifying both the CREST router, and the SMS.
* First the CREST router is modified, and then the SMS. If the SMS modifications fail, the CREST router modifications
* will be rolled-back, so that a publish can be successfully re-tried.
* @param instanceConfig The RestSTSInstanceConfig which defined the guice bindings which specify the functionality of
* the RestSTS instance. This RestSTSInstanceConfig will be persisted so that persisted instances
* can be reconstituted in case of a server restart.
* @param restSTSInstance The RestSTS instance defining the functionality of the rest STS service.
* @param republish Indicates whether this is an original publish, or a republish following OpenAM restart.
* @throws STSPublishException thrown in case a rest-sts instance has already been published at the specified
* subPath, or in case other errors prevented a successful publish.
*/
@Override
public synchronized String publishInstance(RestSTSInstanceConfig instanceConfig, RestSTS restSTSInstance, boolean republish) throws STSPublishException {
/*
Exclude the possibility that a rest-sts instance has already been added at the sub-path.
Looking at the router.add code to determine what happens if route already exists: it looks like it amounts to a no-op -
the backing route collection is a CopyOnWriteArraySet, which will just return false if the add did not work, but
because this value is not returned, we don't know what the outcome of the operation was. But because the Route class
is contained in the CoWAS, and it does not over-ride the equals method, every new reference to a Route will be added -
i.e. equality is defined as reference equality. So it seems possible to add the same path several times, and the
specific SingletonResourceProvider chosen to service a given request is a function of the RouteMatcher.
But because it should not be possible to add a new rest-sts instance at the same path, I can avoid all of these
complexities by checking my HashMap if an entry is present, as I need to maintain a reference to all
published Routes in order to be able to remove them.
*/
String deploymentSubPath = deploymentPathNormalization.normalizeDeploymentPath(instanceConfig.getDeploymentSubPath());
if (publishedRoutes.containsKey(normalizeDeploymentSubPathForRouteCache(deploymentSubPath))) {
throw new STSPublishException(ResourceException.CONFLICT, "A rest-sts instance at sub-path " + deploymentSubPath + " has already been published.");
}
// Use InjectorHolder to lookup AuditFilter as Guice struggles to inject it
AuditFilter auditFilter = InjectorHolder.getInstance(AuditFilter.class);
FilterChain auditedRestSTSService = new FilterChain(Resources.newSingleton(new RestSTSService(restSTSInstance, logger)), new AuditFilterWrapper(auditFilter, STS));
RouteMatcher<Request> route = router.addRoute(EQUALS, uriTemplate(deploymentSubPath), auditedRestSTSService);
/*
Need to persist the published Route instance as it is necessary for router removal.
*/
publishedRoutes.put(normalizeDeploymentSubPathForRouteCache(deploymentSubPath), route);
/*
If this is a republish (i.e. re-constitute previously-published Rest STS instances following OpenAM restart),
then the RestSTSInsanceConfig does not need to be persisted, as it was obtained from the SMS via a GET
on the publish service by the RestSTSInstanceRepublishServlet.
*/
if (!republish) {
try {
persistentStore.persistSTSInstance(deploymentSubPath, instanceConfig.getDeploymentConfig().getRealm(), instanceConfig);
} catch (STSPublishException e) {
//roll-back the router mutation before throwing exception
router.removeRoute(route);
publishedRoutes.remove(normalizeDeploymentSubPathForRouteCache(deploymentSubPath));
throw e;
}
}
return deploymentSubPath;
}
Aggregations