domenica 28 ottobre 2018

Comunicazione tra MicroServices in Spring Boot con RabbitMQ


Dopo attenta lettura di documentazione on-line e suggerimenti da amici provo ad eseguire qualche test di comunicazione tra Micro Services utilizzando un gestore di code di messaggi RabbitMQ.

Con una semplice app in Spring Boot, con interfaccia rest,  al richiamo di una path, viene spedito un messaggio al RabbitMQ installato sullo stesso PC in locale.

Per RabbitMQ vi consiglio vivamente di installare il plugin per il management da web

 http://localhost:15672/ guest/guest.





La parte di controller è molto semplice, è un api rest che quando viene richiamata spedisce un messaggio al RabbitMQ e nella stessa classe un metodo che rimane in ascolto sulla stessa coda.


Adesso eseguiamo alcuni stress test:

  1.  creiamo diversi file di configurazione di spring per ogni file cambiamo semplicemente la porta.
  2. eseguiamo la build del progetto e lanciamo n jar per ogni profiles creato nel file di configurazione yaml.

java -jar rabbit-spring-test-0.0.1.jar  --spring.profiles.active=9001
java -jar rabbit-spring-test-0.0.1.jar  --spring.profiles.active=9002
java -jar rabbit-spring-test-0.0.1.jar  --spring.profiles.active=9003
java -jar rabbit-spring-test-0.0.1.jar  --spring.profiles.active=9004


il vostro desktop diventa qualcosa di delirante...

3. Configuro il jMeter per iniziare ad eseguire chiamate sui quattro server 
http://localhost:900{1-4}/sendMessage


C:\dev\apache-jmeter-5.0\bin> .\jmeter -n -t .\sendmessage.jmx -l tmp\jmeter-o.log -o tmp\dashboard

il file sendmessage.jmx



Client web di RabbitMQ



Riassumendo con jMeter abbiamo spedito 48000 richiese di invio di messaggi alle 4 app Spring Boot.
Le app hanno inviato una richiesta in coda al RabbitMQ che a sua volta per ognuno dei suddetti ha reinviato il messaggio alle 4 app.

In ingresso ha processato 48000 messaggi.
In uscita ha processato 192000 messaggi.
Tutto questo in 1 minuto.


martedì 9 ottobre 2018

Nginx, Angular 6 e FontAwesome 4.7 - Problemi Url

I Modulo npm dei FontAwesome 4.7.0 in Angular aggiunge alla path chiamante del file css l'estensione con la versione:

es: http://xxx.xxx.xx/static/fontawesome-webfont.af7ae505a9eed503f8b8.woff2?v=4.7.0

Nginx non accetta di default la tipologia di file, quindi è necessario modificare il file mime.types, aggiungendo le seguenti tipologie:

application/x-font-ttf ttc ttf;
application/x-font-otf otf;
application/font-woff  woff;
application/font-woff2 woff2;
application/vnd.ms-fontobject eot;

Questa cosa causa nella risposta standard del browser un errore OTP, a questo punto è necessario inserire un regola di rewrite su Nginx per eliminare la parte di estensione non prevista ?v=4.7.0

    location /static/ {
         alias  /opt/static/html/;
         index index.html;

        if ($request_uri ~* ^.+\.(woff2|otf|woff|tff)\?v=(.*)$){
             rewrite ^(.*)$ $uri? permanent;
         }
         try_files $uri$args $uri$args/ $uri/ /index.html =404;
         error_log /var/log/nginx/static_error.log;
         access_log /var/log/nginx/static_access.log;
     }

Esempio completo:

venerdì 5 ottobre 2018

Jasper Report - Report senza query ma solo con params

Il problema nascosto di jasper report è la possibilità di creare un report (con il vecchio iReport) senza dati al suo interno, semplicemente un documento a cui passo un oggetto java e poi elaboro, magari un DTO proveniente da elaborazione di una chiamata API rest o simili.

Il documento non viene generato via java, perché?

E' necessario aggiungere all'XML di jasper una attributo nel ramo principale del file:

<jasperReport ........  whenNoDataType="AllSectionsNoDetail">

a questo punto il report viene correttamente interpretato e renderizzato via java

JasperReport versione 6.1.1



