From cbd1ae1309b00e6c52c0ae8b891f124e6797c89f Mon Sep 17 00:00:00 2001 From: blavenie <benoit.lavenier@e-is.pro> Date: Fri, 19 May 2017 19:05:57 +0200 Subject: [PATCH] [fix] currency index is always clean at startup [fix] peer index not executed [fix] email subcription not executing [enh] Better message when error on http request [enh] new option to send email subscription at startup --- .../client/model/elasticsearch/Currency.java | 8 -- .../core/client/service/HttpServiceImpl.java | 34 ++++-- .../service/local/NetworkServiceImpl.java | 3 +- .../duniter4j-core-client_en_GB.properties | 5 +- .../duniter4j-core-client_fr_FR.properties | 5 +- .../src/main/assembly/config/logging.yml | 7 +- .../dao/impl/CurrencyDaoImpl.java | 6 -- .../AbstractBlockchainListenerService.java | 2 +- .../service/BlockchainService.java | 19 ---- .../service/CurrencyService.java | 102 +----------------- .../elasticsearch/service/PeerService.java | 2 +- .../subscription/PluginInit.java | 17 ++- .../subscription/PluginSettings.java | 8 ++ .../subscription/rest/RestModule.java | 5 +- .../service/SubscriptionService.java | 20 ++-- .../elasticsearch/user/model/UserEvent.java | 23 +--- 16 files changed, 76 insertions(+), 190 deletions(-) diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Currency.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Currency.java index 9a23e4f0..6ac3c695 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Currency.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Currency.java @@ -33,7 +33,6 @@ import java.io.Serializable; public class Currency extends org.duniter.core.client.model.local.Currency implements Serializable { private String[] tags; - private String issuer; public String[] getTags() { return tags; @@ -43,11 +42,4 @@ public class Currency extends org.duniter.core.client.model.local.Currency imple this.tags = tags; } - public String getIssuer() { - return issuer; - } - - public void setIssuer(String issuer) { - this.issuer = issuer; - } } \ No newline at end of file diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java index 7810c7e5..dbdb1ab4 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/HttpServiceImpl.java @@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Charsets; import com.google.common.base.Joiner; +import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; @@ -37,6 +38,7 @@ import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.utils.URIBuilder; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.entity.ContentType; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; @@ -50,6 +52,7 @@ import org.duniter.core.client.model.local.Peer; import org.duniter.core.client.service.bma.BmaTechnicalException; import org.duniter.core.client.service.exception.*; import org.duniter.core.exception.TechnicalException; +import org.duniter.core.util.ObjectUtils; import org.duniter.core.util.StringUtils; import org.duniter.core.util.cache.SimpleCache; import org.duniter.core.util.websocket.WebsocketClientEndpoint; @@ -62,6 +65,7 @@ import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URI; import java.net.URISyntaxException; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -299,7 +303,7 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean result = (T)response; } else { - result = (T) parseResponse(response, resultClass); + result = (T) parseResponse(request, response, resultClass); EntityUtils.consume(response.getEntity()); } break; @@ -311,7 +315,7 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean throw new HttpNotFoundException(I18n.t("duniter4j.client.notFound", request.toString())); case HttpStatus.SC_BAD_REQUEST: try { - Object errorResponse = parseResponse(response, errorClass); + Object errorResponse = parseResponse(request, response, errorClass); if (errorResponse instanceof Error) { throw new HttpBadRequestException((Error)errorResponse); } @@ -329,7 +333,7 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean break; default: String defaultMessage = I18n.t("duniter4j.client.status", request.toString(), response.getStatusLine().toString()); - if (response.getEntity() != null && response.getEntity().getContentType().toString().contains("application/json")) { + if (isContentType(response, ContentType.APPLICATION_JSON)) { JsonNode node = objectMapper.readTree(response.getEntity().getContent()); if (node.hasNonNull("ucode")) { throw new BmaTechnicalException(node.get("ucode").asInt(), node.get("message").asText(defaultMessage)); @@ -379,7 +383,7 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean return result; } - protected Object parseResponse(HttpResponse response, Class<?> ResultClass) throws IOException { + protected Object parseResponse(HttpUriRequest request, HttpResponse response, Class<?> ResultClass) throws IOException { Object result = null; boolean isStreamContent = ResultClass == null || ResultClass.equals(InputStream.class); @@ -411,11 +415,22 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean // deserialize Json else { + try { result = readValue(content, ResultClass); } catch (Exception e) { - throw new TechnicalException(I18n.t("duniter4j.client.core.invalidResponse"), e); + String requestPath = request.getURI().toString(); + + // Check if content-type error + ContentType contentType = ContentType.getOrDefault(response.getEntity()); + String actualMimeType = contentType.getMimeType(); + if (!ObjectUtils.equals(ContentType.APPLICATION_JSON.getMimeType(), actualMimeType)) { + throw new TechnicalException(I18n.t("duniter4j.client.core.invalidResponseContentType", requestPath, ContentType.APPLICATION_JSON.getMimeType(), actualMimeType)); + } + + // throw a generic error + throw new TechnicalException(I18n.t("duniter4j.client.core.invalidResponse", requestPath), e); } finally { if (content!= null) { @@ -425,12 +440,19 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean } if (result == null) { - throw new TechnicalException(I18n.t("duniter4j.client.core.emptyResponse")); + throw new TechnicalException(I18n.t("duniter4j.client.core.emptyResponse", request.getURI().toString())); } return result; } + private boolean isContentType(HttpResponse response, ContentType expectedContentType) { + if (response.getEntity() == null) return false; + ContentType contentType = ContentType.getOrDefault(response.getEntity()); + String actualMimeType = contentType.getMimeType(); + return ObjectUtils.equals(expectedContentType.getMimeType(), actualMimeType); + } + protected String getContentAsString(InputStream content) throws IOException { Reader reader = new InputStreamReader(content, StandardCharsets.UTF_8); StringBuilder result = new StringBuilder(); diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java index 924c107c..8e5f2888 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java @@ -466,7 +466,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network NetworkPeers.Peer peer = networkRemoteService.getPeerLeaf(requestedPeer, leaf); addEndpointsAsPeers(peer, result, leaf); - } catch(HttpNotFoundException e) { + } catch(HttpNotFoundException | TechnicalException e) { log.warn("Peer not found for leaf=" + leaf); // skip } @@ -524,7 +524,6 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network protected Peer getVersion(final Peer peer) { JsonNode json = executeRequest(peer, BMA_URL_STATUS, JsonNode.class); - // TODO update peer json = json.get("duniter"); if (json.isMissingNode()) throw new TechnicalException(String.format("Invalid format of [%s] response", BMA_URL_STATUS)); json = json.get("version"); diff --git a/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_en_GB.properties b/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_en_GB.properties index 3a45de92..b9d77141 100644 --- a/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_en_GB.properties +++ b/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_en_GB.properties @@ -1,7 +1,8 @@ duniter4j.client.authentication=Http request error (unauthorized or forbidden). duniter4j.client.core.connect=Could not connect to Duniter node [%s] -duniter4j.client.core.emptyResponse= -duniter4j.client.core.invalidResponse= +duniter4j.client.core.emptyResponse=[%s] Empty Response +duniter4j.client.core.invalidResponse=[%s] Invalid response +duniter4j.client.core.invalidResponseContentType=[%s] Invalid response content-type\: expected [%s] but get [%s] duniter4j.client.core.timeout= duniter4j.client.notFound=Resource non found [%s] duniter4j.client.status=Http request error\: %s diff --git a/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_fr_FR.properties b/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_fr_FR.properties index 1f9872aa..202c0342 100644 --- a/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_fr_FR.properties +++ b/duniter4j-core-client/src/main/resources/i18n/duniter4j-core-client_fr_FR.properties @@ -1,7 +1,8 @@ duniter4j.client.authentication=Echec de la requete (Accès interdit ou non autorisé). duniter4j.client.core.connect=Echec de la connection au noeud Duniter [%s] -duniter4j.client.core.emptyResponse=Réponse HTTP vide -duniter4j.client.core.invalidResponse=Réponse HTTP non valide +duniter4j.client.core.emptyResponse=[%s] Réponse vide +duniter4j.client.core.invalidResponse=[%s] Réponse non valide +duniter4j.client.core.invalidResponseContentType=[%s] Type de réponse invalide\: attendu [%s] mais [%s] obtenu duniter4j.client.core.timeout=Délai d'attente de la requête dépassé duniter4j.client.notFound=Ressource non trouvée [%s] duniter4j.client.status=Echec de requete HTTP [%s] \: %s diff --git a/duniter4j-es-assembly/src/main/assembly/config/logging.yml b/duniter4j-es-assembly/src/main/assembly/config/logging.yml index 808683b6..bfd01648 100644 --- a/duniter4j-es-assembly/src/main/assembly/config/logging.yml +++ b/duniter4j-es-assembly/src/main/assembly/config/logging.yml @@ -18,12 +18,13 @@ logger: security: INFO org.duniter: INFO - org.nuiton.i18n: WARN + org.nuiton.i18n: ERROR org.nuiton.config: ERROR org.nuiton.converter: WARN - org.glassfish.tyrus: WARN - org.apache.http: INFO + org.apache.http: WARN org.apache.http.client: ERROR + org.glassfish.grizzly: WARN + org.glassfish.tyrus: WARN # gateway #gateway: DEBUG diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/dao/impl/CurrencyDaoImpl.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/dao/impl/CurrencyDaoImpl.java index 07f265ec..357f4187 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/dao/impl/CurrencyDaoImpl.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/dao/impl/CurrencyDaoImpl.java @@ -183,12 +183,6 @@ public class CurrencyDaoImpl extends AbstractIndexTypeDao<CurrencyExtendDao> imp .field("type", "integer") .endObject() - // issuer - .startObject("issuer") - .field("type", "string") - .field("index", "not_analyzed") - .endObject() - // tags .startObject("tags") .field("type", "completion") diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractBlockchainListenerService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractBlockchainListenerService.java index 4c9bbf18..722b3aec 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractBlockchainListenerService.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractBlockchainListenerService.java @@ -139,7 +139,7 @@ public abstract class AbstractBlockchainListenerService extends AbstractService protected abstract void beforeFlush(); protected void flushBulkRequestOrSchedule() { - if (flushing) return; + if (flushing || bulkRequest.numberOfActions() == 0) return; // Flush now, if need or later if (bulkRequest.numberOfActions() % bulkSize == 0) { diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java index 34a4fbf4..8efd2166 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java @@ -47,7 +47,6 @@ import org.duniter.elasticsearch.PluginSettings; import org.duniter.elasticsearch.client.Duniter4jClient; import org.duniter.elasticsearch.dao.BlockDao; import org.duniter.elasticsearch.exception.DuplicateIndexIdException; -import org.duniter.elasticsearch.exception.NotFoundException; import org.duniter.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequestBuilder; @@ -386,26 +385,8 @@ public class BlockchainService extends AbstractService { return blockDao.getBlockById(currencyName, CURRENT_BLOCK_ID); } - public Map<String, Object> getBlockFieldsById(String currencyName, int number, String... fields) { - return getBlockFieldsById(currencyName, String.valueOf(number), fields); - } - - public Map<String, Object> getCurrentBlockFields(String currencyName, String... fields) { - return getBlockFieldsById(currencyName, CURRENT_BLOCK_ID, fields); - } - /* -- Internal methods -- */ - - protected Map<String, Object> getBlockFieldsById(String currency, String blockId, String... fields) { - try { - return client.getMandatoryFieldsById(currency, BLOCK_TYPE, blockId, fields); - } - catch(NotFoundException e) { - throw new BlockNotFoundException(e); - } - } - protected Collection<String> indexBlocksNoBulk(Peer peer, String currencyName, int firstNumber, int lastNumber, ProgressionModel progressionModel) { Set<String> missingBlockNumbers = new LinkedHashSet<>(); diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java index a715e5c4..07fdae83 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java @@ -118,7 +118,7 @@ public class CurrencyService extends AbstractService { } try { - Thread.sleep(10 * 1000); // wait 20s + Thread.sleep(10 * 1000); // wait 10s } catch(Exception e) { throw new TechnicalException(e); } @@ -146,7 +146,7 @@ public class CurrencyService extends AbstractService { result.setParameters(parameters); // Save it - saveCurrency(result, pluginSettings.getKeyringPublicKey()); + saveCurrency(result); return result; } @@ -154,21 +154,17 @@ public class CurrencyService extends AbstractService { /** * Save a blockchain (update or create) into the blockchain index. * @param currency - * @param issuer * @throws DuplicateIndexIdException * @throws AccessDeniedException if exists and user if not the original blockchain sender */ - public void saveCurrency(Currency currency, String issuer) throws DuplicateIndexIdException { + public void saveCurrency(Currency currency) throws DuplicateIndexIdException { Preconditions.checkNotNull(currency, "currency could not be null") ; Preconditions.checkNotNull(currency.getId(), "currency attribute 'currency' could not be null"); - String previousIssuer = getSenderPubkeyByCurrencyId(currency.getId()); + boolean exists = currencyDao.isExists(currency.getId()); // Currency not exists, so create it - if (previousIssuer == null) { - // make sure to fill the sender - currency.setIssuer(issuer); - + if (!exists) { // Save it currencyDao.create(currency); @@ -181,14 +177,6 @@ public class CurrencyService extends AbstractService { // Exists, so check the owner signature else { - if (issuer != null && !Objects.equals(issuer, previousIssuer)) { - throw new AccessDeniedException("Could not change the currency, because it has been registered by another public key."); - } - - // Make sure the sender is not changed - if (issuer != null) { - currency.setIssuer(previousIssuer); - } // Save changes currencyDao.update(currency); @@ -199,88 +187,8 @@ public class CurrencyService extends AbstractService { } } - /** - * Registrer a new blockchain. - * @param pubkey the sender pubkey - * @param jsonCurrency the blockchain, as JSON - * @param signature the signature of sender. - * @throws InvalidSignatureException if signature not correspond to sender pubkey - */ - public void insertCurrency(String pubkey, String jsonCurrency, String signature) { - Preconditions.checkNotNull(pubkey); - Preconditions.checkNotNull(jsonCurrency); - Preconditions.checkNotNull(signature); - - if (!cryptoService.verify(jsonCurrency, signature, pubkey)) { - String currencyName = JacksonUtils.getValueFromJSONAsString(jsonCurrency, "currencyName"); - logger.warn(String.format("Currency not added, because bad signature. blockchain [%s]", currencyName)); - throw new InvalidSignatureException("Bad signature"); - } - - Currency currency; - try { - currency = objectMapper.readValue(jsonCurrency, Currency.class); - Preconditions.checkNotNull(currency); - Preconditions.checkNotNull(currency.getCurrencyName()); - } catch(Throwable t) { - logger.error("Error while reading blockchain JSON: " + jsonCurrency); - throw new TechnicalException("Error while reading blockchain JSON: " + jsonCurrency, t); - } - - saveCurrency(currency, pubkey); - } - - - /* -- Internal methods -- */ - - - /** - * Retrieve a blockchain from its name - * @param currencyId - * @return - */ - protected String getSenderPubkeyByCurrencyId(String currencyId) { - - if (!isCurrencyExists(currencyId)) { - return null; - } - - // Prepare request - - SearchRequestBuilder searchRequest = client - .prepareSearch(INDEX) - .setTypes(RECORD_TYPE) - .setSearchType(SearchType.QUERY_AND_FETCH); - - // If more than a word, search on terms match - searchRequest.setQuery(new IdsQueryBuilder().addIds(currencyId)); - - // Execute query - try { - SearchResponse response = searchRequest.execute().actionGet(); - - // Read query result - SearchHit[] searchHits = response.getHits().getHits(); - for (SearchHit searchHit : searchHits) { - if (searchHit.source() != null) { - Currency currency = objectMapper.readValue(new String(searchHit.source(), "UTF-8"), Currency.class); - return currency.getIssuer(); - } - else { - SearchHitField field = searchHit.getFields().get("issuer"); - return field.getValue().toString(); - } - } - } - catch(SearchPhaseExecutionException | IOException e) { - // Failed or no item on index - } - - return null; - } - protected IndexDao<?> getCurrencyDataDao(final String currencyId) { // Create data IndexDao<?> dataDao = currencyDataDaos.get(currencyId); diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/PeerService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/PeerService.java index 83c53144..1313fe25 100644 --- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/PeerService.java +++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/PeerService.java @@ -71,7 +71,7 @@ public class PeerService extends AbstractService { CryptoService cryptoService, PeerDao peerDao, final ServiceLocator serviceLocator){ - super("duniter.peers", client, settings, cryptoService); + super("duniter.network.peer", client, settings, cryptoService); this.peerDao = peerDao; this.threadPool = threadPool; threadPool.scheduleOnStarted(() -> { diff --git a/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/PluginInit.java b/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/PluginInit.java index 5eec5ec7..3716c074 100644 --- a/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/PluginInit.java +++ b/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/PluginInit.java @@ -109,22 +109,17 @@ public class PluginInit extends AbstractLifecycleComponent<PluginInit> { protected void doAfterStart() { - // Wait cluster state OK, then synchronize - threadPool.scheduleOnClusterHealthStatus(this::synchronize, - ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN); - } + // Start subscription services + if (pluginSettings.enableSubscription()) { - protected void synchronize() { + injector.getInstance(SubscriptionService.class).startScheduling(); + } + // Synchronize data if (pluginSettings.enableDataSync()) { // Synchronize injector.getInstance(SynchroService.class).synchronize(); } - - // Start subscription services - if (pluginSettings.enableSubscription()) { - - injector.getInstance(SubscriptionService.class).startScheduling(); - } } + } diff --git a/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/PluginSettings.java b/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/PluginSettings.java index 8bd0c1ee..4d1473f8 100644 --- a/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/PluginSettings.java +++ b/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/PluginSettings.java @@ -83,6 +83,14 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> { return this.settings.get("duniter.subscription.email.cesium.url", "https://g1.duniter.fr"); } + /** + * Should email subscription be send at startup ? + * @return + */ + public boolean isEmailSubscriptionsExecuteAtStartup() { + return settings.getAsBoolean("duniter.subscription.email.atStartup", false); + } + /** * Day of the week to trigger weekly email subscription (default: 2 = monday) * @return diff --git a/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/rest/RestModule.java b/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/rest/RestModule.java index ab10fa80..3c9c969e 100644 --- a/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/rest/RestModule.java +++ b/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/rest/RestModule.java @@ -22,9 +22,10 @@ package org.duniter.elasticsearch.subscription.rest; * #L% */ +import org.duniter.elasticsearch.subscription.rest.execution.RestSubscriptionExecutionGetAction; +import org.duniter.elasticsearch.subscription.rest.record.RestSubscriptionCategoryGetAction; import org.duniter.elasticsearch.subscription.rest.record.RestSubscriptionRecordIndexAction; import org.duniter.elasticsearch.subscription.rest.record.RestSubscriptionRecordUpdateAction; -import org.duniter.elasticsearch.subscription.rest.record.RestSubscriptionCategoryGetAction; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Module; @@ -36,7 +37,7 @@ public class RestModule extends AbstractModule implements Module { bind(RestSubscriptionCategoryGetAction.class).asEagerSingleton(); // Subscription execution - bind(RestSubscriptionCategoryGetAction.class).asEagerSingleton(); + bind(RestSubscriptionExecutionGetAction.class).asEagerSingleton(); // Subscription record bind(RestSubscriptionRecordIndexAction.class).asEagerSingleton(); diff --git a/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/service/SubscriptionService.java b/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/service/SubscriptionService.java index 3e63b770..8a955cbc 100644 --- a/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/service/SubscriptionService.java +++ b/duniter4j-es-subscription/src/main/java/org/duniter/elasticsearch/subscription/service/SubscriptionService.java @@ -34,7 +34,6 @@ import org.duniter.core.service.CryptoService; import org.duniter.core.util.CollectionUtils; import org.duniter.core.util.Preconditions; import org.duniter.core.util.StringUtils; -import org.duniter.core.util.concurrent.CompletableFutures; import org.duniter.core.util.crypto.CryptoUtils; import org.duniter.elasticsearch.client.Duniter4jClient; import org.duniter.elasticsearch.subscription.PluginSettings; @@ -46,8 +45,6 @@ import org.duniter.elasticsearch.subscription.model.email.EmailSubscription; import org.duniter.elasticsearch.subscription.util.DateUtils; import org.duniter.elasticsearch.subscription.util.stringtemplate.DateRenderer; import org.duniter.elasticsearch.subscription.util.stringtemplate.StringRenderer; -import org.duniter.elasticsearch.threadpool.CompletableActionFuture; -import org.duniter.elasticsearch.threadpool.ScheduledActionFuture; import org.duniter.elasticsearch.threadpool.ThreadPool; import org.duniter.elasticsearch.user.model.UserEvent; import org.duniter.elasticsearch.user.service.AdminService; @@ -55,15 +52,14 @@ import org.duniter.elasticsearch.user.service.MailService; import org.duniter.elasticsearch.user.service.UserEventService; import org.duniter.elasticsearch.user.service.UserService; import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.unit.TimeValue; import org.nuiton.i18n.I18n; import org.stringtemplate.v4.ST; import org.stringtemplate.v4.STGroup; import org.stringtemplate.v4.STGroupDir; -import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -92,7 +88,7 @@ public class SubscriptionService extends AbstractService { AdminService adminService, UserService userService, UserEventService userEventService) { - super("subscription.service", client, settings, cryptoService); + super("duniter.subscription", client, settings, cryptoService); this.subscriptionRecordDao = subscriptionRecordDao; this.subscriptionExecutionDao = subscriptionExecutionDao; this.threadPool = threadPool; @@ -156,6 +152,14 @@ public class SubscriptionService extends AbstractService { logger.warn(I18n.t("duniter4j.es.subscription.email.start", pluginSettings.getEmailSubscriptionsExecuteHour(), dayOfWeek)); } + // Execution at startup + if (pluginSettings.isEmailSubscriptionsExecuteAtStartup()) { + threadPool.schedule( + () -> executeEmailSubscriptions(EmailSubscription.Frequency.daily), + new TimeValue(20, TimeUnit.SECONDS) /* after 20s */ + ); + } + // Daily execution threadPool.scheduleAtFixedRate( () -> executeEmailSubscriptions(EmailSubscription.Frequency.daily), @@ -390,10 +394,10 @@ public class SubscriptionService extends AbstractService { if (execution.getId() == null) { - subscriptionExecutionDao.create(json, false/*not wait*/); + //subscriptionExecutionDao.create(json, false/*not wait*/); } else { - subscriptionExecutionDao.update(execution.getId(), json, false/*not wait*/); + //subscriptionExecutionDao.update(execution.getId(), json, false/*not wait*/); } return execution; } diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/model/UserEvent.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/model/UserEvent.java index 95c9e97a..70d0d09e 100644 --- a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/model/UserEvent.java +++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/model/UserEvent.java @@ -22,10 +22,7 @@ package org.duniter.elasticsearch.user.model; * #L% */ -import com.fasterxml.jackson.annotation.JsonGetter; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.ObjectMapper; import org.duniter.core.util.Preconditions; import org.duniter.core.client.model.elasticsearch.Record; @@ -178,24 +175,6 @@ public class UserEvent extends Record { this.id = id; } - @JsonIgnore - public String toJson() { - try { - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - return mapper.writeValueAsString(this); - } catch(Exception e) { - throw new TechnicalException(e); - } - } - - @JsonIgnore - public String toJson(Locale locale) { - UserEvent copy = new UserEvent(this); - copy.setMessage(getLocalizedMessage(locale)); - return copy.toJson(); - } - private static long getDefaultTime() { return Math.round(1d * System.currentTimeMillis() / 1000); } -- GitLab