/*
* Copyright 2012-2015, the original author or authors.
*
* 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
*
* 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 com.flipkart.phantom.runtime.impl.server.netty;
import com.flipkart.phantom.runtime.impl.server.AbstractNetworkServer;
import org.jboss.netty.bootstrap.Bootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.ChannelGroupFuture;
import org.springframework.util.Assert;
import java.util.HashMap;
import java.util.Map;
/**
* <code>AbstractNettyNetworkServer</code> is a sub-type of {@link AbstractNetworkServer} that uses {@link http://netty.io/}
* for creating NetworkServerS for various {@link TransmissionProtocol}
*
* @author Regunath B
* @version 1.0, 14 Mar 2013
*/
public abstract class AbstractNettyNetworkServer extends AbstractNetworkServer {
/** The default channel group*/
protected ChannelGroup defaultChannelGroup;
/** The Netty Bootstrap instance*/
protected Bootstrap serverBootstrap;
/** The Netty ChannelPipelineFactory instance*/
protected ChannelHandlerPipelineFactory pipelineFactory;
/** Map of Netty Bootstrap options*/
private Map<String,Object> bootstrapOptions = new HashMap<String,Object>();
/** No args constructor*/
public AbstractNettyNetworkServer() {
}
/**
* Interface method implementation. Checks if all manadatory properties have been set
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.pipelineFactory, "The 'pipelineFactory' may not be null");
this.serverBootstrap = this.createServerBootstrap();
this.serverBootstrap.setPipelineFactory(this.pipelineFactory);
this.serverBootstrap.setOptions(this.bootstrapOptions);
// call the super class implementation to start up this server
super.afterPropertiesSet();
}
/**
* Overriden superclass method. Creates a new Server Channel and adds it to the default channel group
* @see com.flipkart.phantom.runtime.impl.server.AbstractNetworkServer#doStartServer()
*/
protected void doStartServer() throws RuntimeException {
this.defaultChannelGroup.add(createChannel());
}
/**
* Overriden superclass method. Closes all channels registered with the default channel group, the pipleline factory and the serverbootstrap
* @see com.flipkart.phantom.runtime.impl.server.AbstractNetworkServer#doStopServer()
*/
protected void doStopServer() throws RuntimeException {
// close all channels registered with the default channel group
ChannelGroupFuture future = this.defaultChannelGroup.close();
future.awaitUninterruptibly();
// close the pipleline factory and instruct the serverbootstrap to release external resources
this.pipelineFactory.close();
this.serverBootstrap.releaseExternalResources();
}
/**
* Delegated method to concrete implementations to create the appropriate Netty Bootstrap instance
* @return the transmission protocol specific Bootstrap instance
*/
protected abstract Bootstrap createServerBootstrap() throws RuntimeException ;
/**
* Delegated method to concrete implementations to create the appropriate Netty Channel
*/
protected abstract Channel createChannel() throws RuntimeException;
/** Start Getter/Setter methods */
public Bootstrap getServerBootstrap() {
return this.serverBootstrap;
}
public ChannelHandlerPipelineFactory getPipelineFactory() {
return this.pipelineFactory;
}
public void setPipelineFactory(ChannelHandlerPipelineFactory pipelineFactory) {
this.pipelineFactory = pipelineFactory;
}
public Map<String, Object> getBootstrapOptions() {
return this.bootstrapOptions;
}
public void setBootstrapOptions(Map<String, Object> bootstrapOptions) {
this.bootstrapOptions = bootstrapOptions;
}
public ChannelGroup getDefaultChannelGroup() {
return this.defaultChannelGroup;
}
public void setDefaultChannelGroup(ChannelGroup defaultChannelGroup) {
this.defaultChannelGroup = defaultChannelGroup;
}
/** End Getter/Setter methods */
}