Skip to content

Commit

Permalink
Move config specific functions to their own package
Browse files Browse the repository at this point in the history
  • Loading branch information
Roland Shoemaker committed May 17, 2017
1 parent d0c7380 commit 8b48ccf
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 61 deletions.
64 changes: 64 additions & 0 deletions configs/configs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2017 Google Inc. 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 configs

import (
"encoding/json"
"errors"
"flag"
"fmt"
"io/ioutil"
"time"
)

// JSONDuration is an abstraction used to simplifying unmarshalling
// json into structs that contain time.Duration fields. Expected
// format is the same as provided to time.ParseDuration.
type JSONDuration struct {
time.Duration
}

// UnmarshalJSON parses a time.Duration field from a string
func (jd *JSONDuration) UnmarshalJSON(data []byte) error {
s := ""
err := json.Unmarshal(data, &s)
if err != nil {
return err
}
d, err := time.ParseDuration(s)
if err != nil {
return err
}
jd.Duration = d
return nil
}

// LoadConfig loads a configuration JSON file from the provided path and
// unmarshals it into the provided object. It also enforces --config being
// the only flag provided to the binary calling LoadConfig.
func LoadConfig(path string, obj interface{}) error {
// Only allow either --config OR any other flags
if flag.CommandLine.NFlag() > 1 {
return errors.New("Cannot use --config with any other flags")
}
f, err := ioutil.ReadFile(path)
if err != nil {
return fmt.Errorf("Failed to read config file: %v", err)
}
if err := json.Unmarshal(f, obj); err != nil {
return fmt.Errorf("Failed to parse config file: %v", err)
}
return nil
}
38 changes: 21 additions & 17 deletions util/config.go → configs/configs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package util
package configs

import (
"encoding/json"
"testing"
"time"
)

