forked from dinstein/fabric
/
node_start.go
187 lines (155 loc) · 5.88 KB
/
node_start.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package startnode
import (
"fmt"
"github.com/abchain/fabric/core/chaincode"
"github.com/abchain/fabric/core/config"
"github.com/abchain/fabric/core/peer"
"github.com/abchain/fabric/events/producer"
"github.com/abchain/fabric/node"
webapi "github.com/abchain/fabric/node/rest"
api "github.com/abchain/fabric/node/service"
pb "github.com/abchain/fabric/protos"
"github.com/op/go-logging"
"github.com/spf13/viper"
"golang.org/x/net/context"
)
//entries for init and run the fabric node, including following steps
//* Pre-init (call PreInitFabricNode), which will create the global node
// object and execute PreInit in the node, and init other required
// variables
// the context passed in PreInitFabricNode will act as a "final switch"
// which will close all running routine inside the node
//* Init (call InitFabricNode), init the node object, all of the
// rpc services is ready now
//* Run (call RunFabricNode), the node start accepting incoming request
// and communicating to the world
//* Keep, run the guard function, which will keep block until the incoming
// context is canceled, and just keep tracking the status of each rpc
// services. When finish, the running rpc services in the node will be stopped
// (and RunFabricNode can be called again)
// if a nil context is passed, it exit without blocking and simply stop
// current running node
//* Final, when exit, just do not forget call Final to release most of the
// resources (process is recommended to be exit after that)
var (
logger = logging.MustGetLogger("engine")
theNode *node.NodeEngine
)
func GetNode() *node.NodeEngine { return theNode }
func PreInitFabricNode(ctx context.Context, name string) {
if theNode != nil {
panic("Doudble call of init")
}
theNode = new(node.NodeEngine)
theNode.Name = name
theNode.PreInit()
peer.PeerGlobalParentCtx = ctx
}
func Final() {
theNode.FinalRelease()
}
func RunFabricNode() (error, func(ctx context.Context)) {
status, err := theNode.RunAll()
if err != nil {
return err, nil
}
return nil, func(ctx context.Context) {
defer theNode.StopServices(status)
for {
select {
case <-ctx.Done():
return
case srvp := <-status:
logger.Errorf("server point [%s] fail: %s", srvp.Spec().Address, srvp.Status())
//simply respawn it (just fail for we do not clean the error)
//TODO: we may need a more robust way before we can really respawn the
//server (for example, retry after serveral seconds, stop after some
//times of retrying, etc)
srvp.Start(status)
}
}
}
}
func InitFabricNode() error {
if err := theNode.ExecInit(); err != nil {
return fmt.Errorf("NODE INIT FAILURE: ***** %s *****", err)
}
//create node and other infrastructures ... (if no setting, use default peer's server point)
//chaincode: TODO: support mutiple chaincode platforms
if ccConf := config.SubViper("chaincode"); !ccConf.GetBool("disabled") {
ccsrv, err := node.CreateServerPoint(ccConf)
if err != nil {
logger.Infof("Can not create server spec for chaincode: [%s], merge it into peer", err)
ccsrv = theNode.DefaultPeer().GetServerPoint()
} else {
theNode.AddServicePoint(ccsrv)
}
userRunsCC := false
if ccConf.GetString("mode") == chaincode.DevModeUserRunsChaincode {
userRunsCC = true
}
chaincode.NewSystemChaincodeSupport(theNode.Name)
ccplatform := chaincode.NewChaincodeSupport(chaincode.DefaultChain, theNode.Name, ccsrv.Spec(), userRunsCC)
pb.RegisterChaincodeSupportServer(ccsrv.Server, ccplatform)
} else {
logger.Info("Chaincode platform setting is disabled")
}
devOps := api.NewDevopsServer(theNode)
//omit the error of chainsrv, later it should return no error
nbif, _ := theNode.DefaultPeer().Peer.GetNeighbour()
ocsrv, _ := api.NewOpenchainServerWithPeerInfo(nbif)
//api, also bind the event hub, and "service" configuration in YA-fabric 0.7/0.8 is abandoned
if viper.IsSet("node.api") {
apiConf := config.SubViper("node.api")
if !apiConf.GetBool("disabled") {
apisrv, err := node.CreateServerPoint(config.SubViper("node.api"))
if err != nil {
return fmt.Errorf("Error setting for API service: %s", err)
}
theNode.AddServicePoint(apisrv)
//init each term, with separated disabled switch on them
if !apiConf.GetBool("service.disabled") {
logger.Info("client service is attached")
pb.RegisterDevopsServer(apisrv.Server, devOps)
}
if !apiConf.GetBool("admin.disabled") {
logger.Info("administrator interface is attached")
pb.RegisterAdminServer(apisrv.Server, api.NewAdminServer())
}
if !apiConf.GetBool("chain.disabled") {
logger.Info("chain service is attached")
pb.RegisterOpenchainServer(apisrv.Server, ocsrv)
}
if evtConf := config.SubViper("events", apiConf); !evtConf.GetBool("disabled") {
logger.Info("event service is attached")
pb.RegisterEventsServer(apisrv.Server, producer.NewEventsServer(
uint(evtConf.GetInt("buffersize")),
evtConf.GetInt("timeout")))
}
} else {
logger.Info("api interface has been disabled")
}
} else {
logger.Info("Apply legacy API configurations")
//respect legacy configuration: enable all interfaces and bind them to default peer, except for
//event
apisrv := theNode.DefaultPeer().GetServerPoint()
pb.RegisterAdminServer(apisrv.Server, api.NewAdminServer())
pb.RegisterDevopsServer(apisrv.Server, devOps)
pb.RegisterOpenchainServer(apisrv.Server, ocsrv)
if evtsrv, err := node.CreateServerPoint(config.SubViper("peer.validator.events")); err != nil {
return fmt.Errorf("Error setting for event service: %s", err)
} else {
theNode.AddServicePoint(evtsrv)
evtConf := config.SubViper("peer.validator.events")
pb.RegisterEventsServer(evtsrv.Server, producer.NewEventsServer(
uint(evtConf.GetInt("buffersize")),
evtConf.GetInt("timeout")))
}
}
//finally the rest, may be abandoned later
if viper.GetBool("rest.enabled") {
go webapi.StartOpenchainRESTServer(ocsrv, devOps)
}
return nil
}