mirror of https://github.com/apache/lucene.git
SOLR-6476 refactored bulk schema APIs and other read REST APIs to use standard RequestHandler mechanism
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1642641 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a371f353f5
commit
f317f12f87
|
@ -2123,7 +2123,7 @@ public final class ZkController {
|
|||
final ZkController zkController = zkLoader.getZkController();
|
||||
final SolrZkClient zkClient = zkController.getZkClient();
|
||||
final String resourceLocation = zkLoader.getConfigSetZkPath() + "/" + resourceName;
|
||||
String errMsg = "Failed to persist resource at {0} - version mismatch {1}";
|
||||
String errMsg = "Failed to persist resource at {0} - old {1}";
|
||||
try {
|
||||
try {
|
||||
zkClient.setData(resourceLocation , content,znodeVersion, true);
|
||||
|
@ -2136,7 +2136,7 @@ public final class ZkController {
|
|||
} catch (KeeperException.NodeExistsException nee) {
|
||||
try {
|
||||
Stat stat = zkClient.exists(resourceLocation, null, true);
|
||||
log.info("failed to set data version in zk is {} and expected version is {} ", stat.getVersion(),znodeVersion);
|
||||
log.info("failed to set data version in zk is {0} and expected version is {1} ", stat.getVersion(),znodeVersion);
|
||||
} catch (Exception e1) {
|
||||
log.warn("could not get stat");
|
||||
}
|
||||
|
@ -2148,7 +2148,15 @@ public final class ZkController {
|
|||
}
|
||||
|
||||
} catch (KeeperException.BadVersionException bve){
|
||||
log.info(MessageFormat.format(errMsg,resourceLocation));
|
||||
int v = -1;
|
||||
try {
|
||||
Stat stat = zkClient.exists(resourceLocation, null, true);
|
||||
v = stat.getVersion();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
|
||||
}
|
||||
log.info(MessageFormat.format(errMsg+ " zkVersion= "+v,resourceLocation,znodeVersion));
|
||||
throw new ResourceModifiedInZkException(ErrorCode.CONFLICT, MessageFormat.format(errMsg,resourceLocation,znodeVersion) + ", retry.");
|
||||
}catch (ResourceModifiedInZkException e){
|
||||
throw e;
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.solr.common.util.NamedList;
|
|||
import org.apache.solr.handler.PingRequestHandler;
|
||||
import org.apache.solr.handler.RealTimeGetHandler;
|
||||
import org.apache.solr.handler.ReplicationHandler;
|
||||
import org.apache.solr.handler.SchemaHandler;
|
||||
import org.apache.solr.handler.SolrConfigHandler;
|
||||
import org.apache.solr.handler.UpdateRequestHandler;
|
||||
import org.apache.solr.handler.admin.LoggingHandler;
|
||||
|
@ -57,7 +58,8 @@ public class PluginsRegistry {
|
|||
|
||||
//solrconfighandler
|
||||
implicits.add(getReqHandlerInfo("/config", SolrConfigHandler.class, null));
|
||||
|
||||
//schemahandler
|
||||
implicits.add(getReqHandlerInfo("/schema", SchemaHandler.class, null));
|
||||
//register replicationhandler always for SolrCloud
|
||||
implicits.add(getReqHandlerInfo("/replication", ReplicationHandler.class,null));
|
||||
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package org.apache.solr.handler;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.solr.cloud.ZkSolrResourceLoader;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.util.ContentStream;
|
||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.request.SolrRequestHandler;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.ManagedIndexSchema;
|
||||
import org.apache.solr.schema.SchemaManager;
|
||||
import org.apache.solr.schema.ZkIndexSchemaReader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SchemaHandler extends RequestHandlerBase {
|
||||
private static final Logger log = LoggerFactory.getLogger(SchemaHandler.class);
|
||||
@Override
|
||||
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
|
||||
SolrConfigHandler.setWt(req, "json");
|
||||
String httpMethod = (String) req.getContext().get("httpMethod");
|
||||
if("POST".equals(httpMethod)){
|
||||
if (req.getContentStreams() == null) {
|
||||
rsp.add("errors", "no stream");
|
||||
return;
|
||||
}
|
||||
|
||||
for (ContentStream stream : req.getContentStreams()) {
|
||||
try {
|
||||
List errs = new SchemaManager(req).performOperations(stream.getReader());
|
||||
if(!errs.isEmpty()) rsp.add("errors", errs);
|
||||
} catch (IOException e) {
|
||||
rsp.add("errors", Collections.singletonList("Error reading input String " + e.getMessage()));
|
||||
rsp.setException(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
handleGET(req, rsp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleGET(SolrQueryRequest req, SolrQueryResponse rsp) {
|
||||
try {
|
||||
String path = (String) req.getContext().get("path");
|
||||
switch (path){
|
||||
case "/schema":
|
||||
rsp.add(IndexSchema.SCHEMA, req.getSchema().getNamedPropertyValues());
|
||||
break;
|
||||
case "/schema/version" :
|
||||
rsp.add(IndexSchema.VERSION, req.getSchema().getVersion());
|
||||
break;
|
||||
case "/schema/uniquekey" :
|
||||
rsp.add(IndexSchema.UNIQUE_KEY, req.getSchema().getUniqueKeyField().getName());
|
||||
break;
|
||||
case "/schema/similarity" :
|
||||
rsp.add(IndexSchema.SIMILARITY, req.getSchema().getSimilarityFactory().getNamedPropertyValues());
|
||||
break;
|
||||
case "/schema/name" : {
|
||||
final String schemaName = req.getSchema().getSchemaName();
|
||||
if (null == schemaName) {
|
||||
String message = "Schema has no name";
|
||||
throw new SolrException(SolrException.ErrorCode.NOT_FOUND, message);
|
||||
}
|
||||
rsp.add(IndexSchema.NAME, schemaName);
|
||||
break;
|
||||
}
|
||||
case "/schema/defaultsearchfield" : {
|
||||
final String defaultSearchFieldName = req.getSchema().getDefaultSearchFieldName();
|
||||
if (null == defaultSearchFieldName) {
|
||||
final String message = "undefined " + IndexSchema.DEFAULT_SEARCH_FIELD;
|
||||
throw new SolrException(SolrException.ErrorCode.NOT_FOUND, message);
|
||||
}
|
||||
rsp.add(IndexSchema.DEFAULT_SEARCH_FIELD, defaultSearchFieldName);
|
||||
break;
|
||||
}
|
||||
case "/schema/solrqueryparser":{
|
||||
SimpleOrderedMap<Object> props = new SimpleOrderedMap<>();
|
||||
props.add(IndexSchema.DEFAULT_OPERATOR, req.getSchema().getQueryParserDefaultOperator());
|
||||
rsp.add(IndexSchema.SOLR_QUERY_PARSER, props);
|
||||
break;
|
||||
}
|
||||
case "/schema/zkversion" : {
|
||||
int refreshIfBelowVersion = -1;
|
||||
Object refreshParam = req.getParams().get("refreshIfBelowVersion");
|
||||
if (refreshParam != null)
|
||||
refreshIfBelowVersion = (refreshParam instanceof Number) ? ((Number)refreshParam).intValue()
|
||||
: Integer.parseInt(refreshParam.toString());
|
||||
int zkVersion = -1;
|
||||
IndexSchema schema = req.getSchema();
|
||||
if (schema instanceof ManagedIndexSchema) {
|
||||
ManagedIndexSchema managed = (ManagedIndexSchema)schema;
|
||||
zkVersion = managed.getSchemaZkVersion();
|
||||
if (refreshIfBelowVersion != -1 && zkVersion < refreshIfBelowVersion) {
|
||||
log.info("REFRESHING SCHEMA (refreshIfBelowVersion="+refreshIfBelowVersion+
|
||||
", currentVersion="+zkVersion+") before returning version!");
|
||||
ZkSolrResourceLoader zkSolrResourceLoader = (ZkSolrResourceLoader)req.getCore().getResourceLoader();
|
||||
ZkIndexSchemaReader zkIndexSchemaReader = zkSolrResourceLoader.getZkIndexSchemaReader();
|
||||
managed = zkIndexSchemaReader.refreshSchemaFromZk(refreshIfBelowVersion);
|
||||
zkVersion = managed.getSchemaZkVersion();
|
||||
}
|
||||
}
|
||||
rsp.add("zkversion", zkVersion);
|
||||
break;
|
||||
}
|
||||
case "/schema/solrqueryparser/defaultoperator" : {
|
||||
rsp.add(IndexSchema.DEFAULT_OPERATOR, req.getSchema().getQueryParserDefaultOperator());
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
throw new SolrException(SolrException.ErrorCode.NOT_FOUND,"No such path "+path);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
rsp.setException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<String> subPaths = new HashSet<>(Arrays.asList(
|
||||
"/version",
|
||||
"/uniquekey",
|
||||
"/name",
|
||||
"/similarity" ,
|
||||
"/defaultsearchfield",
|
||||
"/solrqueryparser",
|
||||
"/zkversion",
|
||||
"/solrqueryparser/defaultoperator"
|
||||
));
|
||||
|
||||
@Override
|
||||
public SolrRequestHandler getSubHandler(String subPath) {
|
||||
if(subPaths.contains(subPath)) return this;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Edit schema.xml";
|
||||
}
|
||||
}
|
|
@ -52,6 +52,7 @@ import org.apache.solr.request.SolrQueryRequest;
|
|||
import org.apache.solr.request.SolrRequestHandler;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.schema.FieldType;
|
||||
import org.apache.solr.schema.ManagedIndexSchema;
|
||||
import org.apache.solr.schema.SchemaManager;
|
||||
import org.apache.solr.util.CommandOperation;
|
||||
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||
|
@ -104,22 +105,33 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
|
|||
private static Runnable getListener(SolrCore core, ZkSolrResourceLoader zkSolrResourceLoader) {
|
||||
final String coreName = core.getName();
|
||||
final CoreContainer cc = core.getCoreDescriptor().getCoreContainer();
|
||||
final String overlayPath = (zkSolrResourceLoader).getConfigSetZkPath() + "/" + ConfigOverlay.RESOURCE_NAME;
|
||||
final String solrConfigPath = (zkSolrResourceLoader).getConfigSetZkPath() + "/" + core.getSolrConfig().getName();
|
||||
final String overlayPath = zkSolrResourceLoader.getConfigSetZkPath() + "/" + ConfigOverlay.RESOURCE_NAME;
|
||||
final String solrConfigPath = zkSolrResourceLoader.getConfigSetZkPath() + "/" + core.getSolrConfig().getName();
|
||||
String schemaRes = null;
|
||||
if(core.getLatestSchema().isMutable() && core.getLatestSchema() instanceof ManagedIndexSchema){
|
||||
ManagedIndexSchema mis = (ManagedIndexSchema) core.getLatestSchema();
|
||||
schemaRes = mis.getResourceName();
|
||||
}
|
||||
final String managedSchmaResourcePath = schemaRes ==null ? null: zkSolrResourceLoader.getConfigSetZkPath() + "/" + schemaRes;
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
log.info("config update listener called for core {}", coreName);
|
||||
SolrZkClient zkClient = cc.getZkController().getZkClient();
|
||||
int solrConfigversion,overlayVersion;
|
||||
int solrConfigversion,overlayVersion, managedSchemaVersion=0;
|
||||
try (SolrCore core = cc.getCore(coreName)) {
|
||||
if (core.isClosed()) return;
|
||||
solrConfigversion = core.getSolrConfig().getOverlay().getZnodeVersion();
|
||||
overlayVersion = core.getSolrConfig().getZnodeVersion();
|
||||
if(managedSchmaResourcePath != null){
|
||||
managedSchemaVersion = ((ManagedIndexSchema)core.getLatestSchema()).getSchemaZkVersion();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (checkStale(zkClient, overlayPath, solrConfigversion) ||
|
||||
checkStale(zkClient, solrConfigPath, overlayVersion)) {
|
||||
checkStale(zkClient, solrConfigPath, overlayVersion) ||
|
||||
checkStale(zkClient, managedSchmaResourcePath,managedSchemaVersion)) {
|
||||
log.info("core reload {}",coreName);
|
||||
cc.reload(coreName);
|
||||
}
|
||||
|
@ -128,6 +140,7 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
|
|||
}
|
||||
|
||||
private static boolean checkStale(SolrZkClient zkClient, String zkPath, int currentVersion) {
|
||||
if(zkPath == null) return false;
|
||||
try {
|
||||
Stat stat = zkClient.exists(zkPath, null, true);
|
||||
if(stat == null){
|
||||
|
|
|
@ -18,21 +18,12 @@ package org.apache.solr.rest;
|
|||
|
||||
import org.apache.solr.request.SolrRequestInfo;
|
||||
import org.apache.solr.rest.schema.CopyFieldCollectionResource;
|
||||
import org.apache.solr.rest.schema.SchemaResource;
|
||||
import org.apache.solr.rest.schema.DefaultSearchFieldResource;
|
||||
import org.apache.solr.rest.schema.DynamicFieldCollectionResource;
|
||||
import org.apache.solr.rest.schema.DynamicFieldResource;
|
||||
import org.apache.solr.rest.schema.FieldCollectionResource;
|
||||
import org.apache.solr.rest.schema.FieldResource;
|
||||
import org.apache.solr.rest.schema.FieldTypeCollectionResource;
|
||||
import org.apache.solr.rest.schema.FieldTypeResource;
|
||||
import org.apache.solr.rest.schema.SchemaNameResource;
|
||||
import org.apache.solr.rest.schema.SchemaSimilarityResource;
|
||||
import org.apache.solr.rest.schema.SchemaVersionResource;
|
||||
import org.apache.solr.rest.schema.SchemaZkVersionResource;
|
||||
import org.apache.solr.rest.schema.SolrQueryParserDefaultOperatorResource;
|
||||
import org.apache.solr.rest.schema.SolrQueryParserResource;
|
||||
import org.apache.solr.rest.schema.UniqueKeyFieldResource;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.restlet.Application;
|
||||
import org.restlet.Restlet;
|
||||
|
@ -58,30 +49,11 @@ public class SolrSchemaRestApi extends Application {
|
|||
public static final String FIELDTYPES = IndexSchema.FIELD_TYPES.toLowerCase(Locale.ROOT);
|
||||
public static final String FIELDTYPES_PATH = "/" + FIELDTYPES;
|
||||
|
||||
public static final String NAME_PATH = "/" + IndexSchema.NAME.toLowerCase(Locale.ROOT);
|
||||
public static final String NAME_SEGMENT = "/{" + IndexSchema.NAME.toLowerCase(Locale.ROOT) + "}";
|
||||
|
||||
public static final String COPY_FIELDS = IndexSchema.COPY_FIELDS.toLowerCase(Locale.ROOT);
|
||||
public static final String COPY_FIELDS_PATH = "/" + COPY_FIELDS;
|
||||
|
||||
public static final String VERSION_PATH = "/" + IndexSchema.VERSION.toLowerCase(Locale.ROOT);
|
||||
|
||||
public static final String DEFAULT_SEARCH_FIELD = IndexSchema.DEFAULT_SEARCH_FIELD.toLowerCase(Locale.ROOT);
|
||||
public static final String DEFAULT_SEARCH_FIELD_PATH = "/" + DEFAULT_SEARCH_FIELD;
|
||||
|
||||
public static final String SIMILARITY_PATH = "/" + IndexSchema.SIMILARITY.toLowerCase(Locale.ROOT);
|
||||
|
||||
public static final String SOLR_QUERY_PARSER = IndexSchema.SOLR_QUERY_PARSER.toLowerCase(Locale.ROOT);
|
||||
public static final String SOLR_QUERY_PARSER_PATH = "/" + SOLR_QUERY_PARSER;
|
||||
|
||||
public static final String DEFAULT_OPERATOR = IndexSchema.DEFAULT_OPERATOR.toLowerCase(Locale.ROOT);
|
||||
public static final String DEFAULT_OPERATOR_PATH = SOLR_QUERY_PARSER_PATH + "/" + DEFAULT_OPERATOR;
|
||||
|
||||
public static final String UNIQUE_KEY_FIELD = IndexSchema.UNIQUE_KEY.toLowerCase(Locale.ROOT);
|
||||
public static final String UNIQUE_KEY_FIELD_PATH = "/" + UNIQUE_KEY_FIELD;
|
||||
|
||||
public static final String ZK_VERSION_PATH = "/zkversion";
|
||||
|
||||
/**
|
||||
* Returns reserved endpoints under /schema
|
||||
*/
|
||||
|
@ -90,15 +62,7 @@ public class SolrSchemaRestApi extends Application {
|
|||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + FIELDS_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + DYNAMIC_FIELDS_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + FIELDTYPES_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + NAME_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + COPY_FIELDS_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + VERSION_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + DEFAULT_SEARCH_FIELD_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + SIMILARITY_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + SOLR_QUERY_PARSER_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + DEFAULT_OPERATOR_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + UNIQUE_KEY_FIELD_PATH);
|
||||
reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + ZK_VERSION_PATH);
|
||||
return Collections.unmodifiableSet(reservedEndpoints);
|
||||
}
|
||||
|
||||
|
@ -123,10 +87,7 @@ public class SolrSchemaRestApi extends Application {
|
|||
|
||||
log.info("createInboundRoot started for /schema");
|
||||
|
||||
router.attach("", SchemaResource.class);
|
||||
// Allow a trailing slash on full-schema requests
|
||||
router.attach("/", SchemaResource.class);
|
||||
|
||||
|
||||
router.attach(FIELDS_PATH, FieldCollectionResource.class);
|
||||
// Allow a trailing slash on collection requests
|
||||
router.attach(FIELDS_PATH + "/", FieldCollectionResource.class);
|
||||
|
@ -145,23 +106,7 @@ public class SolrSchemaRestApi extends Application {
|
|||
router.attach(COPY_FIELDS_PATH, CopyFieldCollectionResource.class);
|
||||
// Allow a trailing slash on collection requests
|
||||
router.attach(COPY_FIELDS_PATH + "/", CopyFieldCollectionResource.class);
|
||||
|
||||
router.attach(NAME_PATH, SchemaNameResource.class);
|
||||
|
||||
router.attach(VERSION_PATH, SchemaVersionResource.class);
|
||||
|
||||
router.attach(UNIQUE_KEY_FIELD_PATH, UniqueKeyFieldResource.class);
|
||||
|
||||
router.attach(DEFAULT_SEARCH_FIELD_PATH, DefaultSearchFieldResource.class);
|
||||
|
||||
router.attach(SIMILARITY_PATH, SchemaSimilarityResource.class);
|
||||
|
||||
// At present solrQueryParser only contains defaultOperator, but there may be more children in the future
|
||||
router.attach(SOLR_QUERY_PARSER_PATH, SolrQueryParserResource.class);
|
||||
router.attach(DEFAULT_OPERATOR_PATH, SolrQueryParserDefaultOperatorResource.class);
|
||||
|
||||
router.attach(ZK_VERSION_PATH, SchemaZkVersionResource.class);
|
||||
|
||||
router.attachDefault(RestManager.ManagedEndpoint.class);
|
||||
|
||||
// attach all the dynamically registered schema resources
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.SolrException.ErrorCode;
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema/defaultsearchfield
|
||||
*/
|
||||
public class DefaultSearchFieldResource extends BaseSolrResource implements GETable {
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultSearchFieldResource.class);
|
||||
|
||||
public DefaultSearchFieldResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
final String defaultSearchFieldName = getSchema().getDefaultSearchFieldName();
|
||||
if (null == defaultSearchFieldName) {
|
||||
final String message = "undefined " + IndexSchema.DEFAULT_SEARCH_FIELD;
|
||||
throw new SolrException(ErrorCode.NOT_FOUND, message);
|
||||
}
|
||||
getSolrResponse().add(IndexSchema.DEFAULT_SEARCH_FIELD, defaultSearchFieldName);
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema/name
|
||||
*/
|
||||
public class SchemaNameResource extends BaseSolrResource implements GETable {
|
||||
private static final Logger log = LoggerFactory.getLogger(SchemaNameResource.class);
|
||||
|
||||
public SchemaNameResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
final String schemaName = getSchema().getSchemaName();
|
||||
if (null == schemaName) {
|
||||
final String message = "Schema has no name";
|
||||
throw new SolrException(SolrException.ErrorCode.NOT_FOUND, message);
|
||||
}
|
||||
getSolrResponse().add(IndexSchema.NAME, schemaName);
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.request.SolrRequestInfo;
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.rest.POSTable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.SchemaManager;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema
|
||||
*/
|
||||
public class SchemaResource extends BaseSolrResource implements GETable,POSTable {
|
||||
private static final Logger log = LoggerFactory.getLogger(SchemaResource.class);
|
||||
|
||||
public SchemaResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
getSolrResponse().add(IndexSchema.SCHEMA, getSchema().getNamedPropertyValues());
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation post(Representation representation) {
|
||||
SolrRequestInfo requestInfo = SolrRequestInfo.getRequestInfo();
|
||||
List<String> errs = null;
|
||||
try {
|
||||
String text = representation.getText();
|
||||
errs = new SchemaManager(requestInfo.getReq()).performOperations(new StringReader(text));
|
||||
} catch (IOException e) {
|
||||
requestInfo.getRsp().add("errors", Collections.singletonList("Error reading input String " + e.getMessage()));
|
||||
requestInfo.getRsp().setException(e);
|
||||
}
|
||||
if(!errs.isEmpty()){
|
||||
requestInfo.getRsp().add("errors", errs);
|
||||
}
|
||||
|
||||
|
||||
return new BaseSolrResource.SolrOutputRepresentation();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema/similarity
|
||||
*/
|
||||
public class SchemaSimilarityResource extends BaseSolrResource implements GETable {
|
||||
private static final Logger log = LoggerFactory.getLogger(SchemaSimilarityResource.class);
|
||||
|
||||
public SchemaSimilarityResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
getSolrResponse().add(IndexSchema.SIMILARITY, getSchema().getSimilarityFactory().getNamedPropertyValues());
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema/version
|
||||
*/
|
||||
public class SchemaVersionResource extends BaseSolrResource implements GETable {
|
||||
private static final Logger log = LoggerFactory.getLogger(SchemaVersionResource.class);
|
||||
|
||||
public SchemaVersionResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
getSolrResponse().add(IndexSchema.VERSION, getSchema().getVersion());
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.cloud.ZkSolrResourceLoader;
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.ManagedIndexSchema;
|
||||
import org.apache.solr.schema.ZkIndexSchemaReader;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema/zkversion
|
||||
*/
|
||||
public class SchemaZkVersionResource extends BaseSolrResource implements GETable {
|
||||
private static final Logger log = LoggerFactory.getLogger(SchemaZkVersionResource.class);
|
||||
|
||||
protected int refreshIfBelowVersion = -1;
|
||||
|
||||
public SchemaZkVersionResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
|
||||
// sometimes the client knows which version it expects
|
||||
Object refreshParam = getSolrRequest().getParams().get("refreshIfBelowVersion");
|
||||
if (refreshParam != null)
|
||||
refreshIfBelowVersion = (refreshParam instanceof Number) ? ((Number)refreshParam).intValue()
|
||||
: Integer.parseInt(refreshParam.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
int zkVersion = -1;
|
||||
IndexSchema schema = getSchema();
|
||||
if (schema instanceof ManagedIndexSchema) {
|
||||
ManagedIndexSchema managed = (ManagedIndexSchema)schema;
|
||||
zkVersion = managed.getSchemaZkVersion();
|
||||
if (refreshIfBelowVersion != -1 && zkVersion < refreshIfBelowVersion) {
|
||||
log.info("REFRESHING SCHEMA (refreshIfBelowVersion="+refreshIfBelowVersion+
|
||||
", currentVersion="+zkVersion+") before returning version!");
|
||||
ZkSolrResourceLoader zkSolrResourceLoader = (ZkSolrResourceLoader)getSolrCore().getResourceLoader();
|
||||
ZkIndexSchemaReader zkIndexSchemaReader = zkSolrResourceLoader.getZkIndexSchemaReader();
|
||||
managed = zkIndexSchemaReader.refreshSchemaFromZk(refreshIfBelowVersion);
|
||||
zkVersion = managed.getSchemaZkVersion();
|
||||
}
|
||||
}
|
||||
getSolrResponse().add("zkversion", zkVersion);
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema/solrqueryparser/defaultoperator
|
||||
*/
|
||||
public class SolrQueryParserDefaultOperatorResource extends BaseSolrResource implements GETable {
|
||||
private static final Logger log = LoggerFactory.getLogger(SolrQueryParserDefaultOperatorResource.class);
|
||||
|
||||
public SolrQueryParserDefaultOperatorResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
getSolrResponse().add(IndexSchema.DEFAULT_OPERATOR, getSchema().getQueryParserDefaultOperator());
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema/solrqueryparser
|
||||
*/
|
||||
public class SolrQueryParserResource extends BaseSolrResource implements GETable {
|
||||
private static final Logger log = LoggerFactory.getLogger(SolrQueryParserResource.class);
|
||||
|
||||
public SolrQueryParserResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
SimpleOrderedMap<Object> props = new SimpleOrderedMap<>();
|
||||
props.add(IndexSchema.DEFAULT_OPERATOR, getSchema().getQueryParserDefaultOperator());
|
||||
getSolrResponse().add(IndexSchema.SOLR_QUERY_PARSER, props);
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package org.apache.solr.rest.schema;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.rest.GETable;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.restlet.representation.Representation;
|
||||
import org.restlet.resource.ResourceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* This class responds to requests at /solr/(corename)/schema/uniquekey
|
||||
*/
|
||||
public class UniqueKeyFieldResource extends BaseSolrResource implements GETable {
|
||||
private static final Logger log = LoggerFactory.getLogger(UniqueKeyFieldResource.class);
|
||||
|
||||
public UniqueKeyFieldResource() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInit() throws ResourceException {
|
||||
super.doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Representation get() {
|
||||
try {
|
||||
getSolrResponse().add(IndexSchema.UNIQUE_KEY, getSchema().getUniqueKeyField().getName());
|
||||
} catch (Exception e) {
|
||||
getSolrResponse().setException(e);
|
||||
}
|
||||
handlePostExecution(log);
|
||||
|
||||
return new SolrOutputRepresentation();
|
||||
}
|
||||
}
|
|
@ -18,17 +18,26 @@ package org.apache.solr.schema;
|
|||
*/
|
||||
|
||||
|
||||
import org.apache.solr.cloud.ZkController;
|
||||
import org.apache.solr.cloud.ZkSolrResourceLoader;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.core.ConfigOverlay;
|
||||
import org.apache.solr.core.CoreDescriptor;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.core.SolrResourceLoader;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.rest.BaseSolrResource;
|
||||
import org.apache.solr.util.CommandOperation;
|
||||
import org.apache.zookeeper.KeeperException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -79,7 +88,7 @@ public class SchemaManager {
|
|||
* @param rdr The input as a Reader
|
||||
* @return Lis of errors . If the List is empty then the operation is successful.
|
||||
*/
|
||||
public List performOperations(Reader rdr) {
|
||||
public List performOperations(Reader rdr) throws Exception {
|
||||
List<CommandOperation> ops = null;
|
||||
try {
|
||||
ops = CommandOperation.parse(rdr);
|
||||
|
@ -102,13 +111,13 @@ public class SchemaManager {
|
|||
|
||||
}
|
||||
|
||||
private List doOperations(List<CommandOperation> operations){
|
||||
private List doOperations(List<CommandOperation> operations) throws InterruptedException, IOException, KeeperException {
|
||||
int timeout = req.getParams().getInt(BaseSolrResource.UPDATE_TIMEOUT_SECS, -1);
|
||||
long startTime = System.nanoTime();
|
||||
long endTime = timeout >0 ? System.nanoTime()+ (timeout * 1000*1000) : Long.MAX_VALUE;
|
||||
long endTime = timeout > 0 ? System.nanoTime() + (timeout * 1000 * 1000) : Long.MAX_VALUE;
|
||||
SolrCore core = req.getCore();
|
||||
for(;System.nanoTime() < endTime ;) {
|
||||
managedIndexSchema = (ManagedIndexSchema) core.getLatestSchema();
|
||||
for (; System.nanoTime() < endTime; ) {
|
||||
managedIndexSchema = getFreshManagedSchema();
|
||||
for (CommandOperation op : operations) {
|
||||
if (ADD_FIELD.equals(op.name) || ADD_DYNAMIC_FIELD.equals(op.name)) {
|
||||
applyAddField(op);
|
||||
|
@ -123,20 +132,51 @@ public class SchemaManager {
|
|||
}
|
||||
List errs = CommandOperation.captureErrors(operations);
|
||||
if (!errs.isEmpty()) return errs;
|
||||
SolrResourceLoader loader = req.getCore().getResourceLoader();
|
||||
if (loader instanceof ZkSolrResourceLoader) {
|
||||
|
||||
try {
|
||||
managedIndexSchema.persistManagedSchema(false);
|
||||
core.setLatestSchema(managedIndexSchema);
|
||||
waitForOtherReplicasToUpdate(timeout, startTime);
|
||||
return EMPTY_LIST;
|
||||
} catch (ManagedIndexSchema.SchemaChangedInZkException e) {
|
||||
String s = "Failed to update schema because schema is modified";
|
||||
log.warn(s, e);
|
||||
continue;
|
||||
} catch (Exception e){
|
||||
String s = "Exception persisting schema";
|
||||
log.warn(s, e);
|
||||
return singletonList(s + e.getMessage());
|
||||
StringWriter sw = new StringWriter();
|
||||
try {
|
||||
managedIndexSchema.persist(sw);
|
||||
} catch (IOException e) {
|
||||
log.info("race condition ");
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "unable to serialize schema");
|
||||
//unlikely
|
||||
}
|
||||
|
||||
try {
|
||||
ZkController.persistConfigResourceToZooKeeper(loader,
|
||||
managedIndexSchema.getSchemaZkVersion(),
|
||||
managedIndexSchema.getResourceName(),
|
||||
sw.toString().getBytes(StandardCharsets.UTF_8),
|
||||
true);
|
||||
return EMPTY_LIST;
|
||||
} catch (ZkController.ResourceModifiedInZkException e) {
|
||||
log.info("Race condition schema modified by another node");
|
||||
continue;
|
||||
} catch (Exception e) {
|
||||
String s = "Exception persisting schema";
|
||||
log.warn(s, e);
|
||||
return singletonList(s + e.getMessage());
|
||||
}
|
||||
|
||||
}else {
|
||||
|
||||
try {
|
||||
//only for non cloud stuff
|
||||
managedIndexSchema.persistManagedSchema(false);
|
||||
core.setLatestSchema(managedIndexSchema);
|
||||
waitForOtherReplicasToUpdate(timeout, startTime);
|
||||
return EMPTY_LIST;
|
||||
} catch (ManagedIndexSchema.SchemaChangedInZkException e) {
|
||||
String s = "Failed to update schema because schema is modified";
|
||||
log.warn(s, e);
|
||||
continue;
|
||||
} catch (Exception e) {
|
||||
String s = "Exception persisting schema";
|
||||
log.warn(s, e);
|
||||
return singletonList(s + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,4 +271,28 @@ public class SchemaManager {
|
|||
return true;
|
||||
}
|
||||
|
||||
public ManagedIndexSchema getFreshManagedSchema() throws IOException, KeeperException, InterruptedException {
|
||||
SolrResourceLoader resourceLoader = req.getCore().getResourceLoader();
|
||||
if (resourceLoader instanceof ZkSolrResourceLoader) {
|
||||
ZkSolrResourceLoader loader = (ZkSolrResourceLoader) resourceLoader;
|
||||
InputStream in = resourceLoader.openResource(req.getSchema().getResourceName());
|
||||
if (in instanceof ZkSolrResourceLoader.ZkByteArrayInputStream) {
|
||||
int version = ((ZkSolrResourceLoader.ZkByteArrayInputStream) in).getStat().getVersion();
|
||||
log.info("managed schema loaded . version : {} ", version);
|
||||
return new ManagedIndexSchema(req.getCore().getSolrConfig(),
|
||||
req.getSchema().getResourceName() ,new InputSource(in),
|
||||
true,
|
||||
req.getSchema().getResourceName(),
|
||||
version,new Object());
|
||||
}else {
|
||||
return (ManagedIndexSchema) req.getCore().getLatestSchema();
|
||||
}
|
||||
|
||||
} else {
|
||||
return (ManagedIndexSchema) req.getCore().getLatestSchema();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,26 +343,31 @@ public class SolrDispatchFilter extends BaseSolrFilter {
|
|||
// get or create/cache the parser for the core
|
||||
SolrRequestParsers parser = config.getRequestParsers();
|
||||
|
||||
// Handle /schema/* and /config/* paths via Restlet
|
||||
if( path.equals("/schema") || path.startsWith("/schema/")
|
||||
/*|| path.equals("/config") || path.startsWith("/config/")*/) {
|
||||
solrReq = parser.parse(core, path, req);
|
||||
SolrRequestInfo.setRequestInfo(new SolrRequestInfo(solrReq, new SolrQueryResponse()));
|
||||
if( path.equals(req.getServletPath()) ) {
|
||||
// avoid endless loop - pass through to Restlet via webapp
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
// forward rewritten URI (without path prefix and core/collection name) to Restlet
|
||||
req.getRequestDispatcher(path).forward(request, response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine the handler from the url path if not set
|
||||
// (we might already have selected the cores handler)
|
||||
if( handler == null && path.length() > 1 ) { // don't match "" or "/" as valid path
|
||||
handler = core.getRequestHandler( path );
|
||||
|
||||
if(handler == null){
|
||||
//may be a restlet path
|
||||
// Handle /schema/* paths via Restlet
|
||||
if( path.equals("/schema") || path.startsWith("/schema/")) {
|
||||
solrReq = parser.parse(core, path, req);
|
||||
SolrRequestInfo.setRequestInfo(new SolrRequestInfo(solrReq, new SolrQueryResponse()));
|
||||
if( path.equals(req.getServletPath()) ) {
|
||||
// avoid endless loop - pass through to Restlet via webapp
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
// forward rewritten URI (without path prefix and core/collection name) to Restlet
|
||||
req.getRequestDispatcher(path).forward(request, response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
// no handler yet but allowed to handle select; let's check
|
||||
|
||||
if( handler == null && parser.isHandleSelect() ) {
|
||||
if( "/select".equals( path ) || "/select/".equals( path ) ) {
|
||||
solrReq = parser.parse( core, path, req );
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.apache.solr.common.util.ContentStream;
|
|||
import org.apache.solr.common.util.ContentStreamBase;
|
||||
import org.apache.solr.common.util.FastInputStream;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
import org.apache.solr.core.RequestHandlers;
|
||||
import org.apache.solr.core.SolrConfig;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
|
@ -149,7 +150,7 @@ public class SolrRequestParsers
|
|||
|
||||
// Handlers and login will want to know the path. If it contains a ':'
|
||||
// the handler could use it for RESTful URLs
|
||||
sreq.getContext().put( "path", path );
|
||||
sreq.getContext().put( "path", RequestHandlers.normalize(path) );
|
||||
sreq.getContext().put("httpMethod", req.getMethod());
|
||||
|
||||
if(addHttpRequestToContext) {
|
||||
|
|
|
@ -106,13 +106,15 @@ public class MinimalSchemaTest extends SolrTestCaseJ4 {
|
|||
for (String handler : handlerNames) {
|
||||
try {
|
||||
|
||||
if (handler.startsWith("/update")) {
|
||||
|
||||
if (handler.startsWith("/update") ||
|
||||
handler.startsWith("/admin") ||
|
||||
handler.startsWith("/schema") ||
|
||||
handler.startsWith("/config") ||
|
||||
handler.startsWith("/mlt")
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (handler.startsWith("/mlt")) {
|
||||
continue;
|
||||
}
|
||||
if(handler.equals("/admin/ping")) continue;
|
||||
|
||||
assertQ("failure w/handler: '" + handler + "'",
|
||||
req("qt", handler,
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
|
|||
import org.apache.solr.common.cloud.ZkStateReader;
|
||||
import org.apache.solr.util.RESTfulServerProvider;
|
||||
import org.apache.solr.util.RestTestHarness;
|
||||
import org.junit.BeforeClass;
|
||||
import org.noggit.JSONParser;
|
||||
import org.noggit.ObjectBuilder;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -48,6 +49,16 @@ public class TestBulkSchemaConcurrent extends AbstractFullDistribZkTestBase {
|
|||
static final Logger log = LoggerFactory.getLogger(TestBulkSchemaConcurrent.class);
|
||||
private List<RestTestHarness> restTestHarnesses = new ArrayList<>();
|
||||
|
||||
@BeforeClass
|
||||
public static void initSysProperties() {
|
||||
System.setProperty("managed.schema.mutable", "true");
|
||||
System.setProperty("enable.update.log", "true");
|
||||
}
|
||||
|
||||
protected String getCloudSolrConfig() {
|
||||
return "solrconfig-managed-schema.xml";
|
||||
}
|
||||
|
||||
private void setupHarnesses() {
|
||||
for (final SolrServer client : clients) {
|
||||
RestTestHarness harness = new RestTestHarness(new RESTfulServerProvider() {
|
||||
|
@ -101,7 +112,7 @@ public class TestBulkSchemaConcurrent extends AbstractFullDistribZkTestBase {
|
|||
|
||||
}
|
||||
|
||||
assertTrue(success);
|
||||
assertTrue(collectErrors.toString(), success);
|
||||
|
||||
|
||||
}
|
||||
|
@ -138,7 +149,7 @@ public class TestBulkSchemaConcurrent extends AbstractFullDistribZkTestBase {
|
|||
|
||||
|
||||
RestTestHarness publisher = restTestHarnesses.get(r.nextInt(restTestHarnesses.size()));
|
||||
payload = payload.replace("replaceFieldA1", aField);
|
||||
payload = payload.replace("replaceFieldA", aField);
|
||||
|
||||
payload = payload.replace("replaceDynamicField", dynamicFldName);
|
||||
payload = payload.replace("dynamicFieldLol","lol"+seed);
|
||||
|
|
Loading…
Reference in New Issue