package com.neverwinterdp.vm.event;
import static com.neverwinterdp.vm.event.VMEvent.VM_HEARTBEAT;
import static com.neverwinterdp.vm.event.VMEvent.VM_MASTER_ELECTION;
import static com.neverwinterdp.vm.event.VMEvent.VM_STATUS;
import com.neverwinterdp.registry.DataChangeNodeWatcher;
import com.neverwinterdp.registry.Registry;
import com.neverwinterdp.registry.RegistryException;
import com.neverwinterdp.registry.election.LeaderElectionNodeWatcher;
import com.neverwinterdp.registry.event.NodeEvent;
import com.neverwinterdp.registry.event.WaitingEventListener;
import com.neverwinterdp.vm.VMDescriptor;
import com.neverwinterdp.vm.VMStatus;
import com.neverwinterdp.vm.event.VMEvent.VMAttr;
import com.neverwinterdp.vm.service.VMService;
import com.neverwinterdp.vm.service.VMService.Status;
public class VMWaitingEventListener extends WaitingEventListener {
public VMWaitingEventListener(Registry registry) throws RegistryException {
super("Assert sequence of event for VM", registry);
registryListener.watch(VMService.LEADER_PATH, new VMLeaderElectedNodeWatcher(registry), true);
}
public void waitVMServiceStatus(String desc, VMService.Status status) throws Exception {
String path = VMService.MASTER_PATH + "/status";
add(desc, path, true, VMService.Status.class, status);
}
public void waitVMStatus(String desc, String vmName, VMStatus vmStatus) throws Exception {
String path = VMService.getVMStatusPath(vmName);
VMStatusNodeWatcher vmStatusWatcher = new VMStatusNodeWatcher(registry) {
synchronized public void onChange(NodeEvent event, VMDescriptor descriptor, VMStatus status) {
boolean heartBeat = false;
try {
heartBeat = registry.exists(event.getPath() + "/heartbeat");
} catch(RegistryException e) {
throw new RuntimeException(e);
}
VMEvent vmEvent = new VMEvent(VM_STATUS, event);
vmEvent.attr(VMAttr.vmdescriptor, descriptor);
vmEvent.attr(VMAttr.vmstatus, status);
vmEvent.attr(VMAttr.heartbeat, heartBeat);
VMWaitingEventListener.this.process(vmEvent);
}
};
registryListener.watch(path, vmStatusWatcher, true);
add(new VMStatusEventListener(desc, vmName, vmStatus));
}
public void waitHeartbeat(String desc, String vmName, boolean connected) throws RegistryException {
String path = VMService.getVMHeartbeatPath(vmName);
VMHeartbeatNodeWatcher watcher = new VMHeartbeatNodeWatcher(registry) {
@Override
synchronized public void onConnected(NodeEvent event, VMDescriptor vmDescriptor) {
VMEvent vmEvent = new VMEvent(VM_HEARTBEAT, event);
vmEvent.attr(VMAttr.vmdescriptor, vmDescriptor);
vmEvent.attr(VMAttr.heartbeat, true);
VMWaitingEventListener.this.process(vmEvent);
}
@Override
synchronized public void onDisconnected(NodeEvent event, VMDescriptor vmDescriptor) {
VMEvent vmEvent = new VMEvent(VM_HEARTBEAT, event);
vmEvent.attr(VMAttr.vmdescriptor, vmDescriptor);
vmEvent.attr(VMAttr.heartbeat, false);
VMWaitingEventListener.this.process(vmEvent);
}
};
registryListener.watch(path, watcher, true);
add(new VMHeartbeatEventListener(desc, vmName, connected));
}
public void waitVMMaster(String desc, String vmName) throws Exception {
add(new VMMasterElectionEventListener(desc, vmName));
}
public class VMLeaderElectedNodeWatcher extends LeaderElectionNodeWatcher<VMDescriptor> {
public VMLeaderElectedNodeWatcher(Registry registry) {
super(registry, VMDescriptor.class);
}
@Override
public void onElected(NodeEvent event, VMDescriptor learderVMDescriptor) {
VMEvent vmEvent = new VMEvent(VM_MASTER_ELECTION, event);
vmEvent.attr(VMAttr.master_leader, learderVMDescriptor);
VMWaitingEventListener.this.process(vmEvent);
setComplete();
}
}
static public class VMStatusEventListener extends VMEventListener {
String expectVMName;
VMStatus expectVMStatus;
public VMStatusEventListener(String description, String vmName, VMStatus vmStatus) {
super(description);
this.expectVMName = vmName;
this.expectVMStatus = vmStatus;
}
@Override
public boolean process(VMEvent event) {
if(!VM_STATUS.equals(event.getName())) return false;
VMDescriptor vmDescriptor = event.attr(VMAttr.vmdescriptor);
VMStatus status = event.attr(VMAttr.vmstatus);
if(!expectVMName.equals(vmDescriptor.getVmConfig().getName())) return false;
if(!expectVMStatus.equals(status)) return false;
return true;
}
}
static public class VMHeartbeatEventListener extends VMEventListener {
String expectVMName;
boolean connected ;
public VMHeartbeatEventListener(String description, String vmName, boolean connected) {
super(description);
this.expectVMName = vmName;
this.connected = connected ;
}
@Override
public boolean process(VMEvent event) {
if(!VM_HEARTBEAT.equals(event.getName())) return false;
VMDescriptor vmDescriptor = event.attr(VMAttr.vmdescriptor);
boolean connected = event.attr(VMAttr.heartbeat);
if(!expectVMName.equals(vmDescriptor.getVmConfig().getName())) return false;
if(this.connected != connected) return false;
return true;
}
}
static public class VMMasterElectionEventListener extends VMEventListener {
String expectVMName;
public VMMasterElectionEventListener(String description, String vmName) {
super(description);
this.expectVMName = vmName;
}
@Override
public boolean process(VMEvent event) {
if(!VM_MASTER_ELECTION.equals(event.getName())) return false;
VMDescriptor vmDescriptor = event.attr(VMAttr.master_leader);
if(!expectVMName.equals(vmDescriptor.getVmConfig().getName())) return false;
return true;
}
}
}