com.ibm.as400.access.PSController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400 Show documentation
Show all versions of jt400 Show documentation
The Open Source version of the IBM Toolbox for Java
The newest version!
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: PSController.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2000 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Vector;
// Represents a connection to a client of the proxy server.
class PSController extends StoppableThread
{
// Private data.
private static long nextConnectionId_ = 1000;
private static Object nextConnectionIdLock_ = new Object();
private boolean closed_ = false;
//private PSConfig config_;
private Socket connectedSocket_;
private long connectionId_ = -1;
private PxDSFactory factory_;
private InputStream input_;
private boolean ownSocket_ = false;
private OutputStream output_;
private boolean running_ = false;
private PSServerSocketContainerAdapter serverSocket_;
//private Vector threadGroup_;
// Constructs a PSController object.
// @param threadGroup The thread group.
// @param proxyServer The proxy server.
// @param load The load.
// @param loadBalancer The load balancer.
// @param config The configuration.
// @param serverSocket The server socket container.
public PSController(Vector threadGroup, ProxyServer proxyServer, PSLoad load, PSLoadBalancer loadBalancer, PSConfig config, PSServerSocketContainerAdapter serverSocket)
{
super("PSController-" + serverSocket);
//threadGroup_ = threadGroup;
//config_ = config;
serverSocket_ = serverSocket;
factory_ = new PxDSFactory();
factory_.register(new PxBooleanParm());
factory_.register(new PxIntParm());
factory_.register(new PxStringParm());
factory_.register(new PxSerializedObjectParm(null));
factory_.register(new PxConnectReqSV(threadGroup, this, load, loadBalancer));
factory_.register(new PxConfigReqSV(config, this));
factory_.register(new PxEndReqSV(proxyServer, this));
factory_.register(new PxLoadReqSV(load));
if (Trace.isTraceOn()) Trace.log(Trace.PROXY, "Px server controller " + this + " opened.");
}
public void closeServerSocket()
{
if (Trace.isTraceOn()) Trace.log(Trace.PROXY, "Px server controller " + this + " closed.");
closeSocket();
try
{
serverSocket_.close();
}
catch (IOException e)
{
Trace.log(Trace.ERROR, e.getMessage(), e);
}
closed_ = true;
}
public void closeSocket()
{
if (ownSocket_)
{
try
{
if (connectedSocket_ != null) connectedSocket_.close();
}
catch (IOException e)
{
Trace.log(Trace.ERROR, "Exception closing proxy socket:", e);
}
ownSocket_ = false;
}
}
protected void finalize() throws Throwable
{
if (closed_ == false) closeServerSocket();
super.finalize();
}
// Returns the current requesting client's address.
// @return The current requesting client's address.
public InetAddress getClientAddress()
{
return connectedSocket_.getInetAddress();
}
// Returns the current requesting client's socket.
// @return The current requesting client's socket.
public Socket getConnectedSocket()
{
// Give up ownership of the socket. A connection owns it now.
ownSocket_ = false;
return connectedSocket_;
}
// Returns the current requesting client's unique connection id.
// @return The current requesting client's unique connection id.
public long getConnectionId()
{
return connectionId_;
}
// Returns the input stream used for receiving requests from the current client.
// @return The input stream used for receiving requests from the current client.
public InputStream getInputStream()
{
return input_;
}
// Returns the output stream used for sending replies to the current client.
// @return The output stream used for sending replies to the current client.
public OutputStream getOutputStream()
{
return output_;
}
// Runs the controller.
public void run()
{
running_ = true;
// Loop forever, handling each connection that comes in.
while (canContinue())
{
// If anything goes wrong here, stop the controller.
try
{
connectedSocket_ = serverSocket_.accept();
// Test note: We see the phrase "Address in use: bind" on occasion when calling this method. My best guess is that the JDK is printing it!
}
catch(Exception e)
{
Verbose.println(e);
Trace.log(Trace.ERROR, "Exception accepting proxy socket:", e);
break;
}
// From here on out, if anything goes wrong, we just loop and try again!
try
{
input_ = new BufferedInputStream(connectedSocket_.getInputStream());
output_ = new BufferedOutputStream(connectedSocket_.getOutputStream());
// For now, this class "owns" the socket... at least until a connection gets it for its own use.
ownSocket_ = true;
synchronized (nextConnectionIdLock_)
{
connectionId_ = ++nextConnectionId_;
}
// Get the next request.
if (Trace.isTraceProxyOn())
Trace.log(Trace.PROXY,this,"calling factory_.getNextDS");
PxReqSV request = (PxReqSV)factory_.getNextDS(input_);
if (Trace.isTraceProxyOn()) request.dump(Trace.getPrintWriter());
// Process the request and return the reply, if any.
PxRepSV reply = (PxRepSV)request.process();
if (reply != null)
{
reply.setCorrelationId(request.getCorrelationId());
synchronized (output_)
{
if (Trace.isTraceProxyOn()) reply.dump(Trace.getPrintWriter());
reply.writeTo(output_);
output_.flush();
}
}
}
catch (Exception e)
{
Verbose.println(e);
Trace.log(Trace.ERROR, "Exception processing proxy request:", e);
}
finally
{
closeSocket();
}
}
running_ = false;
}
// Stops the thread safely.
public void stopSafely()
{
super.stopSafely();
// Close the sockets, etc.
closeServerSocket();
// Wait for controller loop to finish. This verifies that the socket was finally closed. (On some platforms (e.g. Windows) it seems like the close does not take full effect until a few seconds after close() is called.
try
{
while (running_) Thread.sleep(500);
}
catch(InterruptedException e)
{
// Ignore.
}
Verbose.println(ResourceBundleLoader.getText("PROXY_SERVER_ENDED", serverSocket_));
}
public String toString()
{
return serverSocket_.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy