Project

General

Profile

1 7542 tao
/**
2 8138 tao
 *  Copyright: 2013 Regents of the University of California and the
3 7542 tao
 *             National Center for Ecological Analysis and Synthesis
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
package edu.ucsb.nceas.metacat.index;
20
21 7783 tao
import java.io.File;
22 7811 leinfelder
import java.io.FileNotFoundException;
23 7613 tao
import java.util.ArrayList;
24 7542 tao
import java.util.List;
25 7788 tao
import java.util.Timer;
26 7542 tao
27 7783 tao
import org.apache.commons.configuration.ConfigurationException;
28 7542 tao
import org.apache.commons.logging.Log;
29
import org.apache.commons.logging.LogFactory;
30 7589 leinfelder
import org.apache.solr.client.solrj.SolrServer;
31 7783 tao
import org.dataone.configuration.Settings;
32
import org.dataone.service.exceptions.ServiceFailure;
33 7542 tao
import org.springframework.context.ApplicationContext;
34 8128 tao
import org.springframework.context.support.ClassPathXmlApplicationContext;
35 7542 tao
36 7783 tao
37 7811 leinfelder
import edu.ucsb.nceas.metacat.common.SolrServerFactory;
38
import edu.ucsb.nceas.metacat.common.query.EnabledQueryEngines;
39
40 7542 tao
/**
41
 * The start class of the index.
42
 * @author tao
43
 *
44
 */
