@Test
public void testAspectsWithPropagation() {
System.out.println("----------- Running testAspectsWithPropagation ...");
DependencyManager m = new DependencyManager(context);
// helper class that ensures certain steps get executed in sequence
m_invokeStep = new Ensure();
// Create our original "S" service.
Dictionary props = new Hashtable();
props.put("foo", "bar");
Component s = m.createComponent()
.setImplementation(new SImpl())
.setInterface(S.class.getName(), props);
// Create an aspect aware client, depending on "S" service.
Client clientImpl;
Component client = m.createComponent()
.setImplementation((clientImpl = new Client()))
.add(m.createServiceDependency()
.setService(S.class)
.setRequired(true)
.setDebug("client")
.setCallbacks("add", "change", "remove", "swap"));
// Create some "S" aspects
Component[] aspects = new Component[ASPECTS];
for (int rank = 1; rank <= ASPECTS; rank ++) {
aspects[rank-1] = m.createAspectService(S.class, null, rank, "add", "change", "remove", "swap")
.setImplementation(new A("A" + rank, rank));
props = new Hashtable();
props.put("a" + rank, "v" + rank);
aspects[rank-1].setServiceProperties(props);
}
// Register client
m.add(client);
// Randomly register aspects and original service
boolean originalServiceAdded = false;
for (int i = 0; i < ASPECTS; i ++) {
int index = getRandomAspect();
m.add(aspects[index]);
if (_rnd.nextBoolean()) {
m.add(s);
originalServiceAdded = true;
}
}
if (! originalServiceAdded) {
m.add(s);
}
// All set, check if client has inherited from top level aspect properties + original service properties
Map check = new HashMap();
check.put("foo", "bar");
for (int i = 1; i < (ASPECTS - 1); i ++) {
check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect.
}
check.put("a" + ASPECTS, "v" + ASPECTS);
checkServiceProperties(check, clientImpl.getServiceProperties());
// Now invoke client, which orderly calls all aspects in the chain, and finally the original service "S".
System.out.println("-------------------------- Invoking client.");
clientImpl.invoke();
m_invokeStep.waitForStep(ASPECTS+1, 5000);
// Now, change original service "S" properties: this will orderly trigger "change" callbacks on aspects, and on client.
System.out.println("-------------------------- Modifying original service properties.");
m_changeStep = new Ensure();
props = new Hashtable();
props.put("foo", "barModified");
s.setServiceProperties(props);
// Check if aspects and client have been orderly called in their "changed" callback
m_changeStep.waitForStep(ASPECTS+1, 5000);
// Check if modified "foo" original service property has been propagated
check = new HashMap();
check.put("foo", "barModified");
for (int i = 1; i < (ASPECTS - 1); i ++) {
check.put("a" + i, null); // we must not inherit from lower ranks, only from the top-level aspect.
}
check.put("a" + ASPECTS, "v" + ASPECTS); // we only see top-level aspect service properties
checkServiceProperties(check, clientImpl.getServiceProperties());
// Now, change the top-level ranked aspect: it must propagate to all upper aspects, as well as to the client
System.out.println("-------------------------- Modifying top-level aspect service properties.");
m_changeStep = new Ensure();
for (int i = 1; i <= ASPECTS; i ++) {
m_changeStep.step(i); // only client has to be changed.
}
props = new Hashtable();
props.put("a" + ASPECTS, "v" + ASPECTS + "-Modified");