com.indeed.imhotep.web.config.SpringConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for com.indeed.imhotep.web.config.SpringConfiguration.java

Source

/*
 * Copyright (C) 2014 Indeed Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.indeed.imhotep.web.config;

import com.google.common.base.Strings;
import com.indeed.imhotep.LocalImhotepDaemon;
import com.indeed.imhotep.web.CORSInterceptor;
import com.indeed.imhotep.web.ImhotepClientPinger;
import com.indeed.util.core.threads.NamedThreadFactory;
import com.indeed.imhotep.client.Host;
import com.indeed.imhotep.client.ImhotepClient;
import com.indeed.imhotep.iql.cache.QueryCache;
import com.indeed.imhotep.iql.cache.QueryCacheFactory;
import com.indeed.imhotep.web.ImhotepMetadataCache;
import com.indeed.imhotep.web.QueryServlet;
import com.indeed.imhotep.web.TopTermsCache;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.xml.bind.PropertyException;

@Configuration
@EnableWebMvc
@EnableScheduling
@ComponentScan(basePackageClasses = { SpringConfiguration.class, QueryServlet.class })
public class SpringConfiguration extends WebMvcConfigurerAdapter {
    private static final Logger log = Logger.getLogger(SpringConfiguration.class);

    @Autowired
    Environment env;

    @Bean(destroyMethod = "shutdown")
    public ExecutorService executorService() {
        return new ThreadPoolExecutor(3, 10, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(100),
                new NamedThreadFactory("IQL-Worker"));
    }

    @Bean
    QueryCache queryCache() throws PropertyException {
        return QueryCacheFactory.newQueryCache(env);
    }

    @Bean(destroyMethod = "close")
    public ImhotepClient imhotepClient() {
        if (env.getProperty("imhotep.daemons.localmode", Boolean.class, false)) {
            // when running an imhotep daemon instance in process
            final String shardsDir = env.getProperty("imhotep.shards.directory");
            if (!Strings.isNullOrEmpty(shardsDir) && new File(shardsDir).exists()) {
                final int localImhotepPort = LocalImhotepDaemon.startInProcess(shardsDir);
                return getImhotepClient("", "", "localhost:" + localImhotepPort, false);
            } else {
                log.warn(
                        "Local mode is enabled for the Imhotep Daemon but imhotep.shards.directory is not set to an existing location."
                                + "It should be set to the local path of a directory containing the Imhotep indexes and shards to be served.");
            }
        }
        // connect to an externally running Imhotep Daemon
        return getImhotepClient(env.getProperty("imhotep.daemons.zookeeper.quorum"),
                env.getProperty("imhotep.daemons.zookeeper.path"), env.getProperty("imhotep.daemons.host"), false);
    }

    @Bean(destroyMethod = "close")
    public ImhotepClient imhotepInteractiveClient() {
        final ImhotepClient interactiveClient = getImhotepClient(
                env.getProperty("imhotep.daemons.interactive.zookeeper.quorum"),
                env.getProperty("imhotep.daemons.interactive.zookeeper.path"),
                env.getProperty("imhotep.daemons.interactive.host"), true);
        if (interactiveClient != null) {
            return interactiveClient;
        } else {
            // interactive not provided, reuse the normal client
            return imhotepClient();
        }
    }

    private ImhotepClient getImhotepClient(String zkNodes, String zkPath, String host, boolean quiet) {
        if (!Strings.isNullOrEmpty(host)) {
            String mergePoint = host.split(",")[0];
            String[] mergePointParts = mergePoint.split(":");
            List<Host> hosts = Arrays.asList(new Host(mergePointParts[0], Integer.parseInt(mergePointParts[1])));
            return new ImhotepClient(hosts);
        } else if (!Strings.isNullOrEmpty(zkNodes)) {
            return new ImhotepClient(zkNodes, zkPath, true);
        } else {
            if (quiet) {
                return null;
            }
            throw new IllegalArgumentException(
                    "either imhotep.daemons.zookeeper.quorum or imhotep.daemons.host config properties must be set");
        }
    }

    @Bean
    public ImhotepMetadataCache metadataCache() {
        return new ImhotepMetadataCache(imhotepClient(), env.getProperty("ramses.metadata.dir"),
                env.getProperty("disabled.fields"));
    }

    @Bean
    public TopTermsCache topTermsCache() {
        return new TopTermsCache(imhotepClient(), metadataCache(), env.getProperty("topterms.cache.dir"),
                IQLEnv.fromSpring(env) == IQLEnv.DEVELOPER);
    }

    @Bean
    public Integer rowLimit() {
        return env.getProperty("row.limit", Integer.class, 1000000);
    }

    @Bean
    public Long imhotepLocalTempFileSizeLimit() {
        final long limitInMegabytes = env.getProperty("imhotep.local.temp.file.size.mb.limit", Long.class,
                Long.MAX_VALUE);
        if (limitInMegabytes < Long.MAX_VALUE) {
            return mbToBytes(limitInMegabytes);
        } else {
            return Long.MAX_VALUE;
        }
    }

    @Bean
    public Long imhotepDaemonTempFileSizeLimit() {
        return mbToBytes(env.getProperty("imhotep.daemon.temp.file.size.mb.limit", Long.class, -1l));
    }

    private Long mbToBytes(Long megabytes) {
        return megabytes <= 0 ? megabytes : megabytes * 1024 * 1024;
    }

    @Bean
    public ImhotepClientPinger imhotepClientPinger() {
        return new ImhotepClientPinger(imhotepClient());
    }

    public static @Bean PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    CORSInterceptor corsInterceptor() {
        return new CORSInterceptor(env);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(corsInterceptor());
    }

    // do we need this?
    //    @PreDestroy
    //    public void destroy() throws IOException {
    //        try {
    //            executorService().awaitTermination(60, TimeUnit.SECONDS);
    //        } catch (InterruptedException e) {
    //            throw new IOException("interrupted while shutting down", e);
    //        }
    //    }
}