45 7776 tao
public class ApplicationController implements Runnable {
46 7542 tao
47 7788 tao
    private static long DEFAULTINTERVAL = 7200000;
48 7542 tao
    private static String SOLRINDEXES = "solrIndexes";
49 7613 tao
    private static short FIRST = 0;
50 7589 leinfelder
51 7542 tao
    private List<SolrIndex> solrIndexes = null;
52 8464 leinfelder
    private List<Runnable> sysmetaListeners = new ArrayList<Runnable>();
53 7542 tao
    private static ApplicationContext context = null;
54 8128 tao
    private String springConfigFileURL = "/index-processor-context.xml";
55 7783 tao
    private String metacatPropertiesFile = null;
56 8352 tao
    private static int waitingTime = IndexGeneratorTimerTask.WAITTIME;
57
    private static int maxAttempts = IndexGeneratorTimerTask.MAXWAITNUMBER;
58 7788 tao
    private static long period = DEFAULTINTERVAL;
59 7542 tao
    Log log = LogFactory.getLog(ApplicationController.class);
60
61 7613 tao
62 7542 tao
    /**
63
     * Constructor
64
     */
65 7783 tao
    /*public ApplicationController () throws Exception {
66 7542 tao
        init();
67 7783 tao
    }*/
68 7542 tao
69 7552 tao
    /**
70 8128 tao
     * Set the Spring configuration file url and metacat.properties file
71 7552 tao
     * @param springConfigFile  the path of the Spring configuration file
72 7783 tao
     * @param metacatPropertyFile  the path of the metacat.properties file
73 7552 tao
     */
74 8128 tao
    public ApplicationController(String springConfigFileURL, String metacatPropertiesFile) throws Exception {
75
        this.springConfigFileURL = springConfigFileURL;
76 7783 tao
        this.metacatPropertiesFile = metacatPropertiesFile;
77
        //init();
78 7552 tao
    }
79
80 7560 leinfelder
    /**
81 7783 tao
     * Loads the metacat.prioerties into D1 Settings utility
82
     * this gives us access to all metacat properties as well as
83
     * overriding any properties as needed.
84
     * Note: in the junit test, we are using the test.properties rather than this properties file.
85
     *
86
     * Makes sure shared Hazelcast configuration file location is set
87
     */
88
    private void initializeSharedConfiguration() {
89
        int times = 0;
90 7788 tao
        boolean foundProperty = false;
91 7783 tao
        while(true) {
92
            File metacatProperties = new File(metacatPropertiesFile);
93
            if(metacatProperties.exists()) {
94 7788 tao
                foundProperty = true;
95 7783 tao
                break;
96
            } else {
97
                try {
98
                        Thread.sleep(waitingTime);
99
                } catch (InterruptedException e) {
100
                            // TODO Auto-generated catch block
101
                        e.printStackTrace();
102
                }
103
            }
104
            times++;
105
            if(times >= maxAttempts) {
106
                log.error("ApplicationController.initialzeSharedConfiguration - MetacatIndex wait a while and still can't find the metacat.properties file.");
107
                break;//we still break the while loop and continue. But the properties in the metacat.properties can't be read.
108
            }
109
110
        }
111
112
        try {
113
            Settings.getConfiguration();
114
            Settings.augmentConfiguration(metacatPropertiesFile);
115
        } catch (ConfigurationException e) {
116
            log.error("Could not initialize shared Metacat properties. " + e.getMessage(), e);
117
        }
118
119
        // make sure hazelcast configuration is defined so that
120
        String hzConfigFileName = Settings.getConfiguration().getString("dataone.hazelcast.configFilePath");
121
        if (hzConfigFileName == null) {
122
            // use default metacat hazelcast.xml file in metacat deployment
123
            hzConfigFileName =
124
                    Settings.getConfiguration().getString("application.deployDir") +
125
                    "/" +
126
                    Settings.getConfiguration().getString("application.context") +
127
                    "/WEB-INF/hazelcast.xml";
128
            // set it for other parts of the code
129
            Settings.getConfiguration().setProperty("dataone.hazelcast.configFilePath", hzConfigFileName);
130
            //set data.hazelcast.location.clientconfig. This property will be used in d1_cn_index_processor module.
131
            //if we don't set this property, d1_cn_index_processor will use the default location /etc/dataone/storage.
132
            Settings.getConfiguration().setProperty("dataone.hazelcast.location.clientconfig", hzConfigFileName);
133
        }
134 7788 tao
        if(foundProperty) {
135
            period = Settings.getConfiguration().getLong("index.regenerate.interval");
136
        }
137
138 7783 tao
    }
139
140
    /**
141 7589 leinfelder
     * Initialize the list of the SolrIndex objects from the configuration file.
142
     * Set the SolrServer implementation using the factory.
143 7542 tao
     */
144 7783 tao
    public void initialize() throws Exception {
145 7542 tao
        context = getContext();
146
        solrIndexes = (List<SolrIndex>) context.getBean(SOLRINDEXES);
147
148 7591 leinfelder
        // use factory to create the correct impl
149 7589 leinfelder
    	SolrServer solrServer = null;
150 7591 leinfelder
		try {
151
			solrServer = SolrServerFactory.createSolrServer();
152
		} catch (Exception e) {
153
			log.error("Could not create SolrServer form factory", e);
154 7613 tao
			throw e;
155 7591 leinfelder
		}
156 7589 leinfelder
157 7560 leinfelder
        // start the SystemMetadata listener[s] (only expect there to be one)
158
        for (SolrIndex solrIndex: solrIndexes) {
159 7589 leinfelder
        	// set the solr server to use
160
			solrIndex.setSolrServer(solrServer);
161
162
			// start listening for events
163 7560 leinfelder
        	SystemMetadataEventListener smel = new SystemMetadataEventListener();
164
        	smel.setSolrIndex(solrIndex);
165 7776 tao
        	sysmetaListeners.add(smel);
166 7560 leinfelder
        }
167
168 7542 tao
    }
169
170 7589 leinfelder
    /**
171 7542 tao
     * Get the ApplicaionContext of Spring.
172
     */
173
    private ApplicationContext getContext() {
174
        if (context == null) {
175 8128 tao
            context = new ClassPathXmlApplicationContext(springConfigFileURL);
176 7542 tao
        }
177
        return context;
178
    }
179
180
    /**
181
     * Get the path of the Spring configuration file.
182
     * @return the path of the Spring configuration file.
183
     */
184
    public String getSpringConfigFile() {
185 8128 tao
        return this.springConfigFileURL;
186 7542 tao
    }
187
188
    /**
189
     * Get the list of the solr index.
190
     * @return the list of the solr index.
191
     */
192
    public List<SolrIndex> getSolrIndexes() {
193
        return this.solrIndexes;
194
    }
195 7613 tao
196
197
    /**
198
     * Start to generate indexes for those haven't been indexed in another thread.
199 7788 tao
     * It will create a timer to run this task periodically.
200
     * If the property of "index.regenerate.interval" is less than 0, the thread would NOT run.
201 7613 tao
     */
202 8292 tao
    private void startIndexGenerator() {
203 7788 tao
        if(period > 0) {
204
            SolrIndex index = solrIndexes.get(FIRST);
205
            //SystemMetadataEventListener listener = sysmetaListeners.get(FIRST);
206 8352 tao
            IndexGeneratorTimerTask generator = new IndexGeneratorTimerTask(index);
207 7788 tao
            //Thread indexThread = new Thread(generator);
208
            //indexThread.start();
209
            Timer indexTimer = new Timer();
210 7866 tao
            //indexTimer.scheduleAtFixedRate(generator, Calendar.getInstance().getTime(), period);
211 8291 tao
            indexTimer.schedule(generator, 60000, period);
212 7788 tao
        }
213
214 7613 tao
    }
215 7776 tao
216
    /**
217 7783 tao
     * Start the system metadata listener. Prior to call this method, we should call
218
     * initialize method first.
219 7811 leinfelder
     * @throws ServiceFailure
220
     * @throws FileNotFoundException
221 7776 tao
     */
222 8292 tao
    private void startSysmetaListener() throws FileNotFoundException, ServiceFailure {
223 7776 tao
        if(sysmetaListeners != null) {
224
            //only expects one listener.
225 8464 leinfelder
            for(Runnable listener : sysmetaListeners) {
226 7776 tao
                if(listener != null) {
227 8464 leinfelder
                    listener.run();
228 7776 tao
                }
229
            }
230
        }
231
    }
232
233
    /**
234 7783 tao
     * It will initialize the shared metacat.properties and the SolrIndex, then start system metadata event listener and
235
     *  generate indexes for those haven't been indexed in another thread. This method is for the MetacatIndexServlet.
236
     *  The reason we put those methods (init, startSysmetaListener, startIndex)in the run (another thread) is that the waiting readiness of the metacat wouldn't
237
     *  block the start of the servlet container (e.g., tomcat).
238 7776 tao
     */
239
    public void run() {
240 7783 tao
        initializeSharedConfiguration();
241
        try {
242
            boolean isSolrEnabled = true;
243
            try {
244
               isSolrEnabled = EnabledQueryEngines.getInstance().isEnabled(EnabledQueryEngines.SOLRENGINE);
245
            } catch (Exception e) {
246
                log.error("ApplicationController.run - Metacat-index can't read the enabled query engine list from metacat.properties :"+e.getMessage());
247
            }
248
            //if the solr query engine is disabled, we stop here.
249
            if(!isSolrEnabled) {
250
                return;
251
            }
252
            initialize();
253
            startSysmetaListener();
254 8292 tao
            startIndexGenerator();//it will create another thread.
255 7783 tao
        } catch (Exception e) {
256
            log.error("Application.run "+e.getMessage());
257
        }
258
259 7776 tao
    }
260 7542 tao
}