com.smartitengineering.cms.maven.tools.plugin.StartMojo.java Source code

Java tutorial

Introduction

Here is the source code for com.smartitengineering.cms.maven.tools.plugin.StartMojo.java

Source

/*
 *
 * This is a simple Content Management System (CMS)
 * Copyright (C) 2011  Imran M Yousuf (imyousuf@smartitengineering.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.smartitengineering.cms.maven.tools.plugin;

import com.smartitengineering.util.rest.client.jersey.cache.CacheableClient;
import com.sun.jersey.api.client.Client;
import java.io.BufferedReader;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;

import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;

/**
 * Goal which starts the tools
 *
 * @author imyousuf
 * @goal start
 */
public class StartMojo extends AbstractMojo {

    /**
     * Solr HBase war artifact
     * @parameter
     */
    private ArtifactItem solrArtifact;
    /**
     * Event Hub HBase war artifact
     * @parameter
     */
    private ArtifactItem eventHubArtifact;
    /**
     * CMS Event Hub war artifact
     * @parameter
     */
    private ArtifactItem cmsWebServiceArtifact;
    /**
     * Location of the output files.
     * @parameter expression="${project.build.directory}"
     * @required
     */
    private File outputDirectory;
    /**
     * Location of the Solr config files.
     * @parameter 
     * @required
     */
    private File solrHomeDirectory;
    /**
     * Whether the tools will run in daemon mode
     * @parameter expression="false"
     * @required
     */
    private boolean daemonMode;
    private Integer jettyPort = 10080;
    /**
     * Embedded ZooKeeper port
     * @parameter expression="2181"
     * @required
     */
    private Integer zooKeeperPort;
    /**
     * Embedded tools port
     * @parameter expression="40404"
     * @required
     */
    private Integer embeddedPort;
    /**
     * HBase version
     * @parameter expression="${hbase.version}"
     * @required
     */
    private String hbaseVersion;
    /**
     * Hadoop Version
     * @parameter expression="${hadoop.version}"
     * @required
     */
    private String hadoopVersion;
    /**
     * Jersey version
     * @parameter expression="${jersey.version}"
     * @required
     */
    private String jerseyVersion;
    /**
     * @component
     */
    private ArtifactFactory factory;
    /**
     * Used to look up Artifacts in the remote repository.
     *
     * @component
     */
    protected ArtifactResolver resolver;
    /**
     * Location of the local repository.
     *
     * @parameter expression="${localRepository}"
     * @readonly
     * @required
     */
    protected ArtifactRepository local;
    /**
     * List of Remote Repositories used by the resolver
     *
     * @parameter expression="${project.remoteArtifactRepositories}"
     * @readonly
     * @required
     */
    protected List remoteRepos;
    /**
     * EventHub channel name
     * @parameter expression="test"
     * @required
     */
    private String eventHubChannelName;

    public String getEventHubChannelName() {
        return eventHubChannelName;
    }

    public void setEventHubChannelName(String eventHubChannelName) {
        this.eventHubChannelName = eventHubChannelName;
    }

    public String getJerseyVersion() {
        return jerseyVersion;
    }

    public void setJerseyVersion(String jerseyVersion) {
        this.jerseyVersion = jerseyVersion;
    }

    public String getHadoopVersion() {
        return hadoopVersion;
    }

    public void setHadoopVersion(String hadoopVersion) {
        this.hadoopVersion = hadoopVersion;
    }

    public String getHbaseVersion() {
        return hbaseVersion;
    }

    public void setHbaseVersion(String hbaseVersion) {
        this.hbaseVersion = hbaseVersion;
    }

    public ArtifactItem getEventHubArtifact() {
        return eventHubArtifact;
    }

    public void setEventHubArtifact(ArtifactItem eventHubArtifact) {
        this.eventHubArtifact = eventHubArtifact;
    }

    public ArtifactItem getSolrArtifact() {
        return solrArtifact;
    }

    public void setSolrArtifact(ArtifactItem solrArtifact) {
        this.solrArtifact = solrArtifact;
    }

    public boolean isDaemonMode() {
        return daemonMode;
    }

    public void setDaemonMode(boolean daemonMode) {
        this.daemonMode = daemonMode;
    }

    public File getOutputDirectory() {
        return outputDirectory;
    }

    public void setOutputDirectory(File outputDirectory) {
        this.outputDirectory = outputDirectory;
    }

