JENA-1435: Place ServiceDispatchRegistry in ServletContext
Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/be57485f Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/be57485f Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/be57485f Branch: refs/heads/master Commit: be57485f614b0964e0d45beda53f3d4c8d81aeee Parents: c2b0973 Author: Andy Seaborne <[email protected]> Authored: Fri Nov 24 17:51:11 2017 +0000 Committer: Andy Seaborne <[email protected]> Committed: Mon Dec 11 14:56:08 2017 +0000 ---------------------------------------------------------------------- .../fuseki/server/DataAccessPointRegistry.java | 3 +- .../fuseki/server/FusekiServerListener.java | 12 ++- .../apache/jena/fuseki/server/Operation.java | 4 +- .../jena/fuseki/servlets/ActionService.java | 2 +- .../apache/jena/fuseki/servlets/Dispatch.java | 62 ----------- .../apache/jena/fuseki/servlets/HttpAction.java | 11 +- .../servlets/ServiceDispatchRegistry.java | 108 +++++++++++++++++++ .../jena/fuseki/servlets/ServiceRouter.java | 2 +- .../jena/fuseki/embedded/FusekiServer.java | 13 +++ 9 files changed, 144 insertions(+), 73 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java index 5e63132..965ed0f 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java @@ -54,11 +54,10 @@ public class DataAccessPointRegistry extends Registry<String, DataAccessPoint> // The server DataAccessPointRegistry is held in the ServletContext for the server. private static final String attrNameRegistry = "jena-fuseki:dataAccessPointRegistry" ; - // Policy for the location of the server-wide DataAccessPointRegistry public static DataAccessPointRegistry get(ServletContext cxt) { DataAccessPointRegistry registry = (DataAccessPointRegistry)cxt.getAttribute(attrNameRegistry) ; if ( registry == null ) - Log.warn(DataAccessPointRegistry.class, "No registry for ServletContext") ; + Log.warn(DataAccessPointRegistry.class, "No data access point registry for ServletContext") ; return registry ; } http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java index 231a0fa..ce8bb10 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java @@ -24,6 +24,7 @@ import javax.servlet.ServletContextListener ; import org.apache.jena.fuseki.Fuseki ; import org.apache.jena.fuseki.FusekiException; +import org.apache.jena.fuseki.servlets.ServiceDispatchRegistry; import org.apache.jena.tdb.StoreConnection ; /** Setup configuration. @@ -66,8 +67,11 @@ public class FusekiServerListener implements ServletContextListener { return ; initialized = true ; - DataAccessPointRegistry registry = new DataAccessPointRegistry() ; - DataAccessPointRegistry.set(servletContext, registry); + ServiceDispatchRegistry serviceDispatchRegistry = new ServiceDispatchRegistry(true); + ServiceDispatchRegistry.set(servletContext, serviceDispatchRegistry); + DataAccessPointRegistry dataAccessPointRegistry = new DataAccessPointRegistry() ; + DataAccessPointRegistry.set(servletContext, dataAccessPointRegistry); + try { FusekiSystem.formatBaseArea() ; @@ -85,7 +89,7 @@ public class FusekiServerListener implements ServletContextListener { } if ( initialSetup != null ) { - FusekiSystem.initializeDataAccessPoints(registry, + FusekiSystem.initializeDataAccessPoints(dataAccessPointRegistry, initialSetup, FusekiSystem.dirConfiguration.toString()) ; } else { Fuseki.serverLog.error("No configuration") ; @@ -95,7 +99,7 @@ public class FusekiServerListener implements ServletContextListener { Fuseki.serverLog.error("Exception in initialization: {}", th.getMessage()) ; throw th ; } - FusekiInfo.info(initialSetup, registry); + FusekiInfo.info(initialSetup, dataAccessPointRegistry); } } http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java index 1a136e4..06331df 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java @@ -18,10 +18,10 @@ package org.apache.jena.fuseki.server; -import org.apache.jena.fuseki.servlets.Dispatch; +import org.apache.jena.fuseki.servlets.ServiceDispatchRegistry; /** - * Operations are symbol to look up in the {@link Dispatch#operationToHandler} map. The name + * Operations are symbol to look up in the {@link ServiceDispatchRegistry#operationToHandler} map. The name * of an {@code Operation} is not related to the service name used to invoke the operation * which is determined by the {@link Endpoint}. */ http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java index b026574..cc247ba 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java @@ -97,7 +97,7 @@ public abstract class ActionService extends ActionBase { ServletOps.errorBadRequest(format("dataset=%s", dataAccessPoint.getName())); } - ActionService handler = Dispatch.operationToHandler.get(operation); + ActionService handler = action.getServiceDispatchRegistry().findHandler(operation); if ( handler == null ) ServletOps.errorBadRequest(format("dataset=%s: op=%s", dataAccessPoint.getName(), operation.getName())); // XXX -- replace action.setEndpoint http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java deleted file mode 100644 index 2d66909..0000000 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java +++ /dev/null @@ -1,62 +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.jena.fuseki.servlets; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.jena.fuseki.server.DataService; -import org.apache.jena.fuseki.server.Operation; -import org.apache.jena.riot.WebContent; - -/** The global mapping of content-type to Operation. */ - -public class Dispatch { - /** Map ContentType (lowercase, no charset) to the {@code Operation} for handling it. */ - public static Map<String, Operation> contentTypeToOperation = new ConcurrentHashMap<>(); - static { - contentTypeToOperation.put(WebContent.contentTypeSPARQLQuery, Operation.Query); - contentTypeToOperation.put(WebContent.contentTypeSPARQLUpdate, Operation.Update); - } - - /** Map {@link Operation} to servlet handler. - * {@code Operation}s are the internal symbol identifying an operation, - * not the name used in the configuration file, - * which is mapped by {@link DataService#getEndpoint(String)}. - */ - public static Map<Operation, ActionService> operationToHandler = new ConcurrentHashMap<>(); - - public static final ActionService queryServlet = new SPARQL_QueryDataset() ; - public static final ActionService updateServlet = new SPARQL_Update() ; - public static final ActionService uploadServlet = new SPARQL_Upload() ; - public static final ActionService gspServlet_R = new SPARQL_GSP_R() ; - public static final ActionService gspServlet_RW = new SPARQL_GSP_RW() ; - public static final ActionService restQuads_R = new REST_Quads_R() ; - public static final ActionService restQuads_RW = new REST_Quads_RW() ; - - static { - operationToHandler.put(Operation.Query, queryServlet); - operationToHandler.put(Operation.Update, updateServlet); - operationToHandler.put(Operation.Upload, uploadServlet); - operationToHandler.put(Operation.GSP_R, gspServlet_R); - operationToHandler.put(Operation.GSP_RW, gspServlet_RW); - operationToHandler.put(Operation.Quads_R, restQuads_R); - operationToHandler.put(Operation.Quads_RW, restQuads_RW); - } -} http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java index 55e32c2..9c10db1 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java @@ -91,7 +91,8 @@ public class HttpAction public HttpServletResponseTracker response ; private final String actionURI ; private final String contextPath ; - // Currently, global. + + private final ServiceDispatchRegistry serviceDispatchRegistry; private final DataAccessPointRegistry dataAccessPointRegistry ; /** @@ -113,6 +114,7 @@ public class HttpAction this.verbose = verbose ; this.contextPath = request.getServletContext().getContextPath() ; this.actionURI = ActionLib.actionURI(request) ; + this.serviceDispatchRegistry = ServiceDispatchRegistry.get(request.getServletContext()) ; this.dataAccessPointRegistry = DataAccessPointRegistry.get(request.getServletContext()) ; } @@ -227,6 +229,13 @@ public class HttpAction } /** + * Get the ServiceRegistry for this action + */ + public ServiceDispatchRegistry getServiceDispatchRegistry() { + return serviceDispatchRegistry ; + } + + /** * Get the DataAccessPointRegistry for this action */ public DataAccessPointRegistry getDataAccessPointRegistry() { http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java new file mode 100644 index 0000000..3d7303a --- /dev/null +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java @@ -0,0 +1,108 @@ +/* + * 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.jena.fuseki.servlets; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.ServletContext; + +import org.apache.jena.atlas.logging.Log; +import org.apache.jena.fuseki.server.DataService; +import org.apache.jena.fuseki.server.Operation; +import org.apache.jena.riot.WebContent; + +/** + * The global mapping of content-type to Operation and operation to implementation. + */ + +public class ServiceDispatchRegistry { + + public static final ActionService queryServlet = new SPARQL_QueryDataset() ; + public static final ActionService updateServlet = new SPARQL_Update() ; + public static final ActionService uploadServlet = new SPARQL_Upload() ; + public static final ActionService gspServlet_R = new SPARQL_GSP_R() ; + public static final ActionService gspServlet_RW = new SPARQL_GSP_RW() ; + public static final ActionService restQuads_R = new REST_Quads_R() ; + public static final ActionService restQuads_RW = new REST_Quads_RW() ; + + /** Map ContentType (lowercase, no charset) to the {@code Operation} for handling it. */ + private final Map<String, Operation> contentTypeToOperation = new ConcurrentHashMap<>(); + + /** Map {@link Operation} to servlet handler. + * {@code Operation}s are the internal symbol identifying an operation, + * not the name used in the configuration file, + * which is mapped by {@link DataService#getEndpoint(String)}. + */ + private final Map<Operation, ActionService> operationToHandler = new ConcurrentHashMap<>(); + + public ServiceDispatchRegistry(boolean includeStdConfig) { + if ( includeStdConfig ) { + register(Operation.Query, WebContent.contentTypeSPARQLQuery, queryServlet); + register(Operation.Update, WebContent.contentTypeSPARQLUpdate, updateServlet); + register(Operation.Upload, null, uploadServlet); + register(Operation.GSP_R, null, gspServlet_R); + register(Operation.GSP_RW, null, gspServlet_RW); + register(Operation.Quads_R, null, restQuads_R); + register(Operation.Quads_RW, null, restQuads_RW); + } + } + + /** Find the {@link Operation} for a {@code Content-Type}, or return null. */ + public Operation findOperation(String contentType) { + if ( contentType == null ) + return null; + return contentTypeToOperation.get(contentType); + } + + /** Find the {@link ActionService} implementation for an {@link Operation}, or return null..*/ + public ActionService findHandler(Operation operation) { + if ( operation == null ) + return null; + return operationToHandler.get(operation); + } + + /** + * Register a new {@link Operation}, with its {@code Content-Type} (may be null, + * meaning no dispatch by content type), and the implementation handler. + */ + public void register(Operation operation, String contentType, ActionService action) { + Objects.requireNonNull(operation); + Objects.requireNonNull(action); + if ( contentType != null ) + contentTypeToOperation.put(contentType, operation); + operationToHandler.put(operation, action); + } + + // The server DataAccessPointRegistry is held in the ServletContext for the server. + + private static final String attrServiceRegistry = "jena-fuseki:ServiceDispatchRegistry" ; + + public static ServiceDispatchRegistry get(ServletContext servletContext) { + ServiceDispatchRegistry registry = (ServiceDispatchRegistry)servletContext.getAttribute(attrServiceRegistry) ; + if ( registry == null ) + Log.warn(ServiceDispatchRegistry.class, "No service registry for ServletContext") ; + return registry ; + } + + public static void set(ServletContext cxt, ServiceDispatchRegistry registry) { + cxt.setAttribute(attrServiceRegistry, registry) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java index 4f4a2df..cb3cf1b 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java @@ -247,7 +247,7 @@ public abstract class ServiceRouter extends ActionService { // This does no have the ";charset=" String ct = request.getContentType(); if ( ct != null ) { - Operation operation = Dispatch.contentTypeToOperation.get(ct); + Operation operation = action.getServiceDispatchRegistry().findOperation(ct); if ( operation != null ) return operation; } http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java b/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java index 6ac739f..ae38265 100644 --- a/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java +++ b/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java @@ -37,6 +37,7 @@ import org.apache.jena.fuseki.mgt.ActionStats ; import org.apache.jena.fuseki.server.DataAccessPoint ; import org.apache.jena.fuseki.server.DataAccessPointRegistry ; import org.apache.jena.fuseki.server.DataService ; +import org.apache.jena.fuseki.servlets.ServiceDispatchRegistry; import org.apache.jena.fuseki.servlets.FusekiFilter ; import org.apache.jena.query.Dataset ; import org.apache.jena.riot.WebContent; @@ -136,6 +137,13 @@ public class FusekiServer { return DataAccessPointRegistry.get(getServletContext()) ; } + /** Get the {@link DataAccessPointRegistry}. + * This method is intended for inspecting the registry. + */ + public ServiceDispatchRegistry getServiceDispatchRegistry() { + return ServiceDispatchRegistry.get(getServletContext()) ; + } + /** Start the server - the server continues to run after this call returns. * To synchronise with the server stopping, call {@link #join}. */ @@ -283,17 +291,22 @@ public class FusekiServer { /** Build a server according to the current description */ public FusekiServer build() { + ServiceDispatchRegistry serviceRegistry = new ServiceDispatchRegistry(true); DataAccessPointRegistry registry = new DataAccessPointRegistry() ; + map.forEach((name, dSrv) -> { DataAccessPoint dap = new DataAccessPoint(name, dSrv) ; registry.put(name, dap) ; }) ; ServletContextHandler handler = buildServletContext(contextPath, registry) ; + + ServiceDispatchRegistry.set(handler.getServletContext(), serviceRegistry); setMimeTypes(handler); servlets(handler); DataAccessPointRegistry.set(handler.getServletContext(), registry) ; + Server server = jettyServer(port, loopback) ; server.setHandler(handler); return new FusekiServer(port, server) ;
