package org.ovirt.engine.core.vdsbroker.gluster;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.ovirt.engine.core.common.businessentities.gluster.GeoRepCrawlStatus;
import org.ovirt.engine.core.common.businessentities.gluster.GeoRepSessionStatus;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSession;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSessionDetails;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterServer;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dao.gluster.GlusterDBUtils;
import org.ovirt.engine.core.di.Injector;
import org.ovirt.engine.core.vdsbroker.irsbroker.StatusReturn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GlusterVolumeGeoRepStatus extends StatusReturn {
protected static final Logger log = LoggerFactory.getLogger(GlusterVolumeGeoRepStatus.class);
protected static final String VOLUME_NAME = "volumeName";
protected static final String BRICKS = "bricks";
private static final String SESSIONS = "sessions";
private static final String SESSION_KEY = "sessionKey";
private static final String HOST_UUID = "hostUuid";
private static final String BRICK_NAME = "brickName";
private static final String REMOTE_HOST = "remoteHost";
private static final String STATUS = "status";
private static final String CHECK_POINT_STATUS = "checkpointStatus";
private static final String CRAWL_STATUS = "crawlStatus";
private static final String REMOTE_VOL_NAME = "remoteVolumeName";
protected final List<GlusterGeoRepSession> geoRepSessions = new ArrayList<>();
protected GlusterGeoRepSessionDetails getSessionDetails(Map<String, Object> innerMap) {
GlusterGeoRepSessionDetails details = new GlusterGeoRepSessionDetails();
Guid masterNodeGlusterId;
if (innerMap.containsKey(HOST_UUID)) {
masterNodeGlusterId = new Guid(innerMap.get(HOST_UUID).toString());
} else {
log.error("Master node uuid is not available");
return null;
}
String masterBrickDir = innerMap.containsKey(BRICK_NAME) ? innerMap.get(BRICK_NAME).toString() : null;
GlusterServer glusterServer = getDbUtils().getServerByUuid(masterNodeGlusterId);
if (glusterServer != null) {
GlusterBrickEntity brick =
getDbUtils().getGlusterBrickByServerUuidAndBrickDir(glusterServer.getId(), masterBrickDir);
if (brick != null) {
details.setMasterBrickId(brick.getId());
}
}
if (details.getMasterBrickId() == null) {
log.error("Brick information could not be retrieved for gluster host id {} and brick dir {}",
masterNodeGlusterId,
masterBrickDir);
}
String slave = innerMap.containsKey(REMOTE_HOST) ? innerMap.get(REMOTE_HOST).toString() : null;
details.setSlaveHostName(slave);
details.setStatus(GeoRepSessionStatus.from((String) innerMap.get(STATUS)));
details.setCrawlStatus(GeoRepCrawlStatus.from((String) innerMap.get(CRAWL_STATUS)));
details.setCheckPointStatus((String) innerMap.get(CHECK_POINT_STATUS));
return details;
}
protected GlusterGeoRepSession getSession(String masterVolumeName, Map<String, Object> innerMap) {
GlusterGeoRepSession geoRepSession = new GlusterGeoRepSession();
// sessionKey in the form - the uuid is the gluster server uuid on master
// <sessionKey>11ae7a03-e793-4270-8fc4-b42def8b3051:ssh://192.168.122.14::slave2:bd52ddf1-9659-4168-8197-c62e9f3e855c</sessionKey>
String sessionKey = (String) innerMap.get(SESSION_KEY);
String[] sessSplit = sessionKey.split("([://]+)");
// Older gluster versions doesn't have slave volume ID in the sessionKey, it is added in Glusterfs 3.7.12
String slaveNode = sessSplit[2];
if(slaveNode.contains("@")) {
String[] hostComponents = slaveNode.split("@");
slaveNode = hostComponents[hostComponents.length - 1];
geoRepSession.setUserName(hostComponents[0]);
}
String slaveVolume = (String) innerMap.get(REMOTE_VOL_NAME);
geoRepSession.setSlaveHostName(slaveNode);
geoRepSession.setSlaveVolumeName(slaveVolume);
geoRepSession.setSessionKey(sessionKey);
geoRepSession.setMasterVolumeName(masterVolumeName);
return geoRepSession;
}
private GlusterDBUtils getDbUtils() {
return Injector.get(GlusterDBUtils.class);
}
@SuppressWarnings("unchecked")
protected void populateSessions(Map<String, Object> geoRepVolSessions) {
for (Entry<String, Object> entry : geoRepVolSessions.entrySet()) {
log.debug("received session information for volume '{}'", entry.getKey());
String masterVolName = entry.getKey();
Map<String, Object> sessionsMap = (Map<String, Object>) entry.getValue();
if (sessionsMap.containsKey(SESSIONS)) {
for (Object session : (Object[]) sessionsMap.get(SESSIONS)) {
geoRepSessions.add(populateSession(masterVolName, (Map<String, Object>) session));
}
}
}
}
private GlusterGeoRepSession populateSession(String volumeName, Map<String, Object> innerMap) {
GlusterGeoRepSession geoRepSession = getSession(volumeName, innerMap);
ArrayList<GlusterGeoRepSessionDetails> geoRepSessionDetails = new ArrayList<>();
if (innerMap.containsKey(BRICKS)) {
for (Object brickSession : (Object[]) innerMap.get(BRICKS)) {
geoRepSessionDetails.add(getSessionDetails((Map<String, Object>) brickSession));
}
}
geoRepSession.setSessionDetails(geoRepSessionDetails);
return geoRepSession;
}
public GlusterVolumeGeoRepStatus(Map<String, Object> innerMap) {
this(innerMap, true);
}
public GlusterVolumeGeoRepStatus(Map<String, Object> innerMap, boolean includeSessions) {
super(innerMap);
if (includeSessions && innerMap.containsKey(SESSIONS)) {
populateSessions((Map<String, Object>) innerMap.get(SESSIONS));
}
}
public List<GlusterGeoRepSession> getGeoRepSessions() {
return geoRepSessions;
}
}