diff --git a/lib/package/plugins/PD002-emptyRouteRules.js b/lib/package/plugins/PD002-emptyRouteRules.js index 7e26608..156e516 100644 --- a/lib/package/plugins/PD002-emptyRouteRules.js +++ b/lib/package/plugins/PD002-emptyRouteRules.js @@ -1,5 +1,5 @@ /* - Copyright 2019 Google LLC + Copyright 2019-2024 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,40 +15,46 @@ */ const ruleId = require("../myUtil.js").getRuleId(); - //debug = require("debug")("apigeelint:" + ruleId); const plugin = { - ruleId, - name: "Unreachable Route Rules - Defaults", - message: - "Check RouteRules in a ProxyEndpoint to ensure that one and only one has a blank set of conditions.", - fatal: false, - severity: 2, //error - nodeType: "RouteRule", - enabled: true - }; - -const onProxyEndpoint = function(ep, cb) { - let routeRules = ep.getRouteRules(), - hadError = false; + ruleId, + name: "Unconditional Route Rule Structure", + message: + "Check RouteRules in a ProxyEndpoint to ensure that one and only one has a blank set of conditions.", + fatal: false, + severity: 2, //2=error + nodeType: "RouteRule", + enabled: true +}; + +const onProxyEndpoint = function (ep, cb) { + const routeRules = ep.getRouteRules(); + let hadError = false; if (routeRules) { - let blankRR = routeRules.filter( rr => - !rr.getCondition() || - rr.getCondition().getExpression() === ""); + const blankRR = routeRules.filter( + (rr) => !rr.getCondition() || rr.getCondition().getExpression() === "" + ); if (blankRR.length > 1) { - blankRR.forEach( rr => - ep.addMessage({ - plugin, - source: rr.getSource(), - line: rr.getElement().lineNumber, - column: rr.getElement().columnNumber, - message: `Multiple RouteRules with no Condition. Only the first is evaluated.` - })); + blankRR.slice(1).forEach((rr) => + ep.addMessage({ + plugin, + source: rr.getSource(), + line: rr.getElement().lineNumber, + column: rr.getElement().columnNumber, + message: `Multiple RouteRules with no Condition. Only the first is evaluated.` + }) + ); hadError = true; + } else if (blankRR.length == 0) { + ep.addMessage({ + plugin, + severity: 1, //1=warning + message: `There is no RouteRule with no Condition. Your proxy may not operate correctly.` + }); } } - if (typeof(cb) == 'function') { + if (typeof cb == "function") { cb(null, hadError); } }; diff --git a/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/failed-route.xml b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/failed-route.xml new file mode 100644 index 0000000..191e64a --- /dev/null +++ b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/failed-route.xml @@ -0,0 +1,4 @@ + + + failed-route + diff --git a/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Clean-Request-Headers-From-Response.xml b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Clean-Request-Headers-From-Response.xml new file mode 100644 index 0000000..0705cbd --- /dev/null +++ b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Clean-Request-Headers-From-Response.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + diff --git a/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Inject-Proxy-Revision-Header.xml b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Inject-Proxy-Revision-Header.xml new file mode 100644 index 0000000..fcf6c0a --- /dev/null +++ b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Inject-Proxy-Revision-Header.xml @@ -0,0 +1,7 @@ + + + +
{apiproxy.name} r{apiproxy.revision}
+
+
+
diff --git a/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Response.xml b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Response.xml new file mode 100644 index 0000000..f976727 --- /dev/null +++ b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/AM-Response.xml @@ -0,0 +1,12 @@ + + true + + { + "status" : "ok" +} + + OK + 200 + + response + diff --git a/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/RF-Unknown-Request.xml b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/RF-Unknown-Request.xml new file mode 100644 index 0000000..9f5f7fe --- /dev/null +++ b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/policies/RF-Unknown-Request.xml @@ -0,0 +1,16 @@ + + true + + + { + "error" : { + "code" : 404.01, + "message" : "that request was unknown; try a different request." + } +} + + 404 + Not Found + + + diff --git a/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/proxies/endpoint1.xml b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/proxies/endpoint1.xml new file mode 100644 index 0000000..983255c --- /dev/null +++ b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/proxies/endpoint1.xml @@ -0,0 +1,79 @@ + + Proxy Endpoint 1 + + /failed-route + + + + + + AM-Inject-Proxy-Revision-Header + + true + + + + + + + + AM-Clean-Request-Headers-From-Response + + + + + + + + + + AM-Inject-Proxy-Revision-Header + + + + + + + + + + + + + + + + + + + AM-Response + + + (proxy.pathsuffix MatchesPath "/t1") and (request.verb = "GET") + + + + + + RF-Unknown-Request + + + + + + + + + + target-1 + proxy.pathsuffix = "/foobar" + + + + + diff --git a/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/targets/target-1.xml b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/targets/target-1.xml new file mode 100644 index 0000000..0dbc6c2 --- /dev/null +++ b/test/fixtures/resources/PD002-no-unconditional-routerule/apiproxy/targets/target-1.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + true + true + false + + + https://echo.dchiesa.demo.altostrat.com + + diff --git a/test/specs/PD002-at-least-one-unconditional-RouteRule.js b/test/specs/PD002-at-least-one-unconditional-RouteRule.js new file mode 100644 index 0000000..9d05096 --- /dev/null +++ b/test/specs/PD002-at-least-one-unconditional-RouteRule.js @@ -0,0 +1,69 @@ +/* + Copyright 2019-2024 Google LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* global describe, it */ + +const ruleId = "PD002", + assert = require("assert"), + path = require("path"), + util = require("util"), + debug = require("debug")(`apigeelint:${ruleId}`), + bl = require("../../lib/package/bundleLinter.js"); + +describe(`${ruleId} - bundle with no unconditional route`, () => { + it("should generate the expected errors", () => { + const configuration = { + debug: true, + source: { + type: "filesystem", + path: path.resolve( + __dirname, + "../fixtures/resources/PD002-no-unconditional-routerule/apiproxy" + ), + bundleType: "apiproxy" + }, + profile: "apigeex", + excluded: { TD004: true, TD002: true }, + setExitCode: false, + output: () => {} // suppress output + }; + + bl.lint(configuration, (bundle) => { + const items = bundle.getReport(); + assert.ok(items); + assert.ok(items.length); + const actualErrors = items.filter( + (item) => item.messages && item.messages.length + ); + assert.ok(actualErrors.length); + debug(util.format(actualErrors)); + debug(JSON.stringify(actualErrors)); + + const ep1 = actualErrors.find((e) => + e.filePath.endsWith("endpoint1.xml") + ); + assert.ok(ep1); + debug(util.format(ep1.messages)); + const pd002Messages = ep1.messages.filter((m) => m.ruleId == "PD002"); + assert.equal(pd002Messages.length, 1); + assert.ok(pd002Messages[0].message); + assert.equal( + pd002Messages[0].message, + "There is no RouteRule with no Condition. Your proxy may not operate correctly." + ); + }); + }); +});