SOLR-6163: Correctly decode special characters in managed stopwords and synonym endpoints.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1616361 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Timothy Potter 2014-08-06 21:50:40 +00:00
parent ddbd55d24d
commit c119cf89a4
6 changed files with 111 additions and 5 deletions

View File

@ -238,6 +238,9 @@ Bug Fixes
* SOLR-6264: Distributed commit and optimize are executed serially across all
replicas. (Mark Miller, Timothy Potter)
* SOLR-6163: Correctly decode special characters in managed stopwords and synonym endpoints.
(Vitaliy Zhovtyuk, Timo Schmidt via Timothy Potter)
Optimizations
---------------------

View File

@ -66,6 +66,8 @@ public class RestManager {
// used for validating resourceIds provided during registration
private static final Pattern resourceIdRegex = Pattern.compile("(/config|/schema)(/.*)");
private static final boolean DECODE = true;
/**
* Used internally to keep track of registrations during core initialization
*/
@ -251,6 +253,7 @@ public class RestManager {
* to. ManagedResource implementations are heavy-weight objects that live for the duration of
* a SolrCore, so this class acts as the proxy between Restlet and a ManagedResource when
* doing request processing.
*
*/
public static class ManagedEndpoint extends BaseSolrResource
implements GETable, PUTable, POSTable, DELETEable
@ -258,14 +261,15 @@ public class RestManager {
/**
* Determines the ManagedResource resourceId from the Restlet request.
*/
public static String resolveResourceId(Request restletReq) {
public static String resolveResourceId(Request restletReq) {
String resourceId = restletReq.getResourceRef().
getRelativeRef(restletReq.getRootRef().getParentRef()).getPath();
getRelativeRef(restletReq.getRootRef().getParentRef()).getPath(DECODE);
// all resources are registered with the leading slash
if (!resourceId.startsWith("/"))
resourceId = "/"+resourceId;
return resourceId;
}

View File

@ -427,7 +427,7 @@
<!-- A specialized field for geospatial search. If indexed, this fieldType must not be multivalued. -->
<fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
<!-- Field type where stopwords are managed by the REST API -->
<!-- Field type where english stopwords are managed by the REST API -->
<fieldtype name="managed_en" class="solr.TextField">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
@ -436,6 +436,15 @@
</analyzer>
</fieldtype>
<!-- Field type where german stopwords are managed by the REST API -->
<fieldtype name="managed_de" class="solr.TextField">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.ManagedStopFilterFactory" managed="german" />
<filter class="solr.ManagedSynonymFilterFactory" managed="german" />
</analyzer>
</fieldtype>
</types>

View File

@ -28,6 +28,8 @@ import org.apache.solr.rest.ManagedResourceStorage.StorageIO;
import org.apache.solr.rest.schema.analysis.ManagedWordSetResource;
import org.junit.Test;
import org.noggit.JSONUtil;
import org.restlet.Request;
import org.restlet.data.Reference;
/**
* Tests {@link RestManager} functionality, including resource registration,
@ -248,4 +250,30 @@ public class TestRestManager extends SolrRestletTestBase {
RestManager restManager2 = new RestManager();
restManager2.init(loader, initArgs, storageIO);
}
@Test
public void testResolveResourceId () throws Exception {
Request testRequest = new Request();
Reference rootRef = new Reference("http://solr.apache.org/");
testRequest.setRootRef(rootRef);
Reference resourceRef = new Reference("http://solr.apache.org/schema/analysis/synonyms/de");
testRequest.setResourceRef(resourceRef);
String resourceId = RestManager.ManagedEndpoint.resolveResourceId(testRequest);
assertEquals(resourceId, "/schema/analysis/synonyms/de");
}
@Test
public void testResolveResourceIdDecodeUrlEntities () throws Exception {
Request testRequest = new Request();
Reference rootRef = new Reference("http://solr.apache.org/");
testRequest.setRootRef(rootRef);
Reference resourceRef = new Reference("http://solr.apache.org/schema/analysis/synonyms/de/%C3%84ndern");
testRequest.setResourceRef(resourceRef);
String resourceId = RestManager.ManagedEndpoint.resolveResourceId(testRequest);
assertEquals(resourceId, "/schema/analysis/synonyms/de/Ändern");
}
}

View File

@ -185,4 +185,29 @@ public class TestManagedStopFilterFactory extends RestTestBase {
// should fail with 404 as foo doesn't exist
assertJDelete(endpoint + "/foo", "/error/code==404");
}
/**
* Can we add and remove stopwords with umlauts
*/
@Test
public void testCanHandleDecodingAndEncodingForStopwords() throws Exception {
String endpoint = "/schema/analysis/stopwords/german";
//initially it should not exist
assertJQ(endpoint + "/schön", "/error/code==404");
//now we put a stopword with an umlaut
assertJPut(endpoint,
JSONUtil.toJSON(Arrays.asList("schön")),
"/responseHeader/status==0");
//let's check if it exists
assertJQ(endpoint + "/schön", "/schön=='schön'");
//now let's remove it
assertJDelete(endpoint + "/schön", "/responseHeader/status==0");
//and of it is unavailable again
assertJQ(endpoint + "/schön", "/error/code==404");
}
}

View File

@ -196,4 +196,41 @@ public class TestManagedSynonymFilterFactory extends RestTestBase {
assertJQ(endpoint+"/MB",
"/MB==['Megabyte','MiB','megabyte']");
}
/**
* Can we add and remove stopwords with umlauts
*/
@Test
public void testCanHandleDecodingAndEncodingForSynonyms() throws Exception {
String endpoint = "/schema/analysis/synonyms/german";
assertJQ(endpoint,
"/synonymMappings/initArgs/ignoreCase==false",
"/synonymMappings/managedMap=={}");
// does not exist
assertJQ(endpoint+"/fröhlich",
"/error/code==404");
Map<String,List<String>> syns = new HashMap<>();
// now put a synonym
syns.put("fröhlich", Arrays.asList("glücklick"));
assertJPut(endpoint,
JSONUtil.toJSON(syns),
"/responseHeader/status==0");
// and check if it exists
assertJQ(endpoint,
"/synonymMappings/managedMap/fröhlich==['glücklick']");
// verify delete works
assertJDelete(endpoint+"/fröhlich",
"/responseHeader/status==0");
// was it really deleted?
assertJDelete(endpoint+"/fröhlich",
"/error/code==404");
}
}