grpc-zpages: link channelz.js with angular compiler (#306)

Rather than importing the script with a <script> tag, use angular's
build system to import the script. This makes our HTML consistent
internally and externally, and is probably the way to go if we want to
use the library in unit tests.
This commit is contained in:
zpencer 2018-08-08 08:57:09 -07:00 committed by GitHub
parent a9fa4c674b
commit 851a674d9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 31 additions and 23 deletions

View File

@ -29,4 +29,4 @@ docker build -t channelz_codegen codegen
exec docker run --rm -v "$GRPC_ZPAGES_DIR"/docker/codegen/shared_dir:/shared_dir/ channelz_codegen bash -c "function fixFiles() { chown -R $(id -u):$(id -g) /shared_dir; }; trap fixFiles EXIT; /shared_dir/scripts/gen_channelz_pb.sh $GRPC_PROTO_SHA"
mv "$GRPC_ZPAGES_DIR"/docker/codegen/shared_dir/gen_out/channelz.js "$GRPC_ZPAGES_DIR"/web/channelzui/src/assets/channelz.js
mv "$GRPC_ZPAGES_DIR"/docker/codegen/shared_dir/gen_out/channelz.js "$GRPC_ZPAGES_DIR"/web/channelzui/src/generated/channelz.js

View File

@ -23,7 +23,7 @@
"styles": [
"src/styles.css"
],
"scripts": []
"scripts": ["src/generated/channelz.js"]
},
"configurations": {
"production": {

View File

@ -20,7 +20,6 @@ import { AppRoutingModule } from './app-routing.module';
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { ServersComponent } from './servers/servers.component';
import { SocketComponent } from './socket/socket.component';
@ -52,7 +51,6 @@ import { TopChannelsComponent } from './top-channels/top-channels.component';
BrowserModule,
CommonModule,
FormsModule,
HttpClientModule,
],
providers: [ChannelzService],
bootstrap: [AppComponent]

View File

@ -15,15 +15,16 @@
* limitations under the License.
*/
import { Injectable } from "@angular/core";
import { Injectable, Optional } from "@angular/core";
import { Observable } from "rxjs";
import { HttpClient } from "@angular/common/http";
import { environment } from "../environments/environment";
// goog and proto are symbols provided by grpc generated code
// In OSS, the grpc generated code is imported from a standalone .js file
// When building with angular CLI in OSS:
// The standalone channelz.js file provides a proto symbol with the
// client and message types. goog.require() is effectively a noop.
// When building with closure compiler:
// goog.require() imports the client and message libraries
declare var goog: any;
declare var proto: any;
goog.require('proto.grpc.channelz.v1.ChannelzClient');
goog.require('proto.grpc.channelz.v1.GetChannelRequest');
goog.require('proto.grpc.channelz.v1.GetServerSocketsRequest');
@ -31,29 +32,34 @@ goog.require('proto.grpc.channelz.v1.GetServersRequest');
goog.require('proto.grpc.channelz.v1.GetSocketRequest');
goog.require('proto.grpc.channelz.v1.GetSubchannelRequest');
goog.require('proto.grpc.channelz.v1.GetTopChannelsRequest');
declare var proto: any;
@Injectable()
export class ChannelzService {
xsrfMeta: {};
client: any;
constructor(private http: HttpClient) {
// Because this class is @Injectable, angular takes care of DI for parameters.
// This means we can not provide a default parameter value.
// The parameter is either injected or it is null.
constructor(@Optional() private grpcRemoteAddr:string) {
this.xsrfMeta = ChannelzService.genXsrfMeta();
this.client = new proto.grpc.channelz.v1.ChannelzClient(
grpcRemoteAddr == null ? environment.grpcRemoteAddr : grpcRemoteAddr);
}
private static genXsrfMeta(): any {
const arr = new Int8Array(32); // 256 bits of entropy
window.crypto.getRandomValues(arr);
const xsrfVal = btoa(arr.toString());
document.cookie = `grpc-channelz-v1-channelz-token=${xsrfVal};path=/`;
this.xsrfMeta = {"grpc-channelz-v1-channelz-token": xsrfVal};
return {"grpc-channelz-v1-channelz-token": xsrfVal};
}
// window.location.origin is the reverse proxy that both serves the
// app and performs grpc-web translation
private client = new proto.grpc.channelz.v1.ChannelzClient(
environment.grpcRemoteAddr);
private functionToObserver(rpcMethod: any, req: any): Observable<any> {
return new Observable(observer => {
// To pass a method around as a parameter, the method must be bound
// to an instance of the object. In this case it is the client.
// To use a method passed around as a parameter, the method must be bound
// to an instance of the object.
rpcMethod.bind(this.client)(req, this.xsrfMeta, function(err, response) {
observer.next(response);
observer.complete();

View File

@ -17,14 +17,17 @@
import { Pipe, PipeTransform } from '@angular/core';
// goog and proto are symbols provided by grpc generated code
// In OSS, the grpc generated code is imported from a standalone .js file
// When building with angular CLI in OSS:
// The standalone channelz.js file provides a proto symbol with the
// client and message types. goog.require() is effectively a noop.
// When building with closure compiler:
// goog.require() imports the client and message libraries
declare var goog: any;
declare var proto: any;
goog.require('proto.grpc.channelz.v1.SocketOptionLinger');
goog.require('proto.grpc.channelz.v1.SocketOptionTimeout');
goog.require('proto.grpc.channelz.v1.SocketOptionTcpInfo');
goog.require('proto.grpc.channelz.v1.ChannelConnectivityState.State');
declare var proto: any;
const protoAnyToStringHelpers = {
'type.googleapis.com/grpc.channelz.v1.SocketOptionLinger': (protoAny: any) => {

View File

@ -5,5 +5,7 @@
export const environment = {
production: false,
// window.location.origin is the reverse proxy that both serves the
// app and performs grpc-web translation
grpcRemoteAddr: window.location.origin,
};

View File

@ -7,7 +7,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<script src="./assets/channelz.js" type="text/javascript"/>
<body>
<app-root></app-root>
</body>