NTPDate.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */



  20. package org.openspcoop2.utils.date;

  21. import java.net.InetAddress;
  22. import java.sql.Timestamp;
  23. import java.util.Calendar;
  24. import java.util.Date;
  25. import java.util.GregorianCalendar;
  26. import java.util.Map;
  27. import java.util.concurrent.ConcurrentHashMap;

  28. import org.apache.commons.net.ntp.NTPUDPClient;
  29. import org.apache.commons.net.ntp.TimeInfo;
  30. import org.openspcoop2.utils.SemaphoreLock;
  31. import org.openspcoop2.utils.UtilsException;

  32. /**
  33.  * Classe per la produzione di date utilizzando un server NTP
  34.  *
  35.  * @author Poli Andrea (apoli@link.it)
  36.  * @author $Author$
  37.  * @version $Rev$, $Date$
  38.  */
  39. public class NTPDate implements IDate {

  40.     private static InetAddress server = null;
  41.     private static NTPUDPClient udpClient = null;
  42.     private static int defaultTimeout = -1;
  43.     private static Map<String,Date> time = null;
  44.     private static boolean cacheEnabled = true;
  45.     private static int cacheRefresh = 100;
  46.    
  47.     private static org.openspcoop2.utils.Semaphore semaphore = new org.openspcoop2.utils.Semaphore("NTPDate");
  48.    
  49.     private static Date getDateCached() throws Exception{
  50.        
  51.         if(NTPDate.cacheEnabled==false){
  52.             TimeInfo tInfo = NTPDate.udpClient.getTime(NTPDate.server);
  53.             return tInfo.getMessage().getReceiveTimeStamp().getDate();
  54.         }
  55.         else{
  56.             String key = (System.currentTimeMillis() / (NTPDate.cacheRefresh)) + ""; // al massimo vengono eseguite 10 richieste al secondo.
  57.             if(NTPDate.time.containsKey(key)){
  58.                 //System.out.println("NOW ["+key+"] from cache");
  59.                 return NTPDate.time.get(key);
  60.             }else{
  61.                 //synchronized(NTPDate.time){
  62.                 SemaphoreLock lock = semaphore.acquire("getDateCached");
  63.                 try {
  64.                     if(NTPDate.time.containsKey(key)){
  65.                         //System.out.println("NOW ["+key+"] from cache sync");
  66.                         return NTPDate.time.get(key);
  67.                     }else{
  68.                         //System.out.println("NOW ["+key+"] no cache");
  69.                         TimeInfo tInfo = NTPDate.udpClient.getTime(NTPDate.server);
  70.                         Date d = tInfo.getMessage().getReceiveTimeStamp().getDate();
  71.                         NTPDate.time.clear();
  72.                         NTPDate.time.put(key, d);
  73.                         return d;
  74.                     }
  75.                 }finally {
  76.                     semaphore.release(lock, "getDateCached");
  77.                 }
  78.             }
  79.         }
  80.     }
  81.    
  82.     /**
  83.      * Impostazione delle proprieta' per il DateManager
  84.      */
  85.     @Override
  86.     public void init(java.util.Properties properties) throws UtilsException{
  87.         _init(properties);
  88.     }
  89.    
  90.     private static void _init(java.util.Properties properties) throws UtilsException{
  91.         if(NTPDate.udpClient==null) {
  92.             _initSync(properties);
  93.         }
  94.     }
  95.     private static synchronized void _initSync(java.util.Properties properties) throws UtilsException{
  96.         if(NTPDate.udpClient!=null) {
  97.             return;
  98.         }
  99.         try{
  100.             NTPDate.udpClient = new NTPUDPClient();
  101.            
  102.             // timeout
  103.             String timeoutS = properties.getProperty("ntp.timeout");
  104.             if(timeoutS!=null){
  105.                 try{
  106.                     NTPDate.defaultTimeout = Integer.parseInt(timeoutS);
  107.                 }catch(Exception e){
  108.                     throw new Exception("org.openspcoop.pdd.date.property.ntp.timeout value non valido: "+e.getMessage(),e);
  109.                 }
  110.             }
  111.             if(NTPDate.defaultTimeout!=-1)
  112.                 NTPDate.udpClient.setDefaultTimeout(NTPDate.defaultTimeout);
  113.            
  114.             // ipaddress
  115.             String ipaddressS = properties.getProperty("ntp.server");
  116.             if(ipaddressS==null)
  117.                 throw new Exception("org.openspcoop.pdd.date.property.ntp.server value non definito");
  118.             if(ipaddressS!=null){
  119.                 try{
  120.                     NTPDate.server = InetAddress.getByName(ipaddressS);
  121.                 }catch(Exception e){
  122.                     throw new Exception("org.openspcoop.pdd.date.property.ntp.server value non valido: "+e.getMessage(),e);
  123.                 }
  124.             }
  125.            
  126.             // cache
  127.             String cacheS = properties.getProperty("ntp.cache.enable");
  128.             if(cacheS!=null){
  129.                 try{
  130.                     NTPDate.cacheEnabled = Boolean.parseBoolean(cacheS);
  131.                 }catch(Exception e){
  132.                     throw new Exception("org.openspcoop.pdd.date.property.ntp.cache.enable non valido: "+e.getMessage(),e);
  133.                 }
  134.             }
  135.            
  136.             // intervallo cache refresh
  137.             String cacheRefreshS = properties.getProperty("ntp.cache.refresh");
  138.             if(cacheRefreshS!=null){
  139.                 try{
  140.                     int value = Integer.parseInt(cacheRefreshS);
  141.                     if(value>1000)
  142.                         throw new Exception("Valore deve essere minore di 1000");
  143.                     NTPDate.cacheRefresh = 1000 / value;
  144.                 }catch(Exception e){
  145.                     throw new Exception("org.openspcoop.pdd.date.property.ntp.cache.refresh non valido: "+e.getMessage(),e);
  146.                 }
  147.             }
  148.            
  149.             NTPDate.udpClient.open();
  150.            
  151.             NTPDate.time = new ConcurrentHashMap<String,Date>();
  152.            
  153.         }catch(Exception e){
  154.             NTPDate.udpClient=null;
  155.             throw new UtilsException("Inizializzazione NTP Client (properties) non riuscita: "+e.getMessage(),e);
  156.         }
  157.     }
  158.    
  159.     /**
  160.      * Close il DataManager
  161.      *
  162.      * @throws UtilsException
  163.      */
  164.     @Override
  165.     public void close() throws UtilsException{
  166.         try{
  167.             if(NTPDate.udpClient!=null)
  168.                 NTPDate.udpClient.close();
  169.         }catch(Exception e){
  170.             throw new UtilsException("Chiusura NTP Client non riuscita: "+e.getMessage(),e);
  171.         }
  172.     }
  173.    
  174.     /**
  175.      * Ritorna la data corrente.
  176.      *
  177.      * @return Data corrente
  178.      */
  179.     @Override
  180.     public Date getDate() throws UtilsException{
  181.         try{
  182.             if(NTPDate.udpClient==null)
  183.                 throw new Exception("Inizializzazione non effettuata, invocare metodo init");
  184.            
  185.             //System.out.println("NTP getDate ("+NTPDate.getDateCached()+")");
  186.             return NTPDate.getDateCached();
  187.                        
  188.         }catch(Exception e){
  189.             throw new UtilsException("getDate error: "+e.getMessage(),e);
  190.         }
  191.     }
  192.    
  193.     /**
  194.      * Ritorna la data corrente in millisecondi da Gennaio 1.4970.
  195.      *
  196.      * @return Data corrente
  197.      */
  198.     @Override
  199.     public long getTimeMillis()throws UtilsException {
  200.         try{
  201.             if(NTPDate.udpClient==null)
  202.                 throw new Exception("Inizializzazione non effettuata, invocare metodo init");
  203.            
  204.             //System.out.println("NTP getTime ("+NTPDate.getDateCached().getTime()+")");
  205.             return NTPDate.getDateCached().getTime();
  206.                        
  207.         }catch(Exception e){
  208.             throw new UtilsException("getDate error: "+e.getMessage(),e);
  209.         }
  210.     }
  211.    
  212.     /**
  213.      * Ritorna la data corrente come timestamp SQL.
  214.      *
  215.      * @return Data corrente
  216.      */
  217.     @Override
  218.     public Timestamp getTimestamp() throws UtilsException{
  219.         try{
  220.             if(NTPDate.udpClient==null)
  221.                 throw new Exception("Inizializzazione non effettuata, invocare metodo init");
  222.            
  223.             //System.out.println("NTP getTimestamp ("+new Timestamp(NTPDate.getDateCached().getTime())+")");
  224.             return new Timestamp(NTPDate.getDateCached().getTime());
  225.                        
  226.         }catch(Exception e){
  227.             throw new UtilsException("getDate error: "+e.getMessage(),e);
  228.         }  
  229.     }
  230.    
  231.     /**
  232.      * Ritorna la data corrente come Calendar
  233.      *
  234.      * @return Data corrente
  235.      */
  236.     @Override
  237.     public Calendar getCalendar() throws UtilsException{
  238.         Calendar c = new GregorianCalendar();
  239.         c.setTime(this.getDate());
  240.         return c;
  241.     }
  242. }