Skip to content
Snippets Groups Projects
Commit 17cc0ab4 authored by Benoit Lavenier's avatar Benoit Lavenier
Browse files

- shared: Add mail service

 - elasticsearch: Add event service
parent 7b6ac381
No related branches found
No related tags found
No related merge requests found
Showing
with 803 additions and 8 deletions
package org.duniter.core.client.model.elasticsearch;
import org.nuiton.i18n.I18n;
import java.util.Locale;
/**
* Created by blavenie on 29/11/16.
*/
public class Event extends Record {
public static final String PROPERTY_TYPE="type";
public static final String PROPERTY_CODE="code";
public static final String PROPERTY_MESSAGE="message";
public static final String PROPERTY_PARAMS="params";
private String type;
private String code;
private String message;
private String[] params;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String[] getParams() {
return params;
}
public void setParams(String[] params) {
this.params = params;
}
}
......@@ -30,6 +30,7 @@ import org.duniter.core.client.service.elasticsearch.CurrencyRegistryRemoteServi
import org.duniter.core.client.service.local.CurrencyService;
import org.duniter.core.client.service.local.PeerService;
import org.duniter.core.service.CryptoService;
import org.duniter.core.service.MailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -139,6 +140,10 @@ public class ServiceLocator implements Closeable {
return getBean(CurrencyRegistryRemoteService.class);
}
public MailService getMaiLService() {
return getBean(MailService.class);
}
public <S extends Bean> S getBean(Class<S> clazz) {
if (beanFactory == null) {
initBeanFactory();
......
......@@ -58,6 +58,10 @@
<groupId>org.nuiton.i18n</groupId>
<artifactId>nuiton-i18n</artifactId>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</dependency>
<!-- Unit test -->
<dependency>
......
package org.duniter.core.service;
import org.duniter.core.beans.Bean;
import org.duniter.core.exception.TechnicalException;
import javax.mail.internet.ContentType;
import javax.mail.internet.ParseException;
/**
* Created by blavenie on 28/11/16.
*/
public interface MailService extends Bean {
void sendTextEmail(String smtpHost,
int smtpPort,
String smtpUsername,
String smtpPassword,
String issuer,
String recipients,
String subject,
String textContent);
void sendEmail(String smtpHost,
int smtpPort,
String smtpUsername,
String smtpPassword,
String issuer,
String recipients,
String subject,
ContentType contentType,
String content);
}
package org.duniter.core.service;
import org.duniter.core.exception.TechnicalException;
import org.duniter.core.util.StringUtils;
import javax.mail.*;
import javax.mail.internet.ContentType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.ParseException;
import java.io.Closeable;
import java.util.Properties;
public class MailServiceImpl implements MailService, Closeable {
private static Session session;
private static Transport transport;
public MailServiceImpl() {
}
@Override
public void sendTextEmail(String smtpHost,
int smtpPort,
String smtpUsername,
String smtpPassword,
String issuer,
String recipients,
String subject,
String textContent) {
try{
ContentType contentType = new ContentType("text/plain");
contentType.setParameter("charset", "UTF-8");
sendEmail(smtpHost, smtpPort, smtpUsername, smtpPassword,
issuer,
recipients,
subject,
contentType,
textContent);
}
catch(ParseException e) {
// Should never occur
throw new TechnicalException(e);
}
}
@Override
public void sendEmail(String smtpHost,
int smtpPort,
String smtpUsername,
String smtpPassword,
String issuer,
String recipients,
String subject,
ContentType contentType,
String content) {
// check arguments
if (StringUtils.isBlank(smtpHost) || smtpPort <= 0) {
throw new TechnicalException("Invalid arguments: 'smtpHost' could not be null or empty, and 'smtpPort' could not be <= 0");
}
if (StringUtils.isBlank(issuer)) {
throw new TechnicalException("Invalid arguments: 'issuer' could not be null or empty");
}
if (StringUtils.isBlank(recipients) || StringUtils.isBlank(subject) || StringUtils.isBlank(content) || contentType == null) {
throw new TechnicalException("Invalid arguments: 'recipients', 'subject', 'contentType' or 'content' could not be null or empty");
}
if (!isConnected()) {
connect(smtpHost, smtpPort, smtpUsername, smtpPassword, issuer);
}
// send email to recipients
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(issuer));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
message.setSubject(subject);
message.setContent(content, contentType.toString());
message.saveChanges();
transport.sendMessage(message, message.getAllRecipients());
} catch (MessagingException e) {
throw new TechnicalException(String.format("Error while sending email to [%s] using smtp server [%s]",
recipients,
getSmtpServerAsString(smtpHost, smtpPort, smtpUsername)
), e);
} catch (IllegalStateException e) {
throw new TechnicalException(String.format("Error while sending email to [%s] using smtp server [%s]",
recipients,
getSmtpServerAsString(smtpHost, smtpPort, smtpUsername)
), e);
}
}
public void close() {
if (isConnected()) {
try {
transport.close();
}
catch(Exception e) {
// silent is gold
}
transport = null;
session = null;
}
}
/* -- private methods -- */
private String getSmtpServerAsString(String smtpHost, int smtpPort, String smtpUsername) {
StringBuilder buffer = new StringBuilder();
if (StringUtils.isNotBlank(smtpUsername)) {
buffer.append(smtpUsername).append("@");
}
return buffer.append(smtpHost)
.append(":")
.append(smtpPort)
.toString();
}
private void connect(String smtpHost, int smtpPort,
String smtpUsername,
String smtpPassword,
String issuer) {
Properties props = new Properties();
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", smtpPort);
if (StringUtils.isNotBlank(issuer)) {
props.put("mail.from", issuer);
}
boolean useAuth = false;
// auto set authentification if smtp user name is provided
if (StringUtils.isNotBlank(smtpUsername)) {
props.put("mail.smtp.auth", "true");
//props.put("mail.smtp.starttls.enable", "true");
useAuth = true;
}
session = Session.getInstance(props);
try {
transport = session.getTransport("smtp");
if (useAuth) {
transport.connect(smtpUsername, smtpPassword);
} else {
transport.connect();
}
} catch (NoSuchProviderException e) {
throw new TechnicalException(e);
} catch (MessagingException e) {
throw new TechnicalException(e);
}
}
private boolean isConnected() {
if ((session == null) || (transport == null)) {
return false;
}
return transport.isConnected();
}
}
\ No newline at end of file
org.duniter.core.service.Ed25519CryptoServiceImpl
\ No newline at end of file
org.duniter.core.service.Ed25519CryptoServiceImpl
org.duniter.core.service.MailServiceImpl
\ No newline at end of file
......@@ -241,6 +241,34 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
return settings.getAsInt("duniter.data.sync.port", 80);
}
public String getMailSmtpHost() {
return settings.get("duniter.mail.smtp.host", "localhost");
}
public int getMailSmtpPort() {
return settings.getAsInt("duniter.mail.smtp.port", 25);
}
public String getMailSmtpUsername() {
return settings.get("duniter.mail.smtp.username");
}
public String getMailSmtpPassword() {
return settings.get("duniter.mail.smtp.password");
}
public String getMailAdmin() {
return settings.get("duniter.mail.admin");
}
public String getMailFrom() {
return settings.get("duniter.mail.from", "no-reply@duniter.fr");
}
public String getMailSubjectPrefix() {
return settings.get("duniter.mail.subject.prefix", "[Duniter4j ES]");
}
/* protected methods */
protected void initI18n() throws IOException {
......
......@@ -27,8 +27,12 @@ import org.duniter.core.client.model.local.Peer;
import org.duniter.elasticsearch.PluginSettings;
import org.duniter.elasticsearch.action.security.RestSecurityController;
import org.duniter.elasticsearch.service.*;
import org.duniter.elasticsearch.service.event.Event;
import org.duniter.elasticsearch.service.event.EventCodes;
import org.duniter.elasticsearch.service.event.EventService;
import org.duniter.elasticsearch.service.synchro.SynchroService;
import org.duniter.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
......@@ -47,13 +51,17 @@ public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
private final ThreadPool threadPool;
private final Injector injector;
private final static ESLogger logger = Loggers.getLogger("node");
private final Client client;
private final String clusterName;
@Inject
public DuniterNode(Settings settings, PluginSettings pluginSettings, ThreadPool threadPool, final Injector injector) {
public DuniterNode(Client client, Settings settings, PluginSettings pluginSettings, ThreadPool threadPool, final Injector injector) {
super(settings);
this.pluginSettings = pluginSettings;
this.threadPool = threadPool;
this.injector = injector;
this.client = client;
this.clusterName = settings.get("cluster.name");
}
@Override
......@@ -66,6 +74,16 @@ public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
synchronize();
}, ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN);
}, ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN);
// When started
threadPool.scheduleOnStarted(() -> {
// Notify admin
injector.getInstance(EventService.class)
.notifyAdmin(new Event(
Event.EventType.INFO,
EventCodes.NODE_STARTED.name(),
new String[]{clusterName}));
});
}
@Override
......@@ -104,6 +122,11 @@ public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
.deleteIndex()
.createIndexIfNotExists();
injector.getInstance(EventService.class)
.deleteIndex()
.createIndexIfNotExists();
if (logger.isInfoEnabled()) {
logger.info("Reloading all Duniter indices... [OK]");
}
......@@ -117,6 +140,7 @@ public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
injector.getInstance(MessageService.class).createIndexIfNotExists();
injector.getInstance(UserService.class).createIndexIfNotExists();
injector.getInstance(HistoryService.class).createIndexIfNotExists();
injector.getInstance(EventService.class).createIndexIfNotExists();
if (logger.isInfoEnabled()) {
logger.info("Checking Duniter indices... [OK]");
......
......@@ -40,6 +40,8 @@ import org.duniter.core.client.service.local.PeerServiceImpl;
import org.duniter.core.exception.TechnicalException;
import org.duniter.core.service.CryptoService;
import org.duniter.core.service.Ed25519CryptoServiceImpl;
import org.duniter.core.service.MailService;
import org.duniter.core.service.MailServiceImpl;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.Injector;
import org.elasticsearch.common.inject.Singleton;
......@@ -90,6 +92,7 @@ public class ServiceLocator
.bind(WotRemoteService.class, WotRemoteServiceImpl.class)
.bind(TransactionRemoteService.class, TransactionRemoteServiceImpl.class)
.bind(CryptoService.class, Ed25519CryptoServiceImpl.class)
.bind(MailService.class, MailServiceImpl.class)
.bind(PeerService.class, PeerServiceImpl.class)
.bind(CurrencyService.class, CurrencyServiceImpl.class)
.bind(HttpService.class, HttpServiceImpl.class)
......
......@@ -35,6 +35,7 @@ import org.duniter.core.client.service.local.CurrencyService;
import org.duniter.core.client.service.local.PeerService;
import org.duniter.core.service.CryptoService;
import org.duniter.elasticsearch.PluginSettings;
import org.duniter.elasticsearch.service.event.EventService;
import org.duniter.elasticsearch.service.synchro.SynchroService;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module;
......@@ -46,6 +47,7 @@ public class ServiceModule extends AbstractModule implements Module {
// ES common service
bind(PluginSettings.class).asEagerSingleton();
bind(EventService.class).asEagerSingleton();
// ES indexation services
bind(RegistryService.class).asEagerSingleton();
......@@ -62,7 +64,6 @@ public class ServiceModule extends AbstractModule implements Module {
bindWithLocator(NetworkRemoteService.class);
bindWithLocator(WotRemoteService.class);
bindWithLocator(TransactionRemoteService.class);
bindWithLocator(CryptoService.class);
bindWithLocator(PeerService.class);
bindWithLocator(CurrencyService.class);
bindWithLocator(HttpService.class);
......@@ -70,6 +71,10 @@ public class ServiceModule extends AbstractModule implements Module {
bindWithLocator(PeerDao.class);
bindWithLocator(DataContext.class);
// Duniter Shared API beans
bindWithLocator(CryptoService.class);
bindWithLocator(org.duniter.core.service.MailService.class);
/*
bindWithLocator(BlockchainRemoteServiceImpl.class);
bindWithLocator(NetworkRemoteServiceImpl.class);
......
......@@ -29,6 +29,7 @@ import org.duniter.core.client.service.bma.BlockchainRemoteService;
import org.duniter.core.client.service.bma.WotRemoteService;
import org.duniter.core.exception.TechnicalException;
import org.duniter.core.service.CryptoService;
import org.duniter.core.service.MailService;
import org.duniter.elasticsearch.PluginSettings;
import org.duniter.elasticsearch.exception.AccessDeniedException;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
......@@ -54,7 +55,8 @@ public class UserService extends AbstractService {
@Inject
public UserService(Client client,
PluginSettings settings,
CryptoService cryptoService) {
CryptoService cryptoService,
MailService mailService) {
super("gchange." + INDEX, client, settings,cryptoService);
}
......
package org.duniter.elasticsearch.service.event;
import org.nuiton.i18n.I18n;
import java.util.Locale;
/**
* Created by blavenie on 29/11/16.
*/
public class Event {
private EventType type;
private String code;
private long time;
private String message;
private String[] params;
public Event(EventType type, String code) {
this(type, code, null);
}
public Event(EventType type, String code, String[] params) {
this.type = type;
this.code = code;
this.params = params;
// default
this.message = I18n.t("duniter4j.event." + code, params);
this.time = Math.round(1d * System.currentTimeMillis() / 1000);
}
public EventType getType() {
return type;
}
public void setType(EventType type) {
this.type = type;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public String getLocalizedMessage(Locale locale) {
return I18n.l(locale, "duniter4j.event." + code, params);
}
public void setMessage(String message) {
this.message = message;
}
public String[] getParams() {
return params;
}
public void setParams(String[] params) {
this.params = params;
}
public long getTime() {
return time;
}
public enum EventType {
INFO,
WARN,
ERROR
}
}
package org.duniter.elasticsearch.service.event;
/**
* Created by blavenie on 29/11/16.
*/
public enum EventCodes {
NODE_STARTED
}
package org.duniter.elasticsearch.service.event;
/*
* #%L
* UCoin Java Client :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import org.duniter.core.exception.TechnicalException;
import org.duniter.core.service.CryptoService;
import org.duniter.core.service.MailService;
import org.duniter.core.util.CollectionUtils;
import org.duniter.core.util.StringUtils;
import org.duniter.core.util.crypto.CryptoUtils;
import org.duniter.core.util.crypto.KeyPair;
import org.duniter.elasticsearch.PluginSettings;
import org.duniter.elasticsearch.service.AbstractService;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.nuiton.i18n.I18n;
import java.io.IOException;
import java.util.Locale;
/**
* Created by Benoit on 30/03/2015.
*/
public class EventService extends AbstractService {
public static final String INDEX = "user";
public static final String EVENT_TYPE = "event";
private final MailService mailService;
public final KeyPair nodeKeyPair;
public final String nodePubkey;
@Inject
public EventService(Client client, PluginSettings settings, CryptoService cryptoService, MailService mailService) {
super("duniter.event." + INDEX, client, settings, cryptoService);
this.mailService = mailService;
this.nodeKeyPair = getNodeKeyPairOrNull(pluginSettings);
this.nodePubkey = getNodePubKey(this.nodeKeyPair);
}
/**
* Notify cluster admin
*/
public void notifyAdmin(Event event) {
Locale locale = I18n.getDefaultLocale(); // TODO get locale from admin
// Add new event to index
if (StringUtils.isNotBlank(nodePubkey)) {
indexEvent(nodePubkey, locale, event);
}
// Retrieve admin email
String adminEmail = pluginSettings.getMailAdmin();
if (StringUtils.isBlank(adminEmail) && StringUtils.isNotBlank(nodePubkey)) {
adminEmail = getEmailByPk(nodePubkey);
}
// Send email to admin
if (StringUtils.isNotBlank(adminEmail)) {
String subjectPrefix = pluginSettings.getMailSubjectPrefix();
sendEmail(adminEmail,
I18n.l(locale, "duniter4j.event.subject."+event.getType().name(), subjectPrefix),
event.getLocalizedMessage(locale));
}
}
/**
* Notify a user
*/
public void notifyUser(String recipient, Event event) {
String email = getEmailByPk(recipient);
Locale locale = I18n.getDefaultLocale(); // TODO get locale
// Add new event to index
indexEvent(recipient, locale, event);
// Send email to user
if (StringUtils.isNotBlank(email)) {
String subjectPrefix = pluginSettings.getMailSubjectPrefix();
sendEmail(email,
I18n.l(locale, "duniter4j.event.subject."+event.getType().name(), subjectPrefix),
event.getLocalizedMessage(locale));
}
}
/**
* Delete blockchain index, and all data
* @throws JsonProcessingException
*/
public EventService deleteIndex() {
deleteIndexIfExists(INDEX);
return this;
}
public boolean existsIndex() {
return super.existsIndex(INDEX);
}
/**
* Create index need for blockchain registry, if need
*/
public EventService createIndexIfNotExists() {
try {
if (!existsIndex(INDEX)) {
createIndex();
}
}
catch(JsonProcessingException e) {
throw new TechnicalException(String.format("Error while creating index [%s]", INDEX));
}
return this;
}
/**
* Create index need for category registry
* @throws JsonProcessingException
*/
public EventService createIndex() throws JsonProcessingException {
logger.info(String.format("Creating index [%s/%s]", INDEX, EVENT_TYPE));
CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(INDEX);
Settings indexSettings = Settings.settingsBuilder()
.put("number_of_shards", 2)
.put("number_of_replicas", 1)
//.put("analyzer", createDefaultAnalyzer())
.build();
createIndexRequestBuilder.setSettings(indexSettings);
createIndexRequestBuilder.addMapping(EVENT_TYPE, createEventType());
createIndexRequestBuilder.execute().actionGet();
return this;
}
public String indexEvent(String recipient, Locale locale, Event event) {
// Generate json
String eventJson;
if (StringUtils.isNotBlank(nodePubkey)) {
eventJson = toJson(nodePubkey, recipient, locale, event, null);
String signature = cryptoService.sign(eventJson, nodeKeyPair.getSecKey());
eventJson = toJson(nodePubkey, recipient, locale, event, signature);
} else {
// Node has not keyring : TODO no issuer ?
eventJson = toJson(recipient, recipient, locale, event, null);
}
if (logger.isDebugEnabled()) {
logger.debug(String.format("Indexing a event to recipient [%s]", recipient.substring(0, 8)));
}
// do indexation
return indexEvent(eventJson, false /*checkSignature*/);
}
public String indexEvent(String eventJson) {
return indexEvent(eventJson, true);
}
public String indexEvent(String eventJson, boolean checkSignature) {
if (checkSignature) {
JsonNode jsonNode = readAndVerifyIssuerSignature(eventJson);
String recipient = jsonNode.get(org.duniter.core.client.model.elasticsearch.Event.PROPERTY_ISSUER).asText();
if (logger.isDebugEnabled()) {
logger.debug(String.format("Indexing a event to recipient [%s]", recipient.substring(0, 8)));
}
}
if (logger.isTraceEnabled()) {
logger.trace(eventJson);
}
IndexResponse response = client.prepareIndex(INDEX, EVENT_TYPE)
.setSource(eventJson)
.setRefresh(false)
.execute().actionGet();
return response.getId();
}
/* -- Internal methods -- */
public XContentBuilder createEventType() {
try {
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(EVENT_TYPE)
.startObject("properties")
// type
.startObject("type")
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
// issuer
.startObject("issuer")
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
// recipient
.startObject("recipient")
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
// time
.startObject("time")
.field("type", "integer")
.endObject()
// code
.startObject("code")
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
// params
.startObject("params")
.field("type", "string")
.endObject()
// message
.startObject("message")
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
.endObject()
.endObject().endObject();
return mapping;
}
catch(IOException ioe) {
throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX, EVENT_TYPE, ioe.getMessage()), ioe);
}
}
private String getEmailByPk(String issuerPk) {
return "benoit.lavenier@e-is.pro";
}
private String getEmailSubject(Locale locale, Event event) {
return I18n.l(locale, "duniter4j.event.subject."+event.getType().name());
}
/**
* Send email
*/
private void sendEmail(String recipients, String subject, String textContent) {
String smtpHost = pluginSettings.getMailSmtpHost();
int smtpPort = pluginSettings.getMailSmtpPort();
String smtpUsername = pluginSettings.getMailSmtpUsername();
String smtpPassword = pluginSettings.getMailSmtpPassword();
String from = pluginSettings.getMailFrom();
try {
mailService.sendTextEmail(smtpHost, smtpPort, smtpUsername, smtpPassword, from, recipients, subject, textContent);
}
catch(TechnicalException e) {
if (logger.isDebugEnabled()) {
logger.error(String.format("Error while trying to send email: %s", e.getMessage()), e);
}
else {
logger.error(String.format("Error while trying to send email: %s", e.getMessage()));
}
}
}
private String toJson(String issuer, String recipient, Locale locale, Event event, String signature) {
try {
XContentBuilder eventObject = XContentFactory.jsonBuilder().startObject()
.field("type", event.getType().name())
.field("issuer", issuer) // TODO isuer = node pubkey
.field("recipient", recipient)
.field("time", event.getTime())
.field("code", event.getCode())
.field("message", event.getLocalizedMessage(locale));
if (CollectionUtils.isNotEmpty(event.getParams())) {
eventObject.array("params", event.getParams());
}
if (StringUtils.isNotBlank(signature)) {
eventObject.field("signature", signature);
}
eventObject.endObject();
return eventObject.string();
}
catch(IOException e) {
throw new TechnicalException(e);
}
}
private KeyPair getNodeKeyPairOrNull(PluginSettings pluginSettings) {
if (StringUtils.isNotBlank(pluginSettings.getKeyringSalt()) &&
StringUtils.isNotBlank(pluginSettings.getKeyringPassword())) {
return cryptoService.getKeyPair(pluginSettings.getKeyringSalt(),
pluginSettings.getKeyringPassword());
}
return null;
}
private String getNodePubKey(KeyPair nodeKeyPair) {
if (nodeKeyPair == null) return null;
return CryptoUtils.encodeBase58(nodeKeyPair.getPubKey());
}
}
......@@ -4,6 +4,7 @@ org.duniter.core.client.service.bma.WotRemoteServiceImpl
org.duniter.core.client.service.bma.TransactionRemoteServiceImpl
org.duniter.core.client.service.elasticsearch.CurrencyRegistryRemoteServiceImpl
org.duniter.core.service.Ed25519CryptoServiceImpl
org.duniter.core.service.MailServiceImpl
org.duniter.core.client.service.HttpServiceImpl
org.duniter.core.client.service.DataContext
org.duniter.core.client.service.local.PeerServiceImpl
......
......@@ -34,6 +34,10 @@ duniter4j.config.option.tasks.queueCapacity.description=
duniter4j.config.option.temp.directory.description=
duniter4j.config.option.version.description=
duniter4j.config.parse.error=
duniter4j.event.NODE_STARTED=Node started on cluster Duniter4j ES [%s]
duniter4j.event.subject.ERROR=[%s] Error message
duniter4j.event.subject.INFO=[%s] Information message
duniter4j.event.subject.WARN=[%s] Warning message
duniter4j.executor.task.waitingExecution=
duniter4j.job.stopped=
duniter4j.job.stopping=
......
......@@ -4,7 +4,7 @@ duniter4j.blockIndexerService.detectFork.invalidBlockchain=[%s] [%s] Peer has an
duniter4j.blockIndexerService.detectFork.remoteBlockNotFound=[%s] [%s] Unable to get block \#%s from peer\: %s
duniter4j.blockIndexerService.detectFork.resync=[%s] [%s] Rollback index from block \#%s, and resync
duniter4j.blockIndexerService.indexBlock=[%s] [%s] Indexing block \#%s - hash [%s]
duniter4j.blockIndexerService.indexLastBlocks.invalidBlockchain=
duniter4j.blockIndexerService.indexLastBlocks.invalidBlockchain=[%s] [%s] Peer has another blockchain (no common blocks \!). Skipping last blocks indexation.
duniter4j.blockIndexerService.indexLastBlocks.otherPeers.task=Indexing missing blocks of [%s] from other peers
duniter4j.blockIndexerService.indexLastBlocks.progress=[%s] [%s] Indexing block \#%s / %s (%s%%)...
duniter4j.blockIndexerService.indexLastBlocks.remoteParametersError=[%s] Error when calling [/blockchain/parameters]\: %s
......@@ -34,6 +34,10 @@ duniter4j.config.option.tasks.queueCapacity.description=
duniter4j.config.option.temp.directory.description=
duniter4j.config.option.version.description=
duniter4j.config.parse.error=
duniter4j.event.NODE_STARTED=Noeud démarré sur le cluster Duniter4j ES [%s]
duniter4j.event.subject.ERROR=%s Message d'erreur
duniter4j.event.subject.INFO=%s Message d'information
duniter4j.event.subject.WARN=%s Message d'avertissement
duniter4j.executor.task.waitingExecution=
duniter4j.job.stopped=
duniter4j.job.stopping=
......@@ -42,4 +46,3 @@ duniter4j.removeServiceUtils.waitThenRetry=Remote request failed [%s]. Waiting t
duniter4j.task.issuer.system=Système
duniter4j.task.starting=Démarrage du traitement...
duniter4j.threadPool.clusterHealthStatus.changed=Cluster health status changed to [%s]. Executing pending job...
uniter4j.blockIndexerService.indexLastBlocks.invalidBlockchain=[%s] [%s] Peer has another blockchain (no common blocks \!). Skipping last blocks indexation.
......@@ -121,7 +121,7 @@ duniter.string.analyzer: french
#
# Enabling node blockchain synchronization
#
duniter.blockchain.sync.enable: true
duniter.blockchain.sync.enable: false
#
# Duniter node to synchronize
#
......@@ -130,6 +130,9 @@ duniter.port: 9330
#
# ---------------------------------- Duniter4j security -------------------------
#
duniter.keyring.salt: abc
duniter.keyring.password: def
# Enable security, to disable HTTP access to the default ES admin API
#
duniter.security.enable: false
......@@ -148,4 +151,25 @@ duniter.security.enable: false
#
duniter.data.sync.enable: false
#duniter.data.sync.host: data.duniter.fr
#duniter.data.sync.port: 80
\ No newline at end of file
#duniter.data.sync.port: 80
# ---------------------------------- Duniter4j SMTP server -------------------------
#
# SMTP server configuration (host and port)
#
#duniter.mail.smtp.host: localhost
#duniter.mail.smtp.port: 25
#
# Mail 'from' address
#
#duniter.mail.from: no-reply@domain.com
duniter.mail.from: root@EIS-DEV
#
# Mail: admin address
#
#duniter.mail.admin: user@domain.com
duniter.mail.admin: blavenie@EIS-DEV
#
# Mail subject prefix
#
#duniter.mail.subject.prefix: [Duniter4j ES]
......@@ -3,6 +3,7 @@ org.duniter.core.client.service.bma.NetworkRemoteServiceImpl
org.duniter.core.client.service.bma.WotRemoteServiceImpl
org.duniter.core.client.service.bma.TransactionRemoteServiceImpl
org.duniter.core.service.Ed25519CryptoServiceImpl
org.duniter.core.service.MailServiceImpl
org.duniter.core.client.service.HttpServiceImpl
org.duniter.core.client.service.DataContext
org.duniter.core.client.service.local.PeerServiceImpl
......
......@@ -314,6 +314,11 @@
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!-- NaCL lib -->
<dependency>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment