1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 import java.io.InputStream; 26 import java.io.OutputStream; 27 import java.net.ServerSocket; 28 import java.net.Socket; 29 import java.net.SocketAddress; 30 import java.nio.file.Paths; 31 import java.util.List; 32 import jdk.jfr.Recording; 33 import jdk.jfr.consumer.RecordedEvent; 34 import jdk.jfr.consumer.RecordingFile; 35 import com.oracle.java.testlibrary.OutputAnalyzer; 36 37 38 // This class is intended to run inside a container 39 public class JfrNetwork { 40 // use a unique hostname for container 41 public static final String HOST_NAME = "container-unique-8221711"; 42 public static final String JFR_REPORTED_CONTAINER_HOSTNAME_TAG = "jfr_reported_container_hostname="; 43 44 public static void main(String[] args) throws Exception { 45 String event = args[0]; 46 try (ServerSocket ss = new ServerSocket()) { 47 testNetworkInfo(ss, event); 48 } 49 } 50 51 private static void assertTrue(boolean expr, String msg) { 52 if (!expr) { 53 throw new RuntimeException(msg); 54 } 55 } 56 57 private static void testNetworkInfo(ServerSocket ss, String event) throws Exception { 58 ServerSocketListener server = new ServerSocketListener(ss); 59 server.start(); 60 SocketWriter writer = new SocketWriter(ss.getLocalSocketAddress()); 61 62 // setup and start the recording 63 String recordingPath = event + ".jfr"; 64 log("========= Recording event: " + event); 65 Recording r = new Recording(); 66 r.enable(event); 67 r.setDestination(Paths.get("/", "tmp", recordingPath)); 68 r.start(); 69 70 // start the socker writer thread, write some data into the socket 71 writer.start(); 72 73 // wait for writer thread to terminate, then for server thread, then stop recording 74 writer.joinAndThrow(); 75 server.joinAndThrow(); 76 r.stop(); 77 78 // analyze the recording 79 List<RecordedEvent> events = RecordingFile.readAllEvents(r.getDestination()); 80 events.forEach(e -> log ("event = " + e)); 81 assertTrue(!events.isEmpty(), "No recorded network events"); 82 RecordedEvent e = events.get(0); 83 log(JFR_REPORTED_CONTAINER_HOSTNAME_TAG + e.getString("host")); 84 verifyIpAddress(e.getString("address")); 85 } 86 87 private static void verifyIpAddress(String eventIp) throws Exception { 88 ProcessBuilder pb = new ProcessBuilder("hostname", "--ip-address"); 89 OutputAnalyzer out = new OutputAnalyzer(pb.start()); 90 out.shouldHaveExitValue(0); 91 log("hostname --ip-address returned: " + out.getOutput()); 92 out.shouldContain(eventIp); 93 } 94 95 private static void log(String msg) { 96 System.out.println(msg); 97 } 98 99 100 private static class ServerSocketListener extends Thread { 101 Exception exception; 102 ServerSocket ss; 103 104 ServerSocketListener(ServerSocket socket) throws Exception { 105 ss = socket; 106 ss.setReuseAddress(true); 107 ss.bind(null); 108 log("ServerSocker Local Address: " + ss.getLocalSocketAddress()); 109 } 110 111 public void joinAndThrow() throws Exception { 112 join(); 113 if (exception != null) { 114 throw exception; 115 } 116 } 117 118 public void run() { 119 try { 120 try (Socket s = ss.accept(); InputStream is = s.getInputStream()) { 121 System.out.println("ServerSocketListener: accepted socket connection: s = " + s); 122 is.read(); 123 is.read(); 124 is.read(); 125 } 126 } catch (Exception e) { 127 exception = e; 128 } 129 } 130 } 131 132 133 private static class SocketWriter extends Thread { 134 Exception exception; 135 private SocketAddress ssAddr; 136 137 public SocketWriter(SocketAddress sa) { 138 this.ssAddr = sa; 139 System.out.println("SocketWriter(): sa = " + sa); 140 } 141 142 public void joinAndThrow() throws Exception { 143 join(); 144 if (exception != null) { 145 throw exception; 146 } 147 } 148 149 public void run() { 150 try (Socket s = new Socket()) { 151 s.connect(ssAddr); 152 try (OutputStream os = s.getOutputStream()) { 153 os.write('A'); 154 os.write('B'); 155 os.write('C'); 156 } 157 } catch (Exception e) { 158 exception = e; 159 } 160 } 161 } 162 163 }