Forráskód Böngészése

operator:set-metadata

Leszek Wiesner 3 éve
szülő
commit
5d96865a69

+ 1 - 1
distributor-node/package.json

@@ -81,7 +81,7 @@
     "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme",
     "test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"",
     "version": "oclif-dev readme && git add README.md",
-    "generate:types:json-schema": "yarn ts-node ./src/validation/generateTypes.ts",
+    "generate:types:json-schema": "yarn ts-node ./src/services/validation/generateTypes.ts",
     "generate:types:graphql": "yarn graphql-codegen -c ./src/services/networking/query-node/codegen.yml",
     "generate:types:openapi": "yarn openapi-typescript ./src/api-spec/openapi.yml -o ./src/types/generated/OpenApi.ts -c ../prettierrc.js",
     "generate:types:all": "yarn generate:types:json-schema && yarn generate:types:graphql && yarn generate:types:openapi",

+ 12 - 0
distributor-node/scripts/example-metadata.json

@@ -0,0 +1,12 @@
+{
+  "endpoint": "http://localhost:3334",
+  "location": {
+    "countryCode": "DE",
+    "city": "Berlin",
+    "coordinates": {
+      "latitude": 52.520008,
+      "longitude": 13.404954
+    }
+  },
+  "extra": "Some additional information"
+}

+ 1 - 0
distributor-node/scripts/test-commands.sh

@@ -20,6 +20,7 @@ ${CLI} leader:invite-bucket-operator -f ${FAMILY_ID} -B ${BUCKET_ID} -w 0
 ${CLI} leader:cancel-invitation -f ${FAMILY_ID} -B ${BUCKET_ID} -w 0
 ${CLI} leader:invite-bucket-operator -f ${FAMILY_ID} -B ${BUCKET_ID} -w 0
 ${CLI} operator:accept-invitation -f ${FAMILY_ID} -B ${BUCKET_ID} -w 0
+${CLI} operator:set-metadata -f ${FAMILY_ID} -B ${BUCKET_ID} -w 0 -i ./example-metadata.json
 
 # Deletion commands tested separately, since bucket operator removal is not yet supported
 FAMILY_TO_DELETE_ID=`${CLI} leader:create-bucket-family ${CONFIG}`

+ 2 - 2
distributor-node/src/command-base/default.ts

@@ -68,8 +68,8 @@ export default abstract class DefaultCommandBase extends Command {
     this.autoConfirm = !!(process.env.AUTO_CONFIRM === 'true' || parseInt(process.env.AUTO_CONFIRM || '') || yes)
   }
 
