/*
* Copyright 2009 Red Hat, Inc.
*
* Red Hat 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.krakenapps.proxy.impl;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Invalidate;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Validate;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.socket.ClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.krakenapps.proxy.ForwardProxy;
import org.krakenapps.proxy.ForwardRoute;
@Component(name = "forward-proxy")
@Provides
public class ForwardProxyImpl implements ForwardProxy {
private ExecutorService executor;
private ConcurrentMap<String, ForwardChannel> routeMap;
@Validate
public void start() {
executor = Executors.newCachedThreadPool();
routeMap = new ConcurrentHashMap<String, ForwardChannel>();
}
@Invalidate
public void stop() {
if (routeMap != null) {
// stop all proxies
for (ForwardChannel channel : routeMap.values())
channel.server.close();
routeMap.clear();
}
if (executor != null) {
executor.shutdownNow();
executor = null;
}
}
@Override
public Collection<String> getRouteNames() {
if (routeMap != null)
return new ArrayList<String>(routeMap.keySet());
return null;
}
@Override
public ForwardRoute getRoute(String name) {
if (routeMap == null)
return null;
ForwardChannel channel = routeMap.get(name);
if (channel != null)
return channel.route;
return null;
}
@Override
public void addRoute(String name, ForwardRoute route) {
ServerBootstrap sb = new ServerBootstrap(new NioServerSocketChannelFactory(executor, executor));
ClientSocketChannelFactory cf = new NioClientSocketChannelFactory(executor, executor);
String remoteHost = route.getRemote().getHostName();
int remotePort = route.getRemote().getPort();
int localPort = route.getLocal().getPort();
sb.setPipelineFactory(new ForwardProxyPipelineFactory(cf, remoteHost, remotePort));
Channel server = sb.bind(new InetSocketAddress(localPort));
routeMap.put(name, new ForwardChannel(server, route));
}
@Override
public void removeRoute(String name) {
if (routeMap.containsKey(name)) {
ForwardChannel channel = routeMap.remove(name);
if (channel != null)
channel.server.close();
}
}
static class ForwardChannel {
public ForwardChannel(Channel server, ForwardRoute route) {
this.server = server;
this.route = route;
}
private ForwardRoute route;
private Channel server;
}
}