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  }