8004213: JDP packet needs pid, broadcast interval and rmi server hostname fields
authordsamersoff
Sat, 19 Oct 2013 00:05:42 +0400
changeset 21295 5c73446feb1f
parent 21294 545dfa5b947e
child 21296 de1c1faa6f77
8004213: JDP packet needs pid, broadcast interval and rmi server hostname fields Summary: Add some extra fileds to jdp packet Reviewed-by: allwin, sla, hirt
jdk/src/share/classes/sun/management/jdp/JdpController.java
jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java
jdk/test/sun/management/jdp/JdpClient.java
jdk/test/sun/management/jdp/JdpDoSomething.java
jdk/test/sun/management/jdp/JdpTest.sh
--- a/jdk/src/share/classes/sun/management/jdp/JdpController.java	Fri Oct 18 16:28:35 2013 +0100
+++ b/jdk/src/share/classes/sun/management/jdp/JdpController.java	Sat Oct 19 00:05:42 2013 +0400
@@ -29,6 +29,12 @@
 import java.net.UnknownHostException;
 import java.util.UUID;
 
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import sun.management.VMManagement;
+
 /**
  * JdpController is responsible to create and manage a broadcast loop
  *
@@ -126,6 +132,25 @@
         }
     }
 
+    // Get the process id of the current running Java process
+    private static Integer getProcessId() {
+        try {
+            // Get the current process id using a reflection hack
+            RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+            Field jvm = runtime.getClass().getDeclaredField("jvm");
+            jvm.setAccessible(true);
+
+            VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+            Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
+            pid_method.setAccessible(true);
+            Integer pid = (Integer) pid_method.invoke(mgmt);
+            return pid;
+        } catch(Exception ex) {
+            return null;
+        }
+    }
+
+
     /**
      * Starts discovery service
      *
@@ -173,6 +198,20 @@
         // it the key is skipped. PacketWriter is responsible to skip keys having null value.
         packet.setInstanceName(instanceName);
 
+        // Set rmi server hostname if it explicitly specified by user with
+        // java.rmi.server.hostname
+        String rmiHostname = System.getProperty("java.rmi.server.hostname");
+        packet.setRmiHostname(rmiHostname);
+
+        // Set broadcast interval
+        packet.setBroadcastInterval(new Integer(pause).toString());
+
+        // Set process id
+        Integer pid = getProcessId();
+        if (pid != null) {
+           packet.setProcessId(pid.toString());
+        }
+
         JdpBroadcaster bcast = new JdpBroadcaster(address, sourceAddress, port, ttl);
 
         // Stop discovery service if it's already running
--- a/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java	Fri Oct 18 16:28:35 2013 +0100
+++ b/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java	Sat Oct 19 00:05:42 2013 +0400
@@ -64,11 +64,27 @@
      * Name of Java instance
      */
     public final static String INSTANCE_NAME_KEY = "INSTANCE_NAME";
+    /**
+     * PID of java process, optional presented if it could be obtained
+     */
+    public final static String PROCESS_ID_KEY = "PROCESS_ID";
+    /**
+     * Hostname of rmi server, optional presented if user overrides rmi server
+     * hostname by java.rmi.server.hostname property
+     */
+    public final static String RMI_HOSTNAME_KEY = "RMI_HOSTNAME";
+    /**
+     * Configured broadcast interval, optional
+     */
+    public final static String BROADCAST_INTERVAL_KEY = "BROADCAST_INTERVAL";
 
     private UUID id;
     private String mainClass;
     private String jmxServiceUrl;
     private String instanceName;
