This commit is contained in:
Cao Manh Dat 2017-08-21 15:30:29 +07:00
commit 9d8d3b0f29
54 changed files with 868 additions and 239 deletions

View File

@ -861,7 +861,7 @@ def testSolrExample(unpackPath, javaPath, isSrc):
if s.find('"numFound":3,"start":0') == -1: if s.find('"numFound":3,"start":0') == -1:
print('FAILED: response is:\n%s' % s) print('FAILED: response is:\n%s' % s)
raise RuntimeError('query on solr example instance failed') raise RuntimeError('query on solr example instance failed')
s = load('http://localhost:8983/v2/cores') s = load('http://localhost:8983/api/cores')
if s.find('"status":0,') == -1: if s.find('"status":0,') == -1:
print('FAILED: response is:\n%s' % s) print('FAILED: response is:\n%s' % s)
raise RuntimeError('query api v2 on solr example instance failed') raise RuntimeError('query api v2 on solr example instance failed')

View File

@ -136,7 +136,7 @@ org.apache.directory.server.version = 2.0.0-M15
/org.apache.directory.server/apacheds-protocol-shared = ${org.apache.directory.server.version} /org.apache.directory.server/apacheds-protocol-shared = ${org.apache.directory.server.version}
/org.apache.directory.server/apacheds-xdbm-partition = ${org.apache.directory.server.version} /org.apache.directory.server/apacheds-xdbm-partition = ${org.apache.directory.server.version}
org.apache.hadoop.version = 2.7.2 org.apache.hadoop.version = 2.7.4
/org.apache.hadoop/hadoop-annotations = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-annotations = ${org.apache.hadoop.version}
/org.apache.hadoop/hadoop-auth = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-auth = ${org.apache.hadoop.version}
/org.apache.hadoop/hadoop-common = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-common = ${org.apache.hadoop.version}
@ -252,6 +252,7 @@ org.gagravarr.vorbis.java.version = 0.8
org.mortbay.jetty.version = 6.1.26 org.mortbay.jetty.version = 6.1.26
/org.mortbay.jetty/jetty = ${org.mortbay.jetty.version} /org.mortbay.jetty/jetty = ${org.mortbay.jetty.version}
/org.mortbay.jetty/jetty-sslengine = ${org.mortbay.jetty.version}
/org.mortbay.jetty/jetty-util = ${org.mortbay.jetty.version} /org.mortbay.jetty/jetty-util = ${org.mortbay.jetty.version}
/org.noggit/noggit = 0.8 /org.noggit/noggit = 0.8

View File

@ -134,12 +134,12 @@ class Geo3DUtil {
final GeoPolygon component = fromPolygon(polygons[0]); final GeoPolygon component = fromPolygon(polygons[0]);
if (component == null) { if (component == null) {
// Polygon is degenerate // Polygon is degenerate
shape = new GeoCompositePolygon(); shape = new GeoCompositePolygon(PlanetModel.WGS84);
} else { } else {
shape = component; shape = component;
} }
} else { } else {
final GeoCompositePolygon poly = new GeoCompositePolygon(); final GeoCompositePolygon poly = new GeoCompositePolygon(PlanetModel.WGS84);
for (final Polygon p : polygons) { for (final Polygon p : polygons) {
final GeoPolygon component = fromPolygon(p); final GeoPolygon component = fromPolygon(p);
if (component != null) { if (component != null) {

View File

@ -22,7 +22,7 @@ package org.apache.lucene.spatial3d.geom;
* *
* @lucene.internal * @lucene.internal
*/ */
public abstract class BasePlanetObject { public abstract class BasePlanetObject implements PlanetObject {
/** This is the planet model embedded in all objects derived from this /** This is the planet model embedded in all objects derived from this
* class. */ * class. */
@ -35,7 +35,7 @@ public abstract class BasePlanetObject {
this.planetModel = planetModel; this.planetModel = planetModel;
} }
/** Returns the {@link PlanetModel} provided when this shape was created. */ @Override
public PlanetModel getPlanetModel() { public PlanetModel getPlanetModel() {
return planetModel; return planetModel;
} }

View File

@ -94,6 +94,9 @@ abstract class GeoBaseAreaShape extends GeoBaseMembershipShape implements GeoAre
@Override @Override
public int getRelationship(GeoShape geoShape) { public int getRelationship(GeoShape geoShape) {
if (!geoShape.getPlanetModel().equals(planetModel)) {
throw new IllegalArgumentException("Cannot relate shapes with different planet models.");
}
final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape); final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape);
if (insideGeoAreaShape == SOME_INSIDE) { if (insideGeoAreaShape == SOME_INSIDE) {
return GeoArea.OVERLAPS; return GeoArea.OVERLAPS;

View File

@ -35,7 +35,8 @@ abstract class GeoBaseCompositeAreaShape<T extends GeoAreaShape> extends GeoBase
/** /**
* Constructor. * Constructor.
*/ */
public GeoBaseCompositeAreaShape() { public GeoBaseCompositeAreaShape(PlanetModel planetModel) {
super(planetModel);
} }
@Override @Override
@ -50,6 +51,9 @@ abstract class GeoBaseCompositeAreaShape<T extends GeoAreaShape> extends GeoBase
@Override @Override
public int getRelationship(GeoShape geoShape) { public int getRelationship(GeoShape geoShape) {
if (!geoShape.getPlanetModel().equals(planetModel)) {
throw new IllegalArgumentException("Cannot relate shapes with different planet models.");
}
final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape); final int insideGeoAreaShape = isShapeInsideGeoAreaShape(geoShape);
if (insideGeoAreaShape == SOME_INSIDE) { if (insideGeoAreaShape == SOME_INSIDE) {
return GeoArea.OVERLAPS; return GeoArea.OVERLAPS;

View File

@ -29,7 +29,8 @@ abstract class GeoBaseCompositeMembershipShape<T extends GeoMembershipShape>
/** /**
* Constructor. * Constructor.
*/ */
GeoBaseCompositeMembershipShape() { GeoBaseCompositeMembershipShape(PlanetModel planetModel) {
super(planetModel);
} }
@Override @Override

View File

@ -27,7 +27,7 @@ import java.util.List;
* @param <T> is the type of GeoShapes of the composite. * @param <T> is the type of GeoShapes of the composite.
* @lucene.experimental * @lucene.experimental
*/ */
public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoShape { public abstract class GeoBaseCompositeShape<T extends GeoShape> extends BasePlanetObject implements GeoShape {
/** /**
* Shape's container * Shape's container
@ -37,7 +37,8 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoSh
/** /**
* Constructor. * Constructor.
*/ */
public GeoBaseCompositeShape() { public GeoBaseCompositeShape(PlanetModel planetModel) {
super(planetModel);
} }
/** /**
@ -46,6 +47,9 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoSh
* @param shape is the shape to add. * @param shape is the shape to add.
*/ */
public void addShape(final T shape) { public void addShape(final T shape) {
if (!shape.getPlanetModel().equals(planetModel)) {
throw new IllegalArgumentException("Cannot add a shape into a composite with different planet models.");
}
shapes.add(shape); shapes.add(shape);
} }
@ -108,7 +112,7 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoSh
@Override @Override
public int hashCode() { public int hashCode() {
return shapes.hashCode(); return super.hashCode() + shapes.hashCode();
} }
@Override @Override
@ -116,6 +120,6 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> implements GeoSh
if (!(o instanceof GeoBaseCompositeShape<?>)) if (!(o instanceof GeoBaseCompositeShape<?>))
return false; return false;
GeoBaseCompositeShape<?> other = (GeoBaseCompositeShape<?>) o; GeoBaseCompositeShape<?> other = (GeoBaseCompositeShape<?>) o;
return shapes.equals(other.shapes); return super.equals(other) && shapes.equals(other.shapes);
} }
} }

View File

@ -27,7 +27,15 @@ public class GeoCompositeAreaShape extends GeoBaseCompositeAreaShape<GeoAreaShap
/** /**
* Constructor. * Constructor.
*/ */
public GeoCompositeAreaShape() { public GeoCompositeAreaShape(PlanetModel planetModel) {
super(planetModel);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof GeoCompositeAreaShape))
return false;
return super.equals(o);
} }
@Override @Override

View File

@ -26,7 +26,15 @@ public class GeoCompositeMembershipShape extends GeoBaseCompositeMembershipShape
/** /**
* Constructor. * Constructor.
*/ */
public GeoCompositeMembershipShape() { public GeoCompositeMembershipShape(PlanetModel planetModel) {
super(planetModel);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof GeoCompositeMembershipShape))
return false;
return super.equals(o);
} }
@Override @Override

View File

@ -25,7 +25,15 @@ public class GeoCompositePolygon extends GeoBaseCompositeAreaShape<GeoPolygon> i
/** /**
* Constructor. * Constructor.
*/ */
public GeoCompositePolygon() { public GeoCompositePolygon(PlanetModel planetModel) {
super(planetModel);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof GeoCompositePolygon))
return false;
return super.equals(o);
} }
@Override @Override

View File

@ -39,6 +39,11 @@ class GeoDegeneratePoint extends GeoPoint implements GeoBBox, GeoCircle {
this.edgePoints = new GeoPoint[]{this}; this.edgePoints = new GeoPoint[]{this};
} }
@Override
public PlanetModel getPlanetModel() {
return planetModel;
}
@Override @Override
public GeoBBox expand(final double angle) { public GeoBBox expand(final double angle) {
final double newTopLat = latitude + angle; final double newTopLat = latitude + angle;

View File

@ -336,19 +336,19 @@ public class GeoPolygonFactory {
final SidedPlane initialPlane = new SidedPlane(testPoint, filteredPointList.get(0), filteredPointList.get(1)); final SidedPlane initialPlane = new SidedPlane(testPoint, filteredPointList.get(0), filteredPointList.get(1));
// We don't know if this is the correct siding choice. We will only know as we build the complex polygon. // We don't know if this is the correct siding choice. We will only know as we build the complex polygon.
// So we need to be prepared to try both possibilities. // So we need to be prepared to try both possibilities.
GeoCompositePolygon rval = new GeoCompositePolygon(); GeoCompositePolygon rval = new GeoCompositePolygon(planetModel);
MutableBoolean seenConcave = new MutableBoolean(); MutableBoolean seenConcave = new MutableBoolean();
if (buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, testPoint) == false) { if (buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, testPoint) == false) {
// The testPoint was within the shape. Was that intended? // The testPoint was within the shape. Was that intended?
if (testPointInside) { if (testPointInside) {
// Yes: build it for real // Yes: build it for real
rval = new GeoCompositePolygon(); rval = new GeoCompositePolygon(planetModel);
seenConcave = new MutableBoolean(); seenConcave = new MutableBoolean();
buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, null); buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, null);
return rval; return rval;
} }
// No: do the complement and return that. // No: do the complement and return that.
rval = new GeoCompositePolygon(); rval = new GeoCompositePolygon(planetModel);
seenConcave = new MutableBoolean(); seenConcave = new MutableBoolean();
buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null); buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null);
return rval; return rval;
@ -359,7 +359,7 @@ public class GeoPolygonFactory {
return rval; return rval;
} }
// No: return the complement // No: return the complement
rval = new GeoCompositePolygon(); rval = new GeoCompositePolygon(planetModel);
seenConcave = new MutableBoolean(); seenConcave = new MutableBoolean();
buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null); buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null);
return rval; return rval;

