public class LowLevelSocketImpl extends java.lang.Object implements LowLevelSocket, SessionListener
Modifier and Type | Class and Description |
---|---|
private static class |
LowLevelSocketImpl.ReadListener
This class is dedicated to listening for incoming socket data.
|
(package private) static class |
LowLevelSocketImpl.SocketData
A container holding the various client-socket data.
|
private static class |
LowLevelSocketImpl.StagedInput
Due to the nature of java sockets and how the 4GL sockets behave, all reading must be done
in a dedicated thread.
|
private static class |
LowLevelSocketImpl.WorkArea
Container for the context-local data.
|
Modifier and Type | Field and Description |
---|---|
private static LowLevelSocketImpl |
instance
The single instance available of this class.
|
private static ContextLocal<LowLevelSocketImpl.WorkArea> |
local
The context-local data of this class.
|
private static java.util.logging.Logger |
LOG
Logger
|
private static java.lang.Object |
modToken
Token used to authenticate with the dispatcher when registering APIs.
|
static java.lang.String |
P2J_NOHOSTVERIFY
The name of the property used for passing custom configuration to SSL sockets used by AXIS2
when accessing web services over SSL.
|
private static java.lang.String |
trustStoreFilename
Filename of client-side SSL certificate store.
|
private static java.lang.String |
trustStorePassword
The password for access to client-side SSL certificate store.
|
Modifier | Constructor and Description |
---|---|
private |
LowLevelSocketImpl()
Private c'tor, to not allow explicit usage of this class.
|
Modifier and Type | Method and Description |
---|---|
int |
connect(long resourceId,
java.lang.String host,
int port)
Establish a connection to the given host and port.
|
int |
connectSSL(long resourceId,
java.lang.String host,
int port,
boolean nosessionreuse,
boolean nohostverify)
Establish a SSL connection to the given host and port.
|
private static javax.net.ssl.SSLSocket |
createSslSocket(java.lang.String host,
int port,
java.net.InetAddress inetAddress,
int localPort,
int timeout,
boolean nohostverify,
boolean errManager)
Worker for creating a SSL socket and secure it according to specifications.
|
boolean |
disconnect(int id)
Disconnect this socket.
|
long |
getBytesAvailable(int id)
Get the available bytes to be read.
|
boolean |
getKeepAlive(int id)
Get the SO_KEEPALIVE option value for this socket.
|
java.lang.String |
getLocalHost(int id)
Get the IP address of this side of this connection.
|
int |
getLocalPort(int id)
Get the port number of this side of this connection.
|
int |
getReceiveBufferSize(int id)
Get the SO_RCVBUF option value for this socket.
|
java.lang.String |
getRemoteHost(int id)
Get the host IP address of the remote side of this connection.
|
int |
getRemotePort(int id)
Get the port number of the remote side of this connection.
|
boolean |
getReuseAddress(int id)
Get the SO_REUSEADDR option value for this socket.
|
int |
getSendBufferSize(int id)
Get the SO_SNDBUF option value for this socket.
|
int |
getSoLinger(int id)
Get the SO_LINGER option value for this socket.
|
int |
getSoTimeout(int id)
Get the SO_RCVTIMEO option value for this socket.
|
java.lang.String |
getSslServerName(int id)
In case of a SSL connection, get the digital certificate subject name of the server for
the current SSL session; else, return
null . |
boolean |
getTcpNoDelay(int id)
Get the TCP_NODELAY option value for this socket.
|
static void |
initialize(BootstrapConfig cfg,
Session session,
boolean single)
Initialize the client-side socket support:
export the singleton instance of this class as a network server;
initialize client side SSL by registering a custom secure socket factory for
https protocol and setting truststore location and password.
|
void |
initialize(Session session)
This method is called when the session is starting.
|
boolean |
isConnected(int id)
Check if the java socket is still connected.
|
private static boolean |
isReady(int id,
java.util.concurrent.CountDownLatch ready)
Wait until all socket-related threads are initialized.
|
private static LowLevelSocketImpl.SocketData |
locate(int id)
Identify the socket
socket data using the given ID. |
private static java.net.Socket |
locateSocket(int id)
Identify the associated
socket for the given ID. |
long |
read(int id,
memptr buffer,
long pos,
long len,
int mode)
Java implementation for the READ() SOCKET method, this will read the specified number of
bytes from the available data on the socket, and put it inside the memory buffer
argument at the specified position.
|
(package private) static LowLevelSocketImpl.SocketData |
registerClientSocket(java.net.Socket client,
boolean ssl)
When the server socket accepts a new connection, this will make sure the new socket is
registered and a
SocketImpl resource is also created on P2J server side. |
void |
setKeepAlive(int id,
boolean on)
Set the SO_KEEPALIVE option for this socket.
|
void |
setReceiveBufferSize(int id,
int size)
Set the SO_RCVBUF value (the receive buffer size) for this socket.
|
void |
setReuseAddress(int id,
boolean on)
Set the SO_REUSEADDR option for this socket.
|
void |
setSendBufferSize(int id,
int size)
Set the SO_SNDBUF value (the send buffer size) for this socket.
|
void |
setSoLinger(int id,
boolean on,
int linger)
Set the SO_LINGER option for this socket.
|
void |
setSoTimeout(int id,
int timeout)
Set the SO_RCVTIMEO value (the number of seconds the socket waits to receive data before
timing out) for this socket.
|
void |
setTcpNoDelay(int id,
boolean on)
Set the TCP_NODELAY option for this socket.
|
void |
terminate(Session session)
When the P2J client session is ending, disconnect all active sockets.
|
long |
write(int id,
memptr buffer,
long pos,
long len)
Java implementation for the WRITE() SOCKET method, this will write data from the specified
buffer location (position and number of bytes) to the socket.
|
public static final java.lang.String P2J_NOHOSTVERIFY
private static final java.util.logging.Logger LOG
private static java.lang.Object modToken
private static ContextLocal<LowLevelSocketImpl.WorkArea> local
private static final LowLevelSocketImpl instance
private static java.lang.String trustStoreFilename
trusted-cert.store
from
current directory.
In P4GL the store is a folder and each imported certificate being a file in PEM (ASCII plain text). They should be imported to this store.
private static java.lang.String trustStorePassword
private LowLevelSocketImpl()
public static void initialize(BootstrapConfig cfg, Session session, boolean single)
https
protocol and setting truststore location and password.cfg
- The configuration to use for setup of the client sockets.session
- The P2J session. May be null
if running in embedded mode.single
- true
to startup within the server process which must bypass the
shared infrastructure initialization. Use false
for the normal client
JVM startup.private static javax.net.ssl.SSLSocket createSslSocket(java.lang.String host, int port, java.net.InetAddress inetAddress, int localPort, int timeout, boolean nohostverify, boolean errManager) throws java.io.IOException, java.lang.SecurityException
Documentation states that OpenEdge keeps the public keys (certificates) as individual files
in a per-installation store (directory DLC/certs
). We use per-client JKS storage
facilities in a unified trusted-cert.store
in client installation. Certificates need
to be imported with java keytool
:
keytool -import -alias a_server -file a_server.cer -keystore trusted-cert.storeThe location of the store and password for access it can be passed-in at client startup as bootstrap config value with the default value of
trusted-cert.store
in the current
directory.
Apparently OpenEdge's mkhashfile
utility uses the rehashing function for creating
(not so) unique ids for each imported certificate. A similar (if not identical) feature is
offered by OpenSSL:
openssl x509 -in a_server.pem -noout -hash
host
- The host name/IP to connect to.port
- The port on the host.inetAddress
- The local host name/IP to bind the socket to.localPort
- The port on the local machine.timeout
- Socket timeout (in milliseconds), or 0 if it never expires.nohostverify
- If true
, disables host verification for connection using HTTPS.errManager
- Instruct how to handle encountered errors. If true
ant exception is fed to
P2J ErrorManager
, otherwise let the caller handle it using normal java
exceptions.java.io.IOException
- If any problems are encountered in the process.java.lang.SecurityException
static LowLevelSocketImpl.SocketData registerClientSocket(java.net.Socket client, boolean ssl) throws java.io.IOException
SocketImpl
resource is also created on P2J server side.client
- The client socket.ssl
- Flag indicating if this is a SSL connection.SocketImpl
instance with the details of the new socket.java.io.IOException
- If the socket's input or output streams couldn't be obtained.private static LowLevelSocketImpl.SocketData locate(int id)
socket data
using the given ID.id
- The ID of the associated socket on P2J Client side.private static java.net.Socket locateSocket(int id)
socket
for the given ID.id
- The ID of the associated socket on P2J Client side.private static boolean isReady(int id, java.util.concurrent.CountDownLatch ready)
id
- The socket ID on P2J client side.ready
- The signal to wait on. If null
, it returns true
.true
if all threads are initialized or ready
is null;
false
if someone interrupted the CountDownLatch.await()
public int connect(long resourceId, java.lang.String host, int port) throws java.io.IOException
connect
in interface LowLevelSocket
resourceId
- The ID of the associated SocketImpl
resource on server side.host
- The IP address or name of the target host.port
- The port number.java.io.IOException
- In case of errors while establishing the connection.public int connectSSL(long resourceId, java.lang.String host, int port, boolean nosessionreuse, boolean nohostverify) throws java.io.IOException, java.security.GeneralSecurityException
connectSSL
in interface LowLevelSocket
resourceId
- The ID of the associated SocketImpl
resource on server side.host
- The IP address or name of the target host.port
- The port number.nosessionreuse
- Flag indicating that the ssl session ID must not be reused.nohostverify
- Flag indicating that the target host name must not be validated against the
certificate's principal name.java.io.IOException
- In case of errors while establishing the connection.java.security.GeneralSecurityException
- In case of errors while establishing the SSL connection.public boolean isConnected(int id)
isConnected
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.true
if the java socket is still connected.public boolean disconnect(int id)
disconnect
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.true
if no errors were encountered during disconnect.public long getBytesAvailable(int id)
getBytesAvailable
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.public long read(int id, memptr buffer, long pos, long len, int mode) throws java.io.IOException
Optionally the read mode can be set by the following values:
During READ processing, the read listener
will be blocked from raising
new READ-RESPONSE events.
read
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.buffer
- The memory buffer where read() puts the data.pos
- The position in the memory buffer where the data is added.len
- The number of bytes to read from the socket.mode
- The mode to set for the reading operation.java.io.IOException
- In case IO errors were encountered during read.public long write(int id, memptr buffer, long pos, long len) throws java.io.IOException
write
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.buffer
- The memory buffer from which the data will be written to the socket.pos
- The position in the memory buffer from where the data to be taken starts.len
- The number of bytes to take from the memory buffer.java.io.IOException
- In case IO errors were encoubtered during write.public java.lang.String getSslServerName(int id)
null
.getSslServerName
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.public boolean getTcpNoDelay(int id) throws java.net.SocketException
Socket.getTcpNoDelay()
for more details.getTcpNoDelay
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.java.net.SocketException
- If the socket option could not be interrogated.public int getSoLinger(int id) throws java.net.SocketException
Socket.getSoLinger()
for more details.getSoLinger
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.java.net.SocketException
- If the socket option could not be interrogated.public boolean getKeepAlive(int id) throws java.net.SocketException
Socket.getKeepAlive()
for more details.getKeepAlive
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.java.net.SocketException
- If the socket option could not be interrogated.public boolean getReuseAddress(int id) throws java.net.SocketException
Socket.getReuseAddress()
for more details.getReuseAddress
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.java.net.SocketException
- If the socket option could not be interrogated.public int getReceiveBufferSize(int id) throws java.net.SocketException
Socket.getReceiveBufferSize()
for more details.getReceiveBufferSize
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.java.net.SocketException
- If the socket option could not be interrogated.public int getSendBufferSize(int id) throws java.net.SocketException
Socket.getSendBufferSize()
for more details.getSendBufferSize
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.java.net.SocketException
- If the socket option could not be interrogated.public int getSoTimeout(int id) throws java.net.SocketException
Socket.getSoTimeout()
for more details.getSoTimeout
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.java.net.SocketException
- If the socket option could not be interrogated.public void setTcpNoDelay(int id, boolean on) throws java.net.SocketException
Socket.setTcpNoDelay(boolean)
for more details.setTcpNoDelay
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.on
- The TCP_NODELAY value.java.net.SocketException
- If the socket option could not be set.public void setSoLinger(int id, boolean on, int linger) throws java.net.SocketException
Socket.setSoLinger(boolean, int)
for more details.setSoLinger
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.on
- true
to turn on the SO_LINGER option.linger
- The linger time.java.net.SocketException
- If the socket option could not be set.public void setKeepAlive(int id, boolean on) throws java.net.SocketException
Socket.setKeepAlive(boolean)
for more details.setKeepAlive
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.on
- The SO_KEEPALIVE value.java.net.SocketException
- If the socket option could not be set.public void setReuseAddress(int id, boolean on) throws java.net.SocketException
Socket.setReuseAddress(boolean)
for more details.setReuseAddress
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.on
- The SO_REUSEADDR value.java.net.SocketException
- If the socket option could not be set.public void setReceiveBufferSize(int id, int size) throws java.net.SocketException
Socket.setReceiveBufferSize(int)
for more details.setReceiveBufferSize
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.size
- The SO_RCVBUF value.java.net.SocketException
- If the socket option could not be set.public void setSendBufferSize(int id, int size) throws java.net.SocketException
Socket.setSendBufferSize(int)
for more details.setSendBufferSize
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.size
- The SO_SNDBUF value.java.net.SocketException
- If the socket option could not be set.public void setSoTimeout(int id, int timeout) throws java.net.SocketException
Socket.setSoTimeout(int)
for more details.setSoTimeout
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.timeout
- The SO_RCVTIMEO value.java.net.SocketException
- If the socket option could not be set.public java.lang.String getLocalHost(int id)
getLocalHost
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.public int getLocalPort(int id)
getLocalPort
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.public java.lang.String getRemoteHost(int id)
getRemoteHost
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.public int getRemotePort(int id)
getRemotePort
in interface LowLevelSocket
id
- The ID of the associated socket on P2J Client side.public void terminate(Session session)
terminate
in interface SessionListener
session
- The session that is ending.public void initialize(Session session)
initialize
in interface SessionListener
session
- The session that is starting.