All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aQute.remote.util.AgentSupervisor Maven / Gradle / Ivy

Go to download

A main program (executable JAR) that will listen to port 29998. At first, it can only answer that it is an Envoy (a limited agent). The only function it supports is installing a -runpath. It will then create a framework + agent and transfer the connection to the just installed agent who will then install the bundles. This JAR is a main command for JPM called bndremote. In JPM, it will start up with debug enabled. This JAR does some highly complicated class loading wizardy to ensure that it does not enforce any constraints on the -runpath.

The newest version!
package aQute.remote.util;

import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

import aQute.bnd.util.dto.DTO;
import aQute.lib.collections.MultiMap;
import aQute.lib.io.IO;
import aQute.libg.cryptography.SHA1;

/**
 * This is a base class that provides the basic functionality of a supervisor.
 * In general an actual supervisor extends this class to provide the
 * functionality to use on the client side.
 *
 * @param  The supervisor type
 * @param  The agent type
 */
public class AgentSupervisor {
	private static final Map			fileInfo	= new ConcurrentHashMap<>();
	private static final MultiMap	shaInfo		= new MultiMap<>();
	private static final int						connectWait	= 200;
	private static byte[]							EMPTY		= new byte[0];
	private Agent									agent;
	private CountDownLatch							latch		= new CountDownLatch(1);
	protected volatile int							exitCode;
	private Link					link;
	private AtomicBoolean							quit		= new AtomicBoolean(false);

	static class Info extends DTO {
		public String	sha;
		public long		lastModified;
	}

	protected void connect(Class agent, Supervisor supervisor, String host, int port) throws Exception {
		connect(agent, supervisor, host, port, -1);
	}

	protected void connect(Class agent, Supervisor supervisor, String host, int port, final int timeout)
		throws Exception {
		if (timeout < -1) {
			throw new IllegalArgumentException("timeout can not be less than -1");
		}

		int retryTimeout = timeout;

		while (true) {
			try {
				Socket socket = new Socket();
				socket.connect(new InetSocketAddress(host, port), Math.max(timeout, 0));
				link = new Link<>(agent, supervisor, socket);
				this.setAgent(link);
				link.open();
				return;
			} catch (ConnectException e) {
				if (retryTimeout == 0) {
					throw e;
				}
				if (retryTimeout > 0) {
					retryTimeout = Math.max(retryTimeout - connectWait, 0);
				}
				Thread.sleep(connectWait);
			}
		}
	}

	public byte[] getFile(String sha) throws Exception {
		List copy;
		synchronized (shaInfo) {
			List list = shaInfo.get(sha);
			if (list == null)
				return EMPTY;

			copy = new ArrayList<>(list);
		}
		for (String path : copy) {
			File f = new File(path);
			if (f.isFile()) {
				byte[] data = IO.read(f);
				return data;
			}
		}
		return EMPTY;
	}

	public void setAgent(Link link) {
		this.agent = link.getRemote();
		this.link = link;
	}

	public void close() throws IOException {
		if (quit.getAndSet(true))
			return;

		// link can be null in case of connection issues
		if (link != null && link.isOpen())
			link.close();

		latch.countDown();
	}

	public int join() throws InterruptedException {
		latch.await();
		return exitCode;
	}

	protected void exit(int exitCode) {
		this.exitCode = exitCode;
		try {
			close();
		} catch (Exception e) {
			// ignore
		}
	}

	public Agent getAgent() {
		return agent;
	}

	public String addFile(File file) throws NoSuchAlgorithmException, Exception {
		file = file.getAbsoluteFile();
		Info info = fileInfo.get(file);
		if (info == null) {
			info = new Info();
			fileInfo.put(file, info);
			info.lastModified = -1;
		}

		synchronized (shaInfo) {
			if (info.lastModified != file.lastModified()) {
				String sha = SHA1.digest(file)
					.asHex();
				if (info.sha != null && !sha.equals(info.sha))
					shaInfo.removeValue(info.sha, file.getAbsolutePath());
				info.sha = sha;
				info.lastModified = file.lastModified();
				shaInfo.add(sha, file.getAbsolutePath());
			}
			return info.sha;
		}
	}

	public boolean isOpen() {
		return link.isOpen();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy