package org.openslx.dnbd3; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import org.jdom2.Attribute; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.filter.Filters; import org.jdom2.input.SAXBuilder; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; import org.jdom2.xpath.XPathExpression; import org.jdom2.xpath.XPathFactory; public class DNBD3Server { private static final int CMDSTOP = 0; private static final int CMDRELOAD = 1; private static final int CMDINFO = 2; private static final int CMDCONFIG = 3; private static final String HOST = "127.0.0.1"; private static final int PORT = 5004; public void doReload() throws IOException, DNBD3Exception { Socket sock = new Socket(HOST, PORT); sendHeader(sock, new DNBD3Header(CMDRELOAD, 0, 0)); receiveHeader(sock); sock.close(); } public void doShutdown() throws IOException, DNBD3Exception { Socket sock = new Socket(HOST, PORT); sendHeader(sock, new DNBD3Header(CMDSTOP, 0, 0)); receiveHeader(sock); sock.close(); } public void addImage(DNBD3Image image) throws IOException, DNBD3Exception { Element rootNode = new Element("dnbd3-server"); Element imageNode = new Element("image"); imageNode.setAttribute(new Attribute("group", image.getGroup())); imageNode.setAttribute(new Attribute("atime", image.getAtime())); imageNode.setAttribute(new Attribute("vid", String.valueOf(image.getVid()))); imageNode.setAttribute(new Attribute("rid", String.valueOf(image.getRid()))); imageNode.setAttribute(new Attribute("file", image.getPath())); imageNode.setAttribute(new Attribute("servers", image.getServers())); imageNode.setAttribute(new Attribute("cache_file", image.getCache())); rootNode.addContent(imageNode); Document doc = new Document(rootNode); Socket sock = new Socket(HOST, PORT); OutputStream os = sock.getOutputStream(); XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat()); sendHeader(sock, new DNBD3Header(CMDCONFIG, outputter.outputString(doc).length(), 0)); outputter.output(doc, os); receiveHeader(sock); sock.close(); } public List getImages() throws IOException, DNBD3Exception { List images = new ArrayList(); Socket sock = new Socket(HOST, PORT); sendHeader(sock, new DNBD3Header(CMDINFO, 0, 0)); receiveHeader(sock); try { String group, atime, path, servers, cache; int vid, rid; InputStream is = sock.getInputStream(); SAXBuilder builder = new SAXBuilder(); Document document = (Document) builder.build(is); XPathFactory xpfac = XPathFactory.instance(); XPathExpression xp; xp = xpfac.compile("//dnbd3-server/images/image", Filters.element()); for (Element e : xp.evaluate(document)) { group = e.getAttributeValue("group"); atime = e.getAttributeValue("atime"); vid = Integer.parseInt(e.getAttributeValue("vid")); rid = Integer.parseInt(e.getAttributeValue("rid")); path = e.getAttributeValue("file"); servers = e.getAttributeValue("servers"); cache = e.getAttributeValue("cache_file"); images.add(new DNBD3Image(group, atime, vid, rid, path, servers, cache)); } } catch (JDOMException ex) { ex.printStackTrace(); } sock.close(); return images; } public List getClients() throws IOException, DNBD3Exception { List clients = new ArrayList(); Socket sock = new Socket(HOST, PORT); sendHeader(sock, new DNBD3Header(CMDINFO, 0, 0)); receiveHeader(sock); try { String ip, image; InputStream is = sock.getInputStream(); SAXBuilder builder = new SAXBuilder(); Document document = (Document) builder.build(is); XPathFactory xpfac = XPathFactory.instance(); XPathExpression xp; xp = xpfac.compile("//dnbd3-server/clients/client", Filters.element()); for (Element e : xp.evaluate(document)) { ip = e.getAttributeValue("ip"); image = e.getAttributeValue("file"); clients.add(new DNBD3Client(ip, image)); } } catch (JDOMException ex) { ex.printStackTrace(); } sock.close(); return clients; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void sendHeader(Socket sock, DNBD3Header header) throws IOException { OutputStream os = sock.getOutputStream(); os.write(header.toByteArray()); } private DNBD3Header receiveHeader(Socket sock) throws IOException, DNBD3Exception { DNBD3Header header = new DNBD3Header(); InputStream is = sock.getInputStream(); byte[] bytes = ByteBuffer.allocate(12).array(); is.read(bytes, 0, 12); header.fromByteArray(bytes); switch (header.getError()) { case 0: return header; case DNBD3Header.ERROR_IMAGE_NOT_FOUND: throw new DNBD3Exception(DNBD3Header.ERROR_IMAGE_NOT_FOUND, "Image file does not exist or is not readable"); case DNBD3Header.ERROR_IMAGE_ALREADY_EXISTS: throw new DNBD3Exception(DNBD3Header.ERROR_IMAGE_ALREADY_EXISTS, "Image with given vid and rid already exists"); case DNBD3Header.ERROR_CONFIG_FILE_PERMISSIONS: throw new DNBD3Exception(DNBD3Header.ERROR_CONFIG_FILE_PERMISSIONS, "Config file is not writable"); default: throw new DNBD3Exception(DNBD3Header.ERROR_UNKNOWN, "Unknown error, something went horribly wrong..."); } } }