github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/pehrest/hash-delete-key.go (about)

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