| /* |
| * Copyright (c) 2008, 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. |
| */ |
| |
| package com.sun.servicetag; |
| |
| import java.io.*; |
| import java.net.UnknownHostException; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import static com.sun.servicetag.RegistrationDocument.*; |
| |
| /** |
| * A {@code RegistrationData} object is a container of one or more |
| * {@link #getServiceTags service tags} that identify the |
| * components for product registration. |
| * Each {@code RegistrationData} object has a {@link #getRegistrationURN |
| * uniform resource name} (URN) as its identifier. |
| * <a name="EnvMap"></a> |
| * It also has an <i>environment map</i> with |
| * the following elements: |
| * <blockquote> |
| * <table border=0> |
| * <tr> |
| * <td><tt>hostname</tt></td> |
| * <td>Hostname of the system</td> |
| * <td>e.g. woody</td> |
| * </tr> |
| * <tr> |
| * <td><tt>hostId</tt></td> |
| * <td>Host ID of the system</td> |
| * <td>e.g. 83abc1ab</td> |
| * </tr> |
| * <tr> |
| * <td><tt>osName</tt></td> |
| * <td>Operating system name</td> |
| * <td> e.g. SunOS</td> |
| * </tr> |
| * <tr> |
| * <td><tt>osVersion</tt></td> |
| * <td>Operating system version</td> |
| * <td> e.g. 5.10</td> |
| * </tr> |
| * <tr> |
| * <td><tt>osArchitecture</tt></td> |
| * <td>Operating system architecture</td> |
| * <td> e.g. sparc</td> |
| * </tr> |
| * <tr> |
| * <td><tt>systemModel</tt></td> |
| * <td>System model</td> |
| * <td> e.g. SUNW,Sun-Fire-V440</td> |
| * </tr> |
| * <tr> |
| * <td><tt>systemManufacturer</tt></td> |
| * <td>System manufacturer</td> |
| * <td> e.g. Sun Microsystems</td> |
| * </tr> |
| * <tr> |
| * <td><tt>cpuManufacturer</tt></td> |
| * <td>CPU manufacturer</td> |
| * <td> e.g. Sun Microsystems</td> |
| * </tr> |
| * <tr> |
| * <td><tt>serialNumber</tt></td> |
| * <td>System serial number</td> |
| * <td> e.g. BEL078932</td> |
| * </tr> |
| * </table> |
| * </blockquote> |
| * The <tt>hostname</tt> and <tt>osName</tt> element must have a non-empty value. |
| * If an element is not available on a system and their value will be |
| * empty. |
| * <p> |
| * <a name="XMLSchema"> |
| * <b>Registration XML Schema</b></a> |
| * <p> |
| * A {@code RegistrationData} object can be {@link #loadFromXML loaded} from |
| * and {@link #storeToXML stored} into an XML file in the format described |
| * by the |
| * <a href="https://sn-tools.central.sun.com/twiki/pub/ServiceTags/RegistrationRelayService/product_registration.xsd"> |
| * registration data schema</a>. The registration data schema is defined by the |
| * Service Tags Technology. |
| * <p> |
| * Typically the registration data is constructed at installation time |
| * and stored in an XML file for later service tag lookup or registration. |
| * |
| * <p> |
| * <b>Example Usage</b> |
| * <p> |
| * The examples below show how the {@code RegistrationData} can be |
| * used for product registration. |
| * Exception handling is not shown in these examples for clarity. |
| * <ol> |
| * <li>This example shows how the JDK creates a JDK service tag, installs it |
| * in the system service tag registry and adds it to the registration data. |
| * <br> |
| * <blockquote><pre> |
| * // create a service tag object with an instance_urn |
| * ServiceTag st = ServiceTag.newInstance(ServiceTag.generateInstanceURN(), |
| * ....); |
| * // Adds to the system service tag registry if supported |
| * if (Registry.isSupported()) { |
| * Registry.getSystemRegistry().addServiceTag(st); |
| * } |
| * |
| * // add to the registration data |
| * RegistrationData registration = new RegistrationData(); |
| * registration.addServiceTag(st); |
| * </pre></blockquote> |
| * </li> |
| * <li>At this point, the registration data is ready to |
| * send to Sun Connection for registration. This example shows how to register |
| * the JDK via the <i>Registration Relay Service</i>. |
| * <p> |
| * There are several registration services for Sun Connection. For example, |
| * the <a href="https://sn-tools.central.sun.com/twiki/bin/view/ServiceTags/RegistrationRelayService"> |
| * Registration Relay Service</a> is a web application interface that |
| * processes the registration data payload sent via HTTP post |
| * and hosts the registration user interface for a specified |
| * registration URL. Refer to the |
| * Registration Relay Service Specification for details. |
| * <p> |
| * <blockquote><pre> |
| * // Open the connection to the URL of the registration service |
| * HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); |
| * con.setDoInput(true); |
| * con.setDoOutput(true); |
| * con.setUseCaches(false); |
| * con.setAllowUserInteraction(false); |
| * con.setRequestMethod("POST"); |
| * con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\""); |
| * con.connect(); |
| * |
| * // send the registration data to the registration service |
| * OutputStream out = con.getOutputStream(); |
| * registration.storeToXML(out); |
| * out.close(); |
| * </pre></blockquote> |
| * </li> |
| * <li>This example shows how to store the registration data in an XML file. |
| * for later service tag lookup or registration. |
| * <br> |
| * <blockquote><pre> |
| * BufferedOutputStream out = new BufferedOutputStream( |
| * new FileOutputStream(""<JAVA_HOME>/lib/servicetag/registration.xml")); |
| * registration.storeToXML(out); |
| * out.close(); |
| * </pre></blockquote> |
| * </li> |
| * <li>This example shows how to install service tags that are in the |
| * registration data in the system service tag registry when determined |
| * to be available. The system service tag registry might not have existed |
| * when the registration data was constructed. |
| * <br> |
| * <blockquote><pre> |
| * if (Registry.isSupported()) { |
| * Set<ServiceTag> svctags = registration.getServiceTags(); |
| * for (ServiceTag st : svctags) { |
| * Registry.getSystemRegistry().addServiceTag(st); |
| * } |
| * } |
| * </pre></blockquote> |
| * </li> |
| * </ol> |
| * |
| * @see <a href="https://sunconnection.sun.com/inventory">Sun Connection Inventory Channel</a> |
| */ |
| public class RegistrationData { |
| private final Map<String, String> environment = initEnvironment(); |
| private final Map<String, ServiceTag> svcTagMap = |
| new LinkedHashMap<String, ServiceTag>(); |
| private final String urn; |
| |
| /** |
| * Creates a {@code RegistrationData} object with a generated |
| * {@link #getRegistrationURN registration URN}. |
| * The following keys in the {@link #getEnvironmentMap environment map} |
| * will be initialized for the configuration of the |
| * running system: |
| * <blockquote> |
| * <tt>hostname</tt>, <tt>osName</tt>, <tt>osVersion</tt> and |
| * <tt>osArchitecture</tt> |
| * </blockquote> |
| * and the value of other keys may be empty. |
| */ |
| public RegistrationData() { |
| this(Util.generateURN()); |
| SystemEnvironment sysEnv = SystemEnvironment.getSystemEnvironment(); |
| setEnvironment(ST_NODE_HOSTNAME, sysEnv.getHostname()); |
| setEnvironment(ST_NODE_HOST_ID, sysEnv.getHostId()); |
| setEnvironment(ST_NODE_OS_NAME, sysEnv.getOsName()); |
| setEnvironment(ST_NODE_OS_VERSION, sysEnv.getOsVersion()); |
| setEnvironment(ST_NODE_OS_ARCH, sysEnv.getOsArchitecture()); |
| setEnvironment(ST_NODE_SYSTEM_MODEL, sysEnv.getSystemModel()); |
| setEnvironment(ST_NODE_SYSTEM_MANUFACTURER, sysEnv.getSystemManufacturer()); |
| setEnvironment(ST_NODE_CPU_MANUFACTURER, sysEnv.getCpuManufacturer()); |
| setEnvironment(ST_NODE_SERIAL_NUMBER, sysEnv.getSerialNumber()); |
| } |
| |
| // package private |
| RegistrationData(String urn) { |
| this.urn = urn; |
| } |
| |
| private Map<String, String> initEnvironment() { |
| Map<String, String> map = new LinkedHashMap<String, String>(); |
| map.put(ST_NODE_HOSTNAME, ""); |
| map.put(ST_NODE_HOST_ID, ""); |
| map.put(ST_NODE_OS_NAME, ""); |
| map.put(ST_NODE_OS_VERSION, ""); |
| map.put(ST_NODE_OS_ARCH, ""); |
| map.put(ST_NODE_SYSTEM_MODEL, ""); |
| map.put(ST_NODE_SYSTEM_MANUFACTURER, ""); |
| map.put(ST_NODE_CPU_MANUFACTURER, ""); |
| map.put(ST_NODE_SERIAL_NUMBER, ""); |
| return map; |
| } |
| |
| /** |
| * Returns the uniform resource name of this registration data |
| * in this format: |
| * <tt>urn:st:<32-char {@link java.util.UUID uuid}></tt> |
| * |
| * @return the URN of this registration data. |
| */ |
| public String getRegistrationURN() { |
| return urn; |
| } |
| |
| /** |
| * Returns a map containing the environment information for this |
| * registration data. See the set of <a href="#EnvMap">keys</a> |
| * in the environment map. Subsequent update to the environment |
| * map via the {@link #setEnvironment setEnvironment} method will not be reflected |
| * in the returned map. |
| * |
| * @return an environment map for this registration data. |
| */ |
| public Map<String, String> getEnvironmentMap() { |
| return new LinkedHashMap<String,String>(environment); |
| } |
| |
| /** |
| * Sets an element of the specified {@code name} in the environment map |
| * with the given {@code value}. |
| * |
| * @throws IllegalArgumentException if {@code name} is not a valid key |
| * in the environment map, or {@code value} is not valid. |
| */ |
| public void setEnvironment(String name, String value) { |
| if (name == null) { |
| throw new NullPointerException("name is null"); |
| } |
| if (value == null) { |
| throw new NullPointerException("value is null"); |
| } |
| if (environment.containsKey(name)) { |
| if (name.equals(ST_NODE_HOSTNAME) || name.equals(ST_NODE_OS_NAME)) { |
| if (value.length() == 0) { |
| throw new IllegalArgumentException("\"" + |
| name + "\" requires non-empty value."); |
| } |
| } |
| environment.put(name, value); |
| } else { |
| throw new IllegalArgumentException("\"" + |
| name + "\" is not an environment element."); |
| } |
| } |
| |
| /** |
| * Returns all service tags in this registration data. |
| * |
| * @return a {@link Set Set} of the service tags |
| * in this registration data. |
| */ |
| public Set<ServiceTag> getServiceTags() { |
| return new HashSet<ServiceTag>(svcTagMap.values()); |
| } |
| |
| /** |
| * Adds a service tag to this registration data. |
| * If the given service tag has an empty <tt>instance_urn</tt>, |
| * this method will generate a URN and place it in the copy |
| * of the service tag in this registration data. |
| * This method will return the {@code ServiceTag} object |
| * added to this registration data. |
| * |
| * @param st {@code ServiceTag} object to be added. |
| * @return a {@code ServiceTag} object added to this registration data. |
| * |
| * @throws IllegalArgumentException if |
| * a service tag of the same {@link ServiceTag#getInstanceURN |
| * <tt>instance_urn</tt>} already exists in the registry. |
| */ |
| public synchronized ServiceTag addServiceTag(ServiceTag st) { |
| ServiceTag svcTag = ServiceTag.newInstanceWithUrnTimestamp(st); |
| |
| String instanceURN = svcTag.getInstanceURN(); |
| if (svcTagMap.containsKey(instanceURN)) { |
| throw new IllegalArgumentException("Instance_urn = " + instanceURN + |
| " already exists in the registration data."); |
| } else { |
| svcTagMap.put(instanceURN, svcTag); |
| } |
| return svcTag; |
| } |
| |
| /** |
| * Returns a service tag of the given <tt>instance_urn</tt> in this registration |
| * data. |
| * |
| * @param instanceURN the <tt>instance_urn</tt> of the service tag |
| * @return the {@code ServiceTag} object of the given <tt>instance_urn</tt> |
| * if exists; otherwise return {@code null}. |
| */ |
| public synchronized ServiceTag getServiceTag(String instanceURN) { |
| if (instanceURN == null) { |
| throw new NullPointerException("instanceURN is null"); |
| } |
| return svcTagMap.get(instanceURN); |
| } |
| |
| /** |
| * Removes a service tag of the given <tt>instance_urn</tt> from this |
| * registration data. |
| * |
| * @param instanceURN the <tt>instance_urn</tt> of |
| * the service tag to be removed. |
| * |
| * @return the removed {@code ServiceTag} object; |
| * or {@code null} if the service tag does not exist in this |
| * registration data. |
| */ |
| public synchronized ServiceTag removeServiceTag(String instanceURN) { |
| if (instanceURN == null) { |
| throw new NullPointerException("instanceURN is null"); |
| } |
| |
| ServiceTag svcTag = null; |
| if (svcTagMap.containsKey(instanceURN)) { |
| svcTag = svcTagMap.remove(instanceURN); |
| } |
| return svcTag; |
| } |
| |
| /** |
| * Updates the <tt>product_defined_instance_id</tt> in the service tag |
| * of the given <tt>instance_urn</tt> in this registration data. |
| * |
| * @param instanceURN the <tt>instance_urn</tt> of the service tag to be updated. |
| * @param productDefinedInstanceID the value of the |
| * <tt>product_defined_instance_id</tt> to be set. |
| * |
| * @return the updated {@code ServiceTag} object; |
| * or {@code null} if the service tag does not exist in this |
| * registration data. |
| */ |
| public synchronized ServiceTag updateServiceTag(String instanceURN, |
| String productDefinedInstanceID) { |
| ServiceTag svcTag = getServiceTag(instanceURN); |
| if (svcTag == null) { |
| return null; |
| } |
| |
| svcTag = ServiceTag.newInstanceWithUrnTimestamp(svcTag); |
| // update the product defined instance ID field |
| svcTag.setProductDefinedInstanceID(productDefinedInstanceID); |
| svcTagMap.put(instanceURN, svcTag); |
| return svcTag; |
| } |
| |
| /** |
| * Reads the registration data from the XML document on the |
| * specified input stream. The XML document must be |
| * in the format described by the <a href="#XMLSchema"> |
| * registration data schema</a>. |
| * The specified stream is closed after this method returns. |
| * |
| * @param in the input stream from which to read the XML document. |
| * @return a {@code RegistrationData} object read from the input |
| * stream. |
| * |
| * @throws IllegalArgumentException if the input stream |
| * contains an invalid registration data. |
| * |
| * @throws IOException if an error occurred when reading from the input stream. |
| */ |
| public static RegistrationData loadFromXML(InputStream in) throws IOException { |
| try { |
| return RegistrationDocument.load(in); |
| } finally { |
| in.close(); |
| } |
| } |
| |
| /** |
| * Writes the registration data to the specified output stream |
| * in the format described by the <a href="#XMLSchema"> |
| * registration data schema</a> with "UTF-8" encoding. |
| * The specified stream remains open after this method returns. |
| * |
| * @param os the output stream on which to write the XML document. |
| * |
| * @throws IOException if an error occurred when writing to the output stream. |
| */ |
| public void storeToXML(OutputStream os) throws IOException { |
| RegistrationDocument.store(os, this); |
| os.flush(); |
| } |
| |
| /** |
| * Returns a newly allocated byte array containing the registration |
| * data in XML format. |
| * |
| * @return a newly allocated byte array containing the registration |
| * data in XML format. |
| */ |
| public byte[] toXML() { |
| try { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| storeToXML(out); |
| return out.toByteArray(); |
| } catch (IOException e) { |
| // should not reach here |
| return new byte[0]; |
| } |
| } |
| |
| /** |
| * Returns a string representation of this registration data in XML |
| * format. |
| * |
| * @return a string representation of this registration data in XML |
| * format. |
| */ |
| @Override |
| public String toString() { |
| try { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| storeToXML(out); |
| return out.toString("UTF-8"); |
| } catch (IOException e) { |
| // should not reach here |
| return "Error creating the return string."; |
| } |
| } |
| } |