diff --git a/pom.xml b/pom.xml
index 17729f465..cf32cbdcd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,8 +8,8 @@
war
- 1.16.1
- 1.13.0
+ 1.17.0
+ 1.14.0
UTF-8
UTF-8
diff --git a/src/java/com/rjconsultores/ventaboletos/web/gui/controladores/seguridad/api/LimparCacheApiController.java b/src/java/com/rjconsultores/ventaboletos/web/gui/controladores/seguridad/api/LimparCacheApiController.java
new file mode 100644
index 000000000..ec7637807
--- /dev/null
+++ b/src/java/com/rjconsultores/ventaboletos/web/gui/controladores/seguridad/api/LimparCacheApiController.java
@@ -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 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 getLsCachesApiEnum() {
+ return lsCachesApiEnum;
+ }
+
+ public void setLsCachesApiEnum(List 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("\\|");
+ }
+}
diff --git a/src/java/com/rjconsultores/ventaboletos/web/utilerias/InputMessageBox.java b/src/java/com/rjconsultores/ventaboletos/web/utilerias/InputMessageBox.java
new file mode 100644
index 000000000..b9cea908c
--- /dev/null
+++ b/src/java/com/rjconsultores/ventaboletos/web/utilerias/InputMessageBox.java
@@ -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 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 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);
+ }
+
+}
diff --git a/src/java/com/rjconsultores/ventaboletos/web/utilerias/api/ApiCallRunnable.java b/src/java/com/rjconsultores/ventaboletos/web/utilerias/api/ApiCallRunnable.java
index b5d38f934..1a7768f5b 100644
--- a/src/java/com/rjconsultores/ventaboletos/web/utilerias/api/ApiCallRunnable.java
+++ b/src/java/com/rjconsultores/ventaboletos/web/utilerias/api/ApiCallRunnable.java
@@ -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;
@@ -61,15 +68,40 @@ public class ApiCallRunnable implements Runnable {
this.url = url;
this.tenant = tenant;
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;
+ }
+
}
\ No newline at end of file
diff --git a/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/item/seguridad/ItemMenuLimparCacheAPI.java b/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/item/seguridad/ItemMenuLimparCacheAPI.java
new file mode 100644
index 000000000..4d8d6d0d4
--- /dev/null
+++ b/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/item/seguridad/ItemMenuLimparCacheAPI.java
@@ -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);
+
+ }
+}
diff --git a/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/item/seguridad/ItemMenuLimparCacheLocalidadesAPI.java b/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/item/seguridad/ItemMenuLimparCacheLocalidadesAPI.java
index c8735cb55..fd8930d96 100644
--- a/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/item/seguridad/ItemMenuLimparCacheLocalidadesAPI.java
+++ b/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/item/seguridad/ItemMenuLimparCacheLocalidadesAPI.java
@@ -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();
diff --git a/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/menu_original.properties b/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/menu_original.properties
index 2ab4908e6..6fcb97e45 100644
--- a/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/menu_original.properties
+++ b/src/java/com/rjconsultores/ventaboletos/web/utilerias/menu/menu_original.properties
@@ -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
diff --git a/web/WEB-INF/i3-label_en.label b/web/WEB-INF/i3-label_en.label
index b0468b047..4cbfd9203 100644
--- a/web/WEB-INF/i3-label_en.label
+++ b/web/WEB-INF/i3-label_en.label
@@ -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
diff --git a/web/WEB-INF/i3-label_es_MX.label b/web/WEB-INF/i3-label_es_MX.label
index 9852ec8fd..548dc093d 100644
--- a/web/WEB-INF/i3-label_es_MX.label
+++ b/web/WEB-INF/i3-label_es_MX.label
@@ -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
diff --git a/web/WEB-INF/i3-label_pt_BR.label b/web/WEB-INF/i3-label_pt_BR.label
index e3f6a22a0..19e25d9e6 100644
--- a/web/WEB-INF/i3-label_pt_BR.label
+++ b/web/WEB-INF/i3-label_pt_BR.label
@@ -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
diff --git a/web/component/inputMessageBox.zul b/web/component/inputMessageBox.zul
new file mode 100644
index 000000000..dcd481c22
--- /dev/null
+++ b/web/component/inputMessageBox.zul
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/gui/seguridad/api/limparCacheApi.zul b/web/gui/seguridad/api/limparCacheApi.zul
new file mode 100644
index 000000000..e662f8900
--- /dev/null
+++ b/web/gui/seguridad/api/limparCacheApi.zul
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+