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."
+ );
+ });
+ });
+});