Skip to content
This repository has been archived by the owner on Mar 7, 2023. It is now read-only.

Commit

Permalink
Run multiple odata services in parallel, enable persistence for mocks (
Browse files Browse the repository at this point in the history
…#183)

* fixed problem when booting up multiple server
added persistence for mocks
  • Loading branch information
a-thaler authored Apr 12, 2019
1 parent 028719c commit 2b71c14
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 59 deletions.
9 changes: 5 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
**/node_modules
keys/
node_modules
keys
*.log
kyma-responses
deployments
index.js
**/generated
generated
.nyc_output
dist
dist
data
1 change: 1 addition & 0 deletions app-connector-client/test/test_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ describe("should work", () => {
return request(server)
.get("/metadata")
.expect(200)
.expect('Content-Type', 'text/yaml; charset=UTF-8')
})
it('404 everything else', () => {
return request(server)
Expand Down
6 changes: 4 additions & 2 deletions examples/combined-odata-mock/varkes_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
"specification": "apis/products.xml",
"auth": "basic",
"type": "odata",
"basepath":"/odata/product.svc"
"basepath": "/odata/product.svc",
"persistence": true
},
{
"name": "Northwind Service",
"specification": "apis/northwind.xml",
"auth": "basic",
"type": "odata",
"basepath":"/odata/northwind.svc"
"basepath": "/odata/northwind.svc",
"persistence": true
}
],
"events": [
Expand Down
6 changes: 4 additions & 2 deletions examples/combined-openapi-mock/varkes_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"basepath": "/api2",
"specification": "apis/schools.yaml",
"name": "Schools API",
"auth": "basic"
"auth": "basic",
"persistence": true
},
{
"basepath": "/api1",
Expand All @@ -14,7 +15,8 @@
"metadata": "/courseMetadata",
"specification": "apis/courses.yaml",
"auth": "oauth",
"oauth": "/coursesOauth/token"
"oauth": "/coursesOauth/token",
"persistence": true
}
],
"events": [
Expand Down
43 changes: 36 additions & 7 deletions odata-mock/src/server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ const express = require('express')
const bodyParser = require('body-parser');
import { logger as LOGGER } from "./logger"
import * as parser from "./parser"
const path = require("path")

async function init(varkesConfigPath: string, currentPath = "") {
var varkesConfig = config(varkesConfigPath, currentPath)

var promises: Promise<any>[] = [];
for (var i = 0; i < varkesConfig.apis.length; i++) {
var api = varkesConfig.apis[i]
Expand Down Expand Up @@ -51,24 +52,52 @@ async function bootLoopback(api: any, varkesConfig: any) {
}

async function generateBootConfig(api: any) {
var parsedModel = await parser.parseEdmx(api.specification)
let dataSourceName = api.name.replace(/\s/g, '')
var parsedModel = await parser.parseEdmx(api.specification, dataSourceName)

//for configuration, see https://apidocs.strongloop.com/loopback-boot/
var bootConfig = JSON.parse(fs.readFileSync(__dirname + "/resources/boot_config_template.json", "utf-8"))

parsedModel.modelConfigs.forEach(function (config: any) {
bootConfig.models[config.name] = config.value
})
bootConfig.models["ACL"] = {
dataSource: dataSourceName,
public: false
}
parsedModel.modelDefs.forEach(function (definition: any) {
bootConfig.modelDefinitions.push(definition)
})

bootConfig.appRootDir = __dirname
bootConfig.appConfigRootDir = __dirname

let restBasePath = api.basepath.replace("/odata", "/api")
bootConfig.components["n-odata-server"].path = api.basepath + "/*"
bootConfig.components["loopback-component-explorer"].mountPath = restBasePath + "/console"
bootConfig.components["loopback-component-explorer"].basePath = restBasePath
bootConfig.middleware.routes["n-odata-server#odata"].paths.push(api.basepath + "/*")
bootConfig.middleware.routes["loopback#rest"].paths.push(restBasePath)
bootConfig.components["loopback-component-explorer"] = {
mountPath: restBasePath + "/console",
basePath: restBasePath
}
bootConfig.components["./odata-server"] = {
path: api.basepath + "/*",
odataversion: "2",
useViaMiddleware: false
}

bootConfig.middleware.routes["n-odata-server#odata"].paths = [api.basepath + "/*"]
bootConfig.middleware.routes["loopback#rest"].paths = [restBasePath]
bootConfig.middleware["initial:before"]["loopback#favicon"].params = path.join(__dirname, "resources/favicon.ico")

bootConfig.dataSources[dataSourceName] = {
name: dataSourceName,
connector: "memory"
}

if (api.persistence) {
if (!fs.existsSync("./data")) {
fs.mkdirSync("./data");
}
bootConfig.dataSources[dataSourceName].file = "data/" + dataSourceName + ".json"
}

return bootConfig
}
Expand Down
8 changes: 0 additions & 8 deletions odata-mock/src/server/boot/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ const fs = require('fs');
module.exports = function (app: any) {
registerLogger(app);
var apis = app.varkesConfig.apis;
apis.forEach(function (api: any) {
app.get(api.metadata ? api.metadata : "/metadata", function (req: any, res: any, next: any) {
var spec = fs.readFileSync(api.specification, 'utf-8');
res.status(200);
res.type("text/xml");
res.send(spec);
});
});

function modifyResponseBody(req: any, res: any, next: any) {
var oldSend = res.send;
Expand Down
6 changes: 6 additions & 0 deletions odata-mock/src/server/odata-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
var odata = require('n-odata-server/lib/odata');

module.exports = function (loopbackApplication: any, options: any) {
odata.init(loopbackApplication, options);
odata.OData.singletonInstance = null
}
10 changes: 5 additions & 5 deletions odata-mock/src/server/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@

import { logger as LOGGER } from "./logger"
const fs = require("fs");
import {ParsedModels} from "./types"
import { ParsedModels } from "./types"
Object.defineProperty(exports, "__esModule", { value: true });
const { parse } = require('odata2openapi');

function parseEdmx(path: string):Promise<ParsedModels> {
function parseEdmx(path: string, dataSourceName: string): Promise<ParsedModels> {
return new Promise<ParsedModels>(function (resolve, reject) {
fs.readFile(path, "utf8", function (err: Error, data: any) {
if (err) reject(err);

parse(data)
.then((service: any) => {
let result = createEntities(service);
let result = createEntities(service, dataSourceName);
resolve(result);
}).catch((error: Error) => {
LOGGER.error("Error while parsing API '%s'", path)
Expand All @@ -24,7 +24,7 @@ function parseEdmx(path: string):Promise<ParsedModels> {
})
}

function createEntities(service: any):ParsedModels{
function createEntities(service: any, dataSourceName: string): ParsedModels {
let result: ParsedModels = {
modelConfigs: [],
modelDefs: []
Expand All @@ -34,7 +34,7 @@ function createEntities(service: any):ParsedModels{
let jsonTemplate = JSON.parse(fs.readFileSync(__dirname + "/resources/model_template.json", "utf8"));
let entityName = entityType.name;

result.modelConfigs.push({ name: entityName, value: { dataSource: "db", public: true } })
result.modelConfigs.push({ name: entityName, value: { dataSource: dataSourceName, public: true } })

jsonTemplate.definition.name = entityName;
jsonTemplate.definition.plural = entityName + "s";
Expand Down
23 changes: 6 additions & 17 deletions odata-mock/src/server/resources/boot_config_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
"./boot"
],
"dataSources": {
"db": {
"name": "db",
"connector": "memory"
}

},
"middleware": {
"initial:before": {
"loopback#favicon": {}
"loopback#favicon": {

}
},
"initial": {
"compression": {},
Expand Down Expand Up @@ -66,20 +65,10 @@
}
},
"components": {
"loopback-component-explorer": {
"mountPath": "XXX"
},
"n-odata-server": {
"path": "XXX",
"odataversion": "2",
"useViaMiddleware": true
}

},
"modelDefinitions": [],
"models": {
"ACL": {
"dataSource": "db",
"public": false
}

}
}
Binary file added odata-mock/src/server/resources/favicon.ico
Binary file not shown.
27 changes: 13 additions & 14 deletions odata-mock/src/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ describe('test app', function () {
});
});

describe('GET Categorys via API', function () {
describe('GET Summary_of_Sales_by_Years via API', function () {
it('should return response 200', function (done) {
request(app)
.get('/northwind/api/northwind.svc/Categorys')
.get('/northwind/api/northwind.svc/Summary_of_Sales_by_Years')
.set('Accept', 'application/json')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(200, done)
Expand All @@ -41,10 +41,10 @@ describe('test app', function () {
});
});

describe('GET non-existing Category via API', function () {
describe('GET non-existing Summary_of_Sales_by_Years via API', function () {
it('should return response 200', function (done) {
request(app)
.get('/northwind/api/northwind.svc/Categorys/10')
.get('/northwind/api/northwind.svc/Summary_of_Sales_by_Years/10')
.set('Accept', 'application/json')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(404, done)
Expand Down Expand Up @@ -83,19 +83,18 @@ describe('test app', function () {
});
});

describe('POST/GET Category via API', function () {
describe('POST/GET Summary_of_Sales_by_Years via API', function () {
it('should return response 200', function () {
return new Promise((resolve, reject) => {
request(app)
.post('/northwind/api/northwind.svc/Categorys')
.post('/northwind/api/northwind.svc/Summary_of_Sales_by_Years')
.send({
CategoryID: 0,
CategoryName: "string",
Description: "string"
"OrderID": 0,
"Subtotal": 0
})
.set('Accept', 'application/json')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(/"CategoryID":0/)
.expect(/"id":1/)
.expect(200)
.end((err: any, res: any) => {
if (err) {
Expand All @@ -106,10 +105,10 @@ describe('test app', function () {
})
}).then(() => {
return request(app)
.get('/northwind/api/northwind.svc/Categorys/1')
.get('/northwind/api/northwind.svc/Summary_of_Sales_by_Years/1')
.set('Accept', 'application/json')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(/"CategoryID":0/)
.expect(/"id":1/)
.expect(200)
})
});
Expand All @@ -125,10 +124,10 @@ describe('test app', function () {
});
});

describe('GET Categorys via odata', function () {
describe('GET Summary_of_Sales_by_Years via odata', function () {
it('should return response 200', function (done) {
request(app)
.get('/northwind/odata/northwind.svc/Categorys')
.get('/northwind/odata/northwind.svc/Summary_of_Sales_by_Years')
.set('Accept', 'application/json')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(200, done)
Expand Down
6 changes: 6 additions & 0 deletions openapi-mock/src/server/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ async function mock(config: any) {
writeSpec(pretty_yaml.stringify(spec), api, i)

let myDB = new middleware.MemoryDataStore();
if (api.persistence) {
if (!fs.existsSync("./data")) {
fs.mkdirSync("./data");
}
myDB = new middleware.FileDataStore("./data");
}

var middlewares = [];
middlewares.push(
Expand Down

0 comments on commit 2b71c14

Please sign in to comment.