View File

@ -23,7 +23,7 @@ package org.apache.lucene.spatial3d.geom;
* *
* @lucene.experimental * @lucene.experimental
*/ */
public interface GeoShape extends Membership { public interface GeoShape extends Membership, PlanetObject {
/** /**
* Return a sample point that is on the outside edge/boundary of the shape. * Return a sample point that is on the outside edge/boundary of the shape.

View File

@ -0,0 +1,29 @@
/*
* 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.lucene.spatial3d.geom;
/**
* Relates all Geo3d shape with a specific {@link PlanetModel}.
*
* @lucene.experimental
*/
public interface PlanetObject {
/** Returns the {@link PlanetModel} provided when this shape was created. */
PlanetModel getPlanetModel();
}

View File

@ -21,6 +21,6 @@ package org.apache.lucene.spatial3d.geom;
* *
* @lucene.internal * @lucene.internal
*/ */
public interface XYZSolid extends GeoArea { public interface XYZSolid extends GeoArea, PlanetObject {
} }

View File

@ -833,7 +833,7 @@ public class CompositeGeoPolygonRelationshipsTest {
points2.add(point8); points2.add(point8);
GeoPolygon p1 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points1); GeoPolygon p1 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points1);
GeoPolygon p2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2); GeoPolygon p2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2);
GeoCompositeMembershipShape compositeMembershipShape = new GeoCompositeMembershipShape(); GeoCompositeMembershipShape compositeMembershipShape = new GeoCompositeMembershipShape(PlanetModel.SPHERE);
compositeMembershipShape.addShape(p1); compositeMembershipShape.addShape(p1);
compositeMembershipShape.addShape(p2); compositeMembershipShape.addShape(p2);
return compositeMembershipShape; return compositeMembershipShape;

View File