-  public log(message: string, meta?: unknown[]): void {
-    this.logger.info(message, meta)
+  public log(message: string, ...meta: unknown[]): void {
+    this.logger.info(message, ...meta)
   }
 
   public output(value: unknown): void {

+ 61 - 0
distributor-node/src/commands/operator/set-metadata.ts

@@ -0,0 +1,61 @@
+import fs from 'fs'
+import AccountsCommandBase from '../../command-base/accounts'
+import DefaultCommandBase, { flags } from '../../command-base/default'
+import { ValidationService } from '../../services/validation/ValidationService'
+import { DistributionBucketOperatorMetadata, IDistributionBucketOperatorMetadata } from '@joystream/metadata-protobuf'
+
+export default class OperatorSetMetadata extends AccountsCommandBase {
+  static description = `Set/update distribution bucket operator metadata.
+  Requires active distribution bucket operator worker role key.`
+
+  static flags = {
+    bucketId: flags.integer({
+      char: 'B',
+      description: 'Distribution bucket id',
+      required: true,
+    }),
+    familyId: flags.integer({
+      char: 'f',
+      description: 'Distribution bucket family id',
+      required: true,
+    }),
+    workerId: flags.integer({
+      char: 'w',
+      description: 'ID of the invited operator (distribution group worker)',
+      required: true,
+    }),
+    endpoint: flags.string({
+      char: 'e',
+      description: 'Root distribution node endpoint',
+      exclusive: ['input'],
+    }),
+    input: flags.string({
+      char: 'i',
+      description: 'Path to JSON metadata file',
+      exclusive: ['endpoint'],
+    }),
+    ...DefaultCommandBase.flags,
+  }
+
+  async run(): Promise<void> {
+    const { bucketId, familyId, workerId, input, endpoint } = this.parse(OperatorSetMetadata).flags
+    const workerKey = await this.getDistributorWorkerRoleKey(workerId)
+
+    const validation = new ValidationService()
+    const metadata: IDistributionBucketOperatorMetadata = input
+      ? validation.validate('OperatorMetadata', JSON.parse(fs.readFileSync(input).toString()))
+      : { endpoint }
+
+    this.log(`Setting bucket operator metadata (bucket: ${bucketId}, worker: ${workerId})...`, metadata)
+    await this.sendAndFollowTx(
+      await this.getDecodedPair(workerKey),
+      this.api.tx.storage.setDistributionOperatorMetadata(
+        workerId,
+        familyId,
+        bucketId,
+        '0x' + Buffer.from(DistributionBucketOperatorMetadata.encode(metadata).finish()).toString('hex')
+      )
+    )
+    this.log('Bucket operator metadata succesfully set/updated!')
+  }
+}

+ 6 - 1
distributor-node/src/services/logging/LoggingService.ts

@@ -42,8 +42,13 @@ export class LoggingService {
 
     const format = winston.format.combine(
       winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:ms' }),
+      winston.format.metadata({ fillExcept: ['label', 'level', 'timestamp', 'message'] }),
       winston.format.colorize({ all: true }),
-      winston.format.printf((info) => `${info.timestamp} ${info.label} ${info.level}: ${info.message}`)
+      winston.format.printf(
+        (info) =>
+          `${info.timestamp} ${info.label} ${info.level}: ${info.message}` +
+          (Object.keys(info.metadata).length ? `\n${JSON.stringify(info.metadata, null, 4)}` : '')
+      )
     )
     return new LoggingService({
       transports: new winston.transports.Console({

+ 2 - 2
distributor-node/src/services/validation/ValidationService.ts

@@ -17,7 +17,7 @@ export class ValidationService {
     this.ajv = new Ajv({ allErrors: true, schemas })
   }
 
-  validate(schemaKey: SchemaKey, input: unknown): TypeBySchemaKey<SchemaKey> {
+  validate<SK extends SchemaKey>(schemaKey: SK, input: unknown): TypeBySchemaKey<SK> {
     const valid = this.ajv.validate(schemaKey, input) as boolean
     if (!valid) {
       throw new ValidationError(
@@ -25,6 +25,6 @@ export class ValidationService {
         this.ajv.errors?.map((e) => `${e.instancePath}: ${e.message} (${JSON.stringify(e.params)})`) || []
       )
     }
-    return input as TypeBySchemaKey<SchemaKey>
+    return input as TypeBySchemaKey<SK>
   }
 }

+ 5 - 3
distributor-node/src/services/validation/generateTypes.ts

@@ -6,6 +6,8 @@ import { schemas } from './schemas'
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const prettierConfig = require('@joystream/prettier-config')
 
-compile(schemas.Config, 'ConfigJson', { style: prettierConfig }).then((output) =>
-  fs.writeFileSync(path.resolve(__dirname, '../../types/generated/ConfigJson.d.ts'), output)
-)
+Object.entries(schemas).forEach(([schemaKey, schema]) => {
+  compile(schema, `${schemaKey}Json`, { style: prettierConfig }).then((output) =>
+    fs.writeFileSync(path.resolve(__dirname, `../../types/generated/${schemaKey}Json.d.ts`), output)
+  )
+})

+ 8 - 1
distributor-node/src/services/validation/schemas/index.ts

@@ -1,12 +1,19 @@
 import { ConfigJson } from '../../../types/generated/ConfigJson'
+import { OperatorMetadataJson } from '../../../types/generated/OperatorMetadataJson'
 import { configSchema } from './configSchema'
+import { operatorMetadataSchema } from './operatorMetadataSchema'
 
 export const schemas = {
   Config: configSchema,
+  OperatorMetadata: operatorMetadataSchema,
 } as const
 
 export type SchemaKey = keyof typeof schemas & string
 
-export type TypeBySchemaKey<T extends SchemaKey> = T extends 'Config' ? ConfigJson : never
+export type TypeBySchemaKey<T extends SchemaKey> = T extends 'Config'
+  ? ConfigJson
+  : T extends 'OperatorMetadata'
+  ? OperatorMetadataJson
+  : never
 
 export default schemas

+ 25 - 0
distributor-node/src/services/validation/schemas/operatorMetadataSchema.ts

@@ -0,0 +1,25 @@
+import { JSONSchema4 } from 'json-schema'
+import { strictObject } from './utils'
+
+export const operatorMetadataSchema: JSONSchema4 = {
+  type: 'object',
+  additionalProperties: false,
+  properties: {
+    endpoint: { type: 'string' },
+    location: {
+      type: 'object',
+      additionalProperties: false,
+      properties: {
+        countryCode: { type: 'string' },
+        city: { type: 'string' },
+        coordinates: strictObject({
+          latitude: { type: 'number' },
+          longitude: { type: 'number' },
+        }),
+      },
+    },
+    extra: { type: 'string' },
+  },
+}
+
+export default operatorMetadataSchema

+ 0 - 2
distributor-node/src/types/generated/ConfigJson.d.ts

@@ -18,10 +18,8 @@ export interface ConfigJson {
   log?: {
     file?: 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly'
     console?: 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly'
-    [k: string]: unknown
   }
   port: number
   keys: [string, ...string[]]
   buckets: [number, ...number[]]
-  [k: string]: unknown
 }

+ 19 - 0
distributor-node/src/types/generated/OperatorMetadataJson.d.ts

@@ -0,0 +1,19 @@
+/* tslint:disable */
+/**
+ * This file was automatically generated by json-schema-to-typescript.
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
+ * and run json-schema-to-typescript to regenerate this file.
+ */
+
+export interface OperatorMetadataJson {
+  endpoint?: string
+  location?: {
+    countryCode?: string
+    city?: string
+    coordinates?: {
+      latitude: number
+      longitude: number
+    }
+  }
+  extra?: string
+}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 18 - 547
yarn.lock


Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott