http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/FieldAnalysisRequest.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/FieldAnalysisRequest.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/FieldAnalysisRequest.java new file mode 100644 index 0000000..66ef535 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/FieldAnalysisRequest.java @@ -0,0 +1,270 @@ +/* + * 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.solr.client.solrj.request; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.response.FieldAnalysisResponse; +import org.apache.solr.common.params.AnalysisParams; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.ContentStream; + +import java.io.IOException; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +/** + * A request for the org.apache.solr.handler.FieldAnalysisRequestHandler. + * + * + * @since solr.14 + */ +public class FieldAnalysisRequest extends SolrRequest<FieldAnalysisResponse> { + + private String fieldValue; + private String query; + private boolean showMatch; + private List<String> fieldNames; + private List<String> fieldTypes; + + /** + * Constructs a new FieldAnalysisRequest with a default uri of "/fieldanalysis". + */ + public FieldAnalysisRequest() { + super(METHOD.GET, "/analysis/field"); + } + + /** + * Constructs a new FieldAnalysisRequest with a given uri. + * + * @param uri the uri of the request handler. + */ + public FieldAnalysisRequest(String uri) { + super(METHOD.GET, uri); + } + + /** + * {@inheritDoc} + */ + @Override + public Collection<ContentStream> getContentStreams() throws IOException { + return null; + } + + @Override + protected FieldAnalysisResponse createResponse(SolrClient client) { + if (fieldTypes == null && fieldNames == null) { + throw new IllegalStateException("At least one field type or field name need to be specified"); + } + if (fieldValue == null) { + throw new IllegalStateException("The field value must be set"); + } + return new FieldAnalysisResponse(); + } + + /** + * {@inheritDoc} + */ + @Override + public SolrParams getParams() { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set(AnalysisParams.FIELD_VALUE, fieldValue); + if (query != null) { + params.add(AnalysisParams.QUERY, query); + params.add(AnalysisParams.SHOW_MATCH, String.valueOf(showMatch)); + } + if (fieldNames != null) { + String fieldNameValue = listToCommaDelimitedString(fieldNames); + params.add(AnalysisParams.FIELD_NAME, fieldNameValue); + } + if (fieldTypes != null) { + String fieldTypeValue = listToCommaDelimitedString(fieldTypes); + params.add(AnalysisParams.FIELD_TYPE, fieldTypeValue); + } + return params; + } + + //================================================ Helper Methods ================================================== + + /** + * Convers the given list of string to a comma-separated string. + * + * @param list The list of string. + * + * @return The comma-separated string. + */ + static String listToCommaDelimitedString(List<String> list) { + StringBuilder result = new StringBuilder(); + for (String str : list) { + if (result.length() > 0) { + result.append(","); + } + result.append(str); + } + return result.toString(); + } + + + //============================================ Setter/Getter Methods =============================================== + + /** + * Sets the field value to be analyzed. + * + * @param fieldValue The field value to be analyzed. + * + * @return This FieldAnalysisRequest (fluent interface support). + */ + public FieldAnalysisRequest setFieldValue(String fieldValue) { + this.fieldValue = fieldValue; + return this; + } + + /** + * Returns the field value that will be analyzed when this request is processed. + * + * @return The field value that will be analyzed when this request is processed. + */ + public String getFieldValue() { + return fieldValue; + } + + /** + * Sets the query to be analyzed. May be {@code null} indicated that no query analysis should take place. + * + * @param query The query to be analyzed. + * + * @return This FieldAnalysisRequest (fluent interface support). + */ + public FieldAnalysisRequest setQuery(String query) { + this.query = query; + return this; + } + + /** + * Returns the query that will be analyzed. May return {@code null} indicating that no query analysis will be + * performed. + * + * @return The query that will be analyzed. May return {@code null} indicating that no query analysis will be + * performed. + */ + public String getQuery() { + return query; + } + + /** + * Sets whether index time tokens that match query time tokens should be marked as a "match". By default this is set + * to {@code false}. Obviously, this flag is ignored if when the query is set to {@code null}. + * + * @param showMatch Sets whether index time tokens that match query time tokens should be marked as a "match". + * + * @return This FieldAnalysisRequest (fluent interface support). + */ + public FieldAnalysisRequest setShowMatch(boolean showMatch) { + this.showMatch = showMatch; + return this; + } + + /** + * Returns whether index time tokens that match query time tokens should be marked as a "match". + * + * @return Whether index time tokens that match query time tokens should be marked as a "match". + * + * @see #setShowMatch(boolean) + */ + public boolean isShowMatch() { + return showMatch; + } + + /** + * Adds the given field name for analysis. + * + * @param fieldName A field name on which the analysis should be performed. + * + * @return this FieldAnalysisRequest (fluent interface support). + */ + public FieldAnalysisRequest addFieldName(String fieldName) { + if (fieldNames == null) { + fieldNames = new LinkedList<>(); + } + fieldNames.add(fieldName); + return this; + } + + /** + * Sets the field names on which the analysis should be performed. + * + * @param fieldNames The field names on which the analysis should be performed. + * + * @return this FieldAnalysisRequest (fluent interface support). + */ + public FieldAnalysisRequest setFieldNames(List<String> fieldNames) { + this.fieldNames = fieldNames; + return this; + } + + /** + * Returns a list of field names the analysis should be performed on. May return {@code null} indicating that no + * analysis will be performed on field names. + * + * @return The field names the analysis should be performed on. + */ + public List<String> getFieldNames() { + return fieldNames; + } + + /** + * Adds the given field type for analysis. + * + * @param fieldTypeName A field type name on which analysis should be performed. + * + * @return This FieldAnalysisRequest (fluent interface support). + */ + public FieldAnalysisRequest addFieldType(String fieldTypeName) { + if (fieldTypes == null) { + fieldTypes = new LinkedList<>(); + } + fieldTypes.add(fieldTypeName); + return this; + } + +/** + * Sets the field types on which analysis should be performed. + * + * @param fieldTypes The field type names on which analysis should be performed. + * + * @return This FieldAnalysisRequest (fluent interface support). + */ + public FieldAnalysisRequest setFieldTypes(List<String> fieldTypes) { + this.fieldTypes = fieldTypes; + return this; + } + + + /** + * Returns a list of field types the analysis should be performed on. May return {@code null} indicating that no + * analysis will be peformed on field types. + * + * @return The field types the analysis should be performed on. + */ + public List<String> getFieldTypes() { + return fieldTypes; + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/IsUpdateRequest.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/IsUpdateRequest.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/IsUpdateRequest.java new file mode 100644 index 0000000..ec49e30 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/IsUpdateRequest.java @@ -0,0 +1,26 @@ +package org.apache.solr.client.solrj.request; + +/* + * 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. + */ + + +/** + * Marker class so that we can determine which requests are updates. + */ +public interface IsUpdateRequest { + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/JavaBinUpdateRequestCodec.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/JavaBinUpdateRequestCodec.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/JavaBinUpdateRequestCodec.java new file mode 100644 index 0000000..7bb64b4 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/JavaBinUpdateRequestCodec.java @@ -0,0 +1,251 @@ +/* + * 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.solr.client.solrj.request; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.DataInputInputStream; +import org.apache.solr.common.util.JavaBinCodec; +import org.apache.solr.common.util.NamedList; + +/** + * Provides methods for marshalling an UpdateRequest to a NamedList which can be serialized in the javabin format and + * vice versa. + * + * + * @see org.apache.solr.common.util.JavaBinCodec + * @since solr 1.4 + */ +public class JavaBinUpdateRequestCodec { + + /** + * Converts an UpdateRequest to a NamedList which can be serialized to the given OutputStream in the javabin format + * + * @param updateRequest the UpdateRequest to be written out + * @param os the OutputStream to which the request is to be written + * + * @throws IOException in case of an exception during marshalling or writing to the stream + */ + public void marshal(UpdateRequest updateRequest, OutputStream os) throws IOException { + NamedList nl = new NamedList(); + NamedList params = solrParamsToNamedList(updateRequest.getParams()); + if (updateRequest.getCommitWithin() != -1) { + params.add("commitWithin", updateRequest.getCommitWithin()); + } + Iterator<SolrInputDocument> docIter = null; + + if(updateRequest.getDocIterator() != null){ + docIter = updateRequest.getDocIterator(); + } + + Map<SolrInputDocument,Map<String,Object>> docMap = updateRequest.getDocumentsMap(); + + nl.add("params", params);// 0: params + if (updateRequest.getDeleteByIdMap() != null) { + nl.add("delByIdMap", updateRequest.getDeleteByIdMap()); + } + nl.add("delByQ", updateRequest.getDeleteQuery()); + + if (docMap != null) { + nl.add("docsMap", docMap.entrySet().iterator()); + } else { + if (updateRequest.getDocuments() != null) { + docIter = updateRequest.getDocuments().iterator(); + } + nl.add("docs", docIter); + } + JavaBinCodec codec = new JavaBinCodec(); + codec.marshal(nl, os); + } + + /** + * Reads a NamedList from the given InputStream, converts it into a SolrInputDocument and passes it to the given + * StreamingUpdateHandler + * + * @param is the InputStream from which to read + * @param handler an instance of StreamingUpdateHandler to which SolrInputDocuments are streamed one by one + * + * @return the UpdateRequest + * + * @throws IOException in case of an exception while reading from the input stream or unmarshalling + */ + public UpdateRequest unmarshal(InputStream is, final StreamingUpdateHandler handler) throws IOException { + final UpdateRequest updateRequest = new UpdateRequest(); + List<List<NamedList>> doclist; + List<Entry<SolrInputDocument,Map<Object,Object>>> docMap; + List<String> delById; + Map<String,Map<String,Object>> delByIdMap; + List<String> delByQ; + final NamedList[] namedList = new NamedList[1]; + JavaBinCodec codec = new JavaBinCodec() { + + // NOTE: this only works because this is an anonymous inner class + // which will only ever be used on a single stream -- if this class + // is ever refactored, this will not work. + private boolean seenOuterMostDocIterator = false; + + @Override + public NamedList readNamedList(DataInputInputStream dis) throws IOException { + int sz = readSize(dis); + NamedList nl = new NamedList(); + if (namedList[0] == null) { + namedList[0] = nl; + } + for (int i = 0; i < sz; i++) { + String name = (String) readVal(dis); + Object val = readVal(dis); + nl.add(name, val); + } + return nl; + } + + @Override + public List readIterator(DataInputInputStream fis) throws IOException { + + // default behavior for reading any regular Iterator in the stream + if (seenOuterMostDocIterator) return super.readIterator(fis); + + // special treatment for first outermost Iterator + // (the list of documents) + seenOuterMostDocIterator = true; + return readOuterMostDocIterator(fis); + } + + private List readOuterMostDocIterator(DataInputInputStream fis) throws IOException { + NamedList params = (NamedList) namedList[0].get("params"); + updateRequest.setParams(new ModifiableSolrParams(SolrParams.toSolrParams(params))); + if (handler == null) return super.readIterator(fis); + Integer commitWithin = null; + Boolean overwrite = null; + while (true) { + Object o = readVal(fis); + if (o == END_OBJ) break; + SolrInputDocument sdoc = null; + if (o instanceof List) { + sdoc = listToSolrInputDocument((List<NamedList>) o); + } else if (o instanceof NamedList) { + UpdateRequest req = new UpdateRequest(); + req.setParams(new ModifiableSolrParams(SolrParams.toSolrParams((NamedList) o))); + handler.update(null, req, null, null); + } else if (o instanceof Map.Entry){ + sdoc = (SolrInputDocument) ((Map.Entry) o).getKey(); + Map p = (Map) ((Map.Entry) o).getValue(); + if (p != null) { + commitWithin = (Integer) p.get(UpdateRequest.COMMIT_WITHIN); + overwrite = (Boolean) p.get(UpdateRequest.OVERWRITE); + } + } else { + + sdoc = (SolrInputDocument) o; + } + handler.update(sdoc, updateRequest, commitWithin, overwrite); + } + return Collections.EMPTY_LIST; + } + + }; + + codec.unmarshal(is); + + // NOTE: if the update request contains only delete commands the params + // must be loaded now + if(updateRequest.getParams()==null) { + NamedList params = (NamedList) namedList[0].get("params"); + if(params!=null) { + updateRequest.setParams(new ModifiableSolrParams(SolrParams.toSolrParams(params))); + } + } + delById = (List<String>) namedList[0].get("delById"); + delByIdMap = (Map<String,Map<String,Object>>) namedList[0].get("delByIdMap"); + delByQ = (List<String>) namedList[0].get("delByQ"); + doclist = (List) namedList[0].get("docs"); + Object docsMapObj = namedList[0].get("docsMap"); + + if (docsMapObj instanceof Map) {//SOLR-5762 + docMap = new ArrayList(((Map)docsMapObj).entrySet()); + } else { + docMap = (List<Entry<SolrInputDocument, Map<Object, Object>>>) docsMapObj; + } + + + // we don't add any docs, because they were already processed + // deletes are handled later, and must be passed back on the UpdateRequest + + if (delById != null) { + for (String s : delById) { + updateRequest.deleteById(s); + } + } + if (delByIdMap != null) { + for (Map.Entry<String,Map<String,Object>> entry : delByIdMap.entrySet()) { + Map<String,Object> params = entry.getValue(); + if (params != null) { + Long version = (Long) params.get(UpdateRequest.VER); + if (params.containsKey(UpdateRequest.ROUTE)) + updateRequest.deleteById(entry.getKey(), (String) params.get(UpdateRequest.ROUTE)); + else + updateRequest.deleteById(entry.getKey(), version); + } else { + updateRequest.deleteById(entry.getKey()); + } + + } + } + if (delByQ != null) { + for (String s : delByQ) { + updateRequest.deleteByQuery(s); + } + } + + return updateRequest; + } + + private SolrInputDocument listToSolrInputDocument(List<NamedList> namedList) { + SolrInputDocument doc = new SolrInputDocument(); + for (int i = 0; i < namedList.size(); i++) { + NamedList nl = namedList.get(i); + if (i == 0) { + doc.setDocumentBoost(nl.getVal(0) == null ? 1.0f : (Float) nl.getVal(0)); + } else { + doc.addField((String) nl.getVal(0), + nl.getVal(1), + nl.getVal(2) == null ? 1.0f : (Float) nl.getVal(2)); + } + } + return doc; + } + + private NamedList solrParamsToNamedList(SolrParams params) { + if (params == null) return new NamedList(); + return params.toNamedList(); + } + + public static interface StreamingUpdateHandler { + public void update(SolrInputDocument document, UpdateRequest req, Integer commitWithin, Boolean override); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/LukeRequest.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/LukeRequest.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/LukeRequest.java new file mode 100644 index 0000000..82b5330 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/LukeRequest.java @@ -0,0 +1,120 @@ +/* + * 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.solr.client.solrj.request; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.response.LukeResponse; +import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.ContentStream; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * + * + * @since solr 1.3 + */ +public class LukeRequest extends SolrRequest<LukeResponse> { + + private List<String> fields; + private int numTerms = -1; + private boolean showSchema = false; + + public LukeRequest() + { + super( METHOD.GET, "/admin/luke" ); + } + + public LukeRequest( String path ) + { + super( METHOD.GET, path ); + } + + //--------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------- + + public void addField( String f ) + { + if( fields == null ) { + fields = new ArrayList<>(); + } + fields.add( f ); + } + + public void setFields( List<String> f ) + { + fields = f; + } + + //--------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------- + + public boolean isShowSchema() { + return showSchema; + } + + public void setShowSchema(boolean showSchema) { + this.showSchema = showSchema; + } + + public int getNumTerms() { + return numTerms; + } + + /** + * the number of terms to return for a given field. If the number is 0, it will not traverse the terms. + */ + public void setNumTerms(int count) { + this.numTerms = count; + } + + //--------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------- + + @Override + public Collection<ContentStream> getContentStreams() { + return null; + } + + @Override + protected LukeResponse createResponse(SolrClient client) { + return new LukeResponse(); + } + + @Override + public SolrParams getParams() { + ModifiableSolrParams params = new ModifiableSolrParams(); + if( fields != null && fields.size() > 0 ) { + params.add( CommonParams.FL, fields.toArray( new String[fields.size()] ) ); + } + if( numTerms >= 0 ) { + params.add( "numTerms", numTerms+"" ); + } + if (showSchema) { + params.add("show", "schema"); + } + return params; + } + +} + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/QueryRequest.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/QueryRequest.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/QueryRequest.java new file mode 100644 index 0000000..9d47f99 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/QueryRequest.java @@ -0,0 +1,89 @@ +/* + * 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.solr.client.solrj.request; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.ContentStream; + +import java.util.Collection; + +/** + * + * + * @since solr 1.3 + */ +public class QueryRequest extends SolrRequest<QueryResponse> { + + private SolrParams query; + + public QueryRequest() + { + super( METHOD.GET, null ); + } + + public QueryRequest( SolrParams q ) + { + super( METHOD.GET, null ); + query = q; + } + + public QueryRequest( SolrParams q, METHOD method ) + { + super( method, null ); + query = q; + } + + /** + * Use the params 'QT' parameter if it exists + */ + @Override + public String getPath() { + String qt = query == null ? null : query.get( CommonParams.QT ); + if( qt == null ) { + qt = super.getPath(); + } + if( qt != null && qt.startsWith( "/" ) ) { + return qt; + } + return "/select"; + } + + //--------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------- + + @Override + public Collection<ContentStream> getContentStreams() { + return null; + } + + @Override + protected QueryResponse createResponse(SolrClient client) { + return new QueryResponse(client); + } + + @Override + public SolrParams getParams() { + return query; + } + +} + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/RequestWriter.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/RequestWriter.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/RequestWriter.java new file mode 100644 index 0000000..15872b2 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/RequestWriter.java @@ -0,0 +1,146 @@ +/* + * 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.solr.client.solrj.request; + +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.util.ClientUtils; +import org.apache.solr.common.util.ContentStream; +import org.apache.solr.common.util.ContentStreamBase; + +import java.io.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + * A RequestWriter is used to write requests to Solr. + * <p> + * A subclass can override the methods in this class to supply a custom format in which a request can be sent. + * + * + * @since solr 1.4 + */ +public class RequestWriter { + public static final Charset UTF_8 = StandardCharsets.UTF_8; + + public Collection<ContentStream> getContentStreams(SolrRequest req) throws IOException { + if (req instanceof UpdateRequest) { + UpdateRequest updateRequest = (UpdateRequest) req; + if (isEmpty(updateRequest)) return null; + List<ContentStream> l = new ArrayList<>(); + l.add(new LazyContentStream(updateRequest)); + return l; + } + return req.getContentStreams(); + } + + private boolean isEmpty(UpdateRequest updateRequest) { + return isNull(updateRequest.getDocuments()) && + isNull(updateRequest.getDeleteByIdMap()) && + isNull(updateRequest.getDeleteQuery()) && + updateRequest.getDocIterator() == null; + } + + public String getPath(SolrRequest req) { + return req.getPath(); + } + + public ContentStream getContentStream(UpdateRequest req) throws IOException { + return new ContentStreamBase.StringStream(req.getXML()); + } + + public void write(SolrRequest request, OutputStream os) throws IOException { + if (request instanceof UpdateRequest) { + UpdateRequest updateRequest = (UpdateRequest) request; + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, UTF_8)); + updateRequest.writeXML(writer); + writer.flush(); + } + } + + public String getUpdateContentType() { + return ClientUtils.TEXT_XML; + + } + + public class LazyContentStream implements ContentStream { + ContentStream contentStream = null; + UpdateRequest req = null; + + public LazyContentStream(UpdateRequest req) { + this.req = req; + } + + private ContentStream getDelegate() { + if (contentStream == null) { + try { + contentStream = getContentStream(req); + } catch (IOException e) { + throw new RuntimeException("Unable to write xml into a stream", e); + } + } + return contentStream; + } + + @Override + public String getName() { + return getDelegate().getName(); + } + + @Override + public String getSourceInfo() { + return getDelegate().getSourceInfo(); + } + + @Override + public String getContentType() { + return getUpdateContentType(); + } + + @Override + public Long getSize() { + return getDelegate().getSize(); + } + + @Override + public InputStream getStream() throws IOException { + return getDelegate().getStream(); + } + + @Override + public Reader getReader() throws IOException { + return getDelegate().getReader(); + } + + public void writeTo(OutputStream os) throws IOException { + write(req, os); + + } + } + + protected boolean isNull(List l) { + return l == null || l.isEmpty(); + } + + protected boolean isNull(Map l) { + return l == null || l.isEmpty(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/SolrPing.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/SolrPing.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/SolrPing.java new file mode 100644 index 0000000..00ad41f --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/SolrPing.java @@ -0,0 +1,111 @@ +/* + * 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.solr.client.solrj.request; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.util.ContentStream; + +import java.util.Collection; + +/** + * Verify that there is a working Solr core at the URL of a {@link org.apache.solr.client.solrj.SolrClient}. + * To use this class, the solrconfig.xml for the relevant core must include the + * request handler for <code>/admin/ping</code>. + * + * @since solr 1.3 + */ +public class SolrPing extends SolrRequest<SolrPingResponse> { + + /** serialVersionUID. */ + private static final long serialVersionUID = 5828246236669090017L; + + /** Request parameters. */ + private ModifiableSolrParams params; + + /** + * Create a new SolrPing object. + */ + public SolrPing() { + super(METHOD.GET, CommonParams.PING_HANDLER); + params = new ModifiableSolrParams(); + } + + @Override + public Collection<ContentStream> getContentStreams() { + return null; + } + + @Override + protected SolrPingResponse createResponse(SolrClient client) { + return new SolrPingResponse(); + } + + @Override + public ModifiableSolrParams getParams() { + return params; + } + + /** + * Remove the action parameter from this request. This will result in the same + * behavior as {@code SolrPing#setActionPing()}. For Solr server version 4.0 + * and later. + * + * @return this + */ + public SolrPing removeAction() { + params.remove(CommonParams.ACTION); + return this; + } + + /** + * Set the action parameter on this request to enable. This will delete the + * health-check file for the Solr core. For Solr server version 4.0 and later. + * + * @return this + */ + public SolrPing setActionDisable() { + params.set(CommonParams.ACTION, CommonParams.DISABLE); + return this; + } + + /** + * Set the action parameter on this request to enable. This will create the + * health-check file for the Solr core. For Solr server version 4.0 and later. + * + * @return this + */ + public SolrPing setActionEnable() { + params.set(CommonParams.ACTION, CommonParams.ENABLE); + return this; + } + + /** + * Set the action parameter on this request to ping. This is the same as not + * including the action at all. For Solr server version 4.0 and later. + * + * @return this + */ + public SolrPing setActionPing() { + params.set(CommonParams.ACTION, CommonParams.PING); + return this; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/UpdateRequest.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/UpdateRequest.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/UpdateRequest.java new file mode 100644 index 0000000..0e6580c --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/UpdateRequest.java @@ -0,0 +1,463 @@ +/* + * 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.solr.client.solrj.request; + +import org.apache.solr.client.solrj.impl.LBHttpSolrClient; +import org.apache.solr.client.solrj.util.ClientUtils; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.cloud.DocCollection; +import org.apache.solr.common.cloud.DocRouter; +import org.apache.solr.common.cloud.Slice; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.util.ContentStream; +import org.apache.solr.common.util.XML; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * + * + * @since solr 1.3 + */ +public class UpdateRequest extends AbstractUpdateRequest { + + public static final String REPFACT = "rf"; + public static final String MIN_REPFACT = "min_rf"; + public static final String VER = "ver"; + public static final String ROUTE = "_route_"; + public static final String OVERWRITE = "ow"; + public static final String COMMIT_WITHIN = "cw"; + private Map<SolrInputDocument,Map<String,Object>> documents = null; + private Iterator<SolrInputDocument> docIterator = null; + private Map<String,Map<String,Object>> deleteById = null; + private List<String> deleteQuery = null; + + public UpdateRequest() { + super(METHOD.POST, "/update"); + } + + public UpdateRequest(String url) { + super(METHOD.POST, url); + } + + // --------------------------------------------------------------------------- + // --------------------------------------------------------------------------- + + /** + * clear the pending documents and delete commands + */ + public void clear() { + if (documents != null) { + documents.clear(); + } + if (deleteById != null) { + deleteById.clear(); + } + if (deleteQuery != null) { + deleteQuery.clear(); + } + } + + // --------------------------------------------------------------------------- + // --------------------------------------------------------------------------- + + public UpdateRequest add(final SolrInputDocument doc) { + if (documents == null) { + documents = new LinkedHashMap<>(); + } + documents.put(doc, null); + return this; + } + + public UpdateRequest add(final SolrInputDocument doc, Boolean overwrite) { + return add(doc, null, overwrite); + } + + public UpdateRequest add(final SolrInputDocument doc, Integer commitWithin) { + return add(doc, commitWithin, null); + } + + public UpdateRequest add(final SolrInputDocument doc, Integer commitWithin, + Boolean overwrite) { + if (documents == null) { + documents = new LinkedHashMap<>(); + } + Map<String,Object> params = new HashMap<>(2); + if (commitWithin != null) params.put(COMMIT_WITHIN, commitWithin); + if (overwrite != null) params.put(OVERWRITE, overwrite); + + documents.put(doc, params); + + return this; + } + + public UpdateRequest add(final Collection<SolrInputDocument> docs) { + if (documents == null) { + documents = new LinkedHashMap<>(); + } + for (SolrInputDocument doc : docs) { + documents.put(doc, null); + } + return this; + } + + public UpdateRequest deleteById(String id) { + if (deleteById == null) { + deleteById = new LinkedHashMap<>(); + } + deleteById.put(id, null); + return this; + } + + public UpdateRequest deleteById(String id, String route) { + return deleteById(id, route, null); + } + + public UpdateRequest deleteById(String id, String route, Long version) { + if (deleteById == null) { + deleteById = new LinkedHashMap<>(); + } + Map<String, Object> params = (route == null && version == null) ? null : new HashMap<String, Object>(1); + if (version != null) + params.put(VER, version); + if (route != null) + params.put(ROUTE, route); + deleteById.put(id, params); + return this; + } + + + public UpdateRequest deleteById(List<String> ids) { + if (deleteById == null) { + deleteById = new LinkedHashMap<>(); + } + + for (String id : ids) { + deleteById.put(id, null); + } + + return this; + } + + public UpdateRequest deleteById(String id, Long version) { + return deleteById(id, null, version); + } + + public UpdateRequest deleteByQuery(String q) { + if (deleteQuery == null) { + deleteQuery = new ArrayList<>(); + } + deleteQuery.add(q); + return this; + } + + /** + * @param router to route updates with + * @param col DocCollection for the updates + * @param urlMap of the cluster + * @param params params to use + * @param idField the id field + * @return a Map of urls to requests + */ + public Map<String,LBHttpSolrClient.Req> getRoutes(DocRouter router, + DocCollection col, Map<String,List<String>> urlMap, + ModifiableSolrParams params, String idField) { + + if ((documents == null || documents.size() == 0) + && (deleteById == null || deleteById.size() == 0)) { + return null; + } + + Map<String,LBHttpSolrClient.Req> routes = new HashMap<>(); + if (documents != null) { + Set<Entry<SolrInputDocument,Map<String,Object>>> entries = documents.entrySet(); + for (Entry<SolrInputDocument,Map<String,Object>> entry : entries) { + SolrInputDocument doc = entry.getKey(); + Object id = doc.getFieldValue(idField); + if (id == null) { + return null; + } + Slice slice = router.getTargetSlice(id + .toString(), doc, null, null, col); + if (slice == null) { + return null; + } + List<String> urls = urlMap.get(slice.getName()); + String leaderUrl = urls.get(0); + LBHttpSolrClient.Req request = (LBHttpSolrClient.Req) routes + .get(leaderUrl); + if (request == null) { + UpdateRequest updateRequest = new UpdateRequest(); + updateRequest.setMethod(getMethod()); + updateRequest.setCommitWithin(getCommitWithin()); + updateRequest.setParams(params); + updateRequest.setPath(getPath()); + request = new LBHttpSolrClient.Req(updateRequest, urls); + routes.put(leaderUrl, request); + } + UpdateRequest urequest = (UpdateRequest) request.getRequest(); + Map<String,Object> value = entry.getValue(); + Boolean ow = null; + if (value != null) { + ow = (Boolean) value.get(OVERWRITE); + } + if (ow != null) { + urequest.add(doc, ow); + } else { + urequest.add(doc); + } + } + } + + // Route the deleteById's + + if (deleteById != null) { + + Iterator<Map.Entry<String,Map<String,Object>>> entries = deleteById.entrySet() + .iterator(); + while (entries.hasNext()) { + + Map.Entry<String,Map<String,Object>> entry = entries.next(); + + String deleteId = entry.getKey(); + Map<String,Object> map = entry.getValue(); + Long version = null; + if (map != null) { + version = (Long) map.get(VER); + } + Slice slice = router.getTargetSlice(deleteId, null, null, null, col); + if (slice == null) { + return null; + } + List<String> urls = urlMap.get(slice.getName()); + String leaderUrl = urls.get(0); + LBHttpSolrClient.Req request = routes.get(leaderUrl); + if (request != null) { + UpdateRequest urequest = (UpdateRequest) request.getRequest(); + urequest.deleteById(deleteId, version); + } else { + UpdateRequest urequest = new UpdateRequest(); + urequest.setParams(params); + urequest.deleteById(deleteId, version); + request = new LBHttpSolrClient.Req(urequest, urls); + routes.put(leaderUrl, request); + } + } + } + + return routes; + } + + public void setDocIterator(Iterator<SolrInputDocument> docIterator) { + this.docIterator = docIterator; + } + + public void setDeleteQuery(List<String> deleteQuery) { + this.deleteQuery = deleteQuery; + } + + // -------------------------------------------------------------------------- + // -------------------------------------------------------------------------- + + @Override + public Collection<ContentStream> getContentStreams() throws IOException { + return ClientUtils.toContentStreams(getXML(), ClientUtils.TEXT_XML); + } + + public String getXML() throws IOException { + StringWriter writer = new StringWriter(); + writeXML(writer); + writer.flush(); + + // If action is COMMIT or OPTIMIZE, it is sent with params + String xml = writer.toString(); + // System.out.println( "SEND:"+xml ); + return (xml.length() > 0) ? xml : null; + } + + private List<Map<SolrInputDocument,Map<String,Object>>> getDocLists(Map<SolrInputDocument,Map<String,Object>> documents) { + List<Map<SolrInputDocument,Map<String,Object>>> docLists = new ArrayList<>(); + Map<SolrInputDocument,Map<String,Object>> docList = null; + if (this.documents != null) { + + Boolean lastOverwrite = true; + Integer lastCommitWithin = -1; + + Set<Entry<SolrInputDocument,Map<String,Object>>> entries = this.documents + .entrySet(); + for (Entry<SolrInputDocument,Map<String,Object>> entry : entries) { + Map<String,Object> map = entry.getValue(); + Boolean overwrite = null; + Integer commitWithin = null; + if (map != null) { + overwrite = (Boolean) entry.getValue().get(OVERWRITE); + commitWithin = (Integer) entry.getValue().get(COMMIT_WITHIN); + } + if (overwrite != lastOverwrite || commitWithin != lastCommitWithin + || docLists.size() == 0) { + docList = new LinkedHashMap<>(); + docLists.add(docList); + } + docList.put(entry.getKey(), entry.getValue()); + lastCommitWithin = commitWithin; + lastOverwrite = overwrite; + } + } + + if (docIterator != null) { + docList = new LinkedHashMap<>(); + docLists.add(docList); + while (docIterator.hasNext()) { + SolrInputDocument doc = docIterator.next(); + if (doc != null) { + docList.put(doc, null); + } + } + + } + + return docLists; + } + + /** + * @since solr 1.4 + */ + public void writeXML(Writer writer) throws IOException { + List<Map<SolrInputDocument,Map<String,Object>>> getDocLists = getDocLists(documents); + + for (Map<SolrInputDocument,Map<String,Object>> docs : getDocLists) { + + if ((docs != null && docs.size() > 0)) { + Entry<SolrInputDocument,Map<String,Object>> firstDoc = docs.entrySet() + .iterator().next(); + Map<String,Object> map = firstDoc.getValue(); + Integer cw = null; + Boolean ow = null; + if (map != null) { + cw = (Integer) firstDoc.getValue().get(COMMIT_WITHIN); + ow = (Boolean) firstDoc.getValue().get(OVERWRITE); + } + if (ow == null) ow = true; + int commitWithin = (cw != null && cw != -1) ? cw : this.commitWithin; + boolean overwrite = ow; + if (commitWithin > -1 || overwrite != true) { + writer.write("<add commitWithin=\"" + commitWithin + "\" " + + "overwrite=\"" + overwrite + "\">"); + } else { + writer.write("<add>"); + } + + Set<Entry<SolrInputDocument,Map<String,Object>>> entries = docs + .entrySet(); + for (Entry<SolrInputDocument,Map<String,Object>> entry : entries) { + ClientUtils.writeXML(entry.getKey(), writer); + } + + writer.write("</add>"); + } + } + + // Add the delete commands + boolean deleteI = deleteById != null && deleteById.size() > 0; + boolean deleteQ = deleteQuery != null && deleteQuery.size() > 0; + if (deleteI || deleteQ) { + if (commitWithin > 0) { + writer.append("<delete commitWithin=\"" + commitWithin + "\">"); + } else { + writer.append("<delete>"); + } + if (deleteI) { + for (Map.Entry<String,Map<String,Object>> entry : deleteById.entrySet()) { + writer.append("<id"); + Map<String,Object> map = entry.getValue(); + if (map != null) { + Long version = (Long) map.get(VER); + String route = (String)map.get(ROUTE); + if (version != null) { + writer.append(" version=\"" + version + "\""); + } + + if (route != null) { + writer.append(" _route_=\"" + route + "\""); + } + } + writer.append(">"); + + XML.escapeCharData(entry.getKey(), writer); + writer.append("</id>"); + } + } + if (deleteQ) { + for (String q : deleteQuery) { + writer.append("<query>"); + XML.escapeCharData(q, writer); + writer.append("</query>"); + } + } + writer.append("</delete>"); + } + } + + // -------------------------------------------------------------------------- + // -------------------------------------------------------------------------- + + // -------------------------------------------------------------------------- + // + // -------------------------------------------------------------------------- + + public List<SolrInputDocument> getDocuments() { + if (documents == null) return null; + List<SolrInputDocument> docs = new ArrayList<>(documents.size()); + docs.addAll(documents.keySet()); + return docs; + } + + public Map<SolrInputDocument,Map<String,Object>> getDocumentsMap() { + return documents; + } + + public Iterator<SolrInputDocument> getDocIterator() { + return docIterator; + } + + public List<String> getDeleteById() { + if (deleteById == null) return null; + List<String> deletes = new ArrayList<>(deleteById.keySet()); + return deletes; + } + + public Map<String,Map<String,Object>> getDeleteByIdMap() { + return deleteById; + } + + public List<String> getDeleteQuery() { + return deleteQuery; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/package-info.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/package-info.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/package-info.java new file mode 100644 index 0000000..899a562 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/request/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * Convenience classes for dealing with various types of Solr requests. + */ +package org.apache.solr.client.solrj.request; + + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/AnalysisResponseBase.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/AnalysisResponseBase.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/AnalysisResponseBase.java new file mode 100644 index 0000000..21396a5 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/AnalysisResponseBase.java @@ -0,0 +1,252 @@ +/* + * 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.solr.client.solrj.response; + +import org.apache.solr.common.util.NamedList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * A base class for all analysis responses. + * + * + * @since solr 1.4 + */ +public class AnalysisResponseBase extends SolrResponseBase { + + /** + * Parses the given named list and builds a list of analysis phases form it. Expects a named list of the form: + * <br> + * <pre><code> + * <lst name="index"> + * <arr name="Tokenizer"> + * <str name="text">the_text</str> + * <str name="rawText">the_raw_text</str> (optional) + * <str name="type">the_type</str> + * <int name="start">1</str> + * <int name="end">3</str> + * <int name="position">1</str> + * <bool name="match">true | false</bool> (optional) + * </arr> + * <arr name="Filter1"> + * <str name="text">the_text</str> + * <str name="rawText">the_raw_text</str> (optional) + * <str name="type">the_type</str> + * <int name="start">1</str> + * <int name="end">3</str> + * <int name="position">1</str> + * <bool name="match">true | false</bool> (optional) + * </arr> + * ... + * </lst> + * </code></pre> + * + * @param phaseNL The names list to parse. + * + * @return The built analysis phases list. + */ + protected List<AnalysisPhase> buildPhases(NamedList<List<NamedList<Object>>> phaseNL) { + List<AnalysisPhase> phases = new ArrayList<>(phaseNL.size()); + for (Map.Entry<String, List<NamedList<Object>>> phaseEntry : phaseNL) { + AnalysisPhase phase = new AnalysisPhase(phaseEntry.getKey()); + List<NamedList<Object>> tokens = phaseEntry.getValue(); + for (NamedList<Object> token : tokens) { + TokenInfo tokenInfo = buildTokenInfo(token); + phase.addTokenInfo(tokenInfo); + } + phases.add(phase); + } + return phases; + } + + /** + * Parses the given named list and builds a token infoform it. Expects a named list of the form: + * <br> + * <pre><code> + * <arr name="Tokenizer"> + * <str name="text">the_text</str> + * <str name="rawText">the_raw_text</str> (optional) + * <str name="type">the_type</str> + * <int name="start">1</str> + * <int name="end">3</str> + * <int name="position">1</str> + * <bool name="match">true | false</bool> (optional) + * </arr> + * </code></pre> + * + * @param tokenNL The named list to parse. + * + * @return The built token info. + */ + protected TokenInfo buildTokenInfo(NamedList<Object> tokenNL) { + String text = (String) tokenNL.get("text"); + String rawText = (String) tokenNL.get("rawText"); + String type = (String) tokenNL.get("type"); + int start = (Integer) tokenNL.get("start"); + int end = (Integer) tokenNL.get("end"); + int position = (Integer) tokenNL.get("position"); + Boolean match = (Boolean) tokenNL.get("match"); + return new TokenInfo(text, rawText, type, start, end, position, (match == null ? false : match)); + } + + + //================================================= Inner Classes ================================================== + + /** + * A phase in the analysis process. The phase holds the tokens produced in this phase and the name of the class that + * produced them. + */ + public static class AnalysisPhase { + + private final String className; + private List<TokenInfo> tokens = new ArrayList<>(); + + AnalysisPhase(String className) { + this.className = className; + } + + /** + * The name of the class (analyzer, tokenzier, or filter) that produced the token stream for this phase. + * + * @return The name of the class that produced the token stream for this phase. + */ + public String getClassName() { + return className; + } + + private void addTokenInfo(TokenInfo tokenInfo) { + tokens.add(tokenInfo); + } + + /** + * Returns a list of tokens which represent the token stream produced in this phase. + * + * @return A list of tokens which represent the token stream produced in this phase. + */ + public List<TokenInfo> getTokens() { + return tokens; + } + + } + + /** + * Holds all information of a token as part of an analysis phase. + */ + public static class TokenInfo { + + private final String text; + private final String rawText; + private final String type; + private final int start; + private final int end; + private final int position; + private final boolean match; + + /** + * Constructs a new TokenInfo. + * + * @param text The text of the token + * @param rawText The raw text of the token. If the token is stored in the index in a special format (e.g. + * dates or padded numbers) this argument should hold this value. If the token is stored as is, + * then this value should be {@code null}. + * @param type The type fo the token (typically either {@code word} or {@code <ALPHANUM>} though it depends + * on the tokenizer/filter used). + * @param start The start position of the token in the original text where it was extracted from. + * @param end The end position of the token in the original text where it was extracted from. + * @param position The position of the token within the token stream. + * @param match Indicates whether this token matches one of the the query tokens. + */ + TokenInfo(String text, String rawText, String type, int start, int end, int position, boolean match) { + this.text = text; + this.rawText = rawText; + this.type = type; + this.start = start; + this.end = end; + this.position = position; + this.match = match; + } + + /** + * Returns the text of the token. + * + * @return The text of the token. + */ + public String getText() { + return text; + } + + /** + * Returns the raw text of the token. If the token is index in a special format (e.g. date or paddded numbers) + * it will be returned as the raw text. Returns {@code null} if the token is indexed as is. + * + * @return Returns the raw text of the token. + */ + public String getRawText() { + return rawText; + } + + /** + * Returns the type of the token. Typically this will be {@code word} or {@code <ALPHANUM>}, but it really + * depends on the tokenizer and filters that are used. + * + * @return The type of the token. + */ + public String getType() { + return type; + } + + /** + * Returns the start position of this token within the text it was originally extracted from. + * + * @return The start position of this token within the text it was originally extracted from. + */ + public int getStart() { + return start; + } + + /** + * Returns the end position of this token within the text it was originally extracted from. + * + * @return The end position of this token within the text it was originally extracted from. + */ + public int getEnd() { + return end; + } + + /** + * Returns the position of this token within the produced token stream. + * + * @return The position of this token within the produced token stream. + */ + public int getPosition() { + return position; + } + + /** + * Returns whether this token matches one of the query tokens (if query analysis is performed). + * + * @return Whether this token matches one of the query tokens (if query analysis is performed). + */ + public boolean isMatch() { + return match; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/CollectionAdminResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/CollectionAdminResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/CollectionAdminResponse.java new file mode 100644 index 0000000..8acf2e2 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/CollectionAdminResponse.java @@ -0,0 +1,79 @@ +/* + * 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.solr.client.solrj.response; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.solr.common.util.NamedList; + +public class CollectionAdminResponse extends SolrResponseBase +{ + @SuppressWarnings("unchecked") + public NamedList<NamedList<Object>> getCollectionStatus() + { + return (NamedList<NamedList<Object>>) getResponse().get( "success" ); + } + + public boolean isSuccess() + { + return getResponse().get( "success" ) != null; + } + + // this messages are typically from individual nodes, since + // all the failures at the router are propagated as exceptions + @SuppressWarnings("unchecked") + public NamedList<String> getErrorMessages() + { + return (NamedList<String>) getResponse().get( "failure" ); + } + + @SuppressWarnings("unchecked") + public Map<String, NamedList<Integer>> getCollectionCoresStatus() + { + Map<String, NamedList<Integer>> res = new HashMap<>(); + NamedList<NamedList<Object>> cols = getCollectionStatus(); + if( cols != null ) { + for (Map.Entry<String, NamedList<Object>> e : cols) { + NamedList<Object> item = e.getValue(); + String core = (String) item.get("core"); + if (core != null) { + res.put(core, (NamedList<Integer>)item.get("responseHeader")); + } + } + } + + return res; + } + + @SuppressWarnings("unchecked") + public Map<String, NamedList<Integer>> getCollectionNodesStatus() + { + Map<String, NamedList<Integer>> res = new HashMap<>(); + NamedList<NamedList<Object>> cols = getCollectionStatus(); + if( cols != null ) { + for (Map.Entry<String,NamedList<Object>> e : cols) { + if (e.getKey() != null) { + res.put(e.getKey(), (NamedList<Integer>) (e.getValue().get("responseHeader"))); + } + } + } + + return res; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/CoreAdminResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/CoreAdminResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/CoreAdminResponse.java new file mode 100644 index 0000000..0492165 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/CoreAdminResponse.java @@ -0,0 +1,58 @@ +/* + * 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.solr.client.solrj.response; + +import java.util.Date; +import org.apache.solr.common.util.NamedList; + +/** + * + * + * @since solr 1.3 + */ +public class CoreAdminResponse extends SolrResponseBase +{ + @SuppressWarnings("unchecked") + public NamedList<NamedList<Object>> getCoreStatus() + { + return (NamedList<NamedList<Object>>) getResponse().get( "status" ); + } + + public NamedList<Object> getCoreStatus( String core ) + { + return getCoreStatus().get( core ); + } + + public Date getStartTime( String core ) + { + NamedList<Object> v = getCoreStatus( core ); + if( v == null ) { + return null; + } + return (Date) v.get( "startTime" ); + } + + public Long getUptime( String core ) + { + NamedList<Object> v = getCoreStatus( core ); + if( v == null ) { + return null; + } + return (Long) v.get( "uptime" ); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/DocumentAnalysisResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/DocumentAnalysisResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/DocumentAnalysisResponse.java new file mode 100644 index 0000000..2f11d78 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/DocumentAnalysisResponse.java @@ -0,0 +1,258 @@ +/* + * 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.solr.client.solrj.response; + +import org.apache.solr.common.util.NamedList; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * A response that is returned by processing the {@link org.apache.solr.client.solrj.request.DocumentAnalysisRequest}. + * Holds a map of {@link DocumentAnalysis} objects by a document id (unique key). + * + * + * @since solr 1.4 + */ +public class DocumentAnalysisResponse extends AnalysisResponseBase implements Iterable<Map.Entry<String, DocumentAnalysisResponse.DocumentAnalysis>> { + + private final Map<String, DocumentAnalysis> documentAnalysisByKey = new HashMap<>(); + + /** + * {@inheritDoc} + */ + @Override + public void setResponse(NamedList<Object> response) { + super.setResponse(response); + + @SuppressWarnings("unchecked") + NamedList<NamedList<NamedList<Object>>> analysis + = (NamedList<NamedList<NamedList<Object>>>) response.get("analysis"); + for (Map.Entry<String, NamedList<NamedList<Object>>> document : analysis) { + DocumentAnalysis documentAnalysis = new DocumentAnalysis(document.getKey()); + for (Map.Entry<String, NamedList<Object>> fieldEntry : document.getValue()) { + FieldAnalysis fieldAnalysis = new FieldAnalysis(fieldEntry.getKey()); + + NamedList<Object> field = fieldEntry.getValue(); + + @SuppressWarnings("unchecked") + NamedList<List<NamedList<Object>>> query + = (NamedList<List<NamedList<Object>>>) field.get("query"); + if (query != null) { + List<AnalysisPhase> phases = buildPhases(query); + fieldAnalysis.setQueryPhases(phases); + } + + @SuppressWarnings("unchecked") + NamedList<NamedList<List<NamedList<Object>>>> index + = (NamedList<NamedList<List<NamedList<Object>>>>) field.get("index"); + for (Map.Entry<String, NamedList<List<NamedList<Object>>>> valueEntry : index) { + String fieldValue = valueEntry.getKey(); + NamedList<List<NamedList<Object>>> valueNL = valueEntry.getValue(); + List<AnalysisPhase> phases = buildPhases(valueNL); + fieldAnalysis.setIndexPhases(fieldValue, phases); + } + + documentAnalysis.addFieldAnalysis(fieldAnalysis); + } + + documentAnalysisByKey.put(documentAnalysis.getDocumentKey(), documentAnalysis); + } + } + + /** + * Returns the number of document analyses in this response. + * + * @return The number of document analyses in this response. + */ + public int getDocumentAnalysesCount() { + return documentAnalysisByKey.size(); + } + + /** + * Returns the document analysis for the document associated with the given unique key (id), {@code null} if no such + * association exists. + * + * @param documentKey The document unique key. + * + * @return The document analysis for the document associated with the given unique key (id). + */ + public DocumentAnalysis getDocumentAnalysis(String documentKey) { + return documentAnalysisByKey.get(documentKey); + } + + /** + * Returns an iterator over the document analyses map. + * + * @return An iterator over the document analyses map. + */ + @Override + public Iterator<Map.Entry<String, DocumentAnalysis>> iterator() { + return documentAnalysisByKey.entrySet().iterator(); + } + + //================================================= Inner Classes ================================================== + + /** + * An analysis process breakdown of a document. Holds a map of field analyses by the field name. + */ + public static class DocumentAnalysis implements Iterable<Map.Entry<String, FieldAnalysis>> { + + private final String documentKey; + private Map<String, FieldAnalysis> fieldAnalysisByFieldName = new HashMap<>(); + + private DocumentAnalysis(String documentKey) { + this.documentKey = documentKey; + } + + private void addFieldAnalysis(FieldAnalysis fieldAnalysis) { + fieldAnalysisByFieldName.put(fieldAnalysis.getFieldName(), fieldAnalysis); + } + + /** + * Returns the unique key of the analyzed document. + * + * @return The unique key of the analyzed document. + */ + public String getDocumentKey() { + return documentKey; + } + + /** + * Returns the number of field analyses for the documents. + * + * @return The number of field analyses for the documents. + */ + public int getFieldAnalysesCount() { + return fieldAnalysisByFieldName.size(); + } + + public FieldAnalysis getFieldAnalysis(String fieldName) { + return fieldAnalysisByFieldName.get(fieldName); + } + + /** + * Returns an iterator over the field analyses map. + * + * @return An iterator over the field analyses map. + */ + @Override + public Iterator<Map.Entry<String, FieldAnalysis>> iterator() { + return fieldAnalysisByFieldName.entrySet().iterator(); + } + } + + /** + * An analysis process breakdown for a specific field. Holds a list of query time analysis phases (that is, if a + * query analysis was requested in the first place) and a list of index time analysis phases for each field value (a + * field can be multi-valued). + */ + public static class FieldAnalysis { + + private final String fieldName; + private List<AnalysisPhase> queryPhases; + private Map<String, List<AnalysisPhase>> indexPhasesByFieldValue = new HashMap<>(); + + private FieldAnalysis(String fieldName) { + this.fieldName = fieldName; + } + + public void setQueryPhases(List<AnalysisPhase> queryPhases) { + this.queryPhases = queryPhases; + } + + public void setIndexPhases(String fieldValue, List<AnalysisPhase> indexPhases) { + indexPhasesByFieldValue.put(fieldValue, indexPhases); + } + + /** + * Returns the field name. + * + * @return The name of the field. + */ + public String getFieldName() { + return fieldName; + } + + /** + * Returns the number of query time analysis phases or {@code -1} if + * this field analysis doesn't hold a query time analysis. + * + * @return Returns the number of query time analysis phases or {@code -1} + * if this field analysis doesn't hold a query time analysis. + */ + public int getQueryPhasesCount() { + return queryPhases == null ? -1 : queryPhases.size(); + } + + /** + * Returns the query time analysis phases for the field or {@code null} + * if this field doesn't hold a query time analysis. + * + * @return Returns the query time analysis phases for the field or + * {@code null} if this field doesn't hold a query time analysis. + */ + public Iterable<AnalysisPhase> getQueryPhases() { + return queryPhases; + } + + /** + * Returns the number of values the field has. + * + * @return The number of values the field has. + */ + public int getValueCount() { + return indexPhasesByFieldValue.entrySet().size(); + } + + /** + * Returns the number of index time analysis phases the given field value has. + * + * @param fieldValue The field value. + * + * @return The number of index time analysis phases the given field value has. + */ + public int getIndexPhasesCount(String fieldValue) { + return indexPhasesByFieldValue.get(fieldValue).size(); + } + + /** + * Returns the index time analysis phases for the given field value. + * + * @param fieldValue The field value. + * + * @return The index time analysis phases for the given field value. + */ + public Iterable<AnalysisPhase> getIndexPhases(String fieldValue) { + return indexPhasesByFieldValue.get(fieldValue); + } + + /** + * Returns the index time analysis phases for all field values. + * + * @return Returns the index time analysis phases for all field value. + */ + public Iterable<Map.Entry<String, List<AnalysisPhase>>> getIndexPhasesByFieldValue() { + return indexPhasesByFieldValue.entrySet(); + } + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FacetField.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FacetField.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FacetField.java new file mode 100644 index 0000000..086c999 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FacetField.java @@ -0,0 +1,176 @@ +/* + * 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.solr.client.solrj.response; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import org.apache.solr.client.solrj.util.ClientUtils; + + /** + * A utility class to hold the facet response. It could use the NamedList container, + * but for JSTL, it is nice to have something that implements List so it can be iterated + * + * @since solr 1.3 + */ + public class FacetField implements Serializable + { + public static class Count implements Serializable + { + private String _name = null; + private long _count = 0; + // hang onto the FacetField for breadcrumb creation convenience + private FacetField _ff = null; + + public Count( FacetField ff, String n, long c ) + { + _name = n; + _count = c; + _ff = ff; + } + + public String getName() { + return _name; + } + + public void setName( String n ) + { + _name = n; + } + + public long getCount() { + return _count; + } + + public void setCount( long c ) + { + _count = c; + } + + public FacetField getFacetField() { + return _ff; + } + + @Override + public String toString() + { + return _name+" ("+_count+")"; + } + + public String getAsFilterQuery() { + if (_ff.getName().equals("facet_queries")) { + return _name; + } + return + ClientUtils.escapeQueryChars( _ff._name ) + ":" + + ClientUtils.escapeQueryChars( _name ); + } + } + + private String _name = null; + private List<Count> _values = null; + private String _gap = null; + private Date _end = null; + + public FacetField( final String n ) + { + _name = n; + } + + public FacetField(String name, String gap, Date end) { + _name = name; + _gap = gap; + _end = end; + } + + /** + * Date Gap Facet parameter + * + * @return the value specified for facet.date.gap + */ + public String getGap() { + return _gap; + } + + /** + * Date End Facet parameter + * + * @return the value specified for facet.date.end + */ + public Date getEnd() { + return _end; + } + + /** + * Insert at the end of the list + */ + public void add( String name, long cnt ) + { + if( _values == null ) { + _values = new ArrayList<>( 30 ); + } + _values.add( new Count( this, name, cnt ) ); + } + + /** + * Insert at the beginning of the list. + */ + public void insert( String name, long cnt ) + { + if( _values == null ) { + _values = new ArrayList<>( 30 ); + } + _values.add( 0, new Count( this, name, cnt ) ); + } + + public String getName() { + return _name; + } + + public List<Count> getValues() { + return _values == null ? Collections.<Count>emptyList() : _values; + } + + public int getValueCount() + { + return _values == null ? 0 : _values.size(); + } + + public FacetField getLimitingFields(long max) + { + FacetField ff = new FacetField( _name ); + if( _values != null ) { + ff._values = new ArrayList<>( _values.size() ); + for( Count c : _values ) { + if( c._count < max ) { // !equal to + ff._values.add( c ); + } + } + } + return ff; + } + + @Override + public String toString() + { + return _name + ":" + _values; + } + }
