From 37314475c112cfcf8fe2e222ba583faba810fc33 Mon Sep 17 00:00:00 2001 From: Mari Wade Date: Thu, 10 Nov 2016 15:15:39 -0500 Subject: [PATCH] FAB-1087 Add config option in core.yaml for history Add config option in core.yaml for history database to store the transaction history. The history database will be a queryable database such as CouchDB. The default will be false. If set to false, the transaction history will not be persisted in the history database. Move the ledger config directory up one level to ledger to be the config for state and history databases as well as any other ledger functionality that needs a config option. Change-Id: If4607047082b686dd903d8b3805362d0c05e1c64 Signed-off-by: Mari Wade --- core/ledger/kvledger/kv_ledger.go | 6 +- .../couchdbtxmgmt/couchdb/couchdb_test.go | 21 ++--- .../couchdbtxmgmt/couchdb_txmgmt_test.go | 6 +- .../ledger_config.go} | 15 +++- .../ledger/ledgerconfig/ledger_config_test.go | 86 +++++++++++++++++++ core/ledger/testutil/test_util.go | 9 +- peer/core.yaml | 6 ++ 7 files changed, 131 insertions(+), 18 deletions(-) rename core/ledger/{kvledger/kvledgerconfig/kv_ledger_config.go => ledgerconfig/ledger_config.go} (75%) create mode 100644 core/ledger/ledgerconfig/ledger_config_test.go diff --git a/core/ledger/kvledger/kv_ledger.go b/core/ledger/kvledger/kv_ledger.go index aa9a5c4ffd0..684f34ea3b9 100644 --- a/core/ledger/kvledger/kv_ledger.go +++ b/core/ledger/kvledger/kv_ledger.go @@ -24,10 +24,10 @@ import ( "github.com/hyperledger/fabric/core/ledger" "github.com/hyperledger/fabric/core/ledger/blkstorage" "github.com/hyperledger/fabric/core/ledger/blkstorage/fsblkstorage" - "github.com/hyperledger/fabric/core/ledger/kvledger/kvledgerconfig" "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt" "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/couchdbtxmgmt" "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/lockbasedtxmgmt" + "github.com/hyperledger/fabric/core/ledger/ledgerconfig" logging "github.com/op/go-logging" @@ -76,11 +76,11 @@ func NewKVLedger(conf *Conf) (*KVLedger, error) { blockStorageConf := fsblkstorage.NewConf(conf.blockStorageDir, conf.maxBlockfileSize) blockStore := fsblkstorage.NewFsBlockStore(blockStorageConf, indexConfig) - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { //By default we can talk to CouchDB with empty id and pw (""), or you can add your own id and password to talk to a secured CouchDB logger.Debugf("===COUCHDB=== NewKVLedger() Using CouchDB instead of RocksDB...hardcoding and passing connection config for now") - couchDBDef := kvledgerconfig.GetCouchDBDefinition() + couchDBDef := ledgerconfig.GetCouchDBDefinition() //create new transaction manager based on couchDB txmgmt := couchdbtxmgmt.NewCouchDBTxMgr(&couchdbtxmgmt.Conf{DBPath: conf.txMgrDBPath}, diff --git a/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb/couchdb_test.go b/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb/couchdb_test.go index 183407c47e9..74f7a194834 100644 --- a/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb/couchdb_test.go +++ b/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb/couchdb_test.go @@ -21,7 +21,7 @@ import ( "fmt" "testing" - "github.com/hyperledger/fabric/core/ledger/kvledger/kvledgerconfig" + "github.com/hyperledger/fabric/core/ledger/ledgerconfig" "github.com/hyperledger/fabric/core/ledger/testutil" ) @@ -63,7 +63,7 @@ func TestDBBadConnectionDef(t *testing.T) { func TestDBCreateSaveWithoutRevision(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() @@ -85,7 +85,7 @@ func TestDBCreateSaveWithoutRevision(t *testing.T) { func TestDBBadConnection(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { //create a new connection db, err := CreateConnectionDefinition(badConnectURL, database, username, password) @@ -108,7 +108,7 @@ func TestDBBadConnection(t *testing.T) { func TestDBCreateDatabaseAndPersist(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { cleanup() @@ -175,9 +175,10 @@ func TestDBCreateDatabaseAndPersist(t *testing.T) { func TestDBBadJSON(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { cleanup() + defer cleanup() //create a new connection db, err := CreateConnectionDefinition(connectURL, database, username, password) @@ -204,7 +205,7 @@ func TestDBBadJSON(t *testing.T) { func TestDBSaveAttachment(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() @@ -239,7 +240,7 @@ func TestDBSaveAttachment(t *testing.T) { func TestDBRetrieveNonExistingDocument(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() @@ -261,7 +262,7 @@ func TestDBRetrieveNonExistingDocument(t *testing.T) { func TestDBTestExistingDB(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() @@ -283,7 +284,7 @@ func TestDBTestExistingDB(t *testing.T) { func TestDBTestDropNonExistDatabase(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() @@ -301,7 +302,7 @@ func TestDBTestDropNonExistDatabase(t *testing.T) { func TestDBTestDropDatabaseBadConnection(t *testing.T) { - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() diff --git a/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb_txmgmt_test.go b/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb_txmgmt_test.go index 0d553ed8558..6b38b1f037b 100644 --- a/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb_txmgmt_test.go +++ b/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb_txmgmt_test.go @@ -21,8 +21,8 @@ import ( "os" "testing" - "github.com/hyperledger/fabric/core/ledger/kvledger/kvledgerconfig" "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb" + "github.com/hyperledger/fabric/core/ledger/ledgerconfig" "github.com/hyperledger/fabric/core/ledger/testutil" ) @@ -39,7 +39,7 @@ func newTestEnv(t testing.TB) *testEnv { //call a helper method to load the core.yaml testutil.SetupCoreYAMLConfig("./../../../../../peer") - couchDBDef := kvledgerconfig.GetCouchDBDefinition() + couchDBDef := ledgerconfig.GetCouchDBDefinition() conf := &Conf{"/tmp/tests/ledger/kvledger/txmgmt/couchdbtxmgmt"} os.RemoveAll(conf.DBPath) @@ -69,7 +69,7 @@ func TestDatabaseAutoCreate(t *testing.T) { //Only run the tests if CouchDB is explitily enabled in the code, //otherwise CouchDB may not be installed and all the tests would fail //TODO replace this with external config property rather than config within the code - if kvledgerconfig.IsCouchDBEnabled() == true { + if ledgerconfig.IsCouchDBEnabled() == true { env := newTestEnv(t) env.Cleanup() //cleanup at the beginning to ensure the database doesn't exist already diff --git a/core/ledger/kvledger/kvledgerconfig/kv_ledger_config.go b/core/ledger/ledgerconfig/ledger_config.go similarity index 75% rename from core/ledger/kvledger/kvledgerconfig/kv_ledger_config.go rename to core/ledger/ledgerconfig/ledger_config.go index 6b6905611bb..6ed15d60e55 100644 --- a/core/ledger/kvledger/kvledgerconfig/kv_ledger_config.go +++ b/core/ledger/ledgerconfig/ledger_config.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kvledgerconfig +package ledgerconfig import "github.com/spf13/viper" @@ -22,6 +22,7 @@ var stateDatabase = "goleveldb" var couchDBAddress = "127.0.0.1:5984" var username = "" var password = "" +var historyDatabase = true // CouchDBDef contains parameters type CouchDBDef struct { @@ -48,3 +49,15 @@ func GetCouchDBDefinition() *CouchDBDef { return &CouchDBDef{couchDBAddress, username, password} } + +//IsHistoryDBEnabled exposes the historyDatabase variable +//History database can only be enabled if couchDb is enabled +//as it the history stored in the same couchDB instance. +//TODO put History DB in it's own instance +func IsHistoryDBEnabled() bool { + historyDatabase = viper.GetBool("ledger.state.historyDatabase") + if IsCouchDBEnabled() && historyDatabase { + return historyDatabase + } + return false +} diff --git a/core/ledger/ledgerconfig/ledger_config_test.go b/core/ledger/ledgerconfig/ledger_config_test.go new file mode 100644 index 00000000000..94b3fc1d172 --- /dev/null +++ b/core/ledger/ledgerconfig/ledger_config_test.go @@ -0,0 +1,86 @@ +/* +Copyright IBM Corp. 2016 All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ledgerconfig + +import ( + "testing" + + "github.com/hyperledger/fabric/core/ledger/testutil" + "github.com/spf13/viper" +) + +func TestIsCouchDBEnabledDefault(t *testing.T) { + setUpCoreYAMLConfig() + defaultValue := IsCouchDBEnabled() + testutil.AssertEquals(t, defaultValue, false) //test default config is false +} + +func TestIsCouchDBEnabled(t *testing.T) { + setUpCoreYAMLConfig() + defer testutil.ResetConfigToDefaultValues() + viper.Set("ledger.state.stateDatabase", "CouchDB") + updatedValue := IsCouchDBEnabled() + testutil.AssertEquals(t, updatedValue, true) //test config returns true +} + +func TestGetCouchDBDefinition(t *testing.T) { + setUpCoreYAMLConfig() + defer testutil.ResetConfigToDefaultValues() + viper.Set("ledger.state.stateDatabase", "CouchDB") + couchDBDef := GetCouchDBDefinition() + testutil.AssertEquals(t, couchDBDef.URL, "127.0.0.1:5984") + testutil.AssertEquals(t, couchDBDef.Username, "") + testutil.AssertEquals(t, couchDBDef.Password, "") +} + +func TestIsHistoryDBEnabledDefault(t *testing.T) { + setUpCoreYAMLConfig() + defaultValue := IsHistoryDBEnabled() + testutil.AssertEquals(t, defaultValue, false) //test default config is false +} + +func TestIsHistoryDBEnabledWhenCouchDBIsDisabled(t *testing.T) { + setUpCoreYAMLConfig() + defer testutil.ResetConfigToDefaultValues() + viper.Set("ledger.state.stateDatabase", "goleveldb") + viper.Set("ledger.state.historyDatabase", true) + updatedValue := IsHistoryDBEnabled() + testutil.AssertEquals(t, updatedValue, false) //test config is false +} + +func TestIsHistoryDBEnabledWhenOnlyCouchDBEnabled(t *testing.T) { + setUpCoreYAMLConfig() + defer testutil.ResetConfigToDefaultValues() + viper.Set("ledger.state.stateDatabase", "CouchDB") + viper.Set("ledger.state.historyDatabase", false) + updatedValue := IsHistoryDBEnabled() + testutil.AssertEquals(t, updatedValue, false) //test config is false +} + +func TestIsHistoryDBEnabled(t *testing.T) { + setUpCoreYAMLConfig() + defer testutil.ResetConfigToDefaultValues() + viper.Set("ledger.state.stateDatabase", "CouchDB") + viper.Set("ledger.state.historyDatabase", true) + updatedValue := IsHistoryDBEnabled() + testutil.AssertEquals(t, updatedValue, true) //test config returns true +} + +func setUpCoreYAMLConfig() { + //call a helper method to load the core.yaml + testutil.SetupCoreYAMLConfig("./../../../peer") +} diff --git a/core/ledger/testutil/test_util.go b/core/ledger/testutil/test_util.go index 827a519f51a..2a2f90e1782 100644 --- a/core/ledger/testutil/test_util.go +++ b/core/ledger/testutil/test_util.go @@ -72,7 +72,7 @@ func SetupTestConfig() { logging.SetFormatter(formatter) } -// SetupCoreYAMLConfig sets up configurations for tetsing +// SetupCoreYAMLConfig sets up configurations for testing func SetupCoreYAMLConfig(coreYamlPath string) { viper.SetConfigName("core") viper.SetEnvPrefix("CORE") @@ -85,6 +85,13 @@ func SetupCoreYAMLConfig(coreYamlPath string) { } } +// ResetConfigToDefaultValues resets configurations optins back to defaults +func ResetConfigToDefaultValues() { + //reset to defaults + viper.Set("ledger.state.stateDatabase", "goleveldb") + viper.Set("ledger.state.historyDatabase", false) +} + // SetLogLevel sets up log level func SetLogLevel(level logging.Level, module string) { logging.SetLevel(level, module) diff --git a/peer/core.yaml b/peer/core.yaml index 5de49126e7c..d4b14a5feee 100644 --- a/peer/core.yaml +++ b/peer/core.yaml @@ -413,6 +413,12 @@ ledger: couchDBAddress: 127.0.0.1:5984 username: password: + # historyDatabase - options are true or false + # Indicates if the transaction history should be stored in + # a querable database such as "CouchDB". + # The stateDatabase must be also stored in CouchDB for + # history to be enabled. + historyDatabase: false ############################################################################### #