All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.apphosting.runtime.jetty94.AppVersionHandlerMap Maven / Gradle / Ivy

/*
 * Copyright 2021 Google LLC
 *
 * Licensed 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
 *
 *     https://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 com.google.apphosting.runtime.jetty94;

import com.google.apphosting.base.AppVersionKey;
import com.google.apphosting.runtime.AppVersion;
import com.google.apphosting.runtime.SessionStore;
import com.google.apphosting.runtime.SessionStoreFactory;
import com.google.apphosting.runtime.jetty9.JettyConstants;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandlerContainer;

/**
 * {@code AppVersionHandlerMap} is a {@code HandlerContainer} that identifies each child {@code
 * Handler} with a particular {@code AppVersionKey}.
 *
 * 

In order to identify which application version each request should be sent to, this class * assumes that an attribute will be set on the {@code HttpServletRequest} with a value of the * {@code AppVersionKey} that should be used. * */ public class AppVersionHandlerMap extends AbstractHandlerContainer { private final AppVersionHandlerFactory appVersionHandlerFactory; private final Map appVersionMap; private final Map handlerMap; public AppVersionHandlerMap(AppVersionHandlerFactory appVersionHandlerFactory) { this.appVersionHandlerFactory = appVersionHandlerFactory; this.appVersionMap = new HashMap<>(); this.handlerMap = new HashMap<>(); } public void addAppVersion(AppVersion appVersion) { appVersionMap.put(appVersion.getKey(), appVersion); } public void removeAppVersion(AppVersionKey appVersionKey) { appVersionMap.remove(appVersionKey); } /** * Sets the {@link SessionStoreFactory} that will be used for generating the list of {@link * SessionStore SessionStores} that will be passed to {@link SessionManager} for apps for which * sessions are enabled. This setter is currently used only for testing purposes. Normally the * default factory is sufficient. */ public void setSessionStoreFactory(SessionStoreFactory factory) { // No op with the new Jetty Session management. } /** * Returns the {@code Handler} that will handle requests for the specified application version. */ public synchronized Handler getHandler(AppVersionKey appVersionKey) throws ServletException { Handler handler = handlerMap.get(appVersionKey); if (handler == null) { AppVersion appVersion = appVersionMap.get(appVersionKey); if (appVersion != null) { handler = appVersionHandlerFactory.createHandler(appVersion); handlerMap.put(appVersionKey, handler); } } return handler; } /** * Forward the specified request on to the {@link Handler} associated with its application * version. */ @Override public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { AppVersionKey appVersionKey = (AppVersionKey) request.getAttribute(JettyConstants.APP_VERSION_KEY_REQUEST_ATTR); if (appVersionKey == null) { throw new ServletException("Request did not provide an application version"); } Handler handler = getHandler(appVersionKey); if (handler == null) { // If we throw an exception here it'll get caught, logged, and // turned into a 500, which is definitely not what we want. // Instead, we check for this before calling handle(), so this // should never happen. throw new ServletException("Unknown application: " + appVersionKey); } try { handler.handle(target, baseRequest, request, response); } catch (ServletException | IOException ex) { throw ex; } catch (Exception ex) { throw new ServletException(ex); } } @Override protected void doStart() throws Exception { for (Handler handler : getHandlers()) { handler.start(); } super.doStart(); } @Override protected void doStop() throws Exception { super.doStop(); for (Handler handler : getHandlers()) { handler.stop(); } } @Override public void setServer(Server server) { super.setServer(server); for (Handler handler : getHandlers()) { handler.setServer(server); } } @Override public Handler[] getHandlers() { return handlerMap.values().toArray(new Handler[0]); } /** * Not supported. * * @throws UnsupportedOperationException */ public void setHandlers(Handler[] handlers) { throw new UnsupportedOperationException(); } /** * Not supported. * * @throws UnsupportedOperationException */ public void addHandler(Handler handler) { throw new UnsupportedOperationException(); } /** * Not supported. * * @throws UnsupportedOperationException */ public void removeHandler(Handler handler) { throw new UnsupportedOperationException(); } @Override protected void expandChildren(List list, Class byClass) { for (Handler handler : getHandlers()) { expandHandler(handler, list, byClass); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy