Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * --- * Modificacin apoyada por la Superintendencia de Servicios de Certificacin * Electrnica (SUSCERTE) durante 2010-2014 por: * Ing. Felix D. Lopez M. - flex.developments en gmail | flopez en suscerte gob ve * Ing. Yessica De Ascencao - yessicadeascencao@gmail.com | ydeascencao en suscerte gob ve */ package flex.helpers; import flex.helpers.exceptions.NTPHelperException; import flex.helpers.i18n.I18n; import java.io.IOException; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.net.ntp.NTPUDPClient; import org.apache.commons.net.ntp.NtpV3Packet; import org.apache.commons.net.ntp.TimeInfo; //import java.net.UnknownHostException; //import java.text.NumberFormat; //import org.apache.commons.net.ntp.NtpUtils; /** * This is an example program demonstrating how to use the NTPUDPClient * class. This program sends a Datagram client request packet to a * Network time Protocol (NTP) service port on a specified server, * retrieves the time, and prints it to standard output along with * the fields from the NTP message header (e.g. stratum level, reference id, * poll interval, root delay, mode, ...) * See <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc868.txt"> the spec </A> * for details. * <p> * Usage: NTPClient <hostname-or-address-list> * <br> * Example: NTPClient clock.psu.edu * * @author Jason Mathews, MITRE Corp * ---- * @author Ing. Felix D. Lopez M. - flex.developments en gmail * @author Ing. Yessica De Ascencao - yessicadeascencao@gmail.com * @version 1.0 **/ public final class NTPHelper { final public static int NTP_TIMEOUT = 5000; /** * Solicitar hora y fecha a un pool de servidores NTP, donde se devolver * solo la hora del primer servidor que responda. Adicionalmente se puede * indicar un servidor como principal el cual se considerara como un favorito. * * @param ntpServers Lista de Strings con el pool de servidores NTP. * @param principalNTPServer * @return Date con la respuesta del primer servidor que responda * @throws NTPHelperException */ public static Date getDateTime(List<String> ntpServers, String principalNTPServer) throws NTPHelperException { Map<String, Date> result = getServerAndDateTime(ntpServers, principalNTPServer); Iterator it = result.entrySet().iterator(); Map.Entry e = (Map.Entry) it.next(); return (Date) e.getValue(); } /** * Solicitar hora y fecha a un pool de servidores NTP, donde se devolver * un HashMap con el servidor y la hora del primer servidor que responda. * Adicionalmente se puede indicar un servidor como principal el cual se * considerara como un favorito. * * @param ntpServers Lista de Strings con el pool de servidores NTP. * @param principalNTPServer * @return Date con la respuesta del primer servidor que responda * @throws NTPHelperException */ public static Map<String, Date> getServerAndDateTime(List<String> ntpServers, String principalNTPServer) throws NTPHelperException { Map<String, Date> result = new HashMap<>(); Date ntpTime = null; String trazaNTP = ""; //Intentar obtener la hora desde el NTP principal if (principalNTPServer != null) try { ntpTime = getDateTime(principalNTPServer); result.put(principalNTPServer, ntpTime); return result; } catch (NTPHelperException ex) { //No logra obtener la hora. Genera traza e intenta con la lista trazaNTP = I18n.get(I18n.L_NTP_TRACE, principalNTPServer, ex.getLocalizedMessage()); } //Validar la lista if (ntpServers == null) throw new NTPHelperException(NTPHelperException.ERROR_NTP_EMPTY); if (ntpServers.isEmpty()) throw new NTPHelperException(NTPHelperException.ERROR_NTP_EMPTY); //Intenta obtener la hora desde cualquier servidor de la lista for (String ntpServer : ntpServers) { try { ntpTime = getDateTime(ntpServer); result.put(ntpServer, ntpTime); return result; } catch (NTPHelperException ex) { //No se logra la conexion NTP trazaNTP = trazaNTP + I18n.get(I18n.L_NTP_TRACE, ntpServer, ex.getLocalizedMessage()); } } //No logra obtener la hora de ningun NTP. throw new NTPHelperException(trazaNTP); } /** * Solicitar hora y fecha a servidor NTP. * * @param ntpServer Direccin ip del servidor NTP * @return * @throws NTPHelperException */ public static Date getDateTime(String ntpServer) throws NTPHelperException { if (ntpServer == null) throw new NTPHelperException(NTPHelperException.ERROR_NTP_EMPTY); if (ntpServer.isEmpty()) throw new NTPHelperException(NTPHelperException.ERROR_NTP_EMPTY); Date time = null; NTPUDPClient client = new NTPUDPClient(); client.setDefaultTimeout(NTP_TIMEOUT); try { client.open(); InetAddress hostAddr = InetAddress.getByName(ntpServer); TimeInfo info = client.getTime(hostAddr); time = processResponse(info); } catch (UnknownHostException ex) { throw new NTPHelperException(NTPHelperException.ERROR_NTP_UNKNOWN_HOST, ex.getCause()); } catch (SocketException ex) { throw new NTPHelperException(NTPHelperException.ERROR_NTP_SOCKET, ex.getCause()); } catch (IOException ex) { throw new NTPHelperException(NTPHelperException.ERROR_NTP_READ, ex.getCause()); } finally { client.close(); System.gc(); } return time; } /** * Process <code>TimeInfo</code> object and print its details. * * @param info <code>TimeInfo</code> object. * @return */ public static Date processResponse(TimeInfo info) { NtpV3Packet message = info.getMessage(); org.apache.commons.net.ntp.TimeStamp rcvNtpTime = message.getReceiveTimeStamp(); //Receive Time is time request received by server (t2) return new Date(rcvNtpTime.getTime()); //OJO... Para mejorar // TimeStamp refNtpTime = message.getReferenceTimeStamp(); // TimeStamp origNtpTime = message.getOriginateTimeStamp(); //Originate Time is time request sent by client (t1) // TimeStamp xmitNtpTime = message.getTransmitTimeStamp(); //Transmit time is time reply sent by server (t3) // long destTime = info.getReturnTime(); // TimeStamp destNtpTime = TimeStamp.getNtpTime(destTime); //Destination time is time reply received by client (t4) // int stratum = message.getStratum(); //Stratum should be 0..15... // String refType; // if (stratum <= 0) { // refType = "(Unspecified or Unavailable)"; // } else if (stratum == 1) { // refType = "(Primary Reference; e.g., GPS)"; //GPS, radio clock, etc. // } else { // refType = "(Secondary Reference; e.g. via NTP or SNTP)"; // } // // int version = message.getVersion(); // int li = message.getLeapIndicator(); // int poll = message.getPoll(); //poll value typically btwn MINPOLL (4) and MAXPOLL (14) // double disp = message.getRootDispersionInMillisDouble(); // int refId = message.getReferenceId(); // String refAddr = NtpUtils.getHostAddress(refId); // String refName = null; // if (refId != 0) { // if (refAddr.compareTo("127.127.1.0") == 0) { // refName = "LOCAL"; //This is the ref address for the Local Clock // } else if (stratum >= 2) { // //If reference id has 127.127 prefix then it uses its own reference clock // //defined in the form 127.127.clock-type.unit-num (e.g. 127.127.8.0 mode 5 // //for GENERIC DCF77 AM; see refclock.htm from the NTP software distribution. // if (!refAddr.startsWith("127.127")) { // try { // InetAddress addr = InetAddress.getByName(refAddr); // String name = addr.getHostName(); // if (name != null && !(name.compareTo(refAddr) == 0)) { // refName = name; // } // } catch (UnknownHostException e) { // //some stratum-2 servers sync to ref clock device but fudge stratum level higher... (e.g. 2) // //ref not valid host maybe it's a reference clock name? // //otherwise just show the ref IP address. // refName = NtpUtils.getReferenceClock(message); // } // } // } else if (version >= 3 && (stratum == 0 || stratum == 1)) { // refName = NtpUtils.getReferenceClock(message); // //refname usually have at least 3 characters (e.g. GPS, WWV, LCL, etc.) // } // //otherwise give up on naming the beast... // } // if (refName != null && refName.length() > 1) { // refAddr += " (" + refName + ")"; // } // // info.computeDetails(); // compute offset/delay if not already done // Long offsetValue = info.getOffset(); // Long delayValue = info.getDelay(); // String delay = (delayValue == null) ? "N/A" : delayValue.toString(); // String offset = (offsetValue == null) ? "N/A" : offsetValue.toString(); // final NumberFormat numberFormat = new java.text.DecimalFormat("0.00"); // // System.out.println(" Stratum: " + stratum + " " + refType); // System.out.println(" leap=" + li + ", version=" + version + ", precision=" + message.getPrecision()); // System.out.println(" mode: " + message.getModeName() + " (" + message.getMode() + ")"); // System.out.println(" poll: " + (poll <= 0 ? 1 : (int) Math.pow(2, poll)) + " seconds" + " (2 ** " + poll + ")"); // System.out.println(" rootdelay=" + numberFormat.format(message.getRootDelayInMillisDouble()) + ", rootdispersion(ms): " + numberFormat.format(disp)); // System.out.println(" Reference Identifier:\t" + refAddr); // System.out.println(" Reference Timestamp:\t" + refNtpTime + " " + refNtpTime.toDateString()); // System.out.println(" Originate Timestamp:\t" + origNtpTime + " " + origNtpTime.toDateString()); // System.out.println(" Receive Timestamp:\t" + rcvNtpTime + " " + rcvNtpTime.toDateString()); // System.out.println(" Transmit Timestamp:\t" + xmitNtpTime + " " + xmitNtpTime.toDateString()); // System.out.println(" Destination Timestamp:\t" + destNtpTime + " " + destNtpTime.toDateString()); // System.out.println(" Roundtrip delay(ms)=" + delay + ", clock offset(ms)=" + offset); //offset in ms } }