github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/events/producer/handler.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 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 package producer 18 19 import ( 20 "fmt" 21 "strconv" 22 23 pb "github.com/hyperledger/fabric/protos/peer" 24 ) 25 26 type handler struct { 27 ChatStream pb.Events_ChatServer 28 interestedEvents map[string]*pb.Interest 29 } 30 31 func newEventHandler(stream pb.Events_ChatServer) (*handler, error) { 32 d := &handler{ 33 ChatStream: stream, 34 } 35 d.interestedEvents = make(map[string]*pb.Interest) 36 return d, nil 37 } 38 39 // Stop stops this handler 40 func (d *handler) Stop() error { 41 d.deregisterAll() 42 d.interestedEvents = nil 43 return nil 44 } 45 46 func getInterestKey(interest pb.Interest) string { 47 var key string 48 switch interest.EventType { 49 case pb.EventType_BLOCK: 50 key = "/" + strconv.Itoa(int(pb.EventType_BLOCK)) 51 case pb.EventType_REJECTION: 52 key = "/" + strconv.Itoa(int(pb.EventType_REJECTION)) 53 case pb.EventType_CHAINCODE: 54 key = "/" + strconv.Itoa(int(pb.EventType_CHAINCODE)) + "/" + interest.GetChaincodeRegInfo().ChaincodeId + "/" + interest.GetChaincodeRegInfo().EventName 55 default: 56 producerLogger.Errorf("unknown interest type %s", interest.EventType) 57 } 58 return key 59 } 60 61 func (d *handler) register(iMsg []*pb.Interest) error { 62 // Could consider passing interest array to registerHandler 63 // and only lock once for entire array here 64 for _, v := range iMsg { 65 if err := registerHandler(v, d); err != nil { 66 producerLogger.Errorf("could not register %s: %s", v, err) 67 continue 68 } 69 d.interestedEvents[getInterestKey(*v)] = v 70 } 71 72 return nil 73 } 74 75 func (d *handler) deregister(iMsg []*pb.Interest) error { 76 for _, v := range iMsg { 77 if err := deRegisterHandler(v, d); err != nil { 78 producerLogger.Errorf("could not deregister %s", v) 79 continue 80 } 81 delete(d.interestedEvents, getInterestKey(*v)) 82 } 83 return nil 84 } 85 86 func (d *handler) deregisterAll() { 87 for k, v := range d.interestedEvents { 88 if err := deRegisterHandler(v, d); err != nil { 89 producerLogger.Errorf("could not deregister %s", v) 90 continue 91 } 92 delete(d.interestedEvents, k) 93 } 94 } 95 96 // HandleMessage handles the Openchain messages for the Peer. 97 func (d *handler) HandleMessage(msg *pb.Event) error { 98 //producerLogger.Debug("Handling Event") 99 switch msg.Event.(type) { 100 case *pb.Event_Register: 101 eventsObj := msg.GetRegister() 102 if err := d.register(eventsObj.Events); err != nil { 103 return fmt.Errorf("Could not register events %s", err) 104 } 105 case *pb.Event_Unregister: 106 eventsObj := msg.GetUnregister() 107 if err := d.deregister(eventsObj.Events); err != nil { 108 return fmt.Errorf("Could not unregister events %s", err) 109 } 110 case nil: 111 default: 112 return fmt.Errorf("Invalide type from client %T", msg.Event) 113 } 114 //TODO return supported events.. for now just return the received msg 115 if err := d.ChatStream.Send(msg); err != nil { 116 return fmt.Errorf("Error sending response to %v: %s", msg, err) 117 } 118 119 return nil 120 } 121 122 // SendMessage sends a message to the remote PEER through the stream 123 func (d *handler) SendMessage(msg *pb.Event) error { 124 err := d.ChatStream.Send(msg) 125 if err != nil { 126 return fmt.Errorf("Error Sending message through ChatStream: %s", err) 127 } 128 return nil 129 }