Skip to content

Project structure

1. Changing items

  • Starting with extension version 1.0.12 , If the Node.js version configured on the user's desktop or laptop is below Node.js 18, the extension will not function.
  • Default framework of Application lambda or Long-Term Service is changed from @rdk/lambda@cals-framework/lambda
  • Adjustments or deployments of the Application Lambda or Long-Term Service may vary depending on framework changes.
  • When modifying and deploying an existing Application Lambda or Long-Term Service, the following tasks must be performed due to the changes in the framework. (※ Please refer to the subsequent change guide for detailed changes and instructions.)
    • Rename index.js to app.js and update the source code information accordingly,
    • Modify the method in controller.js
    • Change the configuration file at the bottom of the config/ folder from JSON format to JavaScript format.
    • Update files associated with the framework change, including: LambdaBaseConstant, ApplicationLambdaException, LambdaBaseLib, ApplicationLambdaBaseModel, LambdaBaseUtil, BaseHandler, BaseController, BaseService and BaseDAO.
    • After clicking the Migration button in the Extension – localExplorer, proceed with the deployment process.

2. Folder structure explanation

Alt text

No.Folder nameExplanation
1configContains configuration values that define the execution environment.
2constantA folder that consolidates constants used throughout the project.
3exceptionA folder for storing class files that define exceptions.
4libA folder for storing class files using external libraries.
5modelA space for storing class files of model definition.
6queryThe site gathers Query XML files.
7srcFolder gathers business-related source code to be used in the project.
8utilManages commonly used source code shared across the project.

3. File structure explanation

3.1. File is used to distinguish Local and Production environments automatically based on environment variables value. /config/projectBaseConfig.js

const { ProjectBaseConfigDev } = require('./projectBaseConfigDev')
const { ProjectBaseConfigProd } = require('./projectBaseConfigProd')

module.exports.ProjectBaseConfig = process.env.NODE_ENV !== 'production' ? ProjectBaseConfigDev : ProjectBaseConfigProd

3.2. The file to configure the environment to debug in the Local environment. /config/projectBaseConfigDev.js

'use strict'


const { LambdaBaseConfig, DB_CONNECTION_TYPE, LogLevel, NODE_ENV_TYPE } = require('@cals-framework/lambda')
const { resolve } = require('path')


/**
* ProjectBaseConstant class
*
* @class
*/
class ProjectBaseConfigDev extends LambdaBaseConfig {
 /**
  * Create constant variable by constructor
  *
  * @constructor
  */


 // can modify from this area
 constructor() {
   super()


   this.NODE_ENV = NODE_ENV_TYPE.DEVELOPMENT


   this.OBJ_MAPPER.path.push(resolve(__dirname, '../query/mysql/mysql.xml'))
   this.OBJ_MAPPER.namespace.mysql = 'mysql'


   this.Logger.LEVEL = LogLevel.DEBUG
   this.Logger.ParamEnabled = false
   this.Logger.ResultEnabled = false
   this.Logger.DBLogEnabled = true


   this._DB.ENGINE = 'mysql'
   this._DB.CONNECTION_TYPE = DB_CONNECTION_TYPE.CONFIG
   this._DB.HOST = '{{dbHost}}'
   this._DB.USER = '{{dbUser}}'
   this._DB.PASSWORD = '{{dbPassword}}'
   this._DB.SCHEMA = '{{dbSchema}}'
 }
}
module.exports.ProjectBaseConfigDev = ProjectBaseConfigDev

3.3. This is environment config file for operation in product environment. (Support Key: is displayed at YES status only.)/config/projectBaseConfigProd.js

'use strict'


const { LambdaBaseConfig, DB_CONNECTION_TYPE, LogLevel, NODE_ENV_TYPE } = require('@cals-framework/lambda')
const { resolve } = require('path')


console.log(`process.env.AWS_REGION: ${process.env.AWS_REGION}`)


/**
* ProjectBaseConstant class
*
* @class
*/
class ProjectBaseConfigProd extends LambdaBaseConfig {
 /**
  * Create constant variable by construction 
  *
  * @constructor
  */


