Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SwaggerApi.js 13.01 KiB
import React from "react";
import SwaggerClient from 'swagger-client';
import { createContext, useContext, useEffect, useState } from "react";
import { CircularProgress } from '@material-ui/core';
import { useHistory } from 'react-router';
import { useCustomSnackbar } from '../components/common/snackbar/Snackbar';

const SERVER = `${process.env.REACT_APP_SERVER_ADDRESS}`; // current domain

const createSwaggerClient = async () => {
  const swaggerOptions = {
    url: `${SERVER}${process.env.REACT_APP_API_BASE_ENDPOINT}`,
    requestInterceptor: (req) => {
      // if (user) req.headers["Authorization"] = `Bearer ${user.token}`;
      req.headers['Content-Type'] = 'application/json';
      req.headers['accept'] = 'application/json';
      window.req = req;
      console.log(req);
      return req;
    },
    responseInterceptor: (res) => {
      // console.log(res);
      return res;
    }
  };

  const swagger = await SwaggerClient(swaggerOptions)
  // update the server url to be our intended server
  swagger.spec.servers[0].url = SERVER;
  window.swagger = swagger;
  return swagger;
}

export function useAPI() {
  console.log(`inside useAPI, server URL: ${SERVER}/ccce-api`);
  return useAsync({ fcn: createSwaggerClient });
}

export const apiContext = createContext(null);
export const userContext = createContext({ user: null, login: ()=>{}, logout: ()=>{} });

export function UserProvider({ children }) {
  const [user, setUser] = useState();
  const [userInfo, getUserInfo] = useUserInfo();
  const [isLoggedIn, loginFcn] = useLogin();
  const logoutFcn = useLogout();
  const history = useHistory();

  console.log("rendering UserProvider")
  console.log(user);

  useEffect(getUserInfo, [isLoggedIn, getUserInfo]);
  useEffect(() => userInfo && setUser(userInfo), [setUser, userInfo]);

  const logout = async () => {
    console.log("Logging out!")
    setUser(null);
    logoutFcn();
  }

  const login = async (username, password) => {
    console.log("Logging in!");
    await loginFcn(username, password);
    setUser(await getUserInfo());
    console.log(history);
  }

  return (
    <userContext.Provider value={{ user, login, logout }}>
      {children}
    </userContext.Provider>
  );
}

export function APIProvider({ children }) {
  console.log("about to call useAPI")
  const [api] = useAPI();

  console.log(api, api?.requestInterceptor)

  return api ?
    (
      <apiContext.Provider value={api}>
        {children}
      </apiContext.Provider>
    ) :
    <CircularProgress />;
}

export function useAPIErrorHandler() {
  const {logout} = useContext(userContext);
  const showError = useCustomSnackbar();

  function errorHandler(e) {
    const { response, message } = e;
    const { obj, status } = (response ?? {obj: {}, status: ""});
    if (status === 401) {
      logout();
    }
    else {
      showError(obj?.description ?? message);
    }
  }

  return errorHandler;
}

export function useAsync({ fcn, call = true, init = null, onError = null }) {
  const [response, setResponse] = useState(init);
  const errorHandler = useAPIErrorHandler();

  const f = async (...args) => {
    try {
      const r = await fcn(...args);
      console.log(r);
      setResponse(r);
    } catch (e) {
      console.warn(e);
      errorHandler(e);
    }
  };

  const [wrapper] = useState(() => f);
  useEffect(() => {
    if (call) wrapper();
  }, [wrapper, call]);
  return [response, wrapper];
}

function callAndUnpack(fcn, unpacker = x => x) {
  return async (...args) => {
    console.log(...args);
    const response = await fcn(...args);
    const unpacked = unpacker(response.obj);
    return unpacked;
  };
}

