blob: f3661cbb804b13df019aeafd13cd3d2d74952082 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.stanbol.enhancer.topic;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.List;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.stanbol.commons.solr.IndexReference;
import org.apache.stanbol.commons.solr.RegisteredSolrServerTracker;
import org.apache.stanbol.commons.solr.managed.IndexMetadata;
import org.apache.stanbol.commons.solr.managed.ManagedIndexState;
import org.apache.stanbol.commons.solr.managed.ManagedSolrServer;
import org.apache.stanbol.enhancer.engine.topic.TopicClassificationEngine;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
/**
* Helper class to factorize some common code for Solr Core tracking OSGi component
*/
public abstract class ConfiguredSolrCoreTracker {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected ManagedSolrServer managedSolrServer;
protected String solrCoreId;
protected RegisteredSolrServerTracker indexTracker;
// instance of classifierSolrServer to use if not using the OSGi service tracker (e.g. for tests)
protected SolrServer solrServer;
protected ComponentContext context;
protected String solrCoreConfig;
//protected String indexArchiveName;
abstract public void configure(Dictionary<String,Object> config) throws ConfigurationException;
protected String getRequiredStringParam(Dictionary<String,Object> parameters, String paramName) throws ConfigurationException {
return getRequiredStringParam(parameters, paramName, null);
}
protected String getRequiredStringParam(Dictionary<String,Object> config,
String paramName,
String defaultValue) throws ConfigurationException {
Object paramValue = config.get(paramName);
if (paramValue == null) {
if (defaultValue == null) {
throw new ConfigurationException(paramName, paramName + " is a required parameter.");
} else {
return defaultValue;
}
}
return paramValue.toString();
}
@SuppressWarnings("unchecked")
protected List<String> getStringListParan(Dictionary<String,Object> config, String paramName) throws ConfigurationException {
Object paramValue = config.get(paramName);
if (paramValue == null) {
return new ArrayList<String>();
} else if (paramValue instanceof String) {
return Arrays.asList(paramValue.toString().split(",\\s*"));
} else if (paramValue instanceof String[]) {
return Arrays.asList((String[]) paramValue);
} else if (paramValue instanceof List) {
return (List<String>) paramValue;
} else {
throw new ConfigurationException(paramName, String.format(
"Unexpected parameter type for '%s': %s", paramName, paramValue));
}
}
/**
* @return the manually bound classifierSolrServer instance or the one tracked by the OSGi service
* tracker.
*/
public SolrServer getActiveSolrServer() {
SolrServer result;
if(solrServer != null){
result = solrServer;
} else {
result = indexTracker.getService();
if(result == null){
//try to wait for the server (mainly because the evaluation
//server is created on demand and will need some time to be
//initialised).
for(int i = 0; i < 5 && result == null; i++){
try {
result = (SolrServer) indexTracker.waitForService(1000);
} catch (InterruptedException e) {/* ignore */ }
}
}
}
if (result == null) {
if (solrCoreId != null) {
throw new RuntimeException("No Solr Core registered with id: " + solrCoreId);
} else {
throw new RuntimeException("No Solr Core registered");
}
}
return result;
}
protected void configureSolrCore(Dictionary<String,Object> config,
String solrCoreProperty, String defaultCoreId,
String solrCoreConfigProperty)
throws ConfigurationException {
Object solrCoreInfo = config.get(solrCoreProperty);
if (solrCoreInfo instanceof SolrServer) {
// Bind a fixed Solr server client instead of doing dynamic OSGi lookup using the service tracker.
// This can be useful both for unit-testing .
solrServer = (SolrServer) config.get(solrCoreProperty);
solrCoreConfig = TopicClassificationEngine.DEFAULT_SOLR_CORE_CONFIG;
} else {
if (context == null) {
throw new ConfigurationException(solrCoreProperty,
solrCoreProperty + " should be a SolrServer instance for using"
+ " the engine without any OSGi context. Got: " + solrCoreId);
}
if (solrCoreInfo != null && !solrCoreInfo.toString().trim().isEmpty()) {
this.solrCoreId = solrCoreInfo.toString().trim();
} else {
this.solrCoreId = defaultCoreId;
}
solrCoreConfig = getRequiredStringParam(config, solrCoreConfigProperty,
this.solrCoreId + ".solrindex.zip");
try {
IndexReference indexReference = IndexReference.parse(solrCoreId);
//String configName = getRequiredStringParam(config, SOLR_CONFIG, defaultValue)
indexReference = checkInitSolrIndex(indexReference, solrCoreConfig);
// track the solr core OSGi updates
indexTracker = new RegisteredSolrServerTracker(context.getBundleContext(), indexReference);
indexTracker.open();
} catch (Exception e) {
throw new ConfigurationException(solrCoreProperty, e.getMessage(), e);
}
}
}
/**
* Checks if the SolrIndex is available and if not it tries to initialise it
* @param indexReference the SolrCore reference
* @param solrCoreConfig the name of the SolrIndex configuration ({name}.solrindex.zip)
* @return
* @throws IOException
* @throws ConfigurationException
* @throws SAXException
*/
protected IndexReference checkInitSolrIndex(IndexReference indexReference, String solrCoreConfig)
throws IOException, ConfigurationException, SAXException {
// if the solr core is managed, check that the index is properly activated
if (managedSolrServer != null && indexReference.checkServer(managedSolrServer.getServerName())
&& context != null && solrCoreConfig != null) {
log.info(" > check/init index {} on ManagedSolrServer {}", indexReference, managedSolrServer.getServerName());
String indexName = indexReference.getIndex();
final IndexMetadata indexMetadata;
ManagedIndexState indexState = managedSolrServer.getIndexState(indexName);
if(indexState == null){
if(solrCoreConfig.indexOf(".solrindex.") < 0){ //if the suffix is missing
solrCoreConfig = solrCoreConfig + ".solrindex.zip"; //append it
}
log.info("Create SolrCore {} (config: {}) on ManagedSolrServer {} ...",
new Object[]{indexName,solrCoreConfig,managedSolrServer.getServerName()});
indexMetadata = managedSolrServer.createSolrIndex(indexName,
solrCoreConfig, null);
if(indexMetadata != null)
log.info(" ... created {}", indexMetadata.getIndexReference());
} else {
indexMetadata = managedSolrServer.getIndexMetadata(indexName);
if(indexState != ManagedIndexState.ACTIVE){
log.info(" ... activate {}", indexMetadata.getIndexReference());
managedSolrServer.activateIndex(indexName);
} else {
log.info(" ... index {} already active", indexMetadata.getIndexReference());
}
}
// IndexMetadata indexMetadata = managedSolrServer.getIndexMetadata(indexName);
// if (indexMetadata == null) {
// // TODO: debug the DataFileProvider init race conditions instead
// // indexMetadata = managedSolrServer.createSolrIndex(indexName, indexArchiveName, null);
// dfp.getInputStream(context.getBundleContext().getBundle().getSymbolicName(),
// indexArchiveName + ".solrindex.zip", null);
// URL archiveUrl = context.getBundleContext().getBundle()
// .getEntry("/data-files/" + indexArchiveName + ".solrindex.zip");
// if (archiveUrl == null) {
// throw new ConfigurationException(solrCoreId, "Could not find index archive for "
// + indexArchiveName);
// }
// ZipArchiveInputStream zis = new ZipArchiveInputStream(archiveUrl.openStream());
// indexMetadata = managedSolrServer.updateIndex(indexName, zis, indexArchiveName);
// }
// if (!indexMetadata.isActive()) {
// managedSolrServer.activateIndex(indexName);
// }
indexReference = indexMetadata.getIndexReference();
}
return indexReference;
}
protected void bindManagedSolrServer(ManagedSolrServer managedSolrServer) throws IOException,
SAXException {
this.managedSolrServer = managedSolrServer;
}
protected void unbindManagedSolrServer(ManagedSolrServer managedSolrServer) {
if (this.managedSolrServer == managedSolrServer || solrCoreId != null) {
IndexReference indexReference = IndexReference.parse(solrCoreId);
if (!indexReference.checkServer(managedSolrServer.getServerName())) {
return;
}
String indexName = indexReference.getIndex();
IndexMetadata indexMetadata = managedSolrServer.getIndexMetadata(indexName);
if (indexMetadata != null && indexMetadata.isActive()) {
managedSolrServer.deactivateIndex(indexName);
}
this.managedSolrServer = null;
}
}
}