1/* 2 * Copyright (c) 2013, 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 */ 25package sun.management.jdp; 26 27import java.io.IOException; 28import java.util.HashMap; 29import java.util.Map; 30import java.util.Objects; 31import java.util.UUID; 32 33/** 34 * A packet to broadcasts JMX URL 35 * 36 * Fields: 37 * 38 * <ul> 39 * <li>UUID - broadcast session ID, changed every time when we start/stop 40 * discovery service</li> 41 * <li>JMX_URL - URL to connect to JMX service</li> 42 * <li>MAIN_CLASS - optional name of main class, filled from sun.java.command stripped for 43 * security reason to first space</li> 44 * <li>INSTANCE_NAME - optional custom name of particular instance as provided by customer</li> 45 * </ul> 46 */ 47public final class JdpJmxPacket 48 extends JdpGenericPacket 49 implements JdpPacket { 50 51 /** 52 * Session ID 53 */ 54 public final static String UUID_KEY = "DISCOVERABLE_SESSION_UUID"; 55 /** 56 * Name of main class 57 */ 58 public final static String MAIN_CLASS_KEY = "MAIN_CLASS"; 59 /** 60 * JMX service URL 61 */ 62 public final static String JMX_SERVICE_URL_KEY = "JMX_SERVICE_URL"; 63 /** 64 * Name of Java instance 65 */ 66 public final static String INSTANCE_NAME_KEY = "INSTANCE_NAME"; 67 /** 68 * PID of java process, optional presented if it could be obtained 69 */ 70 public final static String PROCESS_ID_KEY = "PROCESS_ID"; 71 /** 72 * Hostname of rmi server, optional presented if user overrides rmi server 73 * hostname by java.rmi.server.hostname property 74 */ 75 public final static String RMI_HOSTNAME_KEY = "RMI_HOSTNAME"; 76 /** 77 * Configured broadcast interval, optional 78 */ 79 public final static String BROADCAST_INTERVAL_KEY = "BROADCAST_INTERVAL"; 80 81 private UUID id; 82 private String mainClass; 83 private String jmxServiceUrl; 84 private String instanceName; 85 private String processId; 86 private String rmiHostname; 87 private String broadcastInterval; 88 89 /** 90 * Create new instance from user provided data. Set mandatory fields 91 * 92 * @param id - java instance id 93 * @param jmxServiceUrl - JMX service url 94 */ 95 public JdpJmxPacket(UUID id, String jmxServiceUrl) { 96 this.id = id; 97 this.jmxServiceUrl = jmxServiceUrl; 98 } 99 100 /** 101 * Create new instance from network data Parse packet and set fields. 102 * 103 * @param data - raw packet data as it came from a Net 104 * @throws JdpException 105 */ 106 public JdpJmxPacket(byte[] data) 107 throws JdpException { 108 JdpPacketReader reader; 109 110 reader = new JdpPacketReader(data); 111 Map<String, String> p = reader.getDiscoveryDataAsMap(); 112 113 String sId = p.get(UUID_KEY); 114 this.id = (sId == null) ? null : UUID.fromString(sId); 115 this.jmxServiceUrl = p.get(JMX_SERVICE_URL_KEY); 116 this.mainClass = p.get(MAIN_CLASS_KEY); 117 this.instanceName = p.get(INSTANCE_NAME_KEY); 118 this.processId = p.get(PROCESS_ID_KEY); 119 this.rmiHostname = p.get(RMI_HOSTNAME_KEY); 120 this.broadcastInterval = p.get(BROADCAST_INTERVAL_KEY); 121 } 122 123 /** 124 * Set main class field 125 * 126 * @param mainClass - main class of running app 127 */ 128 public void setMainClass(String mainClass) { 129 this.mainClass = mainClass; 130 } 131 132 /** 133 * Set instance name field 134 * 135 * @param instanceName - name of instance as provided by customer 136 */ 137 public void setInstanceName(String instanceName) { 138 this.instanceName = instanceName; 139 } 140 141 /** 142 * @return id of discovery session 143 */ 144 public UUID getId() { 145 return id; 146 } 147 148 /** 149 * 150 * @return main class field 151 */ 152 public String getMainClass() { 153 return mainClass; 154 } 155 156 /** 157 * 158 * @return JMX service URL 159 */ 160 public String getJmxServiceUrl() { 161 return jmxServiceUrl; 162 } 163 164 /** 165 * 166 * @return instance name 167 */ 168 public String getInstanceName() { 169 return instanceName; 170 } 171 172 public String getProcessId() { 173 return processId; 174 } 175 176 public void setProcessId(String processId) { 177 this.processId = processId; 178 } 179 180 public String getRmiHostname() { 181 return rmiHostname; 182 } 183 184 public void setRmiHostname(String rmiHostname) { 185 this.rmiHostname = rmiHostname; 186 } 187 188 public String getBroadcastInterval() { 189 return broadcastInterval; 190 } 191 192 public void setBroadcastInterval(String broadcastInterval) { 193 this.broadcastInterval = broadcastInterval; 194 } 195 196 /** 197 * 198 * @return assembled packet ready to be sent across a Net 199 * @throws IOException 200 */ 201 @Override 202 public byte[] getPacketData() throws IOException { 203 // Assemble packet from fields to byte array 204 JdpPacketWriter writer; 205 writer = new JdpPacketWriter(); 206 writer.addEntry(UUID_KEY, (id == null) ? null : id.toString()); 207 writer.addEntry(MAIN_CLASS_KEY, mainClass); 208 writer.addEntry(JMX_SERVICE_URL_KEY, jmxServiceUrl); 209 writer.addEntry(INSTANCE_NAME_KEY, instanceName); 210 writer.addEntry(PROCESS_ID_KEY, processId); 211 writer.addEntry(RMI_HOSTNAME_KEY, rmiHostname); 212 writer.addEntry(BROADCAST_INTERVAL_KEY, broadcastInterval); 213 214 return writer.getPacketBytes(); 215 } 216 217 /** 218 * 219 * @return packet hash code 220 */ 221 @Override 222 public int hashCode() { 223 int hash = 1; 224 hash = hash * 31 + id.hashCode(); 225 hash = hash * 31 + jmxServiceUrl.hashCode(); 226 return hash; 227 } 228 229 /** 230 * Compare two packets 231 * 232 * @param o - packet to compare 233 * @return either packet equals or not 234 */ 235 @Override 236 public boolean equals(Object o) { 237 238 if (o == null || ! (o instanceof JdpJmxPacket) ){ 239 return false; 240 } 241 242 JdpJmxPacket p = (JdpJmxPacket) o; 243 return Objects.equals(id, p.getId()) && Objects.equals(jmxServiceUrl, p.getJmxServiceUrl()); 244 } 245} 246