+    private String processId;
+    private String rmiHostname;
+    private String broadcastInterval;
 
     /**
      * Create new instance from user provided data. Set mandatory fields
@@ -99,6 +115,9 @@
         this.jmxServiceUrl = p.get(JMX_SERVICE_URL_KEY);
         this.mainClass = p.get(MAIN_CLASS_KEY);
         this.instanceName = p.get(INSTANCE_NAME_KEY);
+        this.processId = p.get(PROCESS_ID_KEY);
+        this.rmiHostname = p.get(RMI_HOSTNAME_KEY);
+        this.broadcastInterval = p.get(BROADCAST_INTERVAL_KEY);
     }
 
     /**
@@ -150,6 +169,30 @@
         return instanceName;
     }
 
+    public String getProcessId() {
+        return processId;
+    }
+
+    public void setProcessId(String processId) {
+        this.processId = processId;
+    }
+
+    public String getRmiHostname() {
+        return rmiHostname;
+    }
+
+    public void setRmiHostname(String rmiHostname) {
+        this.rmiHostname = rmiHostname;
+    }
+
+    public String getBroadcastInterval() {
+        return broadcastInterval;
+    }
+
+    public void setBroadcastInterval(String broadcastInterval) {
+        this.broadcastInterval = broadcastInterval;
+    }
+
     /**
      *
      * @return assembled packet ready to be sent across a Net
@@ -164,6 +207,10 @@
         writer.addEntry(MAIN_CLASS_KEY, mainClass);
         writer.addEntry(JMX_SERVICE_URL_KEY, jmxServiceUrl);
         writer.addEntry(INSTANCE_NAME_KEY, instanceName);
+        writer.addEntry(PROCESS_ID_KEY, processId);
+        writer.addEntry(RMI_HOSTNAME_KEY, rmiHostname);
+        writer.addEntry(BROADCAST_INTERVAL_KEY, broadcastInterval);
+
         return writer.getPacketBytes();
     }
 
--- a/jdk/test/sun/management/jdp/JdpClient.java	Fri Oct 18 16:28:35 2013 +0100
+++ b/jdk/test/sun/management/jdp/JdpClient.java	Sat Oct 19 00:05:42 2013 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -35,8 +35,10 @@
 import java.nio.channels.Selector;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.Map;
 import sun.management.jdp.JdpException;
 import sun.management.jdp.JdpJmxPacket;
+import sun.management.jdp.JdpPacketReader;
 
 public class JdpClient {
 
@@ -47,6 +49,31 @@
         private static int maxPacketCount = 1;
         private static int maxEmptyPacketCount = 10;
 
+        private void get(Map<?,?> map, String key)
+            throws JdpException {
+
+            if (map.get(key) == null) {
+                  throw new JdpException("Test failed, packet field " + key + " missed");
+            }
+        }
+
+        private void checkFieldPresence(JdpJmxPacket p)
+            throws IOException, JdpException {
+
+            byte[] b = p.getPacketData();
+
+            JdpPacketReader reader = new JdpPacketReader(b);
+            Map<String,String> pMap = reader.getDiscoveryDataAsMap();
+
+            get(pMap, JdpJmxPacket.UUID_KEY);
+            get(pMap, JdpJmxPacket.MAIN_CLASS_KEY);
+            get(pMap, JdpJmxPacket.JMX_SERVICE_URL_KEY);
+            // get(pMap, JdpJmxPacket.INSTANCE_NAME_KEY);
+            get(pMap, JdpJmxPacket.PROCESS_ID_KEY);
+            get(pMap, JdpJmxPacket.BROADCAST_INTERVAL_KEY);
+            get(pMap, JdpJmxPacket.RMI_HOSTNAME_KEY);
+        }
+
 
         PacketListener(DatagramChannel channel) {
             this.channel = channel;
@@ -67,6 +94,8 @@
                 try {
                     while (true) {
 
+                        // Use tcpdump -U -w - -s 1400 -c 2 -vv port 7095
+                        // to verify that correct packet being sent
                         sel.selectedKeys().clear();
                         buf.rewind();
 
@@ -87,10 +116,10 @@
                         buf.flip();
                         byte[] dgramData = new byte[buf.remaining()];
                         buf.get(dgramData);
-
                         try {
                             JdpJmxPacket packet = new JdpJmxPacket(dgramData);
                             JdpDoSomething.printJdpPacket(packet);
+                            checkFieldPresence(packet);
                             if(++count > maxPacketCount){
                                    break;
                             }
--- a/jdk/test/sun/management/jdp/JdpDoSomething.java	Fri Oct 18 16:28:35 2013 +0100
+++ b/jdk/test/sun/management/jdp/JdpDoSomething.java	Sat Oct 19 00:05:42 2013 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -32,7 +32,7 @@
 public class JdpDoSomething {
 
     private static final String lockFileName = "JdpDoSomething.lck";
-    private static final boolean verbose=false;
+    private static final boolean verbose = false;
 
     public static boolean getVerbose(){
         return verbose;
@@ -52,6 +52,9 @@
             System.out.println("Jmx: " + p.getJmxServiceUrl());
             System.out.println("Main: " + p.getMainClass());
             System.out.println("InstanceName: " + p.getInstanceName());
+            System.out.println("ProccessId: " + p.getProcessId());
+            System.out.println("BroadcastInterval: " + p.getBroadcastInterval());
+            System.out.println("Rmi Hostname: " + p.getRmiHostname());
 
             System.out.flush();
         }
--- a/jdk/test/sun/management/jdp/JdpTest.sh	Fri Oct 18 16:28:35 2013 +0100
+++ b/jdk/test/sun/management/jdp/JdpTest.sh	Sat Oct 19 00:05:42 2013 +0400
@@ -1,6 +1,6 @@
 #!/bin/sh -x
 
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2013, 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
@@ -56,7 +56,7 @@
 
     if [ ! -d ${_testclasses} ]
     then
-	  mkdir -p ${_testclasses}
+       mkdir -p ${_testclasses}
     fi
 
     rm -f ${_testclasses}/*.class
@@ -64,7 +64,7 @@
     # Compile testcase
     ${COMPILEJAVA}/bin/javac -XDignore.symbol.file -d ${_testclasses} \
                                              JdpUnitTest.java \
-                                             JdpDoSomething.java  \
+                                             JdpDoSomething.java \
                                              JdpClient.java
 
 
@@ -84,10 +84,10 @@
   ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} ${testappname}  >> ${_logname} 2>&1 &
  _last_pid=$!
 
-# wait until VM is actually starts. 
+# wait until VM is actually starts.
 # please note, if vm doesn't start for some reason
 # jtreg kills the test by timeout. Don't file a bug.
-  cnt=1 
+  cnt=1
   while true
   do
     npid=`_get_pid`
@@ -135,7 +135,6 @@
     -Dcom.sun.management.jdp.port=${_port} \
     -Dcom.sun.management.jdp.address=${_ip} \
   JdpClient
-
 }
 
 
@@ -156,18 +155,20 @@
     _echo "**** Test one ****"
 
     _app_start JdpUnitTest \
-    -Dcom.sun.management.jdp.port=${_port} \
-    -Dcom.sun.management.jdp.address=${_ip} \
-    -Dcom.sun.management.jdp.pause=5
+        -Dcom.sun.management.jdp.port=${_port} \
+        -Dcom.sun.management.jdp.address=${_ip} \
+        -Dcom.sun.management.jdp.name=testme \
+        -Djava.rmi.server.hostname=localhost \
+        -Dcom.sun.management.jdp.pause=5
 
     res=`_testme`
 
     case "${res}" in
      OK*)
-	_echo "Passed"
+        _echo "Passed"
      ;;
      *)
-	_echo "Failed!"
+        _echo "Failed!"
      ;;
     esac
 
@@ -179,21 +180,23 @@
     _echo "**** Test two ****"
 
     _app_start JdpDoSomething \
-     -Dcom.sun.management.jdp.port=${_port} \
-     -Dcom.sun.management.jdp.address=${_ip} \
-     -Dcom.sun.management.jdp.pause=5 \
-     -Dcom.sun.management.jmxremote.port=${_jmxport} \
-     -Dcom.sun.management.jmxremote.authenticate=false \
-     -Dcom.sun.management.jmxremote.ssl=false
+        -Dcom.sun.management.jdp.port=${_port} \
+        -Dcom.sun.management.jdp.address=${_ip} \
+        -Dcom.sun.management.jdp.pause=5 \
+        -Dcom.sun.management.jdp.name=testme \
+        -Djava.rmi.server.hostname=localhost \
+        -Dcom.sun.management.jmxremote.port=${_jmxport} \
+        -Dcom.sun.management.jmxremote.authenticate=false \
+        -Dcom.sun.management.jmxremote.ssl=false
 
     res=`_testme`
 
     case "${res}" in
      OK*)
-	_echo "Passed"
+        _echo "Passed"
      ;;
      *)
-	_echo "Failed!"
+        _echo "Failed!"
      ;;
     esac
 
@@ -218,10 +221,10 @@
 
     case "${res}" in
      OK*)
-	_echo "Passed"
+        _echo "Passed"
      ;;
      *)
-	_echo "Failed!"
+        _echo "Failed!"
      ;;
     esac
 
@@ -233,19 +236,21 @@
     _echo "**** Test four ****"
 
     _app_start JdpDoSomething \
-     -Dcom.sun.management.jmxremote.autodiscovery=true \
-     -Dcom.sun.management.jmxremote.port=${_jmxport} \
-     -Dcom.sun.management.jmxremote.authenticate=false \
-     -Dcom.sun.management.jmxremote.ssl=false
+        -Dcom.sun.management.jmxremote.autodiscovery=true \
+        -Dcom.sun.management.jdp.name=testme \
+        -Djava.rmi.server.hostname=localhost \
+        -Dcom.sun.management.jmxremote.port=${_jmxport} \
+        -Dcom.sun.management.jmxremote.authenticate=false \
+        -Dcom.sun.management.jmxremote.ssl=false
 
     res=`_testme`
 
     case "${res}" in
      OK*)
-	_echo "Passed"
+        _echo "Passed"
      ;;
      *)
-	_echo "Failed!"
+        _echo "Failed!"
      ;;
     esac
 
@@ -269,10 +274,10 @@
 
     case "${res}" in
      OK*)
-	_echo "Passed"
+        _echo "Passed"
      ;;
      *)
-	_echo "Failed!"
+        _echo "Failed!"
      ;;
     esac
 
@@ -300,28 +305,28 @@
 
 for parm in "$@"
 do
-   case $parm in
-  --verbose)      _verbose=yes  ;;
-  --jtreg)        _jtreg=yes    ;;
-  --no-compile)   _compile=no   ;;
-  --testsuite=*)  _testsuite=`_echo $parm | sed "s,^--.*=\(.*\),\1,"`  ;;
-  *)
-     echo "Undefined parameter $parm. Try --help for help"
-     exit
-   ;;
- esac
+  case $parm in
+      --verbose)      _verbose=yes  ;;
+      --jtreg)        _jtreg=yes    ;;
+      --no-compile)   _compile=no   ;;
+      --testsuite=*)  _testsuite=`_echo $parm | sed "s,^--.*=\(.*\),\1,"`  ;;
+      *)
+        echo "Undefined parameter $parm. Try --help for help"
+        exit
+      ;;
+  esac
 done
 
 if [ "${_compile}" = "yes" ]
 then
- _do_compile
+  _do_compile
 fi
 
 if [ "${_jtreg}" = "yes" ]
 then
- _testclasses=${TESTCLASSES}
- _testsrc=${TESTSRC}
- _logname="output.txt"
+  _testclasses=${TESTCLASSES}
+  _testsrc=${TESTSRC}
+  _logname="output.txt"
 fi
 
 # Make sure _tesclasses is absolute path