Novo menu de limpeza de cache feat bug#AL-3273

master
Fabio Faria 2023-10-18 15:59:03 -03:00
parent cba744f556
commit e7674b659d
12 changed files with 442 additions and 12 deletions

View File

@ -8,8 +8,8 @@
<packaging>war</packaging>
<properties>
<modelWeb.version>1.16.1</modelWeb.version>
<flyway.version>1.13.0</flyway.version>
<modelWeb.version>1.17.0</modelWeb.version>
<flyway.version>1.14.0</flyway.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

View File

@ -0,0 +1,156 @@
package com.rjconsultores.ventaboletos.web.gui.controladores.seguridad.api;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Messagebox;
import com.rjconsultores.ventaboletos.entidad.Usuario;
import com.rjconsultores.ventaboletos.enums.CacheApiEnum;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.InputMessageBox;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.api.ApiCallRunnable;
import com.rjconsultores.ventaboletos.web.utilerias.spring.AppContext;
/**
*
* @author Fabio Faria
*/
@Controller("limparCacheApiController")
@Scope("prototype")
public class LimparCacheApiController extends MyGenericForwardComposer {
private static final String TITULO = "limparCacheAPI.title";
private static final long serialVersionUID = 1L;
private static Logger log = Logger.getLogger(LimparCacheApiController.class);
private List<CacheApiEnum> lsCachesApiEnum;
private Combobox cmbItem;
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
setLsCachesApiEnum(Arrays.asList(CacheApiEnum.values()));
}
public void onClick$btnRecarregar(Event ev) throws Exception {
Comboitem cbiEntidade = cmbItem.getSelectedItem();
if (cbiEntidade != null) {
CacheApiEnum entidade = (CacheApiEnum) cbiEntidade.getValue();
recarregarCache(entidade);
}
}
public Combobox getCmbItem() {
return cmbItem;
}
public void setCmbItem(Combobox cmbItem) {
this.cmbItem = cmbItem;
}
public List<CacheApiEnum> getLsCachesApiEnum() {
return lsCachesApiEnum;
}
public void setLsCachesApiEnum(List<CacheApiEnum> lsCachesApiEnum) {
this.lsCachesApiEnum = lsCachesApiEnum;
}
public void recarregarCache( CacheApiEnum entidade) {
try {
int resp = Messagebox.show(
Labels.getLabel("limparCacheAPI.message.pergunta"),
Labels.getLabel(TITULO), Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);
if (resp == Messagebox.YES) {
String[] urls = getURLSAPI();
if (urls == null || urls.length == 0) {
Clients.alert(Labels.getLabel("limparCacheAPI.message.naoconfigurado"),
Labels.getLabel(TITULO), Messagebox.INFORMATION);
return;
}
String secret = InputMessageBox.showQuestion(
Labels.getLabel("limparCacheAPI.message.senha"),
Labels.getLabel(TITULO),
Messagebox.OK);
for (String url : urls) {
if (StringUtils.isBlank(url) || url.contains("|")) {
Clients.alert(Labels.getLabel("limparCacheAPI.message.naoconfigurado"),
Labels.getLabel(TITULO), Messagebox.INFORMATION);
return;
}
String tenant = StringUtils.substringBetween(url, "[", "]");
if (tenant != null) {
url = url.replaceAll("\\[.*?\\]", "");
}
String urlBase = url;
url = montarUrlRequest(url, entidade.getUri());
Usuario user = UsuarioLogado.getUsuarioLogado();
ApiCallRunnable cache = new ApiCallRunnable(
url,
tenant,
urlBase,
user.getClaveUsuario(),
secret,
false);
Thread thread = new Thread(cache);
thread.start();
thread.join();
Clients.alert(cache.getRetorno(), Labels.getLabel(TITULO), Messagebox.INFORMATION);
}
}
} catch (Exception e) {
Clients.alert(e.getMessage(), Labels.getLabel(TITULO), Messagebox.ERROR);
log.error(e.getMessage(), e);
}
}
private String montarUrlRequest(String url, String uri) {
url = url.toLowerCase();
if (!url.endsWith("/")) {
url += "/";
}
return url.concat(uri);
}
private String[] getURLSAPI() {
ApplicationContext appContext = AppContext.getApplicationContext();
ConstanteService constanteService = (ConstanteService) appContext.getBean("constanteService");
String constante = constanteService.buscarURLAPI();
return constante == null ? null : constante.split("\\|");
}
}

