<commit_before>package fi.csc.microarray.messaging;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.jms.JMSException;

import org.apache.log4j.Logger;

import fi.csc.microarray.messaging.AdminAPI.NodeStatus.Status;
import fi.csc.microarray.messaging.message.CommandMessage;
import fi.csc.microarray.messaging.message.ChipsterMessage;

/**
 * AdminAPI objects should be used only from a one thread.
 * 
 * @author <NAME>
 *
 */
public class AdminAPI {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(AdminAPI.class);

	private static final int SERVICE_CHECK_MAX_WAITTIME = 20;
	private static final int SERVICE_CHECK_MIN_WAITTIME = 5;
	
	public static final int NAME_PARAMETER_INDEX = 0;
	public static final int HOST_PARAMETER_INDEX = 1;

	public static interface AdminAPILIstener {
		public void statusUpdated(Map<String, NodeStatus> statuses);
	}
	
	public static class NodeStatus {

		public final String name;
		public String host = null;
		public Status status = Status.UNKNOWN;
		public int count = 0;
		public int requiredCount = 0;

		public enum Status {
			UP,
			DOWN,
			UNKNOWN;
		}
		
		public NodeStatus(String name) {
			this.name = name;
		}
		
		public NodeStatus(String name, int requiredCount) {
			this(name);
			this.requiredCount = requiredCount;
		}
	}

	private MessagingListener adminListener = new MessagingListener() {
		
		private Lock mutex = new ReentrantLock();
		
		public void onChipsterMessage(ChipsterMessage msg) {
			mutex.lock(); 
			try {
				CommandMessage cmdMsg = (CommandMessage) msg;
				if (cmdMsg.getCommand().equals("ping-reply")) {
					String name = cmdMsg.getParameters().get(NAME_PARAMETER_INDEX);
					String host = cmdMsg.getParameters().get(HOST_PARAMETER_INDEX);
					logger.debug(name + " is up");
					NodeStatus status = nodeStatuses.get(name);
					if (status != null) {
						if (status.host == null) {
							status.host = host;
						} else {
							status.host += ", " + host;
						}
						status.count += 1;
						if (status.count >= status.requiredCount) {
							status.status = Status.UP;
						}
						notifyListener();
					}		
				}
			} finally {
				mutex.unlock();
			}
		}
	};

	private MessagingTopic adminTopic;
	private Map<String, NodeStatus> nodeStatuses = new LinkedHashMap<String, NodeStatus>();
	private AdminAPILIstener listener; 
	private String errorStatus = "";
	
	public AdminAPI(MessagingTopic adminTopic, AdminAPILIstener listener) throws JMSException {
		this.listener = listener;
		this.adminTopic = adminTopic;
		adminTopic.setListener(adminListener);
		this.nodeStatuses.put("authenticator", new NodeStatus("authenticator"));
		this.nodeStatuses.put("analyser", new NodeStatus("analyser"));
		this.nodeStatuses.put("client", new NodeStatus("client"));
	}

	public void setRequiredCountFor(String nodeName, int requiredCount) {
		this.nodeStatuses.get(nodeName).requiredCount = requiredCount;
	}
	
	public String getErrorStatus() {
		return errorStatus;
	}