export function unpackIOC(ioc) {
  console.log(ioc);
  ioc = { ...ioc };
  const { id, description, owner, createdBy, active, configuredToHost, latestVersion, activeDeployment } = ioc;
  const deployedVersion = activeDeployment ? activeDeployment.version : null;

  let inflated = null;
  if (latestVersion) inflated = latestVersion;
  if (deployedVersion) inflated = deployedVersion;

  let unpackedIOC = {
    id: id,
    description: description,
    owner: owner,
    createdBy: createdBy,
    latestVersion: latestVersion,
    activeDeployment: activeDeployment,
    deployedVersion: deployedVersion,
    latestHost: configuredToHost,
    active: active,
    status: configuredToHost ? configuredToHost.status : null,
  };

  if (unpackedIOC.latestHost) unpackedIOC.host = unpackedIOC.latestHost.host;
  if (unpackedIOC.activeDeployment) unpackedIOC.host = unpackedIOC.activeDeployment.host.host;

  if (inflated) {
    const getSubset = (v) => {
      return { 
        git: v.sourceUrl,
        version: v.sourceVersion, 
        namingName: v.namingName,
        epicsVersion: v.epicsVersion,
        requireVersion: v.requireVersion }
    };
    const subset = getSubset(inflated);
    unpackedIOC = Object.assign(unpackedIOC, subset);
  }

  return unpackedIOC;
}

export function unpackIOCList(iocs) {
  console.log(iocs);
  return iocs.iocList.map((ioc) => unpackIOC(ioc));
}

export function useIOCList() {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.IOCs.listIocs, unpackIOCList);
  return useAsync({ fcn: method, init: [] });
}

export function useIOCSearch() {
  const api = useContext(apiContext);
  const method = callAndUnpack(
    (query) => api.apis.IOCs.listIocs({ query: query }),
    unpackIOCList
  );
  return useAsync({ fcn: method, call: false, init: [] });
}

export function useIOC(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.IOCs.getIoc, unpackIOC);
  return useAsync({ fcn: method.bind(null, { iocId: id }) });
}

export function useCreateIOC() {
  const api = useContext(apiContext);
  const method = callAndUnpack(
    body => api.apis.IOCs.createIoc({}, { requestBody: body }),
    unpackIOC
  );
  return useAsync({ fcn: method, call: false });
}

export function useUpdateIOC(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(
    body => api.apis.IOCs.updateIoc({ iocId: id }, { requestBody: body }),
    unpackIOC
  );
  return useAsync({ fcn: method, call: false });
}

export function unpackDeployment(deployment) {
  const d = { ...deployment };
  console.log(d);
  return d;
}

export function unpackDeploymentList(deployments) {
  console.log(deployments);
  return deployments.deployments.map(d => unpackDeployment(d));
}

export function useDeploymentList() {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Deployments.listDeployments, unpackDeploymentList)
  return useAsync({ fcn: method, init: [] });
}

export function useDeploymentSearch() {
  const api = useContext(apiContext);
  const method = callAndUnpack(
    (query) => api.apis.Deployments.listDeployments({ query: query }),
    unpackDeploymentList
  );
  return useAsync({ fcn: method, call: false, init: [] });
}

export function useDeployment(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Deployments.fetchDeployment, unpackDeployment)
  return useAsync({ fcn: method.bind(null, { deploymentId: id }) });
}

export function useDeploymentById() {
  const api = useContext(apiContext);
  const method = callAndUnpack(
    (deploymentId) => api.apis.Deployments.fetchDeployment({ deploymentId: deploymentId }),
    unpackDeployment
  );
  return useAsync({ fcn: method, call: false, init: null });
}

export function unpackDeploymentJob(job) {
  return { ...job };
}

export function useDeploymentJob(awxJobId) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Deployments.fetchDeploymentJobDetails, unpackDeploymentJob)
  return useAsync({ fcn: method.bind(null, { awxJobId: awxJobId }), call: false });
}

export function useCreateDeployment() {
  const api = useContext(apiContext);
  const method = callAndUnpack(
    (iocs, comment = "") => api.apis.Deployments.createDeployment({}, { requestBody: { iocIds: iocs.map((ioc) => ioc.id), comment: comment } }),
    unpackDeployment
  );
  return useAsync({ fcn: method, call: false });
}

export function unpackHost(host) {
  return { ...host };
}

export function unpackHostList(hosts) {
  return hosts.csEntryHosts.map(h => unpackHost(h));
}

export function useHostList() {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Hosts.listHosts, unpackHostList)
  return useAsync({ fcn: method, init: [] });
}

export function useHost(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Hosts.findHostById, unpackHost)
  return useAsync({ fcn: method.bind(null, { hostCSEntryId: id }) });
}