    public void execute() throws MojoExecutionException {
        if (solrArtifact != null) {

            Artifact artifact = getArtifact(solrArtifact);
            File solrOutDir = new File(outputDirectory, "solr");
            solrOutDir.mkdirs();
            extract(artifact.getFile(), solrOutDir);
        }
        if (eventHubArtifact != null) {
            Artifact artifact = getArtifact(eventHubArtifact);
            File hubOutDir = new File(outputDirectory, "hub");
            hubOutDir.mkdirs();
            extract(artifact.getFile(), hubOutDir);
            File libDir = new File(new File(hubOutDir, "WEB-INF"), "lib");
            {
                new File(libDir, new StringBuilder("hbase-").append(hbaseVersion).append(".jar").toString())
                        .delete();
                new File(libDir, new StringBuilder("hadoop-core-").append(hadoopVersion).append(".jar").toString())
                        .delete();
                new File(libDir, new StringBuilder("jersey-core-").append(jerseyVersion).append(".jar").toString())
                        .delete();
                new File(libDir, new StringBuilder("jersey-json-").append(jerseyVersion).append(".jar").toString())
                        .delete();
                new File(libDir,
                        new StringBuilder("jersey-server-").append(jerseyVersion).append(".jar").toString())
                                .delete();
            }
        }
        if (cmsWebServiceArtifact != null) {
            Artifact artifact = getArtifact(cmsWebServiceArtifact);
            File cmsOutDir = new File(outputDirectory, "cms");
            cmsOutDir.mkdirs();
            extract(artifact.getFile(), cmsOutDir);
            File libDir = new File(new File(cmsOutDir, "WEB-INF"), "lib");
            {
                new File(libDir, new StringBuilder("hbase-").append(hbaseVersion).append(".jar").toString())
                        .delete();
                new File(libDir, new StringBuilder("hadoop-core-").append(hadoopVersion).append(".jar").toString())
                        .delete();
                new File(libDir, new StringBuilder("jersey-core-").append(jerseyVersion).append(".jar").toString())
                        .delete();
                new File(libDir, new StringBuilder("jersey-json-").append(jerseyVersion).append(".jar").toString())
                        .delete();
                new File(libDir,
                        new StringBuilder("jersey-server-").append(jerseyVersion).append(".jar").toString())
                                .delete();
            }
        }
        Thread thread = new Thread(new ToolsSuite());
        thread.start();
        if (!daemonMode) {
            try {
                thread.join();
            } catch (Exception ex) {
                getLog().warn(ex.getMessage(), ex);
            }
        }
    }

    protected Artifact getArtifact(ArtifactItem item) {
        VersionRange vr;
        try {
            vr = VersionRange.createFromVersionSpec(item.getVersion());
        } catch (InvalidVersionSpecificationException e1) {
            vr = VersionRange.createFromVersion(item.getVersion());
        }
        final Artifact artifact;
        if (StringUtils.isBlank(item.getClassifier())) {
            artifact = factory.createDependencyArtifact(item.getGroupId(), item.getArtifactId(), vr, item.getType(),
                    item.getClassifier(), Artifact.SCOPE_COMPILE);
        } else {
            artifact = factory.createDependencyArtifact(item.getGroupId(), item.getArtifactId(), vr, item.getType(),
                    null, Artifact.SCOPE_COMPILE);
        }
        try {
            resolver.resolve(artifact, remoteRepos, local);
        } catch (ArtifactResolutionException ex) {
            throw new IllegalArgumentException(ex);
        } catch (ArtifactNotFoundException ex) {
            throw new IllegalArgumentException(ex);
        }
        return artifact;
    }

