github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/go/src/sawtooth_sdk/messaging/connection.go (about) 1 /** 2 * Copyright 2017 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * ------------------------------------------------------------------------------ 16 */ 17 18 // Package messaging handles lower-level communication between a transaction 19 // processor and validator. 20 package messaging 21 22 import ( 23 "fmt" 24 "github.com/golang/protobuf/proto" 25 zmq "github.com/pebbe/zmq4" 26 uuid "github.com/satori/go.uuid" 27 "sawtooth_sdk/logging" 28 "sawtooth_sdk/protobuf/validator_pb2" 29 ) 30 31 var logger *logging.Logger = logging.Get() 32 33 // Generate a new UUID 34 func GenerateId() string { 35 return fmt.Sprint(uuid.NewV4()) 36 } 37 38 // DumpMsg serializes a validator message 39 func DumpMsg(t validator_pb2.Message_MessageType, c []byte, corrId string) ([]byte, error) { 40 msg := &validator_pb2.Message{ 41 MessageType: t, 42 CorrelationId: corrId, 43 Content: c, 44 } 45 return proto.Marshal(msg) 46 } 47 48 // LoadMsg deserializes a validator message 49 func LoadMsg(data []byte) (msg *validator_pb2.Message, err error) { 50 msg = &validator_pb2.Message{} 51 err = proto.Unmarshal(data, msg) 52 return 53 } 54 55 type Connection interface { 56 SendData(id string, data []byte) error 57 SendNewMsg(t validator_pb2.Message_MessageType, c []byte) (corrId string, err error) 58 SendNewMsgTo(id string, t validator_pb2.Message_MessageType, c []byte) (corrId string, err error) 59 SendMsg(t validator_pb2.Message_MessageType, c []byte, corrId string) error 60 SendMsgTo(id string, t validator_pb2.Message_MessageType, c []byte, corrId string) error 61 RecvData() (string, []byte, error) 62 RecvMsg() (string, *validator_pb2.Message, error) 63 RecvMsgWithId(corrId string) (string, *validator_pb2.Message, error) 64 Close() 65 Socket() *zmq.Socket 66 Monitor(zmq.Event) (*zmq.Socket, error) 67 Identity() string 68 } 69 70 // Connection wraps a ZMQ DEALER socket or ROUTER socket and provides some 71 // utility methods for sending and receiving messages. 72 type ZmqConnection struct { 73 identity string 74 uri string 75 socket *zmq.Socket 76 context *zmq.Context 77 incoming map[string]*storedMsg 78 } 79 80 type storedMsg struct { 81 Id string 82 Msg *validator_pb2.Message 83 } 84 85 // NewConnection establishes a new connection using the given ZMQ context and 86 // socket type to the given URI. 87 func NewConnection(context *zmq.Context, t zmq.Type, uri string, bind bool) (*ZmqConnection, error) { 88 socket, err := context.NewSocket(t) 89 if err != nil { 90 return nil, fmt.Errorf("Failed to create ZMQ socket: %v", err) 91 } 92 93 identity := GenerateId() 94 socket.SetIdentity(identity) 95 96 if bind { 97 logger.Info("Binding to ", uri) 98 err = socket.Bind(uri) 99 } else { 100 logger.Info("Connecting to ", uri) 101 err = socket.Connect(uri) 102 } 103 if err != nil { 104 return nil, fmt.Errorf("Failed to establish connection to %v: %v", uri, err) 105 } 106 107 return &ZmqConnection{ 108 identity: identity, 109 uri: uri, 110 socket: socket, 111 context: context, 112 incoming: make(map[string]*storedMsg), 113 }, nil 114 } 115 116 // SendData sends the byte array. 117 // 118 // If id is not "", the id is included as the first part of the message. This 119 // is useful for passing messages to a ROUTER socket so it can route them. 120 func (self *ZmqConnection) SendData(id string, data []byte) error { 121 if id != "" { 122 _, err := self.socket.SendMessage(id, [][]byte{data}) 123 if err != nil { 124 return err 125 } 126 } else { 127 _, err := self.socket.SendMessage([][]byte{data}) 128 if err != nil { 129 return err 130 } 131 } 132 return nil 133 } 134 135 // SendNewMsg creates a new validator message, assigns a new correlation id, 136 // serializes it, and sends it. It returns the correlation id created. 137 func (self *ZmqConnection) SendNewMsg(t validator_pb2.Message_MessageType, c []byte) (corrId string, err error) { 138 return self.SendNewMsgTo("", t, c) 139 } 140 141 // SendNewMsgTo sends a new message validator message with the given id sent as 142 // the first part of the message. This is required when sending to a ROUTER 143 // socket, so it knows where to route the message. 144 func (self *ZmqConnection) SendNewMsgTo(id string, t validator_pb2.Message_MessageType, c []byte) (corrId string, err error) { 145 corrId = GenerateId() 146 return corrId, self.SendMsgTo(id, t, c, corrId) 147 } 148 149 // Send a message with the given correlation id 150 func (self *ZmqConnection) SendMsg(t validator_pb2.Message_MessageType, c []byte, corrId string) error { 151 return self.SendMsgTo("", t, c, corrId) 152 } 153 154 // Send a message with the given correlation id and the prepends the id like 155 // SendNewMsgTo() 156 func (self *ZmqConnection) SendMsgTo(id string, t validator_pb2.Message_MessageType, c []byte, corrId string) error { 157 data, err := DumpMsg(t, c, corrId) 158 if err != nil { 159 return err 160 } 161 162 return self.SendData(id, data) 163 } 164 165 // RecvData receives a ZMQ message from the wrapped socket and returns the 166 // identity of the sender and the data sent. If ZmqConnection does not wrap a 167 // ROUTER socket, the identity returned will be "". 168 func (self *ZmqConnection) RecvData() (string, []byte, error) { 169 msg, err := self.socket.RecvMessage(0) 170 171 if err != nil { 172 return "", nil, err 173 } 174 switch len(msg) { 175 case 1: 176 data := []byte(msg[0]) 177 return "", data, nil 178 case 2: 179 id := msg[0] 180 data := []byte(msg[1]) 181 return id, data, nil 182 default: 183 return "", nil, fmt.Errorf( 184 "Receive message with unexpected length: %v", len(msg), 185 ) 186 } 187 } 188 189 // RecvMsg receives a new validator message and returns it deserialized. If 190 // ZmqConnection wraps a ROUTER socket, id will be the identity of the sender. 191 // Otherwise, id will be "". 192 func (self *ZmqConnection) RecvMsg() (string, *validator_pb2.Message, error) { 193 for corrId, stored := range self.incoming { 194 delete(self.incoming, corrId) 195 return stored.Id, stored.Msg, nil 196 } 197 198 // Receive a message from the socket 199 id, bytes, err := self.RecvData() 200 if err != nil { 201 return "", nil, err 202 } 203 204 msg, err := LoadMsg(bytes) 205 return id, msg, err 206 } 207 208 // RecvMsgWithId receives validator messages until a message with the given 209 // correlation id is found and returns this message. Any messages received that 210 // do not match the id are saved for subsequent receives. 211 func (self *ZmqConnection) RecvMsgWithId(corrId string) (string, *validator_pb2.Message, error) { 212 // If the message is already stored, just return it 213 stored, exists := self.incoming[corrId] 214 if exists { 215 return stored.Id, stored.Msg, nil 216 } 217 218 for { 219 // If the message isn't stored, keep getting messages until it shows up 220 id, bytes, err := self.RecvData() 221 if err != nil { 222 return "", nil, err 223 } 224 msg, err := LoadMsg(bytes) 225 226 // If the ids match, return it 227 if msg.GetCorrelationId() == corrId { 228 return id, msg, err 229 } 230 231 // Otherwise, keep the message for later 232 self.incoming[msg.GetCorrelationId()] = &storedMsg{Id: id, Msg: msg} 233 } 234 } 235 236 // Close closes the wrapped socket. This should be called with defer() after opening the socket. 237 func (self *ZmqConnection) Close() { 238 self.socket.Close() 239 } 240 241 // Socket returns the wrapped socket. 242 func (self *ZmqConnection) Socket() *zmq.Socket { 243 return self.socket 244 } 245 246 // Create a new monitor socket pair and return the socket for listening 247 func (self *ZmqConnection) Monitor(events zmq.Event) (*zmq.Socket, error) { 248 endpoint := fmt.Sprintf("inproc://monitor.%v", self.identity) 249 err := self.socket.Monitor(endpoint, events) 250 if err != nil { 251 return nil, err 252 } 253 monitor, err := self.context.NewSocket(zmq.PAIR) 254 err = monitor.Connect(endpoint) 255 if err != nil { 256 return nil, err 257 } 258 259 return monitor, nil 260 } 261 262 // Identity returns the identity assigned to the wrapped socket. 263 func (self *ZmqConnection) Identity() string { 264 return self.identity 265 }