All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.centurylink.mdw.soccom.SoccomClient Maven / Gradle / Ivy

There is a newer version: 6.1.39
Show newest version
/*
 * Copyright (C) 2017 CenturyLink, Inc.
 *
 * 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.centurylink.mdw.soccom;

// need to log time
// need to set timeout
// need to check msg ID in client_getresp

import java.io.*;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.StringTokenizer;

/**
 * This class defines the method for soccom client.
 *
 * Sample usage:
 * 
 *    try {
 *        SoccomClient client = new SoccomClient(host, port);
 *        client.putreq("test message");
 *        String resp = client.getresp();
 *        System.out.println("response: " + resp);
 *        client.close();
 *    } catch (SoccomException e) {
 *        System.out.println("Exception: " + e);
 *    }
 * 
* * For large messages, if we'd like to get the messages line-by-line * in order to display first part of messages before the entire message is * received, instead of getresp(), we can use the following code: *
 *    String resp = client.getresp_first();
 *    System.out.println("response first: " + resp);
 *    while (client.getresp_hasmore()) {
 *        resp = client.getresp_next();
 *        System.out.println("response next: " + resp);
 *    }
 * 
* * Similarly, we can also send message line-by-line, as shown in the following * example: *
 *    String endmark = "////";
 *    putreq_vheader(endmark);
 *    for (int i=0; i<number_of_lines; i++) {
 *        putreq_vline(lines[i]);
 *    }
 *    putreq_vfooter(endmark);
 * 
* * It is not necessary to open/close the connection for each request, * although a server or a pool has a limited number of open connection * allowed. * * @auther Jiyang Xu * @version 4.5 */ public class SoccomClient { /** * Basic constructor. * @param host Either a domain name or an IP address. * @param port The port number. * @param log A PrintStream for printint log lines * @exception SoccomException The exception is thrown possibly because * of the following reasons: *
    *
  • Host name is unknown
  • *
  • Cannot connect to the service
  • *
  • Failed to create the socket
  • *
*/ public SoccomClient(String host, int port, PrintStream log) throws SoccomException { _log = log; try { _socket = new Socket(host, port); logline("Client connect on host " + host + ", port " + port); logline("Local address: " + _socket.getLocalAddress()); _in = _socket.getInputStream(); _out = _socket.getOutputStream(); _msgid = new byte[SoccomMessage.MSGID_SIZE]; } catch (UnknownHostException e) { throw new SoccomException(SoccomException.HOSTNAME, e); } catch (ConnectException e) { throw new SoccomException(SoccomException.CONNECT, e); } catch (IOException e) { throw new SoccomException(SoccomException.CREATE_SOCKET, e); } } /** * Alternative constructor. It has no parameter for log PrintStream * and it logs all messages to the terminal screen. * * @param host Either a domain name or an IP address. * @param port The port number. * @exception SoccomException The exception is thrown possibly because * of the following reasons: *
    *
  • Host name is unknown
  • *
  • Cannot connect to the service
  • *
  • Failed to create the socket
  • *
*/ public SoccomClient(String host, int port) throws SoccomException { this(host, port, System.out); } private void copy_msgid(byte[] target, byte[] source) { for (int i=0; i0) got += n; else if (n==-1) throw new SoccomException(SoccomException.SOCKET_CLOSED); else throw new SoccomException(SoccomException.RECV_ERROR); } msg = new String(buffer, 0, size); } logline("RECV MSG: " + msg); return msg; } catch (InterruptedIOException e) { throw new SoccomException(SoccomException.RECV_ERROR); } catch (IOException e) { throw new SoccomException(SoccomException.RECV_ERROR); } } /** * This is the same as getresp(int timeout) * except the timeout value is set to the default 120 seconds. * @return The response message. * @exception SoccomException Thrown when an IOException is encountered. */ public String getresp() throws SoccomException { return getresp(120); } /** * The method receives the first part of response message from the * server, up to maxbytes bytes. * Use getresp_hasmore and getresp_next to get * getresp_rest to get the remaining part of messages. * When the server sends the message using ENDM, the string returned * may be longer than maxbytes, but only till the first line after that. * When maxbytes is 0, the procedure reads the first line. * @param maxbytes The maximum number of bytes to be returned. * @param timeout timeout in seconds * @return The string converted from the bytes read. * @exception SoccomException * Any transmission error such as reading socket error. */ public String getresp_first(int maxbytes, int timeout) throws SoccomException { int n; String sizestr, msg; _resp_read = -1; try { byte[] _header = new byte[SoccomMessage.HEADER_SIZE]; _socket.setSoTimeout(timeout*1000); n = _in.read(_header, 0, SoccomMessage.HEADER_SIZE); if (n!=SoccomMessage.HEADER_SIZE) throw new SoccomException(SoccomException.RECV_HEADER); logline("RECV HDR: " + new String(_header)); check_msgid(_msgid, _header); sizestr = new String(_header, SoccomMessage.MSGSIZE_OFFSET, 8); if (sizestr.startsWith("ENDM")) _resp_size = -1; else _resp_size = Integer.parseInt(sizestr); } catch (InterruptedIOException e) { throw new SoccomException(SoccomException.RECV_HEADER); } catch (IOException e) { throw new SoccomException(SoccomException.RECV_HEADER); } try { if (maxbytes==0) { if (_resp_size == -1) { _endm = sizestr.substring(4,8); } _resp_read = 0; if (getresp_hasmore()) msg = getresp_next(maxbytes); else msg = ""; } else if (_resp_size == -1) { _endm = sizestr.substring(4,8); byte[] buffer = new byte[maxbytes]; int k=0; boolean done = false; while (!done && k=0) { _resp_read = n; msg = new String(buffer, 0, n); } else if (n==-1) throw new SoccomException(SoccomException.SOCKET_CLOSED); else throw new SoccomException(SoccomException.RECV_ERROR); logline("RECV MSG: " + msg); } return msg; } catch (InterruptedIOException e) { throw new SoccomException(SoccomException.RECV_ERROR); } catch (IOException e) { throw new SoccomException(SoccomException.RECV_ERROR); } } /** * same as getresp_first(int maxbytes, int timeout) * except the timeout is default to 120 seconds */ public String getresp_first(int maxbytes) throws SoccomException { return getresp_first(maxbytes, 120); } /** * same as getresp_first(int maxbytes, int timeout) * except the timeout is default to 120 seconds and maxbytes is 0 */ public String getresp_first() throws SoccomException { return getresp_first(0, 120); } /** * The method checks if the message is completed read. * @return true if the message has not been completed * read by getresp_first() or * getresp_next(). */ public boolean getresp_hasmore() { if (_resp_size>0) { return _resp_read>=0 && _resp_size > _resp_read; } else { return (_resp_read>=0); } } private int readLine(InputStream in, byte buffer[], int offset, int maxbytes) throws IOException { int n = 0; boolean line_read = false; while (!line_read && n=0) _resp_read += n; else if (n==-1) throw new SoccomException(SoccomException.SOCKET_CLOSED); else throw new SoccomException(SoccomException.RECV_ERROR); msg = new String(buffer, 0, n); } } logline("RECV MSG: " + msg); return msg; } catch (InterruptedIOException e) { throw new SoccomException(SoccomException.RECV_ERROR); } catch (IOException e) { throw new SoccomException(SoccomException.RECV_ERROR); } } private void logline(String msg) { if (_log!=null) _log.println(msg); } /** * Same as getresp_next(0), i.e. read in the next line */ public String getresp_next() throws SoccomException { return getresp_next(0); } /** * This method is a simple wrapper for synchronous invocation * of server's service. It is roughly implemented as: *
     *    SoccomClient soccom = new SoccomClient(host,port,log);
     *    putreq(msg);
     *    return getresp();
     *    soccom.close();
     * 
* @param serverspec In the form of host:port. If ':' is missing, assume * port is 4001 * @param msg The message to be sent. * @param timeout Time out in seconds * @param log For logging information * @return The respose message. * @exception SoccomException It passes up any exception encountered * along the way. */ public static String call(String serverspec, String msg, int timeout, PrintStream log) throws SoccomException { String host; int port; int k = serverspec.indexOf(':'); if (k >= 0) { host = serverspec.substring(0,k); port = Integer.parseInt(serverspec.substring(k+1)); } else { host = serverspec; port = 4001; } SoccomClient soccom = new SoccomClient(host, port, log); String reply; try { soccom.putreq(msg); reply = soccom.getresp(timeout); soccom.close(); } catch (SoccomException e) { soccom.close(); throw e; } return reply; } /** * Close the connection. * This is automatically called at garbage collection but * it is a good idea to voluntarily call it as soon as the connection * is not needed any more. */ public void close() { if (_socket!=null) { try { _socket.close(); _socket = null; } catch (IOException e) { System.err.println("Exception: " + e); // throw new SoccomException(SoccomException.RECV_ERROR); } _in = null; _out = null; } } /** * The method calls close() if the socket has not been * closed yet. */ protected void finalize() { close(); } /** * Tests for client */ private String tests(String msg) { String testcase = msg.substring(6,12); String resp; try { if (testcase.equals("TIMEOU")) { int timeout = Integer.parseInt(msg.substring(13)); putreq("SLEEP " + (timeout+5)); resp = getresp(timeout); } else if (testcase.equals("COMBIN")) { /* test combination of sending/receiving line-by-line * or as a whole. Spec has 4 characters as follows: * 1. for client send: W - as a whole, L - line-by-line * 2. for server recv: W - as a whole, L - not implemented * 3. for server send: W - as a whole, L - line-by-line * 4. for client recv: W - as a whole, L - line-by-line */ StringTokenizer st = new StringTokenizer(msg.substring(12)); String testspec = msg.substring(13,17); if (testspec.charAt(0)=='L') { String endmark = "////"; putreq_vheader(endmark); st = new StringTokenizer(msg, "\n"); while (st.hasMoreTokens()) { putreq_vline(st.nextToken()); } putreq_vfooter(endmark); } else putreq(msg); if (testspec.charAt(3)=='L') { resp = getresp_first(); while (getresp_hasmore()) { resp = resp + getresp_next(); } } else if (testspec.charAt(3)=='P') { String one; resp = getresp_first(80); while (getresp_hasmore()) { one = getresp_next(80); resp = resp + one; } } else resp = getresp(); } else { // default: REQRES, testing reqresp /* SV_LBL falls here, too */ putreq(msg); resp = getresp(); } } catch (SoccomException e) { resp = "TEST ERROR " + e.errdesc() + "\n"; } return resp; } private static void printUsage() { System.err.println("Usage: java soccom.SoccomClient host port msg"); } private InputStream _in; private OutputStream _out; private byte _msgid[]; private Socket _socket; private PrintStream _log; // the followings are used only by getresp_first() and getresp_next(); private int _resp_size; private int _resp_read; private String _endm; }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy