Просмотр исходного кода

refactor: reorganize POST /g2g-transfer

mizozobu 3 лет назад
Родитель
Сommit
a1b6bbb8de

+ 5 - 52
packages/app/src/server/routes/apiv3/g2g-transfer.ts

@@ -6,9 +6,8 @@ import express, { NextFunction, Request, Router } from 'express';
 import { body } from 'express-validator';
 import { body } from 'express-validator';
 import multer from 'multer';
 import multer from 'multer';
 
 
-import GrowiArchiveImportOption from '~/models/admin/growi-archive-import-option';
 import { isG2GTransferError } from '~/server/models/vo/g2g-transfer-error';
 import { isG2GTransferError } from '~/server/models/vo/g2g-transfer-error';
-import { IDataGROWIInfo, uploadConfigKeys, X_GROWI_TRANSFER_KEY_HEADER_NAME } from '~/server/service/g2g-transfer';
+import { IDataGROWIInfo, X_GROWI_TRANSFER_KEY_HEADER_NAME } from '~/server/service/g2g-transfer';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 import { TransferKey } from '~/utils/vo/transfer-key';
 import { TransferKey } from '~/utils/vo/transfer-key';
 
 
@@ -16,7 +15,6 @@ import { TransferKey } from '~/utils/vo/transfer-key';
 import Crowi from '../../crowi';
 import Crowi from '../../crowi';
 import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';
 import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';
 
 