export function useAvailableHost(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Hosts.hostDetail, unpackHost)
  return useAsync({ fcn: method.bind(null, { hostId: id }) });
}

export function unpackCSEntryHost(host) {
  return { ...host };
}

export function unpackCSEntryHostList(hosts) {
  return hosts.csEntryHosts.map(h => unpackCSEntryHost(h));
}

export function useCSEntrySearch() {
  const api = useContext(apiContext);
  const method = callAndUnpack(
    (query) => api.apis.Hosts.listHosts({ query: query }),
    unpackCSEntryHostList
  );
  return useAsync({ fcn: method, call: false, init: [] });
}

export function unpackHostIOCList(iocs) {
  console.log({ ...iocs });
  const deployed = iocs.deployedIocs.map(ioc => unpackIOC(ioc))
  const undeployed = iocs.configuredIocs.map(ioc => unpackIOC(ioc));
  const result = { deployed, undeployed };
  return result;
}

export function useHostIOCList(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Hosts.findAssociatedIocsByHosId, unpackHostIOCList)
  return useAsync({ fcn: method.bind(null, { hostCSEntryId: id }), init: { deployed: [], undeployed: [] } });
}

export function unpackLogin(loginResponse) {
  console.log(loginResponse)
  const isLoggedIn = Boolean(loginResponse);
  return isLoggedIn;
}

export function useLogin() {
  const api = useContext(apiContext);
  const callLogin = (u, p) => api.apis.Authentication.login({}, {
    requestBody: {
      userName: u,
      password: p
    }
  });
  const method = callAndUnpack(callLogin, unpackLogin)
  return useAsync({ fcn: method, call: false })
}

export function unpackUser(user) {
  return { ...user };
}

export function useUserInfo() {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Git.userInfo, unpackUser);
  return useAsync({ fcn: method, call: false });
}

export function useLogout() {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Authentication.logout);
  const [, logout] = useAsync({ fcn: method, call: false });
  return logout;
}

export function useStartIOC(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Deployments.startIoc);
  const [, startIOC] = useAsync({ fcn: method.bind(null, {iocId: id}), call: false });
  return startIOC;
}

export function useStopIOC(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Deployments.stopIoc);
  const [, stopIOC] = useAsync({ fcn: method.bind(null, {iocId: id}), call: false });
  return stopIOC;
}

export function useRestartIOC(id) {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Deployments.restartIoc);
  const [, restartIOC] = useAsync({ fcn: method.bind(null, {iocId: id}), call: false });
  return restartIOC;
}

export function useIOCService(id) {
  console.log(id);
  const startIOC = useStartIOC(id);
  const stopIOC = useStopIOC(id);
  const restartIOC = useRestartIOC(id);
  return { startIOC, stopIOC, restartIOC };
}

export function useRenewToken() {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Authentication.tokenRenew);

  const [, renewToken] = useAsync({ fcn: method, call: false });
  return renewToken;
}

export function unpackLokilog(logData) {
  console.log(logData);
  return { ...logData };
}

export function useLokiSysLog() {
  const api = useContext(apiContext);
  const method = callAndUnpack((hostName, timeRange) => api.apis.Loki.fetchSyslogLines({ hostName: hostName, timeRange: timeRange }), unpackLokilog)
  return useAsync({ fcn: method, call: false });
}


export function useLokiProcServLog() {
  const api = useContext(apiContext);
  const method = callAndUnpack((hostName, iocName, timeRange) => api.apis.Loki.fetchProcServLogLines({ hostName: hostName, iocName:iocName, timeRange: timeRange }), unpackLokilog)

  return useAsync({ fcn: method, call: false });
}

export function unpackStatistics(statistics) {
  return { ...statistics };
}

export function useStatistics() {
  const api = useContext(apiContext);
  const method = callAndUnpack(api.apis.Statistics.generalStatistics, unpackStatistics)

  return useAsync({ fcn: method, call: false });
}

export function unpackNaming(naming) {
  return { ...naming };
}

export function unpackNamingList(naming) {
  return naming.map(h => unpackNaming(h));
}

export function useNamingNames() {
  const api = useContext(apiContext);
  const method = callAndUnpack((iocName) => api.apis.Naming.fetchIOCByName({iocName: iocName}), unpackNamingList)

  return useAsync({ fcn: method, call: false, init: [] });
}