 // Can edit from this part
 constructor() {
   super()


   this.NODE_ENV = NODE_ENV_TYPE.PRODUCTION


   this.OBJ_MAPPER.path.push(resolve(__dirname, '../query/mysql/mysql.xml'))
   this.OBJ_MAPPER.namespace.mysql = 'mysql'


   this.Logger.LEVEL = LogLevel.DEBUG
   this.Logger.ParamEnabled = false
   this.Logger.ResultEnabled = false
   this.Logger.RdkLogEnabled = false
   this.Logger.DBLogEnabled = true


   this._DB.ENGINE = 'mysql'
   this._DB.CONNECTION_TYPE = DB_CONNECTION_TYPE.SECRETS_MANAGER
   this._DB.HOST = 'demo'
   this._DB.USER = ''
   this._DB.PASSWORD = ''
   this._DB.SCHEMA = ''


   this._CACHE_DB.CONNECTION_TYPE = DB_CONNECTION_TYPE.CONFIG
   this._CACHE_DB.ENGINE = ''
   this._CACHE_DB.HOST = '127.0.0.1'
   this._CACHE_DB.PORT = 6379
 }
}
module.exports.ProjectBaseConfigProd = ProjectBaseConfigProd

3.4. The file manages variables within the project. /constant/projectBaseConstant.js

'use strict'
/**
* @fileoverview file containing constant variable
*/


/**
* ProjectBaseConstant
* @module ProjectBaseConstant
* @example
* const ProjectBaseConstant = require('../constant/projectBaseConstant')
* const clsProjectBaseConstant = new ProjectBaseConstant()
*/


const { AppLambdaBaseConstant } = require('@cals-framework/lambda')


/**
* ProjectBaseConstant class
* @class
*/


module.exports = class ProjectBaseConstant extends AppLambdaBaseConstant {
 /**
  * Create constant variables by constructor. 
  * @constructor
  */


 // Can modify from this part. 
 constructor () {
   super()
 }


 static ERROR_MESSAGE = {
   NO_AFFECTED_QUERY: 'NO AFFECTED QUERY'
 }
 static QUERY_INFO = {
   selectTest1: {
     name: 'selectTest1',
     type: this.ORM_QUERY_TYPE.SELECT
   }
 }
}

3.5. The file creates a class including an external library to be used within the project. /lib/lambdaLib.js

'use strict'
/**
* @fileoeverview Sample for Library module 
* lambdaLib.js
*/
const os = require('os')
const { LambdaBaseLib } = require('@cals-framework/lambda')


/**
* Lambda sample for library module
* @module LambdaLib
* @example
* const RdkLambdaLib = require('./lambdaLib.js)
* const clsRdkLambdaLib = new RdkLambdaLib()
* @desc Lambda sample for library module
*/
module.exports = class LambdaLib extends LambdaBaseLib {
 /**
  * Create Library object by constructor
  * @constructs
  * @param
  */
 constructor () {
   super()
   this.homeDir = os.homedir()
   this.hostName = os.hostname()
   this.getTempDir = getTempDir
 }


 /**
  * getTempDir function
  * @function
  * @param
  * @desc return temp Directory
  */
 getTempDir() {
   return this.path.resolve(os.tmpdir())
 }
}

3.6. The file defines a Model object to be used within the project. /model/lambdaModel.js

'use strict'
/**
* @fileoeverview sample for Model module
* lambdaModel.js
*/


const { ApplicationLambdaBaseModel } = require('@cals-framework/lambda')


/**
* sample for Model module
* @module LambdaModel
* @example
* const LambdaModel = require('./lambdaModel.js')
* const clsLambdaModel = new LambdaModel()
* @desc sample for Model module
*/
class SampleAddDataModel extends ApplicationLambdaBaseModel {
 constructor () {
   super()
   this.sampleName = ''
   this.sampleDesc = ''
 }
}
exports.SampleAddDataModel = SampleAddDataModel


class SampleUpdateDataModel extends ApplicationLambdaBaseModel {
 constructor () {
   super()
   this.sampleName = ''
   this.sampleDesc = ''
 }
}
exports.SampleUpdateDataModel = SampleUpdateDataModel

3.7. The file creates source code such as validation for received events and default value according to MVC pattern. /src/controller.js

'use strict'

const { BaseController, CompareUtility, ParameterNonExistException, calsLogger } = require('@cals-framework/lambda')
const Service = require('./service')

