//System.out.println("Request:" + operation);
final long s0 = System.currentTimeMillis();
// TOD: provide proper API
final ProgressElement progressElement = Footer.PROGRESS_ELEMENT;
progressElement.reset();
progressElement.tick();
dispatcher.execute(new DMRAction(operation), new SimpleCallback<DMRResponse>() {
@Override
public void onFailure(Throwable caught) {
//callback.onFailure(new RuntimeException("Failed to create security context for "+id, caught));
progressElement.finish();
Log.error("Failed to create security context for "+id+ ", fallback to temporary read-only context", caught.getMessage());
contextMapping.put(id, READ_ONLY);
callback.onSuccess(READ_ONLY);
}
@Override
public void onSuccess(DMRResponse dmrResponse) {
Log.info("Context http (" + id + "): " + (System.currentTimeMillis() - s0) + "ms");
long s1 = System.currentTimeMillis();
ModelNode response = dmrResponse.get();
Log.info("Context decode (" + id + "): " + (System.currentTimeMillis() - s1) + "ms");
final long s2 = System.currentTimeMillis();
if(response.isFailure())
{
Log.error(
"Failed to retrieve access control meta data, " +
"fallback to temporary read-only context: ",
response.getFailureDescription());
contextMapping.put(id, READ_ONLY);
callback.onSuccess(READ_ONLY);
return;
}
try {
ModelNode overalResult = response.get(RESULT);
SecurityContextImpl context = new SecurityContextImpl(id, references);
// The first part is identify the resource that has been requested.
// Depending on whether you've requested a wildcard address or a specific one
// we either get a ModelType.List or ModelType.Object response.
// The former requires parsing the response to access control meta data matching the inquiry.
for(int i=1; i<=steps.size();i++)
{
String step = "step-"+i;
if(overalResult.hasDefined(step))
{
// break down the address into something we can match against the response
final ResourceRef ref = step2address.get(step);
ModelNode emptyAddress = new ModelNode().setEmptyList();
final ModelNode addressNode = AddressMapping.fromString(ref.address).asResource(emptyAddress, filteringStatementContext);
final List<ModelNode> inquiryAddress = addressNode.get(ADDRESS).asList();
ModelNode stepResult = overalResult.get(step).get(RESULT);
ModelNode payload = null;
// it's a List response when asking for '<resourceType>=*"
if(stepResult.getType() == ModelType.LIST)
{
List<ModelNode> nodes = stepResult.asList();
for(ModelNode node : nodes)
{
// matching the wildcard response
List<ModelNode> responseAddress = node.get(ADDRESS).asList();
// match the inquiry
if(matchingAddress(responseAddress, inquiryAddress))
{
payload = node;
break;
}
}
if(payload == null)
{
//System.out.println(ref.address+" -> "+stepResult);
throw new RuntimeException("Unexpected response format");
}
}
else
{
payload = stepResult;
}
// break down into root resource and children
parseAccessControlChildren(ref, references, context, payload);
}
}
context.seal(); // makes it immutable
contextMapping.put(id, context);
Log.info("Context parse (" + id + "): " + (System.currentTimeMillis() - s2) + "ms");
progressElement.finish();
callback.onSuccess(context);
} catch (Throwable e) {
progressElement.finish();
e.printStackTrace();
callback.onFailure(new RuntimeException("Failed to parse access control meta data: "+ e.getMessage(), e));
}
}