Weblogic JCA Resource Adapter для сокета SSL - PullRequest
0 голосов
/ 26 сентября 2018

Я пытаюсь реализовать простой адаптер ресурсов, который прослушивает сокет-соединение.Мне удалось заставить его работать с обычным сокетом, но почему-то я застрял, пытаясь заставить его работать для сокета SSL.Сокет на самом деле работает, и, кажется, соединение установлено, я мог бы получить поток ввода и выходного потока на клиенте, но каким-то образом, когда я пишу в выходной поток на клиенте, сервер никогда не получит его.

Вотсоответствующий код (да, я знаю, что это не лучшая реализация, но я просто хочу, чтобы было сделано общее дело, прежде чем пытаться найти более сложное решение):

public class SocketResAdapter implements ResourceAdapter {
    private SocketListener listener = null;
    private final Logger logger = Logger.getLogger(SocketResAdapter.class.getName());

    @Override
    public void start(BootstrapContext context) throws ResourceAdapterInternalException {
        logger.info("Starting resource adapter for socket");
        listener = new SocketListener(context.getWorkManager());
    }

    @Override
    public void stop() {
        listener.release();
    } 
}

Это класс, который слушает сокетзапросите соединение и примите его.

public class SocketListener implements Work {

    private final WorkManager workManager;
    private SSLServerSocket   serverSocket;
    private int               port = 9999;
    private String            IP   = "localhost";

    private final Logger logger = Logger.getLogger(SocketListener.class.getName());

    private AtomicBoolean isRunning = new AtomicBoolean(false);

    final boolean isRunning() {
        return isRunning.get();
    }

    final void setRunning(Boolean running) {
        isRunning.set(running);
    }


    public SocketListener(WorkManager manager){
        this.workManager = manager;
        try {
            manager.startWork(this);
        } catch (WorkException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        setRunning(true);
        try {

            // for ssl
            System.setProperty("javax.net.ssl.keyStore", "path/to/my/keystore/keystore.jks");
            System.setProperty("javax.net.ssl.keyStorePassword", "someweirdpassword");

            InetAddress inetAddress = InetAddress.getByName(IP);

            SSLServerSocketFactory l_serverSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();

            serverSocket = (SSLServerSocket) l_serverSocketFactory.createServerSocket(port, 50, inetAddress);

            while (isRunning())
            {
                logger.info("Accepting request from client");
                SSLSocket socket = (SSLSocket) serverSocket.accept();
                socket.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2" });
                workManager.scheduleWork(new SocketProcessor(socket));
            }

        }catch (Exception e){
            setRunning(false);
        }
    }

    @Override
    public void release() {
        setRunning(false);
        try {
            if (serverSocket!=null){
                serverSocket.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Затем клиент обслуживается другим потоком:

 public class SocketProcessor implements Work {

        private Socket socket;
        private AtomicBoolean isRunning = new AtomicBoolean(false);
        private final Logger logger = Logger.getLogger(SocketProcessor.class.getName());

        final boolean isRunning() {
            return isRunning.get();
        }

        final void setRunning(Boolean running) {
            isRunning.set(running);
        }

        public SocketProcessor(Socket socket) throws IOException {
            this.socket = socket;
        }

        @Override
        public void run() {
            setRunning(true);
            logger.info("Running socket processor");
            try{
                LineNumberReader in = new LineNumberReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                final PrintStream socketOutput = new PrintStream(socket.getOutputStream());

                String line;
                int size = 0;
                while ((line = in.readLine()) != null) {
                    logger.info("Reading line");
                    if ( "EXIT".equals( line )){
                        socket.close();
                        break;
                    }else{
                        socketOutput.println(line);
                        size += line.length();
                        socketOutput.flush();
                    }
                }

            }catch (Exception e){
                e.printStackTrace();
                setRunning(false);
            }
            finally {
                closeSocket();
            }
        }

        @Override
        public void release() {
            setRunning(false);
            closeSocket();
        }

        private void closeSocket(){
            try {
                if(!socket.isClosed()) {
                    socket.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

Вот соответствующий код клиента

public class Main {
    public static void main(String[] args){
        int port       = 9999;
        String address = "localhost";

        SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();

        try{
            InetAddress inetAddress = InetAddress.getByName("localhost");
            SSLSocket socket = (SSLSocket) factory.createSocket(inetAddress, port);
            printSocketInfo(socket);
            //socket.con
            //socket.startHandshake();

            if(socket.isConnected())
                System.out.println("THE SOCKET IS CONNECTED");

            final OutputStream outputStream = socket.getOutputStream();
            String sendString = args.length == 0 ? "THES IS DE DEFAULT STRING TO SEND" : args[0];
            outputStream.write(sendString.getBytes());
            System.out.println("Flushing the output stream : " + sendString);
            outputStream.flush();

            final InputStream inputStream = socket.getInputStream();
            final BufferedReader rd       = new BufferedReader(new InputStreamReader(inputStream));

            String str;
            while ((str = rd.readLine()) != null) {
                System.out.println("LOOPS");
                System.out.println(str);
            }
            rd.close();
            socket.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    private static void printSocketInfo(SSLSocket s) {
        System.out.println("Socket class: "+s.getClass());
        System.out.println("   Remote address = "
                +s.getInetAddress().toString());
        System.out.println("   Remote port = "+s.getPort());
        System.out.println("   Local socket address = "
                +s.getLocalSocketAddress().toString());
        System.out.println("   Local address = "
                +s.getLocalAddress().toString());
        System.out.println("   Local port = "+s.getLocalPort());
        System.out.println("   Need client authentication = "
                +s.getNeedClientAuth());
        SSLSession ss = s.getSession();
        System.out.println("   Cipher suite = "+ss.getCipherSuite());
        System.out.println("   Protocol = "+ss.getProtocol());
    }
}

Я успешно получаюинформация о сеансе и сокете печати уже показывает принятый набор и протокол.Там нет ошибки ни на сайте клиента, ни на сайте сервера, сервер просто не получает данные, отправленные с клиента.Интересно, что я сделал не так?Кстати, я использую адаптер на Weblogic.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...