package org.apache.solr.rest;
/*
* 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.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.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;
import org.restlet.routing.Router;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
/**
* Restlet servlet handling /<context>/<collection>/schema/* URL paths
*/
public class SolrSchemaRestApi extends Application {
public static final Logger log = LoggerFactory.getLogger(SolrSchemaRestApi.class);
public static final String FIELDS_PATH = "/" + IndexSchema.FIELDS;
public static final String DYNAMIC_FIELDS = IndexSchema.DYNAMIC_FIELDS.toLowerCase(Locale.ROOT);
public static final String DYNAMIC_FIELDS_PATH = "/" + DYNAMIC_FIELDS;
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;
/**
* Returns reserved endpoints under /schema
*/
public static Set<String> getReservedEndpoints() {
Set<String> reservedEndpoints = new HashSet<>();
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);
return Collections.unmodifiableSet(reservedEndpoints);
}
private Router router;
public SolrSchemaRestApi() {
router = new Router(getContext());
}
@Override
public void stop() throws Exception {
if (null != router) {
router.stop();
}
}
/**
* Bind URL paths to the appropriate ServerResource subclass.
*/
@Override
public synchronized Restlet createInboundRoot() {
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);
router.attach(FIELDS_PATH + NAME_SEGMENT, FieldResource.class);
router.attach(DYNAMIC_FIELDS_PATH, DynamicFieldCollectionResource.class);
// Allow a trailing slash on collection requests
router.attach(DYNAMIC_FIELDS_PATH + "/", DynamicFieldCollectionResource.class);
router.attach(DYNAMIC_FIELDS_PATH + NAME_SEGMENT, DynamicFieldResource.class);
router.attach(FIELDTYPES_PATH, FieldTypeCollectionResource.class);
// Allow a trailing slash on collection requests
router.attach(FIELDTYPES_PATH + "/", FieldTypeCollectionResource.class);
router.attach(FIELDTYPES_PATH + NAME_SEGMENT, FieldTypeResource.class);
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.attachDefault(RestManager.ManagedEndpoint.class);
// attach all the dynamically registered schema resources
RestManager.getRestManager(SolrRequestInfo.getRequestInfo())
.attachManagedResources(RestManager.SCHEMA_BASE_PATH, router);
log.info("createInboundRoot complete for /schema");
return router;
}
}