package com.netflix.priam.cassandra;

import com.netflix.priam.utils.SystemUtils;
import org.apache.cassandra.thrift.CassandraDaemon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class NFThinCassandraDaemon extends CassandraDaemon {
    private static final Logger logger = LoggerFactory.getLogger(NFThinCassandraDaemon.class);

    /**
     * Initialize the Cassandra Daemon based on the given command-line
     * arguments. This is the normal {@code java} entry point.
     *
     * @param args the arguments passed on the command-line
     */
    public static void main(String[] args) {
        NFThinCassandraDaemon daemon = new NFThinCassandraDaemon();
        daemon.setPriamProperties();
        daemon.activate();
    }

    /**
     * Initialize the Cassandra Daemon based on the given <a
     * href="http://commons.apache.org/daemon/jsvc.html">Commons
     * Daemon</a>-specific arguments. To clarify, this is a hook for
     * JSVC and serves as a second entry point.
     *
     * @param args the arguments passed in from JSVC
     * @throws IOException
     */
    @Override
    public void init(String[] args) throws IOException {
        setPriamProperties();
        super.init(args);
    }

    private void setPriamProperties() {
        String token = null;
        String seeds = null;
        boolean isReplace = false;
        while (true) {
            try {
                token = SystemUtils.getDataFromUrl("http://127.0.0.1:8080/v1/cassconfig/get_token");
                seeds = SystemUtils.getDataFromUrl("http://127.0.0.1:8080/v1/cassconfig/get_seeds");
                isReplace = Boolean.parseBoolean(SystemUtils.getDataFromUrl("http://127.0.0.1:8080/v1/cassconfig/is_replace_token"));
            } catch (Exception e) {
                logger.error("Failed to obtain a token from a pre-defined list, we can not start!", e);
            }

            if (token != null && seeds != null) {
                break;
            }
            // sleep for 5 sec and try again.
            try {
                Thread.sleep(5 * 1000);
            } catch (InterruptedException e1) {
                // do nothing.
            }
        }

        System.setProperty("cassandra.initial_token", token);

        if (isReplace) {
            System.setProperty("cassandra.replace_token", token);
        }
    }
}

@@ -185,16 +185,95 @@
 ctory;%0A%0A
+import java.io.BufferedWriter;%0Aimport java.io.File;%0Aimport java.io.FileWriter;%0A
 import j
@@ -292,16 +292,16 @@
 eption;%0A
-
 %0Apublic 
@@ -1290,32 +1290,64 @@
 amProperties();%0A
+        protectFromOomKiller();%0A
         super.in
@@ -2407,24 +2407,24 @@
 sReplace) %7B%0A
-
             
@@ -2492,11 +2492,499 @@
  %7D%0A    %7D
+%0A%0A    private void protectFromOomKiller() %7B%0A        File oomAdj = new File(%22/proc/self/oom_adj%22);%0A%0A        if (!oomAdj.exists()) %7B%0A            return;%0A        %7D%0A%0A        try %7B%0A            BufferedWriter oomAdjWriter = new BufferedWriter(new FileWriter(oomAdj));%0A            // oom_adj ranges from -17 to 15%0A            oomAdjWriter.write(%22-16%22);%0A            oomAdjWriter.close();%0A        %7D catch (IOException e) %7B%0A            logger.warn(%22Failed to write OOM adjust.%22, e);%0A        %7D%0A    %7D
 %0A%7D%0A

Decrease likelihood of oom-killer targeting Cassandra.