giovedì 4 ottobre 2018

Maven - pacchetti danneggiati

Alle volte capita di avere problemi con il deploy di alcune applicazioni legate alle dipendenze maven causate da file corrotti durante lo scaricamento automatico.

Per risolvere questo problema basta ricercare nella cartella di scaricamento dei pacchetti (solitamente la .m2  nella cartella di windows %userprofile%\.m2)  tutti i file "*-sha1-in" e procedere all'eliminazione della cartella padre.

Eseguire da Eclipse un clean ed un maven update.


[grazie a Domenico]

mercoledì 22 agosto 2018

Angular e SWAPI



Mi sono iscritto ad un corso di  Angular e React tenuto da Antony Mistretta.

Nella prima lezione ci ha suggerito un ottimo sito di API online da utilizzare come sorgenti per delle applicazioni di prova  https://swapi.co con un semplice set di oggetti e di chiamate REST basate su architettura Django. ( Indagando sul web ho trovato anche le https://pokeapi.co/ ma sono veramente troppo complesse... e poi bisogna conoscere il mondo dei pokemon.... )



Per realizzare una piccola demo con Angular per sfruttare le informazioni presenti nel sito ho utilizzato alcuni componenti a me famigliari:

- PrimeNG : personalmente le trovo più complete delle Material
- Compodoc: generatore di documentazione like javadoc molto completo


Alcune funzionalità degne di nota:

- Cache : cache delle chiamate nella sessione del browser, quando devo accedere a elementi uguali ricorrenti salvo l'informazione come chiave valore, dove la chiave è il mio url di chiamata e invece il valore è l'object caricato.

- Estensione dei modelli e dei controller principali con classi di base per ridurre codice in esubero.




TODO
- e2e test
- karma test
- Caricamento di un templateUrl dinamico così da utilizzare un solo Componente per gestire tutte le pagine.
- Ricerca sulle tabelle usando i parametri di search

sabato 14 aprile 2018

Firefox Portable Custom

Condeterminati applicativa da rilasciare nasce anche l'esigenza di un browser custom per ridurreal minimo il cambio di configurazione da parte dell'utenza che combina sempre disastri sulle configurazioni. Oppure semplicemente per bloccare l'update di firefox o bloccare le impostazione di proxy o configurare forzatamente dei plug-in evitanto che l'utenza possa andare a toccare le configurazioni.

La soluzione è quella di usare una versione portable di Firefox.

Tutte le configurazioni disponibile sono presenti a questo indirizzo e successivamente vediamo come modificarle.

Per accedere manualmente alla configurazioni è possibile digitare da browser About:config.


Per prima cosa è necessario modificare/creare il file \FirefoxPortable\App\Firefox\defaults\pref\autoconfig.js
inserendo riferimenti nel nostro file di configurazione:

pref("general.config.filename", "nomefile.cfg");
pref("general.config.obscure_value", 0);


il nostro file di configurazione: \FirefoxPortable\App\Firefox\nomefile.cfg

//GENERAL - STARTUP

//pagina di default
pref("browser.startup.homepage", "http://miapagina.lan");
lockPref("browser.startup.homepage", "http://miapagina.lan");

pref("browser.startup.page", 1);
lockPref("browser.startup.page", 1);

//lock default brauser
pref("browser.shell.checkDefaultBrowser", false);
lockPref("browser.shell.checkDefaultBrowser", false);

//GENERAL - TABS
pref("browser.tabs.warnOnClose", false);
lockPref("browser.tabs.warnOnClose", false);


//GENERAL - Language and Apparence
pref("layout.spellcheckDefault", 2);
lockPref("layout.spellcheckDefault", 2);


//GENERAL - Browsing
pref("general.autoScroll", true);
lockPref("general.autoScroll", true);

pref("general.smoothScroll", true);
lockPref("general.smoothScroll", true);

pref("accessibility.typeaheadfind", false);
lockPref("accessibility.typeaheadfind", false);

pref("accessibility.browsewithcaret", false);
lockPref("accessibility.browsewithcaret", false);


//GENERAL - Proxy
pref("network.proxy.type",0);
lockPref("network.proxy.type",0);



//GENERAL - Updated

pref("app.update.enabled", false);
lockPref("app.update.enabled", false);

