/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.intel.mtwilson.ms.business;
import com.intel.mtwilson.i18n.ErrorCode;
import com.intel.mtwilson.datatypes.*;
import com.intel.mtwilson.ms.common.MSConfig;
import com.intel.mtwilson.ms.common.MSException;
import com.intel.mtwilson.ms.MSComponentFactory;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author rksavinx
*/
public class BulkHostRegBO {
private Logger log = LoggerFactory.getLogger(getClass());
private HostBO hostBO = MSComponentFactory.getHostBO();
private int timeout;
private static ExecutorService scheduler = Executors.newFixedThreadPool(MSConfig.getConfiguration().getInt("mtwilson.ms.bulkmgmt.threads.max", 32)); // bug #503 move thread pool to static so multiple requests do not overload it;
public BulkHostRegBO() {
timeout = MSConfig.getConfiguration().getInt("mtwilson.ms.registration.hostTimeout", 600);
}
public BulkHostRegBO(int timeout) {
this.timeout = timeout;
}
/**
* This function handles multithread calls for the register hosts functionality.
* @param hostRecords - List of the hosts that need to be added/updated.
* @return
*/
public HostConfigResponseList registerHosts(TxtHostRecordList hostRecords) {
HostConfigResponseList hostResponses = new HostConfigResponseList();
ArrayList<Future<?>> taskStatus = new ArrayList<Future<?>>();
Set<HostMgmt> tasks = new HashSet<HostMgmt>();
try {
for (TxtHostRecord hostRecord : hostRecords.getHostRecords()) {
HostMgmt task = new HostMgmt(hostBO, hostRecord);
tasks.add(task);
Future<?> status = scheduler.submit(task);
taskStatus.add(status);
}
// The purpose of this below loop is to ensure that all the threads have completed processing.
// If in case we catch an exception from any one of them, we will log the same and continue. Since
// we submitted the Runnable tasks we won't get back the status in this loop.
for (Future<?> status : taskStatus) {
try {
status.get(timeout, TimeUnit.SECONDS);
} catch (Exception ex) {
log.error("Exception while retrieving the status of the task. {}.", ex.getMessage());
}
}
// Retrieve the status from all the threads and return back to the user.
for (HostMgmt task : tasks) {
if (task.getResult() == null) {
hostResponses.getHostRecords().add(task.getTimeoutResult());
} else {
hostResponses.getHostRecords().add(task.getResult());
}
}
return hostResponses;
} catch (Exception ex) {
// throw new MSException(ex);
log.error("Error during bulk host registration. ", ex);
throw new MSException(ErrorCode.MS_BULK_REGISTRATION_ERROR, ex.getClass().getSimpleName());
}
}
private class HostMgmt implements Runnable {
private HostBO dao;
private TxtHostRecord hostObj;
private HostResponse result;
private String hostName;
private boolean isError = false;
public HostMgmt(HostBO dao, TxtHostRecord hostObj) {
this.dao = dao;
this.hostObj = hostObj;
this.hostName = hostObj.HostName;
}
@Override
public void run() {
if (isError()) {
return;
}
try {
boolean success = dao.registerHost(hostObj);
if (success)
result = new HostResponse(ErrorCode.OK);
else
result = new HostResponse(ErrorCode.UNKNOWN_ERROR);
} catch (MSException e) {
isError = true;
result = new HostResponse();
result.setErrorCode(e.getErrorCode().toString());
result.setErrorMessage(e.getErrorMessage());
} catch (Exception e) {
isError = true;
log.error("Error during bulk host registration. ", e);
result = new HostResponse(ErrorCode.MS_BULK_REGISTRATION_ERROR, e.getClass().getSimpleName());
}
}
public boolean isError() {
return isError;
}
public HostConfigResponse getResult() {
HostConfigResponse hostResponse = new HostConfigResponse();
hostResponse.setHostName(hostName);
hostResponse.setErrorCode(result.getErrorCodeEnum());
if (result.getErrorCodeEnum() == ErrorCode.OK) {
hostResponse.setStatus(Boolean.toString(true));
hostResponse.setErrorMessage("");
} else {
hostResponse.setStatus(Boolean.toString(false));
hostResponse.setErrorMessage(result.getErrorMessage());
}
return hostResponse;
}
public HostConfigResponse getTimeoutResult() {
HostConfigResponse hostResponse = new HostConfigResponse();
hostResponse.setHostName(hostName);
hostResponse.setErrorCode(ErrorCode.AS_ASYNC_TIMEOUT);
hostResponse.setStatus(Boolean.toString(false));
hostResponse.setErrorMessage("Exceeded timeout of " + timeout + " seconds");
return hostResponse;
}
}
}