package org.zstack.test.core.cascade;
import com.google.common.collect.Ordering;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.zstack.core.cascade.*;
import org.zstack.core.componentloader.ComponentLoader;
import org.zstack.header.core.Completion;
import org.zstack.header.errorcode.ErrorCode;
import org.zstack.test.BeanConstructor;
import org.zstack.test.WebBeanConstructor;
import org.zstack.utils.Utils;
import org.zstack.utils.logging.CLogger;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
/**
*/
public class TestAsyncCascade3 {
CLogger logger = Utils.getLogger(TestAsyncCascade3.class);
ComponentLoader loader;
CascadeFacade casf;
List<String> seq = new ArrayList<>();
@Before
public void setUp() throws Exception {
BeanConstructor con = new WebBeanConstructor();
con.addXml("PortalForUnitTest.xml");
loader = con.build();
casf = loader.getComponent(CascadeFacade.class);
}
private void bootstrap(Map<String, CascadeExtensionPoint> exts) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method method = CascadeFacadeImpl.class.getDeclaredMethod("populateCascadeNodes", Map.class);
method.setAccessible(true);
method.invoke(casf, exts);
method = CascadeFacadeImpl.class.getDeclaredMethod("populateTree");
method.setAccessible(true);
method.invoke(casf);
}
@Test
public void test() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Map<String, CascadeExtensionPoint> map = new HashMap<String, CascadeExtensionPoint>();
map.put("zone", new AbstractAsyncCascadeExtension() {
@Override
public void asyncCascade(CascadeAction action, Completion completion) {
logger.debug(String.format("asyncCascade: %s", getCascadeResourceName()));
seq.add(this.getCascadeResourceName());
completion.success();
}
@Override
public List<String> getEdgeNames() {
return Arrays.asList();
}
@Override
public String getCascadeResourceName() {
return "zone";
}
@Override
public CascadeAction createActionForChildResource(CascadeAction action) {
return action.copy().setParentIssuer("zone");
}
});
map.put("cluster", new AbstractAsyncCascadeExtension() {
@Override
public void asyncCascade(CascadeAction action, Completion completion) {
if (Arrays.asList("zone").contains(action.getParentIssuer())) {
seq.add(this.getCascadeResourceName());
}
completion.success();
}
@Override
public List<String> getEdgeNames() {
return Arrays.asList("zone");
}
@Override
public String getCascadeResourceName() {
return "cluster";
}
@Override
public CascadeAction createActionForChildResource(CascadeAction action) {
return action.copy().setParentIssuer("cluster");
}
});
map.put("primaryStorage", new AbstractAsyncCascadeExtension() {
@Override
public void asyncCascade(CascadeAction action, Completion completion) {
if (action.getParentIssuer().equals("zone")) {
seq.add(this.getCascadeResourceName());
}
completion.success();
}
@Override
public List<String> getEdgeNames() {
return Arrays.asList("zone");
}
@Override
public String getCascadeResourceName() {
return "primaryStorage";
}
@Override
public CascadeAction createActionForChildResource(CascadeAction action) {
return action.copy().setParentIssuer("primaryStorage");
}
});
map.put("host", new AbstractAsyncCascadeExtension() {
@Override
public void asyncCascade(CascadeAction action, Completion completion) {
if (action.getParentIssuer().equals("zone")) {
seq.add(this.getCascadeResourceName());
}
completion.success();
}
@Override
public List<String> getEdgeNames() {
return Arrays.asList("zone");
}
@Override
public String getCascadeResourceName() {
return "host";
}
@Override
public CascadeAction createActionForChildResource(CascadeAction action) {
return action.copy().setParentIssuer("host");
}
});
map.put("l2Network", new AbstractAsyncCascadeExtension() {
@Override
public void asyncCascade(CascadeAction action, Completion completion) {
if (action.getParentIssuer().equals("zone")) {
seq.add(this.getCascadeResourceName());
}
completion.success();
}
@Override
public List<String> getEdgeNames() {
return Arrays.asList("zone");
}
@Override
public String getCascadeResourceName() {
return "l2Network";
}
@Override
public CascadeAction createActionForChildResource(CascadeAction action) {
return action.copy().setParentIssuer("l2Network");
}
});
map.put("l3Network", new AbstractAsyncCascadeExtension() {
@Override
public void asyncCascade(CascadeAction action, Completion completion) {
if (action.getParentIssuer().equals("zone")) {
seq.add(this.getCascadeResourceName());
}
completion.success();
}
@Override
public List<String> getEdgeNames() {
return Arrays.asList("zone");
}
@Override
public String getCascadeResourceName() {
return "l3Network";
}
@Override
public CascadeAction createActionForChildResource(CascadeAction action) {
return action.copy().setParentIssuer("l3Network");
}
});
bootstrap(map);
casf.asyncCascade("test", "zone", null, new Completion(null) {
@Override
public void success() {
}
@Override
public void fail(ErrorCode errorCode) {
}
});
// Note(WeiW): Since the last element must be issuer, shouldn't be ordered.
// And the seq must be [cluster, host, l2Network, l3Network, primaryStorage, zone]
Assert.assertTrue(Ordering.natural().isOrdered(seq.subList(0, seq.size()-1)));
}
}