pref("app.update.silent", false);
lockPref("app.update.silent", false);

//expire history
pref("browser.history_expire_days",0);
lockPref("browser.history_expire_days",0);

pref("browser.search.update",false);
lockPref("browser.search.update",false);


//SEARCH
pref("browser.urlbar.autocomplete.enabled",false);
lockPref("browser.urlbar.autocomplete.enabled",false);


//PRIVACY
pref("browser.formfill.enable",false);
lockPref("browser.formfill.enable",false);

pref("browser.cache.disk.enable",true);
lockPref("browser.cache.disk.enable",true);

pref("browser.cache.disk.capacity",5000);
lockPref("browser.cache.disk.capacity",5000);

pref("browser.cache.check_doc_frequency",3);
lockPref("browser.cache.check_doc_frequency",3);

pref("signon.rememberSignons",false);
lockPref("signon.rememberSignons",false);

pref("browser.urlbar.autoFill",false);
lockPref("browser.urlbar.autoFill",false);

pref("browser.preferences.privacy.selectedTabIndex",4);
lockPref("browser.preferences.privacy.selectedTabIndex",4);

//PRIVACY - Permissions
pref("browser.urlbar.showPopup",true);
lockPref("browser.urlbar.showPopup",true);

pref("dom.disable_open_during_load",false);
lockPref("dom.disable_open_during_load",false);

pref("privacy.popups.policy",1);
lockPref("privacy.popups.policy",1);

//PRIVACY - Security
pref("browser.safebrowsing.enabled",true);
lockPref("browser.safebrowsing.enabled",true);

pref("browser.safebrowsing.malware.enabled",true);
lockPref("browser.safebrowsing.malware.enabled",true);

pref("browser.safebrowsing.phishing.enabled",true);
lockPref("browser.safebrowsing.phishing.enabled",true);

pref("signon.prefillForms",false);
lockPref("signon.prefillForms",false);

pref("signon.rememberSignons",false);
lockPref("signon.rememberSignons",false);

pref("signon.expireMasterPassword",true);
lockPref("signon.expireMasterPassword",true);

pref("security.OCSP.enabled",0);
lockPref("security.OCSP.enabled",0);

pref("security.warn_entering_secure",false);
lockPref("security.warn_entering_secure",false);

//VARIE
pref("browser.tabs.warnOnClose",false);
lockPref("browser.tabs.warnOnClose",false);

pref("browser.feedview.showBar",false);
lockPref("browser.feedview.showBar",false);

pref("layout.textarea.spellcheckDefault",true);
lockPref("layout.textarea.spellcheckDefault",true);

//disabilita il messaggio di firefox sulle https
pref("security.insecure_field_warning.contextual.enabled", false);
lockPref("security.insecure_field_warning.contextual.enabled", false);


con la creazione di questo file è possibile personalizzare la parte di contenuti

\FirefoxPortable\Data\profile\chrome\userContent.css

ad esempio se vogliamo eliminare delle voci dalla pagina di configurazione alla fine è una semplice pagina html modificabile da questo css.


@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* set default namespace to XUL */

 @-moz-document url("about:preferences") {
#category-sync { display:none!important; }
#category-search { display:none!important; }
}

@-moz-document url("about:addons") {
#category-discover { display:none!important; }
#category-theme { display:none!important; }
#category-plugin { display:none!important; }
#category-service { display:none!important; }
#category-locale { display:none!important; }
#category-dictionary  { display:none!important; }
}

#context-back #context-sep-navigation {
    display:none !important;
}

 Per intercettare le configurazioni basta usare lo strumento di sviluppo integrato:





per eseguire sia firefox portable che firefox installato è necessario inserire questo file nella cartella portable principale.

file: FirefoxPortable.ini

[FirefoxPortable]
FirefoxDirectory=App\firefox
ProfileDirectory=Data\profile
SettingsDirectory=Data\settings
PluginsDirectory=Data\plugins
FirefoxExecutable=firefox.exe
AdditionalParameters=-contentLocale it -UILocale it
LocalHomepage=
DisableSplashScreen=false
AllowMultipleInstances=true
DisableIntelligentStart=false
SkipCompregFix=false
RunLocally=false