    protected void extract(File jarFile, File outDir) {
        try {
            getLog().info(new StringBuilder("Extracting ").append(jarFile.getAbsolutePath()).append(" to ")
                    .append(outDir.getAbsolutePath()).toString());
            java.util.jar.JarFile jar = new java.util.jar.JarFile(jarFile);
            java.util.Enumeration enumeration = jar.entries();
            while (enumeration.hasMoreElements()) {
                java.util.jar.JarEntry file = (java.util.jar.JarEntry) enumeration.nextElement();
                final String str = new StringBuilder(outDir.getAbsolutePath()).append(File.separator)
                        .append(file.getName()).toString();
                File f = new File(str);
                if (file.isDirectory()) {
                    f.mkdir();
                    continue;
                }
                getLog().debug(new StringBuilder("Extracting ").append(file.getName()).append(" to ").append(str)
                        .toString());
                java.io.InputStream is = jar.getInputStream(file); // get the input stream
                java.io.FileOutputStream fos = new java.io.FileOutputStream(f);
                IOUtils.copy(is, fos);
                fos.close();
                is.close();
            }
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
    }

    class ToolsSuite implements Runnable {

        private MiniZooKeeperCluster zooKeeperCluster = new MiniZooKeeperCluster();
        private HBaseTestingUtility hBaseTestingUtility;
        private Server jettyServer;

        public ToolsSuite() {
            System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
                    "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
            try {
                zooKeeperCluster.setClientPort(zooKeeperPort);
                File file = new File(outputDirectory, "zk-server/");
                file.mkdirs();
                zooKeeperCluster.startup(file);
            } catch (Exception ex) {
                throw new IllegalStateException(ex);
            }
            try {
                hBaseTestingUtility = new HBaseTestingUtility();
                hBaseTestingUtility.setZkCluster(zooKeeperCluster);
                hBaseTestingUtility.startMiniCluster();
            } catch (Exception ex) {
                getLog().warn(ex.getMessage(), ex);
                try {
                    zooKeeperCluster.shutdown();
                } catch (Exception ex1) {
                    getLog().warn(ex1.getMessage(), ex1);
                }
                throw new IllegalStateException(ex);
            }
            try {
                jettyServer = new Server(jettyPort);
                HandlerList handlerList = new HandlerList();
                /*
                 * The following is for solr for later, when this is to be used it
                 */
                File solrOutDir = new File(outputDirectory, "solr");
                File hubOutDir = new File(outputDirectory, "hub");
                File cmsOutDir = new File(outputDirectory, "cms");
                if (solrArtifact != null) {
                    System.setProperty("solr.solr.home", solrHomeDirectory.getAbsolutePath());
                    Handler solr = new WebAppContext(solrOutDir.getAbsolutePath(), "/solr");
                    handlerList.addHandler(solr);
                }
                if (eventHubArtifact != null) {
                    WebAppContext hub = new WebAppContext(hubOutDir.getAbsolutePath(), "/hub");
                    final WebAppClassLoader webAppClassLoader = new WebAppClassLoader(hub);
                    hub.setClassLoader(webAppClassLoader);
                    handlerList.addHandler(hub);
                }
                if (cmsWebServiceArtifact != null) {
                    WebAppContext cms = new WebAppContext(cmsOutDir.getAbsolutePath(), "/cms");
                    final WebAppClassLoader cmsWebAppClassLoader = new WebAppClassLoader(cms);
                    cms.setClassLoader(cmsWebAppClassLoader);
                    handlerList.addHandler(cms);
                }
                jettyServer.setHandler(handlerList);
                jettyServer.setSendDateHeader(true);
                jettyServer.start();
            } catch (Exception ex) {
                getLog().warn(ex.getMessage(), ex);
                try {
                    hBaseTestingUtility.shutdownMiniCluster();
                    zooKeeperCluster.shutdown();
                } catch (Exception ex1) {
                    getLog().warn(ex1.getMessage(), ex1);
                }
                throw new IllegalStateException(ex);
            }
            Client client = CacheableClient.create();
            client.resource("http://localhost:10080/hub/api/channels/" + eventHubChannelName)
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
                    .put("{\"name\":\"" + eventHubChannelName + "\"}");
            getLog().debug("Created test channel!");
        }

        public void run() {
            try {
                ServerSocket serverSocket = new ServerSocket(embeddedPort);
                while (true) {
                    Socket socket = serverSocket.accept();
                    InputStream inputStream = socket.getInputStream();
                    Writer writer = new OutputStreamWriter(socket.getOutputStream());
                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                    String firstLine = reader.readLine();
                    if (StringUtils.isNotBlank(firstLine)) {
                        if ("stop".equalsIgnoreCase(firstLine.split(" ")[0])) {
                            getLog().info("Received STOP signal!");
                            stopAll();
                            writer.write("done\n");
                            writer.flush();
                            Thread.sleep(1000);
                            reader.close();
                            writer.close();
                            socket.close();
                            serverSocket.close();
                            break;
                        }
                    }
                }
            } catch (Exception ex) {
                getLog().warn(ex.getMessage(), ex);
                throw new IllegalStateException(ex);
            }
        }

        protected void stopAll() {
            try {
                jettyServer.stop();
            } catch (Exception ex) {
                getLog().warn(ex.getMessage(), ex);
            }
            try {
                hBaseTestingUtility.shutdownMiniCluster();
            } catch (Exception ex) {
                getLog().warn(ex.getMessage(), ex);
            }
            try {
                zooKeeperCluster.shutdown();
            } catch (Exception ex) {
                getLog().warn(ex.getMessage(), ex);
            }
        }
    }
}