mirror of
https://github.com/gusaul/grpcox.git
synced 2024-12-25 09:50:10 +00:00
commit
b941d8727d
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
grpcox
|
grpcox
|
||||||
log
|
log
|
||||||
*.out
|
*.out
|
||||||
|
vendor/
|
||||||
|
.idea
|
|
@ -184,7 +184,7 @@ func (r *Resource) Describe(symbol string) (string, string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke - invoking gRPC function
|
// Invoke - invoking gRPC function
|
||||||
func (r *Resource) Invoke(ctx context.Context, symbol string, in io.Reader) (string, time.Duration, error) {
|
func (r *Resource) Invoke(ctx context.Context, metadata []string, symbol string, in io.Reader) (string, time.Duration, error) {
|
||||||
err := r.openDescriptor()
|
err := r.openDescriptor()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
|
@ -199,8 +199,13 @@ func (r *Resource) Invoke(ctx context.Context, symbol string, in io.Reader) (str
|
||||||
}
|
}
|
||||||
h := grpcurl.NewDefaultEventHandler(&resultBuffer, r.descSource, formatter, false)
|
h := grpcurl.NewDefaultEventHandler(&resultBuffer, r.descSource, formatter, false)
|
||||||
|
|
||||||
|
var headers = r.headers
|
||||||
|
if len(metadata) != 0 {
|
||||||
|
headers = metadata
|
||||||
|
}
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
err = grpcurl.InvokeRPC(ctx, r.descSource, r.clientConn, symbol, r.headers, h, rf.Next)
|
err = grpcurl.InvokeRPC(ctx, r.descSource, r.clientConn, symbol, headers, h, rf.Next)
|
||||||
end := time.Now().Sub(start) / time.Millisecond
|
end := time.Now().Sub(start) / time.Millisecond
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", end, err
|
return "", end, err
|
||||||
|
|
|
@ -221,8 +221,26 @@ func (h *Handler) invokeFunction(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// context metadata
|
||||||
|
metadataHeader := r.Header.Get("Metadata")
|
||||||
|
metadataArr := strings.Split(metadataHeader, ",")
|
||||||
|
|
||||||
|
// construct array of string with "key: value" form to satisfy grpcurl MetadataFromHeaders
|
||||||
|
var metadata []string
|
||||||
|
var metadataStr string
|
||||||
|
for i, m := range metadataArr {
|
||||||
|
i += 1
|
||||||
|
if isEven := i % 2 == 0; isEven {
|
||||||
|
metadataStr = metadataStr+m
|
||||||
|
metadata = append(metadata, metadataStr)
|
||||||
|
metadataStr = ""
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
metadataStr = fmt.Sprintf("%s:", m)
|
||||||
|
}
|
||||||
|
|
||||||
// get param
|
// get param
|
||||||
result, timer, err := res.Invoke(context.Background(), funcName, r.Body)
|
result, timer, err := res.Invoke(context.Background(), metadata, funcName, r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -47,6 +47,50 @@
|
||||||
<div class="proto-collection"></div>
|
<div class="proto-collection"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Context metadata -->
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="custom-control custom-checkbox">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="ctx-metadata-switch">
|
||||||
|
<label class="custom-control-label" for="ctx-metadata-switch">Use request metadata</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group" id="ctx-metadata-input" style="display: none">
|
||||||
|
<br>
|
||||||
|
<div id="ctx-metadata-table" class="table-editable">
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-start" style="width: 10%"></th>
|
||||||
|
<th class="text-start" style="width: 20%">Key</th>
|
||||||
|
<th class="text-start" style="width: 70%">Value</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span class="table-remove">
|
||||||
|
<button type="button" class="btn btn-danger btn-rounded btn-sm my-0">
|
||||||
|
<i class="fa fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="ctx-metadata-input-field pt-3-half" contenteditable="true"></td>
|
||||||
|
<td class="ctx-metadata-input-field pt-3-half" contenteditable="true"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<span class="table-add">
|
||||||
|
<button type="button" class="btn btn-success btn-rounded btn-sm my-0">
|
||||||
|
<i class="fa fa-plus"></i>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Context metadata -->
|
||||||
|
|
||||||
<div class="other-elem" id="choose-service" style="display: none">
|
<div class="other-elem" id="choose-service" style="display: none">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
|
@ -138,6 +182,7 @@
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ace.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ace.js"></script>
|
||||||
<script type="text/javascript" src="js/style.js"></script>
|
<script type="text/javascript" src="js/style.js"></script>
|
||||||
<script type="text/javascript" src="js/proto.js"></script>
|
<script type="text/javascript" src="js/proto.js"></script>
|
||||||
|
<script type="text/javascript" src="js/ctx.metadata.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
64
index/js/ctx.metadata.js
Normal file
64
index/js/ctx.metadata.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// table input for context metadata
|
||||||
|
const ctxMetadataTable = $('#ctx-metadata-table');
|
||||||
|
|
||||||
|
// new row for each context being added
|
||||||
|
const newTr = `
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span class="table-remove">
|
||||||
|
<button type="button" class="btn btn-danger btn-rounded btn-sm my-0">
|
||||||
|
<i class="fa fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="ctx-metadata-input-field pt-3-half" contenteditable="true"></td>
|
||||||
|
<td class="ctx-metadata-input-field pt-3-half" contenteditable="true"></td>
|
||||||
|
</tr>`;
|
||||||
|
|
||||||
|
// helper variable to contains all of the context metadata input
|
||||||
|
let ctxArr = [];
|
||||||
|
|
||||||
|
// helper variable to contain the usage of metadata
|
||||||
|
let ctxUse = false;
|
||||||
|
|
||||||
|
// ctx metadata event listener
|
||||||
|
(function () {
|
||||||
|
// add event listener on ctx metadata checkbox
|
||||||
|
const ctxMetadataSwitch = document.getElementById("ctx-metadata-switch");
|
||||||
|
ctxMetadataSwitch.addEventListener("change", function(event) {
|
||||||
|
const { checked } = event.target;
|
||||||
|
ctxUse = checked;
|
||||||
|
toggleDisplayCtxMetadataTable(checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove for each row in ctx metadata table
|
||||||
|
ctxMetadataTable.on('click', '.table-remove', function () {
|
||||||
|
$(this).parents('tr').detach();
|
||||||
|
});
|
||||||
|
|
||||||
|
// add new row
|
||||||
|
ctxMetadataTable.on('click', '.table-add', () => {
|
||||||
|
$('tbody').append(newTr);
|
||||||
|
});
|
||||||
|
|
||||||
|
// only allow any paste action with plain text
|
||||||
|
ctxMetadataTable.on('paste', '.ctx-metadata-input-field', function (e) {
|
||||||
|
// cancel paste
|
||||||
|
e.preventDefault();
|
||||||
|
// get text representation of clipboard
|
||||||
|
const text = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||||
|
// insert text manually
|
||||||
|
document.execCommand("insertHTML", false, text);
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
// toggle ctx metadata display
|
||||||
|
// will show the key-value pairs table input
|
||||||
|
function toggleDisplayCtxMetadataTable(show) {
|
||||||
|
const style = show ? "display: block" : "display: none";
|
||||||
|
|
||||||
|
const protoInput = document.getElementById("ctx-metadata-input");
|
||||||
|
protoInput.removeAttribute("style");
|
||||||
|
protoInput.style.cssText = style;
|
||||||
|
}
|
|
@ -135,6 +135,13 @@ $('#select-function').change(function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#invoke-func').click(function(){
|
$('#invoke-func').click(function(){
|
||||||
|
|
||||||
|
// use metadata if there is any
|
||||||
|
ctxArr = [];
|
||||||
|
$(".ctx-metadata-input-field").each(function(index, val){
|
||||||
|
ctxArr.push($(val).text())
|
||||||
|
});
|
||||||
|
|
||||||
var func = $('#select-function').val();
|
var func = $('#select-function').val();
|
||||||
if (func == "") {
|
if (func == "") {
|
||||||
return false;
|
return false;
|
||||||
|
@ -160,6 +167,9 @@ $('#invoke-func').click(function(){
|
||||||
beforeSend: function(xhr){
|
beforeSend: function(xhr){
|
||||||
$('#response').hide();
|
$('#response').hide();
|
||||||
xhr.setRequestHeader('use_tls', use_tls);
|
xhr.setRequestHeader('use_tls', use_tls);
|
||||||
|
if(ctxUse) {
|
||||||
|
xhr.setRequestHeader('Metadata', ctxArr);
|
||||||
|
}
|
||||||
$(this).html("Loading...");
|
$(this).html("Loading...");
|
||||||
show_loading();
|
show_loading();
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user