View File

@ -0,0 +1,91 @@
package com.rjconsultores.ventaboletos.web.utilerias;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.impl.MessageboxDlg;
public class InputMessageBox extends Messagebox {
private static Logger log = Logger.getLogger(InputMessageBox.class);
private static String oldTemplate = Messagebox.getTemplate();
private static String _templ = "/component/inputMessageBox.zul";
private static Textbox txtQuestion;
public static final String showQuestion(String message, String title, int buttons) throws InterruptedException {
setTemplate(_templ);
String retorno = null;
if (showInput(message, title, Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION, 0, null) == Messagebox.OK) {
retorno = txtQuestion.getValue();
}
setTemplate(oldTemplate);
return retorno;
}
public static final int showInput(
String message,
String title,
int buttons,
String icon,
int focus,
EventListener listener) throws InterruptedException {
final Map<String, Object> params = new HashMap<>();
params.put("message", message);
params.put("title", title != null ? title: Executions.getCurrent().getDesktop().getWebApp().getAppName());
params.put("icon", icon);
params.put("buttons", (buttons & (OK|CANCEL|YES|NO|ABORT|RETRY|IGNORE)) != 0 ? buttons: OK);
validateButtons(buttons, params);
final MessageboxDlg dlg = (MessageboxDlg)Executions.createComponents(_templ, null, params);
dlg.setButtons(buttons);
dlg.setEventListener(listener);
txtQuestion = (Textbox)dlg.getFellowIfAny("txtQuestion");
if (focus > 0) dlg.setFocus(focus);
if (dlg.getDesktop().getWebApp().getConfiguration().isEventThreadEnabled()) {
try {
dlg.doModal();
} catch (Exception ex) {
if (ex instanceof InterruptedException)
throw (InterruptedException)ex;
try {
dlg.detach();
} catch (Exception ex2) {
log.error("Failed to detach when recovering from an error " + ex2.toString());
}
throw UiException.Aide.wrap(ex);
}
return dlg.getResult();
} else {
dlg.doHighlighted();
return OK;
}
}
private static void validateButtons(int buttons, final Map<String, Object> params) {
if ((buttons & OK) != 0)
params.put("OK", OK);
if ((buttons & CANCEL) != 0)
params.put("CANCEL", CANCEL);
if ((buttons & YES) != 0)
params.put("YES", YES);
if ((buttons & NO) != 0)
params.put("NO", NO);
if ((buttons & RETRY) != 0)
params.put("RETRY", RETRY);
if ((buttons & ABORT) != 0)
params.put("ABORT", ABORT);
if ((buttons & IGNORE) != 0)
params.put("IGNORE", IGNORE);
}
}

View File