// ConfigDuration is an abstraction used to simplifying unmarshalling
// json into structs that contain time.Duration fields
type ConfigDuration struct {
time.Duration
}
func TestJSONDuration(t *testing.T) {
var s struct {
Dur JSONDuration
}

a := []byte(`{"dur":"10s"}`)
if err := json.Unmarshal(a, &s); err != nil {
t.Errorf("Failed to unmarshal duration: %v", err)
}
if s.Dur.Duration != (time.Second * 10) {
t.Errorf("Unexpected duration, want: 10s, got: %s", s.Dur)
}

// UnmarshalJSON parses a time.Duration field from a string
func (cd ConfigDuration) UnmarshalJSON(data []byte) error {
s := ""
err := json.Unmarshal(data, &s)
if err != nil {
return err
b := []byte(`{"dur": 1}`)
if err := json.Unmarshal(b, &s); err == nil {
t.Error("Didn't fail when unmarshalling a non-string type into JSONDuration")
}
d, err := time.ParseDuration(s)
if err != nil {
return err

c := []byte(`{"dur": ""}`)
if err := json.Unmarshal(c, &s); err == nil {
t.Error("Didn't fail when unmarshalling an empty string into JSONDuration")
}
cd.Duration = d
return nil
}
17 changes: 4 additions & 13 deletions examples/ct/ct_server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
package main

import (
"encoding/json"
_ "expvar"
"flag" // For HTTP server registration
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
Expand All @@ -30,6 +28,7 @@ import (
etcdnaming "github.com/coreos/etcd/clientv3/naming"
"github.com/golang/glog"
"github.com/google/trillian"
"github.com/google/trillian/configs"
"github.com/google/trillian/examples/ct"
"github.com/google/trillian/util"
"google.golang.org/grpc"
Expand All @@ -40,7 +39,7 @@ type config struct {
Host string
Port int
LogRPCServer string
RPCDeadline util.ConfigDuration
RPCDeadline configs.JSONDuration
LogConfig string
MaxGetEntriesAllowed int64
EtcdServers string
Expand All @@ -60,16 +59,8 @@ func main() {
flag.Parse()

if *configFlag != "" {
// Only allow either --configFlag OR any other flags
if flag.CommandLine.NFlag() > 2 {
glog.Exit("Cannot use --configFlag with any other flags")
}
f, err := ioutil.ReadFile(*configFlag)
if err != nil {
glog.Exitf("Failed to read config file: %v", err)
}
if err := json.Unmarshal(f, &c); err != nil {
glog.Exitf("Failed to parse config file: %v", err)
if err := configs.LoadConfig(*configFlag, &c); err != nil {
glog.Exit(err)
}
}

Expand Down
17 changes: 4 additions & 13 deletions server/trillian_log_server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ package main

import (
"context"
"encoding/json"
"flag"
"io/ioutil"
_ "net/http/pprof"
"strings"
"time"
Expand All @@ -29,6 +27,7 @@ import (
etcdnaming "github.com/coreos/etcd/clientv3/naming"
"github.com/golang/glog"
"github.com/google/trillian"
"github.com/google/trillian/configs"
"github.com/google/trillian/crypto/keys"
"github.com/google/trillian/extension"
"github.com/google/trillian/monitoring"
Expand All @@ -46,7 +45,7 @@ type config struct {
MySQLURI string
RPCEndpoint string
HTTPEndpoint string
DumpMetricsInterval util.ConfigDuration
DumpMetricsInterval configs.JSONDuration
EtcdServers string
EtcdService string
}
Expand All @@ -64,16 +63,8 @@ func main() {
flag.Parse()

if *configFlag != "" {
// Only allow either --configFlag OR any other flags
if flag.CommandLine.NFlag() > 2 {
glog.Exit("Cannot use --configFlag with any other flags")
}
f, err := ioutil.ReadFile(*configFlag)
if err != nil {
glog.Exitf("Failed to read config file: %v", err)
}
if err := json.Unmarshal(f, &c); err != nil {
glog.Exitf("Failed to parse config file: %v", err)
if err := configs.LoadConfig(*configFlag, &c); err != nil {
glog.Exit(err)
}
}

Expand Down
27 changes: 9 additions & 18 deletions server/trillian_log_signer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@
package main

import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"time"

_ "github.com/go-sql-driver/mysql" // Load MySQL driver

"github.com/golang/glog"
"github.com/google/trillian/configs"
"github.com/google/trillian/crypto/keys"
"github.com/google/trillian/extension"
"github.com/google/trillian/monitoring/metric"
Expand All @@ -39,17 +38,17 @@ import (
type config struct {
MySQLURI string
HTTPEndpoint string
SequencerInterval util.ConfigDuration
SequencerInterval configs.JSONDuration
BatchSize int
NumSequencers int
SequencerGuardWindow util.ConfigDuration
DumpMetricsInterval util.ConfigDuration
SequencerGuardWindow configs.JSONDuration
DumpMetricsInterval configs.JSONDuration
ForceMaster bool
EtcdServers string
LockFilePath string
PreElectionPause util.ConfigDuration
MasterCheckInterval util.ConfigDuration
MasterHoldInterval util.ConfigDuration
PreElectionPause configs.JSONDuration
MasterCheckInterval configs.JSONDuration
MasterHoldInterval configs.JSONDuration
ResignOdds int
}

Expand All @@ -75,16 +74,8 @@ func main() {
flag.Parse()

if *configFlag != "" {
// Only allow either --configFlag OR any other flags
if flag.CommandLine.NFlag() > 2 {
glog.Exit("Cannot use --configFlag with any other flags")
}
f, err := ioutil.ReadFile(*configFlag)
if err != nil {
glog.Exitf("Failed to read config file: %v", err)
}
if err := json.Unmarshal(f, &c); err != nil {
glog.Exitf("Failed to parse config file: %v", err)
if err := configs.LoadConfig(*configFlag, &c); err != nil {
glog.Exit(err)
}
}

Expand Down

0 comments on commit 8b48ccf

Please sign in to comment.