summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/dnbd3/DNBD3Server.java
blob: 36646b5f97bb926a02ed733e01f8f303228e1970 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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<DNBD3Image> getImages() throws IOException, DNBD3Exception {
        List<DNBD3Image> images = new ArrayList<DNBD3Image>();
        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<Element> 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<DNBD3Client> getClients() throws IOException, DNBD3Exception {
        List<DNBD3Client> clients = new ArrayList<DNBD3Client>();
        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<Element> 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...");
        }
    }

}