org.apache.openejb.server.ServiceDaemon Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.openejb.server;
import org.apache.openejb.loader.Options;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.monitoring.Managed;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.StringTemplate;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.BindException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@SuppressWarnings("UnusedDeclaration")
@Managed
public class ServiceDaemon implements ServerService {
private static final Logger log = Logger.getInstance(LogCategory.OPENEJB_SERVER, ServiceDaemon.class);
@Managed
private final ServerService next;
private SocketListener socketListener;
private int timeout = 0;
private InetAddress inetAddress;
private int port;
private int backlog;
private String ip;
private boolean secure;
private StringTemplate discoveryUriFormat;
private URI serviceUri;
private Properties props;
private String[] enabledCipherSuites;
public ServiceDaemon(final ServerService next) {
this.next = next;
}
public ServiceDaemon(final ServerService next, final int port, final String ip) {
this.port = port;
this.ip = ip;
this.inetAddress = getAddress(ip);
this.next = next;
}
public static InetAddress getAddress(final String host) {
try {
return InetAddress.getByName(host);
} catch (final UnknownHostException e) {
throw new IllegalArgumentException(host);
}
}
/**
* Gets the inetAddress number that the
* daemon is listening on.
*/
public InetAddress getInetAddress() {
return this.inetAddress;
}
@Override
public void init(final Properties props) throws Exception {
this.props = props;
final String formatString = props.getProperty("discovery");
if (formatString != null) {
this.discoveryUriFormat = new StringTemplate(formatString);
}
this.ip = props.getProperty("bind");
this.inetAddress = getAddress(this.ip);
final Options options = new Options(props);
this.port = options.get("port", 0);
final int threads = options.get("threads", 100);
this.backlog = options.get("backlog", threads);
this.secure = options.get("secure", false);
this.timeout = options.get("timeout", this.timeout);
this.enabledCipherSuites = options.get("enabledCipherSuites", "SSL_DH_anon_WITH_RC4_128_MD5").split(",");
this.next.init(props);
}
@Override
public void start() throws ServiceException {
synchronized (this) {
// Don't bother if we are already started/starting
if (this.socketListener != null) {
return;
}
this.next.start();
final ServerSocket serverSocket;
try {
if (this.secure) {
final ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
serverSocket = factory.createServerSocket(this.port, this.backlog, this.inetAddress);
((SSLServerSocket) serverSocket).setEnabledCipherSuites(this.enabledCipherSuites);
} else {
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
try {
serverSocket.bind(new InetSocketAddress(this.inetAddress, this.port), this.backlog);
} catch (final BindException e) {
//One retry - Port may be closing
Thread.sleep(1000);
serverSocket.bind(new InetSocketAddress(this.inetAddress, this.port), this.backlog);
}
}
serverSocket.setSoTimeout(this.timeout);
final int serverPort = serverSocket.getLocalPort();
if (this.port == 0 && next.getName() != null) {
SystemInstance.get().getProperties().put(next.getName() + ".port", Integer.toString(serverPort));
this.port = serverPort;
}
} catch (final Exception e) {
throw new ServiceException("Service failed to open socket", e);
}
this.socketListener = new SocketListener(this.next, serverSocket);
final Thread thread = new Thread(this.socketListener);
thread.setName("Service." + this.getName() + "@" + this.socketListener.hashCode());
thread.setDaemon(true);
thread.start();
final DiscoveryAgent agent = SystemInstance.get().getComponent(DiscoveryAgent.class);
if (agent != null && this.discoveryUriFormat != null) {
final Map map = new HashMap();
// add all the properties that were used to construct this service
for (final Map.Entry
© 2015 - 2025 Weber Informatics LLC | Privacy Policy