-import { generateOverwriteParams } from './import';
 import { ApiV3Response } from './interfaces/apiv3-response';
 import { ApiV3Response } from './interfaces/apiv3-response';
 
 
 interface AuthorizedRequest extends Request {
 interface AuthorizedRequest extends Request {
@@ -196,66 +194,21 @@ module.exports = (crowi: Crowi): Router => {
     /*
     /*
      * generate maps of ImportSettings to import
      * generate maps of ImportSettings to import
      */
      */
-    const importSettingsMap = {};
+    let importSettingsMap;
     try {
     try {
-      innerFileStats.forEach(({ fileName, collectionName }) => {
-        const options = new GrowiArchiveImportOption(null, optionsMap[collectionName]);
-
-        if (collectionName === 'configs' && options.mode !== 'flushAndInsert') {
-          throw new Error('`flushAndInsert` is only available as an import setting for configs collection');
-        }
-        if (collectionName === 'pages' && options.mode === 'insert') {
-          throw new Error('`insert` is not available as an import setting for pages collection');
-        }
-        if (collectionName === 'attachmentFiles.chunks') {
-          throw new Error('`attachmentFiles.chunks` must not be transferred. Please omit it from request body `collections`.');
-        }
-        if (collectionName === 'attachmentFiles.files') {
-          throw new Error('`attachmentFiles.files` must not be transferred. Please omit it from request body `collections`.');
-        }
-
-        const importSettings = importService.generateImportSettings(options.mode);
-        importSettings.jsonFileName = fileName;
-        importSettings.overwriteParams = generateOverwriteParams(collectionName, operatorUserId, options);
-        importSettingsMap[collectionName] = importSettings;
-      });
+      importSettingsMap = g2gTransferReceiverService.getImportSettingMap(innerFileStats, optionsMap, operatorUserId);
     }
     }
     catch (err) {
     catch (err) {
       logger.error(err);
       logger.error(err);
       return res.apiv3Err(new ErrorV3('Import settings invalid. See growi docs about details.', 'import_settings_invalid'));
       return res.apiv3Err(new ErrorV3('Import settings invalid. See growi docs about details.', 'import_settings_invalid'));
     }
     }
 
 
-    /*
-     * import collections
-     */
     try {
     try {
-      const shouldKeepUploadConfigs = configManager.getConfig('crowi', 'app:fileUploadType') !== 'none';
-
-      let savedUploadConfigs;
-      if (shouldKeepUploadConfigs) {
-        // save
-        savedUploadConfigs = Object.fromEntries(uploadConfigKeys.map((key) => {
-          return [key, configManager.getConfigFromDB('crowi', key)];
-        }));
-      }
-
-      await importService.import(collections, importSettingsMap);
-
-      // remove & save if none
-      if (shouldKeepUploadConfigs) {
-        await configManager.removeConfigsInTheSameNamespace('crowi', uploadConfigKeys);
-        await configManager.updateConfigsInTheSameNamespace('crowi', savedUploadConfigs);
-      }
-      else {
-        await configManager.updateConfigsInTheSameNamespace('crowi', sourceGROWIUploadConfigs);
-      }
-
-      await crowi?.setUpFileUpload(true);
-      await crowi?.appService?.setupAfterInstall();
+      await g2gTransferReceiverService.importCollections(collections, importSettingsMap, sourceGROWIUploadConfigs);
     }
     }
     catch (err) {
     catch (err) {
       logger.error(err);
       logger.error(err);
-      return res.apiv3Err(new ErrorV3('Failed to import.', 'failed_to_import'), 500);
+      return res.apiv3Err(new ErrorV3('Failed to import MongoDB collections', 'mongo_collection_import_failure'), 500);
     }
     }
 
 
     return res.apiv3({ message: 'Successfully started to receive transfer data.' });
     return res.apiv3({ message: 'Successfully started to receive transfer data.' });

+ 1 - 4
packages/app/src/server/routes/apiv3/overwrite-params/pages.js

@@ -8,10 +8,6 @@ const ImportOptionForPages = require('~/models/admin/import-option-for-pages');
 
 
 const { ObjectId } = mongoose.Types;
 const { ObjectId } = mongoose.Types;
 
 
-const {
-  GRANT_PUBLIC,
-} = mongoose.model('Page');
-
 class PageOverwriteParamsFactory {
 class PageOverwriteParamsFactory {
 
 
   /**
   /**
@@ -23,6 +19,7 @@ class PageOverwriteParamsFactory {
    *  value: any value or a function `(value, { document, schema, propertyName }) => { return newValue }`
    *  value: any value or a function `(value, { document, schema, propertyName }) => { return newValue }`
    */
    */
   static generate(operatorUserId, option) {
   static generate(operatorUserId, option) {
+    const { GRANT_PUBLIC } = mongoose.model('Page');
     const params = {};
     const params = {};
 
 
     if (option.isOverwriteAuthorWithCurrentUser) {
     if (option.isOverwriteAuthorWithCurrentUser) {

+ 59 - 1
packages/app/src/server/service/g2g-transfer.ts

@@ -8,7 +8,9 @@ import FormData from 'form-data';
 import { Types as MongooseTypes } from 'mongoose';
 import { Types as MongooseTypes } from 'mongoose';
 
 
 import { G2G_PROGRESS_STATUS } from '~/interfaces/g2g-transfer';
 import { G2G_PROGRESS_STATUS } from '~/interfaces/g2g-transfer';
+import GrowiArchiveImportOption from '~/models/admin/growi-archive-import-option';
 import TransferKeyModel from '~/server/models/transfer-key';
 import TransferKeyModel from '~/server/models/transfer-key';
+import { generateOverwriteParams } from '~/server/routes/apiv3/import';
 import { createBatchStream } from '~/server/util/batch-stream';
 import { createBatchStream } from '~/server/util/batch-stream';
 import axios from '~/utils/axios';
 import axios from '~/utils/axios';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -20,7 +22,7 @@ const logger = loggerFactory('growi:service:g2g-transfer');
 
 
 export const X_GROWI_TRANSFER_KEY_HEADER_NAME = 'x-growi-transfer-key';
 export const X_GROWI_TRANSFER_KEY_HEADER_NAME = 'x-growi-transfer-key';
 
 
-export const uploadConfigKeys = [
+const uploadConfigKeys = [
   'app:fileUploadType',
   'app:fileUploadType',
   'app:useOnlyEnvVarForFileUploadType',
   'app:useOnlyEnvVarForFileUploadType',
   'aws:referenceFileWithRelayMode',
   'aws:referenceFileWithRelayMode',
@@ -491,6 +493,62 @@ export class G2GTransferReceiverService implements Receiver {
     return tkd.keyString;
     return tkd.keyString;
   }
   }
 
 
+  public getImportSettingMap(innerFileStats, optionsMap, operatorUserId) {
+    const { importService } = this.crowi;
+
+    const importSettingsMap = {};
+    innerFileStats.forEach(({ fileName, collectionName }) => {
+      const options = new GrowiArchiveImportOption(null, optionsMap[collectionName]);
+
+      if (collectionName === 'configs' && options.mode !== 'flushAndInsert') {
+        throw new Error('`flushAndInsert` is only available as an import setting for configs collection');
+      }
+      if (collectionName === 'pages' && options.mode === 'insert') {
+        throw new Error('`insert` is not available as an import setting for pages collection');
+      }
+      if (collectionName === 'attachmentFiles.chunks') {
+        throw new Error('`attachmentFiles.chunks` must not be transferred. Please omit it from request body `collections`.');
+      }
+      if (collectionName === 'attachmentFiles.files') {
+        throw new Error('`attachmentFiles.files` must not be transferred. Please omit it from request body `collections`.');
+      }
+
+      const importSettings = importService.generateImportSettings(options.mode);
+      importSettings.jsonFileName = fileName;
+      importSettings.overwriteParams = generateOverwriteParams(collectionName, operatorUserId, options);
+      importSettingsMap[collectionName] = importSettings;
+    });
+
+    return importSettingsMap;
+  }
+
+  public async importCollections(collections, importSettingsMap, sourceGROWIUploadConfigs): Promise<void> {
+    const { configManager, importService, appService } = this.crowi;
+    const shouldKeepUploadConfigs = configManager.getConfig('crowi', 'app:fileUploadType') !== 'none';
+
+    let savedUploadConfigs;
+    if (shouldKeepUploadConfigs) {
+      // save
+      savedUploadConfigs = Object.fromEntries(uploadConfigKeys.map((key) => {
+        return [key, configManager.getConfigFromDB('crowi', key)];
+      }));
+    }
+
+    await importService.import(collections, importSettingsMap);
+
+    // remove & save if none
+    if (shouldKeepUploadConfigs) {
+      await configManager.removeConfigsInTheSameNamespace('crowi', uploadConfigKeys);
+      await configManager.updateConfigsInTheSameNamespace('crowi', savedUploadConfigs);
+    }
+    else {
+      await configManager.updateConfigsInTheSameNamespace('crowi', sourceGROWIUploadConfigs);
+    }
+
+    await this.crowi.setUpFileUpload(true);
+    await appService.setupAfterInstall();
+  }
+
   public async receive(zipfile: Readable): Promise<void> {
   public async receive(zipfile: Readable): Promise<void> {
     // Import data
     // Import data
     // Call onCompleteTransfer when finished
     // Call onCompleteTransfer when finished