1402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*******************************************************************************
2402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Copyright (c) 2000, 2006 IBM Corporation and others.
3402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * All rights reserved. This program and the accompanying materials
4402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * are made available under the terms of the Eclipse Public License v1.0
5402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * which accompanies this distribution, and is available at
6402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * http://www.eclipse.org/legal/epl-v10.html
7402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
8402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Contributors:
9402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *     IBM Corporation - initial API and implementation
10402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *******************************************************************************/
11402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*
12402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Created on 8-Jan-2004
13402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
14402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * To change this generated comment go to
15402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Window>Preferences>Java>Code Generation>Code Template
16402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
17402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpackage org.eclipse.releng;
18402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
19402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.File;
20402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.FileInputStream;
21402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.FileNotFoundException;
22402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.FileWriter;
23402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.IOException;
24402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.util.StringTokenizer;
25402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.util.Properties;
26402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.PrintWriter;
27402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
28402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
29402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @author SDimitrov
30402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
31402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * This class finds an available build machine by reading a registry of build
32402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * machines and their status.
33402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
34402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
35402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic class BuildMachineManager extends Thread {
36402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// registry mapping of machines being used by a given build
37402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	//list is the path to the configuration of build machines available for a
38402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// given build type
39402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// waitInterval is the number of seconds to wait if no machines are
40402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// available for a given build purpose
41402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// findKey represents the key in cfg from which which to obtain the list of
42402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// machines
43402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// createKey is written to the registry with the machine name that is
44402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// available
45402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
46402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String markerContainer;
47402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private int waitInterval;
48402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String markerName;
49402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String markerKey="0";
50402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String cfgKey;
51402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String cfg;
52402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
53402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	public BuildMachineManager() {
54402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		super();
55402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
56402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	public BuildMachineManager(
57402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String cfg,
58402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String markerContainer,
59402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int waitInterval,
60402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String markerName,
61402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String markerKey,
62402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String cfgKey) {
63402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.waitInterval = waitInterval;
64402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.cfg = cfg;
65402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.markerContainer = markerContainer;
66402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.markerName = markerName;
67402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.markerKey = markerKey;
68402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.cfgKey = cfgKey;
69402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.run();
70402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
71402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
72402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	public void run() {
73402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String[] machines = getNames();
74402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
75402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (new File(markerContainer+"/"+markerName+".marker").exists()){
76402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			System.out.println("Marker already exists: "+markerName+".marker");
77402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return;
78402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
79402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
80402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		boolean machineFound = false;
81402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		try {
82402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			while (!machineFound) {
83402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				for (int i = 0; i < machines.length; i++) {
84402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					if (!inUse(machines[i])) {
85402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						if (createNewMarker(machines[i])) {
86402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll							machineFound = true;
87402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll							return;
88402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						}
89402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					}
90402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				}
91402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
92402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				//wait a given interval before re-checking for an available
93402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				// build machine.
94402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				sleep(1000 * waitInterval);
95402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
96402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		} catch (InterruptedException e) {
97402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			e.printStackTrace();
98402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
99402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
100402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
101402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private boolean createNewMarker(String machineName) {
102402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		//create a temporary lock on marker container
103402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
104402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		File lock = new File(markerContainer + "/" + "lock");
105402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (lock.exists())
106402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return false;
107402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
108402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		try {
109402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			File markerFile =  new File(markerContainer+"/"+markerName+".marker");
110402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			lock.createNewFile();
111402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			markerFile.createNewFile();
112402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			PrintWriter out = new PrintWriter(new FileWriter(markerFile));
113402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			out.println(markerKey+"=" + machineName);
114402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			out.flush();
115402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			out.close();
116402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			lock.delete();
117402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		} catch (IOException e) {
118402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			e.printStackTrace();
119402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return false;
120402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
121402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		return true;
122402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
123402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
124402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private boolean inUse(String machineName) {
125402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
126402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		File container = new File(markerContainer);
127402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
128402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (container.exists() && container.isDirectory()) {
129402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			Properties properties = null;
130402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			File[] markerFiles = container.listFiles();
131402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			for (int i = 0; i < markerFiles.length; i++) {
132402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				File markerFile = markerFiles[i];
133402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				if (markerFile.getName().endsWith(".marker")) {
134402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					properties = new Properties();
135402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					try {
136402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						FileInputStream in = new FileInputStream(markerFiles[i]);
137402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						properties.load(in);
138402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						in.close();
139402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						if (properties.containsValue(machineName)){
140402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll							return true;
141402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						}
142402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					} catch (FileNotFoundException e) {
143402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						e.printStackTrace();
144402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					} catch (IOException e) {
145402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						e.printStackTrace();
146402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					}
147402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				}
148402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
149402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
150402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		return false;
151402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
152402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
153402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String[] getNames() {
154402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		StringTokenizer tokenizer = new StringTokenizer(getList(), ",");
155402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String[] names = new String[tokenizer.countTokens()];
156402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int i = 0;
157402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
158402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		while (tokenizer.hasMoreTokens()) {
159402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			names[i++] = tokenizer.nextToken();
160402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
161402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		return names;
162402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
163402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
164402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String getList() {
165402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		Properties cfgProperties = new Properties();
166402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		try {
167402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			FileInputStream in = new FileInputStream(new File(cfg));
168402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			cfgProperties.load(in);
169402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			in.close();
170402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
171402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		} catch (FileNotFoundException e) {
172402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			e.printStackTrace();
173402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		} catch (IOException e) {
174402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			e.printStackTrace();
175402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
176402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		return cfgProperties.getProperty(cfgKey);
177402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
178402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
179