/* * Copyright 2015, Simon Matić Langford * * 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.betfair.cougar.test.socket.tester.server; import com.betfair.cougar.core.api.ev.Executable; import com.betfair.cougar.core.api.ev.ExecutionVenue; import com.betfair.cougar.core.api.ev.NullExecutionTimingRecorder; import com.betfair.cougar.core.api.ev.OperationDefinition; import com.betfair.cougar.core.api.security.IdentityResolverFactory; import com.betfair.cougar.core.api.transports.TransportRegistry; import com.betfair.cougar.core.impl.logging.EventLoggerImpl; import com.betfair.cougar.core.impl.security.CommonNameCertInfoExtractor; import com.betfair.cougar.core.impl.tracing.CompoundTracer; import com.betfair.cougar.core.impl.transports.TransportRegistryImpl; import com.betfair.cougar.logging.EventLoggingRegistry; import com.betfair.cougar.netutil.nio.NioLogger; import com.betfair.cougar.netutil.nio.TlsNioConfig; import com.betfair.cougar.netutil.nio.hessian.HessianObjectIOFactory; import com.betfair.cougar.netutil.nio.marshalling.DefaultExecutionContextResolverFactory; import com.betfair.cougar.netutil.nio.marshalling.DefaultSocketTimeResolver; import com.betfair.cougar.netutil.nio.marshalling.SocketRMIMarshaller; import com.betfair.cougar.test.socket.tester.common.ClientAuthRequirement; import com.betfair.cougar.test.socket.tester.common.Common; import com.betfair.cougar.test.socket.tester.common.SslRequirement; import com.betfair.cougar.transport.api.protocol.CougarObjectIOFactory; import com.betfair.cougar.transport.impl.DehydratedExecutionContextResolutionImpl; import com.betfair.cougar.transport.nio.ExecutionVenueNioServer; import com.betfair.cougar.transport.nio.ExecutionVenueServerHandler; import com.betfair.cougar.transport.nio.IoSessionManager; import com.betfair.cougar.transport.socket.PooledServerConnectedObjectManager; import com.betfair.cougar.transport.socket.SocketTransportCommandProcessor; import com.betfair.cougar.util.JMXReportingThreadPoolExecutor; import com.betfair.cougar.util.RequestUUIDImpl; import com.betfair.cougar.util.UUIDGeneratorImpl; import com.betfair.cougar.util.geolocation.NullGeoIPLocator; import org.springframework.core.io.ClassPathResource; import javax.management.MBeanServerFactory; import java.io.IOException; import java.net.ServerSocket; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; /** * */ class ServerInstance { private final String name; private final ExecutionVenueNioServer server; private int port; ServerInstance(String name) throws IOException { this(name, SslRequirement.None); } ServerInstance(String name, SslRequirement sslRequirement) throws IOException { this(name, sslRequirement, ClientAuthRequirement.None); } public ServerInstance(String name, SslRequirement sslRequirement, ClientAuthRequirement clientAuthRequirement) throws IOException { this.name = name; port = findPort(); server = new ExecutionVenueNioServer(); TlsNioConfig nioConfig = new TlsNioConfig(); NioLogger sessionLogger = new NioLogger("ALL"); nioConfig.setListenAddress("127.0.0.1"); nioConfig.setListenPort(port); nioConfig.setNioLogger(sessionLogger); nioConfig.setMaxWriteQueueSize(0); nioConfig.setRecvBufferSize(524288); nioConfig.setSendBufferSize(524288); nioConfig.setKeepAlive(true); nioConfig.setKeepAliveInterval(1000); nioConfig.setKeepAliveTimeout(5000); nioConfig.setReuseAddress(true); nioConfig.setTcpNoDelay(true); nioConfig.setWorkerTimeout(0); nioConfig.setUseDirectBuffersInMina(false); nioConfig.setMbeanServer(MBeanServerFactory.createMBeanServer()); if (sslRequirement != SslRequirement.None) { nioConfig.setSupportsTls(sslRequirement == SslRequirement.Supports || sslRequirement == SslRequirement.Requires); nioConfig.setRequiresTls(sslRequirement == SslRequirement.Requires); nioConfig.setKeystore(new ClassPathResource("cougar_server_cert.jks")); nioConfig.setKeystoreType("JKS"); nioConfig.setKeystorePassword("password"); if (clientAuthRequirement != ClientAuthRequirement.None) { nioConfig.setTruststore(new ClassPathResource("cougar_client_ca.jks")); nioConfig.setTruststoreType("JKS"); nioConfig.setTruststorePassword("password"); nioConfig.setWantClientAuth(true); if (clientAuthRequirement == ClientAuthRequirement.Needs) { nioConfig.setNeedClientAuth(true); } } } ExecutorService serverExecutor = new JMXReportingThreadPoolExecutor(2,3,5000, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<Runnable>()); IdentityResolverFactory identityResolverFactory = new IdentityResolverFactory(); DehydratedExecutionContextResolutionImpl contextResolution = new DehydratedExecutionContextResolutionImpl(); contextResolution.registerFactory(new DefaultExecutionContextResolverFactory(new NullGeoIPLocator(), new DefaultSocketTimeResolver(true))); // todo: set false if run on multiple machines contextResolution.onCougarStart(); SocketRMIMarshaller marshaller = new SocketRMIMarshaller(new CommonNameCertInfoExtractor(), contextResolution); EventLoggingRegistry registry = new EventLoggingRegistry(); TestServerExecutionVenue executionVenue = new TestServerExecutionVenue(); Executor executor = new JMXReportingThreadPoolExecutor(2,3,5000,TimeUnit.MILLISECONDS,new LinkedBlockingDeque<Runnable>()); CougarObjectIOFactory objectIoFactory = new HessianObjectIOFactory(false); IoSessionManager sessionManager = new IoSessionManager(); TransportRegistry transportRegistry = new TransportRegistryImpl(); RequestUUIDImpl.setGenerator(new UUIDGeneratorImpl()); PooledServerConnectedObjectManager connectedObjectManager = new PooledServerConnectedObjectManager(); connectedObjectManager.setNioLogger(sessionLogger); connectedObjectManager.setNumProcessingThreads(1); connectedObjectManager.setObjectIOFactory(objectIoFactory); connectedObjectManager.setMaxUpdateActionsPerMessage(100); EventLoggerImpl eventLogger = new EventLoggerImpl(); eventLogger.setEnabled(false); connectedObjectManager.setEventLogger(eventLogger); connectedObjectManager.start(); SocketTransportCommandProcessor processor = new SocketTransportCommandProcessor(); processor.setConnectedObjectManager(connectedObjectManager); processor.setIdentityResolverFactory(identityResolverFactory); processor.setMarshaller(marshaller); processor.setNioLogger(sessionLogger); processor.setRegistry(registry); processor.setUnknownCipherKeyLength(0); processor.setExecutionVenue(executionVenue); processor.setExecutor(executor); processor.setTracer(new CompoundTracer()); ExecutionVenueServerHandler serverHandler = new ExecutionVenueServerHandler(sessionLogger, processor, objectIoFactory); serverHandler.addListener(connectedObjectManager); server.setNioConfig(nioConfig); server.setServerExecutor(serverExecutor); server.setServerHandler(serverHandler); server.setSessionManager(sessionManager); server.setSocketAcceptorProcessors(1); server.setTransportRegistry(transportRegistry); EchoOperation op = new EchoOperation(clientAuthRequirement == ClientAuthRequirement.Needs); registerOp(Common.echoOperationDefinition, op, executionVenue, processor); registerOp(Common.echoFailureOperationDefinition, op, executionVenue, processor); HeapOperation op2 = new HeapOperation(clientAuthRequirement == ClientAuthRequirement.Needs); registerOp(Common.heapSubscribeOperationDefinition, op2, executionVenue, processor); registerOp(Common.heapSetOperationDefinition, op2, executionVenue, processor); registerOp(Common.heapCloseOperationDefinition, op2, executionVenue, processor); server.start(); server.setHealthState(true); } private void registerOp(OperationDefinition def, Executable exec, ExecutionVenue ev, SocketTransportCommandProcessor processor) { ev.registerOperation(null, def, exec, new NullExecutionTimingRecorder(), 0L); processor.bindOperation(def); } private int findPort() { int port = 0; while (true) { try { ServerSocket socket = new ServerSocket(0); port = socket.getLocalPort(); socket.close(); return port; } catch (IOException ioe) { System.err.println("Couldn't bind to port "+port+" trying again"); } } } public String getName() { return name; } public void shutdown() { server.stop(); } public int getPort() { return port; } }