From 63edfb11c619e305c0183b1399b05195185d988f Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Wed, 15 Apr 2015 04:57:39 +0000 Subject: [PATCH] Merged revision(s) 1673647 from lucene/dev/branches/branch_5x: SOLR-7376: Return raw XML or JSON ........ git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1673649 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 4 + .../solr/response/TextResponseWriter.java | 2 + .../transform/TransformerFactory.java | 2 + .../apache/solr/search/SolrReturnFields.java | 8 +- .../apache/solr/common/util/JavaBinCodec.java | 14 ++- .../solr/client/solrj/SolrExampleTests.java | 91 ++++++++++++++++++- 6 files changed, 116 insertions(+), 5 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 162c45778e9..f6277d39bc6 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -97,6 +97,10 @@ New Features * SOLR-7372: Limit memory consumed by LRUCache with a new 'maxRamMB' config parameter. (yonik, shalin) +* SOLR-7376: Return raw XML or JSON (in the appropriate writer) using DocumentTransformers. + ?fl=id,name,json_s:[json],xml_s:[xml] (ryan) + + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java b/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java index d488604183d..e52941f5eed 100644 --- a/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java +++ b/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java @@ -203,6 +203,8 @@ public abstract class TextResponseWriter { writeByteArr(name, arr.bytes, arr.offset, arr.length); } else if (val instanceof EnumFieldValue) { writeStr(name, val.toString(), true); + } else if (val instanceof WriteableValue) { + ((WriteableValue)val).write(name, this); } else { // default... for debugging only writeStr(name, val.getClass().getName() + ':' + val.toString(), true); diff --git a/solr/core/src/java/org/apache/solr/response/transform/TransformerFactory.java b/solr/core/src/java/org/apache/solr/response/transform/TransformerFactory.java index 584144abf3d..f459ae4dca2 100644 --- a/solr/core/src/java/org/apache/solr/response/transform/TransformerFactory.java +++ b/solr/core/src/java/org/apache/solr/response/transform/TransformerFactory.java @@ -48,5 +48,7 @@ public abstract class TransformerFactory implements NamedListInitializedPlugin defaultFactories.put( "docid", new DocIdAugmenterFactory() ); defaultFactories.put( "shard", new ShardAugmenterFactory() ); defaultFactories.put( "child", new ChildDocTransformerFactory() ); + defaultFactories.put( "json", new RawValueTransformerFactory("json") ); + defaultFactories.put( "xml", new RawValueTransformerFactory("xml") ); } } diff --git a/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java b/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java index e352dc7786a..61271d997da 100644 --- a/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java +++ b/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java @@ -22,6 +22,7 @@ import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.queries.function.valuesource.QueryValueSource; import org.apache.lucene.search.Query; import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.MapSolrParams; import org.apache.solr.common.params.SolrParams; @@ -261,10 +262,13 @@ public class SolrReturnFields extends ReturnFields { TransformerFactory factory = req.getCore().getTransformerFactory( augmenterName ); if( factory != null ) { MapSolrParams augmenterParams = new MapSolrParams( augmenterArgs ); - augmenters.addTransformer( factory.create(disp, augmenterParams, req) ); + DocTransformer t = factory.create(disp, augmenterParams, req); + if(t!=null) { + augmenters.addTransformer( t ); + } } else { - // unknown transformer? + //throw new SolrException(ErrorCode.BAD_REQUEST, "Unknown DocTransformer: "+augmenterName); } addField(field, disp, augmenters, true); continue; diff --git a/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java b/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java index 17a556a7682..3674f4dde29 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java @@ -95,6 +95,10 @@ public class JavaBinCodec { this.stringCache = stringCache; } + public ObjectResolver getResolver() { + return resolver; + } + public void marshal(Object nl, OutputStream os) throws IOException { init(FastOutputStream.wrap(os)); try { @@ -159,9 +163,15 @@ public class JavaBinCodec { if (writeKnownType(val)) { return; } else { - Object tmpVal = val; + ObjectResolver resolver = null; + if(val instanceof ObjectResolver) { + resolver = (ObjectResolver)val; + } + else { + resolver = this.resolver; + } if (resolver != null) { - tmpVal = resolver.resolve(val, this); + Object tmpVal = resolver.resolve(val, this); if (tmpVal == null) return; // null means the resolver took care of it fully if (writeKnownType(tmpVal)) return; } diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java index 9ed751fe8be..7641a2fa2cf 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java @@ -19,13 +19,17 @@ package org.apache.solr.client.solrj; import com.google.common.collect.Maps; + import junit.framework.Assert; + import org.apache.lucene.util.TestUtil; import org.apache.solr.SolrTestCaseJ4.SuppressSSL; import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; import org.apache.solr.client.solrj.impl.BinaryResponseParser; import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient; import org.apache.solr.client.solrj.impl.HttpSolrClient; +import org.apache.solr.client.solrj.impl.HttpSolrClient.RemoteSolrException; +import org.apache.solr.client.solrj.impl.NoOpResponseParser; import org.apache.solr.client.solrj.impl.XMLResponseParser; import org.apache.solr.client.solrj.request.AbstractUpdateRequest; import org.apache.solr.client.solrj.request.AbstractUpdateRequest.ACTION; @@ -42,6 +46,7 @@ import org.apache.solr.client.solrj.response.UpdateResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.AnalysisParams; import org.apache.solr.common.params.CommonParams; @@ -49,6 +54,7 @@ import org.apache.solr.common.params.FacetParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; import org.junit.Test; +import org.noggit.JSONParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -521,6 +527,89 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase assertEquals( "aaa", out1.get( "aaa" ) ); assertEquals( 10, ((Integer)out1.get( "ten" )).intValue() ); } + + + @Test + public void testRawFields() throws Exception + { + String rawJson = "{ \"raw\": 1.234, \"id\":\"111\" }"; + String rawXml = "this is "; + SolrClient client = getSolrClient(); + + // Empty the database... + client.deleteByQuery("*:*");// delete everything! + + // Now add something... + SolrInputDocument doc = new SolrInputDocument(); + doc.addField( "id", "111", 1.0f ); + doc.addField( "name", "doc1", 1.0f ); + doc.addField( "json_s", rawJson ); + doc.addField( "xml_s", rawXml ); + client.add(doc); + client.commit(); // make sure this gets in first + + SolrQuery query = new SolrQuery(); + query.setQuery( "*:*" ); + query.set( CommonParams.FL, "id,json_s:[json],xml_s:[xml]" ); + + QueryRequest req = new QueryRequest( query ); + req.setResponseParser(new BinaryResponseParser()); + QueryResponse rsp = req.process(client); + + SolrDocumentList out = rsp.getResults(); + assertEquals( 1, out.getNumFound() ); + SolrDocument out1 = out.get( 0 ); + assertEquals( "111", out1.getFieldValue( "id" ) ); + + // Check that the 'raw' fields are unchanged using the standard formats + assertEquals( rawJson, out1.get( "json_s" ) ); + assertEquals( rawXml, out1.get( "xml_s" ) ); + +// // Check that unknown augmenters throw an error +// query.set( CommonParams.FL, "id,[asdkgjahsdgjka]" ); +// try { +// rsp = client.query( query ); +// fail("Should throw an exception for unknown transformer: "+query.get(CommonParams.FL)); +// } +// catch(SolrException ex) { +// assertEquals(ErrorCode.BAD_REQUEST.code, ex.code()); +// } + + if(client instanceof EmbeddedSolrServer) { + return; // the EmbeddedSolrServer ignores the configured parser + } + + // Check raw JSON Output + query.set("fl", "id,json_s:[json],xml_s:[xml]"); + query.set(CommonParams.WT, "json"); + + req = new QueryRequest( query ); + req.setResponseParser(new NoOpResponseParser("json")); + NamedList resp = client.request(req); + String raw = (String)resp.get("response"); + + // Check that the response parses as JSON + JSONParser parser = new JSONParser(raw); + int evt = parser.nextEvent(); + while(evt!=JSONParser.EOF) { + evt = parser.nextEvent(); + } + assertTrue(raw.indexOf(rawJson)>0); // no escaping + assertTrue(raw.indexOf('"'+rawXml+'"')>0); // quoted xml + + // Check raw XML Output + req.setResponseParser(new NoOpResponseParser("xml")); + query.set("fl", "id,json_s:[json],xml_s:[xml]"); + query.set(CommonParams.WT, "xml"); + req = new QueryRequest( query ); + req.setResponseParser(new NoOpResponseParser("xml")); + resp = client.request(req); + raw = (String)resp.get("response"); + + // Check that we get raw xml and json is escaped + assertTrue(raw.indexOf('>'+rawJson+'<')>0); // escaped + assertTrue(raw.indexOf(rawXml)>0); // raw xml + } @Test public void testUpdateRequestWithParameters() throws Exception { @@ -1781,4 +1870,4 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase } return sdoc; } -} +} \ No newline at end of file