/*
 * Copyright 2019 Red Hat, Inc.
 *
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  and Apache License v2.0 which accompanies this distribution.
 *
 *  The Eclipse Public License is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  The Apache License v2.0 is available at
 *  http://www.opensource.org/licenses/apache2.0.php
 *
 *  You may elect to redistribute this code under either of these licenses.
 */
package io.vertx.ext.web.handler.impl;

import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.MultiTenantHandler;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

Author:Paulo Lopes
/** * @author <a href="http://pmlopes@gmail.com">Paulo Lopes</a> */
public class MultiTenantHandlerImpl implements MultiTenantHandler { private final Map<String, Handler<RoutingContext>> handlerMap = new ConcurrentHashMap<>(); private final Function<RoutingContext, String> tenantExtractor; private final String contextKey; private Handler<RoutingContext> defaultHandler; public MultiTenantHandlerImpl(Function<RoutingContext, String> tenantExtractor, String contextKey) { this.tenantExtractor = Objects.requireNonNull(tenantExtractor); this.contextKey = Objects.requireNonNull(contextKey); } @Override public MultiTenantHandler addTenantHandler(String tenant, Handler<RoutingContext> handler) { Objects.requireNonNull(tenant); Objects.requireNonNull(handler); if (handlerMap.put(tenant, handler) != null) { throw new IllegalStateException("tenant '" + tenant + "' already present"); } return this; } @Override public MultiTenantHandler removeTenant(String tenant) { Objects.requireNonNull(tenant); handlerMap.remove(tenant); return this; } @Override public MultiTenantHandler addDefaultHandler(Handler<RoutingContext> handler) { Objects.requireNonNull(handler); this.defaultHandler = handler; return this; } @Override public void handle(RoutingContext ctx) { final String tenant = tenantExtractor.apply(ctx); final Handler<RoutingContext> handler = tenant == null ? defaultHandler : handlerMap.getOrDefault(tenant, defaultHandler); if (handler != null) { // there's a handler for this tenant and the name is default it we're // falling back to the default handler ctx.put(contextKey, handler == defaultHandler ? "default" : tenant); // continue as usual handler.handle(ctx); } else { // no handler found, this handle is not applicable // continue with the chain ctx.next(); } } }