How to transport data from router folder to utils files In Nodejs using Turnilo library

43 views Asked by At

Turnilo library

queryRouter is a function which routes the route to specific controller. under this there is router.use() which act as middleware for route, here i`m receiving the req params from the client side.

Project Structure screenshot

   import { NextFunction, Request, Response, Router } from "express";
import { Logger } from "../../../common/logger/logger";
import { QueryableDataCube } from "../../../common/models/data-cube/queryable-data-cube";
import { Essence } from "../../../common/models/essence/essence";
import { Timekeeper } from "../../../common/models/timekeeper/timekeeper";
import {
  DEFAULT_VIEW_DEFINITION_VERSION,
  definitionConverters,
} from "../../../common/view-definitions";
import { createEssence } from "../../utils/essence/create-essence";
import { asyncHandler } from "../../utils/express/async-handler";
import {
  AppliedQueryDecorator,
  getQueryDecorator,
} from "../../utils/query-decorator-loader/get-query-decorator";
import { handleRequestErrors } from "../../utils/request-errors/handle-request-errors";
import { parseDataCube } from "../../utils/request-params/parse-data-cube";
import { parseViewDefinition } from "../../utils/request-params/parse-view-definition";
import { SettingsManager } from "../../utils/settings-manager/settings-manager";
import booleanFilterRoute from "./routes/boolean-filter";
import numberFilterRoute from "./routes/number-filter";
import pinboardRoute from "./routes/pinboard";
import rawDataRoute from "./routes/raw-data";
import stringFilterRoute from "./routes/string-filter";
import visualizationRoute from "./routes/visualization";

const converter = definitionConverters[DEFAULT_VIEW_DEFINITION_VERSION];

interface QueryRouterContext {
  dataCube: QueryableDataCube;
  essence: Essence;
  decorator: AppliedQueryDecorator;
  timekeeper: Timekeeper;
  logger: Logger;
  headers: any; // Add the headers property
}

export type QueryRouterRequest = Request & {
  context?: QueryRouterContext;
};

export function queryRouter(
  settings: Pick<
    SettingsManager,
    "logger" | "getSources" | "appSettings" | "anchorPath" | "getTimekeeper"
  >
) {
  // console.log('ClusterManager', ClusterManager);
  const logger = settings.logger;

  const router = Router();

  router.use(
    asyncHandler(async (req: Request, res: Response, next: NextFunction) => {
      console.log("req===================================", req.headers);
      //  headers = req.headers;
      const dataCube = await parseDataCube(req, settings);
      const viewDefinition = parseViewDefinition(req);
      const essence = createEssence(
        viewDefinition,
        converter,
        dataCube,
        settings.appSettings
      );
      const decorator = getQueryDecorator(req, dataCube, settings);

      (req as QueryRouterRequest).context = {
        logger,
        dataCube,
        essence,
        decorator,
        timekeeper: settings.getTimekeeper(),
        headers: req.headers,
      };

      next();
    })
  );

  router.post("/visualization", asyncHandler(visualizationRoute));

  router.post("/raw-data", asyncHandler(rawDataRoute));

  router.post("/boolean-filter", asyncHandler(booleanFilterRoute));

  router.post("/string-filter", asyncHandler(stringFilterRoute));

  router.post("/number-filter", asyncHandler(numberFilterRoute));

  router.post("/pinboard", asyncHandler(pinboardRoute));

  router.use(
    (error: Error, req: Request, res: Response, next: NextFunction) => {
      handleRequestErrors(error, res, logger);
    }
  );

  return router;
}



//I need to transport req.headers data to utils folder under clustermanager file

import { External } from "plywood";
import { PlywoodRequester } from "plywood-base-api";
import {
  DecoratorRequest,
  DruidRequestDecorator,
} from "plywood-druid-requester";
import { Logger } from "../../../common/logger/logger";
import {
  Cluster,
  makeExternalFromSourceName,
  shouldScanSources,
} from "../../../common/models/cluster/cluster";
import { constant, noop } from "../../../common/utils/functional/functional";
import { isNil } from "../../../common/utils/general/general";
import { loadModule } from "../module-loader/module-loader";
import { DruidRequestDecoratorModule } from "../request-decorator/request-decorator";
import { properRequesterFactory } from "../requester/requester";
import { QueryRouterRequest } from "../../routes/query/query";

const CONNECTION_RETRY_TIMEOUT = 20000;
const DRUID_REQUEST_DECORATOR_MODULE_VERSION = 1;

// For each external we want to maintain its source and whether it should introspect at all
export interface ManagedExternal {
  name: string;
  external: External;
  autoDiscovered?: boolean;
  suppressIntrospection?: boolean;
}

export interface ClusterManagerOptions {
  logger: Logger;
  verbose?: boolean;
  anchorPath: string;
  initialExternals?: ManagedExternal[];
  onExternalChange?: (name: string, external: External) => Promise<void>;
  onExternalRemoved?: (name: string, external: External) => Promise<void>;
  generateExternalName?: (external: External) => string;
}

function emptyResolve(): Promise<void> {
  return Promise.resolve(null);
}

function getSourceFromExternal(external: External): string {
  return String(external.source);
}

function externalContainsSource(external: External, source: string): boolean {
  return Array.isArray(external.source)
    ? external.source.indexOf(source) > -1
    : String(external.source) === source;
}

export class ClusterManager {
  public logger: Logger;
  public verbose: boolean;
  public anchorPath: string;
  public cluster: Cluster;
  public initialConnectionEstablished: boolean;
  public introspectedSources: Record<string, boolean>;
  public version: string;
  public managedExternals: ManagedExternal[] = [];
  public onExternalChange: (name: string, external: External) => Promise<void>;
  public onExternalRemoved: (name: string, external: External) => Promise<void>;
  public generateExternalName: (external: External) => string;

  private requester: PlywoodRequester<any>;
  private sourceListRefreshInterval = 0;
  private sourceListRefreshTimer: NodeJS.Timer = null;
  private sourceReintrospectInterval = 0;
  private sourceReintrospectTimer: NodeJS.Timer = null;

  private initialConnectionTimer: NodeJS.Timer = null;

  public headers: any;

  constructor(cluster: Cluster, options: ClusterManagerOptions) {
    if (!cluster) throw new Error("must have cluster");
    this.logger = options.logger;
    this.verbose = Boolean(options.verbose);
    this.anchorPath = options.anchorPath;
    this.cluster = cluster;
    this.initialConnectionEstablished = false;
    this.introspectedSources = {};
    this.version = cluster.version;
    this.managedExternals = options.initialExternals || [];
    this.onExternalChange = options.onExternalChange || emptyResolve;
    this.onExternalRemoved = options.onExternalRemoved || emptyResolve;
    this.generateExternalName =
      options.generateExternalName || getSourceFromExternal;
    this.requester = this.initRequester();
    this.someMethod = this.someMethod;

    this.managedExternals.forEach((managedExternal) => {
      managedExternal.external = managedExternal.external.attachRequester(
        this.requester
      );
    });
  }

  // Do initialization
  public init(): Promise<void> {
    const { cluster, logger } = this;

    if (cluster.sourceListRefreshOnLoad) {
      logger.log(`Cluster '${cluster.name}' will refresh source list on load`);
    }

    if (cluster.sourceReintrospectOnLoad) {
      logger.log(`Cluster '${cluster.name}' will reintrospect sources on load`);
    }

    return this.establishInitialConnection()
      .then(() => this.introspectSources())
      .then(() => this.scanSourceList());
  }

  public destroy() {
    if (this.sourceListRefreshTimer) {
      clearInterval(this.sourceListRefreshTimer);
      this.sourceListRefreshTimer = null;
    }
    if (this.sourceReintrospectTimer) {
      clearInterval(this.sourceReintrospectTimer);
      this.sourceReintrospectTimer = null;
    }
    if (this.initialConnectionTimer) {
      clearTimeout(this.initialConnectionTimer);
      this.initialConnectionTimer = null;
    }
  }

  private addManagedExternal(managedExternal: ManagedExternal): Promise<void> {
    this.managedExternals.push(managedExternal);
    return this.onExternalChange(
      managedExternal.name,
      managedExternal.external
    );
  }

  private updateManagedExternal(
    managedExternal: ManagedExternal,
    newExternal: External
  ): Promise<void> {
    if (managedExternal.external.equals(newExternal)) return null;
    managedExternal.external = newExternal;
    return this.onExternalChange(
      managedExternal.name,
      managedExternal.external
    );
  }

  private removeManagedExternal(
    managedExternal: ManagedExternal
  ): Promise<void> {
    this.managedExternals = this.managedExternals.filter(
      (ext) => ext.external !== managedExternal.external
    );
    return this.onExternalRemoved(
      managedExternal.name,
      managedExternal.external
    );
  }

  private initRequester(): PlywoodRequester<any> {
    const { cluster } = this;
    const druidRequestDecorator = this.createDruidRequestDecorator();

    return properRequesterFactory({
      cluster,
      verbose: this.verbose,
      concurrentLimit: 5,
      druidRequestDecorator,
    });
  }

  private clusterAuthHeaders(): Record<"Authorization", string> | undefined {
    const { auth } = this.cluster;
    console.log("auth", this.cluster);
    if (isNil(auth)) return undefined;
    switch (auth.type) {
      case "http-basic": {
        const credentials = `${auth.username}:${auth.password}`;
        const Authorization = `Basic ${Buffer.from(credentials).toString(
          "base64"
        )}`;
        return { Authorization };
      }
    }
  }

file structure image

0

There are 0 answers