module.exports = class Controller extends BaseController {
 constructor ({ event, context }) {
   super({ event, context })
   this.event = event
   this.context = context

      this.calsContext.serviceContext === undefined
       ? this.clsService = new Service()
       : typeof this.calsContext.serviceContext !== 'undefined'
       ? this.calsContext.serviceContext = new Service()
       : this.clsService = this.calsContext.serviceContext
 }

 async process () {
   calsLogger.param(this.event, this.context)

                                                                                                                                                                                                                                                                                                                                                        

   this.objReturn = await this.clsService.runMethod({ objRequestParams: this.objRequestParams, objReturn: this.objReturn })

   calsLogger.result(this.objReturn)
   return this.objReturn
 }
}

3.8. The file defines a function that is responsible for executing business logic. /src/service.js

'use strict'


const { BaseService, calsLogger } = require('@cals-framework/lambda')
const { NoAffectedDataException } = require('../exception/lambdaException')
const ProjectBaseConstant = require('../constant/projectBaseConstant')
const DAO = require('./dao')


module.exports = class Service extends BaseService {
 constructor () {
   super()


      this.calsContext.daoContext === undefined
        ? this.clsDAO = new DAO()
        : typeof this.calsContext.daoContext !== 'undefined'
        ? this.calsContext.daoContext = new DAO()
        : this.clsDAO = this.calsContext.daoContext
 }


 async runMethod ({ objRequestParams, objReturn }) {
   calsLogger.param(objRequestParams)
   // 1. Create model register data. 
   const SampleAddDataModel = require('../model/lambdaModel').SampleAddDataModel
   const objSampleAddDataModel = new SampleAddDataModel()


   // 2. Register data in data registering module. 
   objSampleAddDataModel.sampleName = objRequestParams.sampleName
   objSampleAddDataModel.sampleDesc = objRequestParams.sampleDesc


   // 3. Input data
   const objAddReturn = await this.clsDAO.addData({ objDAOParams: objSampleAddDataModel, objReturn })
   if (objAddReturn.affectedRows === 0) {
     throw new NoAffectedDataException(ProjectBaseConstant.ERROR_MESSAGE.NO_AFFECTED_QUERY)
   }


   calsLogger.result(objReturn)
   return objReturn
 }
 // can edit up to this part
}

3.9. The file which is responsible for executing SQL queries related to the database.

/src/dao.js

'use strict'


const { ApplicationDAO, calsLogger } = require('@cals-framework/lambda')
const ProjectBaseConstant = require('../constant/projectBaseConstant')


module.exports = class DAO extends ApplicationDAO {
 // can edit form this part 
 async addData ({ objDAOParams, objReturn }) {
   calsLogger.param(objDAOParams)
  
   const objDAOReturn = await this.insert({
     sQueryId: 'insertData',
     objParam: objDAOParams,
     objReturn
   })
  
   calsLogger.result(objDAOReturn)
   return objDAOReturn
 }
}

3.10. The file gathers source code created by project utility. /util/rdkProjectBaseUtil.js

'use strict'
/**
* @fileoeverview Sample for Util module
* Module lambda util Base 
*/
const { RdkLambdaBaseUtil } = require('@cals-framework/lambda')
const LambdaLib = require('../lib/lambdaLib')
const clsLambdaLib = new LambdaLib()
/**
* Sample for Util module
* @module RdkProjectBaseUtil
* @example
* const RdkProjectBaseUtil = require('./rdkProjectBaseUtil.js')
* const clsRdkProjectBaseUtil = new RdkProjectBaseUtil()
* @desc sample for Util module
*/
/**
* sample for Util module
* @class
*/
module.exports = class RdkProjectBaseUtil extends RdkLambdaBaseUtil {
 constructor () {
   super()
   this.getOsInfo = getOsInfo
 }
}
/**
* sample for OS information returning function 
* @function
* @desc  Util function returning OS information. 
*/
const getOsInfo = () => {
 return {
   hostName: clsLambdaLib.hostName,
   homeDir: clsLambdaLib.homeDir,
   tmpDir: clsLambdaLib.getTempDir()
 }
}

3.11. The file assigns Handler to execute lambda projects. /app.js

'use strict'

const { BaseHandler, calsLogger } = require('@cals-framework/lambda')
const { ProjectBaseConfig } = require('./config/projectBaseConfig')
const Controller = require("./src/controller")


class LambdaHandler extends BaseHandler {
 process(event, context) {
   calsLogger.debug('Project Start')
   return Promise.resolve(new Controller({ event, context }).handle())
 }
}

exports.handler = new LambdaHandler(new ProjectBaseConfig()).handle

4. Framework Context

  1. Framework Utility
