blob: c91ef2d0a86b60f6067decc2b8f58f661bf99c6d [file] [log] [blame]
<!--
Copyright 2016 The LUCI Authors. All rights reserved.
Use of this source code is governed under the Apache License, Version 2.0
that can be found in the LICENSE file.
-->
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/google-signin/google-signin-aware.html">
<link rel="import" href="../rpc/rpc-client.html">
<link rel="import" href="rpc-descriptor-util.html">
<link rel="import" href="rpc-editor.html">
<!-- The `rpc-method` is a service method page -->
<dom-module id="rpc-method">
<template>
<style>
rpc-editor {
height: 300px;
}
button {
margin: 5px;
}
</style>
<div on-keypress="_onKeypress">
<rpc-client
id="client"
service="[[service]]"
method="[[method]]"
request="[[requestObject]]"
on-response="_onCallComplete"
on-error="_onCallComplete">
</rpc-client>
<div>[[methodDesc.sourceCodeInfo.leadingComments]]</div>
<hr>
<p>Request:</p>
<div class="row">
<div class="col-md-7">
<rpc-editor value="{{requestText}}"
description="[[description]]"
root-type-name="[[requestTypeName]]"></rpc-editor>
</div>
<div class="col-md-3">
<p>Ctrl+Space for Autocomplete</p>
<p>Shift+Enter for Send</p>
</div>
</div>
<div>
<button on-tap="send">Send</button>
</div>
<div class="alert alert-danger" role="alert" hidden="[[!error]]">
<template is="dom-if" if="[[error.isGrpcError]]">
<div>
Code: [[error.code]]
<template is="dom-if" if="[[error.codeName]]">
([[error.codeName]])
</template>
</div>
<div>Description: [[error.description]]</div>
</template>
<template is="dom-if" if="[[!error.isGrpcError]]">
[[error]]
</template>
</div>
<div class="row">
<div class="col-md-7">
<rpc-editor value="[[responseText]]"></rpc-editor>
</div>
</div>
</div>
</template>
<script>
'use strict';
Polymer({
is: 'rpc-method',
properties: {
/** @type {FileDescriptorSet} */
description: Object,
service: String,
method: String,
/** @type {MethodDescriptorProto} */
methodDesc: {
type: Object,
computed: '_resolveMethod(description, service, method)'
},
requestTypeName: {
type: String,
computed: '_getRequestTypeName(methodDesc)'
},
/** "request" query string parameter. */
request: {
type: String,
value: '{}',
observer: '_onRequestChanged',
notify: true
},
/** Request editor text. */
requestText: String,
/** Parsed from requestText. */
requestObject: Object,
/** Response editor text. */
responseText: String,
error: {
type: Object,
value: null
}
},
_resolveMethod: function(desc, service, method) {
if (!desc || !service || !method) {
return null;
}
var methodDesc = rpcExplorer.descUtil.resolve(
desc, service + '.' + method);
return methodDesc && methodDesc.type === 'method' && methodDesc.desc;
},
_getRequestTypeName: function(methodDesc) {
return (methodDesc &&
rpcExplorer.descUtil.trimPrefixDot(methodDesc.inputType));
},
_onRequestChanged: function() {
try {
this.requestObject = JSON.parse(this.request);
} catch (e) {
console.error('Invalid request: ' + this.request);
this.requestText = this.request;
return;
}
// Reformat the request read from query string parameter
// because it gets corrupted there.
this.requestText = JSON.stringify(this.requestObject, null, 4);
},
_onKeypress: function(e) {
if (e.key === 'Enter' && e.shiftKey) {
this.send();
e.preventDefault();
}
},
getAccessToken: function() {
var user = gapi.auth2.getAuthInstance().currentUser.get();
if (!user) {
return null;
}
return user.getAuthResponse().access_token;
},
send: function() {
this.error = null;
try {
this.requestObject = JSON.parse(this.requestText);
// Reformat request
this.requestText = JSON.stringify(this.requestObject, null, 4);
// Update URL without a refresh.
history.replaceState(
history.state, document.title, "?request=" + this.requestText);
this.$.client.accessToken = this.getAccessToken();
// Actually send the request.
this.$.client.call();
} catch (e) {
this.error = e;
console.error(this.error)
}
},
_onCallComplete: function() {
var client = this.$.client;
if (client.lastError) {
console.error(client.lastError);
}
if (client.lastResponse) {
this.responseText = JSON.stringify(client.lastResponse, null, 4);
} else {
this.responseText = '';
}
this.error = client.lastError;
if (this.error instanceof luci.rpc.GrpcError) {
this.error = {
isGrpcError: true,
code: this.error.code,
codeName: luci.rpc.CodeName(this.error.code),
description: this.error.description
};
}
}
});
</script>
</dom-module>