@ -134,12 +134,12 @@ class Geo3DUtil {
final GeoPolygon component = fromPolygon(polygons[0]); final GeoPolygon component = fromPolygon(polygons[0]);
if (component == null) { if (component == null) {
// Polygon is degenerate // Polygon is degenerate
shape = new GeoCompositePolygon(); shape = new GeoCompositePolygon(PlanetModel.WGS84);
} else { } else {
shape = component; shape = component;
} }
} else { } else {
final GeoCompositePolygon poly = new GeoCompositePolygon(); final GeoCompositePolygon poly = new GeoCompositePolygon(PlanetModel.WGS84);
for (final Polygon p : polygons) { for (final Polygon p : polygons) {
final GeoPolygon component = fromPolygon(p); final GeoPolygon component = fromPolygon(p);
if (component != null) { if (component != null) {

View File

@ -441,7 +441,7 @@ public class GeoPolygonTest {
PlanetModel pm = new PlanetModel(0.7563871189161702, 1.2436128810838298); PlanetModel pm = new PlanetModel(0.7563871189161702, 1.2436128810838298);
// Build the polygon // Build the polygon
GeoCompositeMembershipShape c = new GeoCompositeMembershipShape(); GeoCompositeMembershipShape c = new GeoCompositeMembershipShape(pm);
List<GeoPoint> points1 = new ArrayList<>(); List<GeoPoint> points1 = new ArrayList<>();
points1.add(new GeoPoint(pm, 0.014071770744627236, 0.011030818292803128)); points1.add(new GeoPoint(pm, 0.014071770744627236, 0.011030818292803128));
points1.add(new GeoPoint(pm, 0.006772117088906782, -0.0012531892445234592)); points1.add(new GeoPoint(pm, 0.006772117088906782, -0.0012531892445234592));
@ -500,7 +500,7 @@ shape:
*/ */
PlanetModel pm = new PlanetModel(0.8568069516722363, 1.1431930483277637); PlanetModel pm = new PlanetModel(0.8568069516722363, 1.1431930483277637);
// Build the polygon // Build the polygon
GeoCompositeMembershipShape c = new GeoCompositeMembershipShape(); GeoCompositeMembershipShape c = new GeoCompositeMembershipShape(pm);
List<GeoPoint> points1 = new ArrayList<>(); List<GeoPoint> points1 = new ArrayList<>();
points1.add(new GeoPoint(pm, 1.1577814487635816, 1.6283601832010004)); points1.add(new GeoPoint(pm, 1.1577814487635816, 1.6283601832010004));
points1.add(new GeoPoint(pm, 0.6664570999069251, 2.0855825542851574)); points1.add(new GeoPoint(pm, 0.6664570999069251, 2.0855825542851574));
@ -626,7 +626,7 @@ shape:
points.add(p1); points.add(p1);
final BitSet internal = new BitSet(); final BitSet internal = new BitSet();
final GeoCompositePolygon rval = new GeoCompositePolygon(); final GeoCompositePolygon rval = new GeoCompositePolygon(PlanetModel.WGS84);
final GeoPolygonFactory.MutableBoolean mutableBoolean = new GeoPolygonFactory.MutableBoolean(); final GeoPolygonFactory.MutableBoolean mutableBoolean = new GeoPolygonFactory.MutableBoolean();
boolean result = GeoPolygonFactory.buildPolygonShape(rval, mutableBoolean, PlanetModel.WGS84, points, internal, 0, 1, boolean result = GeoPolygonFactory.buildPolygonShape(rval, mutableBoolean, PlanetModel.WGS84, points, internal, 0, 1,

View File

@ -380,7 +380,7 @@ public class RandomGeoShapeGenerator extends LuceneTestCase {
while (iterations < MAX_SHAPE_ITERATIONS) { while (iterations < MAX_SHAPE_ITERATIONS) {
iterations++; iterations++;
int numberShapes = random().nextInt(3) + 2; int numberShapes = random().nextInt(3) + 2;
GeoCompositeAreaShape collection = new GeoCompositeAreaShape(); GeoCompositeAreaShape collection = new GeoCompositeAreaShape(planetModel);
for(int i=0; i<numberShapes;i++){ for(int i=0; i<numberShapes;i++){
GeoPolygon member = convexPolygon(planetModel, constraints); GeoPolygon member = convexPolygon(planetModel, constraints);
if (member != null){ if (member != null){

View File

@ -829,7 +829,7 @@ public class SimpleGeoPolygonRelationshipsTest {
points2.add(point7); points2.add(point7);
points2.add(point8); points2.add(point8);
GeoPolygon pol2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2); GeoPolygon pol2 = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points2);
GeoCompositeMembershipShape composite = new GeoCompositeMembershipShape(); GeoCompositeMembershipShape composite = new GeoCompositeMembershipShape(PlanetModel.SPHERE);
composite.addShape(pol1); composite.addShape(pol1);
composite.addShape(pol2); composite.addShape(pol2);
return composite; return composite;

View File

@ -884,6 +884,8 @@ public class AssertingLeafReader extends FilterLeafReader {
assertStats(maxDoc); assertStats(maxDoc);
} }
public PointValues getWrapped() { return in; }
private void assertStats(int maxDoc) { private void assertStats(int maxDoc) {
assert in.size() > 0; assert in.size() > 0;
assert in.getDocCount() > 0; assert in.getDocCount() > 0;

View File

@ -95,9 +95,6 @@ Bug Fixes
* SOLR-11190: GraphQuery also supports string fields which are indexed=false and docValues=true. Please refer to the * SOLR-11190: GraphQuery also supports string fields which are indexed=false and docValues=true. Please refer to the
Javadocs for DocValuesTermsQuery for it's performance characteristics. (Karthik Ramachandran, Varun Thacker) Javadocs for DocValuesTermsQuery for it's performance characteristics. (Karthik Ramachandran, Varun Thacker)
* SOLR-11228: Exclude static html files in the partials directory from authentication and authorization checks. The UI
will open correctly with kerberos enabled (Ishan Chattopadhyaya, Varun Thacker)
* SOLR-11084: Issue with starting script with solr.home (-s) == solr (Leil Ireson, Amrit Sarkar via Erick Erickson) * SOLR-11084: Issue with starting script with solr.home (-s) == solr (Leil Ireson, Amrit Sarkar via Erick Erickson)
Optimizations Optimizations
@ -296,6 +293,9 @@ Upgrading from Solr 6.x
* SOLR-11239: The use of maxShardsPerNode is not supported when a cluster policy is in effect or * SOLR-11239: The use of maxShardsPerNode is not supported when a cluster policy is in effect or
when a collection specific policy is specified during collection creation. when a collection specific policy is specified during collection creation.
* V2 APIs are now available at /api, in addition to /v2 (which is now deprecated). Legacy APIs continue to remain
available at /solr.
New Features New Features
---------------------- ----------------------
* SOLR-9857, SOLR-9858: Collect aggregated metrics from nodes and shard leaders in overseer. (ab) * SOLR-9857, SOLR-9858: Collect aggregated metrics from nodes and shard leaders in overseer. (ab)
@ -375,6 +375,8 @@ New Features
* SOLR-10939: Add support for PointsFields to {!join} query. Joined fields should * SOLR-10939: Add support for PointsFields to {!join} query. Joined fields should
also have docValues enabled. (yonik) also have docValues enabled. (yonik)
* SOLR-11173 TermsComponent support for Points fields. (yonik)
Bug Fixes Bug Fixes
---------------------- ----------------------
* SOLR-9262: Connection and read timeouts are being ignored by UpdateShardHandler after SOLR-4509. * SOLR-9262: Connection and read timeouts are being ignored by UpdateShardHandler after SOLR-4509.
@ -469,6 +471,8 @@ Bug Fixes
* SOLR-11243: Replica Placement rules are ignored if a cluster policy exists. (shalin) * SOLR-11243: Replica Placement rules are ignored if a cluster policy exists. (shalin)
* SOLR-11268: AtomicUpdateProcessor complains missing UpdateLog (noble, Ishan Chattopadhyaya)
Optimizations Optimizations
---------------------- ----------------------
@ -678,6 +682,8 @@ Other Changes
collection specific policy is specified during collection creation. collection specific policy is specified during collection creation.
(Noble Paul, shalin) (Noble Paul, shalin)
* SOLR-11183: V2 APIs are now available at /api endpoint. (Ishan Chattopadhyaya)
================== 6.7.0 ================== ================== 6.7.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
@ -863,7 +869,7 @@ Other Changes
with point fields and provides control over dynamic fields used for the raw amount and currency with point fields and provides control over dynamic fields used for the raw amount and currency
code sub-fields. (hossman, Steve Rowe) code sub-fields. (hossman, Steve Rowe)
* SOLR-10966: Add workaround for Hadoop-Common 2.7.2 incompatibility with Java 9. * SOLR-11261, SOLR-10966: Upgrade to Hadoop 2.7.4 to fix incompatibility with Java 9.
(Uwe Schindler) (Uwe Schindler)
================== 6.6.1 ================== ================== 6.6.1 ==================
@ -891,6 +897,15 @@ Bug Fixes
* SOLR-11069: CDCR bootstrapping can get into an infinite loop when a core is reloaded (Amrit Sarkar, Erick Erickson) * SOLR-11069: CDCR bootstrapping can get into an infinite loop when a core is reloaded (Amrit Sarkar, Erick Erickson)
* SOLR-11221: SolrJmxReporter broken on core reload. This resulted in some or most metrics not being reported
via JMX after core reloads, depending on timing. (ab)
* SOLR-11261, SOLR-10966: Upgrade to Hadoop 2.7.4 to fix incompatibility with Java 9.
(Uwe Schindler)
* SOLR-11228: Exclude static html files in the partials directory from authentication and authorization checks. The UI
will open correctly with kerberos enabled (Ishan Chattopadhyaya, Varun Thacker)
================== 6.6.0 ================== ================== 6.6.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

View File

@ -87,6 +87,7 @@
<dependency org="org.mortbay.jetty" name="jetty" rev="${/org.mortbay.jetty/jetty}" conf="test.DfsMiniCluster"/> <dependency org="org.mortbay.jetty" name="jetty" rev="${/org.mortbay.jetty/jetty}" conf="test.DfsMiniCluster"/>
<dependency org="org.codehaus.janino" name="commons-compiler" rev="${/org.codehaus.janino/commons-compiler}" conf="compile"/> <dependency org="org.codehaus.janino" name="commons-compiler" rev="${/org.codehaus.janino/commons-compiler}" conf="compile"/>
<dependency org="org.mortbay.jetty" name="jetty-util" rev="${/org.mortbay.jetty/jetty-util}" conf="test.DfsMiniCluster"/> <dependency org="org.mortbay.jetty" name="jetty-util" rev="${/org.mortbay.jetty/jetty-util}" conf="test.DfsMiniCluster"/>
<dependency org="org.mortbay.jetty" name="jetty-sslengine" rev="${/org.mortbay.jetty/jetty-sslengine}" conf="test.DfsMiniCluster"/>
<dependency org="com.sun.jersey" name="jersey-core" rev="${/com.sun.jersey/jersey-core}" conf="test.DfsMiniCluster"/> <dependency org="com.sun.jersey" name="jersey-core" rev="${/com.sun.jersey/jersey-core}" conf="test.DfsMiniCluster"/>
<dependency org="com.sun.jersey" name="jersey-server" rev="${/com.sun.jersey/jersey-server}" conf="test.DfsMiniCluster"/> <dependency org="com.sun.jersey" name="jersey-server" rev="${/com.sun.jersey/jersey-server}" conf="test.DfsMiniCluster"/>
<dependency org="commons-collections" name="commons-collections" rev="${/commons-collections/commons-collections}" conf="test.DfsMiniCluster"/> <dependency org="commons-collections" name="commons-collections" rev="${/commons-collections/commons-collections}" conf="test.DfsMiniCluster"/>

View File

@ -30,10 +30,12 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext; import org.apache.lucene.index.TermContext;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder; import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.CharsRefBuilder; import org.apache.lucene.util.CharsRefBuilder;
import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.StringHelper;
import org.apache.lucene.util.mutable.MutableValue;
import org.apache.solr.client.solrj.response.TermsResponse; import org.apache.solr.client.solrj.response.TermsResponse;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ModifiableSolrParams;
@ -45,7 +47,9 @@ import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.StrUtils; import org.apache.solr.common.util.StrUtils;
import org.apache.solr.request.SimpleFacets.CountPair; import org.apache.solr.request.SimpleFacets.CountPair;
import org.apache.solr.schema.FieldType; import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.StrField; import org.apache.solr.schema.StrField;
import org.apache.solr.search.PointMerger;
import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.BoundedTreeSet; import org.apache.solr.util.BoundedTreeSet;
@ -108,16 +112,6 @@ public class TermsComponent extends SearchComponent {
rb.rsp.add("terms", termsResult); rb.rsp.add("terms", termsResult);
if (fields == null || fields.length==0) return; if (fields == null || fields.length==0) return;
for (String field : fields) {
FieldType fieldType = rb.req.getSchema().getFieldTypeNoEx(field);
if (null != fieldType) {
if (fieldType.isPointField()) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"The terms component does not support Points-based field " + field);
}
}
}
boolean termStats = params.getBool(TermsParams.TERMS_STATS, false); boolean termStats = params.getBool(TermsParams.TERMS_STATS, false);
@ -134,10 +128,8 @@ public class TermsComponent extends SearchComponent {
return; return;
} }
int limit = params.getInt(TermsParams.TERMS_LIMIT, 10); int _limit = params.getInt(TermsParams.TERMS_LIMIT, 10);
if (limit < 0) { final int limit = _limit < 0 ? Integer.MAX_VALUE : _limit;
limit = Integer.MAX_VALUE;
}
String lowerStr = params.get(TermsParams.TERMS_LOWER); String lowerStr = params.get(TermsParams.TERMS_LOWER);
String upperStr = params.get(TermsParams.TERMS_UPPER); String upperStr = params.get(TermsParams.TERMS_UPPER);
@ -146,10 +138,9 @@ public class TermsComponent extends SearchComponent {
boolean sort = !TermsParams.TERMS_SORT_INDEX.equals( boolean sort = !TermsParams.TERMS_SORT_INDEX.equals(
params.get(TermsParams.TERMS_SORT, TermsParams.TERMS_SORT_COUNT)); params.get(TermsParams.TERMS_SORT, TermsParams.TERMS_SORT_COUNT));
int freqmin = params.getInt(TermsParams.TERMS_MINCOUNT, 1); int freqmin = params.getInt(TermsParams.TERMS_MINCOUNT, 1);
int freqmax = params.getInt(TermsParams.TERMS_MAXCOUNT, UNLIMITED_MAX_COUNT); int _freqmax = params.getInt(TermsParams.TERMS_MAXCOUNT, UNLIMITED_MAX_COUNT);
if (freqmax<0) { final int freqmax = _freqmax < 0 ? Integer.MAX_VALUE : _freqmax;
freqmax = Integer.MAX_VALUE;
}
String prefix = params.get(TermsParams.TERMS_PREFIX_STR); String prefix = params.get(TermsParams.TERMS_PREFIX_STR);
String regexp = params.get(TermsParams.TERMS_REGEXP_STR); String regexp = params.get(TermsParams.TERMS_REGEXP_STR);
Pattern pattern = regexp != null ? Pattern.compile(regexp, resolveRegexpFlags(params)) : null; Pattern pattern = regexp != null ? Pattern.compile(regexp, resolveRegexpFlags(params)) : null;
@ -161,13 +152,76 @@ public class TermsComponent extends SearchComponent {
for (String field : fields) { for (String field : fields) {
NamedList<Integer> fieldTerms = new NamedList<>(); NamedList<Integer> fieldTerms = new NamedList<>();
termsResult.add(field, fieldTerms);
Terms terms = indexReader.terms(field); Terms terms = indexReader.terms(field);
if (terms == null) { if (terms == null) {
// field does not exist // field does not exist in terms index. Check points.
SchemaField sf = rb.req.getSchema().getFieldOrNull(field);
if (sf != null && sf.getType().isPointField()) {
if (lowerStr!=null || upperStr!=null || prefix!=null || regexp!=null) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
String.format(Locale.ROOT, "The terms component does not support Points-based fields with sorting or with parameters %s,%s,%s,%s ", TermsParams.TERMS_LOWER, TermsParams.TERMS_UPPER, TermsParams.TERMS_PREFIX_STR, TermsParams.TERMS_REGEXP_STR));
}
if (sort) {
PointMerger.ValueIterator valueIterator = new PointMerger.ValueIterator(sf, rb.req.getSearcher().getRawReader().leaves());
MutableValue mv = valueIterator.getMutableValue();
BoundedTreeSet<CountPair<MutableValue, Integer>> queue = (sort ? new BoundedTreeSet<>(limit) : null);
for (; ; ) {
long count = valueIterator.getNextCount();
if (count < 0) break;
if (count < freqmin || count > freqmax) continue;
if (queue.size() < limit || queue.last().val < count || (queue.last().val == count && queue.last().key.compareTo(mv) < 0)) {
queue.add(new CountPair<>(mv.duplicate(), (int) count));
}
}
for (CountPair<MutableValue, Integer> item : queue) {
fieldTerms.add(item.key.toString(), item.val);
}
termsResult.add(field, fieldTerms);
continue;
}
if (!sort) {
/***
// streaming solution that is deferred until writing the response
// TODO: we can't use the streaming solution until XML writer supports PushWriter!
termsResult.add(field, (MapWriter) ew -> {
PointMerger.ValueIterator valueIterator = new PointMerger.ValueIterator(sf, rb.req.getSearcher().getRawReader().leaves());
MutableValue mv = valueIterator.getMutableValue();
int num = 0;
for(;;) {
long count = valueIterator.getNextCount();
if (count < 0) break;
if (count < freqmin || count > freqmax) continue;
if (++num > limit) break;
ew.put(mv.toString(), (int)count); // match the numeric type of terms
}
});
***/
PointMerger.ValueIterator valueIterator = new PointMerger.ValueIterator(sf, rb.req.getSearcher().getRawReader().leaves());
MutableValue mv = valueIterator.getMutableValue();
int num = 0;
for(;;) {
long count = valueIterator.getNextCount();
if (count < 0) break;
if (count < freqmin || count > freqmax) continue;
if (++num > limit) break;
fieldTerms.add(mv.toString(), (int)count); // match the numeric type of terms
}
termsResult.add(field, fieldTerms);
continue;
}
}
termsResult.add(field, fieldTerms); // add empty
continue; continue;
} }
termsResult.add(field, fieldTerms);
FieldType ft = raw ? null : rb.req.getSchema().getFieldTypeNoEx(field); FieldType ft = raw ? null : rb.req.getSchema().getFieldTypeNoEx(field);
if (ft==null) ft = new StrField(); if (ft==null) ft = new StrField();
@ -545,7 +599,19 @@ public class TermsComponent extends SearchComponent {
IndexReaderContext topReaderContext = indexSearcher.getTopReaderContext(); IndexReaderContext topReaderContext = indexSearcher.getTopReaderContext();
for (String field : fields) { for (String field : fields) {
FieldType fieldType = indexSearcher.getSchema().getField(field).getType(); SchemaField sf = indexSearcher.getSchema().getField(field);
FieldType fieldType = sf.getType();
if (fieldType.isPointField()) {
NamedList<Object> termsMap = new SimpleOrderedMap<>();
for (String term : splitTerms) {
Query q = fieldType.getFieldQuery(null, sf, term);
int count = indexSearcher.getDocSet(q).size();
termsMap.add(term, count);
}
result.add(field, termsMap);
continue;
}
// Since splitTerms is already sorted, this array will also be sorted // Since splitTerms is already sorted, this array will also be sorted
Term[] terms = new Term[splitTerms.length]; Term[] terms = new Term[splitTerms.length];

View File

@ -0,0 +1,454 @@
/*
* 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.search;
import java.io.IOException;
import java.util.List;
import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PointValues;
import org.apache.lucene.util.PriorityQueue;
import org.apache.lucene.util.mutable.MutableValue;
import org.apache.lucene.util.mutable.MutableValueDate;
import org.apache.lucene.util.mutable.MutableValueDouble;
import org.apache.lucene.util.mutable.MutableValueFloat;
import org.apache.lucene.util.mutable.MutableValueInt;
import org.apache.lucene.util.mutable.MutableValueLong;
import org.apache.solr.schema.SchemaField;
/**
* Merge multiple numeric point fields (segments) together.
*
* @lucene.internal
* @lucene.experimental
*/
public class PointMerger {
public static int TOTAL_BUFFER_SIZE = 1000000; // target number of elements to cache across all segments
public static int MIN_SEG_BUFFER_SIZE = 100; // minimum buffer size on any segment (to limit unnecessary exception throws)
public static class ValueIterator {
PQueue queue;
MutableValue topVal;
public ValueIterator(SchemaField field, List<LeafReaderContext> readers) throws IOException {
this(field, readers, TOTAL_BUFFER_SIZE, MIN_SEG_BUFFER_SIZE);
}
public ValueIterator(SchemaField field, List<LeafReaderContext> readers, int totalBufferSize, int minSegBufferSize) throws IOException {
assert field.getType().isPointField();
queue = new PQueue(readers.size());
long ndocs = readers.get(readers.size()-1).docBase + readers.get(readers.size()-1).reader().maxDoc();
for (LeafReaderContext ctx : readers) {
PointValues pv = ctx.reader().getPointValues(field.getName());
if (pv == null) continue;
BaseSeg seg = null;
// int capacity = 2;
int capacity = (int)((long)totalBufferSize * ctx.reader().maxDoc() / ndocs);
capacity = Math.max(capacity, minSegBufferSize);
switch (field.getType().getNumberType()) {
case INTEGER:
seg = new IntSeg(pv, capacity);
break;
case LONG:
seg = new LongSeg(pv, capacity);
break;
case FLOAT:
seg = new FloatSeg(pv, capacity);
break;
case DOUBLE:
seg = new DoubleSeg(pv, capacity);
break;
}
int count = seg.setNextValue();
if (count >= 0) {
queue.add(seg);
}
}
if (queue.size() > 0) topVal = queue.top().getMutableValue().duplicate();
}
// gets the mutable value that is updated after every call to getNextCount().
// getMutableValue only needs to be called a single time since the instance is reused for every call to getNextCount().
public MutableValue getMutableValue() {
return topVal;
}
public long getNextCount() throws IOException {
if (queue.size() == 0) return -1;
BaseSeg seg = queue.top();
topVal.copy(seg.getMutableValue());
long count = 0;
do {
count += seg.getCurrentCount();
int nextCount = seg.setNextValue();
if (nextCount < 0) {
queue.pop();
if (queue.size() == 0) break;
} else {
queue.updateTop();
}
seg = queue.top();
} while (seg.getMutableValue().equalsSameType(topVal));
return count;
}
}
static class PQueue extends PriorityQueue<BaseSeg> {
public PQueue(int maxSize) {
super(maxSize);
}
@Override
protected boolean lessThan(BaseSeg a, BaseSeg b) {
return BaseSeg.lessThan(a,b);
}
}
abstract static class BaseSeg implements PointValues.IntersectVisitor {
final PointValues points;
final int[] count;
int pos = -1; // index of the last valid entry
int readPos = -1; // last position read from
MutableValue currentValue; // subclass constructor will fill this in
int currentCount;
BaseSeg(PointValues points, int capacity) {
this.points = points;
this.count = new int[capacity];
}
public static boolean lessThan(BaseSeg a, BaseSeg b) {
return a.currentValue.compareTo(b.currentValue) < 0;
}
public MutableValue getMutableValue() {
return currentValue;
}
// returns -1 count if there are no more values
public int getCurrentCount() {
return currentCount;
}
// sets the next value and returns getCurrentCount()
public int setNextValue() throws IOException {
return 0;
};
void refill() throws IOException {
assert readPos >= pos;
readPos = -1;
pos = -1;
try {
points.intersect(this);
} catch (BreakException e) {
// nothing to do
}
}
@Override
public void visit(int docID) throws IOException {
throw new UnsupportedOperationException();
}
}
static class IntSeg extends BaseSeg {
final int[] values;
int last = Integer.MIN_VALUE;
final MutableValueInt mval;
IntSeg(PointValues points, int capacity) {
super(points, capacity);
this.values = new int[capacity];
this.currentValue = this.mval = new MutableValueInt();
}
public int setNextValue() throws IOException {
if (readPos >= pos) {
if (last != Integer.MAX_VALUE) {
++last;
refill();
}
if (readPos >= pos) {
last = Integer.MAX_VALUE;
currentCount = -1;
return -1;
}
}
++readPos;
mval.value = values[readPos];
currentCount = count[readPos];
return currentCount;
}
@Override
public void visit(int docID, byte[] packedValue) throws IOException {
// TODO: handle filter or deleted documents?
int v = IntPoint.decodeDimension(packedValue, 0);
if (v < last) return;
if (v == last && pos >= 0) {
count[pos]++;
} else {
if (pos+1 < values.length) {
last = v;
++pos;
values[pos] = v;
count[pos] = 1;
} else {
// a new value we don't have room for
throw breakException;
}
}
}
@Override
public PointValues.Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
int v = IntPoint.decodeDimension(maxPackedValue, 0);
if (v >= last) {
return PointValues.Relation.CELL_CROSSES_QUERY;
} else {
return PointValues.Relation.CELL_OUTSIDE_QUERY;
}
}
}
static class LongSeg extends BaseSeg {
final long[] values;
long last = Long.MIN_VALUE;
MutableValueLong mval;
LongSeg(PointValues points, int capacity) {
super(points, capacity);
this.values = new long[capacity];
this.currentValue = this.mval = new MutableValueLong();
}
public int setNextValue() throws IOException {
if (readPos >= pos) {
if (last != Long.MAX_VALUE) {
++last;
refill();
}
if (readPos >= pos) {
last = Long.MAX_VALUE;
currentCount = -1;
return -1;
}
}
++readPos;
mval.value = values[readPos];
currentCount = count[readPos];
return currentCount;
}
@Override
public void visit(int docID, byte[] packedValue) throws IOException {
// TODO: handle filter or deleted documents?
long v = LongPoint.decodeDimension(packedValue, 0);
if (v < last) return;
if (v == last && pos >= 0) {
count[pos]++;
} else {
if (pos+1 < values.length) {
last = v;
++pos;
values[pos] = v;
count[pos] = 1;
} else {
// a new value we don't have room for
throw breakException;
}
}
}
@Override
public PointValues.Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
long v = LongPoint.decodeDimension(maxPackedValue, 0);
if (v >= last) {
return PointValues.Relation.CELL_CROSSES_QUERY;
} else {
return PointValues.Relation.CELL_OUTSIDE_QUERY;
}
}
}
static class FloatSeg extends BaseSeg {
final float[] values;
float last = -Float.MAX_VALUE;
final MutableValueFloat mval;
FloatSeg(PointValues points, int capacity) {
super(points, capacity);
this.values = new float[capacity];
this.currentValue = this.mval = new MutableValueFloat();
}
public int setNextValue() throws IOException {
if (readPos >= pos) {
if (last != Float.MAX_VALUE) {
last = Math.nextUp(last);
refill();
}
if (readPos >= pos) {
last = Float.MAX_VALUE;
currentCount = -1;
return -1;
}
}
++readPos;
mval.value = values[readPos];
currentCount = count[readPos];
return currentCount;
}
@Override
public void visit(int docID, byte[] packedValue) throws IOException {
// TODO: handle filter or deleted documents?
float v = FloatPoint.decodeDimension(packedValue, 0);
if (v < last) return;
if (v == last && pos >= 0) {
count[pos]++;
} else {
if (pos+1 < values.length) {
last = v;
++pos;
values[pos] = v;
count[pos] = 1;
} else {
// a new value we don't have room for
throw breakException;
}
}
}
@Override
public PointValues.Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
float v = FloatPoint.decodeDimension(maxPackedValue, 0);
if (v >= last) {
return PointValues.Relation.CELL_CROSSES_QUERY;
} else {
return PointValues.Relation.CELL_OUTSIDE_QUERY;
}
}
}
static class DoubleSeg extends BaseSeg {
final double[] values;
double last = -Double.MAX_VALUE;
final MutableValueDouble mval;
DoubleSeg(PointValues points, int capacity) {
super(points, capacity);
this.values = new double[capacity];
this.currentValue = this.mval = new MutableValueDouble();
}
public int setNextValue() throws IOException {
if (readPos >= pos) {
if (last != Double.MAX_VALUE) {
last = Math.nextUp(last);
refill();
}
if (readPos >= pos) {
last = Double.MAX_VALUE;
currentCount = -1;
return -1;
}
}
++readPos;
mval.value = values[readPos];
currentCount = count[readPos];
return currentCount;
}
@Override
public void visit(int docID, byte[] packedValue) throws IOException {
// TODO: handle filter or deleted documents?
double v = DoublePoint.decodeDimension(packedValue, 0);
if (v < last) return;
if (v == last && pos >= 0) {
count[pos]++;
} else {
if (pos+1 < values.length) {
last = v;
++pos;
values[pos] = v;
count[pos] = 1;
} else {
// a new value we don't have room for
throw breakException;
}
}
}
@Override
public PointValues.Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
double v = DoublePoint.decodeDimension(maxPackedValue, 0);
if (v >= last) {
return PointValues.Relation.CELL_CROSSES_QUERY;
} else {
return PointValues.Relation.CELL_OUTSIDE_QUERY;
}
}
}
static class DateSeg extends LongSeg {
DateSeg(PointValues points, int capacity) {
super(points, capacity);
this.currentValue = this.mval = new MutableValueDate();
}
}
static class BreakException extends RuntimeException {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
static BreakException breakException = new BreakException();
}

View File

@ -18,8 +18,6 @@ package org.apache.solr.servlet;
import javax.servlet.Filter; import javax.servlet.Filter;
import org.apache.solr.util.Java9InitHack;
/** /**
* All Solr filters available to the user's webapp should * All Solr filters available to the user's webapp should
* extend this class and not just implement {@link Filter}. * extend this class and not just implement {@link Filter}.
@ -30,7 +28,6 @@ abstract class BaseSolrFilter implements Filter {
static { static {
CheckLoggingConfiguration.check(); CheckLoggingConfiguration.check();
Java9InitHack.initJava9();
} }
} }

View File

@ -18,8 +18,6 @@ package org.apache.solr.servlet;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import org.apache.solr.util.Java9InitHack;
/** /**
* All Solr servlets available to the user's webapp should * All Solr servlets available to the user's webapp should
* extend this class and not {@link HttpServlet}. * extend this class and not {@link HttpServlet}.
@ -31,7 +29,6 @@ abstract class BaseSolrServlet extends HttpServlet {
static { static {
CheckLoggingConfiguration.check(); CheckLoggingConfiguration.check();
Java9InitHack.initJava9();
} }
} }

View File

@ -36,6 +36,7 @@ import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.util.plugin.PluginInfoInitialized; import org.apache.solr.util.plugin.PluginInfoInitialized;
import org.apache.solr.util.plugin.SolrCoreAware;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -278,7 +279,9 @@ public final class UpdateRequestProcessorChain implements PluginInfoInitialized
PluginInfo pluginInfo = new PluginInfo("updateProcessor", PluginInfo pluginInfo = new PluginInfo("updateProcessor",
Utils.makeMap("name", s, Utils.makeMap("name", s,
"class", factoryClass.getName())); "class", factoryClass.getName()));
core.getUpdateProcessors().put(s, p = core.getUpdateProcessors().createPlugin(pluginInfo).get()); UpdateRequestProcessorFactory plugin = p = core.getUpdateProcessors().createPlugin(pluginInfo).get();
if (plugin instanceof SolrCoreAware) ((SolrCoreAware) plugin).inform(core);
core.getUpdateProcessors().put(s, plugin);
} }
if (p == null) if (p == null)
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No such processor " + s); throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No such processor " + s);

View File

@ -1,78 +0,0 @@
/*
* 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.util;
import java.lang.invoke.MethodHandles;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;
import org.apache.lucene.util.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class works around a bug in hadoop-common-2.7.2 where the Hadoop Shell class cannot
* initialize on Java 9 (due to a bug while parsing Java's version number).
* This class does some early checks and fakes the java version for a very short time
* during class loading of Solr's web application or Solr's test framework.
* <p>
* Be sure to run this only in static initializers, as soon as possible after JVM startup!
* <p>
* Related issues: HADOOP-14586, SOLR-10966
* <p>
* TODO: <b>Remove this ASAP, once we have upgraded Hadoop (SOLR-10951)!</b>
*
* @lucene.internal
*/
public final class Java9InitHack {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String JAVA_VERSION_PROP = "java.version";
private static boolean done = false;
/**
* Runs the hack. Should be done as early as possible on JVM startup, from a static initializer
* to prevent concurrency issues - because we change temporarily some 'important' system properties.
*/
public static synchronized void initJava9() {
if (Constants.JRE_IS_MINIMUM_JAVA9 && done == false) {
AccessController.doPrivileged((PrivilegedAction<Void>) Java9InitHack::initPrivileged);
done = true;
}
}
private static Void initPrivileged() {
log.info("Adding temporary workaround for Hadoop's Shell class to allow running on Java 9 (please ignore any warnings/failures).");
String oldVersion = System.getProperty(JAVA_VERSION_PROP);
try {
System.setProperty(JAVA_VERSION_PROP, "1.9");
Class.forName("org.apache.hadoop.util.Shell");
} catch (Throwable t) {
log.warn("Cannot initialize Hadoop's Shell class on Java 9.", t);
} finally {
if (!Objects.equals(System.getProperty(JAVA_VERSION_PROP), oldVersion)) {
System.setProperty(JAVA_VERSION_PROP, oldVersion);
}
}
return null;
}
private Java9InitHack() {}
}

View File

@ -633,7 +633,11 @@
<dynamicField name="*_b" type="boolean" indexed="true" stored="true"/> <dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/> <dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
<dynamicField name="*_pi" type="pint" indexed="true" stored="true" docValues="false" multiValued="false"/> <dynamicField name="*_pi" type="pint" indexed="true" multiValued="false"/>
<dynamicField name="*_pl" type="plong" indexed="true" multiValued="false"/>
<dynamicField name="*_pf" type="pfloat" indexed="true" multiValued="false"/>
<dynamicField name="*_pd" type="pdouble" indexed="true" multiValued="false"/>
<dynamicField name="*_pdt" type="pdate" indexed="true" multiValued="false"/>
<!-- some trie-coded dynamic fields for faster range queries --> <!-- some trie-coded dynamic fields for faster range queries -->
<dynamicField name="*_ti" type="tint" indexed="true" stored="true"/> <dynamicField name="*_ti" type="tint" indexed="true" stored="true"/>

View File

@ -15,22 +15,24 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.solr.handler.component; package org.apache.solr.handler.component;
import java.util.Arrays;
import java.util.regex.Pattern;
import org.apache.lucene.util.mutable.MutableValueDouble;
import org.apache.lucene.util.mutable.MutableValueFloat;
import org.apache.lucene.util.mutable.MutableValueInt;
import org.apache.lucene.util.mutable.MutableValueLong;
import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.TermsParams; import org.apache.solr.common.params.TermsParams;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.PointMerger;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.util.regex.Pattern;
/**
*
*
**/
// TermsComponent not currently supported for PointFields
@SolrTestCaseJ4.SuppressPointFields(bugUrl="https://issues.apache.org/jira/browse/SOLR-11173")
public class TermsComponentTest extends SolrTestCaseJ4 { public class TermsComponentTest extends SolrTestCaseJ4 {
@BeforeClass @BeforeClass
@ -283,10 +285,12 @@ public class TermsComponentTest extends SolrTestCaseJ4 {
,"//int[@name='1'][.='2']" ,"//int[@name='1'][.='2']"
); );
/* terms.raw only applies to indexed fields
assertQ(req("indent","true", "qt","/terms", "terms","true", assertQ(req("indent","true", "qt","/terms", "terms","true",
"terms.fl","foo_i", "terms.raw","true") "terms.fl","foo_i", "terms.raw","true")
,"not(//int[@name='1'][.='2'])" ,"not(//int[@name='1'][.='2'])"
); );
*/
// check something at the end of the index // check something at the end of the index
assertQ(req("indent","true", "qt","/terms", "terms","true", assertQ(req("indent","true", "qt","/terms", "terms","true",
@ -381,28 +385,121 @@ public class TermsComponentTest extends SolrTestCaseJ4 {
@Test @Test
public void testPointField() throws Exception { public void testPointField() throws Exception {
assertU(adoc("id", "10000", "foo_pi", "1")); int nvals = 10000; int maxval = 1000000;
assertU(commit()); // int nvals = 5; int maxval = 2;
final int vals[] = new int[nvals];
try { for (int i=0; i<nvals; i++) {
final SolrQueryRequest req = req( vals[i] = random().nextInt(maxval);
"qt", "/terms", String v = Integer.toString(vals[i]);
"terms", "true", assertU(adoc("id", Integer.toString(100000+i), "foo_pi",v, "foo_pl",v, "foo_pf",v, "foo_pd",v) );
"terms.fl", "foo_pi"); if (random().nextInt(1000) == 0) assertU(commit()); // make multiple segments
Exception e = expectThrows(SolrException.class, () -> h.query(req)); }
assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, ((SolrException) e).code());
assertTrue(e.getMessage().contains("The terms component does not support Points-based field foo_pi")); assertU(commit());
// assertU(optimize());
Arrays.sort(vals);
// find the first two values and account for dups
int val1 = vals[0];
int val2 = vals[1];
for (int i=2; i<vals.length; i++) {
if (val2 != val1) break;
val2 = vals[i];
}
SolrQueryRequest req = req(
"qt", "/terms",
"terms", "true",
"terms.fl", "foo_pi");
;
try {
SchemaField sf = req.getSchema().getField("foo_pi");
/**
LeafReader r = req.getSearcher().getIndexReader().leaves().get(0).reader();
PointValues pv = r.getPointValues("foo_pi");
System.out.println("pv=" + pv);
if (pv instanceof AssertingLeafReader.AssertingPointValues) {
pv = ((AssertingLeafReader.AssertingPointValues) pv).getWrapped();
}
System.out.println("pv=" + pv);
BKDReader bkdr = (BKDReader)pv;
for (int i=0; i<Math.min(10,nvals); i++) { System.out.println("INDEXED VAL=" + vals[i]); }
**/
//
// iterate all values
//
int totBuff = random().nextInt(50)+1;
int minSegBuff = random().nextInt(10)+1;
PointMerger.ValueIterator iter = new PointMerger.ValueIterator(req.getSchema().getField("foo_pi"), req.getSearcher().getIndexReader().leaves(), totBuff, minSegBuff);
MutableValueInt v = (MutableValueInt)iter.getMutableValue();
int i=0;
for (;;) {
long count = iter.getNextCount();
if (count < 0) break;
assertEquals( vals[i], v.value );
i += count;
// if (i < 10) System.out.println("COUNT=" + count + " OBJ="+v.toObject());
}
assert(i==nvals);
totBuff = random().nextInt(50)+1;
minSegBuff = random().nextInt(10)+1;
iter = new PointMerger.ValueIterator(req.getSchema().getField("foo_pl"), req.getSearcher().getIndexReader().leaves());
MutableValueLong lv = (MutableValueLong)iter.getMutableValue();
i=0;
for (;;) {
long count = iter.getNextCount();
if (count < 0) break;
assertEquals( vals[i], lv.value );
i += count;
// if (i < 10) System.out.println("COUNT=" + count + " OBJ="+v.toObject());
}
assert(i==nvals);
totBuff = random().nextInt(50)+1;
minSegBuff = random().nextInt(10)+1;
iter = new PointMerger.ValueIterator(req.getSchema().getField("foo_pf"), req.getSearcher().getIndexReader().leaves());
MutableValueFloat fv = (MutableValueFloat)iter.getMutableValue();
i=0;
for (;;) {
long count = iter.getNextCount();
if (count < 0) break;
assertEquals( vals[i], fv.value, 0);
i += count;
// if (i < 10) System.out.println("COUNT=" + count + " OBJ="+v.toObject());
}
assert(i==nvals);
totBuff = random().nextInt(50)+1;
minSegBuff = random().nextInt(10)+1;
iter = new PointMerger.ValueIterator(req.getSchema().getField("foo_pd"), req.getSearcher().getIndexReader().leaves());
MutableValueDouble dv = (MutableValueDouble)iter.getMutableValue();
i=0;
for (;;) {
long count = iter.getNextCount();
if (count < 0) break;
assertEquals( vals[i], dv.value, 0);
i += count;
// if (i < 10) System.out.println("COUNT=" + count + " OBJ="+v.toObject());
}
assert(i==nvals);
assertQ(req("indent","true", "qt","/terms", "terms","true",
"terms.fl","foo_pi", "terms.sort","index", "terms.limit","2")
,"count(//lst[@name='foo_pi']/*)=2"
,"//lst[@name='foo_pi']/int[1][@name='" +val1+ "']"
,"//lst[@name='foo_pi']/int[2][@name='" +val2+ "']"
);
final SolrQueryRequest req2 = req(
"qt", "/terms",
"terms", "true",
"terms.fl", "foo_pi",
"terms.list", "1");
e = expectThrows(SolrException.class, () -> h.query(req2));
assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, ((SolrException) e).code());
assertTrue(e.getMessage().contains("The terms component does not support Points-based field foo_pi"));
} finally { } finally {
assertU(delI("10000")); req.close();
assertU(delQ("foo_pi:[* TO *]"));
assertU(commit()); assertU(commit());
} }
} }

View File

@ -83,15 +83,16 @@ public class AtomicUpdateProcessorFactoryTest extends SolrTestCaseJ4 {
public void testBasics() throws Exception { public void testBasics() throws Exception {
ModifiableSolrParams params = new ModifiableSolrParams()
.add("processor", "atomic")
.add("atomic.cat", "add")
.add("atomic.title", "set")
.add("atomic.count_i", "set")
.add("atomic.name_s", "set")
.add("atomic.multiDefault", "set")
.add("commit", "true");
AddUpdateCommand cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(), AddUpdateCommand cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(),
new ModifiableSolrParams() params
.add("processor", "atomic")
.add("atomic.cat", "add")
.add("atomic.title", "set")
.add("atomic.count_i", "set")
.add("atomic.name_s", "set")
.add("atomic.multiDefault", "set")
.add("commit","true")
)); ));
cmd.solrDoc = new SolrInputDocument(); cmd.solrDoc = new SolrInputDocument();
@ -102,11 +103,10 @@ public class AtomicUpdateProcessorFactoryTest extends SolrTestCaseJ4 {
cmd.solrDoc.addField("name_s", "Virat"); cmd.solrDoc.addField("name_s", "Virat");
cmd.solrDoc.addField("multiDefault", "Delhi"); cmd.solrDoc.addField("multiDefault", "Delhi");
AtomicUpdateProcessorFactory factory = new AtomicUpdateProcessorFactory(); UpdateRequestProcessor chain = h.getCore()
factory.inform(h.getCore()); .getUpdateProcessorChain(params)
factory.getInstance(cmd.getReq(), new SolrQueryResponse(), .createProcessor(cmd.getReq(), new SolrQueryResponse());
new DistributedUpdateProcessor(cmd.getReq(), new SolrQueryResponse(), chain.processAdd(cmd);
new RunUpdateProcessor(cmd.getReq(), null))).processAdd(cmd);
assertU(commit()); assertU(commit());
@ -134,16 +134,15 @@ public class AtomicUpdateProcessorFactoryTest extends SolrTestCaseJ4 {
req("q", "multiDefault:Delhi") req("q", "multiDefault:Delhi")
, "//result[@numFound=1]"); , "//result[@numFound=1]");
cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(), params = new ModifiableSolrParams()
new ModifiableSolrParams() .add("processor", "atomic")
.add("processor", "atomic") .add("atomic.cat", "add")
.add("atomic.cat", "add") .add("atomic.title", "set")
.add("atomic.title", "set") .add("atomic.count_i", "inc")
.add("atomic.count_i", "inc") .add("atomic.name_s", "remove")
.add("atomic.name_s", "remove") .add("atomic.multiDefault", "removeregex")
.add("atomic.multiDefault", "removeregex") .add("commit", "true");
.add("commit","true") cmd = new AddUpdateCommand(new LocalSolrQueryRequest(h.getCore(), params));
));
cmd.solrDoc = new SolrInputDocument(); cmd.solrDoc = new SolrInputDocument();
cmd.solrDoc.addField("id", 1); cmd.solrDoc.addField("id", 1);
@ -152,12 +151,8 @@ public class AtomicUpdateProcessorFactoryTest extends SolrTestCaseJ4 {
cmd.solrDoc.addField("count_i", 20); cmd.solrDoc.addField("count_i", 20);
cmd.solrDoc.addField("name_s", "Virat"); cmd.solrDoc.addField("name_s", "Virat");
cmd.solrDoc.addField("multiDefault", ".elh."); cmd.solrDoc.addField("multiDefault", ".elh.");
chain = h.getCore().getUpdateProcessorChain(params).createProcessor(cmd.getReq(), new SolrQueryResponse());
factory = new AtomicUpdateProcessorFactory(); chain.processAdd(cmd);
factory.inform(h.getCore());
factory.getInstance(cmd.getReq(), new SolrQueryResponse(),
new DistributedUpdateProcessor(cmd.getReq(), new SolrQueryResponse(),
new RunUpdateProcessor(cmd.getReq(), null))).processAdd(cmd);
assertU(commit()); assertU(commit());

View File

@ -1 +0,0 @@
80693ef2884927ee3c5464a7539fcfa4af382e14

View File

@ -0,0 +1 @@
d8e0a3abcc3fb46e1418b99d6d1328a95d9bd7b1

View File

@ -1 +0,0 @@
bf613cfec06a1f3d3a91d7f82f9e4af75bc01f72

View File

@ -0,0 +1 @@
a2d5d89a6acfb11dd1a125e86b84fcef549483ae

View File

@ -1 +0,0 @@
482b3051dc384c1e15182a6ad1402649ef24be02

View File

@ -1 +0,0 @@
422eb48913fa6f81835b3192c97a576505b6c192

View File

@ -0,0 +1 @@
a2aa0905c8f980d36f4e861283dccfcad6dd3dec

View File

@ -0,0 +1 @@
9afa8d2004a0bbd930d1ac10d221d927917067be

View File

@ -1 +0,0 @@
dfb6840b97211044e87a0345f7edad51b942fd2a

View File

@ -1 +0,0 @@
3c304b3d9227fbf8af8bc1cab013271538c3cf0a

View File

@ -0,0 +1 @@
3e5dbc6eb1d4d5d4c19a06c0a443f5bdc3740a35

View File

@ -0,0 +1 @@
3e1414e3ae47e97f66b2eb904d3ec6c50a3e29d0

View File

@ -1 +0,0 @@
59d112c8683f563f7aaf05fde7bc4022b90b44a7

View File

@ -0,0 +1 @@
3964a7984a19e553e090a2279569ec0060b87d5b

View File

@ -0,0 +1 @@
60367999cee49a3b09fa86bdcb52310b6c896014

View File

@ -105,6 +105,14 @@
</New> </New>
</Arg> </Arg>
</Call> </Call>
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
<Set name="pattern">/api/*</Set>
<Set name="replacement">/solr/____v2</Set>
</New>
</Arg>
</Call>
<Set name="handler"> <Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection"> <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers"> <Set name="handlers">

View File

@ -165,7 +165,7 @@ Returns the following response:
} }
---- ----
== Arrays == Array (data structure)
The first data structure we'll explore is the *array*. The first data structure we'll explore is the *array*.
@ -370,7 +370,7 @@ Returns the following response:
---- ----
== Tuple == Tuple (data structure)
The *tuple* is the next data structure we'll explore. The *tuple* is the next data structure we'll explore.
@ -419,7 +419,7 @@ Returns the following response:
} }
---- ----
== List == List (data structure)
Next we have the *list* data structure. Next we have the *list* data structure.
@ -467,7 +467,7 @@ Returns the following response:
} }
---- ----
== Let == Let (setting variables)
The `let` function sets *variables* and runs a Streaming Expression that references the variables. The `let` funtion can be used to The `let` function sets *variables* and runs a Streaming Expression that references the variables. The `let` funtion can be used to
write small statistical programs. write small statistical programs.
@ -529,7 +529,7 @@ Here is the output:
} }
---- ----
== Col == Creating arrays with `col` function
The `col` function is used to move a column of numbers from a list of tuples into an `array`. The `col` function is used to move a column of numbers from a list of tuples into an `array`.
This is an important function because Streaming Expressions such as `sql`, `random` and `timeseries` return tuples, This is an important function because Streaming Expressions such as `sql`, `random` and `timeseries` return tuples,
@ -586,7 +586,7 @@ The response shows the arrays:
} }
---- ----
== Statistical Programming == Statistical Programming Example
We've covered how the *data structures*, *variables* and a few *statistical functions* work. We've covered how the *data structures*, *variables* and a few *statistical functions* work.
Let's dive into an example that puts these tools to use. Let's dive into an example that puts these tools to use.
@ -623,7 +623,7 @@ The use case we're reasoning about can often be approached using a K Nearest Nei
With knn we use a *distance* measure to compare vectors of data to find the k nearest neighbors to With knn we use a *distance* measure to compare vectors of data to find the k nearest neighbors to
a specific vector. a specific vector.
=== Distance === Euclidean Distance
The Streaming Expression statistical function library has a function called `distance`. The `distance` function The Streaming Expression statistical function library has a function called `distance`. The `distance` function
computes the Euclidean distance between two vectors. This looks promising for comparing vectors of room rates. computes the Euclidean distance between two vectors. This looks promising for comparing vectors of room rates.

View File

@ -41,38 +41,38 @@ Following are some v2 API URL paths and path prefixes, along with some of the op
[width="100%",options="header",] [width="100%",options="header",]
|=== |===
|Path prefix |Some Supported Operations |Path prefix |Some Supported Operations
|`/v2/collections` or equivalently: `/v2/c` |Create, alias, backup, and restore a collection. |`/api/collections` or equivalently: `/api/c` |Create, alias, backup, and restore a collection.
|`/v2/c/_collection-name_/update` |Update requests. |`/api/c/_collection-name_/update` |Update requests.
|`/v2/c/_collection-name_/config` |Configuration requests. |`/api/c/_collection-name_/config` |Configuration requests.
|`/v2/c/_collection-name_/schema` |Schema requests. |`/api/c/_collection-name_/schema` |Schema requests.
|`/v2/c/_collection-name_/_handler-name_` |Handler-specific requests. |`/api/c/_collection-name_/_handler-name_` |Handler-specific requests.
|`/v2/c/_collection-name_/shards` |Split a shard, create a shard, add a replica. |`/api/c/_collection-name_/shards` |Split a shard, create a shard, add a replica.
|`/v2/c/_collection-name_/shards/_shard-name_` |Delete a shard, force leader election |`/api/c/_collection-name_/shards/_shard-name_` |Delete a shard, force leader election
|`/v2/c/_collection-name_/shards/_shard-name_/_replica-name_` |Delete a replica. |`/api/c/_collection-name_/shards/_shard-name_/_replica-name_` |Delete a replica.
|`/v2/cores` |Create a core. |`/api/cores` |Create a core.
|`/v2/cores/_core-name_` |Reload, rename, delete, and unload a core. |`/api/cores/_core-name_` |Reload, rename, delete, and unload a core.
|`/v2/node` |Perform overseer operation, rejoin leader election. |`/api/node` |Perform overseer operation, rejoin leader election.
|`/v2/cluster` |Add role, remove role, set cluster property. |`/api/cluster` |Add role, remove role, set cluster property.
|`/v2/c/.system/blob` |Upload and download blobs and metadata. |`/api/c/.system/blob` |Upload and download blobs and metadata.
|=== |===
== Introspect == Introspect
Append `/_introspect` to any valid v2 API path and the API specification will be returned in JSON format. Append `/_introspect` to any valid v2 API path and the API specification will be returned in JSON format.
`\http://localhost:8983/v2/c/_introspect` `\http://localhost:8983/api/c/_introspect`
To limit the introspect output to include just one particular HTTP method, add request param `method` with value `GET`, `POST`, or `DELETE`. To limit the introspect output to include just one particular HTTP method, add request param `method` with value `GET`, `POST`, or `DELETE`.
`\http://localhost:8983/v2/c/_introspect?method=POST` `\http://localhost:8983/api/c/_introspect?method=POST`
Most endpoints support commands provided in a body sent via POST. To limit the introspect output to only one command, add request param `command=_command-name_` . Most endpoints support commands provided in a body sent via POST. To limit the introspect output to only one command, add request param `command=_command-name_` .
`\http://localhost:8983/v2/c/gettingstarted/_introspect?method=POST&command=modify` `\http://localhost:8983/api/c/gettingstarted/_introspect?method=POST&command=modify`
=== Interpreting the Introspect Output === Interpreting the Introspect Output
Example : `\http://localhost:8983/v2/c/gettingstarted/get/_introspect` Example : `\http://localhost:8983/api/c/gettingstarted/get/_introspect`
[source,json] [source,json]
---- ----
@ -107,7 +107,7 @@ Description of some of the keys in the above example:
* `**spec/url/params**` : List of supported URL request params * `**spec/url/params**` : List of supported URL request params
* `**availableSubPaths**` : List of valid URL subpaths and the HTTP method(s) each supports * `**availableSubPaths**` : List of valid URL subpaths and the HTTP method(s) each supports
Example of introspect for a POST API: `\http://localhost:8983/v2/c/gettingstarted/_introspect?method=POST&command=modify` Example of introspect for a POST API: `\http://localhost:8983/api/c/gettingstarted/_introspect?method=POST&command=modify`
[source,json] [source,json]
---- ----
@ -161,7 +161,7 @@ For the "gettingstarted" collection, set the replication factor and whether to a
[source,bash] [source,bash]
---- ----
$ curl http://localhost:8983/v2/c/gettingstarted -H 'Content-type:application/json' -d ' $ curl http://localhost:8983/api/c/gettingstarted -H 'Content-type:application/json' -d '
{ modify: { replicationFactor: "3", autoAddReplicas: false } }' { modify: { replicationFactor: "3", autoAddReplicas: false } }'
{"responseHeader":{"status":0,"QTime":842}} {"responseHeader":{"status":0,"QTime":842}}
@ -171,7 +171,7 @@ See the state of the cluster:
[source,bash] [source,bash]
---- ----
$ curl http://localhost:8983/v2/cluster $ curl http://localhost:8983/api/cluster
{"responseHeader":{"status":0,"QTime":0},"collections":["gettingstarted",".system"]} {"responseHeader":{"status":0,"QTime":0},"collections":["gettingstarted",".system"]}
---- ----
@ -180,7 +180,7 @@ Set a cluster property:
[source,bash] [source,bash]
---- ----
$ curl http://localhost:8983/v2/cluster -H 'Content-type: application/json' -d ' $ curl http://localhost:8983/api/cluster -H 'Content-type: application/json' -d '
{ set-property: { name: autoAddReplicas, val: "false" } }' { set-property: { name: autoAddReplicas, val: "false" } }'
{"responseHeader":{"status":0,"QTime":4}} {"responseHeader":{"status":0,"QTime":4}}

View File

@ -355,7 +355,7 @@ public class HttpSolrClient extends SolrClient {
if (request instanceof V2Request) { if (request instanceof V2Request) {
if (System.getProperty("solr.v2RealPath") == null) { if (System.getProperty("solr.v2RealPath") == null) {
basePath = baseUrl.replace("/solr", "/v2"); basePath = baseUrl.replace("/solr", "/api");
} else { } else {
basePath = baseUrl + "/____v2"; basePath = baseUrl + "/____v2";
} }

View File

@ -116,7 +116,6 @@ import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.servlet.DirectSolrConnection; import org.apache.solr.servlet.DirectSolrConnection;
import org.apache.solr.util.AbstractSolrTestCase; import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.solr.util.Java9InitHack;
import org.apache.solr.util.LogLevel; import org.apache.solr.util.LogLevel;
import org.apache.solr.util.RandomizeSSL; import org.apache.solr.util.RandomizeSSL;
import org.apache.solr.util.RandomizeSSL.SSLRandomizer; import org.apache.solr.util.RandomizeSSL.SSLRandomizer;
@ -162,11 +161,6 @@ import static java.util.Objects.requireNonNull;
public abstract class SolrTestCaseJ4 extends LuceneTestCase { public abstract class SolrTestCaseJ4 extends LuceneTestCase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
// this must be a static init block to be safe!
static {
Java9InitHack.initJava9();
}
private static final List<String> DEFAULT_STACK_FILTERS = Arrays.asList(new String [] { private static final List<String> DEFAULT_STACK_FILTERS = Arrays.asList(new String [] {
"org.junit.", "org.junit.",

View File

@ -29,6 +29,8 @@ public class BadHdfsThreadsFilter implements ThreadFilter {
return true; return true;
} else if (name.startsWith("LeaseRenewer")) { // SOLR-7287 } else if (name.startsWith("LeaseRenewer")) { // SOLR-7287
return true; return true;
} else if (name.startsWith("org.apache.hadoop.fs.FileSystem$Statistics")) { // SOLR-11261
return true;
} }
return false; return false;
} }