Class nameExplanation
CompareUtilityA utility containing functions frequently used for comparing values.
ConvertUtilityA utility containing functions frequently used for converting values.
RandomUtilityA utility containing functions frequently used with random operations, such as generating random integer numbers.
StringUtilityA utility containing functions related to string manipulation, commonly used throughout the project.
FsUtilityA utility containing functions related to file system operations, frequently used within the project.
// Destructuring method
const { calsLogger, CompareUtility, ConvertUtility, RandomUtility, StringUtility, FsUtility } = require('@cals-framework/lambda')


// variable assignment method
const CompareUtility = require('@cals-framework/lambda').CompareUtility
const ConvertUtility = require('@cals-framework/lambda').ConvertUtility
const RandomUtility = require('@cals-framework/lambda').RandomUtility
const StringUtility = require('@cals-framework/lambda').StringUtility
const FsUtility = require('@cals-framework/lambda').FsUtility




// calsLogger
calsLogger.debug(“debug log..”)
// => 2024.01.12.T08:46:18.863 [DEBUG] - [PROJECT] debug log..
// Use for the case that developer want to debug by log
calsLogger.param(“param log..”)
// => 2024.01.12.T08:46:18.863 [PARAM] - [PROJECT] param log..
// Use for checking parameter  
calsLogger.result(“result log..”) 
// => 2024.01.12.T08:46:18.863 [RESULT] - [PROJECT] result log..
// Use to check return function 
calsLogger.error(“error log..”) 
// => 2024.01.12.T08:46:18.863 [ERROR] - [PROJECT] error log..
// use for the case that an error log is left




// CompareUtility
CompareUtility.isEmpty(null) // => Return true
CompareUtility.isNotEmpty(null) // => Return false


// ConvertUtility
ConvertUtility.convertCharToBool('1') // => Return true
ConvertUtility.convertNullToEmpty(null) // => Return ''
ConvertUtility.convertStringToInteger('123') // => Return 123




//RandomUtility
RandomUtility.getRandomInt(0, 9) // => Randomly returns a value between 0 and 9
RandomUtility.getUuid() // => Return a 32-digit identifier




// StringUtility
StringUtility.slash('C:\test\path') // => Return 'C:/test/path'
StringUtility.isNonAscii('안녕하세요') // => Return true
StringUtility.lpad('abc', 10, '0') // => Return '000000abc'
StringUtility.rpad('abc', 10, '0') // => Return 'abc000000'
StringUtility.nextLetter('a') // => Return 'b'
StringUtility.getCharSeq().getCharByIndex(27) // => Returns a unique sequence of alphabetic characters based on an index




// FsUtility
FsUtility.existsPath('/temp') // => Return true
FsUtility.writeFile('/temp/file1.txt', 'Hello World')
FsUtility.writeFileAsync('/temp/file2.txt', 'Sample File')
.then(() =>{
console.log('Write Complete!')
})
.catch((err) => {
console.err(`What happens: ${err}`)
})
FsUtility.readDirectory('/temp') // => Return ['file1.txt', 'file2.txt']
FsUtility.readFile('/temp/file1.txt') // => Return 'Hello World'
FsUtility.rmASync('/temp/file2.txt')
.then(() => {
console.log('File Removed.')
})
.catch((err) => {
console.error(`What happens: ${err}`)
})
FsUtility.createDirectory('/temp/newDir')
  1. Exception list
Exception NameExplanation
AlreadyExistExceptionAn error class triggered when data exists.
DataSQLExceptionAn error class triggered when an issue arises during SQL execution.
InvalidRequestExceptionAn error class triggered when an invalid request is made.
MultiDataSelectExceptionAn error class triggered when multiple data entries are accidentally retrieved.
NoDataExceptionAn error class triggered when a database search request yields no result.
OperationFailExceptionAn error class triggered when an issue occurs during the execution of a specific operation.
ParameterNonExistExceptionAn error class triggered when a required parameter for a request is missing.
ApplicationLambdaExceptionAn error class used within the framework for other errors.
WrongConfigException
CalsSdkExecuteException
LambdaBaseException
DBConnectionException
NoPreferenceException
LockObjectException
// Destructuring method
const { AlreadyExistException } = require('@cals-framework/lambda')
throw new AlreadyExistException()


// variable assignment method
const DataSQLException = require('@cals-framework/lambda').DataSQLException
throw new DataSQLException()