You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by rw...@apache.org on 2012/06/30 13:56:51 UTC
svn commit: r1355714 - in
/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl:
SolrFieldMapper.java SolrYard.java
Author: rwesten
Date: Sat Jun 30 11:56:50 2012
New Revision: 1355714
URL: http://svn.apache.org/viewvc?rev=1355714&view=rev
Log:
Fixes for STANBOL-669 and STANBOL-668. See issues for details
Modified:
incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrFieldMapper.java
incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java
Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrFieldMapper.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrFieldMapper.java?rev=1355714&r1=1355713&r2=1355714&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrFieldMapper.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrFieldMapper.java Sat Jun 30 11:56:50 2012
@@ -125,12 +125,16 @@ public class SolrFieldMapper implements
*
* @see LinkedHashMap#
*/
- private final LRU<IndexField,Collection<String>> indexFieldMappings = new LRU<IndexField,Collection<String>>();
+ private final Map<IndexField,Collection<String>> indexFieldMappings =
+ //STANBOL-669: LRU chaches MUST BE synchronized!
+ Collections.synchronizedMap(new LRU<IndexField,Collection<String>>());
/**
* The assumption is, that only a handful of fields appear in index documents. So it makes sense to keep
* some mappings within a cache rather than calculating them again and again.
*/
- private final LRU<String,IndexField> fieldMappings = new LRU<String,IndexField>();
+ private final Map<String,IndexField> fieldMappings =
+ //STANBOL-669: LRU chaches MUST BE synchronized!
+ Collections.synchronizedMap(new LRU<String,IndexField>());
public SolrFieldMapper(SolrServer server) {
if (server == null) {
@@ -599,7 +603,9 @@ public class SolrFieldMapper implements
*/
private Map<String,String> getNamespaceMap() {
if (__namespaceMap == null) {
- loadNamespaceConfig();
+ synchronized (prefixNamespaceMappingsLock) {
+ loadNamespaceConfig();
+ }
}
return __namespaceMap;
}
@@ -608,6 +614,11 @@ public class SolrFieldMapper implements
* Do never access this Map directly! Use {@link #getPrefixMap()}!
*/
private Map<String,String> __prefixMap = null;
+ /**
+ * used as lock during loading of the namespace <-> prefix mappings
+ * (fixes STANBOL-668)
+ */
+ private Object prefixNamespaceMappingsLock = new Object();
/**
* Getter for the prefix to namespace mappings
@@ -616,7 +627,9 @@ public class SolrFieldMapper implements
*/
private Map<String,String> getPrefixMap() {
if (__prefixMap == null) {
- loadNamespaceConfig();
+ synchronized (prefixNamespaceMappingsLock) {
+ loadNamespaceConfig();
+ }
}
return __prefixMap;
}
@@ -729,8 +742,10 @@ public class SolrFieldMapper implements
}
private void addNamespaceMapping(String prefix, String namespace) {
- getPrefixMap().put(prefix, namespace);
- getNamespaceMap().put(namespace, prefix);
+ synchronized (prefixNamespaceMappingsLock) {
+ getPrefixMap().put(prefix, namespace);
+ getNamespaceMap().put(namespace, prefix);
+ }
}
/**
@@ -738,8 +753,8 @@ public class SolrFieldMapper implements
* the prefix <-> namespace mappings
*/
private void loadNamespaceConfig() {
- __prefixMap = new HashMap<String,String>();
- __namespaceMap = new HashMap<String,String>();
+ HashMap<String,String> prefixMap = new HashMap<String,String>();
+ HashMap<String,String> namespaceMap = new HashMap<String,String>();
SolrDocument config = null;
try {
config = getSolrDocument(FieldMapper.URI);
@@ -758,14 +773,14 @@ public class SolrFieldMapper implements
String prefix = configFieldElements[1];
Object value = config.getFirstValue(fieldName);
if (value != null) {
- if (__namespaceMap.containsKey(value.toString())) {
- log.error("found two prefixes (" + __namespaceMap.get(value.toString())
+ if (namespaceMap.containsKey(value.toString())) {
+ log.error("found two prefixes (" + namespaceMap.get(value.toString())
+ " and " + prefix + ") for Namespace " + value.toString()
+ " keep the first one");
} else {
log.debug(" > prefix: " + prefix + " value: " + value);
- __prefixMap.put(prefix, value.toString());
- __namespaceMap.put(value.toString(), prefix);
+ prefixMap.put(prefix, value.toString());
+ namespaceMap.put(value.toString(), prefix);
// check for default NS
if (prefix.startsWith(DEFAULT_NS_PREFIX_STRING)) {
String prefixNumber = prefix.substring(DEFAULT_NS_PREFIX_STRING.length());
@@ -792,6 +807,11 @@ public class SolrFieldMapper implements
}
}
}
+ //only store complete mappings to the member variables (STANBOL-668)
+ synchronized (prefixNamespaceMappingsLock) {
+ __prefixMap = prefixMap;
+ __namespaceMap = namespaceMap;
+ }
}
private String getConfigFieldName(String configName) {
Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java?rev=1355714&r1=1355713&r2=1355714&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java Sat Jun 30 11:56:50 2012
@@ -28,6 +28,9 @@ import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -49,6 +52,7 @@ import org.apache.solr.client.solrj.requ
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.core.SolrCore;
import org.apache.stanbol.commons.solr.IndexReference;
import org.apache.stanbol.commons.solr.RegisteredSolrServerTracker;
import org.apache.stanbol.commons.solr.managed.IndexMetadata;
@@ -76,10 +80,8 @@ import org.apache.stanbol.entityhub.yard
import org.apache.stanbol.entityhub.yard.solr.model.IndexValueFactory;
import org.apache.stanbol.entityhub.yard.solr.query.IndexConstraintTypeEnum;
import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.component.ComponentContext;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
@@ -239,6 +241,17 @@ public class SolrYard extends AbstractYa
* {@link #activate(ComponentContext)}.
*/
private SolrServer _server;
+
+ /**
+ * In case the {@link SolrServer} changes during normal operation the
+ * {@link SolrFieldMapper} needs to be reinitialised for the new Core.
+ * This lock is used to avoid NPE when setting the {@link #_fieldMapper}
+ * variable back to <code>null</code> in those cases. While this will
+ * trigger automatic re-initialisation on the next call to
+ * {@link #getFieldMapper()} there would be the possibility that calls to
+ * {@link #getFieldMapper()} return <code>null</code>.
+ */
+ private final ReadWriteLock fieldMapperLock = new ReentrantReadWriteLock();
/**
* The {@link FieldMapper} is responsible for converting fields of {@link Representation} to fields in the
* {@link SolrInputDocument} and vice versa
@@ -502,10 +515,16 @@ public class SolrYard extends AbstractYa
} catch (InterruptedException e) {}
}
}
- if(server == null || !server.equals(this._server)){
+ if(server != null && !server.equals(this._server)){
//reset the fieldMapper so that it is reinitialised for the new one
//STANBOL-519
- _fieldMapper = null;
+ Lock writeLock = fieldMapperLock.writeLock();
+ writeLock.lock();
+ try {
+ _fieldMapper = null;
+ }finally{
+ writeLock.unlock();
+ }
}
} else {
//for remove servers and when running outside OSGI
@@ -515,8 +534,16 @@ public class SolrYard extends AbstractYa
if(server != null){
return server;
} else {
+ Lock writeLock = fieldMapperLock.writeLock();
+ writeLock.lock();
+ try {
+ _fieldMapper = null;
+ }finally{
+ writeLock.unlock();
+ }
throw new YardException(String.format("The SolrIndex '%s' for SolrYard '%s' is currently not active!",
((SolrYardConfig)getConfig()).getSolrServerLocation(),getName()));
+
}
}
@@ -687,11 +714,24 @@ public class SolrYard extends AbstractYa
}
}
private SolrFieldMapper getFieldMapper() throws YardException {
- if(_fieldMapper == null){
+ Lock readLock = fieldMapperLock.readLock();
+ readLock.lock();
+ try {
+ if(_fieldMapper != null){
+ return _fieldMapper;
+ }
+ } finally {
+ readLock.unlock();
+ }
+ Lock writeLock = fieldMapperLock.writeLock();
+ writeLock.lock();
+ try {
// the fieldMapper need the Server to store it's namespace prefix configuration
_fieldMapper = new SolrFieldMapper(getServer());
+ return _fieldMapper;
+ } finally {
+ writeLock.unlock();
}
- return _fieldMapper;
}
/**
@@ -889,6 +929,12 @@ public class SolrYard extends AbstractYa
* @return the Representation
*/
protected final Representation createRepresentation(FieldMapper fieldMapper, SolrDocument doc, Set<String> fields) {
+ if(fieldMapper == null){
+ throw new IllegalArgumentException("The parsed FieldMapper MUST NOT be NULL!");
+ }
+ if(doc == null){
+ throw new IllegalArgumentException("The parsed SolrDocument MUST NOT be NULL!");
+ }
Object id = doc.getFirstValue(fieldMapper.getDocumentIdField());
if (id == null) {
throw new IllegalStateException(String.format(