lunedì 15 luglio 2019

HellDesk


Oggi e' giornata di articoli visto che sono al secondo... Ma tant'e'. Ve la faro' molto breve: dobbiamo accedere ai servizi di $HOSTING_PAMPERS per deploy del codice, qualita' dello stesso (un'immane cagata imho) etc. Questi sarchiaponi richiedono l'accesso in vpn tramite il client integrato di windows. Probabilmente c'e' una configurazione di questa macchina o qualche pacchetto che va in conflitto o sonasega per cui come cerco di aprire le impostazioni wpn vpn* di windows si pianta.

Ci son stato dietro per un po', poi ho deciso che siccome abbiamo un'astinenza tecnica e che ci avevo gia' perso troppo tempo dietro (e non mi pagano per questo, mi pagano per fare il mio lavoro) era giunto il momento di contattarli. Quello che seguira' sono le email vere scambiate tra me e l'astinenza. Ho solo cambiato un po' di nomi ma non ho inventato niente.

La mia mail con la quale ho aperto il ticket

Buongiorno,

sono un collega che presso $ENTE a $CITTA'

Scrivo per segnalare che usando il client vpn di windows (che e' necessario per eseguire delle attivita' presso $HOSTING_PAMPERS) il client stesso si blocca

e non mi e' possibile ne' modificare la configurazione VPN attuale, ne' aggiungerne di nuove.

Premetto che
  • la configurazione vpn $DITTONA, usando il client cisco e' perfettamente funzionante e *non deve essere toccata*
  • il client vpn integrato di windows e' richiesto da $HOSTING_PAMPERS per attivita' sui loro server
  • ho effettuato tutti gli aggiornamenti di windows disponibili in data $DATA_MOLTO_RECENTE e che il problema non si e' risolto
pertanto chiedo se e' possibile avere supporto in merito a tale problema.

Saluti

La prima loro "risposta"

Buongiorno, vorremmo chiarimenti in merito al ticket aperto.
ci puo' dire se i problemi di connessione sono sulla vpn1 oppure sulla vpn2?
Saluti

La mia risposta:

Scusate cosa intendete con "vpn1" e "vpn2"?

Non ho problemi di connessione, ho problemi di configurazione. Il client vpn di windows si blocca quando si cerca di aprirlo per modificare le impostazioni oppure per creare una vpn nuova.

Invece il client cisco (quello usato per $DITTONA) funziona correttamente.

Saluti

Altra mail dell'astinenza (evidentemente non sono stato abbastanza chiaro):

Deve collegarsi alla vpn $ALTRA_AZIENDA oppure a quella clienti?

Risposta mia (pazienza in esaurimento)

Il problema nasce cercando di configurare una vpn usando il client integrato di windows.

L'uso di tale client e' richiesto da $HOSTING_PAMPERS (hosting partner di $ENTE)

in nessun caso si tratta di una vpn di $DITTONA.

Ecco la perla dell'astinenza:

Provi a collegarsi ad una vpn per volta .


Al che ho deciso che era inutile proseguire, ho preso le responsabili (che fra parentesi leggevano in copia e si son fatte delle grasse risate) e ho chiesto loro, visto che comunque il mio pc ha un'hdd poco capiente, se era possibile cogliere la palla al balzo e sostituire l'hdd di questa macchina. Loro mi mandano l'hdd e IO faccio tutto il lavoro. Reinstallo la macchina da pulito (ho i dischi di ripristino) e si prova cosi'. Ovviamente ho chiuso il ticket...

Alla prossima!

14/08/2019 ogni tanto mi scappa una "w" al posto di "v" perche' e' un modo di scherzare che usiamo in ufficio (w pronunciata u alla martufello). Per cui un ipotetico "Giovanni" diventerebbe "Giouanni" (scritto "Giowanni")

Java Reflection e CSV

Cosa sono le reflection? Sono sostanzialmente un modo per ottenere tutti i nomi dei metodi, ed eventualmente invocarli, senza sapere quali siano questi metodi. Tutti sanno da codice invocare il metodo "getPippo()" di una certa classe scrivendolo da codice, ed e' quello si fa praticamente di normale. Pero' ci sono delle situazioni per le quali non sai il nome dei metodi da invocare (oppure non li vuoi sapere perche' sono centinaia e devi invocarli tutti).

Java ci mette a disposizione uno strumento potentissimo (se usato bene): le reflections. E' possibile da un oggetto Classe ottenere i nomi dei suoi metodi (come oggetto Method). Tramite questi nomi, e' possibile invocarli per esempio, ma e' necessaria un'istanza di quella classe (ovviamente). E' anche possibile passare argomenti.

Il caso che tratteremo qui e' la generazione di un csv. Il caso che mi ha spinto a creare una classe generica e non una ad hoc e' che la tabella (e quindi l'entity) della quale devo generare il csv ha una pletora di campi (2 o 300 tipo) per cui la decisione era:

  • spendo 2h a fare un csv con possibilita' altissima di sbagliare (visto l'elevato nr. di campi)
  • spendo 10min a farlo con una reflection con la possibilita' poi di usarlo per tutto?

La domanda e' semiretorica anche perche' se non avessi scelto la seconda opzione non sarei qui a scrivere questo articolo. Per arrivarci pero' devo fare un po' di premesse:

La prima e' un metodo "generico" che formatta un oggetto usando istanceof (e restituisce una stringa) controllando pure se e' null o not. Se l'oggetto che mi passo in input e' null restituisco stringa vuota (questo perche' in un csv devi comunque mettere un ; se vuoi un campo vuoto).



Poi ci serve (o almeno a ME!!!) un metodo per convertire il camel case in stringa "normale" - questo perche' uso i nomi dei metodi come nomi di colonne (non vorrai mica fare un csv senza intestazione). Ma questo si fa facile - StringUtils di apache ci viene incontro con splitByCharacterTypeCamelCase il cui risultato passeremo al metodo join sempre di StringUtils (non metto screen abbiate pazienza).

Fatto questo io mi sono fatto un metodo di utilita' che data una classe restituisce tutti i suoi getters (escluso getClass che nel csv non serve)

Poi ci serve un metodo di utilita' che restituisca una stringa csv di una certa istanza (generica). Ho usato i generics perche' voglio potergli passare di tutto. Come si puo' notare per invocare un metodo tramite reflection si invoca il metodo invoke passandogli un'istanza che e' quella sulla quale il metodo verra' eseguito il risultato e' un object. Mi passo anche il separator (perche' voglio essere flessibile).

Come si puo' vedere viene invocato il metodo "formattatore" generico presentato all'inizio, questo evita che nella stringa ci sia il toString degli oggetti (che non e' molto human readable). Inoltre, sempre questo metodo, evita che ci siano dei campi sfalsati nel csv (dovuto alla presenza di campi null).

Vi risparmio la parte di scrittura su file perche' non interessante ai fini di questo articolo.

Alla prossima!