All Downloads are FREE. Search and download functionalities are using the official Maven repository.

automately.core.Automately Maven / Gradle / Ivy

package automately.core;

import automately.core.data.Job;
import automately.core.data.Meta;
import automately.core.data.User;
import automately.core.file.VirtualFile;
import automately.core.file.VirtualFileService;
import automately.core.services.api.ApiServer;
import automately.core.services.core.AutomatelyService;
import automately.core.services.job.JobServer;
import automately.core.services.job.script.objects.network.http.HttpServerService;
import automately.core.services.sdk.SdkSockJSServer;
import automately.core.services.sdk.eventbus.SdkAuthManager;
import automately.core.services.sdk.eventbus.SdkEventManager;
import automately.core.data.UserData;
import com.hazelcast.core.IMap;
import io.jcluster.JCluster;
import io.jcluster.core.Cluster;
import io.jcluster.core.ClusterService;
import io.jcluster.core.Config;
import io.jcluster.core.Logger;
import io.jsync.json.JsonObject;
import io.jsync.utils.CryptoUtils;
import org.apache.commons.lang3.ArrayUtils;

import java.util.Date;
import java.util.concurrent.Executors;

/**
 * Automately is a JCluster application that extends the main JCluster class from jsync.io
 * This is a static class therefor you cannot create an instance of Automately but you can access
 * the default instance of Automately via Automately.instance();
 */
public class Automately extends JCluster {

    static {
        System.setProperty("async.pool.eventloop.size", String.valueOf(Runtime.getRuntime().availableProcessors() * 5));
        System.setProperty("async.pool.worker.size", String.valueOf(Runtime.getRuntime().availableProcessors() * 20));
    }

    /**
     * Running Automately.main will result in the initialization of the default Automately instance
     * and will join the JCluster cluster by default
     *
     * @param args the jcluster arguments that you want to use
     * @throws Exception
     */
    public static void main(final String[] args) throws Exception {
        // Automately calls this by default... if we launch from the main..
        // If not JCluster calls it.
        // Default Implementation.

        Automately instance = new Automately();
        instance.initialize(ArrayUtils.add(args, "--join"));
    }

    @Override
    public void prepareConfig(Config config) {
        if (config.isDefault()) {
            config.setRole("all");
        }
        if (!config.rawConfig().containsField("automately")) {
            config.rawConfig().putObject("automately", new JsonObject());
        }
        if (!config.rawConfig().getObject("automately").containsField("core")) {
            config.rawConfig().getObject("automately")
                    .putObject("core", new JsonObject());
        }

    }

    @Override
    public void prepareCluster(Cluster cluster) {

        /**
         * This service is required so we can initialize some things
         * at the startup of the cluster. This is IMPORTANT.
         */
        ClusterService baseService = new AutomatelyService() {
            @Override
            public String name() {
                return "AutomatelyBaseServices";
            }

            @Override
            public void start(Cluster cluster) {

                Logger logger = cluster().logger();

                IMap users = cluster().data().persistentMap("users");
                IMap userMeta = cluster().data().persistentMap("users.meta");
                IMap jobs = cluster().data().persistentMap("jobs");
                IMap files = cluster().data().persistentMap("files");

                users.addIndex("token", false);
                users.addIndex("username", false);
                users.addIndex("created", true);

                userMeta.addIndex("userToken", false);
                userMeta.addIndex("key", false);

                jobs.addIndex("userToken", false);
                jobs.addIndex("token", false);
                jobs.addIndex("service", false);
                jobs.addIndex("lite", false);
                jobs.addIndex("status", false);
                jobs.addIndex("updated", true);

                files.addIndex("userToken", false);
                files.addIndex("token", false);
                files.addIndex("name", false);
                files.addIndex("pathAlias", false);
                files.addIndex("updated", true);
                files.addIndex("isPublic", false);


                Executors.newSingleThreadExecutor().submit(() -> {

                    logger.info("Checking for admin user");
                    // Honestly we really don't care what server we are.
                    // We still need a darn admin user.
                    if (UserData.getUserByUsername("admin") == null) { // We want to ensure the data member creates this user
                        User user = new User();
                        user.username = "admin";
                        user.admin = true;
                        user.enabled = true;
                        users().set(user.token(), user);

                        UserData.setUserPassword(user, "ChangeMe123");
                        UserData.setMetaDefaults(user);
                    }

                    User adminUser = UserData.getUserByUsername("admin");

                    if (adminUser != null) {
                        logger.info("The admin user private key is " + adminUser.key);
                        logger.info("The admin user public key is " + adminUser.publicKey);

                        if (!UserData.containsMeta(adminUser, "password")) {
                            String password = CryptoUtils.calculateHmacSHA1("ChangeMe123", adminUser.username);
                            UserData.setMeta(adminUser, "password", password);
                        }
                    }
                    if (!cluster.data().getMap("global.temp.data").containsKey("systemStart")) {
                        cluster.data().getMap("global.temp.data").put("systemStart", new Date().getTime());
                    }

                });
            }

            @Override
            public void stop() {

            }

        };

        try {

            Config config = cluster.config();

            cluster.addService(baseService);

            /**
             * Add VirtualFileSupport. This needs to be on every member of the cluster and loaded before any other member
             */
            cluster.addService(new VirtualFileService());
            cluster.addService(new HttpServerService());

            // JCluster Roles: default, all, client, data

            // Automately Roles: all, api, job, screenshot

            // All members of the cluster have the JobServer service
            // We don't need to add special services for the job
            cluster.addService(new JobServer());
            //cluster.addService(new VirtualSshServer());

            if (config.isRole("api")) {
                cluster.addService(new ApiServer());
                cluster.addService(new SdkAuthManager());
                cluster.addService(new SdkEventManager());
                cluster.addService(new SdkSockJSServer());
                // Disabling this because it is experimental
                //cluster.addService(new VirtualSshServer());
            } else if (config.isRole("sdk")) {
                cluster.addService(new SdkAuthManager());
                cluster.addService(new SdkEventManager());
                cluster.addService(new SdkSockJSServer());
            } else if (config.isAll()) {
                // API Server
                cluster.addService(new ApiServer());
                // SDK Server
                cluster.addService(new SdkAuthManager());
                cluster.addService(new SdkEventManager());
                cluster.addService(new SdkSockJSServer());
                // Disabling this because it is experimental
                //cluster.addService(new VirtualSshServer());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public final void initialize(String... args) {
        try {
            JCluster.launch(this, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * This is a helper method to return the core automately configuration
     *
     * @return returns a JsonObject that contains all the data in {automately:{core:{}}}
     */
    private JsonObject coreConfig() {
        return cluster().config().rawConfig().getObject("automately").getObject("core");
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy