using NLog; using System; using System.Collections; using System.Collections.Generic; using System.Configuration; using System.Data; using System.IO; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Threading.Tasks; namespace IOB_UT_NEXT { public class baseUtils { #region Public Fields /// /// Indicazione VETO PING a server sino alla data-ora indicata /// public static DateTime dtVetoPing = DateTime.Now; /// /// Indicazione VETO invio a server sino alla data-ora indicata /// public static DateTime dtVetoSend = DateTime.Now; /// /// Status IOB /// public static bool IOB_Online = false; /// /// Classe logger /// public static Logger lg = LogManager.GetCurrentClassLogger(); /// /// Status MP_IO /// public static bool MPIO_Online = false; #if false /// /// Oggetto connessione REDIS /// public static RedisIobCache redisMan = new RedisIobCache(); #endif #endregion Public Fields #region Public Properties /// /// Calcola una pausa con errore casuale x il prossimo send programmato verso SERVER /// public static int nextPauseSendMSec { get { // parto dal dato std di veto per pauseSendMSec int answ = CRI("pauseSendMSec"); // aggiungo NOISE... +/- 50% Random rnd = new Random(); int noise = rnd.Next(1, answ / 2); answ += noise - (answ / 4); return answ; } } #endregion Public Properties #region Public Methods /// /// formatta un numero in forma binaria 0/1 /// /// /// public static string binaryForm(int valore) { string answ = ""; try { answ = string.Format(new BinaryUtils(), "{0:B}", valore); } catch { } return answ; } /// /// formatta un numero in forma binaria 0/1 /// /// /// public static string binaryForm(uint valore) { string answ = ""; try { answ = string.Format(new BinaryUtils(), "{0:B}", valore); } catch { } return answ; } /// /// Effettua chiamata URL e restituisce risultato, SE NON E' in veto send (x mmitigare chiamate...) /// /// /// public static string callUrl(string URL) { string answ = ""; // controllo se ho un VETO all'invio... if (dtVetoSend < DateTime.Now) { answ = callUrlNow(URL); } return answ; } /// /// Effettua chiamata URL e restituisce risultato /// /// /// /// public static string callUrl(string URL, string payload) { string answ = ""; // controllo se ho un VETO all'invio... if (dtVetoSend < DateTime.Now) { answ = callUrlNow(URL, payload); } // restituisco valore! return answ; } /// /// Versione async della chiamata ad URL /// /// /// public static string callUrlAsync(string URL) { // Chiamo in modalità task... var resp = Task.Run(() => callUrl(URL)); resp.Wait(); return resp.Result; } /// /// Versione async della chiamata ad URL /// /// /// /// public static string callUrlAsync(string URL, string payload) { // Chiamo in modalità task... var resp = Task.Run(() => callUrl(URL, payload)); resp.Wait(); return resp.Result; } /// /// Effettua chiamata URL IMMEDIATAMENTE e restituisce risultato /// /// /// public static string callUrlNow(string URL) { string answ = ""; if (client == null) { client = new WebClientWT(); } client.Headers.Add("user-agent", $"{CRS("appName")}"); try { // problema certificati locali... // https://living-sun.com/it/c/226351-webexception-could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel-c-aspnet-web-services-ssl-webexception.html // hack x certificati locali in 10.74.82.* if (URL.Contains("10.74.82.")) { System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; }; } answ = client.DownloadString(URL); } catch (Exception exc) { // imposto veto int pauseSendMSec = nextPauseSendMSec; dtVetoSend = DateTime.Now.AddMilliseconds(pauseSendMSec); // log ogni lg.Error($"Errore in callURL verso {URL}: impostato attesa di {pauseSendMSec} ms prima della prossima chiamata{Environment.NewLine}Eccezione:{Environment.NewLine}{exc}"); } // restituisco valore! return answ; } /// /// Effettua chiamata IMMEDIATAMENTE URL e restituisce risultato /// /// /// /// public static string callUrlNow(string URL, string payload) { string answ = ""; if (clientPayload == null) { clientPayload = new WebClientWT(); } clientPayload.Headers.Add("user-agent", $"{CRS("appName")}-PAYLOAD"); clientPayload.Headers.Add("Content-Type", "application/json"); try { // problema certificati locali... // https://living-sun.com/it/c/226351-webexception-could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel-c-aspnet-web-services-ssl-webexception.html // hack x certificati locali in 10.74.* if (URL.Contains("10.74.")) { System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; }; } answ = clientPayload.UploadString(URL, payload); if (answ != "OK") { lg.Error($"Invio dati fallito, ricevuto messaggio [{answ}]:{Environment.NewLine}- URL{Environment.NewLine}{URL}{Environment.NewLine}- payload{Environment.NewLine}{payload}"); } } catch (Exception exc) { // imposto veto int pauseSendMSec = nextPauseSendMSec; dtVetoSend = DateTime.Now.AddMilliseconds(pauseSendMSec); // log ogni lg.Error($"Errore in callURL con PAYLOAD verso {URL}: impostato attesa di {pauseSendMSec} ms prima della prossima chiamata. Dump Payload:{Environment.NewLine}{payload}{Environment.NewLine}Eccezione:{Environment.NewLine}{exc}"); } // restituisco valore! return answ; } /// /// Conteggio valori true in un array di boolean /// /// /// public static int CountTrue(params bool[] args) { return args.Count(t => t); } /// /// legge conf in formato BOOLean /// /// /// public static bool CRB(string key) { bool answ = false; try { answ = Convert.ToBoolean(CRS(key)); } catch { } return answ; } /// /// legge conf in formato char /// /// /// public static char CRC(string key) { char answ = '-'; try { answ = ConfigurationManager.AppSettings[key].ToCharArray()[0]; } catch { } return answ; } /// /// legge conf in formato INT /// /// /// public static Int32 CRI(string key) { int answ = 0; try { answ = Convert.ToInt32(CRS(key)); } catch { } return answ; } /// /// legge conf in formato stringa /// /// /// public static string CRS(string key) { string answ = ""; try { answ = ConfigurationManager.AppSettings[key].ToString(); } catch { } return answ; } /// /// IP della macchina /// /// public static string GetIP() { NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); String sIpAddr = string.Empty; try { foreach (NetworkInterface adapter in nics) { if (sIpAddr == String.Empty)// only return IP Address from first card { IPInterfaceProperties properties = adapter.GetIPProperties(); foreach (var item in properties.UnicastAddresses) { if (item.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { sIpAddr = item.Address.ToString(); } } } } } catch (Exception exc) { lg.Error(exc); } return sIpAddr; } /// /// Macaddress della macchina /// /// public static string GetMACAddress() { NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); String sMacAddress = string.Empty; foreach (NetworkInterface adapter in nics) { if (sMacAddress == String.Empty)// only return MAC Address from first card { IPInterfaceProperties properties = adapter.GetIPProperties(); //sMacAddress = adapter.GetPhysicalAddress().ToString(); sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray()); } } return sMacAddress; } /// /// Method to convert an integer to a string containing the number in binary. A negative /// number will be formatted as a 32-character binary number in two's compliment. /// /// self-explanatory /// /// if binary number contains fewer characters leading zeros are added /// /// string as described above public static string IntToBinStr(int theNumber, int minimumDigits) { return Convert.ToString(theNumber, 2).PadLeft(minimumDigits, '0'); } /// /// verifica se un dato bit sia alzato (come flag di strobe) /// /// valore da testare /// /// valore cercato, può essere un singolo valore o un insieme in modalità AND /// /// public static bool IsSetAll(StFlag32 value, StFlag32 flag) { return ((value & flag) == flag); } /// /// verifica se un dato bit sia alzato (come flag di strobe) /// /// valore da testare /// /// valore cercato, può essere un singolo valore o un insieme in modalità OR /// /// public static bool IsSetAny(StFlag32 value, StFlag32 flag) { return ((value & flag) != 0); } /// /// Test ping x indirizzo indicato /// /// /// public static bool pingAddress(IPAddress address) { bool answ = false; try { Ping pingSender = new Ping(); PingReply reply = pingSender.Send(address, 100); // se passa il ping do OK... if (reply.Status == IPStatus.Success) { answ = true; } } catch (Exception exc) { lg.Error(exc); } return answ; } /// /// Lettura dictionary da file /// /// /// public static Dictionary ReadBin(string file) { var result = new Dictionary(); // verifico file esista... if (!File.Exists(file)) { FileStream fs = File.Create(file); fs.Close(); } using (FileStream fs = File.OpenRead(file)) using (BinaryReader reader = new BinaryReader(fs)) { // Get count. int count = 0; try { count = reader.ReadInt32(); } catch { } // Read in all pairs. for (int i = 0; i < count; i++) { string key = reader.ReadString(); string value = reader.ReadString(); result[key] = value; } } return result; } /// /// Lettura dictionary da file /// /// /// public static Dictionary ReadPlain(string file) { // inizializzo num righe lette... int numRow = 0; var result = new Dictionary(); // verifico file esista... if (!File.Exists(file)) { FileStream fs = File.Create(file); fs.Close(); } try { string[] lines = File.ReadAllLines(file); result = lines.Select(l => l.Split(':')).ToDictionary(a => a[0], a => a[1]); numRow = result.Count; } catch { } // se leggesse un valore NON coerente (senza righe) restituisce un file vuoto... if (numRow == 0) { result = new Dictionary(); } return result; } public static void resetWebClients() { // resetto i webclients... client = new WebClientWT(); clientPayload = new WebClientWT(); } /// /// Effettua reverse della stringa /// /// /// public static string reverseStr(string s) { char[] arr = s.ToCharArray(); Array.Reverse(arr); return new string(arr); } /// /// imposta un bit al valore richiesto duplicando il valore IN come OUT /// /// valore originale da aggiornare /// valore richiesto x il bit (0/1) /// indice bit, 0 based (es: 0..31 per 32bit) /// public static byte[] setBitOnStFlag(byte[] original, bool bitBool, int bitIndex) { int bitVal = 0; if (bitBool) { bitVal = 1; } // risposta è identica ad originale... byte[] answ = original; // verifico se il bit è 0/1b if (bitVal <= 1 && bitVal >= 0) { // verifico se si possa aggiornare il bit richiesto (<= al totale dei bit...) if (bitIndex <= original.Length * 8 - 1) { // calcolo byte int byteIndex = bitIndex / 8; // bit nel byte int bitInByteIndex = bitIndex % 8; // bit richiesto byte mask = (byte)(bitVal << bitInByteIndex); // imposto! answ[byteIndex] |= mask; } } return answ; } /// /// provvede a verificare la dim della cartella dei log e cancella i + vecchi fino a restare /// a dim inferiori a _logMaxMb /// public static void shrinkDir(string dirPath) { // obj filemover... fileMover.obj.setDirectory(dirPath); float dirSizeMb = fileMover.obj.totalMb(); lg.Info("Inizio shrinkDir LOG folder: {0} Mb", dirSizeMb); // ottengo elenco files *.txt FileInfo[] _fis = fileMover.obj.elencoFiles_FI("*.log"); int numDdMax = 2; try { numDdMax = CRI("zipLogOldDay"); } catch { } foreach (FileInfo _file in _fis) { if (_file.LastWriteTime < DateTime.Now.AddDays(-1)) // zippo files + vecchi di 2 gg... { fileMover.obj.zippaSingoloFile(_file); // cancello l'originale... fileMover.obj.eliminaFile(_file); } } // inizio con eliminare file + vecchi della data indicata... int maxLogDays = CRI("maxLogDays"); fileMover.obj.deleteOlderThan(maxLogDays); // ora controllo SE sia superata la dim max della directory --> in tal caso cancello dal // + vecchio... dirSizeMb = fileMover.obj.totalMb(); int maxLogDirSize = CRI("maxLogDirSize"); int maxTry = 100; // controllo se serva eliminare... if (dirSizeMb > maxLogDirSize) { lg.Info("Continuo shrinkDir LOG folder: {0} Mb --> ELIMINAZIONE FILES", dirSizeMb); while (dirSizeMb > maxLogDirSize) { fileMover.obj.deleteOldest(); maxTry--; if (maxTry > 0) { dirSizeMb = fileMover.obj.totalMb(); } else { // per uscire fingo di aver ridotto... dirSizeMb = maxLogDirSize - 1; } } dirSizeMb = fileMover.obj.totalMb(); lg.Info("Completata shrinkDir LOG folder: {0} Mb", dirSizeMb); } } /// /// Converte un bitarray a byte[] /// /// /// public static byte[] ToByteArray(BitArray bits) { int numBytes = bits.Count / 8; if (bits.Count % 8 != 0) { numBytes++; } byte[] bytes = new byte[numBytes]; int byteIndex = 0, bitIndex = 0; for (int i = 0; i < bits.Count; i++) { if (bits[i]) { bytes[byteIndex] |= (byte)(1 << (7 - bitIndex)); } bitIndex++; if (bitIndex == 8) { bitIndex = 0; byteIndex++; } } return bytes; } /// /// Scrittura dictionary su file /// /// /// public static void WriteBin(Dictionary dictionary, string file) { using (FileStream fs = File.OpenWrite(file)) using (BinaryWriter writer = new BinaryWriter(fs)) { // Put count. writer.Write(dictionary.Count); // Write pairs. foreach (var pair in dictionary) { writer.Write(pair.Key); writer.Write(pair.Value); } } } /// /// Scrittura dictionary su file /// /// /// public static void WritePlain(Dictionary dictionary, string file) { string dirPath = file.Substring(0, file.LastIndexOf('\\')); // verifico directory if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } string[] lines = dictionary.OrderBy(i => i.Key).Select(kvp => kvp.Key + ":" + kvp.Value).ToArray(); try { File.WriteAllLines(file, lines); } catch (Exception exc) { lg.Info(exc, string.Format("Errore in scrittura file {0}", file)); } } #endregion Public Methods #region Protected Properties /// /// Oggetto WebClient BASE da riutilizzare /// protected static WebClientWT client { get; set; } /// /// Oggetto WebClient con PAYLOAD da riutilizzare /// protected static WebClientWT clientPayload { get; set; } #endregion Protected Properties } /// /// Override metodo WebClient con gesitone TimeOut corto /// public class WebClientWT : WebClient { #region Protected Properties /// /// timeout da conf /// protected int urlCallTOut { get { int answ = 5000; answ = baseUtils.CRI("urlCallTOut"); if (answ < 0 || answ > 10000) { answ = 3000; } return answ; } } #endregion Protected Properties #region Protected Methods protected override WebRequest GetWebRequest(Uri address) { WebRequest wr = base.GetWebRequest(address); wr.Timeout = urlCallTOut; // timeout in milliseconds (ms) return wr; } #endregion Protected Methods } }