/*
* 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();
}
}
}