/* * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import java.nio.file.Paths; import java.util.List; import jdk.jfr.Recording; import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordingFile; import com.oracle.java.testlibrary.OutputAnalyzer; // This class is intended to run inside a container public class JfrNetwork { // use a unique hostname for container public static final String HOST_NAME = "container-unique-8221711"; public static final String JFR_REPORTED_CONTAINER_HOSTNAME_TAG = "jfr_reported_container_hostname="; public static void main(String[] args) throws Exception { String event = args[0]; try (ServerSocket ss = new ServerSocket()) { testNetworkInfo(ss, event); } } private static void assertTrue(boolean expr, String msg) { if (!expr) { throw new RuntimeException(msg); } } private static void testNetworkInfo(ServerSocket ss, String event) throws Exception { ServerSocketListener server = new ServerSocketListener(ss); server.start(); SocketWriter writer = new SocketWriter(ss.getLocalSocketAddress()); // setup and start the recording String recordingPath = event + ".jfr"; log("========= Recording event: " + event); Recording r = new Recording(); r.enable(event); r.setDestination(Paths.get("/", "tmp", recordingPath)); r.start(); // start the socker writer thread, write some data into the socket writer.start(); // wait for writer thread to terminate, then for server thread, then stop recording writer.joinAndThrow(); server.joinAndThrow(); r.stop(); // analyze the recording List events = RecordingFile.readAllEvents(r.getDestination()); events.forEach(e -> log ("event = " + e)); assertTrue(!events.isEmpty(), "No recorded network events"); RecordedEvent e = events.get(0); log(JFR_REPORTED_CONTAINER_HOSTNAME_TAG + e.getString("host")); verifyIpAddress(e.getString("address")); } private static void verifyIpAddress(String eventIp) throws Exception { ProcessBuilder pb = new ProcessBuilder("hostname", "--ip-address"); OutputAnalyzer out = new OutputAnalyzer(pb.start()); out.shouldHaveExitValue(0); log("hostname --ip-address returned: " + out.getOutput()); out.shouldContain(eventIp); } private static void log(String msg) { System.out.println(msg); } private static class ServerSocketListener extends Thread { Exception exception; ServerSocket ss; ServerSocketListener(ServerSocket socket) throws Exception { ss = socket; ss.setReuseAddress(true); ss.bind(null); log("ServerSocker Local Address: " + ss.getLocalSocketAddress()); } public void joinAndThrow() throws Exception { join(); if (exception != null) { throw exception; } } public void run() { try { try (Socket s = ss.accept(); InputStream is = s.getInputStream()) { System.out.println("ServerSocketListener: accepted socket connection: s = " + s); is.read(); is.read(); is.read(); } } catch (Exception e) { exception = e; } } } private static class SocketWriter extends Thread { Exception exception; private SocketAddress ssAddr; public SocketWriter(SocketAddress sa) { this.ssAddr = sa; System.out.println("SocketWriter(): sa = " + sa); } public void joinAndThrow() throws Exception { join(); if (exception != null) { throw exception; } } public void run() { try (Socket s = new Socket()) { s.connect(ssAddr); try (OutputStream os = s.getOutputStream()) { os.write('A'); os.write('B'); os.write('C'); } } catch (Exception e) { exception = e; } } } }