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

- Prepare first release

parent cd189ba5
Branches
Tags
No related merge requests found
Showing
with 6 additions and 2602 deletions
......@@ -417,22 +417,22 @@
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<version>2.3</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<version>2.10</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.4.1</version>
<version>2.5.1</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
</configuration>
......@@ -672,7 +672,8 @@
<excludes>
<exclude>**/site/**/*.*</exclude>
<exclude>**/misc/**/*.*</exclude>
<exclude>**/webapp/jquery/**/*.*</exclude>
<exclude>**/webapp/js/jquery-mobile/**/*.*</exclude>
<exclude>**/webapp/css/jquery-mobile/**/*.*</exclude>
<exclude>**/webapp/META-INF/**/*.*</exclude>
<exclude>**/webapp/WEB-INF/**/*.*</exclude>
<exclude>**/*.properties</exclude>
......@@ -748,8 +749,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-changelog-plugin</artifactId>
<!-- FIXME BL : waiting capturing group to be enable (see https://jira.codehaus.org/browse/MCHANGELOG-125) <configuration> <issueLinkUrl>https://forge.ifremer.fr/mantis/view.php?id=%ISSUE%</issueLinkUrl>
<issueIDRegexPattern>[#]([0-9]{4,})</issueIDRegexPattern> </configuration> -->
</plugin>
<plugin>
......
package io.ucoin.client.core.action;
/*
* #%L
* SIH-Adagio :: Core for Allegro
* $Id:$
* $HeadURL:$
* %%
* Copyright (C) 2012 - 2014 Ifremer
* %%
* 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 org.apache.commons.lang3.StringUtils;
import java.util.Scanner;
public class CommandLines {
protected CommandLines() {
}
public static String readNotBlankInput(String message) {
String value = readInput(message, null, true);
return value;
}
public static String readInput(String message, String defaultValue, boolean mandatory) {
Scanner scanIn = new Scanner(System.in);
String inputValue = null;
while (inputValue == null) {
System.out.print(message.trim());
if (StringUtils.isNotEmpty(defaultValue)) {
System.out.print(String.format(" [%s]", defaultValue));
}
System.out.print(": ");
inputValue = scanIn.nextLine();
if (StringUtils.isBlank(inputValue)) {
// A default exists: use it
if (StringUtils.isNotEmpty(defaultValue)) {
inputValue = defaultValue;
}
// No default value, but mandatory: prepare for a new iteration
else if (mandatory) {
inputValue = null;
}
}
}
// scanIn.close();
return inputValue;
}
}
package io.ucoin.client.core.action;
/*
* #%L
* SIH-Adagio :: Shared
* $Id:$
* $HeadURL:$
* %%
* Copyright (C) 2012 - 2014 Ifremer
* %%
* 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 io.ucoin.client.core.config.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CommunityAction {
/* Logger */
private static final Logger log = LoggerFactory.getLogger(CommunityAction.class);
public void members() {
Configuration config = Configuration.instance();
}
}
package io.ucoin.client.core.action;
/*
* #%L
* SIH-Adagio :: Shared
* $Id:$
* $HeadURL:$
* %%
* Copyright (C) 2012 - 2014 Ifremer
* %%
* 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%
*/
public class HelpAction {
public void show() {
StringBuilder sb = new StringBuilder();
sb.append("Usage: <commands> <options>\n")
.append("with <commands>:\n")
.append(" -h --help Display help\n")
.append(" --import-data Import raw data, from the Adagio central database\n")
.append("\n")
.append("with <options>:\n")
.append(" -h --host <user> Node host\n")
.append(" -p --port <pwd> Node port\n")
.append("\n")
.append(" -esh --es-host <user> ElasticSearch host\n")
.append(" -esp --es-port <pwd> ElasticSearch port\n");
System.out.println(sb.toString());
}
}
package io.ucoin.client.core.action;
/*
* #%L
* SIH-Adagio :: Shared
* $Id:$
* $HeadURL:$
* %%
* Copyright (C) 2012 - 2014 Ifremer
* %%
* 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 io.ucoin.client.core.config.Configuration;
import io.ucoin.client.core.model.BlockchainBlock;
import io.ucoin.client.core.model.BlockchainParameter;
import io.ucoin.client.core.service.BlockchainService;
import io.ucoin.client.core.service.ServiceLocator;
import io.ucoin.client.core.service.search.BlockIndexerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IndexerAction {
/* Logger */
private static final Logger log = LoggerFactory.getLogger(IndexerAction.class);
public void indexAllBlocks() {
BlockchainService blockchainService = ServiceLocator.instance().getBlockchainService();
BlockIndexerService indexerService = ServiceLocator.instance().getBlockIndexerService();
Configuration config = Configuration.instance();
try {
// Get the currency name from node
BlockchainParameter parameter = blockchainService.getParameters();
if (parameter == null) {
log.error(String.format("Could not connect to node [%s:%s]",
config.getNodeHost(), config.getNodePort()));
return;
}
String currencyName = parameter.getCurrency();
log.info(String.format("Starting to index blocks of [%s] from node [%s:%s]...",
parameter.getCurrency(), config.getNodeHost(), config.getNodePort()));
// Delete the index
indexerService.deleteIndex(currencyName);
// Then index all blocks
BlockchainBlock currentBlock = blockchainService.getCurrentBlock();
if (currentBlock != null) {
int blockCount = currentBlock.getNumber() + 1;
for (int blockNumber = 0; blockNumber < blockCount; blockNumber++) {
if (blockNumber != 0 && blockNumber % 100 == 0) {
log.info(String.format("Indexing block number [%s]...", blockNumber));
}
String blockAsJson = blockchainService.getBlockAsJson(blockNumber);
indexerService.indexBlockAsJson(currencyName, blockNumber, blockAsJson.getBytes());
}
log.info("All blocks processed");
}
} catch(Exception e) {
log.error("Error during indexation: " + e.getMessage(), e);
}
}
public void updateAllBlocks() {
BlockchainService blockchainService = ServiceLocator.instance().getBlockchainService();
BlockIndexerService indexerService = ServiceLocator.instance().getBlockIndexerService();
Configuration config = Configuration.instance();
try {
// Get the currency name from node
BlockchainParameter parameter = blockchainService.getParameters();
if (parameter == null) {
log.error(String.format("Could not connect to node [%s:%s]",
config.getNodeHost(), config.getNodePort()));
return;
}
String currencyName = parameter.getCurrency();
log.info(String.format("Starting to index blocks of [%s] from node [%s:%s]...",
parameter.getCurrency(), config.getNodeHost(), config.getNodePort()));
// Check if index exists
boolean indexExists = indexerService.existsIndex(currencyName);
if (!indexExists) {
log.error("No index [%s] currently exists on ES node.");
System.exit(-1);
}
// Then index all blocks
BlockchainBlock currentBlock = blockchainService.getCurrentBlock();
if (currentBlock != null) {
int blockCount = currentBlock.getNumber() + 1;
for (int blockNumber = 0; blockNumber < blockCount; blockNumber++) {
if (blockNumber != 0 && blockNumber % 100 == 0) {
log.info(String.format("Updating block number [%s]...", blockNumber));
log.info("TODO");
}
// TODO : check is has code as change...
//String blockAsJson = blockchainService.getBlockAsJson(blockNumber);
//indexerService.indexBlockAsJson(currencyName, blockNumber, blockAsJson.getBytes());
}
log.info("All blocks processed");
}
} catch(Exception e) {
log.error("Error during indexation: " + e.getMessage(), e);
}
}
public void indexLastBlocks() {
BlockchainService blockchainService = ServiceLocator.instance().getBlockchainService();
BlockIndexerService indexerService = ServiceLocator.instance().getBlockIndexerService();
Configuration config = Configuration.instance();
try {
// Get the currency name from node
BlockchainParameter parameter = blockchainService.getParameters();
if (parameter == null) {
log.error(String.format("Could not connect to node [%s:%s]",
config.getNodeHost(), config.getNodePort()));
return;
}
String currencyName = parameter.getCurrency();
log.info(String.format("Starting to index last blocks of [%s] from node [%s:%s]...",
currencyName, config.getNodeHost(), config.getNodePort()));
// Check if index exists
boolean indexExists = indexerService.existsIndex(currencyName);
if (!indexExists) {
log.error("No index [%s] currently exists on ES node.");
System.exit(-1);
}
// Then index all blocks
BlockchainBlock currentBlock = blockchainService.getCurrentBlock();
if (currentBlock != null) {
int blockCount = currentBlock.getNumber() + 1;
// Get the last indexed block number
int startNumber = 0;
BlockchainBlock lastIndexedBlock = indexerService.getCurrentBlock(currencyName);
if (lastIndexedBlock != null) {
startNumber = lastIndexedBlock.getNumber();
}
String currentBlockAsJson = null;
for (int blockNumber = startNumber; blockNumber < blockCount; blockNumber++) {
if (blockNumber != 0 && blockNumber % 100 == 0) {
log.info(String.format("Indexing block number [%s]...", blockNumber));
}
String blockAsJson = blockchainService.getBlockAsJson(blockNumber);
indexerService.indexBlockAsJson(currencyName, blockNumber, blockAsJson.getBytes());
if (blockNumber == blockCount - 1) {
// update the current block
indexerService.indexCurrentBlockAsJson(currencyName, blockAsJson.getBytes());
}
}
log.info("All blocks processed");
}
} catch(Exception e) {
log.error("Error during indexation: " + e.getMessage(), e);
}
}
}
package io.ucoin.client.core.config;
/*
* #%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.google.common.base.Charsets;
import io.ucoin.client.core.technical.UCoinTechnicalException;
import org.nuiton.config.ApplicationConfig;
import org.nuiton.config.ApplicationConfigHelper;
import org.nuiton.config.ApplicationConfigProvider;
import org.nuiton.config.ArgumentsParserException;
import org.nuiton.util.version.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.URL;
import java.util.Locale;
import java.util.Set;
import static org.nuiton.i18n.I18n.t;
/**
* Access to configuration options
* @author Benoit Lavenier <benoit.lavenier@e-is.pro>
* @since 1.0
*/
public class Configuration {
/** Logger. */
private static final Logger log = LoggerFactory.getLogger(Configuration.class);
/**
* Delegate application config.
*/
protected final ApplicationConfig applicationConfig;
private static Configuration instance;
public static Configuration instance() {
return instance;
}
public static void setInstance(Configuration instance) {
Configuration.instance = instance;
}
protected final String[] optionKeyToNotSave;
protected File configFile;
public Configuration(ApplicationConfig applicationConfig) {
super();
this.applicationConfig = applicationConfig;
this.optionKeyToNotSave = null;
// Override application version
initVersion(applicationConfig);
}
public Configuration(String file, String... args) {
super();
this.applicationConfig = new ApplicationConfig();
this.applicationConfig.setEncoding(Charsets.UTF_8.name());
this.applicationConfig.setConfigFileName(file);
// get all config providers
Set<ApplicationConfigProvider> providers =
ApplicationConfigHelper.getProviders(null,
null,
null,
true);
// load all default options
ApplicationConfigHelper.loadAllDefaultOption(applicationConfig,
providers);
// Load actions
for (ApplicationConfigProvider provider : providers) {
applicationConfig.loadActions(provider.getActions());
}
// Define Alias
addAlias(applicationConfig);
// Override application version
initVersion(applicationConfig);
// get all transient and final option keys
Set<String> optionToSkip =
ApplicationConfigHelper.getTransientOptionKeys(providers);
if (log.isDebugEnabled()) {
log.debug("Option that won't be saved: " + optionToSkip);
}
optionKeyToNotSave = optionToSkip.toArray(new String[optionToSkip.size()]);
try {
applicationConfig.parse(args);
} catch (ArgumentsParserException e) {
throw new UCoinTechnicalException(t("ucoinj.config.parse.error"), e);
}
// TODO Review this, this is very dirty to do this...
File appBasedir = applicationConfig.getOptionAsFile(
ConfigurationOption.BASEDIR.getKey());
if (appBasedir == null) {
appBasedir = new File("");
}
if (!appBasedir.isAbsolute()) {
appBasedir = new File(appBasedir.getAbsolutePath());
}
if (appBasedir.getName().equals("..")) {
appBasedir = appBasedir.getParentFile().getParentFile();
}
if (appBasedir.getName().equals(".")) {
appBasedir = appBasedir.getParentFile();
}
if (log.isInfoEnabled()) {
log.info("Application basedir: " + appBasedir);
}
applicationConfig.setOption(
ConfigurationOption.BASEDIR.getKey(),
appBasedir.getAbsolutePath());
}
/**
* Override the version default option, from the MANIFEST implementation version (if any)
* @param applicationConfig
*/
protected void initVersion(ApplicationConfig applicationConfig) {
// Override application version
String implementationVersion = this.getClass().getPackage().getSpecificationVersion();
if (implementationVersion != null) {
applicationConfig.setDefaultOption(
ConfigurationOption.VERSION.getKey(),
implementationVersion);
}
}
/**
* Add alias to the given ApplicationConfig. <p/>
* This method could be override to add specific alias
*
* @param applicationConfig
*/
protected void addAlias(ApplicationConfig applicationConfig) {
applicationConfig.addAlias("-h", "--option", ConfigurationOption.NODE_HOST.getKey());
applicationConfig.addAlias("--host", "--option", ConfigurationOption.NODE_HOST.getKey());
applicationConfig.addAlias("-p", "--option", ConfigurationOption.NODE_PORT.getKey());
applicationConfig.addAlias("--port", "--option", ConfigurationOption.NODE_PORT.getKey());
applicationConfig.addAlias("-c", "--option", ConfigurationOption.NODE_CURRENCY.getKey());
applicationConfig.addAlias("--salt", "--option", ConfigurationOption.USER_SALT.getKey());
applicationConfig.addAlias("--passwd", "--option", ConfigurationOption.USER_PASSWD.getKey());
applicationConfig.addAlias("-esh", "--option", ConfigurationOption.NODE_ELASTICSEARCH_HOST.getKey());
applicationConfig.addAlias("--es-host", "--option", ConfigurationOption.NODE_ELASTICSEARCH_HOST.getKey());
applicationConfig.addAlias("-esp", "--option", ConfigurationOption.NODE_ELASTICSEARCH_PORT.getKey());
applicationConfig.addAlias("--es-port", "--option", ConfigurationOption.NODE_ELASTICSEARCH_PORT.getKey());
}
public File getConfigFile() {
if (configFile == null) {
File dir = getBasedir();
if (dir == null || !dir.exists()) {
dir = new File(applicationConfig.getUserConfigDirectory());
}
configFile = new File(dir, applicationConfig.getConfigFileName());
}
return configFile;
}
/** @return {@link ConfigurationOption#BASEDIR} value */
public File getBasedir() {
File result = applicationConfig.getOptionAsFile(ConfigurationOption.BASEDIR.getKey());
return result;
}
/** @return {@link ConfigurationOption#DATA_DIRECTORY} value */
public File getDataDirectory() {
File result = applicationConfig.getOptionAsFile(ConfigurationOption.DATA_DIRECTORY.getKey());
return result;
}
public ApplicationConfig getApplicationConfig() {
return applicationConfig;
}
public File getTempDirectory() {
return applicationConfig.getOptionAsFile(ConfigurationOption.TMP_DIRECTORY.getKey());
}
public File getCacheDirectory() {
return applicationConfig.getOptionAsFile(ConfigurationOption.CACHE_DIRECTORY.getKey());
}
public Version getVersion() {
return applicationConfig.getOptionAsVersion(ConfigurationOption.VERSION.getKey());
}
public File getI18nDirectory() {
return applicationConfig.getOptionAsFile(
ConfigurationOption.I18N_DIRECTORY.getKey());
}
public Locale getI18nLocale() {
return applicationConfig.getOptionAsLocale(
ConfigurationOption.I18N_LOCALE.getKey());
}
public void setI18nLocale(Locale locale) {
applicationConfig.setOption(ConfigurationOption.I18N_LOCALE.getKey(), locale.toString());
}
public String getNodeCurrency() {
return applicationConfig.getOption(ConfigurationOption.NODE_CURRENCY.getKey());
}
public String getNodeProtocol() {
return applicationConfig.getOption(ConfigurationOption.NODE_PROTOCOL.getKey());
}
public String getNodeHost() {
return applicationConfig.getOption(ConfigurationOption.NODE_HOST.getKey());
}
public int getNodePort() {
return applicationConfig.getOptionAsInt(ConfigurationOption.NODE_PORT.getKey());
}
public URL getNodeUrl() {
return applicationConfig.getOptionAsURL(ConfigurationOption.NODE_URL.getKey());
}
public int getNodeTimeout() {
return applicationConfig.getOptionAsInt(ConfigurationOption.NODE_TIMEOUT.getKey());
}
public String getNodeElasticSearchHost() {
return applicationConfig.getOption(ConfigurationOption.NODE_ELASTICSEARCH_HOST.getKey());
}
public int getNodeElasticSearchPort() {
return applicationConfig.getOptionAsInt(ConfigurationOption.NODE_ELASTICSEARCH_PORT.getKey());
}
public URL getNodeElasticSearchRestUrl() {
return applicationConfig.getOptionAsURL(ConfigurationOption.NODE_ELASTICSEARCH_REST_URL.getKey());
}
public boolean isNodeElasticSearchLocal() {
return applicationConfig.getOptionAsBoolean(ConfigurationOption.NODE_ELASTICSEARCH_LOCAL.getKey());
}
public String getNodeElasticSearchLocalClusterName() {
return applicationConfig.getOption(ConfigurationOption.NODE_ELASTICSEARCH_LOCAL_CLUSTER_NAME.getKey());
}
}
package io.ucoin.client.core.config;
/*
* #%L
* SIH-Adagio :: Shared
* $Id:$
* $HeadURL:$
* %%
* Copyright (C) 2012 - 2014 Ifremer
* %%
* 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 io.ucoin.client.core.action.CommunityAction;
import io.ucoin.client.core.action.HelpAction;
import io.ucoin.client.core.action.IndexerAction;
import org.nuiton.config.ConfigActionDef;
public enum ConfigurationAction implements ConfigActionDef {
HELP(HelpAction.class.getName() + "#show", "--help"),
COMMUNITY_MEMBERS(CommunityAction.class.getName() + "#members", "--members"),
INDEX_ALL_BLOCK(IndexerAction.class.getName() + "#indexAllBlocks", "--index-blocks"),
INDEX_LAST_BLOCK(IndexerAction.class.getName() + "#indexLastBlocks", "--update-last-blocks");
public String action;
public String[] aliases;
private ConfigurationAction(String action, String... aliases) {
this.action = action;
this.aliases = aliases;
}
@Override
public String getAction() {
return action;
}
@Override
public String[] getAliases() {
return aliases;
}
}
package io.ucoin.client.core.config;
/*
* #%L
* Tutti :: Persistence
* $Id: TuttiConfigurationOption.java 1441 2013-12-09 20:13:47Z tchemit $
* $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java $
* %%
* Copyright (C) 2012 - 2013 Ifremer
* %%
* 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 org.nuiton.config.ConfigOptionDef;
import org.nuiton.util.Version;
import java.io.File;
import java.net.URL;
import java.util.Locale;
import static org.nuiton.i18n.I18n.n;
/**
* All application configuration options.
*
* @author Benoit Lavenier <benoit.lavenier@e-is.pro>
* @since 1.0
*/
public enum ConfigurationOption implements ConfigOptionDef {
// ------------------------------------------------------------------------//
// -- READ-ONLY OPTIONS ---------------------------------------------------//
// ------------------------------------------------------------------------//
BASEDIR(
"ucoinj.basedir",
n("ucoinj.config.option.basedir.description"),
"${user.home}/.ucoinj",
File.class),
DATA_DIRECTORY(
"ucoinj.data.directory",
n("ucoinj.config.option.data.directory.description"),
"${ucoinj.basedir}/data",
File.class),
I18N_DIRECTORY(
"ucoinj.i18n.directory",
n("ucoinj.config.option.i18n.directory.description"),
"${ucoinj.basedir}/i18n",
File.class),
TMP_DIRECTORY(
"ucoinj.tmp.directory",
n("ucoinj.config.option.tmp.directory.description"),
"${ucoinj.data.directory}/temp",
File.class),
CACHE_DIRECTORY(
"ucoinj.cache.directory",
n("ucoinj.config.option.cache.directory.description"),
"${ucoinj.data.directory}/cache",
File.class),
VERSION(
"ucoinj.version",
n("ucoinj.config.option.version.description"),
"1.0",
Version.class),
SITE_URL(
"ucoinj.site.url",
n("ucoinj.config.option.site.url.description"),
"http://ucoin.io/ucoinj",
URL.class),
ORGANIZATION_NAME(
"ucoinj.organizationName",
n("ucoinj.config.option.organizationName.description"),
"e-is.pro",
String.class),
INCEPTION_YEAR(
"ucoinj.inceptionYear",
n("ucoinj.config.option.inceptionYear.description"),
"2011",
Integer.class),
USER_SALT(
"ucoinj.salt",
n("ucoinj.config.option.salt.description"),
"",
String.class),
USER_PASSWD(
"ucoinj.passwd",
n("ucoinj.config.option.passwd.description"),
"",
String.class),
// ------------------------------------------------------------------------//
// -- DATA CONSTANTS --------------------------------------------------//
// ------------------------------------------------------------------------//
// ------------------------------------------------------------------------//
// -- READ-WRITE OPTIONS --------------------------------------------------//
// ------------------------------------------------------------------------//
I18N_LOCALE(
"ucoinj.i18n.locale",
n("ucoinj.config.option.i18n.locale.description"),
Locale.FRANCE.getCountry(),
Locale.class,
false),
NODE_CURRENCY(
"ucoinj.node.currency",
n("ucoinj.config.option.node.currency.description"),
"meta_brouzouf",
String.class,
false),
NODE_PROTOCOL(
"ucoinj.node.protocol",
n("ucoinj.config.option.node.protocol.description"),
"http",
String.class,
false),
NODE_HOST(
"ucoinj.node.host",
n("ucoinj.config.option.node.host.description"),
"metab.ucoin.io",
String.class,
false),
NODE_PORT(
"ucoinj.node.port",
n("ucoinj.config.option.node.port.description"),
"9201",
Integer.class,
false),
NODE_URL(
"ucoinj.node.url",
n("ucoinj.config.option.node.port.description"),
"${ucoinj.node.protocol}://${ucoinj.node.host}:${ucoinj.node.port}",
URL.class,
false),
NODE_TIMEOUT(
"ucoinj.node.timeout",
n("ucoinj.config.option.node.timeout.description"),
"1500",
Integer.class,
false),
NODE_ELASTICSEARCH_PROTOCOL(
"ucoinj.node.elasticsearch.protocol",
n("ucoinj.config.option.node.elasticsearch.protocol.description"),
"http",
String.class,
false),
NODE_ELASTICSEARCH_HOST(
"ucoinj.node.elasticsearch.host",
n("ucoinj.config.option.node.elasticsearch.host.description"),
"localhost",
String.class,
false),
NODE_ELASTICSEARCH_PORT(
"ucoinj.node.elasticsearch.port",
n("ucoinj.config.option.node.elasticsearch.port.description"),
"9300",
Integer.class,
false),
NODE_ELASTICSEARCH_REST_PROTOCOL(
"ucoinj.node.elasticsearch.rest.protocol",
n("ucoinj.config.option.node.elasticsearch.rest.protocol.description"),
"http",
String.class,
false),
NODE_ELASTICSEARCH_REST_HOST(
"ucoinj.node.elasticsearch.rest.host",
n("ucoinj.config.option.node.elasticsearch.rest.host.description"),
"localhost",
String.class,
false),
NODE_ELASTICSEARCH_REST_PORT(
"ucoinj.node.elasticsearch.rest.port",
n("ucoinj.config.option.node.elasticsearch.rest.port.description"),
"9200",
Integer.class,
false),
NODE_ELASTICSEARCH_REST_URL(
"ucoinj.node.elasticsearch.rest.url",
n("ucoinj.config.option.node.elasticsearch.rest.url.description"),
"${ucoinj.node.elasticsearch.rest.protocol}://${ucoinj.node.elasticsearch.rest.host}:${ucoinj.node.elasticsearch.rest.port}",
URL.class,
false),
NODE_ELASTICSEARCH_LOCAL(
"ucoinj.node.elasticsearch.local",
n("ucoinj.config.option.node.elasticsearch.local.description"),
"false",
Boolean.class,
false),
NODE_ELASTICSEARCH_LOCAL_CLUSTER_NAME(
"ucoinj.node.elasticsearch.local.clusterName",
n("ucoinj.config.option.node.elasticsearch.local.clusterName.description"),
"data.ucoin.fr",
String.class,
false)
;
/** Configuration key. */
private final String key;
/** I18n key of option description */
private final String description;
/** Type of option */
private final Class<?> type;
/** Default value of option. */
private String defaultValue;
/** Flag to not keep option value on disk */
private boolean isTransient;
/** Flag to not allow option value modification */
private boolean isFinal;
ConfigurationOption(String key,
String description,
String defaultValue,
Class<?> type,
boolean isTransient) {
this.key = key;
this.description = description;
this.defaultValue = defaultValue;
this.type = type;
this.isTransient = isTransient;
this.isFinal = isTransient;
}
ConfigurationOption(String key,
String description,
String defaultValue,
Class<?> type) {
this(key, description, defaultValue, type, true);
}
@Override
public String getKey() {
return key;
}
@Override
public Class<?> getType() {
return type;
}
@Override
public String getDescription() {
return description;
}
@Override
public String getDefaultValue() {
return defaultValue;
}
@Override
public boolean isTransient() {
return isTransient;
}
@Override
public boolean isFinal() {
return isFinal;
}
@Override
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public void setTransient(boolean newValue) {
// not used
}
@Override
public void setFinal(boolean newValue) {
// not used
}
}
package io.ucoin.client.core.config;
/*
* #%L
* Tutti :: Persistence
* $Id: TuttiConfigurationProvider.java 1418 2013-12-01 21:18:22Z tchemit $
* $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationProvider.java $
* %%
* Copyright (C) 2012 - 2013 Ifremer
* %%
* 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 org.nuiton.config.ApplicationConfigProvider;
import org.nuiton.config.ConfigActionDef;
import org.nuiton.config.ConfigOptionDef;
import java.util.Locale;
import static org.nuiton.i18n.I18n.l;
/**
* Config provider (for site generation).
*
* @author Benoit Lavenier <benoit.lavenier@e-is.pro>
*/
public class ConfigurationProvider implements ApplicationConfigProvider {
@Override
public String getName() {
return "ucoinj";
}
@Override
public String getDescription(Locale locale) {
return l(locale, "ucoinj.config");
}
@Override
public ConfigOptionDef[] getOptions() {
return ConfigurationOption.values();
}
@Override
public ConfigActionDef[] getActions() {
return ConfigurationAction.values();
}
}
package io.ucoin.client.core.model;
/*
* #%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 java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Created by eis on 05/02/15.
*/
public class Currency implements Serializable {
private List<Peer> peers = new ArrayList<Peer>();
private Long id;
private String currencyName;
private Integer membersCount;
private String firstBlockSignature;
private Account account;
private Long accountId;
private String[] tags;
private String senderPubkey;
public Currency() {
}
public Currency(String currencyName,
String firstBlockSignature,
int membersCount,
List<Peer> peers) {
this.currencyName = currencyName;
this.firstBlockSignature = firstBlockSignature;
this.membersCount = membersCount;
this.peers = peers;
}
public Currency(String currencyName,
String firstBlockSignature,
List<Peer> peers) {
this.currencyName = currencyName;
this.firstBlockSignature = firstBlockSignature;
this.membersCount = null;
this.peers = peers;
}
public Long getId() {
return id;
}
public String getCurrencyName()
{
return currencyName;
}
public Integer getMembersCount() {
return membersCount;
}
public String getFirstBlockSignature() {
return firstBlockSignature;
}
public List<Peer> getPeers() {
return peers;
}
public void addPeer(Peer peer) {
this.peers.add(peer);
}
public void setPeers(List<Peer> peers) {
this.peers = peers;
}
public void setId(Long id) {
this.id = id;
}
public void setCurrencyName(String currencyName) {
this.currencyName = currencyName;
}
public void setMembersCount(Integer membersCount) {
this.membersCount = membersCount;
}
public void setFirstBlockSignature(String firstBlockSignature) {
this.firstBlockSignature = firstBlockSignature;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public String toString() {
return currencyName;
}
public String[] getTags() {
return tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
public String getSenderPubkey() {
return senderPubkey;
}
public void setSenderPubkey(String senderPubkey) {
this.senderPubkey = senderPubkey;
}
}
\ No newline at end of file
package io.ucoin.client.core.model;
/*
* #%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 java.io.Serializable;
public class Peer implements Serializable {
private Long id;
private Long currencyId;
private String host;
private int port;
private String url;
public Peer() {
// default constructor, need for de-serialization
}
public Peer(String host, int port) {
this.host = host;
this.port = port;
this.url = initUrl(host, port);
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public String getUrl() {
return url;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getCurrencyId() {
return currencyId;
}
public void setCurrencyId(Long currencyId) {
this.currencyId = currencyId;
}
public void setPort(int port) {
this.port = port;
this.url = initUrl(host, port);
}
public void setHost(String host) {
this.host = host;
this.url = initUrl(host, port);
}
public String toString() {
return new StringBuilder().append("url=").append(url).append(",")
.append("host=").append(host).append(",")
.append("port=").append(port)
.toString();
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (id != null && o instanceof Peer) {
return id.equals(((Peer)o).getId());
}
return super.equals(o);
}
/* -- Internal methods -- */
protected String initUrl(String host, int port) {
return String.format("http://%s:%s", host, port);
}
}
package io.ucoin.client.core.model;
/*
* #%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 java.io.Serializable;
public class TxSource implements Serializable, Cloneable {
private static final long serialVersionUID = 8084087351543574142L;
private String type;
private int number;
private String fingerprint;
private long amount;
@Override
public Object clone() throws CloneNotSupportedException {
TxSource clone = (TxSource)super.clone();
clone.type = type;
clone.number = number;
clone.fingerprint = fingerprint;
clone.amount = amount;
return clone;
}
/**
* Source type : <ul>
* <li><code>D</code> : Universal Dividend</li>
* <li><code>T</code> : Transaction</li>
* </ul>
* @return
*/
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
* The block number where the source has been written
* @return
*/
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getFingerprint() {
return fingerprint;
}
public void setFingerprint(String fingerprint) {
this.fingerprint = fingerprint;
}
public long getAmount() {
return amount;
}
public void setAmount(long amount) {
this.amount = amount;
}
}
package io.ucoin.client.core.model;
/*
* #%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 io.ucoin.client.core.technical.crypto.CryptoUtils;
import io.ucoin.client.core.technical.crypto.KeyPair;
/**
* A wallet is a user account
* Created by eis on 13/01/15.
*/
public class Wallet extends KeyPair {
private Identity identity;
private String salt;
private String currency;
public Wallet() {
super(null, null);
this.identity = new Identity();
}
public Wallet(String currency, String uid, byte[] pubKey, byte[] secKey) {
super(pubKey, secKey);
this.currency = currency;
this.identity = new Identity();
this.identity.setPubkey(pubKey == null ? null : CryptoUtils.encodeBase58(pubKey));
this.identity.setUid(uid);
}
public Wallet(String currency, byte[] secKey, Identity identity) {
super(CryptoUtils.decodeBase58(identity.getPubkey()), secKey);
this.currency = currency;
this.identity = identity;
}
public Identity getIdentity() {
return identity;
}
public void setIdentity(Identity identity) {
this.identity = identity;
}
public String getPubKeyHash() {
return identity.getPubkey();
}
public String getSalt(){
return salt;
}
public void setSalt(String salt){
this.salt = salt;
}
public boolean isAuthenticate() {
return secretKey != null && identity != null && identity.getPubkey() != null;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
}
package io.ucoin.client.core.service;
/*
* #%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.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import io.ucoin.client.core.config.Configuration;
import io.ucoin.client.core.technical.UCoinTechnicalException;
import io.ucoin.client.core.technical.gson.GsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.ConnectException;
import java.net.URI;
import java.net.URISyntaxException;
public class AbstractNetworkService extends BaseService implements Closeable {
private static final Logger log = LoggerFactory.getLogger(AbstractNetworkService.class);
protected URI baseUri;
protected Integer baseTimeOut;
protected final Gson gson;
protected final CloseableHttpClient httpClient;
public AbstractNetworkService() {
super();
Configuration config = Configuration.instance();
this.gson = GsonUtils.newBuilder().create();
this.baseTimeOut = config.getNodeTimeout();
this.httpClient = initHttpClient(config);
this.baseUri = initNodeURI(config);
}
@Override
public void close() throws IOException {
httpClient.close();
}
/* -- Internal methods -- */
protected CloseableHttpClient initHttpClient(Configuration config) {
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(getRequestConfig())
// .setDefaultCredentialsProvider(getCredentialsProvider())
.build();
return httpClient;
}
protected URI initNodeURI(Configuration config) {
try {
URI nodeURI = config.getNodeUrl().toURI();
return nodeURI;
} catch (URISyntaxException ex) {
throw new UCoinTechnicalException(ex);
}
}
protected URIBuilder getURIBuilder(String... path) {
String pathToAppend = Joiner.on('/').skipNulls().join(path);
int customQueryStartIndex = pathToAppend.indexOf('?');
String customQuery = null;
if (customQueryStartIndex != -1) {
customQuery = pathToAppend.substring(customQueryStartIndex+1);
pathToAppend = pathToAppend.substring(0, customQueryStartIndex);
}
URIBuilder builder = new URIBuilder(baseUri);
builder.setPath(baseUri.getPath() + pathToAppend);
if (StringUtils.isNotBlank(customQuery)) {
builder.setCustomQuery(customQuery);
}
return builder;
}
protected URI getAppendedPath(String... path) {
try {
return getURIBuilder(path).build();
}
catch(URISyntaxException e) {
throw new UCoinTechnicalException(e);
}
}
protected RequestConfig getRequestConfig() {
// build request config for timeout
return RequestConfig.custom().setSocketTimeout(baseTimeOut).setConnectTimeout(baseTimeOut).build();
}
@SuppressWarnings("unchecked")
protected <T> T executeRequest(HttpUriRequest request, Class<? extends T> resultClass) {
Preconditions.checkNotNull(httpClient);
T result = null;
if (log.isDebugEnabled()) {
log.debug("Executing request : " + request.getRequestLine());
}
try {
try (CloseableHttpResponse response = httpClient.execute(request)) {
if (log.isDebugEnabled()) {
log.debug("Received response : " + response.getStatusLine());
}
switch (response.getStatusLine().getStatusCode()) {
case HttpStatus.SC_OK: {
result = (T) parseResponse(response, resultClass);
EntityUtils.consume(response.getEntity());
break;
}
case HttpStatus.SC_UNAUTHORIZED:
case HttpStatus.SC_FORBIDDEN:
throw new UCoinTechnicalException("ucoin.client.authentication");
default:
throw new UCoinTechnicalException("ucoin.client.status" + response.getStatusLine().toString());
}
}
} catch (ConnectException e) {
throw new UCoinTechnicalException("ucoin.client.core.connect", e);
}
catch (IOException e) {
throw new UCoinTechnicalException(e.getMessage(), e);
}
return result;
}
protected Object parseResponse(CloseableHttpResponse response, Class<?> ResultClass) throws IOException {
Object result;
boolean stringOutput = ResultClass.equals(String.class);
// If trace enable, log the response before parsing
if (log.isTraceEnabled() || stringOutput) {
try (InputStream content = response.getEntity().getContent()) {
String stringContent = getContentAsString(content);
if (log.isTraceEnabled()) {
log.trace("Parsing response:\n" + stringContent);
}
if (stringOutput) {
return stringContent;
}
result = gson.fromJson(stringContent, ResultClass);
}
}
// trace not enable
else {
try (InputStream content = response.getEntity().getContent()) {
Reader reader = new InputStreamReader(content, Charsets.UTF_8);
result = gson.fromJson(reader, ResultClass);
}
}
if (result == null) {
throw new UCoinTechnicalException("ucoin.client.core.emptyResponse");
}
if (log.isDebugEnabled()) {
log.debug("response: " + ToStringBuilder.reflectionToString(result, ToStringStyle.SHORT_PREFIX_STYLE));
}
return result;
}
protected String getContentAsString(InputStream content) throws IOException {
Reader reader = new InputStreamReader(content, Charsets.UTF_8);
StringBuilder result = new StringBuilder();
char[] buf = new char[64];
int len = 0;
while((len = reader.read(buf)) != -1) {
result.append(buf, 0, len);
}
return result.toString();
}
protected Gson getGson() {
return gson;
}
}
package io.ucoin.client.core.service;
/*
* #%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 io.ucoin.client.core.model.BlockchainBlock;
import io.ucoin.client.core.model.BlockchainParameter;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class BlockchainService extends AbstractNetworkService {
private static final Logger log = LoggerFactory.getLogger(BlockchainService.class);
public BlockchainService() {
super();
}
/**
* get the blockchain parameters (currency parameters)
* @return
* @throws Exception
*/
public BlockchainParameter getParameters() throws Exception {
// get blockchain parameter
HttpGet httpGet = new HttpGet(getAppendedPath(ProtocolUrls.BLOCKCHAIN_PARAMETERS));
BlockchainParameter result = executeRequest(httpGet, BlockchainParameter.class);
return result;
}
/**
* Retrieve a block, by id (from 0 to current)
* @param number
* @return
* @throws Exception
*/
public BlockchainBlock getBlock(int number) throws Exception {
// get blockchain parameter
String path = String.format(ProtocolUrls.BLOCKCHAIN_BLOCK, number);
HttpGet httpGet = new HttpGet(getAppendedPath(path));
BlockchainBlock result = executeRequest(httpGet, BlockchainBlock.class);
return result;
}
/**
* Retrieve a block, by id (from 0 to current)
* @param number
* @return
* @throws Exception
*/
public String getBlockAsJson(int number) throws Exception {
// get blockchain parameter
String path = String.format(ProtocolUrls.BLOCKCHAIN_BLOCK, number);
HttpGet httpGet = new HttpGet(getAppendedPath(path));
return executeRequest(httpGet, String.class);
}
/**
* Retrieve a block, by id (from 0 to current)
* @param number
* @return
* @throws Exception
*/
public List<BlockchainBlock> getBlocks(int count, int fromNumber) throws Exception {
// get blockchain parameter
String path = String.format(ProtocolUrls.BLOCKCHAIN_BLOCKS, count, fromNumber);
HttpGet httpGet = new HttpGet(getAppendedPath(path));
List<BlockchainBlock> result = null;
// FIXME : how to do this ?
// result = executeRequest(httpGet, List<BlockchainBlock>.class);
return result;
}
/**
* Retrieve the current block
* @param number
* @return
* @throws Exception
*/
public BlockchainBlock getCurrentBlock() throws Exception {
// get blockchain parameter
HttpGet httpGet = new HttpGet(getAppendedPath(ProtocolUrls.BLOCKCHAIN_BLOCK_CURRENT));
BlockchainBlock result = executeRequest(httpGet, BlockchainBlock.class);
return result;
}
/**
* Request to integrate the wot
* @throws Exception
*/
public void requestMembership() throws Exception {
HttpPost httpPost = new HttpPost(getAppendedPath(ProtocolUrls.BLOCKCHAIN_MEMBERSHIP));
// StringEntity entity = new StringEntity(gson.toJson(form), ContentType.APPLICATION_JSON);
// httpPost.setEntity(entity);
executeRequest(httpPost, null);
}
/* -- Internal methods -- */
}
package io.ucoin.client.core.service;
/*
* #%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%
*/
public interface ProtocolUrls {
/* Block chain */
public static final String BLOCKCHAIN_BASE = "/blockchain";
public static final String BLOCKCHAIN_PARAMETERS = BLOCKCHAIN_BASE + "/parameters";
public static final String BLOCKCHAIN_BLOCK = BLOCKCHAIN_BASE + "/block/%s";
public static final String BLOCKCHAIN_BLOCKS = BLOCKCHAIN_BASE + "/blocks/%s/%s";
public static final String BLOCKCHAIN_BLOCK_CURRENT = BLOCKCHAIN_BASE + "/current";
public static final String BLOCKCHAIN_MEMBERSHIP = BLOCKCHAIN_BASE + "/membership";
/* Web Of Trust */
public static final String WOT_BASE = "/wot";
public static final String WOT_ADD = WOT_BASE + "/add";
public static final String WOT_LOOKUP = WOT_BASE + "/lookup/%s";
public static final String WOT_CERTIFIED_BY = WOT_BASE + "/certified-by/%s";
public static final String WOT_CERTIFIERS_OF = WOT_BASE + "/certifiers-of/%s";
/* Transaction */
public static final String TX_BASE = "/tx";
public static final String TX_PROCESS = TX_BASE + "/process";
public static final String TX_SOURCES = TX_BASE + "/sources/%s";
}
package io.ucoin.client.core.service;
/*
* #%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 io.ucoin.client.core.service.search.BlockIndexerService;
import io.ucoin.client.core.service.search.CurrencyIndexerService;
import io.ucoin.client.core.service.search.ElasticSearchService;
import io.ucoin.client.core.service.search.client.CurrencyIndexerRestClientService;
import io.ucoin.client.core.technical.UCoinTechnicalException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ServiceLocator implements Closeable {
/* Logger */
private static final Logger log = LoggerFactory.getLogger(ServiceLocator.class);
/**
* The shared instance of this ServiceLocator.
*/
private static ServiceLocator instance = new ServiceLocator();
private final Map<Class<?>, Object> serviceCache;
protected ServiceLocator() {
// shouldn't be instantiated
serviceCache = new HashMap<Class<?>, Object>();
}
public void init() {
}
@Override
public void close() throws IOException {
for(Object service: serviceCache.values()) {
if (service instanceof Closeable) {
((Closeable)service).close();
}
}
}
/**
* replace the default shared instance of this Class
*
* @param newInstance the new shared service locator instance.
*/
public static void setInstance(ServiceLocator newInstance) {
instance = newInstance;
}
/**
* Gets the shared instance of this Class
*
* @return the shared service locator instance.
*/
public static ServiceLocator instance() {
return instance;
}
public BlockchainService getBlockchainService() {
return getService(BlockchainService.class);
}
public TransactionService getTransactionService() {
return getService(TransactionService.class);
}
public CryptoService getCryptoService() {
return getService(CryptoService.class);
}
/* -- ElasticSearch Service-- */
public CurrencyIndexerService getCurrencyIndexerService() {
return getService(CurrencyIndexerService.class);
}
public ElasticSearchService getElasticSearchService() {
return getService(ElasticSearchService.class);
}
public BlockIndexerService getBlockIndexerService() {
return getService(BlockIndexerService.class);
}
public CurrencyIndexerRestClientService getCurrencyIndexerRestClientService() {
return getService(CurrencyIndexerRestClientService.class);
}
/* -- Internal methods -- */
protected <S extends BaseService> S getService(Class<S> clazz) {
if (serviceCache.containsKey(clazz)) {
return (S)serviceCache.get(clazz);
}
try {
S service = (S)clazz.newInstance();
serviceCache.put(clazz, service);
// Call initialization
service.initialize();
return service;
}
catch (Exception e) {
throw new UCoinTechnicalException("Could not load service: " + clazz.getName(), e);
}
}
}
package io.ucoin.client.core.service;
/*
* #%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 io.ucoin.client.core.model.TxOutput;
import io.ucoin.client.core.model.TxSource;
import io.ucoin.client.core.model.TxSourceResults;
import io.ucoin.client.core.model.Wallet;
import io.ucoin.client.core.technical.UCoinTechnicalException;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class TransactionService extends AbstractNetworkService {
private static final Logger log = LoggerFactory.getLogger(TransactionService.class);
public CryptoService cryptoService;
public TransactionService() {
super();
}
@Override
public void initialize() {
cryptoService = ServiceLocator.instance().getCryptoService();
}
public void transfert(Wallet wallet, String destPubKey, long amount,
String comments) throws Exception {
// http post /tx/process
HttpPost httpPost = new HttpPost(
getAppendedPath(ProtocolUrls.TX_PROCESS));
// compute transaction
String transaction = getSignedTransaction(wallet, destPubKey, amount,
comments);
if (log.isDebugEnabled()) {
log.debug(String.format(
"Will send transaction document: \n------\n%s------",
transaction));
}
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("transaction", transaction));
httpPost.setEntity(new UrlEncodedFormEntity(urlParameters));
String selfResult = executeRequest(httpPost, String.class);
log.info("received from /tx/process: " + selfResult);
}
public TxSourceResults getSources(String pubKey) {
if (log.isDebugEnabled()) {
log.debug(String.format("Get sources by pubKey: %s", pubKey));
}
// get parameter
String path = String.format(ProtocolUrls.TX_SOURCES, pubKey);
HttpGet httpGet = new HttpGet(getAppendedPath(path));
TxSourceResults result = executeRequest(httpGet, TxSourceResults.class);
// Compute the balance
result.setBalance(computeBalance(result.getSources()));
return result;
}
/* -- internal methods -- */
public String getSignedTransaction(Wallet wallet, String destPubKey,
long amount, String comments) {
String transaction = getTransaction(wallet, destPubKey, amount,
comments);
String signature = cryptoService.sign(transaction, wallet.getSecKey());
return new StringBuilder().append(transaction).append(signature)
.append('\n').toString();
}
public String getTransaction(Wallet wallet, String destPubKey, long amount,
String comments) {
// Retrieve the wallet sources
TxSourceResults sourceResults = getSources(wallet.getPubKeyHash());
if (sourceResults == null) {
throw new UCoinTechnicalException("Unable to load user sources.");
}
List<TxSource> sources = sourceResults.getSources();
if (sources == null || sources.isEmpty()) {
throw new InsufficientCredit(
"Insufficient credit : no credit found.");
}
List<TxSource> txInputs = new ArrayList<TxSource>();
List<TxOutput> txOutputs = new ArrayList<TxOutput>();
computeInputsAndOuputs(wallet.getPubKeyHash(), destPubKey, sources,
amount, txInputs, txOutputs);
return getTransaction(wallet.getCurrency(), wallet.getPubKeyHash(),
destPubKey, txInputs, txOutputs, comments);
}
public String getTransaction(String currency, String srcPubKey,
String destPubKey, List<TxSource> inputs, List<TxOutput> outputs,
String comments) {
StringBuilder sb = new StringBuilder();
sb.append("Version: 1\n").append("Type: Transaction\n")
.append("Currency: ").append(currency).append('\n')
.append("Issuers:\n")
// add issuer pubkey
.append(srcPubKey).append('\n');
// Inputs coins
sb.append("Inputs:\n");
for (TxSource input : inputs) {
// INDEX:SOURCE:NUMBER:FINGERPRINT:AMOUNT
sb.append(0).append(':').append(input.getType()).append(':')
.append(input.getNumber()).append(':')
.append(input.getFingerprint()).append(':')
.append(input.getAmount()).append('\n');
}
// Output
sb.append("Outputs:\n");
for (TxOutput output : outputs) {
// PUBLIC_KEY:AMOUNT
sb.append(output.getPubKey()).append(':')
.append(output.getAmount()).append('\n');
}
// Comment
sb.append("Comment: ").append(comments).append('\n');
return sb.toString();
}
public void computeInputsAndOuputs(String srcPubKey, String destPubKey,
List<TxSource> sources, long amount, List<TxSource> inputs,
List<TxOutput> outputs) {
long rest = amount;
long restForHimSelf = 0;
for (TxSource source : sources) {
long srcAmount = source.getAmount();
inputs.add(source);
if (srcAmount >= rest) {
restForHimSelf = srcAmount - rest;
rest = 0;
break;
}
rest -= srcAmount;
}
if (rest > 0) {
throw new InsufficientCredit(String.format(
"Insufficient credit. Need %s more units.", rest));
}
// outputs
{
TxOutput output = new TxOutput();
output.setPubKey(destPubKey);
output.setAmount(amount);
outputs.add(output);
}
if (restForHimSelf > 0) {
TxOutput output = new TxOutput();
output.setPubKey(srcPubKey);
output.setAmount(restForHimSelf);
outputs.add(output);
}
}
protected long computeBalance(List<TxSource> sources) {
if (sources == null) {
return 0;
}
long balance = 0;
for (TxSource source : sources) {
balance += source.getAmount();
}
return balance;
}
}
package io.ucoin.client.core.service;
/*
* #%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 io.ucoin.client.core.model.*;
import io.ucoin.client.core.technical.UCoinTechnicalException;
import io.ucoin.client.core.technical.crypto.SecretBox;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class WotService extends AbstractNetworkService {
private static final Logger log = LoggerFactory.getLogger(WotService.class);
public WotService() {
super();
}
public WotLookupResults find(String uidPattern) throws Exception {
if (log.isDebugEnabled()) {
log.debug(String.format("Try to find user info by uid: %s", uidPattern));
}
// get parameter
String path = String.format(ProtocolUrls.WOT_LOOKUP, uidPattern);
HttpGet lookupHttpGet = new HttpGet(getAppendedPath(path));
WotLookupResults lookupResult = executeRequest(lookupHttpGet, WotLookupResults.class);
return lookupResult;
}
public WotLookupUId findByUid(String uid) throws Exception {
if (log.isDebugEnabled()) {
log.debug(String.format("Try to find user info by uid: %s", uid));
}
// call lookup
String path = String.format(ProtocolUrls.WOT_LOOKUP, uid);
HttpGet lookupHttpGet = new HttpGet(getAppendedPath(path));
WotLookupResults lookupResults = executeRequest(lookupHttpGet, WotLookupResults.class);
// Retrieve the exact uid
WotLookupUId uniqueResult = getUid(lookupResults, uid);
if (uniqueResult == null) {
throw new UCoinTechnicalException("User not found, with uid=" + uid);
}
return uniqueResult;
}
public WotIdentityCertifications getCertifiedBy(String uid) throws Exception {
if (log.isDebugEnabled()) {
log.debug(String.format("Try to get certifications done by uid: %s", uid));
}
// call certified-by
String path = String.format(ProtocolUrls.WOT_CERTIFIED_BY, uid);
HttpGet httpGet = new HttpGet(getAppendedPath(path));
WotIdentityCertifications result = executeRequest(httpGet, WotIdentityCertifications.class);
return result;
}
public WotIdentityCertifications getCertifiersOf(String uid) throws Exception {
if (log.isDebugEnabled()) {
log.debug(String.format("Try to get certifications done to uid: %s", uid));
}
// call certifiers-of
String path = String.format(ProtocolUrls.WOT_CERTIFIERS_OF, uid);
HttpGet httpGet = new HttpGet(getAppendedPath(path));
WotIdentityCertifications result = executeRequest(httpGet, WotIdentityCertifications.class);
return result;
}
public void sendSelf(String uid, SecretBox secretBox) throws Exception {
// http post /wot/add
HttpPost httpPost = new HttpPost(getAppendedPath(ProtocolUrls.WOT_ADD));
// compute the self-certification
String selfCertification = getSelfCertification(secretBox, uid);
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("pubkey", secretBox.getPublicKey()));
urlParameters.add(new BasicNameValuePair("self", selfCertification));
urlParameters.add(new BasicNameValuePair("other", ""));
httpPost.setEntity(new UrlEncodedFormEntity(urlParameters));
String selfResult = executeRequest(httpPost, String.class);
log.info("received from /add: " + selfResult);
}
public String getSelfCertification(SecretBox secretBox, String uid) throws Exception {
return getSelfCertification(secretBox, uid, new Date().getTime());
}
public String getSelfCertification(SecretBox secretBox, String uid, long timestamp) throws Exception {
// Create the self part to sign
StringBuilder buffer = new StringBuilder()
.append("UID:")
.append(uid)
.append("\nMETA:TS:")
.append(timestamp)
.append('\n');
// Compute the signature
String signature = secretBox.sign(buffer.toString());
// Append the signature
return buffer.append(signature)
.append('\n')
.toString();
}
public String getCertification(SecretBox secretBox, String userUid,
long userTimestamp,
String userSignature) throws Exception {
BlockchainService blockchainServcie = ServiceLocator.instance().getBlockchainService();
BlockchainBlock currentBlock = blockchainServcie.getCurrentBlock();
return getCertification(secretBox, userUid, userTimestamp, userSignature,
currentBlock.getNumber(),
currentBlock.getHash());
}
public String getCertification(SecretBox secretBox, String userUid,
long userTimestamp,
String userSignature,
int blockNumber,
String blockHash) throws Exception {
// Create the self part to sign
StringBuilder buffer = new StringBuilder()
.append("UID:")
.append(userUid)
.append("\nMETA:TS:")
.append(userTimestamp)
.append('\n')
.append(userSignature)
.append("\nMETA:TS:")
.append(blockNumber)
.append('-')
.append(blockHash)
.append('\n');
// Compute the signature
String signature = secretBox.sign(buffer.toString());
// Append the signature
return buffer.append(signature)
.append('\n')
.toString();
}
/* -- Internal methods -- */
protected WotLookupUId getUid(WotLookupResults lookupResults, String filterUid) {
if (CollectionUtils.isEmpty(lookupResults.getResults())) {
return null;
}
for (WotLookupResult result : lookupResults.getResults()) {
if (CollectionUtils.isNotEmpty(result.getUids())) {
for (WotLookupUId uid : result.getUids()) {
if (filterUid.equals(uid.getUid())) {
return uid;
}
}
}
}
return null;
}
}
package io.ucoin.client.core.service.search;
/*
* #%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.ObjectMapper;
import io.ucoin.client.core.service.BaseService;
import io.ucoin.client.core.service.ServiceLocator;
import io.ucoin.client.core.technical.UCoinTechnicalException;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequestBuilder;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
* Created by Benoit on 08/04/2015.
*/
public abstract class BaseIndexerService extends BaseService{
private static final Logger log = LoggerFactory.getLogger(BaseIndexerService.class);
private ElasticSearchService elasticSearchService;
public BaseIndexerService() {
}
@Override
public void initialize() {
super.initialize();
elasticSearchService = ServiceLocator.instance().getElasticSearchService();
}
public Client getClient() {
return elasticSearchService.getClient();
}
public ObjectMapper getObjectMapper() {
return elasticSearchService.getObjectMapper();
}
public boolean existsIndex(String indexes) throws JsonProcessingException {
IndicesExistsRequestBuilder requestBuilder = getClient().admin().indices().prepareExists(indexes);
IndicesExistsResponse response = requestBuilder.execute().actionGet();
return response.isExists();
}
public void deleteIndexIfExists(String indexes) throws JsonProcessingException {
if (!existsIndex(indexes)) {
return;
}
DeleteIndexRequestBuilder deleteIndexRequestBuilder = getClient().admin().indices().prepareDelete(indexes);
DeleteIndexResponse response = deleteIndexRequestBuilder.execute().actionGet();
}
protected XContentBuilder getDefaultAnalyzer() {
try {
XContentBuilder analyzer = XContentFactory.jsonBuilder().startObject().startObject("analyzer")
.startObject("custom_french_analyzer")
.field("tokenizer", "letter")
.field("filter", "asciifolding", "lowercase", "french_stem", "elision", "stop")
.endObject()
.startObject("tag_analyzer")
.field("tokenizer", "keyword")
.field("filter", "asciifolding", "lowercase")
.endObject()
.endObject().endObject();
return analyzer;
} catch(IOException e) {
throw new UCoinTechnicalException("Error while preparing default index analyzer: " + e.getMessage(), e);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment