Skip to content

Commit

Permalink
FAB-1087 Add config option in core.yaml for history
Browse files Browse the repository at this point in the 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 <mariwade@us.ibm.com>
  • Loading branch information
mariwade committed Nov 30, 2016
1 parent d148c38 commit 3731447
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 18 deletions.
6 changes: 3 additions & 3 deletions core/ledger/kvledger/kv_ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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},
Expand Down
21 changes: 11 additions & 10 deletions core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb/couchdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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()
Expand All @@ -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)
Expand All @@ -108,7 +108,7 @@ func TestDBBadConnection(t *testing.T) {

func TestDBCreateDatabaseAndPersist(t *testing.T) {

if kvledgerconfig.IsCouchDBEnabled() == true {
if ledgerconfig.IsCouchDBEnabled() == true {

cleanup()

Expand Down Expand Up @@ -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)
Expand All @@ -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()
Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package kvledgerconfig
package ledgerconfig

import "github.com/spf13/viper"

var stateDatabase = "goleveldb"
var couchDBAddress = "127.0.0.1:5984"
var username = ""
var password = ""
var historyDatabase = true

// CouchDBDef contains parameters
type CouchDBDef struct {
Expand All @@ -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
}
86 changes: 86 additions & 0 deletions core/ledger/ledgerconfig/ledger_config_test.go
Original file line number Diff line number Diff line change
@@ -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")
}
9 changes: 8 additions & 1 deletion core/ledger/testutil/test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions peer/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

###############################################################################
#
Expand Down

0 comments on commit 3731447

Please sign in to comment.