/**
* Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
*
* @author Andra Cismaru
*/
package net.juniper.contrail.vcenter;
import com.google.common.base.Throwables;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import net.juniper.contrail.contrail_vrouter_api.ContrailVRouterApi;
public class VRouterNotifier {
static volatile Map<String, ContrailVRouterApi> vrouterApiMap =
new ConcurrentHashMap<String, ContrailVRouterApi>();
static final int vrouterApiPort = 9091;
private final static Logger s_logger =
Logger.getLogger(VRouterNotifier.class);
public static Map<String, ContrailVRouterApi> getVrouterApiMap() {
return vrouterApiMap;
}
public static void created(VirtualMachineInterfaceInfo vmiInfo) {
if (vmiInfo == null) {
s_logger.error("Null vmiInfo argument, cannot perform addPort");
return;
}
if (vmiInfo.vmInfo == null) {
s_logger.error("Null vmInfo, cannot perform addPort for " + vmiInfo);
return;
}
if (vmiInfo.vnInfo == null) {
s_logger.error("Null vnInfo, cannot perform addPort for " + vmiInfo);
return;
}
if (vmiInfo.getUuid() == null) {
s_logger.error("Null uuid, cannot perform addPort for " + vmiInfo);
return;
}
String vrouterIpAddress = vmiInfo.getVmInfo().getVrouterIpAddress();
String ipAddress = vmiInfo.getIpAddress();
VirtualMachineInfo vmInfo = vmiInfo.vmInfo;
VirtualNetworkInfo vnInfo = vmiInfo.vnInfo;
if (vrouterIpAddress == null) {
s_logger.error(
"addPort notification NOT sent as vRouterIp Address not known for " + vmiInfo);
return;
}
if (!vmInfo.isPoweredOnState()) {
s_logger.info(vmInfo + " is PoweredOff. Skip AddPort now for " + vmiInfo);
return;
}
if (ipAddress == null) {
ipAddress = "0.0.0.0";
}
try {
ContrailVRouterApi vrouterApi = getVrouterApi(vrouterIpAddress);
boolean ret = vrouterApi.addPort(vmiInfo.getUuid(),
vmInfo.getUuid(), vmiInfo.getUuid(),
ipAddress,
vmiInfo.getMacAddress(),
vnInfo.getUuid(),
vnInfo.getPrimaryVlanId(),
vnInfo.getIsolatedVlanId(),
vmInfo.getDisplayName(),
vnInfo.getProjectUuid());
if (ret) {
s_logger.info("vRouter " + vrouterIpAddress + " addPort success for " + vmiInfo);
} else {
// log failure but don't worry. Periodic KeepAlive task will
// attempt to connect to vRouter Agent and replay AddPorts.
s_logger.warn("vRouter " + vrouterIpAddress + " addPort failed for " + vmiInfo);
}
} catch(Throwable e) {
s_logger.warn("vRouter " + vrouterIpAddress + " Exception in addPort for "
+ vmiInfo + ": " + e.getMessage());
s_logger.error(Throwables.getStackTraceAsString(e));
}
}
public static void deleted(VirtualMachineInterfaceInfo vmiInfo) {
if (vmiInfo == null) {
s_logger.error("Null vmiInfo argument, cannot perform deletePort");
return;
}
if (vmiInfo.vmInfo == null) {
s_logger.error("Null vmInfo, cannot perform deletePort for " + vmiInfo);
return;
}
if (vmiInfo.vnInfo == null) {
s_logger.error("Null vnInfo, cannot perform deletePort for " + vmiInfo);
return;
}
if (vmiInfo.getUuid() == null) {
s_logger.error("Null uuid, cannot perform deletePort for " + vmiInfo);
return;
}
String vrouterIpAddress = vmiInfo.getVmInfo().getVrouterIpAddress();
String ipAddress = vmiInfo.getIpAddress();
if (vrouterIpAddress == null) {
s_logger.error(
"deletePort notification NOT sent as vRouterIp Address not known for " + vmiInfo);
return;
}
if (ipAddress == null) {
ipAddress = "0.0.0.0";
}
ContrailVRouterApi vrouterApi = getVrouterApi(vrouterIpAddress);
boolean ret = vrouterApi.deletePort(vmiInfo.getUuid());
if (ret) {
s_logger.info("vRouter " + vrouterIpAddress +
" DeletePort success for " + vmiInfo);
} else {
// log failure but don't worry. Periodic KeepAlive task will
// attempt to connect to vRouter Agent and replay DeletePorts.
s_logger.warn("vRouter " + vrouterIpAddress + " DeletePort failed for " + vmiInfo);
}
}
private static ContrailVRouterApi getVrouterApi(String vrouterIpAddress) {
ContrailVRouterApi vrouterApi = null;
if (vrouterApiMap.containsKey(vrouterIpAddress)) {
vrouterApi = vrouterApiMap.get(vrouterIpAddress);
}
if (vrouterApi == null) {
vrouterApi = new ContrailVRouterApi(vrouterIpAddress, vrouterApiPort);
vrouterApiMap.put(vrouterIpAddress, vrouterApi);
}
return vrouterApi;
}
// KeepAlive with all active vRouter Agent Connections.
public static void vrouterAgentPeriodicConnectionCheck() {
for (Map.Entry<String, ContrailVRouterApi> entry: vrouterApiMap.entrySet()) {
String vrouterIpAddress = entry.getKey();
ContrailVRouterApi vrouterApi = getVrouterApi(vrouterIpAddress);
if (!vrouterApi.getActive()) {
// host is in maintenance mode or Contrail VM is down
continue;
}
if (!vrouterApi.periodicCheck()) {
s_logger.warn(vrouterIpAddress + " periodic check failed");
}
}
}
public static void syncVrouterAgent() {
for (Map.Entry<String, ContrailVRouterApi> entry: vrouterApiMap.entrySet()) {
String vrouterIpAddress = entry.getKey();
ContrailVRouterApi vrouterApi = getVrouterApi(vrouterIpAddress);
if (!vrouterApi.getActive()) {
// host is in maintenance mode or Contrail VM is down
continue;
}
boolean ret = vrouterApi.sync();
if (ret) {
s_logger.info("vRouter " + vrouterIpAddress +
" sync request success");
} else {
// log failure but don't worry. Periodic task will
// attempt to connect to vRouter Agent and replay sync.
s_logger.warn("vRouter " + vrouterIpAddress + " sync request failed");
}
}
}
public static void setVrouterActive(String vrouterIpAddress, boolean active) {
ContrailVRouterApi vrouterApi = getVrouterApi(vrouterIpAddress);
vrouterApi.setActive(active);
}
}