	/**
	 * Checks that analyser and frontend are up.
	 * 
	 * @return true iff services are up
	 * @throws JMSException 
	 */
	public boolean areAllServicesUp(boolean fastCheck) throws InterruptedException, JMSException {
		// send ping
		ping();		
		
		// start to wait for status changes
		boolean allServicesUp = false;		
		for (int seconds = 0; ; seconds++) {
			// wait a second
			Thread.sleep(1024);
			
			// check status
			allServicesUp = areAlreadyUp();
			
			// if we are satisfied, stop waiting<commit_msg>fixed error in filebroker check<commit_after>package fi.csc.microarray.messaging;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.jms.JMSException;

import org.apache.log4j.Logger;

import fi.csc.microarray.messaging.AdminAPI.NodeStatus.Status;
import fi.csc.microarray.messaging.message.CommandMessage;
import fi.csc.microarray.messaging.message.ChipsterMessage;

/**
 * AdminAPI objects should be used only from a one thread.
 * 
 * @author <NAME>
 *
 */
public class AdminAPI {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(AdminAPI.class);

	private static final int SERVICE_CHECK_MAX_WAITTIME = 20;
	private static final int SERVICE_CHECK_MIN_WAITTIME = 5;
	
	public static final int NAME_PARAMETER_INDEX = 0;
	public static final int HOST_PARAMETER_INDEX = 1;

	public static interface AdminAPILIstener {
		public void statusUpdated(Map<String, NodeStatus> statuses);
	}
	
	public static class NodeStatus {

		public final String name;
		public String host = null;
		public Status status = Status.UNKNOWN;
		public int count = 0;
		public int requiredCount = 0;

		public enum Status {
			UP,
			DOWN,
			UNKNOWN;
		}
		
		public NodeStatus(String name) {
			this.name = name;
		}
		
		public NodeStatus(String name, int requiredCount) {
			this(name);
			this.requiredCount = requiredCount;
		}
	}

	private MessagingListener adminListener = new MessagingListener() {
		
		private Lock mutex = new ReentrantLock();
		
		public void onChipsterMessage(ChipsterMessage msg) {
			mutex.lock(); 
			try {
				CommandMessage cmdMsg = (CommandMessage) msg;
				if (cmdMsg.getCommand().equals("ping-reply")) {
					String name = cmdMsg.getParameters().get(NAME_PARAMETER_INDEX);
					String host = cmdMsg.getParameters().get(HOST_PARAMETER_INDEX);
					logger.debug(name + " is up");
					NodeStatus status = nodeStatuses.get(name);
					if (status != null) {
						if (status.host == null) {
							status.host = host;
						} else {
							status.host += ", " + host;
						}
						status.count += 1;
						if (status.count >= status.requiredCount) {
							status.status = Status.UP;
						}
						notifyListener();
					}		
				}
			} finally {
				mutex.unlock();
			}
		}
	};

	private MessagingTopic adminTopic;
	private Map<String, NodeStatus> nodeStatuses = new LinkedHashMap<String, NodeStatus>();
	private AdminAPILIstener listener; 
	private String errorStatus = "";
	
	public AdminAPI(MessagingTopic adminTopic, AdminAPILIstener listener) throws JMSException {
		this.listener = listener;
		this.adminTopic = adminTopic;
		adminTopic.setListener(adminListener);
		this.nodeStatuses.put("authenticator", new NodeStatus("authenticator"));
		this.nodeStatuses.put("analyser", new NodeStatus("analyser"));
		this.nodeStatuses.put("filebroker", new NodeStatus("filebroker"));
		this.nodeStatuses.put("manager", new NodeStatus("manager"));
		this.nodeStatuses.put("client", new NodeStatus("client"));
	}

	public void setRequiredCountFor(String nodeName, int requiredCount) {
		this.nodeStatuses.get(nodeName).requiredCount = requiredCount;
	}
	
	public String getErrorStatus() {
		return errorStatus;
	}

	/**
	 * Checks that analyser and frontend are up.
	 * 
	 * @return true iff services are up
	 * @throws JMSException 
	 */
	public boolean areAllServicesUp(boolean fastCheck) throws InterruptedException, JMSException {
		// send ping
		ping();		
		
		// start to wait for status changes
		boolean allServicesUp = false;		
		for (int seconds = 0; ; seconds++) {
			// wait a second
			Thread.sleep(1024);
			
			// check status
			allServicesUp = areAlreadyUp();
			
			// if we are satisfied, stop waiting
{'fraction_non_alphanumeric': 0.10438074634937804, 'fraction_numerical': 0.0037858301784748512, 'mean_word_length': 3.726517571884984, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6812531', 'n_tokens_mistral': 2641, 'n_tokens_neox': 2206, 'n_words': 567}