use of org.forgerock.openam.sts.STSPublishException in project OpenAM by OpenRock.
the class SoapSTSPublishServiceRequestHandler method handleRead.
public Promise<ResourceResponse, ResourceException> handleRead(Context context, ReadRequest request) {
try {
if (EMPTY_STRING.equals(request.getResourcePath())) {
List<SoapSTSInstanceConfig> publishedInstances = publisher.getPublishedInstances();
JsonObject jsonObject = JsonValueBuilder.jsonValue();
for (SoapSTSInstanceConfig instanceConfig : publishedInstances) {
jsonObject.put(instanceConfig.getDeploymentSubPath(), mapStringToJson(instanceConfig.toJson().toString()));
}
/*
Note that the revision etag is not set, as this is not a resource which should really be cached.
If caching becomes necessary, a string composed of the hash codes of each of the SoapSTSInstanceConfig
instances could be used (or a hash of that string).
*/
return newResultPromise(newResourceResponse(PUBLISHED_INSTANCES, EMPTY_STRING, jsonObject.build()));
} else {
final String realm = getRealmFromResourceName(request.getResourcePath());
if (!realmValidator.isRealm(realm)) {
logger.warn("Read of soap STS instance state for instance " + request.getResourcePath() + " in realm " + realm + " rejected because realm does not exist");
return new NotFoundException("The specified realm does not exist.").asPromise();
}
SoapSTSInstanceConfig instanceConfig = publisher.getPublishedInstance(request.getResourcePath(), realm);
return newResultPromise(newResourceResponse(instanceConfig.getDeploymentSubPath(), getInstanceConfigEtag(instanceConfig), JsonValueBuilder.jsonValue().put(instanceConfig.getDeploymentSubPath(), mapStringToJson(instanceConfig.toJson().toString())).build()));
}
} catch (STSPublishException e) {
String message = "Exception caught obtaining soap sts instance corresponding to id: " + request.getResourcePath() + "; Exception: " + e;
logger.error(message, e);
return e.asPromise();
}
}
use of org.forgerock.openam.sts.STSPublishException 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;
}
use of org.forgerock.openam.sts.STSPublishException in project OpenAM by OpenRock.
the class RestSTSPublishServiceListener method handleInstanceCreation.
private void handleInstanceCreation(String normalizedServiceComponent, String orgName, String serviceComponent) {
final String logIdentifier = "RestSTSPublishServiceListener#handleInstanceCreation";
if (StringUtils.isBlank(normalizedServiceComponent)) {
logger.warn("In RestSTSPublishServiceListener#handleInstanceCreation, the normalized name of the rest-sts service for " + "which the creation event was received is blank. The un-normalized name: " + serviceComponent + ". This happens " + "the first time a rest-sts instance is published in a newly-created realm, as the first step in this creation " + "is the addition of a new service configuration object for this subrealm, which also triggers the invocation " + "of this listener. If this message is appearing after the first creation of a rest-sts instance in a new realm, " + "then something is wrong.");
return;
}
if (!instancePublisher.isInstanceExposedInCrest(normalizedServiceComponent)) {
String realm = DNMapper.orgNameToRealmName(orgName);
RestSTSInstanceConfig createdInstance;
try {
createdInstance = restSTSInstanceConfigStore.getSTSInstanceConfig(normalizedServiceComponent, realm);
} catch (STSPublishException e) {
logger.error(logIdentifier + ":could not obtain newly created rest-sts instance " + serviceComponent + " from SMS. " + "This means this instance will not be hung off of the CREST router. Exception: " + e);
return;
}
Injector instanceInjector;
try {
instanceInjector = createInjector(createdInstance);
} catch (ResourceException e) {
logger.error(logIdentifier + ":could not create injector corresponding to newly created rest-sts " + "instance " + serviceComponent + ". The instanceConfig " + createdInstance.toJson() + "\nThis means this instance will not be hung off of the CREST router. Exception: " + e);
return;
}
try {
instancePublisher.publishInstance(createdInstance, instanceInjector.getInstance(RestSTS.class), REPUBLISH_INSTANCE);
logger.info(logIdentifier + ": Successfully hung rest-sts instance " + createdInstance.getDeploymentSubPath() + " published at another server in the site deployment off of CREST router.");
} catch (ResourceException e) {
logger.error(logIdentifier + ":could not create injector corresponding to newly created rest-sts " + "instance " + serviceComponent + ". The instanceConfig " + createdInstance.toJson() + "\nThis means this instance will not be hung off of the CREST router. Exception: " + e);
}
}
}
use of org.forgerock.openam.sts.STSPublishException in project OpenAM by OpenRock.
the class STSInstanceConfigStoreBase method getAllRealmNames.
private Set<String> getAllRealmNames() throws STSPublishException {
Set<String> realmNames = new HashSet<>();
/*
The OrganizationConfigManager#SubOrganizationNames only returns realms under the root realm. The root
realm needs to be added separately
*/
realmNames.add(AMSTSConstants.ROOT_REALM);
try {
Set<String> subRealms = getSubrealms(realmNames);
while (!subRealms.isEmpty()) {
realmNames.addAll(subRealms);
subRealms = getSubrealms(subRealms);
}
return realmNames;
} catch (SMSException e) {
throw new STSPublishException(ResourceException.INTERNAL_ERROR, "Could not obtain list of realms from the OrganizationConfigManager. " + "This means list of previously-published " + restOrSoap() + " sts instances cannot be returned. " + "Exception: " + e);
}
}
use of org.forgerock.openam.sts.STSPublishException in project OpenAM by OpenRock.
the class STSInstanceConfigStoreBase method updateSTSInstance.
/**
* Updates attributes corresponding to the existing STS instance.
* @param stsInstanceId the identifier for the to-be-updated sts instance
* @param realm The realm in which the sts instance should be deployed
* @param instance The updated STSInstanceConfig subclass
* @throws STSPublishException if the SMS encounters a problem during persistence.
*/
@Override
public synchronized void updateSTSInstance(String stsInstanceId, String realm, T instance) throws STSPublishException {
/*
Model for code below taken from AuthPropertiesModelImpl#setValues
*/
ServiceConfig baseService;
try {
baseService = new ServiceConfigManager(serviceName, getAdminToken()).getOrganizationConfig(realm, null);
if (baseService != null) {
ServiceConfig serviceConfig = baseService.getSubConfig(stsInstanceId);
if (serviceConfig != null) {
serviceConfig.setAttributes(instanceConfigMarshaller.toMap(instance));
logger.debug(restOrSoap() + "sts instance " + stsInstanceId + " in realm " + realm + " updated in persistent store.");
} else {
throw new STSPublishException(ResourceException.NOT_FOUND, "Could not create ServiceConfig for realm " + realm + " in order to update " + restOrSoap() + " sts instance with id " + stsInstanceId);
}
} else {
throw new STSPublishException(ResourceException.NOT_FOUND, "Could not create ServiceConfigManager for realm " + realm + " in order to update " + restOrSoap() + " sts instance with id " + stsInstanceId);
}
} catch (SMSException | SSOException e) {
throw new STSPublishException(ResourceException.INTERNAL_ERROR, "Exception caught updating " + restOrSoap() + " sts instance with id " + stsInstanceId + " in realm " + realm + ". Exception: " + e, e);
}
}
Aggregations