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

com.versioneye.mojo.CentralMojo Maven / Gradle / Ivy

Go to download

The maven-indexer project is used by VersionEye to download, read and iterate Maven indexes from Maven repository servers. This project is part of the VersionEye crawling framework.

There is a newer version: 1.1.5
Show newest version
package com.versioneye.mojo;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.versioneye.maven.MavenIndexer;
import com.versioneye.service.RabbitMqService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.maven.index.ArtifactInfo;
import org.apache.maven.index.context.IndexUtils;
import org.apache.maven.index.context.IndexingContext;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.versioneye.domain.MavenRepository;
import com.versioneye.service.ProductService;

import java.util.Properties;
import java.util.concurrent.*;

/**
 * Fetches the index from the maven central repository and walks through the index
 * to update the database.
 */
@Mojo( name = "central", defaultPhase = LifecyclePhase.PROCESS_SOURCES )
public class CentralMojo extends SuperMojo {

    static final Logger logger = LogManager.getLogger(CentralMojo.class.getName());

    protected ProductService productService;

    protected final static String QUEUE_NAME = "maven_index_worker";
    protected Connection connection;
    protected Channel channel;


    public void execute() throws MojoExecutionException, MojoFailureException {
        try{
            super.execute();
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            productService = (ProductService) context.getBean("productService");

            MavenRepository typesafeRepo = mavenRepositoryDao.findByName("typesafe");
            addRepo(typesafeRepo);

            initMavenRepository();

            doUpdateFromIndex();
        } catch( Exception exception ){
            logger.error(exception.getStackTrace());
            throw new MojoExecutionException("Oh no! Something went wrong. Get in touch with the VersionEye guys and give them feedback.", exception);
        }
    }


    protected void doUpdateFromIndex() {
        try{
            initTheRabbit();

            String centralCache = getCacheDirectory(mavenRepository.getName());
            String centralIndex = getIndexDirectory(mavenRepository.getName());

            MavenIndexer mavenIndexer = new MavenIndexer();
            mavenIndexer.initCentralContext(mavenRepository.getUrl(), centralCache, centralIndex);
            mavenIndexer.updateIndex(mavenRepository.getUsername(), mavenRepository.getPassword());

            IndexingContext context = mavenIndexer.getCentralContext();
            IndexSearcher searcher  = context.acquireIndexSearcher();
            final IndexReader ir    = searcher.getIndexReader();
            for ( int i = 0; i < ir.maxDoc(); i++ ) {
                processArtifact(context, ir, i);
            }
            context.releaseIndexSearcher(searcher);

            mavenIndexer.closeIndexer();

            closeTheRabbit();
        } catch (Exception ex){
            logger.error(ex);
            logger.error("ERROR in doUpdateFromIndex" + ex.getMessage());
        }
    }


    protected void processArtifact(IndexingContext context, IndexReader indexReader, int i) {
        try {
            if ( indexReader.isDeleted( i ) )
                return ;

            final Document doc = indexReader.document( i );
            final ArtifactInfo artifactInfo = IndexUtils.constructArtifactInfo( doc, context );
            if (artifactInfo == null || artifactInfo.groupId == null || artifactInfo.artifactId == null){
                return ;
            }

            if (skipKnown && productDao.doesVersionExistAlreadyByGA(artifactInfo.groupId.toLowerCase(), artifactInfo.artifactId.toLowerCase(), artifactInfo.version)){
                return ;
            }

            processArtifact(artifactInfo);
        } catch (Exception ex) {
            logger.error("Error in processArtifact - " + ex.toString());
            logger.error(ex.getStackTrace());
        }
    }


    protected void processArtifact(ArtifactInfo artifactInfo) {
        String gav = artifactInfo.groupId + ":" + artifactInfo.artifactId + ":pom:" + artifactInfo.version;
        sendGav(gav, artifactInfo.lastModified);
    }


    protected void processArtifactAsync( ArtifactInfo artifactInfo ) {
        ExecutorService executor = Executors.newCachedThreadPool();
        Callable task = new MyCallable(artifactInfo);

        Future future = executor.submit(task);
        try {
            future.get(30, TimeUnit.MINUTES);
        } catch (TimeoutException ex) {
            logger.error("Timeout Exception for " + artifactInfo.groupId + ":" + artifactInfo.artifactId + ":" + artifactInfo.version + " - " + ex);
            logger.error(ex);
        } catch (InterruptedException ex) {
            logger.error("Interrupted Exception: " + artifactInfo.groupId + ":" + artifactInfo.artifactId + ":" + artifactInfo.version + " - " + ex);
            logger.error(ex);
        } catch (ExecutionException ex) {
            logger.error("Execution Exception: " + artifactInfo.groupId + ":" + artifactInfo.artifactId + ":" + artifactInfo.version + " - " + ex);
            logger.error(ex);
        } finally {
            future.cancel(true);
        }
    }


    public class MyCallable implements Callable {

        private ArtifactInfo artifactInfo;

        public MyCallable (ArtifactInfo artifactInf) {
            artifactInfo = artifactInf;
        }

        public Object call() throws Exception {
            logger.info("send " + artifactInfo.groupId + ":" + artifactInfo.artifactId + ":" + artifactInfo.version);
            String gav = artifactInfo.groupId + ":" + artifactInfo.artifactId + ":pom:" + artifactInfo.version;
            sendGav(gav, artifactInfo.lastModified);
            return null;
        }
    }


    protected void sendGav(String gav, long lastModified){
        try{
            String message = mavenRepository.getName() + "::" + mavenRepository.getUrl() + "::" + gav + "::" + lastModified;
            channel.queueDeclare(QUEUE_NAME, true, false, false, null);
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
            logger.info(" [x] Sent '" + message + "'");
        } catch (Exception exception) {
            logger.error("urlToPom: " + gav + " - " + exception.toString());
            logger.error(exception.getStackTrace());
        }
    }


    protected void initTheRabbit(){
        try {
            String rabbitmqAddr = System.getenv("RM_PORT_5672_TCP_ADDR");
            String rabbitmqPort = System.getenv("RM_PORT_5672_TCP_PORT");
            if (rabbitmqAddr == null || rabbitmqAddr.isEmpty() || rabbitmqPort == null || rabbitmqPort.isEmpty()){
                Properties properties = getProperties();
                rabbitmqAddr = properties.getProperty("rabbitmq_addr");
                rabbitmqPort = properties.getProperty("rabbitmq_port");
            }
            connection = RabbitMqService.getConnection(rabbitmqAddr, new Integer(rabbitmqPort));
            channel = connection.createChannel();
            String msg = "Connected to RabbitMQ " + rabbitmqAddr + ":" + rabbitmqPort;
            logger.info(msg);
            System.out.println(msg);
        } catch (Exception exception){
            logger.error("ERROR in initTheRabbit - " + exception.toString());
            logger.error(exception.getStackTrace());
        }
    }


    protected void closeTheRabbit(){
        try{
            channel.close();
            connection.close();
            String msg = "Connection to RabbitMQ closed.";
            logger.info(msg);
            System.out.println(msg);
        } catch (Exception exception){
            logger.error("ERROR in closeTheRabbit - " + exception.toString());
            logger.error(exception.getStackTrace());
        }
    }


    private void initMavenRepository(){
        mavenRepository = mavenRepositoryDao.findByName("central");
        if (mavenRepository == null){
            mavenRepository = new MavenRepository();
            mavenRepository.setId("central");
            mavenRepository.setName("central");
            mavenRepository.setUrl("http://repo.maven.apache.org/maven2");
            mavenRepository.setLanguage("Java");
        }
    }


}