Skip to content

Commit

Permalink
feat(js-sdk): Impl Binding API
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Nov 3, 2021
1 parent 08905cf commit 963fbb8
Show file tree
Hide file tree
Showing 25 changed files with 245 additions and 104 deletions.
7 changes: 7 additions & 0 deletions configs/config_integration_redis_etcd.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@
"hello": "greeting"
}
},
"bindings": {
"http": {
"metadata": {
"url": "https://registry.npmmirror.com/layotto/0.0.0"
}
}
},
"config_stores": {
"etcd": {
"address": [
Expand Down
1 change: 1 addition & 0 deletions sdk/js-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"ts-node": "^10.3.0",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
"type-fest": "^2.5.2",
"typescript": "^4.4.4"
},
"dependencies": {
Expand Down
6 changes: 3 additions & 3 deletions sdk/js-sdk/src/client/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
*/
import { Metadata } from '@grpc/grpc-js';
import { RuntimeClient } from '../../proto/runtime_grpc_pb';
import { KVString, RequestWithMeta, Map } from '../types/common';
import { KV, RequestWithMeta, Map } from '../types/common';

export class API {
readonly runtime: RuntimeClient;
constructor(runtime: RuntimeClient) {
this.runtime = runtime;
}

createMetadata(request: RequestWithMeta): Metadata {
createMetadata(request: RequestWithMeta<{}>): Metadata {
const metadata = new Metadata();
if (!request.requestMeta) return metadata;
for (const key of Object.keys(request.requestMeta)) {
Expand All @@ -31,7 +31,7 @@ export class API {
return metadata;
}

mergeMetadataToMap(map: Map<string>, ...metadatas: (KVString | undefined)[]) {
mergeMetadataToMap(map: Map<string>, ...metadatas: (KV<string> | undefined)[]) {
for (const metadata of metadatas) {
if (!metadata) continue;
for (const key of Object.keys(metadata)) {
Expand Down
48 changes: 48 additions & 0 deletions sdk/js-sdk/src/client/Binding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2021 Layotto Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
InvokeBindingRequest as InvokeBindingRequestPB,
InvokeBindingResponse as InvokeBindingResponsePB,
} from '../../proto/runtime_pb';
import { API } from './API';
import {
InvokeBindingRequest,
InvokeBindingResponse,
} from '../types/Binding';
import { convertMapToKVString } from '../utils';

export default class Binding extends API {
async invoke(request: InvokeBindingRequest): Promise<InvokeBindingResponse> {
const req = new InvokeBindingRequestPB();
req.setName(request.name);
req.setOperation(request.operation);
if (typeof request.data === 'string') {
req.setData(Buffer.from(request.data, 'utf8'));
} else {
req.setData(request.data);
}
this.mergeMetadataToMap(req.getMetadataMap(), request.metadata);

return new Promise((resolve, reject) => {
this.runtime.invokeBinding(req, this.createMetadata(request), (err, res: InvokeBindingResponsePB) => {
if (err) return reject(err);
resolve({
data: res.getData_asU8(),
metadata: convertMapToKVString(res.getMetadataMap()),
});
});
});
}
}
11 changes: 9 additions & 2 deletions sdk/js-sdk/src/client/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Sequencer from './Sequencer';
import Configuration from './Configuration';
import PubSub from './PubSub';
import File from './File';
import Binding from './Binding';

const debug = debuglog('layotto:client:main');

Expand All @@ -38,9 +39,10 @@ export default class Client {
private _configuration: Configuration;
private _pubsub: PubSub;
private _file: File;
private _binding: Binding;

constructor(port: string = process.env.runtime_GRPC_PORT || '34904',
host: string = process.env.runtime_GRPC_HOST || '127.0.0.1') {
constructor(port: string = process.env.runtime_GRPC_PORT ?? '34904',
host: string = process.env.runtime_GRPC_HOST ?? '127.0.0.1') {
this.host = host;
this.port = port;
const clientCredentials = ChannelCredentials.createInsecure();
Expand Down Expand Up @@ -87,4 +89,9 @@ export default class Client {
if (!this._file) this._file = new File(this._runtime);
return this._file;
}

get binding() {
if (!this._binding) this._binding = new Binding(this._runtime);
return this._binding;
}
}
4 changes: 1 addition & 3 deletions sdk/js-sdk/src/client/File.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { strict as assert } from 'assert';
import { debuglog } from 'node:util';
import { Transform, Readable } from 'stream';
import { pipeline as pipelinePromise } from 'stream/promises';
Expand Down Expand Up @@ -51,8 +50,7 @@ export default class File extends API {
}

async put(request: PutFileRequest): Promise<void> {
assert(request.stream || request.data, 'Parameters "stream" or "data" was required at least one');
const stream = request.stream || Readable.from(request.data);
const stream = request.stream ?? Readable.from(request.data);

const ac = new AbortController();
const signal = ac.signal;
Expand Down
2 changes: 1 addition & 1 deletion sdk/js-sdk/src/client/Hello.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class Hello extends API {
async sayHello(request?: SayHelloRequest): Promise<string> {
const req = new SayHelloRequestPB();
if (!request) request = {};
req.setServiceName(request.serviceName || 'helloworld');
req.setServiceName(request.serviceName ?? 'helloworld');
if (request.name) req.setName(request.name);

return new Promise((resolve, reject) => {
Expand Down
8 changes: 5 additions & 3 deletions sdk/js-sdk/src/client/Invoker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,25 @@ export default class Invoker extends API {
const message = new CommonInvokeRequestPB();
message.setMethod(request.method);

const httpVerb = request.httpVerb || HTTPExtension.Verb.GET;
const httpVerb = request.httpVerb ?? HTTPExtension.Verb.GET;
const httpExtension = new HTTPExtension();
httpExtension.setVerb(httpVerb);
message.setHttpExtension(httpExtension);

if (request.data) {
const dataSerialized = new Any();
if (typeof request.data === 'string') {
message.setContentType('text/plain; charset=UTF-8');
message.setContentType(request.contentType ?? 'text/plain; charset=UTF-8');
dataSerialized.setValue(Buffer.from(request.data, 'utf8'));
} else {
message.setContentType('application/json');
message.setContentType(request.contentType ?? 'application/json');
dataSerialized.setValue(Buffer.from(JSON.stringify(request.data), 'utf8'));
}
message.setData(dataSerialized);
}

console.log(message);

const req = new InvokeServiceRequestPB();
req.setId(request.id);
req.setMessage(message);
Expand Down
8 changes: 5 additions & 3 deletions sdk/js-sdk/src/client/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
Etag as EtagPB,
StateOptions as StateOptionsPB,
GetStateRequest as GetStateRequestPB,
GetStateResponse as GetStateResponsePB,
GetBulkStateRequest as GetBulkStateRequestPB,
DeleteStateRequest as DeleteStateRequestPB,
DeleteBulkStateRequest as DeleteBulkStateRequestPB,
Expand All @@ -36,7 +37,7 @@ import {
SaveStateRequest,
StateItem,
} from '../types/State';
import { isEmptyPBMessage } from '../utils';
import { isEmptyPBMessage, convertMapToKVString } from '../utils';

export default class State extends API {
// Saves an array of state objects
Expand Down Expand Up @@ -66,7 +67,7 @@ export default class State extends API {
this.mergeMetadataToMap(req.getMetadataMap(), request.metadata);

return new Promise((resolve, reject) => {
this.runtime.getState(req, this.createMetadata(request), (err, res) => {
this.runtime.getState(req, this.createMetadata(request), (err, res: GetStateResponsePB) => {
if (err) return reject(err);
if (isEmptyPBMessage(res)) {
return resolve(null);
Expand All @@ -75,6 +76,7 @@ export default class State extends API {
key: request.key,
value: res.getData_asU8(),
etag: res.getEtag(),
metadata: convertMapToKVString(res.getMetadataMap()),
});
});
});
Expand Down Expand Up @@ -102,7 +104,7 @@ export default class State extends API {
key: item.getKey(),
value: item.getData_asU8(),
etag: item.getEtag(),
// metadata: item.getMetadataMap(),
metadata: convertMapToKVString(item.getMetadataMap()),
});
}
resolve(states);
Expand Down
2 changes: 1 addition & 1 deletion sdk/js-sdk/src/server/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class Server {
private readonly _serverImpl: GRPCServerImpl;
private readonly _server: GRPCServer;

constructor(port: string = process.env.appcallback_GRPC_PORT || '9999') {
constructor(port: string = process.env.appcallback_GRPC_PORT ?? '9999') {
this.port = port;
this._serverImpl = new GRPCServerImpl();
this.pubsub = new PubSub(this._serverImpl);
Expand Down
13 changes: 13 additions & 0 deletions sdk/js-sdk/src/types/Binding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { KV, RequestWithMeta } from './common';

export type InvokeBindingRequest = RequestWithMeta<{
name: string,
data: Uint8Array | string,
metadata: KV<string>
operation: string,
}>;

export type InvokeBindingResponse = {
data: Uint8Array,
metadata: KV<string>
};
34 changes: 17 additions & 17 deletions sdk/js-sdk/src/types/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,59 +12,59 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { KVString, RequestWithMeta } from './common';
import { KV, RequestWithMeta } from './common';

export type GetConfigurationRequest = {
export type GetConfigurationRequest = RequestWithMeta<{
storeName: string;
appId: string;
keys: string[];
group?: string;
label?: string;
subscribeUpdate?: boolean;
metadata?: KVString;
} & RequestWithMeta;
metadata?: KV<string>;
}>;

export type GetConfigurationItem = {
key: string;
content: string;
group: string;
label: string;
tags: KVString;
metadata: KVString;
tags: KV<string>;
metadata: KV<string>;
};

export type SaveConfigurationItem = {
key: string,
content: string,
group?: string,
label?: string,
tags?: KVString,
metadata?: KVString,
tags?: KV<string>,
metadata?: KV<string>,
};

export type SaveConfigurationRequest = {
export type SaveConfigurationRequest = RequestWithMeta<{
storeName: string;
appId: string;
items: SaveConfigurationItem[];
metadata?: KVString;
} & RequestWithMeta;
metadata?: KV<string>;
}>;

export type DeleteConfigurationRequest = {
export type DeleteConfigurationRequest = RequestWithMeta<{
storeName: string;
appId: string;
keys: string[];
group?: string;
label?: string;
metadata?: KVString;
} & RequestWithMeta;
metadata?: KV<string>;
}>;

export type SubscribeConfigurationRequest = {
export type SubscribeConfigurationRequest = RequestWithMeta<{
storeName: string;
appId: string;
keys: string[];
group?: string;
label?: string;
metadata?: KVString;
metadata?: KV<string>;
onData(items: GetConfigurationItem[]): void;
onClose(err?: Error): void;
} & RequestWithMeta;
}>;
15 changes: 8 additions & 7 deletions sdk/js-sdk/src/types/File.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { Readable } from 'stream';
import { KVString, RequestWithMeta, RequireOnlyOne } from './common';
import { RequireExactlyOne } from 'type-fest';
import { KV, RequestWithMeta } from './common';

export type GetFileRequest = {
export type GetFileRequest = RequestWithMeta<{
storeName: string;
name: string;
metadata?: KVString;
} & RequestWithMeta;
metadata?: KV<string>;
}>;

export type PutFileRequest = RequireOnlyOne<{
export type PutFileRequest = RequestWithMeta<RequireExactlyOne<{
storeName: string;
name: string;
stream?: Readable,
data?: Uint8Array,
metadata?: KVString;
}, 'stream' | 'data'> & RequestWithMeta;
metadata?: KV<string>;
}, 'stream' | 'data'>>;

export type ListFileResponse = {
names: string[];
Expand Down
4 changes: 2 additions & 2 deletions sdk/js-sdk/src/types/Hello.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { RequestWithMeta } from './common';

export type SayHelloRequest = {
export type SayHelloRequest = RequestWithMeta<{
serviceName?: string;
name?: string;
} & RequestWithMeta;
}>;
5 changes: 3 additions & 2 deletions sdk/js-sdk/src/types/Invoker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
import { HTTPExtension } from '../../proto/runtime_pb';
import { RequestWithMeta } from './common';

export type InvokeServiceRequest = {
export type InvokeServiceRequest = RequestWithMeta<{
id: string;
method: string;
httpVerb?: HTTPExtension.Verb;
data?: string | object;
} & RequestWithMeta;
contentType?: string,
}>;

export type InvokeResponse = {
contentType: string;
Expand Down
Loading

0 comments on commit 963fbb8

Please sign in to comment.