aboutsummaryrefslogtreecommitdiff
path: root/agent/src/main/java/moe/yuuta/dn42peering/agent/Persistent.java
blob: 0f29da4e11ef634065c44e93aed091208bb93d74 (plain)
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
package moe.yuuta.dn42peering.agent;

import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.file.AsyncFile;
import io.vertx.core.file.OpenOptions;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;
import moe.yuuta.dn42peering.agent.proto.DeployResult;
import moe.yuuta.dn42peering.agent.proto.NodeConfig;

import javax.annotation.Nonnull;
import java.io.*;

public class Persistent {
    private static final Logger logger = LoggerFactory.getLogger(Persistent.class.getSimpleName());

    public static boolean enabled(@Nonnull Vertx vertx) {
        return vertx.getOrCreateContext().config().getBoolean("persistent", false);
    }

    @Nonnull
    public static String getPath(@Nonnull Vertx vertx) {
        return vertx.getOrCreateContext().config().getString("persistent_path",
                "/var/lib/dn42peering/agent/config");
    }

    public static Future<DeployResult> recover(@Nonnull Vertx vertx) {
        if(!enabled(vertx)) {
            logger.info("Persistent disabled.");
            return Future.succeededFuture(null);
        }
        if(!new File(getPath(vertx)).exists()) {
            logger.info("Persistent file is not found.");
            return Future.succeededFuture(null);
        }
        return vertx.<NodeConfig>executeBlocking(f -> {
            logger.info("Recovering from persistent state...");
            try(final InputStream in = new FileInputStream(getPath(vertx))) {
                final NodeConfig config = NodeConfig.parseDelimitedFrom(in);
                f.complete(config);
            } catch (IOException e) {
                f.fail(e);
            }
        }).compose(config -> Deploy.deploy(vertx, config))
                .onSuccess(res ->
                        logger.info("Recovered from persistent state."));
    }

    @Nonnull
    public static Future<Void> persistent(@Nonnull Vertx vertx, @Nonnull NodeConfig config) {
        if (!enabled(vertx)) return Future.succeededFuture();
        return vertx.fileSystem()
                .open(getPath(vertx),
                        new OpenOptions()
                                .setWrite(true)
                                .setCreate(true))
                .<AsyncFile>compose(file -> {
                    return vertx.executeBlocking(f -> {
                        try {
                            final ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            config.writeDelimitedTo(stream);
                            file.write(Buffer.buffer(stream.toByteArray()));
                            stream.close();
                            f.complete(file);
                        } catch (IOException e) {
                            f.fail(e);
                        }
                    });
                })
                .compose(AsyncFile::close)
                .compose(file ->
                        vertx.fileSystem().chmod(getPath(vertx), "rw-------"))
                .onFailure(err -> logger.error("Cannot persistent node configuration", err));
    }
}