github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/pehrest/hash-delete-value.go (about)

     1  /* For license and copyright information please see LEGAL file in repository */
     2  
     3  package pehrest
     4  
     5  import (
     6  	"../authorization"
     7  	"../ganjine"
     8  	"../protocol"
     9  	"../srpc"
    10  	"../syllab"
    11  )
    12  
    13  // HashDeleteValueService store details about HashDeleteValue service
    14  var HashDeleteValueService = service.Service{
    15  	URN:                "urn:giti:index.protocol:service:has-delete-value",
    16  	Domain:             DomainName,
    17  	ID:                 4811402533981149999,
    18  	IssueDate:          1587282740,
    19  	ExpiryDate:         0,
    20  	ExpireInFavorOfURN: "",
    21  	ExpireInFavorOfID:  0,
    22  	Status:             protocol.Software_PreAlpha,
    23  
    24  	Authorization: authorization.Service{
    25  		CRUD:     authorization.CRUDDelete,
    26  		UserType: protocol.UserType_App,
    27  	},
    28  
    29  	Detail: map[protocol.LanguageID]service.ServiceDetail{
    30  		protocol.LanguageEnglish: {
    31  			Name:        "Index Hash - Delete Value",
    32  			Description: "Delete the value from exiting index hash key",
    33  			TAGS:        []string{},
    34  		},
    35  	},
    36  
    37  	SRPCHandler: HashDeleteValueSRPC,
    38  }
    39  
    40  // HashDeleteValue delete the value from exiting index key
    41  func HashDeleteValue(req *HashDeleteValueReq) (err protocol.Error) {
    42  	var node protocol.ApplicationNode
    43  	node, err = protocol.App.GetNodeByStorage(req.MediaTypeID, req.IndexKey)
    44  	if err != nil {
    45  		return
    46  	}
    47  
    48  	if node.Node.State == protocol.ApplicationState_LocalNode {
    49  		return HashDeleteValue(req)
    50  	}
    51  
    52  	var st protocol.Stream
    53  	st, err = node.Conn.MakeOutcomeStream(0)
    54  	if err != nil {
    55  		return
    56  	}
    57  
    58  	st.Service = &HashDeleteValueService
    59  	st.OutcomePayload = req.ToSyllab()
    60  
    61  	err = node.Conn.Send(st)
    62  	if err != nil {
    63  		return
    64  	}
    65  	return
    66  }
    67  
    68  // HashDeleteValueSRPC is sRPC handler of HashDeleteValue service.
    69  func HashDeleteValueSRPC(st protocol.Stream) {
    70  	if st.Connection.UserID != protocol.OS.AppManifest().AppUUID() {
    71  		// TODO::: Attack??
    72  		err = authorization.ErrUserNotAllow
    73  		return
    74  	}
    75  
    76  	var req = &HashDeleteValueReq{}
    77  	req.FromSyllab(srpc.GetPayload(st.IncomePayload))
    78  
    79  	err = HashDeleteValue(req)
    80  	st.OutcomePayload = make([]byte, srpc.MinLength)
    81  }
    82  
    83  // HashDeleteValueReq is request structure of HashDeleteValue()
    84  type HashDeleteValueReq struct {
    85  	Type       ganjine.RequestType
    86  	IndexKey   [32]byte
    87  	IndexValue [32]byte
    88  }
    89  
    90  // HashDeleteValue delete the value from exiting index key
    91  func HashDeleteValue(req *HashDeleteValueReq) (err protocol.Error) {
    92  	if req.Type == ganjine.RequestTypeBroadcast {
    93  		// tell other node that this node handle request and don't send this request to other nodes!
    94  		req.Type = ganjine.RequestTypeStandalone
    95  		var reqEncoded = req.ToSyllab()
    96  
    97  		// send request to other related nodes
    98  		for i := 1; i < len(ganjine.Cluster.Replications.Zones); i++ {
    99  			var conn = ganjine.Cluster.Replications.Zones[i].Nodes[ganjine.Cluster.Node.ID].Conn
   100  			var st protocol.Stream
   101  			st, err = conn.MakeOutcomeStream(0)
   102  			if err != nil {
   103  				// TODO::: Can we easily return error if two nodes did their job and not have enough resource to send request to final node??
   104  				return
   105  			}
   106  
   107  			st.Service = &service.Service{ID: 4811402533981149999}
   108  			st.OutcomePayload = reqEncoded
   109  
   110  			err = conn.Send(st)
   111  			if err != nil {
   112  				// TODO::: Can we easily return error if two nodes do their job and just one node connection lost??
   113  				return
   114  			}
   115  
   116  			// TODO::: Can we easily return response error without handle some known situations??
   117  			err = err
   118  		}
   119  	}
   120  
   121  	// Do for i=0 as local node
   122  	var hashIndex = IndexHash{
   123  		RecordID: req.IndexKey,
   124  	}
   125  	err = hashIndex.Delete(req.IndexValue)
   126  	return
   127  }
   128  
   129  /*
   130  	-- Syllab Encoder & Decoder --
   131  */
   132  
   133  // FromSyllab decode from buf to req
   134  // Due to this service just use internally, It skip check buf size syllab rule! Panic occur if bad request received!
   135  func (req *HashDeleteValueReq) FromSyllab(payload []byte, stackIndex uint32) {
   136  	req.Type = ganjine.RequestType(syllab.GetUInt8(buf, 0))
   137  	copy(req.IndexKey[:], buf[1:])
   138  	copy(req.IndexValue[:], buf[33:])
   139  	return
   140  }
   141  
   142  // ToSyllab encode req to buf
   143  func (req *HashDeleteValueReq) ToSyllab(payload []byte, stackIndex, heapIndex uint32) (freeHeapIndex uint32) {
   144  	buf = make([]byte, req.LenAsSyllab()+4) // +4 for sRPC ID instead get offset argument
   145  	syllab.SetUInt8(buf, 4, uint8(req.Type))
   146  	copy(buf[5:], req.IndexKey[:])
   147  	copy(buf[37:], req.IndexValue[:])
   148  	return
   149  }
   150  
   151  func (req *HashDeleteValueReq) LenOfSyllabStack() uint32 {
   152  	return 65
   153  }
   154  
   155  func (req *HashDeleteValueReq) LenOfSyllabHeap() (ln uint32) {
   156  	return
   157  }
   158  
   159  func (req *HashDeleteValueReq) LenAsSyllab() uint64 {
   160  	return uint64(req.LenOfSyllabStack() + req.LenOfSyllabHeap())
   161  }