-
Notifications
You must be signed in to change notification settings - Fork 26
[#175072065] EXPERIMENTAL: Start io-backend as Azure Function #722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
93c5691
8a8e8ae
9a5bd62
67816b2
8028b3d
fa0147d
70bc538
f59c56d
e641ee7
94282ce
4a6d18a
6a7a1d8
07f66d5
95de2e8
a13fdeb
26ccedf
2e70348
2ddafb0
d2316d8
480050e
4c11a09
7ec83a1
61cb35a
a4fb41a
3ae06ab
7dba4e6
52ee814
08e37de
0f5a573
d4cf44a
972ede7
d7312f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| *.js.map | ||
| *.ts | ||
| .git* | ||
| .vscode* | ||
| .circleci* | ||
| .prettierrc | ||
| local.settings.json* | ||
| tsconfig.json | ||
| tslint.json | ||
| README.md | ||
| yarn.lock | ||
| jest.config.js | ||
| __* | ||
| Dangerfile.js | ||
| CODEOWNERS |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| { | ||
| "bindings": [ | ||
| { | ||
| "authLevel": "anonymous", | ||
| "type": "httpTrigger", | ||
| "direction": "in", | ||
| "name": "req", | ||
| "route": "{*segments}", | ||
| "methods": [ | ||
| "get", | ||
| "post", | ||
| "put", | ||
| "patch", | ||
| "delete" | ||
| ] | ||
| }, | ||
| { | ||
| "type": "http", | ||
| "direction": "out", | ||
| "name": "res" | ||
| } | ||
| ], | ||
| "scriptFile": "./index.js" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| import * as winston from "winston"; | ||
|
|
||
| import { Context } from "@azure/functions"; | ||
| import { secureExpressApp } from "io-functions-commons/dist/src/utils/express"; | ||
| import { AzureContextTransport } from "io-functions-commons/dist/src/utils/logging"; | ||
| import { setAppContext } from "io-functions-commons/dist/src/utils/middlewares/context_middleware"; | ||
| import createAzureFunctionHandler from "io-functions-express/dist/src/createAzureFunctionsHandler"; | ||
|
|
||
| /** | ||
| * Main entry point for the Digital Citizenship proxy. | ||
| */ | ||
|
|
||
| import { fromNullable } from "fp-ts/lib/Option"; | ||
| import { newApp } from "../src/app"; | ||
| import { | ||
| ALLOW_BPD_IP_SOURCE_RANGE, | ||
| ALLOW_MYPORTAL_IP_SOURCE_RANGE, | ||
| ALLOW_NOTIFY_IP_SOURCE_RANGE, | ||
| ALLOW_PAGOPA_IP_SOURCE_RANGE, | ||
| ALLOW_SESSION_HANDLER_IP_SOURCE_RANGE, | ||
| API_BASE_PATH, | ||
| AUTHENTICATION_BASE_PATH, | ||
| BONUS_API_BASE_PATH, | ||
| BPD_BASE_PATH, | ||
| DEFAULT_APPINSIGHTS_SAMPLING_PERCENTAGE, | ||
| ENV, | ||
| MYPORTAL_BASE_PATH, | ||
| PAGOPA_BASE_PATH | ||
| } from "../src/config"; | ||
| import { initAppInsights } from "../src/utils/appinsights"; | ||
| import { | ||
| getCurrentBackendVersion, | ||
| getValueFromPackageJson | ||
| } from "../src/utils/package"; | ||
|
|
||
| const authenticationBasePath = AUTHENTICATION_BASE_PATH; | ||
| const APIBasePath = API_BASE_PATH; | ||
| const BonusAPIBasePath = BONUS_API_BASE_PATH; | ||
| const PagoPABasePath = PAGOPA_BASE_PATH; | ||
| const MyPortalBasePath = MYPORTAL_BASE_PATH; | ||
| const BPDBasePath = BPD_BASE_PATH; | ||
|
|
||
| /** | ||
| * If APPINSIGHTS_INSTRUMENTATIONKEY env is provided initialize an App Insights Client | ||
| * WARNING: When the key is provided several information are collected automatically | ||
| * and sent to App Insights. | ||
| * To see what kind of informations are automatically collected | ||
| * @see: utils/appinsights.js into the class AppInsightsClientBuilder | ||
| */ | ||
| const maybeAppInsightsClient = fromNullable( | ||
| process.env.APPINSIGHTS_INSTRUMENTATIONKEY | ||
| ).map(k => | ||
| initAppInsights(k, { | ||
| applicationVersion: getCurrentBackendVersion(), | ||
| cloudRole: getValueFromPackageJson("name"), | ||
| disableAppInsights: process.env.APPINSIGHTS_DISABLED === "true", | ||
| samplingPercentage: process.env.APPINSIGHTS_SAMPLING_PERCENTAGE | ||
| ? parseInt(process.env.APPINSIGHTS_SAMPLING_PERCENTAGE, 10) | ||
| : DEFAULT_APPINSIGHTS_SAMPLING_PERCENTAGE | ||
| }) | ||
| ); | ||
|
|
||
| // tslint:disable-next-line: no-let | ||
| let logger: Context["log"] | undefined; | ||
| const contextTransport = new AzureContextTransport(() => logger, { | ||
| level: "debug" | ||
| }); | ||
| winston.add(contextTransport); | ||
|
|
||
| // Setup Express | ||
| const init = newApp({ | ||
| APIBasePath, | ||
| BPDBasePath, | ||
| BonusAPIBasePath, | ||
| MyPortalBasePath, | ||
| PagoPABasePath, | ||
| allowBPDIPSourceRange: ALLOW_BPD_IP_SOURCE_RANGE, | ||
| allowMyPortalIPSourceRange: ALLOW_MYPORTAL_IP_SOURCE_RANGE, | ||
| allowNotifyIPSourceRange: ALLOW_NOTIFY_IP_SOURCE_RANGE, | ||
| allowPagoPAIPSourceRange: ALLOW_PAGOPA_IP_SOURCE_RANGE, | ||
| allowSessionHandleIPSourceRange: ALLOW_SESSION_HANDLER_IP_SOURCE_RANGE, | ||
| appInsightsClient: maybeAppInsightsClient.toUndefined(), | ||
| authenticationBasePath, | ||
| env: ENV, | ||
| withBodyParser: false | ||
| }).then(app => { | ||
| secureExpressApp(app); | ||
| return { | ||
| app, | ||
| azureFunctionHandler: createAzureFunctionHandler(app) | ||
| }; | ||
| }); | ||
|
|
||
| // Binds the express app to an Azure Function handler | ||
| function httpStart(context: Context): void { | ||
| logger = context.log; | ||
| init | ||
| .then(({ app, azureFunctionHandler }) => { | ||
| setAppContext(app, context); | ||
| azureFunctionHandler(context); | ||
| }) | ||
| .catch(context.log); | ||
| } | ||
|
|
||
| export default httpStart; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| <PropertyGroup> | ||
| <TargetFramework>netcoreapp3.1</TargetFramework> | ||
| <AzureFunctionsVersion>v3</AzureFunctionsVersion> | ||
| <WarningsAsErrors></WarningsAsErrors> | ||
| <DefaultItemExcludes>**</DefaultItemExcludes> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.2.2" /> | ||
| <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="4.0.1" /> | ||
| <PackageReference Include="Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator" Version="1.1.8" /> | ||
| </ItemGroup> | ||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "version": "2.0", | ||
| "logging": { | ||
| "logLevel": { | ||
| "default": "Information" | ||
| } | ||
| }, | ||
| "extensions": { | ||
| "http": { | ||
| "routePrefix": "" | ||
| }, | ||
| "durableTask": { | ||
| "hubName": "%SLOT_TASK_HUBNAME%" | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,6 +54,7 @@ import ServicesController from "./controllers/servicesController"; | |
| import SessionController from "./controllers/sessionController"; | ||
| import UserMetadataController from "./controllers/userMetadataController"; | ||
|
|
||
| import * as mime from "mime"; | ||
| import { log } from "./utils/logger"; | ||
| import checkIP from "./utils/middleware/checkIP"; | ||
|
|
||
|
|
@@ -64,6 +65,7 @@ import * as appInsights from "applicationinsights"; | |
| import { tryCatch2v } from "fp-ts/lib/Either"; | ||
| import { isEmpty, StrMap } from "fp-ts/lib/StrMap"; | ||
| import { fromLeft, taskEither, tryCatch } from "fp-ts/lib/TaskEither"; | ||
| import * as fs from "fs"; | ||
| import { VersionPerPlatform } from "../generated/public/VersionPerPlatform"; | ||
| import BonusController from "./controllers/bonusController"; | ||
| import SessionLockController from "./controllers/sessionLockController"; | ||
|
|
@@ -129,9 +131,10 @@ export interface IAppFactoryParameters { | |
| PagoPABasePath: string; | ||
| MyPortalBasePath: string; | ||
| BPDBasePath: string; | ||
| withBodyParser: boolean; | ||
| } | ||
|
|
||
| // tslint:disable-next-line: no-big-function | ||
| // tslint:disable-next-line: cognitive-complexity no-big-function | ||
| export function newApp({ | ||
| env, | ||
| allowNotifyIPSourceRange, | ||
|
|
@@ -145,7 +148,8 @@ export function newApp({ | |
| BonusAPIBasePath, | ||
| PagoPABasePath, | ||
| MyPortalBasePath, | ||
| BPDBasePath | ||
| BPDBasePath, | ||
| withBodyParser | ||
| }: IAppFactoryParameters): Promise<Express> { | ||
| const REDIS_CLIENT = | ||
| ENV === NodeEnvironmentEnum.DEVELOPMENT | ||
|
|
@@ -247,21 +251,47 @@ export function newApp({ | |
|
|
||
| app.use(morgan(loggerFormat)); | ||
|
|
||
| // | ||
| // Setup parsers | ||
| // | ||
|
|
||
| // Parse the incoming request body. This is needed by Passport spid strategy. | ||
| app.use(bodyParser.json()); | ||
| // When the application is running as Azure Function | ||
| // Express Body parser must be disabled. | ||
| if (withBodyParser) { | ||
| // Parse the incoming request body. This is needed by Passport spid strategy. | ||
| app.use(bodyParser.json()); | ||
|
|
||
| // Parse an urlencoded body. | ||
| app.use(bodyParser.urlencoded({ extended: true })); | ||
| // Parse an urlencoded body. | ||
| app.use(bodyParser.urlencoded({ extended: true })); | ||
| } | ||
|
|
||
| // | ||
| // Define the folder that contains the public assets. | ||
| // | ||
|
|
||
| app.use(express.static("public")); | ||
| app.get(/(\.html|\.svg|\.png)$/, async (req, res, next) => { | ||
|
||
| try { | ||
| const path = "public" + req.path; | ||
| if (!fs.existsSync(path)) { | ||
| return next(); | ||
| } | ||
| const stat = await fs.promises.stat(path); | ||
| if (stat.isDirectory()) { | ||
| return next(); | ||
| } | ||
| const type = mime.lookup(path); | ||
| if (type) { | ||
| const charset = mime.charsets.lookup(type); | ||
| res.setHeader( | ||
| "Content-Type", | ||
| // tslint:disable-next-line: restrict-plus-operands | ||
| type + (charset ? `; charset=${charset}` : "") | ||
| ); | ||
| } | ||
| const content = await fs.promises.readFile(path); | ||
| res.setHeader("Content-Length", stat.size); | ||
| res.status(200).send(content); | ||
| } catch (err) { | ||
| log.error(`static|Error retrieving static file asset|error:%s`, err); | ||
| return next(err); | ||
| } | ||
|
||
| }); | ||
|
|
||
| // | ||
| // Initializes Passport for incoming requests. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does SPID login work without this?