/*
* Licensed to Crate under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership. Crate 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.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial
* agreement.
*/
package io.crate.http.netty;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.Singleton;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.http.netty3.Netty3HttpServerTransport;
import org.elasticsearch.threadpool.ThreadPool;
import org.jboss.netty.channel.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
@Singleton
public class CrateNettyHttpServerTransport extends Netty3HttpServerTransport {
/**
* A data structure for items that can be added to the channel pipeline of the HTTP transport.
*/
public static class ChannelPipelineItem {
final String base;
final String name;
final Supplier<ChannelUpstreamHandler> handlerFactory;
/**
* @param base the name of the existing handler in the pipeline before/after which the new handler should be added
* @param name the name of the new handler that should be added to the pipeline
* @param handlerFactory a supplier that provides a new instance of the handler
*/
public ChannelPipelineItem(String base, String name, Supplier<ChannelUpstreamHandler> handlerFactory) {
this.base = base;
this.name = name;
this.handlerFactory = handlerFactory;
}
}
private CopyOnWriteArrayList<ChannelPipelineItem> addBeforeList = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<ChannelPipelineItem> addAfterList = new CopyOnWriteArrayList<>();
@Inject
public CrateNettyHttpServerTransport(Settings settings,
NetworkService networkService,
BigArrays bigArrays,
ThreadPool threadPool) {
super(settings, networkService, bigArrays, threadPool);
}
@Override
public ChannelPipelineFactory configureServerChannelPipelineFactory() {
return new CrateHttpChannelPipelineFactory(this, detailedErrorsEnabled, threadPool);
}
public void addBefore(ChannelPipelineItem item) {
addBeforeList.add(item);
}
public void addAfter(ChannelPipelineItem item) {
addAfterList.add(item);
}
protected class CrateHttpChannelPipelineFactory extends HttpChannelPipelineFactory {
CrateHttpChannelPipelineFactory(CrateNettyHttpServerTransport transport,
boolean detailedErrorsEnabled,
ThreadPool threadPool) {
super(transport, detailedErrorsEnabled, threadPool.getThreadContext());
}
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = super.getPipeline();
for (ChannelPipelineItem item : addBeforeList) {
pipeline.addBefore(item.base, item.name, item.handlerFactory.get());
}
for (ChannelPipelineItem item : addAfterList) {
pipeline.addAfter(item.base, item.name, item.handlerFactory.get());
}
return pipeline;
}
}
}