package org.openslx.dnbd3; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.nio.ByteBuffer; import java.util.List; import org.openslx.dnbd3.xml.Client; import org.openslx.dnbd3.xml.Image; import org.openslx.dnbd3.xml.Info; import org.simpleframework.xml.core.Persister; 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 CMDADDIMG = 3; private static final int CMDDELIMG = 4; private static final String HOST = "127.0.0.1"; private static final int PORT = 5004; public void doReload() throws IOException, DNBD3Exception { sndCommand(CMDRELOAD); } public void doShutdown() throws IOException, DNBD3Exception { sndCommand(CMDSTOP); } public void addImage(Image image) throws Exception { Info info = new Info(); info.getImages().add(image); sndData(CMDADDIMG, info); doReload(); } public void delImage(Image image) throws Exception { Info info = new Info(); info.getImages().add(image); sndData(CMDDELIMG, info); doReload(); } public List getImages() throws Exception { return rcvData().getImages(); } public List getClients() throws Exception { return rcvData().getClients(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void sndCommand(int cmd) throws IOException, DNBD3Exception { Socket sock = new Socket(HOST, PORT); sndHeader(sock, new DNBD3Header(cmd, 0, 0)); rcvHeader(sock); sock.close(); } private void sndData(int cmd, Info info) throws Exception { ByteArrayOutputStream os = new ByteArrayOutputStream(); new Persister().write(info, os); Socket sock = new Socket(HOST, PORT); sndHeader(sock, new DNBD3Header(cmd, os.size(), 0)); sock.getOutputStream().write(os.toByteArray()); rcvHeader(sock); sock.close(); } private Info rcvData() throws Exception { Socket sock = new Socket(HOST, PORT); sndHeader(sock, new DNBD3Header(CMDINFO, 0, 0)); rcvHeader(sock); Info info = new Persister().read(Info.class, sock.getInputStream()); sock.close(); return info; } private void sndHeader(Socket sock, DNBD3Header header) throws IOException { OutputStream os = sock.getOutputStream(); os.write(header.toByteArray()); } private DNBD3Header rcvHeader(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_FILE_NOT_FOUND: throw new DNBD3Exception(DNBD3Header.ERROR_FILE_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"); case DNBD3Header.ERROR_IMAGE_NOT_FOUND: throw new DNBD3Exception(DNBD3Header.ERROR_IMAGE_NOT_FOUND, "Image does not exist"); case DNBD3Header.ERROR_RID: throw new DNBD3Exception(DNBD3Header.ERROR_RID, "Delete with rid=0 is not allowed"); case DNBD3Header.ERROR_IMAGE_IN_USE: throw new DNBD3Exception(DNBD3Header.ERROR_IMAGE_IN_USE, "Image is in use"); default: throw new DNBD3Exception(DNBD3Header.ERROR_UNKNOWN, "Unknown error, something went horribly wrong..."); } } }