@ -6,12 +6,17 @@ import java.util.Date;
import javax.xml.bind.DatatypeConverter;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import com.nimbusds.jose.JOSEException;
@ -26,12 +31,14 @@ public class ApiCallRunnable implements Runnable {
private static Logger log = Logger.getLogger(ApiCallRunnable.class);
private static final int minutesExpireToken = 10;
private static final String secret = "#KO&Fm4_k.sU9M8`6Mx'F\\\"H:*Qxu]6F4r,)JmZ2Jwafd)I.2[RET'1:)VQ6mG9,";
private String secret = "#KO&Fm4_k.sU9M8`6Mx'F\\\"H:*Qxu]6F4r,)JmZ2Jwafd)I.2[RET'1:)VQ6mG9,";
private final String url;
private final String tenant;
private String retorno;
private String urlBase;
private String user = "internal";
private boolean get = true;
public String getUrl() {
return url;
@ -63,13 +70,38 @@ public class ApiCallRunnable implements Runnable {
this.urlBase = urlOriginal;
}
public ApiCallRunnable(String url, String tenant, String urlBase, String user, String secret, boolean get) {
super();
this.secret = secret;
this.url = url;
this.tenant = tenant;
this.urlBase = urlBase;
this.user = user;
this.get = get;
}
@SuppressWarnings("deprecation")
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setSocketTimeout(5000).build();
HttpUriRequest request;
if(isGet()) {
request = new HttpGet(url);
}else {
request = new HttpPost(url);
}
UsernamePasswordCredentials creds = null;
try {
creds = new UsernamePasswordCredentials("internal", getToken());
try(CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(config).build()) {
if( user.equals("internal")) {
secret = getToken();
}
creds = new UsernamePasswordCredentials(user, secret);
request.addHeader(new BasicScheme().authenticate(creds, request));
if (tenant != null) {
@ -79,6 +111,9 @@ public class ApiCallRunnable implements Runnable {
HttpResponse response = client.execute(request);
if (response != null && response.getStatusLine() != null) {
log.info(String.format(":: Response Status Code %d :: Headers = %s", response.getStatusLine().getStatusCode(),Arrays.toString(response.getAllHeaders())));
HttpEntity responseEntity = response.getEntity();
String corpo = EntityUtils.toString(responseEntity);
log.debug(corpo);
}
Integer codigoRetorno = (response != null && response.getStatusLine() != null) ? response.getStatusLine().getStatusCode() : null;
@ -103,6 +138,7 @@ public class ApiCallRunnable implements Runnable {
return mensagemRetorno.toString();
}
private String getToken() throws JOSEException {
long ttlMillis = minutesExpireToken * 60000;
long nowMillis = System.currentTimeMillis();
@ -110,7 +146,7 @@ public class ApiCallRunnable implements Runnable {
JWTClaimsSet claims = new JWTClaimsSet.Builder()
.claim("sub", new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date()))
.claim("userId", "adm")
.claim("userId", user)
.claim("role", "ROLE_TOKEN")
.claim("exp", expMillis)
.build();
@ -123,4 +159,24 @@ public class ApiCallRunnable implements Runnable {
return jwsObject.serialize();
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public void setSecret(String secret) {
this.secret = secret;
}
public boolean isGet() {
return get;
}
public void setGet(boolean get) {
this.get = get;
}
}

View File

@ -0,0 +1,27 @@
package com.rjconsultores.ventaboletos.web.utilerias.menu.item.seguridad;
import org.zkoss.util.resource.Labels;
import com.rjconsultores.ventaboletos.web.utilerias.PantallaUtileria;
import com.rjconsultores.ventaboletos.web.utilerias.menu.DefaultItemMenuSistema;
public class ItemMenuLimparCacheAPI extends DefaultItemMenuSistema {
private static final String TITULO = "limparCacheAPI.title";
public ItemMenuLimparCacheAPI() {
super("indexController.mniLimparCacheAPI.label");
}
@Override
public String getClaveMenu() {
return "COM.RJCONSULTORES.ADMINISTRACION.GUI.SEGURIDAD.MENU.RECARREGARCACHEAPI";
}
@Override
public void ejecutar() {
PantallaUtileria.openWindow("/gui/seguridad/api/limparCacheApi.zul",
Labels.getLabel(TITULO), getArgs(), desktop);
}
}

View File

@ -59,7 +59,7 @@ public class ItemMenuLimparCacheLocalidadesAPI extends DefaultItemMenuSistema {
String urlBase = url;
url = montarUrlRequest(url);
ApiCallRunnable cache = new ApiCallRunnable(url, tenant, urlBase);
ApiCallRunnable cache = new ApiCallRunnable(url, tenant, urlBase );
Thread thread = new Thread(cache);
thread.start();
thread.join();

View File

@ -321,6 +321,7 @@ seguridad.contingencia=com.rjconsultores.ventaboletos.web.utilerias.menu.item.se
seguridad.reenvioBpe=com.rjconsultores.ventaboletos.web.utilerias.menu.item.seguridad.ItemMenuReenvioBPe
seguridad.reenvioBpe=com.rjconsultores.ventaboletos.web.utilerias.menu.item.seguridad.ItemMenuExtrairBPeXml
seguridad.menuAPI=com.rjconsultores.ventaboletos.web.utilerias.menu.item.seguridad.MenuAPI
seguridad.menuAPI.limparCacheEmbarcadaAPI=com.rjconsultores.ventaboletos.web.utilerias.menu.item.seguridad.ItemMenuLimparCacheAPI
seguridad.menuAPI.limparCacheLocalidadesAPI=com.rjconsultores.ventaboletos.web.utilerias.menu.item.seguridad.ItemMenuLimparCacheLocalidadesAPI
seguridad.menuAPI.limparCacheEmbarcadaAPI=com.rjconsultores.ventaboletos.web.utilerias.menu.item.seguridad.ItemMenuLimparCacheEmbarcadaAPI
seguridad.logAuditoria=com.rjconsultores.ventaboletos.web.utilerias.menu.item.seguridad.ItemMenuLogAuditoria

View File

@ -10431,6 +10431,13 @@ limparCacheEmbarcadaAPI.title = Cache Embarcada (API)
limparCacheEmbarcadaAPI.message.naoconfigurado=A constante de configuração da URL da API não foi encontrada. ATENÇÃO: Quando o cliente tem 2 APIs, uma para venda e outra para embarcada, as duas devem ser parametrizadas em constantes diferentes..
limparCacheEmbarcadaAPI.message.pergunta=Deseja recarregar o Cache de Sincronização (API) ?
indexController.mniLimparCacheAPI.label = Recarregar Caches (API)
limparCacheAPI.title = Cache (API)
limparCacheAPI.message.naoconfigurado=A constante de configuração da URL da API não foi encontrada.
limparCacheAPI.message.pergunta=Deseja recarregar Cache selecionado na API?\n (API em questão ficará indisponível durante a execução)
limparCacheApiController.lbTipo.value = Entidade
limparCacheAPI.message.senha = Informe Sua Senha
#Relatório de Aproveitamento Financeiro
relatorioAproveitamentoFinanceiroController.window.title = Relatório de Aproveitamento Financeiro
relatorioAproveitamentoFinanceiroController.lbDatInicial.value = Data inicial

View File

@ -9627,7 +9627,14 @@ filtroTaxaEmbarqueW2i.labelAviso.value= Atenção. Certifique-se que todos os da
indexController.mniLimparCacheLocalidadesAPI.label = Recarregar Cache de Localidades (API)
limparCacheLocalidadesAPI.title = Localidades (API)
limparCacheLocalidadesAPI.message.naoconfigurado=A constante de configuração da URL da API não foi encontrada.
limparCacheLocalidadesAPI.message.pergunta=Deseja Recarregar Cache de Localidades (API) ? (API de Localidade ficará indisponível durante a execução)
limparCacheLocalidadesAPI.message.pergunta=Deseja Recarregar Cache de Localidades (API)? (API de Localidade ficará indisponível durante a execução)
indexController.mniLimparCacheAPI.label = Recarregar Caches (API)
limparCacheAPI.title = Cache (API)
limparCacheAPI.message.naoconfigurado=A constante de configuração da URL da API não foi encontrada.
limparCacheAPI.message.pergunta=Deseja recarregar Cache selecionado na API?\n (API em questão ficará indisponível durante a execução)
limparCacheApiController.lbTipo.value = Entidade
limparCacheAPI.message.senha = Informe Sua Senha
#Relatório de Aproveitamento Financeiro
relatorioAproveitamentoFinanceiroController.window.title = Relatório de Aproveitamento Financeiro

View File

@ -10487,6 +10487,14 @@ limparCacheEmbarcadaAPI.title = Cache Embarcada (API)
limparCacheEmbarcadaAPI.message.naoconfigurado=A constante de configuração da URL da API não foi encontrada. ATENÇÃO: Quando o cliente tem 2 APIs, uma para venda e outra para embarcada, as duas devem ser parametrizadas em constantes diferentes..
limparCacheEmbarcadaAPI.message.pergunta=Deseja recarregar o Cache de Sincronização (API) ?
indexController.mniLimparCacheAPI.label = Recarregar Caches (API)
limparCacheAPI.title = Cache (API)
limparCacheAPI.message.naoconfigurado=A constante de configuração da URL da API não foi encontrada.
limparCacheAPI.message.pergunta=Deseja recarregar Cache selecionado na API ? (API em questão ficará indisponível durante a execução)
limparCacheApiController.lbTipo.value = Entidade
limparCacheApiController.btnRecarregar.value = Recarregar Cache
limparCacheAPI.message.senha = Informe Sua Senha
#Relatório de Aproveitamento Financeiro
relatorioAproveitamentoFinanceiroController.window.title = Relatório de Aproveitamento Financeiro
relatorioAproveitamentoFinanceiroController.lbDatInicial.value = Data inicial

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<?page title="${arg.title}" language="xul/html"?>
<window title="${arg.title}" border="normal" width="auto" closable="true"
use="org.zkoss.zul.impl.MessageboxDlg">
<hbox>
<div class="${arg.icon}"/>
<div sclass="z-messagebox" width="auto">
<label value="${arg.message}" multiline="true"/>
</div>
<div sclass="z-messagebox" width="auto">
<textbox id="txtQuestion" type="password"/>
</div>
</hbox>
<separator bar="true"/>
<hbox style="margin-left:auto; margin-right:auto">
<button id="btn1" identity="${arg.OK}" sclass="z-messagebox-btn" use="org.zkoss.zul.impl.MessageboxDlg$Button"
if="$"/>
<button identity="${arg.CANCEL}" sclass="z-messagebox-btn" use="org.zkoss.zul.impl.MessageboxDlg$Button"
if="$"/>
<button identity="${arg.YES}" sclass="z-messagebox-btn" use="org.zkoss.zul.impl.MessageboxDlg$Button"
if="$"/>
<button identity="${arg.NO}" sclass="z-messagebox-btn" use="org.zkoss.zul.impl.MessageboxDlg$Button"
if="$"/>
<button identity="${arg.RETRY}" sclass="z-messagebox-btn" use="org.zkoss.zul.impl.MessageboxDlg$Button"
if="$"/>
<button identity="${arg.ABORT}" sclass="z-messagebox-btn" use="org.zkoss.zul.impl.MessageboxDlg$Button"
if="$"/>
<button identity="${arg.IGNORE}" sclass="z-messagebox-btn" use="org.zkoss.zul.impl.MessageboxDlg$Button"
if="$"/>
</hbox>
</window>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<?page contentType="text/html;charset=UTF-8"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="winLimparCacheApi"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk>
<window id="winLimparCacheApi" border="normal"
apply="${limparCacheApiController}" width="350px" height="130px"
contentStyle="overflow:auto"
title="${c:l('limparCacheAPI.title')}">
<toolbar>
<hbox spacing="5px" style="padding:1px" align="right">
<button id="btnFechar" height="20"
image="/gui/img/exit.png" width="35px"
onClick="winLimparCacheApi.detach()"
tooltiptext="${c:l('limparCacheApiController.btnFechar.tooltiptext')}" />
</hbox>
</toolbar>
<grid>
<columns>
<column width="20%" />
<column width="80%" />
</columns>
<rows>
<row>
<label id="lbTipo"
value="${c:l('limparCacheApiController.lbTipo.value')}" />
<combobox id="cmbItem"
mold="rounded" buttonVisible="true" width="100%"
use="com.rjconsultores.ventaboletos.web.utilerias.MyComboboxEstandar"
model="@{winLimparCacheApi$composer.lsCachesApiEnum}"
/>
</row>
</rows>
</grid>
<toolbar>
<button id="btnRecarregar" image="/gui/img/find.png"
label="${c:l('limparCacheApiController.btnRecarregar.value')}"/>
</toolbar>
</window>
</zk>