From ffa6e10c448771914b018b6840b6061d631c2777 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 15 Sep 2023 15:53:41 +0200 Subject: [PATCH 01/93] doc: Architectural Decision Records --- .../workflows/close_stale_pr_and_issues.yml | 4 +- ADRs.md | 94 +++++++++++++++++++ ARCHITECTURE.md | 6 +- CODE_CONVENTIONS.md | 25 ++--- ISSUE_TEMPLATE/ADR.md | 32 +++++++ .../ISSUE_TEMPLATE.md | 0 .../transit/service/StopModel.java | 2 + 7 files changed, 145 insertions(+), 18 deletions(-) create mode 100644 ADRs.md create mode 100644 ISSUE_TEMPLATE/ADR.md rename ISSUE_TEMPLATE => ISSUE_TEMPLATE/ISSUE_TEMPLATE.md (100%) diff --git a/.github/workflows/close_stale_pr_and_issues.yml b/.github/workflows/close_stale_pr_and_issues.yml index 98619f7e763..0c337fbc485 100644 --- a/.github/workflows/close_stale_pr_and_issues.yml +++ b/.github/workflows/close_stale_pr_and_issues.yml @@ -20,5 +20,7 @@ jobs: days-before-stale: 90 days-before-close: 30 operations-per-run: 260 - exempt-issue-labels: 'Roadmap' + exempt-issue-labels: + - 'Roadmap' + - 'ADR' ascending: true diff --git a/ADRs.md b/ADRs.md new file mode 100644 index 00000000000..27fa73faf8c --- /dev/null +++ b/ADRs.md @@ -0,0 +1,94 @@ +# Architectural Decision Records (ADRs) + +An Architectural Decision (AD) is a justified software design choice that addresses a functional or +non-functional requirement that is architecturally significant. ([adr.github.io](https://adr.github.io/)) + +## Process + +Architectural decisions we make in the developer meetings are recorded here. If the decision is +small and uncontroversial, but yet important and can be expressed in maximum 2 sentences, we will +list it here without any reference. If the decision require a bit more discussion and explanations +an issue on GitHub should be created - use the template below. + +### How to discuss and document an Architectural Decision + + - [Create a new issue](https://github.com/opentripplanner/OpenTripPlanner/issues/new/choose?template=adr.md) +using the [ADR.md](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/ISSUE_TEMPLATE/ADR.md) +template. + - Make sure to update the main description based on the feedback/discussion and decisions in the + developer meeting. + - The final approval is done in the developer meeting, at least 3 developers representing 3 + different organisations should approve - and no vote against the proposal. If the developers + are not able to agree the PLC can decide. + - Add the ADR to the list below. Maximum two sentences should be used - try to keep it as short as + possible. Remember to link to the discussion. + - References to Architectural Decision Records in reviews can be done by linking or just typing + e.g. `ADR2`. Use the `[ADR1]()` + + +## Records + +### ADR-0 Scout rule +Leave Things BETTER than you found them - clean up code you visit or/and add unit +tests. Expect to include some code cleanup as part of all PRs. + +### ADR-1 Naming +[Follow naming conventions](CODE_CONVENTIONS.md#naming-conventions) . Make sure the +code is easy to read and understand. + +### ADR-2 Code documentation - JavaDoc +Document the business intention and decisions in the relevant code. Do not repeat the logic +expressed in the code. The prefered way is to use JavaDoc, you may have to refactor part of your +code to encapsulate the business logic into a method or class to do this. + +> If you decide to NOT follow an Architectural Decision, then expect to document why. + +**See also** + - [Developers-Guide > Code comments](docs/Developers-Guide.md#code-comments). + - [Codestyle > Javadoc Guidlines](docs/Codestyle.md#javadoc-guidlines) - JavaDoc checklist + +### ADR-3 Code style +OTP uses prettier to format code. For more information on code style see the +[Codestyle](docs/Codestyle.md) document. + +### ADR-4 OOP +Respect Object-Oriented principals + - Honer encapsulation & Single-responsibility principle + - Abstraction - Use interfaces when a module need "someone" to play a role + - Inheritance - Inheritances expresses “is-a” and/or “has-a” relationship, do not use it "just" + to share data/functionality. + - Use polymorphism and not `instanceof`. + +### ADR-5 Dependency injection +Use dependency injection to wire components. You can use manual DI or Dagger. Put the +wiring code in `/configure/Module.java`. + +### ADR-6 Module encapsulation +Keep modules clean. Consider adding an `api`, `spi` and mapping code to +isolate the module from the rest of the code. Avoid circular dependencies between modules. + +### ADR-7 JavaDoc +Document all `public` types, methods and fields. + +### ADR-8 API doc +Document API and configuration parameters. + +### ADR-9 DRY +Keep the code [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) - Do not +repeat yourself. Avoid implementing the same business rule in two places -> refactor. + +### ADR-10 Feature envy +[Feature envy](https://refactoring.guru/smells/feature-envy) + +### ADR-11 Test coverage +All business logic should have unit tests. Keep integration/system tests to a +minimum. Add test at the lowest level practical to test the business feature. Prefer unit tests on +a method over a class, over a module, over the system. + +### ADR-12 Immutable types +Prefer immutable types over mutable. Use builders where appropriate. See +[Records, POJOs and Builders](CODE_CONVENTIONS.md#records-pojos-and-builders) + +### ADR-13 Records +[Avoid using records if you can not encapsulate it properly](CODE_CONVENTIONS.md#records) + diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index dd0f986e518..7233bf9d0b3 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,6 +1,6 @@ # OTP Architecture -OTP is developed over more than 10 years, and most of the design documentation is in the code as +OTP is developed over more than 15 years, and most of the design documentation is in the code as comments and JavaDoc. Over the years the complexity have increased, and the natural developer turnover creates a demand for more architecture and design documentation. The new OTP2 documentation is put together with the source; hopefully making it easier to maintain. Instead of documenting @@ -11,6 +11,10 @@ This document is far from complete - hopefully it can evolve over time and becom introduction to OTP architecture. The OTP project GitHub issues are a good place to look for detailed discussions on many design decisions. +We document Architectural Decision in a log. Make sure you as a developer is familiar with the +decisions and follow them. Reviewers should use them actively when reviewing code and may use them +to ask for changes. + Be sure to also read the [developer documentation](docs/Developers-Guide.md). ## Modules/Components diff --git a/CODE_CONVENTIONS.md b/CODE_CONVENTIONS.md index a9fd73a0497..9a53e32fcc1 100644 --- a/CODE_CONVENTIONS.md +++ b/CODE_CONVENTIONS.md @@ -12,21 +12,6 @@ These conventions are not "hard" rules, and often there might be other forces wh decision in another direction, in that case documenting your choice is often enough to pass the review. -## Best practices - in focus - -- [ ] Document `public` interfaces, classes and methods - especially those part of a module api. -- [ ] Leave Things BETTER than you found them - clean up code you visit or/and add unit tests. -- [ ] [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) - Do not repeat yourself. Avoid implementing the same business rule in two places -> refactor. -- [ ] [Feature envy](https://refactoring.guru/smells/feature-envy) -- [ ] Make types immutable if possible. References to other Entities might need to be mutable, if - so try to init them once, and throw an exception if set again. - Example: - -```java -Builder initStop(Stop stop) { - this.stop = requireNotInitialized(this.stop, stop); -} -``` ## Naming Conventions @@ -104,7 +89,15 @@ stop = stop.copyOf().withPrivateCode("TEX").build(); ## Records, POJOs and Builders We prefer immutable typesafe types over flexibility and "short" class definitions. This make -the code more robust and less error-prune. +the code more robust and less error-prune. References to other entities might need to be mutable, +if so try to init them once, and throw an exception if set again. Example: + +```java +Builder initStop(Stop stop) { + this.stop = requireNotInitialized(this.stop, stop); +} +``` + ### Records diff --git a/ISSUE_TEMPLATE/ADR.md b/ISSUE_TEMPLATE/ADR.md new file mode 100644 index 00000000000..d0d04cc9cf8 --- /dev/null +++ b/ISSUE_TEMPLATE/ADR.md @@ -0,0 +1,32 @@ + + +### Description +*One or two sentences witch goes into the [Architectural Decision Records](../ADRs.md) document +later* + +### Context and Problem Statement +*Describe the context and problem statement, e.g., in free form using two to three sentences. You +may want to articulate the issue in form of a question* + +### Other options + + - + +### Decision & Consequences +Describes the effects of the change. What becomes easier? What will be more difficult? + +#### Positive Consequences + + - + +#### Negative Consequences + + - + +#### Checklist +- [ ] Tag issue with `ADR`. +- [ ] Give it a meaningful title that quickly lets the reader understand what this ADR is all about. +- [ ] Approved in a developer meeting with 3 votes in favor (3 organisations) +- [ ] This issue description is up-to-date with the discussion below. +- [ ] The name and description is added to the + [Architectural Decision Records](../ADRs.md) document and the ADR is linked this issue. diff --git a/ISSUE_TEMPLATE b/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md similarity index 100% rename from ISSUE_TEMPLATE rename to ISSUE_TEMPLATE/ISSUE_TEMPLATE.md diff --git a/src/main/java/org/opentripplanner/transit/service/StopModel.java b/src/main/java/org/opentripplanner/transit/service/StopModel.java index 110260c1cde..ee90bd0ce71 100644 --- a/src/main/java/org/opentripplanner/transit/service/StopModel.java +++ b/src/main/java/org/opentripplanner/transit/service/StopModel.java @@ -23,6 +23,8 @@ /** * Repository for Stop entities. + * + * ARCHITECTURAL_DECISION_RECORDS.md */ public class StopModel implements Serializable { From 37ac87da3eb78ed2580873b749777c364b725409 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 5 Oct 2023 18:18:40 +0200 Subject: [PATCH 02/93] Apply suggestions from code review Co-authored-by: Leonard Ehrenfried --- ADRs.md | 2 +- CODE_CONVENTIONS.md | 2 +- ISSUE_TEMPLATE/ADR.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ADRs.md b/ADRs.md index 27fa73faf8c..b13054aff0e 100644 --- a/ADRs.md +++ b/ADRs.md @@ -53,7 +53,7 @@ OTP uses prettier to format code. For more information on code style see the ### ADR-4 OOP Respect Object-Oriented principals - - Honer encapsulation & Single-responsibility principle + - Honor encapsulation & Single-responsibility principle - Abstraction - Use interfaces when a module need "someone" to play a role - Inheritance - Inheritances expresses “is-a” and/or “has-a” relationship, do not use it "just" to share data/functionality. diff --git a/CODE_CONVENTIONS.md b/CODE_CONVENTIONS.md index 9a53e32fcc1..093c2afdcb5 100644 --- a/CODE_CONVENTIONS.md +++ b/CODE_CONVENTIONS.md @@ -89,7 +89,7 @@ stop = stop.copyOf().withPrivateCode("TEX").build(); ## Records, POJOs and Builders We prefer immutable typesafe types over flexibility and "short" class definitions. This make -the code more robust and less error-prune. References to other entities might need to be mutable, +the code more robust and less error-prone. References to other entities might need to be mutable, if so try to init them once, and throw an exception if set again. Example: ```java diff --git a/ISSUE_TEMPLATE/ADR.md b/ISSUE_TEMPLATE/ADR.md index d0d04cc9cf8..9e32a45204b 100644 --- a/ISSUE_TEMPLATE/ADR.md +++ b/ISSUE_TEMPLATE/ADR.md @@ -1,7 +1,7 @@ ### Description -*One or two sentences witch goes into the [Architectural Decision Records](../ADRs.md) document +*One or two sentences which goes into the [Architectural Decision Records](../ADRs.md) document later* ### Context and Problem Statement From 247ec7d629ffb7b1293a4887a23895d1708fa305 Mon Sep 17 00:00:00 2001 From: Andrew Byrd Date: Thu, 25 Jan 2024 20:19:19 +0800 Subject: [PATCH 03/93] Rewording in ARCHITECTURE.md Co-authored-by: Jim Martens --- ARCHITECTURE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 7233bf9d0b3..ece6cf811dd 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,6 +1,6 @@ # OTP Architecture -OTP is developed over more than 15 years, and most of the design documentation is in the code as +OTP has been developed for more than 15 years, and most of the design documentation is in the code as comments and JavaDoc. Over the years the complexity have increased, and the natural developer turnover creates a demand for more architecture and design documentation. The new OTP2 documentation is put together with the source; hopefully making it easier to maintain. Instead of documenting From 254657f4b478d7fdc8a3e06908fba4d5b1523b3a Mon Sep 17 00:00:00 2001 From: Andrew Byrd Date: Thu, 25 Jan 2024 20:50:06 +0800 Subject: [PATCH 04/93] add ADR for dependency injection --- ADRs.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ADRs.md b/ADRs.md index b13054aff0e..3bcd7213e91 100644 --- a/ADRs.md +++ b/ADRs.md @@ -92,3 +92,10 @@ Prefer immutable types over mutable. Use builders where appropriate. See ### ADR-13 Records [Avoid using records if you can not encapsulate it properly](CODE_CONVENTIONS.md#records) +### ADR-14 Dependency Injection +OTP will use a dependency injection library or framework to handle object lifecycles (particularly +request-scoped vs. singleton scoped) and ensure selective availability of components, services, +context, and configuration at their site of use. Systems that operate via imperative Java code +(whether hand-written or generated) will be preferred over those operating through reflection or +external markup files. See [additional background](https://github.com/opentripplanner/OpenTripPlanner/pull/5360#issuecomment-1910134299). + From 868582b012da39842afe212bcee87e9e4b16b097 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 2 Jul 2024 17:27:37 +0200 Subject: [PATCH 05/93] Small stylistic changes --- ISSUE_TEMPLATE/ADR.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ISSUE_TEMPLATE/ADR.md b/ISSUE_TEMPLATE/ADR.md index 9e32a45204b..695c75925a5 100644 --- a/ISSUE_TEMPLATE/ADR.md +++ b/ISSUE_TEMPLATE/ADR.md @@ -1,7 +1,7 @@ ### Description -*One or two sentences which goes into the [Architectural Decision Records](../ADRs.md) document +*One or two sentences which go into the [Architectural Decision Records](../ADRs.md) document later* ### Context and Problem Statement @@ -26,7 +26,7 @@ Describes the effects of the change. What becomes easier? What will be more diff #### Checklist - [ ] Tag issue with `ADR`. - [ ] Give it a meaningful title that quickly lets the reader understand what this ADR is all about. -- [ ] Approved in a developer meeting with 3 votes in favor (3 organisations) -- [ ] This issue description is up-to-date with the discussion below. -- [ ] The name and description is added to the +- [ ] Get it approved in a developer meeting with 3 votes in favor (3 organisations). +- [ ] Update the issue description is up-to-date with the discussion below. +- [ ] Add name and description to the [Architectural Decision Records](../ADRs.md) document and the ADR is linked this issue. From 4253f3239bdddcebb53af92b4f8669890d5bd421 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 3 Jul 2024 11:58:59 +0200 Subject: [PATCH 06/93] Revert changes made to StopModel --- .../java/org/opentripplanner/transit/service/StopModel.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/transit/service/StopModel.java b/src/main/java/org/opentripplanner/transit/service/StopModel.java index ee90bd0ce71..110260c1cde 100644 --- a/src/main/java/org/opentripplanner/transit/service/StopModel.java +++ b/src/main/java/org/opentripplanner/transit/service/StopModel.java @@ -23,8 +23,6 @@ /** * Repository for Stop entities. - * - * ARCHITECTURAL_DECISION_RECORDS.md */ public class StopModel implements Serializable { From c1bcfddc7e6e0489ff754b93f61eab6f08fbb725 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 3 Jul 2024 12:38:25 +0200 Subject: [PATCH 07/93] doc: Update ADR-11 --- ADRs.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ADRs.md b/ADRs.md index 3bcd7213e91..5fa3ad2d923 100644 --- a/ADRs.md +++ b/ADRs.md @@ -81,9 +81,11 @@ repeat yourself. Avoid implementing the same business rule in two places -> refa [Feature envy](https://refactoring.guru/smells/feature-envy) ### ADR-11 Test coverage -All business logic should have unit tests. Keep integration/system tests to a -minimum. Add test at the lowest level practical to test the business feature. Prefer unit tests on -a method over a class, over a module, over the system. +All _business_ logic should have unit tests. Keep integration/system tests to a minimum. Add test at +the lowest level practical to test the business feature. Prefer unit tests on a method over a class, +over a module, over the system. On all non-trivial code full _branch_ test coverage is preferable. +Tests should be designed to genuinely demonstrate correctness or adherence to specifications, not +simply inflate line coverage numbers. ### ADR-12 Immutable types Prefer immutable types over mutable. Use builders where appropriate. See From 6b8da31fd361b38e06bba5eb20ec97dd27ac83e9 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 3 Jul 2024 13:01:06 +0200 Subject: [PATCH 08/93] doc: Add link to ADR.md in ARCHITECTURE.md --- ARCHITECTURE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index ece6cf811dd..ff12aee97d0 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -11,9 +11,9 @@ This document is far from complete - hopefully it can evolve over time and becom introduction to OTP architecture. The OTP project GitHub issues are a good place to look for detailed discussions on many design decisions. -We document Architectural Decision in a log. Make sure you as a developer is familiar with the -decisions and follow them. Reviewers should use them actively when reviewing code and may use them -to ask for changes. +We document [Architectural Decision](ADRs.md) in a log. Make sure you as a developer are familiar +with the decisions and follow them. Reviewers should use them actively when reviewing code and may +use them to ask for changes. Be sure to also read the [developer documentation](docs/Developers-Guide.md). From 5a0da59e2be315d5682eb04b91176e1a45aac2da Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 3 Jul 2024 13:13:39 +0200 Subject: [PATCH 09/93] doc: Title Case --- ADRs.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ADRs.md b/ADRs.md index 5fa3ad2d923..757891f3b8e 100644 --- a/ADRs.md +++ b/ADRs.md @@ -36,7 +36,7 @@ tests. Expect to include some code cleanup as part of all PRs. [Follow naming conventions](CODE_CONVENTIONS.md#naming-conventions) . Make sure the code is easy to read and understand. -### ADR-2 Code documentation - JavaDoc +### ADR-2 Code Documentation - JavaDoc Document the business intention and decisions in the relevant code. Do not repeat the logic expressed in the code. The prefered way is to use JavaDoc, you may have to refactor part of your code to encapsulate the business logic into a method or class to do this. @@ -59,11 +59,11 @@ Respect Object-Oriented principals to share data/functionality. - Use polymorphism and not `instanceof`. -### ADR-5 Dependency injection +### ADR-5 Dependency Injection Use dependency injection to wire components. You can use manual DI or Dagger. Put the wiring code in `/configure/Module.java`. -### ADR-6 Module encapsulation +### ADR-6 Module Encapsulation Keep modules clean. Consider adding an `api`, `spi` and mapping code to isolate the module from the rest of the code. Avoid circular dependencies between modules. @@ -77,17 +77,17 @@ Document API and configuration parameters. Keep the code [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) - Do not repeat yourself. Avoid implementing the same business rule in two places -> refactor. -### ADR-10 Feature envy +### ADR-10 Avoid Feature Envy [Feature envy](https://refactoring.guru/smells/feature-envy) -### ADR-11 Test coverage +### ADR-11 Test Coverage All _business_ logic should have unit tests. Keep integration/system tests to a minimum. Add test at the lowest level practical to test the business feature. Prefer unit tests on a method over a class, over a module, over the system. On all non-trivial code full _branch_ test coverage is preferable. Tests should be designed to genuinely demonstrate correctness or adherence to specifications, not simply inflate line coverage numbers. -### ADR-12 Immutable types +### ADR-12 Immutable Types Prefer immutable types over mutable. Use builders where appropriate. See [Records, POJOs and Builders](CODE_CONVENTIONS.md#records-pojos-and-builders) From 27eb36ca5518866c71f1656bcf334f5c22a3f8a4 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jul 2024 15:46:23 +0200 Subject: [PATCH 10/93] Cleanup decision records based on reviews. --- ADRs.md | 103 ------------ ARCHITECTURE.md | 6 +- DECISION_RECORDS.md | 106 +++++++++++++ ISSUE_TEMPLATE/ADR.md | 32 ---- .../dev/decisionrecords}/Codestyle.md | 2 +- .../dev/decisionrecords/NamingConventions.md | 148 +----------------- .../decisionrecords/RecordsPOJOsBuilders.md | 112 +++++++++++++ doc/dev/decisionrecords/UseDecisionRecords.md | 37 +++++ doc/dev/decisionrecords/_TEMPLATE.md | 31 ++++ docs/Developers-Guide.md | 2 +- 10 files changed, 299 insertions(+), 280 deletions(-) delete mode 100644 ADRs.md create mode 100644 DECISION_RECORDS.md delete mode 100644 ISSUE_TEMPLATE/ADR.md rename {docs => doc/dev/decisionrecords}/Codestyle.md (98%) rename CODE_CONVENTIONS.md => doc/dev/decisionrecords/NamingConventions.md (57%) create mode 100644 doc/dev/decisionrecords/RecordsPOJOsBuilders.md create mode 100644 doc/dev/decisionrecords/UseDecisionRecords.md create mode 100644 doc/dev/decisionrecords/_TEMPLATE.md diff --git a/ADRs.md b/ADRs.md deleted file mode 100644 index 757891f3b8e..00000000000 --- a/ADRs.md +++ /dev/null @@ -1,103 +0,0 @@ -# Architectural Decision Records (ADRs) - -An Architectural Decision (AD) is a justified software design choice that addresses a functional or -non-functional requirement that is architecturally significant. ([adr.github.io](https://adr.github.io/)) - -## Process - -Architectural decisions we make in the developer meetings are recorded here. If the decision is -small and uncontroversial, but yet important and can be expressed in maximum 2 sentences, we will -list it here without any reference. If the decision require a bit more discussion and explanations -an issue on GitHub should be created - use the template below. - -### How to discuss and document an Architectural Decision - - - [Create a new issue](https://github.com/opentripplanner/OpenTripPlanner/issues/new/choose?template=adr.md) -using the [ADR.md](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/ISSUE_TEMPLATE/ADR.md) -template. - - Make sure to update the main description based on the feedback/discussion and decisions in the - developer meeting. - - The final approval is done in the developer meeting, at least 3 developers representing 3 - different organisations should approve - and no vote against the proposal. If the developers - are not able to agree the PLC can decide. - - Add the ADR to the list below. Maximum two sentences should be used - try to keep it as short as - possible. Remember to link to the discussion. - - References to Architectural Decision Records in reviews can be done by linking or just typing - e.g. `ADR2`. Use the `[ADR1]()` - - -## Records - -### ADR-0 Scout rule -Leave Things BETTER than you found them - clean up code you visit or/and add unit -tests. Expect to include some code cleanup as part of all PRs. - -### ADR-1 Naming -[Follow naming conventions](CODE_CONVENTIONS.md#naming-conventions) . Make sure the -code is easy to read and understand. - -### ADR-2 Code Documentation - JavaDoc -Document the business intention and decisions in the relevant code. Do not repeat the logic -expressed in the code. The prefered way is to use JavaDoc, you may have to refactor part of your -code to encapsulate the business logic into a method or class to do this. - -> If you decide to NOT follow an Architectural Decision, then expect to document why. - -**See also** - - [Developers-Guide > Code comments](docs/Developers-Guide.md#code-comments). - - [Codestyle > Javadoc Guidlines](docs/Codestyle.md#javadoc-guidlines) - JavaDoc checklist - -### ADR-3 Code style -OTP uses prettier to format code. For more information on code style see the -[Codestyle](docs/Codestyle.md) document. - -### ADR-4 OOP -Respect Object-Oriented principals - - Honor encapsulation & Single-responsibility principle - - Abstraction - Use interfaces when a module need "someone" to play a role - - Inheritance - Inheritances expresses “is-a” and/or “has-a” relationship, do not use it "just" - to share data/functionality. - - Use polymorphism and not `instanceof`. - -### ADR-5 Dependency Injection -Use dependency injection to wire components. You can use manual DI or Dagger. Put the -wiring code in `/configure/Module.java`. - -### ADR-6 Module Encapsulation -Keep modules clean. Consider adding an `api`, `spi` and mapping code to -isolate the module from the rest of the code. Avoid circular dependencies between modules. - -### ADR-7 JavaDoc -Document all `public` types, methods and fields. - -### ADR-8 API doc -Document API and configuration parameters. - -### ADR-9 DRY -Keep the code [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) - Do not -repeat yourself. Avoid implementing the same business rule in two places -> refactor. - -### ADR-10 Avoid Feature Envy -[Feature envy](https://refactoring.guru/smells/feature-envy) - -### ADR-11 Test Coverage -All _business_ logic should have unit tests. Keep integration/system tests to a minimum. Add test at -the lowest level practical to test the business feature. Prefer unit tests on a method over a class, -over a module, over the system. On all non-trivial code full _branch_ test coverage is preferable. -Tests should be designed to genuinely demonstrate correctness or adherence to specifications, not -simply inflate line coverage numbers. - -### ADR-12 Immutable Types -Prefer immutable types over mutable. Use builders where appropriate. See -[Records, POJOs and Builders](CODE_CONVENTIONS.md#records-pojos-and-builders) - -### ADR-13 Records -[Avoid using records if you can not encapsulate it properly](CODE_CONVENTIONS.md#records) - -### ADR-14 Dependency Injection -OTP will use a dependency injection library or framework to handle object lifecycles (particularly -request-scoped vs. singleton scoped) and ensure selective availability of components, services, -context, and configuration at their site of use. Systems that operate via imperative Java code -(whether hand-written or generated) will be preferred over those operating through reflection or -external markup files. See [additional background](https://github.com/opentripplanner/OpenTripPlanner/pull/5360#issuecomment-1910134299). - diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index ff12aee97d0..d73b09edc31 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -7,11 +7,11 @@ is put together with the source; hopefully making it easier to maintain. Instead modules in old style _package-info.java_ files we use _package.md_ files. This document should serve as an index to all existing top-level documented components. -This document is far from complete - hopefully it can evolve over time and become a good +This document is far from complete. Hopefully it can evolve over time and become a good introduction to OTP architecture. The OTP project GitHub issues are a good place to look for detailed discussions on many design decisions. -We document [Architectural Decision](ADRs.md) in a log. Make sure you as a developer are familiar +We document [Decision Records](DECISION_RECORDS.md) in a log. Make sure you as a developer are familiar with the decisions and follow them. Reviewers should use them actively when reviewing code and may use them to ask for changes. @@ -30,7 +30,7 @@ examples. The Transit model is more complex than the VehiclePosition model. class has the same name as the interface with prefix `Default`. - `Domain Model` A model witch encapsulate a business area. In the drawing two examples are shown, the `transit` and `vhicleposition` domain model. The transit model is more complex so the - implementation have a separate `Service` and `Repository`. Almost all http endpoints are , + implementation has a separate `Service` and `Repository`. Almost all http endpoints are, read-only so the `Service` can focus on serving the http API endpoints, while the repository is used to maintain the model by the updaters. diff --git a/DECISION_RECORDS.md b/DECISION_RECORDS.md new file mode 100644 index 00000000000..dbe044c6168 --- /dev/null +++ b/DECISION_RECORDS.md @@ -0,0 +1,106 @@ +# Records + + +## Use-Decision-Records + +We will [use decision-records](doc/dev/decisionrecords/UseDecisionRecords.md) to document OTP +development relevant decision. Use the [template](doc/dev/decisionrecords/_TEMPLATE.md) to describe +new decision records. + + +## Scout-Rule + +Leave things BETTER than you found them, clean up code you visit or/and add unit +tests. Expect to include some code cleanup as part of all PRs. + +## Follow-Naming-Conventions + +Use established terminology from GTFS, NeTEx or the existing OTP code. Make sure the code is easy +to read and understand. [Follow naming conventions](CODE_CONVENTIONS.md#naming-conventions) . + + +## Write-Code-Documentation - Use JavaDoc + +Document the business intention and decisions in the relevant code. Do not repeat the logic +expressed in the code. Use JavaDoc, you may have to refactor part of your code to encapsulate the +business logic into a method or class to do this. + +Document all `public` types, methods and fields with JavaDoc. It is ok to document implementation +notes on `private` members and as inline comments. + +> If you decide to NOT follow these decision records, then you must document why. + +**See also** + - [Developers-Guide > Code comments](docs/Developers-Guide.md#code-comments). + - [Codestyle > Javadoc Guidlines](doc/dev/decisionrecords/Codestyle.md#javadoc-guidlines) - JavaDoc checklist + + +## Document-Config-and-APIs + +Document API and configuration parameters. + + +## Respect-Codestyle + +OTP uses prettier to format code. For more information on code style see the +[Codestyle](doc/dev/decisionrecords/Codestyle.md) document. + + +## Use-Object-Oriented-Principals + +Respect Object-Oriented principals + - Honor encapsulation & Single-responsibility principle + - Abstraction - Use interfaces when a module needs "someone" to play a role + - Inheritance - Inheritances expresses “is-a” and/or “has-a” relationship, do not use it "just" + to share data/functionality. + - Use polymorphism and not `instanceof`. + + +## Use-Dependency-Injection + +Use dependency injection to wire components. You can use manual DI or Dagger. Put the +wiring code in `/configure/Module.java`. + +OTP will use a dependency injection library or framework to handle object lifecycles (particularly +request-scoped vs. singleton scoped) and ensure selective availability of components, services, +context, and configuration at their site of use. Systems that operate via imperative Java code +(whether hand-written or generated) will be preferred over those operating through reflection or +external markup files. See [additional background](https://github.com/opentripplanner/OpenTripPlanner/pull/5360#issuecomment-1910134299). + +## Use-Module-Encapsulation + +Keep modules clean. Consider adding an `api`, `spi` and mapping code to +isolate the module from the rest of the code. Avoid circular dependencies between modules. + + +## DRY - Do not repeat yourself + +Keep the code [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) - Do not +repeat yourself. Avoid implementing the same business rule in two places -> refactor. + + +## Avoid-Feature-Envy + +[Feature envy](https://refactoring.guru/smells/feature-envy) + + +## Test-Coverage + +All _business_ logic should have unit tests. Keep integration/system tests to a minimum. Add test at +the lowest level practical to test the business feature. Prefer unit tests on a method over a class, +over a module, over the system. On all non-trivial code, full _branch_ test coverage is preferable. +Tests should be designed to genuinely demonstrate correctness or adherence to specifications, not +simply inflate line coverage numbers. + + +## Use-Immutable-Types + +Prefer immutable types over mutable. Use builders where appropriate. See +[Records, POJOs and Builders](doc/dev/decisionrecords/RecordsPOJOsBuilders.md#records-pojos-and-builders) + + +## Be-Careful-With-Records + +[Avoid using records if you cannot encapsulate it properly](doc/dev/decisionrecords/RecordsPOJOsBuilders.md#records) + + diff --git a/ISSUE_TEMPLATE/ADR.md b/ISSUE_TEMPLATE/ADR.md deleted file mode 100644 index 695c75925a5..00000000000 --- a/ISSUE_TEMPLATE/ADR.md +++ /dev/null @@ -1,32 +0,0 @@ - - -### Description -*One or two sentences which go into the [Architectural Decision Records](../ADRs.md) document -later* - -### Context and Problem Statement -*Describe the context and problem statement, e.g., in free form using two to three sentences. You -may want to articulate the issue in form of a question* - -### Other options - - - - -### Decision & Consequences -Describes the effects of the change. What becomes easier? What will be more difficult? - -#### Positive Consequences - - - - -#### Negative Consequences - - - - -#### Checklist -- [ ] Tag issue with `ADR`. -- [ ] Give it a meaningful title that quickly lets the reader understand what this ADR is all about. -- [ ] Get it approved in a developer meeting with 3 votes in favor (3 organisations). -- [ ] Update the issue description is up-to-date with the discussion below. -- [ ] Add name and description to the - [Architectural Decision Records](../ADRs.md) document and the ADR is linked this issue. diff --git a/docs/Codestyle.md b/doc/dev/decisionrecords/Codestyle.md similarity index 98% rename from docs/Codestyle.md rename to doc/dev/decisionrecords/Codestyle.md index d127ff21e5c..f5b10d669c7 100644 --- a/docs/Codestyle.md +++ b/doc/dev/decisionrecords/Codestyle.md @@ -51,7 +51,7 @@ Editor > Code Style_. Then select **Project** in the \_Scheme drop down. You can run the Prettier Maven plugin as an external tool in IntelliJ. Set it up as an `External tool` and assign a key-shortcut to the tool execution. -![External Tool Dialog](images/ExternalToolDialog.png) +![External Tool Dialog](../../../docs/images/ExternalToolDialog.png) ``` Name: Prettier Format Current File diff --git a/CODE_CONVENTIONS.md b/doc/dev/decisionrecords/NamingConventions.md similarity index 57% rename from CODE_CONVENTIONS.md rename to doc/dev/decisionrecords/NamingConventions.md index 093c2afdcb5..97d89404942 100644 --- a/CODE_CONVENTIONS.md +++ b/doc/dev/decisionrecords/NamingConventions.md @@ -1,21 +1,6 @@ -# Code Conventions +# Naming Conventions -We try to follow these conventions or best practices. The goal is to get cleaner code and make the -review process easier: - -- the developer knows what to expect -- the reviewer knows what to look for -- discussions and personal preferences can be avoided saving time -- new topics should be documented here - -These conventions are not "hard" rules, and often there might be other forces which pull a -decision in another direction, in that case documenting your choice is often enough to pass the -review. - - -## Naming Conventions - -### Packages +## Packages Try to arrange code by domain functionality, not technology. The main structure of a package should be `org.opentripplanner...`. @@ -34,14 +19,14 @@ be `org.opentripplanner...`. | `util` | General "util" functionality, often characterized by `static` methods. Dependencies to other OTP packages is NOT allowed, only 3rd party utils libs. | | `o.o.apis` | OTP external endpoints. Note! Many apis are in the Sandbox where they are in the `o.o.ext` package. | -> **Note!** The above is the goal, the current package structure needs cleanup. +> **Note!** The above is the goal, the current package structure needs cleanup. > **Note!** Util methods depending on an OTP type/component should go into that type/component, not in the -utils class. E.g. static factory methods. Warning the "pure" utilities right now are placed into +utils class. E.g. static factory methods. Warning the "pure" utilities right now are placed into sub-packages of `o.o.util`, the root package needs cleanup. -### Methods +## Methods Here are a list of common prefixes used, and what to expect. @@ -67,15 +52,15 @@ These prefixes are also "allowed", but not preferred - they have some kind of ne | `setStop(Stop stop)` | Set a mutable stop reference. Avoid if not part of natural lifecycle. Use `initStop(...)` if possible | | `getStop() : Stop` | Old style accessor, use the shorter form `stop() : Stop` | -### Service, Model and Repository +## Service, Model and Repository -![MainModelOverview](docs/images/ServiceModelOverview.png) +![MainModelOverview](docs/images/ServiceModelOverview.png) Naming convention for builders with and without a context. -##### Graph Build and tests run without a context +#### Graph Build and tests run without a context ```Java // Create a new Stop @@ -84,120 +69,3 @@ trip = Trip.of(id).withName("The Express").build(); // Modify and existing stop stop = stop.copyOf().withPrivateCode("TEX").build(); ``` - - -## Records, POJOs and Builders - -We prefer immutable typesafe types over flexibility and "short" class definitions. This make -the code more robust and less error-prone. References to other entities might need to be mutable, -if so try to init them once, and throw an exception if set again. Example: - -```java -Builder initStop(Stop stop) { - this.stop = requireNotInitialized(this.stop, stop); -} -``` - - -### Records - -You may use records, but avoid using records if you can not encapsulate it properly. Be especially -aware of arrays fields (can not be protected) and collections (remember to make a defensive copy). -If you need to override `equals` and `hashCode`, then it is probably not worth it. -Be aware that `equals` compare references, not the value of a field. Consider overriding `toString`. - -### Builders - -OTP used a simple builder pattern in many places, especially when creating immutable types. - -#### Builder conventions -- Use factory methods to create builder, either `of()` or `copyOf()`. The _copyOf_ uses an existing - instance as its base. The `of()` creates a builder with all default values set. All constructors - should be private (or package local) to enforce the use of the factory methods. -- If the class have more than 5 fields avoid using an inner class builder, instead create a builder - in the same package. -- Make all fields in the main class final to enforce immutability. -- Consider using utility methods for parameter checking, like `Objects#requireNonNull` and - `ObjectUtils.ifNotNull`. -- Validate all fields in the main type constructor(i.e. not in the builder), especially null checks. - Prefer default values over null-checks. All business logic using the type can rely on its validity. -- You may keep the original instance in the builder to avoid creating a new object if nothing - changed. This prevents polluting the heap for long-lived objects and make comparison very fast. -- There is no need to provide all get accessors in the Builder if not needed. -- Unit-test builders and verify all fields are copied over. -- For nested builders see the field `nested` in the example. - -
- Builder example - -```Java -/** - * THIS CLASS IS IMMUTABLE AND THREAD-SAFE - */ -public class A { - public static final A DEFAULT = new A(); - private final List names; - private final int age; - private final B nested; - - private A() { - this.names = List.of("default"); - this.age = 7; - this.nested = B.of(); - } - - private A(Builder builder) { - this.names = List.copyOf(builder.names); - this.age = builder.age; - this.nested = builder.nested(); - - if(age < 0 || age > 150) { - throw new IllegalArgumentException("Age is out of range[0..150]: " + age); - } - } - - public static A.Builder of() { return DEFAULT.copyOf(); } - public A.Builder copyOf() { return new Builder(this); } - - public List listNames() { return names; } - public int age() { return age; } - - public boolean equals(Object other) { ... } - public int hashCode() { ... } - public String toString() { return ToStringBuilder.of(A.class)...; } - - public static class Builder { - private final A original; - private final List names; - private int age; - private B.Builder nested = null; - - public Builder(A original) { - this.original = original; - this.names = new ArrayList<>(original.names); - this.age = original.age; - } - - public Builder withName(String name) { this.names.add(name); return this; } - - public int age() { return age; } - public Builder withAge(int age) { this.age = age; return this; } - - private B nested() { return nested==null ? original.nested() : nested.build(); } - public Builder withB(Consumer body) { - if(nested == null) { nested = original.nested.copyOf(); } - body.accept(nested); - return this; - } - public A build() { - A value = new A(this); - return original.equals(value) ? original : value; - } - } -} -``` - -
- - - diff --git a/doc/dev/decisionrecords/RecordsPOJOsBuilders.md b/doc/dev/decisionrecords/RecordsPOJOsBuilders.md new file mode 100644 index 00000000000..34019d503e6 --- /dev/null +++ b/doc/dev/decisionrecords/RecordsPOJOsBuilders.md @@ -0,0 +1,112 @@ +## Records, POJOs and Builders + +We prefer immutable typesafe types over flexibility and "short" class definitions. This makes +the code more robust and less error-prone. References to other entities might need to be mutable, +if so try to init them once, and throw an exception if set again. Example: + +```java +Builder initStop(Stop stop) { + this.stop = requireNotInitialized(this.stop, stop); +} +``` + + +### Records + +You may use records, but avoid using records if you can not encapsulate it properly. Be especially +aware of arrays fields (can not be protected) and collections (remember to make a defensive copy). +If you need to override `equals` and `hashCode`, then it is probably not worth it. +Be aware that `equals` compare references, not the value of a field. Consider overriding `toString`. + +### Builders + +OTP used a simple builder pattern in many places, especially when creating immutable types. + +#### Builder conventions +- Use factory methods to create builder, either `of()` or `copyOf()`. The _copyOf_ uses an existing + instance as its base. The `of()` creates a builder with all default values set. All constructors + should be private (or package local) to enforce the use of the factory methods. +- If the class has more than 5 fields, then avoid using an inner class builder, instead create a + builder in the same package. +- Make all fields in the main class final to enforce immutability. +- Consider using utility methods for parameter checking, like `Objects#requireNonNull` and + `ObjectUtils.ifNotNull`. +- Validate all fields in the main type constructor(i.e. not in the builder), especially null checks. + Prefer default values over null-checks. All business logic using the type can rely on its validity. +- You may keep the original instance in the builder to avoid creating a new object if nothing + changed. This prevents polluting the heap for long-lived objects and make comparison very fast. +- There is no need to provide all get accessors in the Builder if not needed. +- Unit-test builders and verify all fields are copied over. +- For nested builders see the field `nested` in the example. + +
+ Builder example + +```Java +/** + * THIS CLASS IS IMMUTABLE AND THREAD-SAFE + */ +public class A { + public static final A DEFAULT = new A(); + private final List names; + private final int age; + private final B nested; + + private A() { + this.names = List.of("default"); + this.age = 7; + this.nested = B.of(); + } + + private A(Builder builder) { + this.names = List.copyOf(builder.names); + this.age = builder.age; + this.nested = builder.nested(); + + if(age < 0 || age > 150) { + throw new IllegalArgumentException("Age is out of range[0..150]: " + age); + } + } + + public static A.Builder of() { return DEFAULT.copyOf(); } + public A.Builder copyOf() { return new Builder(this); } + + public List listNames() { return names; } + public int age() { return age; } + + public boolean equals(Object other) { ... } + public int hashCode() { ... } + public String toString() { return ToStringBuilder.of(A.class)...; } + + public static class Builder { + private final A original; + private final List names; + private int age; + private B.Builder nested = null; + + public Builder(A original) { + this.original = original; + this.names = new ArrayList<>(original.names); + this.age = original.age; + } + + public Builder withName(String name) { this.names.add(name); return this; } + + public int age() { return age; } + public Builder withAge(int age) { this.age = age; return this; } + + private B nested() { return nested==null ? original.nested() : nested.build(); } + public Builder withB(Consumer body) { + if(nested == null) { nested = original.nested.copyOf(); } + body.accept(nested); + return this; + } + public A build() { + A value = new A(this); + return original.equals(value) ? original : value; + } + } +} +``` + +
diff --git a/doc/dev/decisionrecords/UseDecisionRecords.md b/doc/dev/decisionrecords/UseDecisionRecords.md new file mode 100644 index 00000000000..1900218195e --- /dev/null +++ b/doc/dev/decisionrecords/UseDecisionRecords.md @@ -0,0 +1,37 @@ +# Decision Records + +[TODO - Not precise] An OTP Decision Record is a justified software design choice that addresses a +functional or non-functional requirement that is significant. [Architectural Decision Records](https://adr.github.io/) +is a similar concept, but we have widened the scope to include any relevant decision about the +OTP development. + +## Process + +Decisions we make in the developer meetings are recorded in the [Decision Records](/DECISION_RECORDS.md) +list. If the decision is small and uncontroversial, but yet important and can be expressed in +maximum 2 sentences, we will list it here without any more documentation. If the decision requires +a bit more discussion and explanations, then we will create a PR with a document for it. + +Use the **[template](/doc/dev/decisionrecords/_TEMPLATE.md) as a starting point for documenting +the decision. + + +### How to discuss and document a Decision Record + +- Create a new pull-request and describe the decision record by adding a document to the + `/doc/dev/decisionrecords` folder. Use the [template](/doc/dev/decisionrecords/_TEMPLATE.md). + template. +- Present the decision record in a developer meeting. Make sure to update the main description + based on the feedback/discussion and decisions in the developer meeting. +- The final approval is done in the developer meeting, at least 3 developers representing 3 + different organisations should approve it. No vote against the proposal. If the developers + are not able to agree, the PLC can decide. +- References to Architectural Decision Records in reviews can be done by linking or just typing + e.g. `Use-Dependency-Injection` or [Use-Dependency-Injection](/DECISION_RECORDS.md#use-dependency-injection) + +### Checklist +- [ ] Give it a meaningful title that quickly lets the reader understand what it is all about. +- [ ] Get it approved in a developer meeting with 3 votes in favor (3 organisations). +- [ ] Add the name and description to the list in the [Decision Records](/DECISION_RECORDS.md) list. + Maximum two sentences should be used. Try to keep it as short as possible. +- [ ] Remember to link to the PR. diff --git a/doc/dev/decisionrecords/_TEMPLATE.md b/doc/dev/decisionrecords/_TEMPLATE.md new file mode 100644 index 00000000000..f8389d4a551 --- /dev/null +++ b/doc/dev/decisionrecords/_TEMPLATE.md @@ -0,0 +1,31 @@ +# {TITLE} + +{DESCRIPTION} + + +Original pull-request: {#NNNN} + + +### Context and Problem Statement + + + +### Other options + + - + +### Decision & Consequences + + + +#### Positive Consequences + + - + +#### Negative Consequences + + - diff --git a/docs/Developers-Guide.md b/docs/Developers-Guide.md index 5f834580df8..7d05b723ac8 100644 --- a/docs/Developers-Guide.md +++ b/docs/Developers-Guide.md @@ -199,7 +199,7 @@ formats like 02/01/12. ## Code style -The OTP code style is described on a separate [style guide page](Codestyle.md). +The OTP code style is described on a separate [style guide page](../doc/dev/decisionrecords/Codestyle.md). ## Code conventions and architecture From b04d71e7325735ee68ce09be887b6c36e0b3f51b Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jul 2024 18:05:57 +0200 Subject: [PATCH 11/93] Remove codestyle the published OTP user doc --- mkdocs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 7925151ac35..586f78566aa 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -90,7 +90,6 @@ nav: - "Developers' Guide": 'Developers-Guide.md' - Localization: 'Localization.md' - Bibliography: 'Bibliography.md' - - Codestyle: 'Codestyle.md' - Sandbox Development: 'SandboxExtension.md' - Release Checklist: 'ReleaseChecklist.md' - Sandbox: From 42a2f80f62896786a3c9e70182ba010785b40fef Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jul 2024 18:12:37 +0200 Subject: [PATCH 12/93] Fix merrge errors --- .github/ISSUE_TEMPLATE/bug_report.md | 27 +++++++++++++++++++ .../workflows/close_stale_pr_and_issues.yml | 4 +-- ISSUE_TEMPLATE/ISSUE_TEMPLATE.md | 27 ------------------- 3 files changed, 28 insertions(+), 30 deletions(-) delete mode 100644 ISSUE_TEMPLATE/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e69de29bb2d..15e9e772595 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: Bug report +about: Report a bug or issue +title: '' +labels: '' +assignees: '' + +--- + +**NOTE:** this issue system is intended for reporting bugs and tracking progress in software +development. For all other usage and software development questions or discussion, please post a +question in our chat room: https://gitter.im/opentripplanner/OpenTripPlanner. + + +## Expected behavior + +## Observed behavior + +## Version of OTP used (exact commit hash or JAR name) + +## Data sets in use (links to GTFS and OSM PBF files) + +## Command line used to start OTP + +## Router config and graph build config JSON + +## Steps to reproduce the problem diff --git a/.github/workflows/close_stale_pr_and_issues.yml b/.github/workflows/close_stale_pr_and_issues.yml index 0c337fbc485..98619f7e763 100644 --- a/.github/workflows/close_stale_pr_and_issues.yml +++ b/.github/workflows/close_stale_pr_and_issues.yml @@ -20,7 +20,5 @@ jobs: days-before-stale: 90 days-before-close: 30 operations-per-run: 260 - exempt-issue-labels: - - 'Roadmap' - - 'ADR' + exempt-issue-labels: 'Roadmap' ascending: true diff --git a/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md deleted file mode 100644 index 15e9e772595..00000000000 --- a/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Bug report -about: Report a bug or issue -title: '' -labels: '' -assignees: '' - ---- - -**NOTE:** this issue system is intended for reporting bugs and tracking progress in software -development. For all other usage and software development questions or discussion, please post a -question in our chat room: https://gitter.im/opentripplanner/OpenTripPlanner. - - -## Expected behavior - -## Observed behavior - -## Version of OTP used (exact commit hash or JAR name) - -## Data sets in use (links to GTFS and OSM PBF files) - -## Command line used to start OTP - -## Router config and graph build config JSON - -## Steps to reproduce the problem From a3fdb4bf94bdc2a86af499ad931fa13a110596ec Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jul 2024 18:15:15 +0200 Subject: [PATCH 13/93] Update doc/dev/decisionrecords/_TEMPLATE.md --- doc/dev/decisionrecords/_TEMPLATE.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/dev/decisionrecords/_TEMPLATE.md b/doc/dev/decisionrecords/_TEMPLATE.md index f8389d4a551..768430265ff 100644 --- a/doc/dev/decisionrecords/_TEMPLATE.md +++ b/doc/dev/decisionrecords/_TEMPLATE.md @@ -11,8 +11,10 @@ Original pull-request: {#NNNN} ### Context and Problem Statement - + ### Other options From 4c9a8144cb7126c13cc2ff67d1441d22a8652cb6 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 24 Jul 2024 14:59:54 +0200 Subject: [PATCH 14/93] Rename from DECISION_RECORDS to DEVELOPMENT_DECISION_RECORDS --- DECISION_RECORDS.md => DEVELOPMENT_DECISION_RECORDS.md | 2 +- doc/dev/decisionrecords/UseDecisionRecords.md | 2 +- doc/dev/decisionrecords/_TEMPLATE.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename DECISION_RECORDS.md => DEVELOPMENT_DECISION_RECORDS.md (99%) diff --git a/DECISION_RECORDS.md b/DEVELOPMENT_DECISION_RECORDS.md similarity index 99% rename from DECISION_RECORDS.md rename to DEVELOPMENT_DECISION_RECORDS.md index dbe044c6168..8ba584e2c57 100644 --- a/DECISION_RECORDS.md +++ b/DEVELOPMENT_DECISION_RECORDS.md @@ -1,4 +1,4 @@ -# Records +# Development Decision Records ## Use-Decision-Records diff --git a/doc/dev/decisionrecords/UseDecisionRecords.md b/doc/dev/decisionrecords/UseDecisionRecords.md index 1900218195e..d30c255e556 100644 --- a/doc/dev/decisionrecords/UseDecisionRecords.md +++ b/doc/dev/decisionrecords/UseDecisionRecords.md @@ -7,7 +7,7 @@ OTP development. ## Process -Decisions we make in the developer meetings are recorded in the [Decision Records](/DECISION_RECORDS.md) +Decisions we make in the developer meetings are recorded in the [Developer Decision Records](/DEVELOPMENT_DECISION_RECORDS.md) list. If the decision is small and uncontroversial, but yet important and can be expressed in maximum 2 sentences, we will list it here without any more documentation. If the decision requires a bit more discussion and explanations, then we will create a PR with a document for it. diff --git a/doc/dev/decisionrecords/_TEMPLATE.md b/doc/dev/decisionrecords/_TEMPLATE.md index 768430265ff..45bb3b11d34 100644 --- a/doc/dev/decisionrecords/_TEMPLATE.md +++ b/doc/dev/decisionrecords/_TEMPLATE.md @@ -2,7 +2,7 @@ {DESCRIPTION} From 77093434b951790f7812ebd3b5a376d5568496ed Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 24 Jul 2024 15:00:38 +0200 Subject: [PATCH 15/93] Fix relative links to external developer doc in user doc --- docs/Developers-Guide.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/Developers-Guide.md b/docs/Developers-Guide.md index 3ec7489276d..0b9ec011f96 100644 --- a/docs/Developers-Guide.md +++ b/docs/Developers-Guide.md @@ -197,17 +197,16 @@ Please use only ISO 8601 date format (YYYY-MM-DD) in documentation, comments, an project. This avoids the ambiguity that can result from differing local interpretations of date formats like 02/01/12. -## Code style - -The OTP code style is described on a separate [style guide page](../doc/dev/decisionrecords/Codestyle.md). - ## Code conventions and architecture -The [architecture](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/ARCHITECTURE.md) -and [code conventions](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/CODE_CONVENTIONS.md) -are only available on GitHub, not in the project documentation. These documents contain relative -links to code so, they are a bit easier to maintain that way. The target audience is also active -OTP developers that have the code checked out locally. +The development and architecture documentation are only available on GitHub, not in the user project +documentation (https://www.opentripplanner.org/). These documents contain relative links to code, +so they are a bit easier to maintain that way. The primary audience is also active OTP developers +that have the code checked out locally. + + - [Architecture](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/ARCHITECTURE.md) + - [Code Conventions](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/CODE_CONVENTIONS.md) + - [Development Decision Records](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/DECISION_RECORDS.md) ## Continuous Integration From 564d9b087b9d03978a966cfc4a0be4a1652bc107 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 24 Jul 2024 15:36:14 +0200 Subject: [PATCH 16/93] Move /docs to /doc/user --- .github/pull_request_template.md | 4 +- .github/workflows/cibuild.yml | 2 +- .github/workflows/post-merge.yml | 4 +- .gitignore | 2 +- ARCHITECTURE.md | 4 +- DEVELOPMENT_DECISION_RECORDS.md | 2 +- doc/dev/decisionrecords/Codestyle.md | 2 +- doc/dev/decisionrecords/NamingConventions.md | 2 +- {docs => doc/user}/Accessibility.md | 2 +- {docs => doc/user}/Analysis.md | 0 {docs => doc/user}/Basic-Tutorial.md | 414 +++++++++--------- {docs => doc/user}/Bibliography.md | 0 {docs => doc/user}/BoardingLocations.md | 0 {docs => doc/user}/BuildConfiguration.md | 0 {docs => doc/user}/Changelog.md | 0 {docs => doc/user}/Configuration.md | 0 {docs => doc/user}/Container-Image.md | 0 {docs => doc/user}/Data-Sources.md | 0 {docs => doc/user}/Deployments.md | 192 ++++---- {docs => doc/user}/Developers-Guide.md | 2 +- {docs => doc/user}/Frontends.md | 0 {docs => doc/user}/Getting-OTP.md | 0 {docs => doc/user}/Governance.md | 0 {docs => doc/user}/History.md | 0 {docs => doc/user}/In-Station-Navigation.md | 0 {docs => doc/user}/IslandPruning.md | 0 {docs => doc/user}/Localization.md | 0 {docs => doc/user}/Logging.md | 0 {docs => doc/user}/Migrating-Configuration.md | 0 {docs => doc/user}/Netex-Norway.md | 0 {docs => doc/user}/Preparing-OSM.md | 0 {docs => doc/user}/Presentations.md | 0 {docs => doc/user}/Product-Overview.md | 0 {docs => doc/user}/README-DOCS.txt | 0 {docs => doc/user}/ReleaseChecklist.md | 8 +- {docs => doc/user}/Roadmap.md | 0 {docs => doc/user}/RouteRequest.md | 0 {docs => doc/user}/RouterConfiguration.md | 0 {docs => doc/user}/RoutingModes.md | 0 {docs => doc/user}/SandboxExtension.md | 2 +- {docs => doc/user}/StopAreas.md | 0 {docs => doc/user}/System-Requirements.md | 0 {docs => doc/user}/Troubleshooting-Routing.md | 0 {docs => doc/user}/UpdaterConfig.md | 0 {docs => doc/user}/Version-Comparison.md | 0 {docs => doc/user}/Visual-Identity.md | 0 {docs => doc/user}/apis/Apis.md | 0 {docs => doc/user}/apis/GTFS-GraphQL-API.md | 0 {docs => doc/user}/apis/GraphQL-Tutorial.md | 0 {docs => doc/user}/apis/TransmodelApi.md | 0 {docs => doc/user}/examples/Readme.md | 0 {docs => doc/user}/examples/entur/Readme.md | 0 .../user}/examples/entur/build-config.json | 0 .../user}/examples/entur/otp-config.json | 0 .../user}/examples/entur/router-config.json | 0 .../examples/ibi/atlanta/build-config.json | 0 .../examples/ibi/atlanta/otp-config.json | 0 .../examples/ibi/atlanta/router-config.json | 0 .../examples/ibi/houston/build-config.json | 0 .../examples/ibi/portland/build-config.json | 0 .../examples/ibi/portland/otp-config.json | 0 .../examples/ibi/portland/router-config.json | 0 .../examples/ibi/seattle/build-config.json | 0 .../examples/ibi/seattle/router-config.json | 0 .../examples/ibi/septa/router-config.json | 0 .../user}/examples/skanetrafiken/Readme.md | 0 .../examples/skanetrafiken/build-config.json | 0 .../user}/examples/skanetrafiken/oresund.json | 0 .../examples/skanetrafiken/router-config.json | 0 {docs => doc/user}/github_issue_linker.py | 0 .../user}/images/ExternalToolDialog.png | Bin .../user}/images/ServiceModelOverview.png | Bin {docs => doc/user}/images/TransitTimeLine.svg | 0 {docs => doc/user}/images/badprojection.png | Bin .../user}/images/bicycle-safety-report.png | Bin .../user}/images/boarding-schwabstrasse.png | Bin .../user}/images/buckhead-station.png | Bin {docs => doc/user}/images/cli-flow.svg | 0 .../user}/images/example-isochrone.png | Bin .../user}/images/exiting-oesterfeld.png | Bin .../user}/images/graphiql-autocomplete.png | Bin .../user}/images/graphiql-documentation.png | Bin {docs => doc/user}/images/graphiql.png | Bin {docs => doc/user}/images/nothruisland.png | Bin {docs => doc/user}/images/osmislands.png | Bin {docs => doc/user}/images/otp-logo.svg | 5 +- {docs => doc/user}/images/roadmap-1.png | Bin {docs => doc/user}/images/roadmap-2.png | Bin {docs => doc/user}/images/roadmap-3.png | Bin {docs => doc/user}/images/roadmap-4.png | Bin {docs => doc/user}/images/roadmap-5.png | Bin {docs => doc/user}/images/roadmap-6.png | Bin {docs => doc/user}/images/roadmap-7.png | Bin {docs => doc/user}/images/stationisland.png | Bin {docs => doc/user}/images/stopisland.png | Bin .../user}/images/stopislandproblem.png | Bin {docs => doc/user}/images/transfer-oslo-1.png | Bin {docs => doc/user}/images/transfer-oslo-2.png | Bin .../user}/images/transfer-suedkreuz.png | Bin {docs => doc/user}/images/trueisland.png | Bin {docs => doc/user}/index.md | 152 +++---- {docs => doc/user}/requirements.txt | 0 {docs => doc/user}/sandbox/ActuatorAPI.md | 0 {docs => doc/user}/sandbox/DataOverlay.md | 0 {docs => doc/user}/sandbox/Emissions.md | 0 {docs => doc/user}/sandbox/Fares.md | 0 {docs => doc/user}/sandbox/Flex.md | 0 {docs => doc/user}/sandbox/GeocoderAPI.md | 0 .../user}/sandbox/GoogleCloudStorage.md | 0 .../user}/sandbox/IBIAccessibilityScore.md | 0 .../user}/sandbox/InteractiveOtpMain.md | 0 .../user}/sandbox/MapboxVectorTilesApi.md | 0 {docs => doc/user}/sandbox/ParkAndRideApi.md | 0 {docs => doc/user}/sandbox/ReportApi.md | 0 {docs => doc/user}/sandbox/RideHailing.md | 0 .../user}/sandbox/SmooveBikeRental.md | 0 .../user}/sandbox/StopConsolidation.md | 0 {docs => doc/user}/sandbox/VehicleParking.md | 0 .../sandbox/VehicleRentalServiceDirectory.md | 0 .../user}/sandbox/siri/SiriAzureUpdater.md | 0 .../sandbox/siri/SiriGooglePubSubUpdater.md | 0 .../user}/sandbox/siri/SiriUpdater.md | 0 .../user}/sandbox/transferanalyzer.md | 0 pom.xml | 4 +- .../doc/BuildConfigurationDocTest.java | 2 +- .../generate/doc/ConfigurationDocTest.java | 6 +- .../generate/doc/GraphQLTutorialDocTest.java | 2 +- .../generate/doc/RouteRequestDocTest.java | 2 +- .../doc/RouterConfigurationDocTest.java | 2 +- .../generate/doc/SiriAzureConfigDocTest.java | 2 +- .../generate/doc/SiriConfigDocTest.java | 2 +- .../doc/SiriGooglePubSubConfigDocTest.java | 2 +- .../generate/doc/UpdaterConfigDocTest.java | 2 +- .../doc/framework/DocsTestConstants.java | 4 +- .../standalone/config/ExampleConfigTest.java | 9 +- .../support/FilePatternArgumentsProvider.java | 2 +- 136 files changed, 422 insertions(+), 418 deletions(-) rename {docs => doc/user}/Accessibility.md (99%) rename {docs => doc/user}/Analysis.md (100%) rename {docs => doc/user}/Basic-Tutorial.md (98%) rename {docs => doc/user}/Bibliography.md (100%) rename {docs => doc/user}/BoardingLocations.md (100%) rename {docs => doc/user}/BuildConfiguration.md (100%) rename {docs => doc/user}/Changelog.md (100%) rename {docs => doc/user}/Configuration.md (100%) rename {docs => doc/user}/Container-Image.md (100%) rename {docs => doc/user}/Data-Sources.md (100%) rename {docs => doc/user}/Deployments.md (98%) rename {docs => doc/user}/Developers-Guide.md (99%) rename {docs => doc/user}/Frontends.md (100%) rename {docs => doc/user}/Getting-OTP.md (100%) rename {docs => doc/user}/Governance.md (100%) rename {docs => doc/user}/History.md (100%) rename {docs => doc/user}/In-Station-Navigation.md (100%) rename {docs => doc/user}/IslandPruning.md (100%) rename {docs => doc/user}/Localization.md (100%) rename {docs => doc/user}/Logging.md (100%) rename {docs => doc/user}/Migrating-Configuration.md (100%) rename {docs => doc/user}/Netex-Norway.md (100%) rename {docs => doc/user}/Preparing-OSM.md (100%) rename {docs => doc/user}/Presentations.md (100%) rename {docs => doc/user}/Product-Overview.md (100%) rename {docs => doc/user}/README-DOCS.txt (100%) rename {docs => doc/user}/ReleaseChecklist.md (96%) rename {docs => doc/user}/Roadmap.md (100%) rename {docs => doc/user}/RouteRequest.md (100%) rename {docs => doc/user}/RouterConfiguration.md (100%) rename {docs => doc/user}/RoutingModes.md (100%) rename {docs => doc/user}/SandboxExtension.md (97%) rename {docs => doc/user}/StopAreas.md (100%) rename {docs => doc/user}/System-Requirements.md (100%) rename {docs => doc/user}/Troubleshooting-Routing.md (100%) rename {docs => doc/user}/UpdaterConfig.md (100%) rename {docs => doc/user}/Version-Comparison.md (100%) rename {docs => doc/user}/Visual-Identity.md (100%) rename {docs => doc/user}/apis/Apis.md (100%) rename {docs => doc/user}/apis/GTFS-GraphQL-API.md (100%) rename {docs => doc/user}/apis/GraphQL-Tutorial.md (100%) rename {docs => doc/user}/apis/TransmodelApi.md (100%) rename {docs => doc/user}/examples/Readme.md (100%) rename {docs => doc/user}/examples/entur/Readme.md (100%) rename {docs => doc/user}/examples/entur/build-config.json (100%) rename {docs => doc/user}/examples/entur/otp-config.json (100%) rename {docs => doc/user}/examples/entur/router-config.json (100%) rename {docs => doc/user}/examples/ibi/atlanta/build-config.json (100%) rename {docs => doc/user}/examples/ibi/atlanta/otp-config.json (100%) rename {docs => doc/user}/examples/ibi/atlanta/router-config.json (100%) rename {docs => doc/user}/examples/ibi/houston/build-config.json (100%) rename {docs => doc/user}/examples/ibi/portland/build-config.json (100%) rename {docs => doc/user}/examples/ibi/portland/otp-config.json (100%) rename {docs => doc/user}/examples/ibi/portland/router-config.json (100%) rename {docs => doc/user}/examples/ibi/seattle/build-config.json (100%) rename {docs => doc/user}/examples/ibi/seattle/router-config.json (100%) rename {docs => doc/user}/examples/ibi/septa/router-config.json (100%) rename {docs => doc/user}/examples/skanetrafiken/Readme.md (100%) rename {docs => doc/user}/examples/skanetrafiken/build-config.json (100%) rename {docs => doc/user}/examples/skanetrafiken/oresund.json (100%) rename {docs => doc/user}/examples/skanetrafiken/router-config.json (100%) rename {docs => doc/user}/github_issue_linker.py (100%) rename {docs => doc/user}/images/ExternalToolDialog.png (100%) rename {docs => doc/user}/images/ServiceModelOverview.png (100%) rename {docs => doc/user}/images/TransitTimeLine.svg (100%) rename {docs => doc/user}/images/badprojection.png (100%) rename {docs => doc/user}/images/bicycle-safety-report.png (100%) rename {docs => doc/user}/images/boarding-schwabstrasse.png (100%) rename {docs => doc/user}/images/buckhead-station.png (100%) rename {docs => doc/user}/images/cli-flow.svg (100%) rename {docs => doc/user}/images/example-isochrone.png (100%) rename {docs => doc/user}/images/exiting-oesterfeld.png (100%) rename {docs => doc/user}/images/graphiql-autocomplete.png (100%) rename {docs => doc/user}/images/graphiql-documentation.png (100%) rename {docs => doc/user}/images/graphiql.png (100%) rename {docs => doc/user}/images/nothruisland.png (100%) rename {docs => doc/user}/images/osmislands.png (100%) rename {docs => doc/user}/images/otp-logo.svg (87%) rename {docs => doc/user}/images/roadmap-1.png (100%) rename {docs => doc/user}/images/roadmap-2.png (100%) rename {docs => doc/user}/images/roadmap-3.png (100%) rename {docs => doc/user}/images/roadmap-4.png (100%) rename {docs => doc/user}/images/roadmap-5.png (100%) rename {docs => doc/user}/images/roadmap-6.png (100%) rename {docs => doc/user}/images/roadmap-7.png (100%) rename {docs => doc/user}/images/stationisland.png (100%) rename {docs => doc/user}/images/stopisland.png (100%) rename {docs => doc/user}/images/stopislandproblem.png (100%) rename {docs => doc/user}/images/transfer-oslo-1.png (100%) rename {docs => doc/user}/images/transfer-oslo-2.png (100%) rename {docs => doc/user}/images/transfer-suedkreuz.png (100%) rename {docs => doc/user}/images/trueisland.png (100%) rename {docs => doc/user}/index.md (98%) rename {docs => doc/user}/requirements.txt (100%) rename {docs => doc/user}/sandbox/ActuatorAPI.md (100%) rename {docs => doc/user}/sandbox/DataOverlay.md (100%) rename {docs => doc/user}/sandbox/Emissions.md (100%) rename {docs => doc/user}/sandbox/Fares.md (100%) rename {docs => doc/user}/sandbox/Flex.md (100%) rename {docs => doc/user}/sandbox/GeocoderAPI.md (100%) rename {docs => doc/user}/sandbox/GoogleCloudStorage.md (100%) rename {docs => doc/user}/sandbox/IBIAccessibilityScore.md (100%) rename {docs => doc/user}/sandbox/InteractiveOtpMain.md (100%) rename {docs => doc/user}/sandbox/MapboxVectorTilesApi.md (100%) rename {docs => doc/user}/sandbox/ParkAndRideApi.md (100%) rename {docs => doc/user}/sandbox/ReportApi.md (100%) rename {docs => doc/user}/sandbox/RideHailing.md (100%) rename {docs => doc/user}/sandbox/SmooveBikeRental.md (100%) rename {docs => doc/user}/sandbox/StopConsolidation.md (100%) rename {docs => doc/user}/sandbox/VehicleParking.md (100%) rename {docs => doc/user}/sandbox/VehicleRentalServiceDirectory.md (100%) rename {docs => doc/user}/sandbox/siri/SiriAzureUpdater.md (100%) rename {docs => doc/user}/sandbox/siri/SiriGooglePubSubUpdater.md (100%) rename {docs => doc/user}/sandbox/siri/SiriUpdater.md (100%) rename {docs => doc/user}/sandbox/transferanalyzer.md (100%) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index da79a466e0b..a67cae22195 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -47,7 +47,7 @@ Write a few words on how the new code is tested. - Was the code designed so it is unit testable? - Were any tests applied to the smallest appropriate unit? - Do all tests - pass [the continuous integration service](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Developers-Guide.md#continuous-integration) + pass [the continuous integration service](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/doc/user/Developers-Guide.md#continuous-integration) ? ### Documentation @@ -59,7 +59,7 @@ Write a few words on how the new code is tested. ### Changelog -The [changelog file](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Changelog.md) +The [changelog file](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/doc/user/Changelog.md) is generated from the pull-request title, make sure the title describe the feature or issue fixed. To exclude the PR from the changelog add the label `skip changelog` to the PR. diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 4b814d03e35..89bc77b2b97 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -108,7 +108,7 @@ jobs: if: github.event_name == 'pull_request' - name: Install Python dependencies - run: pip install -r docs/requirements.txt + run: pip install -r doc/user/requirements.txt - name: Build main documentation diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 86f3741aada..b26198e99a6 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -29,8 +29,8 @@ jobs: run: | # add a line above the one which contains AUTOMATIC_CHANGELOG_PLACEHOLDER ITEM="${TITLE} [#${NUMBER}](${URL})" - TEMP_FILE=docs/Changelog.generated.md - FILE=docs/Changelog.md + TEMP_FILE=doc/user/Changelog.generated.md + FILE=doc/user/Changelog.md awk "/CHANGELOG_PLACEHOLDER/{print \"- $ITEM\"}1" $FILE > $TEMP_FILE mv $TEMP_FILE $FILE git add $FILE diff --git a/.gitignore b/.gitignore index a90f06cdcb0..6fac28d2178 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,7 @@ o_o_standalone_config_IncludeFileDirectiveTest_part.json _site/ build/ dist/ -docs/_build/ +doc/user/_build/ gen-java/ gen-javabean/ gen-py/ diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 1cf652ddb87..8df085f3b5d 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -15,14 +15,14 @@ We document [Decision Records](DECISION_RECORDS.md) in a log. Make sure you as a with the decisions and follow them. Reviewers should use them actively when reviewing code and may use them to ask for changes. -Be sure to also read the [developer documentation](docs/Developers-Guide.md). +Be sure to also read the [developer documentation](doc/user/Developers-Guide.md). ## Modules/Components The diagram shows a simplified/generic version on how we want to model the OTP components with 2 examples. The Transit model is more complex than the VehiclePosition model. -![MainModelOverview](docs/images/ServiceModelOverview.png) +![MainModelOverview](doc/user/images/ServiceModelOverview.png) - `Use Case Service` A service which combine the functionality in many `Domain Services` to fulfill a use-case or set of features. It may have an api with request/response classes. These are diff --git a/DEVELOPMENT_DECISION_RECORDS.md b/DEVELOPMENT_DECISION_RECORDS.md index 8ba584e2c57..10b9e005809 100644 --- a/DEVELOPMENT_DECISION_RECORDS.md +++ b/DEVELOPMENT_DECISION_RECORDS.md @@ -31,7 +31,7 @@ notes on `private` members and as inline comments. > If you decide to NOT follow these decision records, then you must document why. **See also** - - [Developers-Guide > Code comments](docs/Developers-Guide.md#code-comments). + - [Developers-Guide > Code comments](doc/user/Developers-Guide.md#code-comments). - [Codestyle > Javadoc Guidlines](doc/dev/decisionrecords/Codestyle.md#javadoc-guidlines) - JavaDoc checklist diff --git a/doc/dev/decisionrecords/Codestyle.md b/doc/dev/decisionrecords/Codestyle.md index bdeab50a283..3aa93c86125 100644 --- a/doc/dev/decisionrecords/Codestyle.md +++ b/doc/dev/decisionrecords/Codestyle.md @@ -58,7 +58,7 @@ Editor > Code Style_. Then select **Project** in the \_Scheme drop down. You can run the Prettier Maven plugin as an external tool in IntelliJ. Set it up as an `External tool` and assign a key-shortcut to the tool execution. -![External Tool Dialog](../../../docs/images/ExternalToolDialog.png) +![External Tool Dialog](../../../doc/user/images/ExternalToolDialog.png) ``` Name: Prettier Format Current File diff --git a/doc/dev/decisionrecords/NamingConventions.md b/doc/dev/decisionrecords/NamingConventions.md index f186d57576a..3a226fa47ae 100644 --- a/doc/dev/decisionrecords/NamingConventions.md +++ b/doc/dev/decisionrecords/NamingConventions.md @@ -60,7 +60,7 @@ These prefixes are also "allowed", but not preferred - they have some kind of ne ## Service, Model and Repository -![MainModelOverview](docs/images/ServiceModelOverview.png) +![MainModelOverview](doc/user/images/ServiceModelOverview.png) diff --git a/docs/Accessibility.md b/doc/user/Accessibility.md similarity index 99% rename from docs/Accessibility.md rename to doc/user/Accessibility.md index 49373c522c2..27cb47ce92e 100644 --- a/docs/Accessibility.md +++ b/doc/user/Accessibility.md @@ -109,4 +109,4 @@ inaccessible to wheelchair users. ## Example A full configuration example is available -at [`/docs/examples`](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/docs/examples/ibi) \ No newline at end of file +at [`/docs/examples`](https://github.com/opentripplanner/OpenTripPlanner/tree/dev-2.x/doc/user/examples/ibi) \ No newline at end of file diff --git a/docs/Analysis.md b/doc/user/Analysis.md similarity index 100% rename from docs/Analysis.md rename to doc/user/Analysis.md diff --git a/docs/Basic-Tutorial.md b/doc/user/Basic-Tutorial.md similarity index 98% rename from docs/Basic-Tutorial.md rename to doc/user/Basic-Tutorial.md index a7a69b8a3bb..d6e46f3f1f5 100644 --- a/docs/Basic-Tutorial.md +++ b/doc/user/Basic-Tutorial.md @@ -1,207 +1,207 @@ -# OpenTripPlanner Basic Tutorial - -This page should allow you to set up and test your own OTP2 server. If all goes well it should only -take a few minutes! - -## Get Java - -As a Java program, OTP must be run within a Java virtual machine (JVM), which is provided as part of -the Java runtime (JRE) or Java development kit (JDK). OTP2 is compatible with Java 21 or later. We -recommend running on Java 21 rather than a later version, as it is a long-term support release. -Run `java -version` to check that you have version 21 or newer of the JVM installed. If you do not, -you will need to install a recent OpenJDK or Oracle Java package for your operating system. - -## Get OTP - -OpenTripPlanner is written in Java and distributed as a single runnable JAR file. This is a "shaded" -JAR containing all other libraries needed for OTP to work, and is available from the Maven Central -repository. You will be able to go -to [the OTP directory at Maven Central](https://repo1.maven.org/maven2/org/opentripplanner/otp/), -navigate to -the [directory of releases](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.5.0/), -and download -the [file with `shaded.jar` suffix](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.5.0/otp-2.5.0-shaded.jar) -. - -You may also want to get your own copy of the OTP source code -and [build a bleeding edge development JAR from scratch](Getting-OTP.md), especially if you plan to -do some development yourself. In that case, check out the branch `dev-2.x`. - -## Get some data - -### GTFS for Transit Schedules and Stops - -First you'll need GTFS data to build a transit network. There's an excellent description of the GTFS -format [here](http://gtfs.org/). Transport agencies throughout the world provide GTFS schedules to -the public. Transitland has a -[registry of feeds](https://transit.land/feed-registry) and [TransitFeeds](http://transitfeeds.com/) -also provides an extensive catalog. The best option is often to simply fetch the data directly from -a transit operator or agency. If you know of a feed you want to work with, download it and put it in -an empty directory you have created for your OTP instance such as `/home/username/otp` on -Linux, `/Users/username/otp` on MacOS, or `C:\Users\username\otp` on Windows. For OTP2 to detect a -GTFS file, **its name must end in `.zip` and must contain the letters 'gtfs'**. We often use the -convention of saving GTFS files with names ending in `.gtfs.zip` which meets both these criteria, -reflecting the fact that a GTFS feed is just a ZIP file containing a specific set of files. If you -don't have a particular feed in mind, the one for Portland, Oregon's TriMet agency is a good option. -It is available at [this URL](http://developer.trimet.org/schedule/gtfs.zip). This is a -moderate-sized input of good quality (TriMet initiated OTP development and helped develop the GTFS -format). On Linux, this could be done on the command line as follows: - - $ cd /home/username - $ mkdir otp - $ cd otp - $ wget "http://developer.trimet.org/schedule/gtfs.zip" -O trimet.gtfs.zip - -### OSM for Streets - -You'll also need OpenStreetMap data to build a road network for walking, cycling, and -driving. [OpenStreetMap](https://www.openstreetmap.org/) is a global collaborative map database that -rivals or surpasses the quality of commercial maps in many locations. Several services extract -smaller geographic regions from this database. Interline Technologies maintains a collection -of [extracts updated daily for urban areas around the world](https://www.interline.io/osm/extracts/) -. [Geofabrik](http://download.geofabrik.de/) provides extracts for larger areas like countries or -states, from which you can prepare your own smaller bounding-box extracts -using [Osmosis](http://wiki.openstreetmap.org/wiki/Osmosis#Extracting_bounding_boxes) -, [osmconvert](http://wiki.openstreetmap.org/wiki/Osmconvert#Applying_Geographical_Borders), or (our -favorite) [Osmium-Tool](https://osmcode.org/osmium-tool/manual.html#creating-geographic-extracts). -There is also [Protomaps](https://app.protomaps.com/) which can create custom extracts -for any region of the world with an easy to use drag and drop interface. -OSM data can be delivered as XML or in the more compact binary PBF format. OpenTripPlanner consumes -only PBF because it's smaller and more efficient. - -Download OSM PBF data for the same geographic region as your GTFS feed, and place this PBF file in -the same directory you created for the OSM data. If you are using the TriMet GTFS feed, you could -download -the [Geofabrik extract for the US state of Oregon](http://download.geofabrik.de/north-america/us/oregon.html) -, then further trim that to just -the [TriMet service area](https://trimet.org/pdfs/taxinfo/trimetdistrictboundary.pdf) using the -bounding box switch of one of the above tools. On Linux or MacOS you could do that as follows: - - $ cd /home/username - $ wget http://download.geofabrik.de/north-america/us/oregon-latest.osm.pbf - $ osmconvert oregon-latest.osm.pbf -b=-123.043,45.246,-122.276,45.652 --complete-ways -o=portland.pbf - $ mv portland.pbf otp - -We find [this tool](https://boundingbox.klokantech.com/) useful for determining the geographic -coordinates of bounding boxes. The CSV option in that tool produces exactly the format expected by -the `osmconvert -b` switch. The `--complete-ways` switch is important to handle roads that cross -outside your bounding box. - -If you have extracted a smaller PBF file from a larger region, be sure to put only your extract (not -the original larger file) in the directory with your GTFS data. Otherwise OTP will try to load both -the original file and the extract in a later step. See -the [page on preparing OSM data](Preparing-OSM.md) for additional information and example commands -for cropping and filtering OSM data. - -## Starting OTP - -A typical command to start OTP looks like `java -Xmx2G -jar otp.shaded.jar `. The -`-Xmx` parameter sets the limit on how much memory OTP is allowed to consume. GTFS and OSM data sets -are often very large, and OTP is relatively memory-hungry. You will need at least 1GB of memory when -working with the Portland TriMet data set, and several gigabytes for larger inputs. -[Here is more information about the system requirements](System-Requirements.md). If you have -sufficient memory in your computer, set this to a couple of gigabytes (e.g. `-Xmx2G`). Java uses -a [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) approach -to memory management, which requires some "breathing room" to efficiently operate. Without -sufficient free memory OTP can grind to a halt. [VisualVM](https://visualvm.github.io) is a good way -to inspect Java memory usage, especially with -the [VisualGC plugin](https://visualvm.github.io/plugins.html). - -## Building Graphs - -There are two main phases to preparing and deploying an OTP server. The first is to analyze the -GTFS, OSM and any other inputs (such as elevation data) and build a representation of the -transportation network. Following mathematical terminology we call this -a ['graph'](http://en.wikipedia.org/wiki/Graph_%28mathematics%29), and refer to this phase as "graph -building". The second phase is to start a server that provides trip planning and other API services -for this graph. - -It is possible to save the graph to a file on disk after the first phase, then load the graph from -the file in the second phase. This allows restarting the server or starting multiple instances of -the server without repeating the often time-consuming process of building the graph. It is also -possible to split the graph building process into separate OSM and GTFS stages for similar reasons: -to allow reusing results from slow processes, such as applying elevation data to streets. These -different options are controlled with command line switches, and will be described in more detail -below and in other tutorials. - -## Simple One-step Server - -The simplest way to use OTP is to build a graph in a single step and start a server immediately, -without saving it to disk. The command to do so is: - - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --build --serve /home/username/otp - -where `/home/username/otp` should be the directory where you put your configuration and input files. - -If you're using the Portland input data, the graph build operation should take about one minute to -complete, and then you'll see a `Grizzly server running` message. At this point you have an -OpenTripPlanner server running locally and can open [http://localhost:8080/](http://localhost:8080/) -in a web browser. You should be presented with a Javascript client application that will interact -with your local OpenTripPlanner instance. - -This map-based user interface is in fact sending HTTP GET requests to the OTP server running on your -local machine. It can be informative to watch the HTTP requests and responses being generated using -the developer tools in your web browser. OTP's built-in web server will run by default on port 8080. -If by any chance some other software is already using that port number, you can specify a different -port number with a switch -`--port 8801`. - - -## Saving a Graph - -If you want speed up the process of repeatedly starting up a server with the same graph, you can -build a graph from street and transit data then save it to a file using the `--build` and `--save` -command line parameters together. If for example your current working directory (`.`) contains the -input files and the OTP JAR file, you can use this command: - - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --build --save . - -This will produce a file called `graph.obj` in the same directory as the inputs. The server can then -be started later using the `--load` parameter, and will read this file instead of building the graph -from scratch: - - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --load . - -Another reason to perform these two phases separately is that the building process loads the entire -GTFS and OSM data sets into memory, so can require significantly more memory than just running a -server. Accordingly, you may want to perform the build on one machine (e.g. a throw-away cloud -instance with more memory or compute capacity), then copy the resulting graph file to one or more -smaller machines to serve the API. - -## Layering GTFS onto OSM - -Building the street graph (especially with elevation data) can take a long time. It is common for -transit data to change more frequently than street data, so it can be convenient to build the street -graph once, and then layer transit data on top of the streets to make the final graph. - -Again assuming the input files and OTP JAR file are in the current working directory, you can build -a street graph with OSM and elevation data only (ignoring transit input files) with this command: - - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --buildStreet . - -Then, to build a graph layering transit data on top of the saved street graph (built using the -previous command): - - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --loadStreet --save . - -Finally, the server can be started using the `--load` parameter: - - $ java -Xmx2G -jar otp-2.5.0-shaded.jar --load . - -## Command Line Switches - -The flow diagram below summarizes all the command line switches used in the above examples, and how -they control which actions are taken when OTP starts up. - -![Command-Line-Parameter-Flow](images/cli-flow.svg) - -You must use at least one of the required parameters: `--load`, `--loadStreet`, `--build` -, `--buildStreet`. A _required_ parameter may imply other parameters when the flow allows for no -other choice. For example, `--load` implies `--serve`, so `--serve` is not necessary and has no -additional effect when used together with `--load`. - -You can run the OTP .jar file with the `--help` option for a full list of command line parameters. - -## Exploring the API - -If you want to learn how to use OTP's API's, check out the [GraphQL tutorial](apis/GraphQL-Tutorial.md). +# OpenTripPlanner Basic Tutorial + +This page should allow you to set up and test your own OTP2 server. If all goes well it should only +take a few minutes! + +## Get Java + +As a Java program, OTP must be run within a Java virtual machine (JVM), which is provided as part of +the Java runtime (JRE) or Java development kit (JDK). OTP2 is compatible with Java 21 or later. We +recommend running on Java 21 rather than a later version, as it is a long-term support release. +Run `java -version` to check that you have version 21 or newer of the JVM installed. If you do not, +you will need to install a recent OpenJDK or Oracle Java package for your operating system. + +## Get OTP + +OpenTripPlanner is written in Java and distributed as a single runnable JAR file. This is a "shaded" +JAR containing all other libraries needed for OTP to work, and is available from the Maven Central +repository. You will be able to go +to [the OTP directory at Maven Central](https://repo1.maven.org/maven2/org/opentripplanner/otp/), +navigate to +the [directory of releases](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.5.0/), +and download +the [file with `shaded.jar` suffix](https://repo1.maven.org/maven2/org/opentripplanner/otp/2.5.0/otp-2.5.0-shaded.jar) +. + +You may also want to get your own copy of the OTP source code +and [build a bleeding edge development JAR from scratch](Getting-OTP.md), especially if you plan to +do some development yourself. In that case, check out the branch `dev-2.x`. + +## Get some data + +### GTFS for Transit Schedules and Stops + +First you'll need GTFS data to build a transit network. There's an excellent description of the GTFS +format [here](http://gtfs.org/). Transport agencies throughout the world provide GTFS schedules to +the public. Transitland has a +[registry of feeds](https://transit.land/feed-registry) and [TransitFeeds](http://transitfeeds.com/) +also provides an extensive catalog. The best option is often to simply fetch the data directly from +a transit operator or agency. If you know of a feed you want to work with, download it and put it in +an empty directory you have created for your OTP instance such as `/home/username/otp` on +Linux, `/Users/username/otp` on MacOS, or `C:\Users\username\otp` on Windows. For OTP2 to detect a +GTFS file, **its name must end in `.zip` and must contain the letters 'gtfs'**. We often use the +convention of saving GTFS files with names ending in `.gtfs.zip` which meets both these criteria, +reflecting the fact that a GTFS feed is just a ZIP file containing a specific set of files. If you +don't have a particular feed in mind, the one for Portland, Oregon's TriMet agency is a good option. +It is available at [this URL](http://developer.trimet.org/schedule/gtfs.zip). This is a +moderate-sized input of good quality (TriMet initiated OTP development and helped develop the GTFS +format). On Linux, this could be done on the command line as follows: + + $ cd /home/username + $ mkdir otp + $ cd otp + $ wget "http://developer.trimet.org/schedule/gtfs.zip" -O trimet.gtfs.zip + +### OSM for Streets + +You'll also need OpenStreetMap data to build a road network for walking, cycling, and +driving. [OpenStreetMap](https://www.openstreetmap.org/) is a global collaborative map database that +rivals or surpasses the quality of commercial maps in many locations. Several services extract +smaller geographic regions from this database. Interline Technologies maintains a collection +of [extracts updated daily for urban areas around the world](https://www.interline.io/osm/extracts/) +. [Geofabrik](http://download.geofabrik.de/) provides extracts for larger areas like countries or +states, from which you can prepare your own smaller bounding-box extracts +using [Osmosis](http://wiki.openstreetmap.org/wiki/Osmosis#Extracting_bounding_boxes) +, [osmconvert](http://wiki.openstreetmap.org/wiki/Osmconvert#Applying_Geographical_Borders), or (our +favorite) [Osmium-Tool](https://osmcode.org/osmium-tool/manual.html#creating-geographic-extracts). +There is also [Protomaps](https://app.protomaps.com/) which can create custom extracts +for any region of the world with an easy to use drag and drop interface. +OSM data can be delivered as XML or in the more compact binary PBF format. OpenTripPlanner consumes +only PBF because it's smaller and more efficient. + +Download OSM PBF data for the same geographic region as your GTFS feed, and place this PBF file in +the same directory you created for the OSM data. If you are using the TriMet GTFS feed, you could +download +the [Geofabrik extract for the US state of Oregon](http://download.geofabrik.de/north-america/us/oregon.html) +, then further trim that to just +the [TriMet service area](https://trimet.org/pdfs/taxinfo/trimetdistrictboundary.pdf) using the +bounding box switch of one of the above tools. On Linux or MacOS you could do that as follows: + + $ cd /home/username + $ wget http://download.geofabrik.de/north-america/us/oregon-latest.osm.pbf + $ osmconvert oregon-latest.osm.pbf -b=-123.043,45.246,-122.276,45.652 --complete-ways -o=portland.pbf + $ mv portland.pbf otp + +We find [this tool](https://boundingbox.klokantech.com/) useful for determining the geographic +coordinates of bounding boxes. The CSV option in that tool produces exactly the format expected by +the `osmconvert -b` switch. The `--complete-ways` switch is important to handle roads that cross +outside your bounding box. + +If you have extracted a smaller PBF file from a larger region, be sure to put only your extract (not +the original larger file) in the directory with your GTFS data. Otherwise OTP will try to load both +the original file and the extract in a later step. See +the [page on preparing OSM data](Preparing-OSM.md) for additional information and example commands +for cropping and filtering OSM data. + +## Starting OTP + +A typical command to start OTP looks like `java -Xmx2G -jar otp.shaded.jar `. The +`-Xmx` parameter sets the limit on how much memory OTP is allowed to consume. GTFS and OSM data sets +are often very large, and OTP is relatively memory-hungry. You will need at least 1GB of memory when +working with the Portland TriMet data set, and several gigabytes for larger inputs. +[Here is more information about the system requirements](System-Requirements.md). If you have +sufficient memory in your computer, set this to a couple of gigabytes (e.g. `-Xmx2G`). Java uses +a [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) approach +to memory management, which requires some "breathing room" to efficiently operate. Without +sufficient free memory OTP can grind to a halt. [VisualVM](https://visualvm.github.io) is a good way +to inspect Java memory usage, especially with +the [VisualGC plugin](https://visualvm.github.io/plugins.html). + +## Building Graphs + +There are two main phases to preparing and deploying an OTP server. The first is to analyze the +GTFS, OSM and any other inputs (such as elevation data) and build a representation of the +transportation network. Following mathematical terminology we call this +a ['graph'](http://en.wikipedia.org/wiki/Graph_%28mathematics%29), and refer to this phase as "graph +building". The second phase is to start a server that provides trip planning and other API services +for this graph. + +It is possible to save the graph to a file on disk after the first phase, then load the graph from +the file in the second phase. This allows restarting the server or starting multiple instances of +the server without repeating the often time-consuming process of building the graph. It is also +possible to split the graph building process into separate OSM and GTFS stages for similar reasons: +to allow reusing results from slow processes, such as applying elevation data to streets. These +different options are controlled with command line switches, and will be described in more detail +below and in other tutorials. + +## Simple One-step Server + +The simplest way to use OTP is to build a graph in a single step and start a server immediately, +without saving it to disk. The command to do so is: + + $ java -Xmx2G -jar otp-2.5.0-shaded.jar --build --serve /home/username/otp + +where `/home/username/otp` should be the directory where you put your configuration and input files. + +If you're using the Portland input data, the graph build operation should take about one minute to +complete, and then you'll see a `Grizzly server running` message. At this point you have an +OpenTripPlanner server running locally and can open [http://localhost:8080/](http://localhost:8080/) +in a web browser. You should be presented with a Javascript client application that will interact +with your local OpenTripPlanner instance. + +This map-based user interface is in fact sending HTTP GET requests to the OTP server running on your +local machine. It can be informative to watch the HTTP requests and responses being generated using +the developer tools in your web browser. OTP's built-in web server will run by default on port 8080. +If by any chance some other software is already using that port number, you can specify a different +port number with a switch +`--port 8801`. + + +## Saving a Graph + +If you want speed up the process of repeatedly starting up a server with the same graph, you can +build a graph from street and transit data then save it to a file using the `--build` and `--save` +command line parameters together. If for example your current working directory (`.`) contains the +input files and the OTP JAR file, you can use this command: + + $ java -Xmx2G -jar otp-2.5.0-shaded.jar --build --save . + +This will produce a file called `graph.obj` in the same directory as the inputs. The server can then +be started later using the `--load` parameter, and will read this file instead of building the graph +from scratch: + + $ java -Xmx2G -jar otp-2.5.0-shaded.jar --load . + +Another reason to perform these two phases separately is that the building process loads the entire +GTFS and OSM data sets into memory, so can require significantly more memory than just running a +server. Accordingly, you may want to perform the build on one machine (e.g. a throw-away cloud +instance with more memory or compute capacity), then copy the resulting graph file to one or more +smaller machines to serve the API. + +## Layering GTFS onto OSM + +Building the street graph (especially with elevation data) can take a long time. It is common for +transit data to change more frequently than street data, so it can be convenient to build the street +graph once, and then layer transit data on top of the streets to make the final graph. + +Again assuming the input files and OTP JAR file are in the current working directory, you can build +a street graph with OSM and elevation data only (ignoring transit input files) with this command: + + $ java -Xmx2G -jar otp-2.5.0-shaded.jar --buildStreet . + +Then, to build a graph layering transit data on top of the saved street graph (built using the +previous command): + + $ java -Xmx2G -jar otp-2.5.0-shaded.jar --loadStreet --save . + +Finally, the server can be started using the `--load` parameter: + + $ java -Xmx2G -jar otp-2.5.0-shaded.jar --load . + +## Command Line Switches + +The flow diagram below summarizes all the command line switches used in the above examples, and how +they control which actions are taken when OTP starts up. + +![Command-Line-Parameter-Flow](images/cli-flow.svg) + +You must use at least one of the required parameters: `--load`, `--loadStreet`, `--build` +, `--buildStreet`. A _required_ parameter may imply other parameters when the flow allows for no +other choice. For example, `--load` implies `--serve`, so `--serve` is not necessary and has no +additional effect when used together with `--load`. + +You can run the OTP .jar file with the `--help` option for a full list of command line parameters. + +## Exploring the API + +If you want to learn how to use OTP's API's, check out the [GraphQL tutorial](apis/GraphQL-Tutorial.md). diff --git a/docs/Bibliography.md b/doc/user/Bibliography.md similarity index 100% rename from docs/Bibliography.md rename to doc/user/Bibliography.md diff --git a/docs/BoardingLocations.md b/doc/user/BoardingLocations.md similarity index 100% rename from docs/BoardingLocations.md rename to doc/user/BoardingLocations.md diff --git a/docs/BuildConfiguration.md b/doc/user/BuildConfiguration.md similarity index 100% rename from docs/BuildConfiguration.md rename to doc/user/BuildConfiguration.md diff --git a/docs/Changelog.md b/doc/user/Changelog.md similarity index 100% rename from docs/Changelog.md rename to doc/user/Changelog.md diff --git a/docs/Configuration.md b/doc/user/Configuration.md similarity index 100% rename from docs/Configuration.md rename to doc/user/Configuration.md diff --git a/docs/Container-Image.md b/doc/user/Container-Image.md similarity index 100% rename from docs/Container-Image.md rename to doc/user/Container-Image.md diff --git a/docs/Data-Sources.md b/doc/user/Data-Sources.md similarity index 100% rename from docs/Data-Sources.md rename to doc/user/Data-Sources.md diff --git a/docs/Deployments.md b/doc/user/Deployments.md similarity index 98% rename from docs/Deployments.md rename to doc/user/Deployments.md index d1df3984b05..56ff23c113c 100644 --- a/docs/Deployments.md +++ b/doc/user/Deployments.md @@ -1,96 +1,96 @@ -# OpenTripPlanner Deployments Worldwide - -## Official Production - -The following are known deployments of OTP in a government- or agency-sponsored production capacity: - -* **Norway (nationwide)** Since November 2017, the national integrated ticketing agency Entur has - prodvided a [national journey planner](https://en-tur.no/) which consumes schedule data in the EU - standard NeTEx format with SIRI real-time updates. Entur has contributed greatly to the OTP2 effort - and primarily uses OTP2 in production, handling peak loads in excess of 20 requests per second. - Most regional agencies in Norway, like **Ruter, Oslo area** uses OTP as a service provided by Entur. -* **Finland (nationwide)** The [Helsinki Regional Transport Authority](https://www.reittiopas.fi/), - the [Finnish Transport Agency](https://opas.matka.fi/), and - other [Finnish cities](https://waltti.fi/?lang=en) have collaborated to - create [Digitransit](https://digitransit.fi/en/), providing OTP-based trip planners, APIs, open - data, Docker containers and open source code. Each member organisation runs its own instance of a - shared codebase and deployment environment. Their source code is - available [on Github](https://github.com/HSLdevcom/), including - a [new custom UI](https://github.com/HSLdevcom/digitransit-ui). This system also has a strong - real-time component. -* **Finland Intercity** The Finnish intercity coach - service [Matkahuolto](https://en.wikipedia.org/wiki/Matkahuolto) - has [developed a trip planner in partnership with Kyyti](https://www.kyyti.com/matkahuoltos-new-app-brings-real-travel-chains-within-the-reach-of-citizens-in-addition-to-coach-travel-hsl-tickets-are-also-available/). -* **Skåne, Sweden**, the JourneyPlanner and mobile app for the regional transit agency [Skånetrafiken](https://www.skanetrafiken.se/) - uses OTP2 with the nordic profile of NeTEx and SIRI for real-time updates. -* [**Northern Colorado**](https://discover.rideno.co/) -* [**Philadelphia and surrounding areas**](https://plan.septa.org) -* **Portland, Oregon** TriMet is the agency that originally started the OpenTripPlanner project. - Their [Regional Trip Planner](http://ride.trimet.org) is based on OTP and provides about 40,000 - trip plans on a typical weekday. -* [**New York City**](https://new.mta.info/) -* **New York State** The State Department of - Transportation's [transit trip planner](https://511ny.org/#TransitRegion-1) provides itineraries - for public transit systems throughout the state in a single unified OTP instance. -* **Los Angeles, California** The new [metro.net trip planner](https://www.metro.net/). -* **Atlanta, Georgia** The Metropolitan Atlanta Rapid Transit Authority's ( - MARTA) [trip planner](http://itsmarta.com/planatrip.aspx) and the Atlanta region's transit - information hub [https://atlrides.com/](https://atlrides.com/) both use OTP to power their website trip - planners. -* **Boston, Massachusetts** - The [Massachusetts Bay Transportation Authority trip planner](https://www.mbta.com/trip-planner). -* **Seattle, Washington** The [Sound Transit Trip Planner](https://www.soundtransit.org/tripplanner) - is based on OTP. OTP also powers the trip planning feature of - the [OneBusAway native apps](http://onebusaway.org/) in the Puget Sound region. Technical details - are [here](https://github.com/OneBusAway/onebusaway-android/blob/master/SYSTEM_ARCHITECTURE.md#add-trip-planning-andor-bike-share-optional) - . -* [**Ride Metro Houston**](https://planyourtrip.ridemetro.org/) -* **Tampa, Florida** Hillsoborough Area Regional Transit uses an OpenTripPlanner server to power the - trip planning feature of the [OneBusAway native apps](http://onebusaway.org/) in their region. - Technical details - are [here](https://github.com/OneBusAway/onebusaway-android/blob/master/SYSTEM_ARCHITECTURE.md#add-trip-planning-andor-bike-share-optional) - . -* [**Piemonte Region, Italy**](https://map.muoversinpiemonte.it/#planner) and the [**City of - Torino**](https://www.muoversiatorino.it/) built on OpenTripPlanner - by [5T](http://www.5t.torino.it/). -* [**Valencia, Spain**](http://www.emtvalencia.es/geoportal/?lang=en_otp) from the Municipal - Transport Company of Valencia S.A.U. -* [**Grenoble, France**](http://www.metromobilite.fr/) from SMTC, Grenoble Alpes métropole, l'État - Français, the Rhône-alpes region, the Isère council and the City of Grenoble. -* **Rennes, France** where the STAR network provides an OTP client - for [iOS](https://itunes.apple.com/us/app/starbusmetro/id899970416?mt=8) - , [Android](https://play.google.com/store/apps/details?id=com.bookbeo.starbusmetro), Windows Phone - et Web. -* **Alençon, France** integrated urban and school bus - network [planner from Réunir Alençon](https://altobus.com/mon-itineraire/). -* [**Poznań, Poland**](http://ztm.poznan.pl/#planner) from Urban Transport Authority of Poznań (ZTM - Poznan). -* **Trento Province, Italy** - - [ViaggiaTrento](https://play.google.com/store/apps/details?id=eu.trentorise.smartcampus.viaggiatrento) - and [ViaggiaRovereto](https://play.google.com/store/apps/details?id=eu.trentorise.smartcampus.viaggiarovereto) - were implemented as part of the [SmartCampus Project](http://www.smartcampuslab.it), a research - project founded by [TrentoRise](http://trentorise.eu), [UNITN](http://www.unitn.it), - and [FBK](http://www.fbk.eu). -* **University of South Florida** (Tampa, Florida). The [USF Maps App](https://maps.usf.edu/) is a - responsive web application for that helps university students, staff, and visitors find their way - around the campus using multiple modes of transportation, including the USF Bull Runner campus - shuttle, Share-A-Bull bike share, and pedestrian pathways. - Open-sourced [on Github](https://github.com/CUTR-at-USF/usf-mobullity). -* **Lower Saxony, Germany** The [VBN](https://www.vbn.de/en/) transportation authority offers an [OTP instance](https://www.vbn.de/en/service/developer-information/opendata-and-openservice) as alternative to the [Hafas](https://www.hacon.de/en/portfolio/information-ticketing/#section_8294) passenger information system. -* **Leipzig, Germany** As of summer 2020 [Leipzig Move](https://leipzig-move.de/) has been using - OpenTripPlanner. - -## Independent Production - -The following OTP-based services are presented as production-quality deployments, but are not backed -by an official transportation authority or government. OTP is also known to be used on the back end -of several popular multi-city mobile trip planning applications. - -* **The Netherlands (nationwide)** [Plannerstack Foundation](http://www.plannerstack.org/) provides - national scale trip planning APIs using OTP and other open source trip planners, based - on [OpenOV's extremely detailed open data](http://gtfs.openov.nl/) including minutely real-time - updates for every vehicle in the country. -* [OTP Android](https://play.google.com/store/apps/details?id=edu.usf.cutr.opentripplanner.android) - by CUTR-USF and Vreixo González can find itineraries on many different OTP servers via a service - discovery mechanism. -* [**ViviBus Bologna**](http://www.vivibus.it/) Bologna, Italy. +# OpenTripPlanner Deployments Worldwide + +## Official Production + +The following are known deployments of OTP in a government- or agency-sponsored production capacity: + +* **Norway (nationwide)** Since November 2017, the national integrated ticketing agency Entur has + prodvided a [national journey planner](https://en-tur.no/) which consumes schedule data in the EU + standard NeTEx format with SIRI real-time updates. Entur has contributed greatly to the OTP2 effort + and primarily uses OTP2 in production, handling peak loads in excess of 20 requests per second. + Most regional agencies in Norway, like **Ruter, Oslo area** uses OTP as a service provided by Entur. +* **Finland (nationwide)** The [Helsinki Regional Transport Authority](https://www.reittiopas.fi/), + the [Finnish Transport Agency](https://opas.matka.fi/), and + other [Finnish cities](https://waltti.fi/?lang=en) have collaborated to + create [Digitransit](https://digitransit.fi/en/), providing OTP-based trip planners, APIs, open + data, Docker containers and open source code. Each member organisation runs its own instance of a + shared codebase and deployment environment. Their source code is + available [on Github](https://github.com/HSLdevcom/), including + a [new custom UI](https://github.com/HSLdevcom/digitransit-ui). This system also has a strong + real-time component. +* **Finland Intercity** The Finnish intercity coach + service [Matkahuolto](https://en.wikipedia.org/wiki/Matkahuolto) + has [developed a trip planner in partnership with Kyyti](https://www.kyyti.com/matkahuoltos-new-app-brings-real-travel-chains-within-the-reach-of-citizens-in-addition-to-coach-travel-hsl-tickets-are-also-available/). +* **Skåne, Sweden**, the JourneyPlanner and mobile app for the regional transit agency [Skånetrafiken](https://www.skanetrafiken.se/) + uses OTP2 with the nordic profile of NeTEx and SIRI for real-time updates. +* [**Northern Colorado**](https://discover.rideno.co/) +* [**Philadelphia and surrounding areas**](https://plan.septa.org) +* **Portland, Oregon** TriMet is the agency that originally started the OpenTripPlanner project. + Their [Regional Trip Planner](http://ride.trimet.org) is based on OTP and provides about 40,000 + trip plans on a typical weekday. +* [**New York City**](https://new.mta.info/) +* **New York State** The State Department of + Transportation's [transit trip planner](https://511ny.org/#TransitRegion-1) provides itineraries + for public transit systems throughout the state in a single unified OTP instance. +* **Los Angeles, California** The new [metro.net trip planner](https://www.metro.net/). +* **Atlanta, Georgia** The Metropolitan Atlanta Rapid Transit Authority's ( + MARTA) [trip planner](http://itsmarta.com/planatrip.aspx) and the Atlanta region's transit + information hub [https://atlrides.com/](https://atlrides.com/) both use OTP to power their website trip + planners. +* **Boston, Massachusetts** + The [Massachusetts Bay Transportation Authority trip planner](https://www.mbta.com/trip-planner). +* **Seattle, Washington** The [Sound Transit Trip Planner](https://www.soundtransit.org/tripplanner) + is based on OTP. OTP also powers the trip planning feature of + the [OneBusAway native apps](http://onebusaway.org/) in the Puget Sound region. Technical details + are [here](https://github.com/OneBusAway/onebusaway-android/blob/master/SYSTEM_ARCHITECTURE.md#add-trip-planning-andor-bike-share-optional) + . +* [**Ride Metro Houston**](https://planyourtrip.ridemetro.org/) +* **Tampa, Florida** Hillsoborough Area Regional Transit uses an OpenTripPlanner server to power the + trip planning feature of the [OneBusAway native apps](http://onebusaway.org/) in their region. + Technical details + are [here](https://github.com/OneBusAway/onebusaway-android/blob/master/SYSTEM_ARCHITECTURE.md#add-trip-planning-andor-bike-share-optional) + . +* [**Piemonte Region, Italy**](https://map.muoversinpiemonte.it/#planner) and the [**City of + Torino**](https://www.muoversiatorino.it/) built on OpenTripPlanner + by [5T](http://www.5t.torino.it/). +* [**Valencia, Spain**](http://www.emtvalencia.es/geoportal/?lang=en_otp) from the Municipal + Transport Company of Valencia S.A.U. +* [**Grenoble, France**](http://www.metromobilite.fr/) from SMTC, Grenoble Alpes métropole, l'État + Français, the Rhône-alpes region, the Isère council and the City of Grenoble. +* **Rennes, France** where the STAR network provides an OTP client + for [iOS](https://itunes.apple.com/us/app/starbusmetro/id899970416?mt=8) + , [Android](https://play.google.com/store/apps/details?id=com.bookbeo.starbusmetro), Windows Phone + et Web. +* **Alençon, France** integrated urban and school bus + network [planner from Réunir Alençon](https://altobus.com/mon-itineraire/). +* [**Poznań, Poland**](http://ztm.poznan.pl/#planner) from Urban Transport Authority of Poznań (ZTM + Poznan). +* **Trento Province, Italy** + - [ViaggiaTrento](https://play.google.com/store/apps/details?id=eu.trentorise.smartcampus.viaggiatrento) + and [ViaggiaRovereto](https://play.google.com/store/apps/details?id=eu.trentorise.smartcampus.viaggiarovereto) + were implemented as part of the [SmartCampus Project](http://www.smartcampuslab.it), a research + project founded by [TrentoRise](http://trentorise.eu), [UNITN](http://www.unitn.it), + and [FBK](http://www.fbk.eu). +* **University of South Florida** (Tampa, Florida). The [USF Maps App](https://maps.usf.edu/) is a + responsive web application for that helps university students, staff, and visitors find their way + around the campus using multiple modes of transportation, including the USF Bull Runner campus + shuttle, Share-A-Bull bike share, and pedestrian pathways. + Open-sourced [on Github](https://github.com/CUTR-at-USF/usf-mobullity). +* **Lower Saxony, Germany** The [VBN](https://www.vbn.de/en/) transportation authority offers an [OTP instance](https://www.vbn.de/en/service/developer-information/opendata-and-openservice) as alternative to the [Hafas](https://www.hacon.de/en/portfolio/information-ticketing/#section_8294) passenger information system. +* **Leipzig, Germany** As of summer 2020 [Leipzig Move](https://leipzig-move.de/) has been using + OpenTripPlanner. + +## Independent Production + +The following OTP-based services are presented as production-quality deployments, but are not backed +by an official transportation authority or government. OTP is also known to be used on the back end +of several popular multi-city mobile trip planning applications. + +* **The Netherlands (nationwide)** [Plannerstack Foundation](http://www.plannerstack.org/) provides + national scale trip planning APIs using OTP and other open source trip planners, based + on [OpenOV's extremely detailed open data](http://gtfs.openov.nl/) including minutely real-time + updates for every vehicle in the country. +* [OTP Android](https://play.google.com/store/apps/details?id=edu.usf.cutr.opentripplanner.android) + by CUTR-USF and Vreixo González can find itineraries on many different OTP servers via a service + discovery mechanism. +* [**ViviBus Bologna**](http://www.vivibus.it/) Bologna, Italy. diff --git a/docs/Developers-Guide.md b/doc/user/Developers-Guide.md similarity index 99% rename from docs/Developers-Guide.md rename to doc/user/Developers-Guide.md index 0b9ec011f96..e5ebfdb5e85 100644 --- a/docs/Developers-Guide.md +++ b/doc/user/Developers-Guide.md @@ -219,7 +219,7 @@ compile and test the new code, providing feedback on the stability of the build. ### Changelog workflow -The [changelog file](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/docs/Changelog.md) +The [changelog file](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/doc/user/Changelog.md) is generated from the pull-request(PR) _title_ using the [changelog workflow](https://github.com/opentripplanner/OpenTripPlanner/actions/workflows/automatic-changelog.yml) . The workflow runs after the PR is merged, and it changes, commits and pushes the _Changelog.md_. A diff --git a/docs/Frontends.md b/doc/user/Frontends.md similarity index 100% rename from docs/Frontends.md rename to doc/user/Frontends.md diff --git a/docs/Getting-OTP.md b/doc/user/Getting-OTP.md similarity index 100% rename from docs/Getting-OTP.md rename to doc/user/Getting-OTP.md diff --git a/docs/Governance.md b/doc/user/Governance.md similarity index 100% rename from docs/Governance.md rename to doc/user/Governance.md diff --git a/docs/History.md b/doc/user/History.md similarity index 100% rename from docs/History.md rename to doc/user/History.md diff --git a/docs/In-Station-Navigation.md b/doc/user/In-Station-Navigation.md similarity index 100% rename from docs/In-Station-Navigation.md rename to doc/user/In-Station-Navigation.md diff --git a/docs/IslandPruning.md b/doc/user/IslandPruning.md similarity index 100% rename from docs/IslandPruning.md rename to doc/user/IslandPruning.md diff --git a/docs/Localization.md b/doc/user/Localization.md similarity index 100% rename from docs/Localization.md rename to doc/user/Localization.md diff --git a/docs/Logging.md b/doc/user/Logging.md similarity index 100% rename from docs/Logging.md rename to doc/user/Logging.md diff --git a/docs/Migrating-Configuration.md b/doc/user/Migrating-Configuration.md similarity index 100% rename from docs/Migrating-Configuration.md rename to doc/user/Migrating-Configuration.md diff --git a/docs/Netex-Norway.md b/doc/user/Netex-Norway.md similarity index 100% rename from docs/Netex-Norway.md rename to doc/user/Netex-Norway.md diff --git a/docs/Preparing-OSM.md b/doc/user/Preparing-OSM.md similarity index 100% rename from docs/Preparing-OSM.md rename to doc/user/Preparing-OSM.md diff --git a/docs/Presentations.md b/doc/user/Presentations.md similarity index 100% rename from docs/Presentations.md rename to doc/user/Presentations.md diff --git a/docs/Product-Overview.md b/doc/user/Product-Overview.md similarity index 100% rename from docs/Product-Overview.md rename to doc/user/Product-Overview.md diff --git a/docs/README-DOCS.txt b/doc/user/README-DOCS.txt similarity index 100% rename from docs/README-DOCS.txt rename to doc/user/README-DOCS.txt diff --git a/docs/ReleaseChecklist.md b/doc/user/ReleaseChecklist.md similarity index 96% rename from docs/ReleaseChecklist.md rename to doc/user/ReleaseChecklist.md index 0f7c0667762..c67849bc538 100644 --- a/docs/ReleaseChecklist.md +++ b/doc/user/ReleaseChecklist.md @@ -14,8 +14,8 @@ manually is more tedious, but keeps eyes on each step and is less prone to failu * Check all links and references to the release and update to the target release version. Search all files for with a regular expression: `2\.[012]\.0` and replace if appropriate with the new version. - * In `docs/index.md` replace what is the latest version and add a new line for the previous one -* Update `docs/Changelog.md` + * In `doc/user/index.md` replace what is the latest version and add a new line for the previous one +* Update `doc/user/Changelog.md` * Lines should have been added or updated as each pull request was merged * If you suspect any changes are not reflected in the Changelog, review the commit log and add any missing items @@ -78,9 +78,9 @@ manually is more tedious, but keeps eyes on each step and is less prone to failu * `git merge master` * `git push` * Set up next development iteration - * Add a new section header to `docs/Changelog.md` like `x.y+1.0-SNAPSHOT (in progress)` + * Add a new section header to `doc/user/Changelog.md` like `x.y+1.0-SNAPSHOT (in progress)` * Edit minor version in `pom.xml` to `x.y+1.0-SNAPSHOT` - * `git add pom.xml docs/Changelog.md` + * `git add pom.xml doc/user/Changelog.md` * `git commit -m "Prepare next development iteration x.y+1.0-SNAPSHOT"` * `git push` * Send a message in Gitter and email the OTP users mailing lists diff --git a/docs/Roadmap.md b/doc/user/Roadmap.md similarity index 100% rename from docs/Roadmap.md rename to doc/user/Roadmap.md diff --git a/docs/RouteRequest.md b/doc/user/RouteRequest.md similarity index 100% rename from docs/RouteRequest.md rename to doc/user/RouteRequest.md diff --git a/docs/RouterConfiguration.md b/doc/user/RouterConfiguration.md similarity index 100% rename from docs/RouterConfiguration.md rename to doc/user/RouterConfiguration.md diff --git a/docs/RoutingModes.md b/doc/user/RoutingModes.md similarity index 100% rename from docs/RoutingModes.md rename to doc/user/RoutingModes.md diff --git a/docs/SandboxExtension.md b/doc/user/SandboxExtension.md similarity index 97% rename from docs/SandboxExtension.md rename to doc/user/SandboxExtension.md index 0d05518fd56..70dec6f678d 100644 --- a/docs/SandboxExtension.md +++ b/doc/user/SandboxExtension.md @@ -30,7 +30,7 @@ added in the test directory: `src/ext-test` - To integrate the new feature into OTP you may have to create new extension points in the main/core code. Changes to the core OTP are subject to normal a review process. -- Create a readme file (`docs/sandbox/.md` package including: +- Create a readme file (`doc/user/sandbox/.md` package including: - Extension Name - Contact info - Change log diff --git a/docs/StopAreas.md b/doc/user/StopAreas.md similarity index 100% rename from docs/StopAreas.md rename to doc/user/StopAreas.md diff --git a/docs/System-Requirements.md b/doc/user/System-Requirements.md similarity index 100% rename from docs/System-Requirements.md rename to doc/user/System-Requirements.md diff --git a/docs/Troubleshooting-Routing.md b/doc/user/Troubleshooting-Routing.md similarity index 100% rename from docs/Troubleshooting-Routing.md rename to doc/user/Troubleshooting-Routing.md diff --git a/docs/UpdaterConfig.md b/doc/user/UpdaterConfig.md similarity index 100% rename from docs/UpdaterConfig.md rename to doc/user/UpdaterConfig.md diff --git a/docs/Version-Comparison.md b/doc/user/Version-Comparison.md similarity index 100% rename from docs/Version-Comparison.md rename to doc/user/Version-Comparison.md diff --git a/docs/Visual-Identity.md b/doc/user/Visual-Identity.md similarity index 100% rename from docs/Visual-Identity.md rename to doc/user/Visual-Identity.md diff --git a/docs/apis/Apis.md b/doc/user/apis/Apis.md similarity index 100% rename from docs/apis/Apis.md rename to doc/user/apis/Apis.md diff --git a/docs/apis/GTFS-GraphQL-API.md b/doc/user/apis/GTFS-GraphQL-API.md similarity index 100% rename from docs/apis/GTFS-GraphQL-API.md rename to doc/user/apis/GTFS-GraphQL-API.md diff --git a/docs/apis/GraphQL-Tutorial.md b/doc/user/apis/GraphQL-Tutorial.md similarity index 100% rename from docs/apis/GraphQL-Tutorial.md rename to doc/user/apis/GraphQL-Tutorial.md diff --git a/docs/apis/TransmodelApi.md b/doc/user/apis/TransmodelApi.md similarity index 100% rename from docs/apis/TransmodelApi.md rename to doc/user/apis/TransmodelApi.md diff --git a/docs/examples/Readme.md b/doc/user/examples/Readme.md similarity index 100% rename from docs/examples/Readme.md rename to doc/user/examples/Readme.md diff --git a/docs/examples/entur/Readme.md b/doc/user/examples/entur/Readme.md similarity index 100% rename from docs/examples/entur/Readme.md rename to doc/user/examples/entur/Readme.md diff --git a/docs/examples/entur/build-config.json b/doc/user/examples/entur/build-config.json similarity index 100% rename from docs/examples/entur/build-config.json rename to doc/user/examples/entur/build-config.json diff --git a/docs/examples/entur/otp-config.json b/doc/user/examples/entur/otp-config.json similarity index 100% rename from docs/examples/entur/otp-config.json rename to doc/user/examples/entur/otp-config.json diff --git a/docs/examples/entur/router-config.json b/doc/user/examples/entur/router-config.json similarity index 100% rename from docs/examples/entur/router-config.json rename to doc/user/examples/entur/router-config.json diff --git a/docs/examples/ibi/atlanta/build-config.json b/doc/user/examples/ibi/atlanta/build-config.json similarity index 100% rename from docs/examples/ibi/atlanta/build-config.json rename to doc/user/examples/ibi/atlanta/build-config.json diff --git a/docs/examples/ibi/atlanta/otp-config.json b/doc/user/examples/ibi/atlanta/otp-config.json similarity index 100% rename from docs/examples/ibi/atlanta/otp-config.json rename to doc/user/examples/ibi/atlanta/otp-config.json diff --git a/docs/examples/ibi/atlanta/router-config.json b/doc/user/examples/ibi/atlanta/router-config.json similarity index 100% rename from docs/examples/ibi/atlanta/router-config.json rename to doc/user/examples/ibi/atlanta/router-config.json diff --git a/docs/examples/ibi/houston/build-config.json b/doc/user/examples/ibi/houston/build-config.json similarity index 100% rename from docs/examples/ibi/houston/build-config.json rename to doc/user/examples/ibi/houston/build-config.json diff --git a/docs/examples/ibi/portland/build-config.json b/doc/user/examples/ibi/portland/build-config.json similarity index 100% rename from docs/examples/ibi/portland/build-config.json rename to doc/user/examples/ibi/portland/build-config.json diff --git a/docs/examples/ibi/portland/otp-config.json b/doc/user/examples/ibi/portland/otp-config.json similarity index 100% rename from docs/examples/ibi/portland/otp-config.json rename to doc/user/examples/ibi/portland/otp-config.json diff --git a/docs/examples/ibi/portland/router-config.json b/doc/user/examples/ibi/portland/router-config.json similarity index 100% rename from docs/examples/ibi/portland/router-config.json rename to doc/user/examples/ibi/portland/router-config.json diff --git a/docs/examples/ibi/seattle/build-config.json b/doc/user/examples/ibi/seattle/build-config.json similarity index 100% rename from docs/examples/ibi/seattle/build-config.json rename to doc/user/examples/ibi/seattle/build-config.json diff --git a/docs/examples/ibi/seattle/router-config.json b/doc/user/examples/ibi/seattle/router-config.json similarity index 100% rename from docs/examples/ibi/seattle/router-config.json rename to doc/user/examples/ibi/seattle/router-config.json diff --git a/docs/examples/ibi/septa/router-config.json b/doc/user/examples/ibi/septa/router-config.json similarity index 100% rename from docs/examples/ibi/septa/router-config.json rename to doc/user/examples/ibi/septa/router-config.json diff --git a/docs/examples/skanetrafiken/Readme.md b/doc/user/examples/skanetrafiken/Readme.md similarity index 100% rename from docs/examples/skanetrafiken/Readme.md rename to doc/user/examples/skanetrafiken/Readme.md diff --git a/docs/examples/skanetrafiken/build-config.json b/doc/user/examples/skanetrafiken/build-config.json similarity index 100% rename from docs/examples/skanetrafiken/build-config.json rename to doc/user/examples/skanetrafiken/build-config.json diff --git a/docs/examples/skanetrafiken/oresund.json b/doc/user/examples/skanetrafiken/oresund.json similarity index 100% rename from docs/examples/skanetrafiken/oresund.json rename to doc/user/examples/skanetrafiken/oresund.json diff --git a/docs/examples/skanetrafiken/router-config.json b/doc/user/examples/skanetrafiken/router-config.json similarity index 100% rename from docs/examples/skanetrafiken/router-config.json rename to doc/user/examples/skanetrafiken/router-config.json diff --git a/docs/github_issue_linker.py b/doc/user/github_issue_linker.py similarity index 100% rename from docs/github_issue_linker.py rename to doc/user/github_issue_linker.py diff --git a/docs/images/ExternalToolDialog.png b/doc/user/images/ExternalToolDialog.png similarity index 100% rename from docs/images/ExternalToolDialog.png rename to doc/user/images/ExternalToolDialog.png diff --git a/docs/images/ServiceModelOverview.png b/doc/user/images/ServiceModelOverview.png similarity index 100% rename from docs/images/ServiceModelOverview.png rename to doc/user/images/ServiceModelOverview.png diff --git a/docs/images/TransitTimeLine.svg b/doc/user/images/TransitTimeLine.svg similarity index 100% rename from docs/images/TransitTimeLine.svg rename to doc/user/images/TransitTimeLine.svg diff --git a/docs/images/badprojection.png b/doc/user/images/badprojection.png similarity index 100% rename from docs/images/badprojection.png rename to doc/user/images/badprojection.png diff --git a/docs/images/bicycle-safety-report.png b/doc/user/images/bicycle-safety-report.png similarity index 100% rename from docs/images/bicycle-safety-report.png rename to doc/user/images/bicycle-safety-report.png diff --git a/docs/images/boarding-schwabstrasse.png b/doc/user/images/boarding-schwabstrasse.png similarity index 100% rename from docs/images/boarding-schwabstrasse.png rename to doc/user/images/boarding-schwabstrasse.png diff --git a/docs/images/buckhead-station.png b/doc/user/images/buckhead-station.png similarity index 100% rename from docs/images/buckhead-station.png rename to doc/user/images/buckhead-station.png diff --git a/docs/images/cli-flow.svg b/doc/user/images/cli-flow.svg similarity index 100% rename from docs/images/cli-flow.svg rename to doc/user/images/cli-flow.svg diff --git a/docs/images/example-isochrone.png b/doc/user/images/example-isochrone.png similarity index 100% rename from docs/images/example-isochrone.png rename to doc/user/images/example-isochrone.png diff --git a/docs/images/exiting-oesterfeld.png b/doc/user/images/exiting-oesterfeld.png similarity index 100% rename from docs/images/exiting-oesterfeld.png rename to doc/user/images/exiting-oesterfeld.png diff --git a/docs/images/graphiql-autocomplete.png b/doc/user/images/graphiql-autocomplete.png similarity index 100% rename from docs/images/graphiql-autocomplete.png rename to doc/user/images/graphiql-autocomplete.png diff --git a/docs/images/graphiql-documentation.png b/doc/user/images/graphiql-documentation.png similarity index 100% rename from docs/images/graphiql-documentation.png rename to doc/user/images/graphiql-documentation.png diff --git a/docs/images/graphiql.png b/doc/user/images/graphiql.png similarity index 100% rename from docs/images/graphiql.png rename to doc/user/images/graphiql.png diff --git a/docs/images/nothruisland.png b/doc/user/images/nothruisland.png similarity index 100% rename from docs/images/nothruisland.png rename to doc/user/images/nothruisland.png diff --git a/docs/images/osmislands.png b/doc/user/images/osmislands.png similarity index 100% rename from docs/images/osmislands.png rename to doc/user/images/osmislands.png diff --git a/docs/images/otp-logo.svg b/doc/user/images/otp-logo.svg similarity index 87% rename from docs/images/otp-logo.svg rename to doc/user/images/otp-logo.svg index 1ed23d0be8e..6e32af842a6 100644 --- a/docs/images/otp-logo.svg +++ b/doc/user/images/otp-logo.svg @@ -1,7 +1,8 @@ - + *
  • The configuration type table
  • *
  • The list of OTP features
  • * - * This test fails if the document have changed. This make sure that this test fails in the - * CI pipeline if config file changes is not committed. Manually inspect the changes in the + * This test fails if the document has changed. This makes sure that this test fails in the + * CI pipeline if config file changes are not committed. Manually inspect the changes in the * configuration, commit the configuration document, and run test again to pass. */ @Test diff --git a/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java b/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java index 3597844a027..83e607449eb 100644 --- a/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java @@ -25,7 +25,7 @@ public class GraphQLTutorialDocTest { private static final File OUT_FILE = new File(DOCS_ROOT + "/apis", "GraphQL-Tutorial.md"); /** - * NOTE! This test updates the {@code docs/GraphQlTutorial.md} document based on the latest + * NOTE! This test updates the {@code doc/user/GraphQlTutorial.md} document based on the latest * version of the code. * This test fails if the document have changed. This make sure that this test fails in the * CI pipeline if config file changes is not committed. Manually inspect the changes in the diff --git a/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java index 76642db3e5a..0d4f0e9cff1 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java @@ -34,7 +34,7 @@ public class RouteRequestDocTest { .build(); /** - * NOTE! This test updates the {@code docs/RouteRequest.md} document based on the latest + * NOTE! This test updates the {@code doc/user/RouteRequest.md} document based on the latest * version of the code. The following is auto generated: *
      *
    • The configuration type table
    • diff --git a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java index 90cdd9de975..2ec95c3cd05 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java @@ -40,7 +40,7 @@ public class RouterConfigurationDocTest { .build(); /** - * NOTE! This test updates the {@code docs/Configuration.md} document based on the latest + * NOTE! This test updates the {@code doc/user/Configuration.md} document based on the latest * version of the code. The following is auto generated: *
        *
      • The configuration type table
      • diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java index 374ac2b4bbb..c910ee3bf7b 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java @@ -37,7 +37,7 @@ public class SiriAzureConfigDocTest { public static final ObjectMapper mapper = new ObjectMapper(); /** - * NOTE! This test updates the {@code docs/sandbox/SiriUpdater.md} document based on the latest + * NOTE! This test updates the {@code doc/user/sandbox/SiriUpdater.md} document based on the latest * version of the code. */ @Test diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java index 2474f37c402..46d829cc4c3 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java @@ -34,7 +34,7 @@ public class SiriConfigDocTest { public static final ObjectMapper mapper = new ObjectMapper(); /** - * NOTE! This test updates the {@code docs/sandbox/SiriUpdater.md} document based on the latest + * NOTE! This test updates the {@code doc/user/sandbox/SiriUpdater.md} document based on the latest * version of the code. */ @Test diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java index f5aa3e130ed..342344363b3 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java @@ -40,7 +40,7 @@ public class SiriGooglePubSubConfigDocTest { public static final ObjectMapper mapper = new ObjectMapper(); /** - * NOTE! This test updates the {@code docs/sandbox/SiriGooglePubSubUpdater.md} document based on the latest + * NOTE! This test updates the {@code doc/user/sandbox/SiriGooglePubSubUpdater.md} document based on the latest * version of the code. */ @Test diff --git a/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java index 264d0d6850a..75d6cb6fe5a 100644 --- a/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java @@ -41,7 +41,7 @@ public class UpdaterConfigDocTest { public static final ObjectMapper mapper = new ObjectMapper(); /** - * NOTE! This test updates the {@code docs/Configuration.md} document based on the latest + * NOTE! This test updates the {@code doc/user/Configuration.md} document based on the latest * version of the code. The following is auto generated: *
          *
        • The configuration type table
        • diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java b/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java index d7a67a3590b..3f9f30c30b1 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java +++ b/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java @@ -10,7 +10,7 @@ public interface DocsTestConstants { Logger LOG = LoggerFactory.getLogger(DocsTestConstants.class); File TEMPLATE_ROOT = new File("doc-templates"); - File DOCS_ROOT = new File("docs"); + File DOCS_ROOT = new File("doc/user"); /** * This method return {@code true} if the /docs directory is available. If not, a warning is @@ -25,7 +25,7 @@ static boolean docsExistOrWarn() { """ SKIP TEST - '/docs' NOT FOUND - The docs/doc-templates directory might not be available if you run the tests outside the + The doc/templates directory might not be available if you run the tests outside the root of the projects. This may happen if the project root is not the working directory, if you run tests using jar files or in a Maven multi-module project. diff --git a/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java b/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java index b250126c019..12b8749c1fe 100644 --- a/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java +++ b/src/test/java/org/opentripplanner/standalone/config/ExampleConfigTest.java @@ -22,7 +22,7 @@ @GeneratesDocumentation public class ExampleConfigTest { - @FilePatternSource(pattern = "docs/examples/**/" + ROUTER_CONFIG_FILENAME) + @FilePatternSource(pattern = "doc/user/examples/**/" + ROUTER_CONFIG_FILENAME) @ParameterizedTest(name = "Check validity of {0}") void routerConfig(Path filename) { testConfig(filename, a -> new RouterConfig(a, true)); @@ -30,7 +30,8 @@ void routerConfig(Path filename) { @FilePatternSource( pattern = { - "docs/examples/**/" + BUILD_CONFIG_FILENAME, "test/performance/**/" + BUILD_CONFIG_FILENAME, + "doc/user/examples/**/" + BUILD_CONFIG_FILENAME, + "test/performance/**/" + BUILD_CONFIG_FILENAME, } ) @ParameterizedTest(name = "Check validity of {0}") @@ -45,7 +46,9 @@ void speedTestConfig(Path filename) { } @FilePatternSource( - pattern = { "test/performance/**/otp-config.json", "docs/examples/**/" + OTP_CONFIG_FILENAME } + pattern = { + "test/performance/**/otp-config.json", "doc/user/examples/**/" + OTP_CONFIG_FILENAME, + } ) @ParameterizedTest(name = "Check validity of {0}") void otpConfig(Path filename) { diff --git a/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java b/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java index 35869a9094e..c084a81a73f 100644 --- a/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java +++ b/src/test/java/org/opentripplanner/test/support/FilePatternArgumentsProvider.java @@ -19,7 +19,7 @@ /** * This annotation processor allows you to provide a file pattern like - * "docs/examples/**\/build-config.json" as the input for a JUnit + * "doc/user/examples/**\/build-config.json" as the input for a JUnit * {@link org.junit.jupiter.params.ParameterizedTest}. *

          * Check the usages of {@link FilePatternSource} to see examples for how to use. From eb5bbae55910c2bb8b733086ddf2f86ef9c62c0a Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 24 Jul 2024 15:45:54 +0200 Subject: [PATCH 17/93] Move /doc-templates to /doc/templates --- {doc-templates => doc/templates}/BuildConfiguration.md | 2 +- {doc-templates => doc/templates}/Configuration.md | 2 +- {doc-templates => doc/templates}/Emissions.md | 0 {doc-templates => doc/templates}/Flex.md | 0 {doc-templates => doc/templates}/GraphQL-Tutorial.md | 2 +- {doc-templates => doc/templates}/RideHailing.md | 0 {doc-templates => doc/templates}/RouteRequest.md | 2 +- {doc-templates => doc/templates}/RouterConfiguration.md | 2 +- {doc-templates => doc/templates}/RoutingModes.md | 0 {doc-templates => doc/templates}/StopConsolidation.md | 2 +- {doc-templates => doc/templates}/UpdaterConfig.md | 2 +- {doc-templates => doc/templates}/VehicleParking.md | 0 .../templates}/sandbox/MapboxVectorTilesApi.md | 0 .../templates}/sandbox/VehicleRentalServiceDirectory.md | 0 .../templates}/sandbox/siri/SiriAzureUpdater.md | 0 .../templates}/sandbox/siri/SiriGooglePubSubUpdater.md | 0 .../templates}/sandbox/siri/SiriUpdater.md | 0 doc/user/BuildConfiguration.md | 2 +- doc/user/Configuration.md | 2 +- doc/user/RouteRequest.md | 2 +- doc/user/RouterConfiguration.md | 2 +- doc/user/UpdaterConfig.md | 2 +- doc/user/apis/GraphQL-Tutorial.md | 2 +- doc/user/sandbox/StopConsolidation.md | 2 +- .../ext/vectortiles/VectorTilesConfigDocTest.java | 8 ++++---- .../VehicleRentalServiceDirectoryConfigDocTest.java | 8 ++++---- .../generate/doc/BuildConfigurationDocTest.java | 8 ++++---- .../generate/doc/ConfigurationDocTest.java | 8 ++++---- .../generate/doc/EmissionsConfigurationDocTest.java | 8 ++++---- .../generate/doc/FlexConfigurationDocTest.java | 8 ++++---- .../generate/doc/GraphQLTutorialDocTest.java | 8 ++++---- .../opentripplanner/generate/doc/RideHailingDocTest.java | 8 ++++---- .../opentripplanner/generate/doc/RouteRequestDocTest.java | 8 ++++---- .../generate/doc/RouterConfigurationDocTest.java | 8 ++++---- .../opentripplanner/generate/doc/RoutingModeDocTest.java | 8 ++++---- .../generate/doc/SiriAzureConfigDocTest.java | 8 ++++---- .../opentripplanner/generate/doc/SiriConfigDocTest.java | 8 ++++---- .../generate/doc/SiriGooglePubSubConfigDocTest.java | 8 ++++---- .../generate/doc/StopConsolidationDocTest.java | 8 ++++---- .../generate/doc/UpdaterConfigDocTest.java | 8 ++++---- .../generate/doc/VehicleParkingDocTest.java | 8 ++++---- .../generate/doc/framework/DocsTestConstants.java | 7 ++++--- 42 files changed, 86 insertions(+), 85 deletions(-) rename {doc-templates => doc/templates}/BuildConfiguration.md (99%) rename {doc-templates => doc/templates}/Configuration.md (99%) rename {doc-templates => doc/templates}/Emissions.md (100%) rename {doc-templates => doc/templates}/Flex.md (100%) rename {doc-templates => doc/templates}/GraphQL-Tutorial.md (97%) rename {doc-templates => doc/templates}/RideHailing.md (100%) rename {doc-templates => doc/templates}/RouteRequest.md (92%) rename {doc-templates => doc/templates}/RouterConfiguration.md (96%) rename {doc-templates => doc/templates}/RoutingModes.md (100%) rename {doc-templates => doc/templates}/StopConsolidation.md (97%) rename {doc-templates => doc/templates}/UpdaterConfig.md (98%) rename {doc-templates => doc/templates}/VehicleParking.md (100%) rename {doc-templates => doc/templates}/sandbox/MapboxVectorTilesApi.md (100%) rename {doc-templates => doc/templates}/sandbox/VehicleRentalServiceDirectory.md (100%) rename {doc-templates => doc/templates}/sandbox/siri/SiriAzureUpdater.md (100%) rename {doc-templates => doc/templates}/sandbox/siri/SiriGooglePubSubUpdater.md (100%) rename {doc-templates => doc/templates}/sandbox/siri/SiriUpdater.md (100%) diff --git a/doc-templates/BuildConfiguration.md b/doc/templates/BuildConfiguration.md similarity index 99% rename from doc-templates/BuildConfiguration.md rename to doc/templates/BuildConfiguration.md index 43a29e1fb79..7e768e30eb1 100644 --- a/doc-templates/BuildConfiguration.md +++ b/doc/templates/BuildConfiguration.md @@ -1,7 +1,7 @@ diff --git a/doc-templates/Configuration.md b/doc/templates/Configuration.md similarity index 99% rename from doc-templates/Configuration.md rename to doc/templates/Configuration.md index e06adc46dc5..0ef96b8d4fa 100644 --- a/doc-templates/Configuration.md +++ b/doc/templates/Configuration.md @@ -1,7 +1,7 @@ diff --git a/doc-templates/Emissions.md b/doc/templates/Emissions.md similarity index 100% rename from doc-templates/Emissions.md rename to doc/templates/Emissions.md diff --git a/doc-templates/Flex.md b/doc/templates/Flex.md similarity index 100% rename from doc-templates/Flex.md rename to doc/templates/Flex.md diff --git a/doc-templates/GraphQL-Tutorial.md b/doc/templates/GraphQL-Tutorial.md similarity index 97% rename from doc-templates/GraphQL-Tutorial.md rename to doc/templates/GraphQL-Tutorial.md index 51f0ef7880a..11a2e304119 100644 --- a/doc-templates/GraphQL-Tutorial.md +++ b/doc/templates/GraphQL-Tutorial.md @@ -1,7 +1,7 @@ diff --git a/doc-templates/RideHailing.md b/doc/templates/RideHailing.md similarity index 100% rename from doc-templates/RideHailing.md rename to doc/templates/RideHailing.md diff --git a/doc-templates/RouteRequest.md b/doc/templates/RouteRequest.md similarity index 92% rename from doc-templates/RouteRequest.md rename to doc/templates/RouteRequest.md index 4abfdec71e2..a452e1d1480 100644 --- a/doc-templates/RouteRequest.md +++ b/doc/templates/RouteRequest.md @@ -1,7 +1,7 @@ diff --git a/doc-templates/RouterConfiguration.md b/doc/templates/RouterConfiguration.md similarity index 96% rename from doc-templates/RouterConfiguration.md rename to doc/templates/RouterConfiguration.md index f181bf5db93..b6c6ccf9c4b 100644 --- a/doc-templates/RouterConfiguration.md +++ b/doc/templates/RouterConfiguration.md @@ -1,7 +1,7 @@ diff --git a/doc-templates/RoutingModes.md b/doc/templates/RoutingModes.md similarity index 100% rename from doc-templates/RoutingModes.md rename to doc/templates/RoutingModes.md diff --git a/doc-templates/StopConsolidation.md b/doc/templates/StopConsolidation.md similarity index 97% rename from doc-templates/StopConsolidation.md rename to doc/templates/StopConsolidation.md index c92cab6afe1..6817ee47d4c 100644 --- a/doc-templates/StopConsolidation.md +++ b/doc/templates/StopConsolidation.md @@ -1,7 +1,7 @@ # Stop consolidation diff --git a/doc-templates/UpdaterConfig.md b/doc/templates/UpdaterConfig.md similarity index 98% rename from doc-templates/UpdaterConfig.md rename to doc/templates/UpdaterConfig.md index f16d28f570c..440cd96f733 100644 --- a/doc-templates/UpdaterConfig.md +++ b/doc/templates/UpdaterConfig.md @@ -1,7 +1,7 @@ diff --git a/doc-templates/VehicleParking.md b/doc/templates/VehicleParking.md similarity index 100% rename from doc-templates/VehicleParking.md rename to doc/templates/VehicleParking.md diff --git a/doc-templates/sandbox/MapboxVectorTilesApi.md b/doc/templates/sandbox/MapboxVectorTilesApi.md similarity index 100% rename from doc-templates/sandbox/MapboxVectorTilesApi.md rename to doc/templates/sandbox/MapboxVectorTilesApi.md diff --git a/doc-templates/sandbox/VehicleRentalServiceDirectory.md b/doc/templates/sandbox/VehicleRentalServiceDirectory.md similarity index 100% rename from doc-templates/sandbox/VehicleRentalServiceDirectory.md rename to doc/templates/sandbox/VehicleRentalServiceDirectory.md diff --git a/doc-templates/sandbox/siri/SiriAzureUpdater.md b/doc/templates/sandbox/siri/SiriAzureUpdater.md similarity index 100% rename from doc-templates/sandbox/siri/SiriAzureUpdater.md rename to doc/templates/sandbox/siri/SiriAzureUpdater.md diff --git a/doc-templates/sandbox/siri/SiriGooglePubSubUpdater.md b/doc/templates/sandbox/siri/SiriGooglePubSubUpdater.md similarity index 100% rename from doc-templates/sandbox/siri/SiriGooglePubSubUpdater.md rename to doc/templates/sandbox/siri/SiriGooglePubSubUpdater.md diff --git a/doc-templates/sandbox/siri/SiriUpdater.md b/doc/templates/sandbox/siri/SiriUpdater.md similarity index 100% rename from doc-templates/sandbox/siri/SiriUpdater.md rename to doc/templates/sandbox/siri/SiriUpdater.md diff --git a/doc/user/BuildConfiguration.md b/doc/user/BuildConfiguration.md index cefd8d2cf2f..561963f1a1f 100644 --- a/doc/user/BuildConfiguration.md +++ b/doc/user/BuildConfiguration.md @@ -1,7 +1,7 @@ diff --git a/doc/user/Configuration.md b/doc/user/Configuration.md index 05611e23628..e7d30fbaae5 100644 --- a/doc/user/Configuration.md +++ b/doc/user/Configuration.md @@ -1,7 +1,7 @@ diff --git a/doc/user/RouteRequest.md b/doc/user/RouteRequest.md index 14d937eeb63..28c5e288971 100644 --- a/doc/user/RouteRequest.md +++ b/doc/user/RouteRequest.md @@ -1,7 +1,7 @@ diff --git a/doc/user/RouterConfiguration.md b/doc/user/RouterConfiguration.md index a3042e7b91f..53aa82f66f2 100644 --- a/doc/user/RouterConfiguration.md +++ b/doc/user/RouterConfiguration.md @@ -1,7 +1,7 @@ diff --git a/doc/user/UpdaterConfig.md b/doc/user/UpdaterConfig.md index ebe0acf94b4..f3a0d982e68 100644 --- a/doc/user/UpdaterConfig.md +++ b/doc/user/UpdaterConfig.md @@ -1,7 +1,7 @@ diff --git a/doc/user/apis/GraphQL-Tutorial.md b/doc/user/apis/GraphQL-Tutorial.md index bfc87813f1d..d65fbc144ba 100644 --- a/doc/user/apis/GraphQL-Tutorial.md +++ b/doc/user/apis/GraphQL-Tutorial.md @@ -1,7 +1,7 @@ diff --git a/doc/user/sandbox/StopConsolidation.md b/doc/user/sandbox/StopConsolidation.md index 750a873b547..b36429b1f60 100644 --- a/doc/user/sandbox/StopConsolidation.md +++ b/doc/user/sandbox/StopConsolidation.md @@ -1,7 +1,7 @@ # Stop consolidation diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java index 233e3fa3737..51e1738ff6c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java @@ -4,8 +4,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromPath; @@ -24,8 +24,8 @@ public class VectorTilesConfigDocTest { private static final String DOCUMENT = "sandbox/MapboxVectorTilesApi.md"; - private static final File TEMPLATE = new File(TEMPLATE_ROOT, DOCUMENT); - private static final File OUT_FILE = new File(DOCS_ROOT, DOCUMENT); + private static final File TEMPLATE = new File(TEMPLATE_PATH, DOCUMENT); + private static final File OUT_FILE = new File(USER_DOC_PATH, DOCUMENT); private static final SkipNodes SKIP_NODES = SkipNodes.of().build(); @Test diff --git a/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java b/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java index 4936bb4dd44..2afcd95949c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; @@ -26,8 +26,8 @@ public class VehicleRentalServiceDirectoryConfigDocTest { private static final String DOCUMENT = "sandbox/VehicleRentalServiceDirectory.md"; - private static final File TEMPLATE = new File(TEMPLATE_ROOT, DOCUMENT); - private static final File OUT_FILE = new File(DOCS_ROOT, DOCUMENT); + private static final File TEMPLATE = new File(TEMPLATE_PATH, DOCUMENT); + private static final File OUT_FILE = new File(USER_DOC_PATH, DOCUMENT); private static final String CONFIG_PATH = "org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/" + ROUTER_CONFIG_FILENAME; private static final String CONFIG_TAG = "vehicleRentalServiceDirectory"; diff --git a/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java index bc17fdc1f31..8189f18f20e 100644 --- a/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java @@ -4,8 +4,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_3; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; @@ -25,8 +25,8 @@ public class BuildConfigurationDocTest { private static final String CONFIG_JSON = OtpFileNames.BUILD_CONFIG_FILENAME; - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "BuildConfiguration.md"); - private static final File OUT_FILE = new File(DOCS_ROOT, "BuildConfiguration.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "BuildConfiguration.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "BuildConfiguration.md"); private static final String CONFIG_PATH = "standalone/config/" + CONFIG_JSON; private static final SkipNodes SKIP_NODES = SkipNodes diff --git a/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java index c310e2858a8..fed5ddb325d 100644 --- a/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java @@ -3,8 +3,8 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.generate.doc.support.ConfigTypeTable.configTypeTable; import static org.opentripplanner.generate.doc.support.OTPFeatureTable.otpFeaturesTable; @@ -16,9 +16,9 @@ @GeneratesDocumentation public class ConfigurationDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "Configuration.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "Configuration.md"); - private static final File OUT_FILE = new File(DOCS_ROOT, "Configuration.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "Configuration.md"); private static final String CONFIG_TYPE_PLACEHOLDER = "CONFIGURATION-TYPES-TABLE"; private static final String OTP_FEATURE_PLACEHOLDER = "OTP-FEATURE-TABLE"; diff --git a/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java index 68caa043e26..5010c78d527 100644 --- a/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/EmissionsConfigurationDocTest.java @@ -4,8 +4,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -24,8 +24,8 @@ @GeneratesDocumentation public class EmissionsConfigurationDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "Emissions.md"); - private static final File OUT_FILE = new File(DOCS_ROOT + "/sandbox", "Emissions.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "Emissions.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH + "/sandbox", "Emissions.md"); private static final String CONFIG_JSON = OtpFileNames.BUILD_CONFIG_FILENAME; private static final String CONFIG_PATH = "standalone/config/" + CONFIG_JSON; private static final SkipNodes SKIP_NODES = SkipNodes.of().build(); diff --git a/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java index fd2d7092dc5..e18090466b9 100644 --- a/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java @@ -4,8 +4,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -23,8 +23,8 @@ @GeneratesDocumentation public class FlexConfigurationDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "Flex.md"); - private static final File OUT_FILE = new File(DOCS_ROOT + "/sandbox", "Flex.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "Flex.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH + "/sandbox", "Flex.md"); private static final String ROUTER_CONFIG_FILENAME = "standalone/config/router-config.json"; private static final SkipNodes SKIP_NODES = SkipNodes.of().build(); diff --git a/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java b/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java index 83e607449eb..7eb6a685cca 100644 --- a/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java @@ -4,8 +4,8 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import com.google.common.io.Resources; @@ -20,9 +20,9 @@ @GeneratesDocumentation public class GraphQLTutorialDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "GraphQL-Tutorial.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "GraphQL-Tutorial.md"); - private static final File OUT_FILE = new File(DOCS_ROOT + "/apis", "GraphQL-Tutorial.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH + "/apis", "GraphQL-Tutorial.md"); /** * NOTE! This test updates the {@code doc/user/GraphQlTutorial.md} document based on the latest diff --git a/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java index 7ebd90260f1..2d04e002413 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RideHailingDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -24,8 +24,8 @@ @GeneratesDocumentation public class RideHailingDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "RideHailing.md"); - private static final File OUT_FILE = new File(DOCS_ROOT + "/sandbox", "RideHailing.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "RideHailing.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH + "/sandbox", "RideHailing.md"); private static final String ROUTER_CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; private static final SkipNodes SKIP_NODES = SkipNodes.of().build(); diff --git a/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java index 0d4f0e9cff1..b4725c5e2a1 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_3; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; @@ -25,8 +25,8 @@ @GeneratesDocumentation public class RouteRequestDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "RouteRequest.md"); - private static final File OUT_FILE = new File(DOCS_ROOT, "RouteRequest.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "RouteRequest.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "RouteRequest.md"); private static final String ROUTER_CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; private static final SkipNodes SKIP_NODES = SkipNodes .of() diff --git a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java index 2ec95c3cd05..77490c506fd 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_3; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceJsonExample; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersDetails; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceParametersTable; @@ -24,8 +24,8 @@ @GeneratesDocumentation public class RouterConfigurationDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "RouterConfiguration.md"); - private static final File OUT_FILE = new File(DOCS_ROOT, "RouterConfiguration.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "RouterConfiguration.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "RouterConfiguration.md"); private static final String CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; private static final SkipNodes SKIP_NODES = SkipNodes diff --git a/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java index 0c6edc7e16b..188101e3b5d 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java @@ -3,8 +3,8 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import java.io.File; @@ -19,8 +19,8 @@ @GeneratesDocumentation public class RoutingModeDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "RoutingModes.md"); - private static final File OUT_FILE = new File(DOCS_ROOT, "RoutingModes.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "RoutingModes.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "RoutingModes.md"); @Test public void updateDocs() { diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java index c910ee3bf7b..fcf93770f38 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/SiriAzureConfigDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -25,8 +25,8 @@ @GeneratesDocumentation public class SiriAzureConfigDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "sandbox/siri/SiriAzureUpdater.md"); - private static final File OUT_FILE = new File(DOCS_ROOT, "sandbox/siri/SiriAzureUpdater.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "sandbox/siri/SiriAzureUpdater.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "sandbox/siri/SiriAzureUpdater.md"); private static final String ROUTER_CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; private static final Set INCLUDE_UPDATERS = Set.of( diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java index 46d829cc4c3..71df3027c7d 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/SiriConfigDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -25,8 +25,8 @@ @GeneratesDocumentation public class SiriConfigDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "sandbox/siri/SiriUpdater.md"); - private static final File OUT_FILE = new File(DOCS_ROOT, "sandbox/siri/SiriUpdater.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "sandbox/siri/SiriUpdater.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "sandbox/siri/SiriUpdater.md"); private static final String ROUTER_CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; private static final Set INCLUDE_UPDATERS = Set.of("siri-et-updater", "siri-sx-updater"); diff --git a/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java index 342344363b3..ce414b298d0 100644 --- a/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/SiriGooglePubSubConfigDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -26,11 +26,11 @@ public class SiriGooglePubSubConfigDocTest { private static final File TEMPLATE = new File( - TEMPLATE_ROOT, + TEMPLATE_PATH, "sandbox/siri/SiriGooglePubSubUpdater.md" ); private static final File OUT_FILE = new File( - DOCS_ROOT, + USER_DOC_PATH, "sandbox/siri/SiriGooglePubSubUpdater.md" ); diff --git a/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java index 62f76032a09..2861253aac7 100644 --- a/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/StopConsolidationDocTest.java @@ -3,8 +3,8 @@ import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -21,8 +21,8 @@ public class StopConsolidationDocTest { private static final String FILE_NAME = "StopConsolidation.md"; - private static final File TEMPLATE = new File(TEMPLATE_ROOT, FILE_NAME); - private static final File OUT_FILE = new File(DOCS_ROOT + "/sandbox", FILE_NAME); + private static final File TEMPLATE = new File(TEMPLATE_PATH, FILE_NAME); + private static final File OUT_FILE = new File(USER_DOC_PATH + "/sandbox", FILE_NAME); private static final String CONFIG_FILENAME = "standalone/config/build-config.json"; diff --git a/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java index 75d6cb6fe5a..7a3f2969c4d 100644 --- a/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -25,8 +25,8 @@ @GeneratesDocumentation public class UpdaterConfigDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "UpdaterConfig.md"); - private static final File OUT_FILE = new File(DOCS_ROOT, "UpdaterConfig.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "UpdaterConfig.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH, "UpdaterConfig.md"); private static final String ROUTER_CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; private static final Set SKIP_UPDATERS = Set.of( diff --git a/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java b/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java index abc9ceee806..caffafdf72b 100644 --- a/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java @@ -5,8 +5,8 @@ import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; -import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_PATH; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.USER_DOC_PATH; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; @@ -23,8 +23,8 @@ @GeneratesDocumentation public class VehicleParkingDocTest { - private static final File TEMPLATE = new File(TEMPLATE_ROOT, "VehicleParking.md"); - private static final File OUT_FILE = new File(DOCS_ROOT + "/sandbox", "VehicleParking.md"); + private static final File TEMPLATE = new File(TEMPLATE_PATH, "VehicleParking.md"); + private static final File OUT_FILE = new File(USER_DOC_PATH + "/sandbox", "VehicleParking.md"); private static final String ROUTER_CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; private static final SkipNodes SKIP_NODES = SkipNodes.of().build(); diff --git a/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java b/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java index 3f9f30c30b1..a7f7afa806a 100644 --- a/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java +++ b/src/test/java/org/opentripplanner/generate/doc/framework/DocsTestConstants.java @@ -9,8 +9,9 @@ */ public interface DocsTestConstants { Logger LOG = LoggerFactory.getLogger(DocsTestConstants.class); - File TEMPLATE_ROOT = new File("doc-templates"); - File DOCS_ROOT = new File("doc/user"); + File DOC_ROOT = new File("doc"); + File TEMPLATE_PATH = new File(DOC_ROOT, "templates"); + File USER_DOC_PATH = new File(DOC_ROOT, "user"); /** * This method return {@code true} if the /docs directory is available. If not, a warning is @@ -18,7 +19,7 @@ public interface DocsTestConstants { * annotation. */ static boolean docsExistOrWarn() { - if (DOCS_ROOT.exists()) { + if (USER_DOC_PATH.exists()) { return true; } LOG.warn( From 3d37531ac1b691b880791d172b0e402619cf2506 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 24 Jul 2024 17:17:02 +0200 Subject: [PATCH 18/93] Set user-doc directory in mkdocs.yml --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 145d3f3809e..8b3748be2b0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -6,7 +6,7 @@ site_name: OpenTripPlanner 2 site_url: https://docs.opentripplanner.org repo_url: https://github.com/opentripplanner/OpenTripPlanner -docs_dir: docs +docs_dir: doc/user site_dir: target/mkdocs strict: true From 759e184b48dbf17508d6c4bb1e6f9ca28961f8e5 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 25 Jul 2024 13:48:16 +0200 Subject: [PATCH 19/93] Update doc/dev/decisionrecords/RecordsPOJOsBuilders.md --- doc/dev/decisionrecords/RecordsPOJOsBuilders.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/dev/decisionrecords/RecordsPOJOsBuilders.md b/doc/dev/decisionrecords/RecordsPOJOsBuilders.md index 34019d503e6..1a836374181 100644 --- a/doc/dev/decisionrecords/RecordsPOJOsBuilders.md +++ b/doc/dev/decisionrecords/RecordsPOJOsBuilders.md @@ -16,7 +16,7 @@ Builder initStop(Stop stop) { You may use records, but avoid using records if you can not encapsulate it properly. Be especially aware of arrays fields (can not be protected) and collections (remember to make a defensive copy). If you need to override `equals` and `hashCode`, then it is probably not worth it. -Be aware that `equals` compare references, not the value of a field. Consider overriding `toString`. +The default `equals()` and `hashCode()` implementation is shallow, so all nested fields need to be records or value-objects. Consider overriding `toString`. ### Builders From 90fd6a4ebb312a4d0a257f0b9ee6d9b08c019795 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 26 Jul 2024 12:00:39 +0200 Subject: [PATCH 20/93] Apply suggestions from code review Co-authored-by: Andrew Byrd --- doc/dev/decisionrecords/UseDecisionRecords.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/dev/decisionrecords/UseDecisionRecords.md b/doc/dev/decisionrecords/UseDecisionRecords.md index d30c255e556..800c8340904 100644 --- a/doc/dev/decisionrecords/UseDecisionRecords.md +++ b/doc/dev/decisionrecords/UseDecisionRecords.md @@ -1,8 +1,8 @@ # Decision Records [TODO - Not precise] An OTP Decision Record is a justified software design choice that addresses a -functional or non-functional requirement that is significant. [Architectural Decision Records](https://adr.github.io/) -is a similar concept, but we have widened the scope to include any relevant decision about the +significant functional or non-functional requirement. [Architectural Decision Records](https://adr.github.io/) +is a similar concept, but we have widened the scope to include any relevant decision about OTP development. ## Process From faa7dfa10188c29c2347416685d334ddb58c4ec4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 27 Jul 2024 22:11:24 +0000 Subject: [PATCH 21/93] fix(deps): update dependency net.logstash.logback:logstash-logback-encoder to v8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2f007cbb214..b4799a15c40 100644 --- a/pom.xml +++ b/pom.xml @@ -577,7 +577,7 @@ net.logstash.logback logstash-logback-encoder - 7.4 + 8.0 From 9f5aa460bfa0059e67b58d687bba07a1404cf127 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 2 Aug 2024 09:43:26 +0200 Subject: [PATCH 22/93] Remove unused field in TransitModel --- .../raptoradapter/transit/TransitLayer.java | 16 ---------------- .../transit/mappers/TransitLayerMapper.java | 1 - .../mapping/RaptorPathToItineraryMapperTest.java | 1 - .../raptoradapter/transit/TransitLayerTest.java | 5 ----- 4 files changed, 23 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java index c92bbd750ad..e5f0544f584 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayer.java @@ -1,7 +1,6 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit; import java.time.LocalDate; -import java.time.ZoneId; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -51,8 +50,6 @@ public class TransitLayer { private final StopModel stopModel; - private final ZoneId transitDataZoneId; - private final RaptorRequestTransferCache transferCache; private ConstrainedTransfersForPatterns constrainedTransfers; @@ -73,7 +70,6 @@ public TransitLayer(TransitLayer transitLayer) { transitLayer.transfersByStopIndex, transitLayer.transferService, transitLayer.stopModel, - transitLayer.transitDataZoneId, transitLayer.transferCache, transitLayer.constrainedTransfers, transitLayer.transferIndexGenerator, @@ -86,7 +82,6 @@ public TransitLayer( List> transfersByStopIndex, TransferService transferService, StopModel stopModel, - ZoneId transitDataZoneId, RaptorRequestTransferCache transferCache, ConstrainedTransfersForPatterns constrainedTransfers, TransferIndexGenerator transferIndexGenerator, @@ -96,7 +91,6 @@ public TransitLayer( this.transfersByStopIndex = transfersByStopIndex; this.transferService = transferService; this.stopModel = stopModel; - this.transitDataZoneId = transitDataZoneId; this.transferCache = transferCache; this.constrainedTransfers = constrainedTransfers; this.transferIndexGenerator = transferIndexGenerator; @@ -117,16 +111,6 @@ public Collection getTripPatternsForRunningDate(LocalDate da return tripPatternsRunningOnDate.getOrDefault(date, List.of()); } - /** - * This is the time zone which is used for interpreting all local "service" times (in transfers, - * trip schedules and so on). This is the time zone of the internal OTP time - which is used in - * logging and debugging. This is independent of the time zone of imported data and of the time - * zone used on any API - it can be the same, but it does not need to. - */ - public ZoneId getTransitDataZoneId() { - return transitDataZoneId; - } - public int getStopCount() { return stopModel.stopIndexSize(); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java index 8ce328fe1b6..d375b4c546c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java @@ -103,7 +103,6 @@ private TransitLayer map(TransitTuningParameters tuningParameters) { transferByStopIndex, transitService.getTransferService(), stopModel, - transitService.getTimeZone(), transferCache, constrainedTransfers, transferIndexGenerator, diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java b/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java index 5da127de2ba..8f5d1a0208e 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java @@ -237,7 +237,6 @@ private static TransitLayer getTransitLayer() { null, null, null, - null, null ); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java index 7c674252e6a..58a56ccb96f 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/TransitLayerTest.java @@ -65,7 +65,6 @@ void testGetTripPatternsRunningOnDateCopy() { null, null, null, - null, null ); var runningOnDate = transitLayer.getTripPatternsRunningOnDateCopy(date); @@ -95,7 +94,6 @@ void testGetTripPatternsForRunningDate() { null, null, null, - null, null ); var runningOnDate = transitLayer.getTripPatternsForRunningDate(date); @@ -124,7 +122,6 @@ void testGetTripPatternsOnServiceDateCopyWithSameRunningAndServiceDate() { null, null, null, - null, null ); var startingOnDate = transitLayer.getTripPatternsOnServiceDateCopy(date); @@ -153,7 +150,6 @@ void testGetTripPatternsOnServiceDateCopyWithServiceRunningAfterMidnight() { null, null, null, - null, null ); var startingOnDate = transitLayer.getTripPatternsOnServiceDateCopy(serviceDate); @@ -187,7 +183,6 @@ void testGetTripPatternsOnServiceDateCopyWithServiceRunningBeforeAndAfterMidnigh null, null, null, - null, null ); var startingOnDate = transitLayer.getTripPatternsOnServiceDateCopy(firstRunningDate); From 46133837081419414c729ee2902f037479923e5d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jul 2024 14:29:24 +0200 Subject: [PATCH 23/93] First implementation of SIRI-FM updater --- .../bikeep/BikeepUpdaterParameters.java | 7 ++ .../bikely/BikelyUpdaterParameters.java | 7 ++ .../hslpark/HslParkUpdaterParameters.java | 7 ++ .../noi/NoiUpdaterParameters.java | 7 ++ .../parkapi/ParkAPIUpdaterParameters.java | 9 +- .../vehicleparking/sirifm/SiriFmUpdater.java | 37 ++++++ .../sirifm/SiriFmUpdaterParameters.java | 34 ++++++ .../vehicle_parking/VehicleParking.java | 33 +++-- .../updaters/VehicleParkingUpdaterConfig.java | 12 ++ .../configure/UpdaterConfigurator.java | 37 ++++-- .../AvailabilityDatasourceFactory.java | 23 ++++ .../vehicle_parking/AvailabiltyUpdate.java | 12 ++ .../VehicleParkingAvailabilityUpdater.java | 114 ++++++++++++++++++ .../VehicleParkingDataSourceFactory.java | 1 + .../VehicleParkingSourceType.java | 1 + .../VehicleParkingUpdaterParameters.java | 6 + .../VehicleParkingUpdaterTest.java | 5 + 17 files changed, 334 insertions(+), 18 deletions(-) create mode 100644 src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java create mode 100644 src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java create mode 100644 src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java create mode 100644 src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java create mode 100644 src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterParameters.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterParameters.java index be937ecdd5e..86e03731dd8 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterParameters.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/bikeep/BikeepUpdaterParameters.java @@ -1,5 +1,7 @@ package org.opentripplanner.ext.vehicleparking.bikeep; +import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.FULL; + import java.net.URI; import java.time.Duration; import org.opentripplanner.updater.spi.HttpHeaders; @@ -22,4 +24,9 @@ public record BikeepUpdaterParameters( public VehicleParkingSourceType sourceType() { return VehicleParkingSourceType.BIKEEP; } + + @Override + public UpdateType updateType() { + return FULL; + } } diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterParameters.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterParameters.java index 26e40f4ec4a..73f26a43aa4 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterParameters.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/bikely/BikelyUpdaterParameters.java @@ -1,5 +1,7 @@ package org.opentripplanner.ext.vehicleparking.bikely; +import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.FULL; + import java.net.URI; import java.time.Duration; import org.opentripplanner.updater.spi.HttpHeaders; @@ -22,4 +24,9 @@ public record BikelyUpdaterParameters( public VehicleParkingSourceType sourceType() { return VehicleParkingSourceType.BIKELY; } + + @Override + public UpdateType updateType() { + return FULL; + } } diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterParameters.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterParameters.java index 4b75d38ea6f..b4ad24ae080 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterParameters.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/hslpark/HslParkUpdaterParameters.java @@ -1,5 +1,7 @@ package org.opentripplanner.ext.vehicleparking.hslpark; +import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.FULL; + import java.time.Duration; import java.time.ZoneId; import org.opentripplanner.updater.vehicle_parking.VehicleParkingSourceType; @@ -25,4 +27,9 @@ public record HslParkUpdaterParameters( public Duration frequency() { return Duration.ofSeconds(utilizationsFrequencySec); } + + @Override + public UpdateType updateType() { + return FULL; + } } diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterParameters.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterParameters.java index 371ffdc9f33..b34769c9dd2 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterParameters.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/noi/NoiUpdaterParameters.java @@ -1,5 +1,7 @@ package org.opentripplanner.ext.vehicleparking.noi; +import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.FULL; + import java.net.URI; import java.time.Duration; import org.opentripplanner.updater.spi.HttpHeaders; @@ -22,4 +24,9 @@ public record NoiUpdaterParameters( public VehicleParkingSourceType sourceType() { return VehicleParkingSourceType.NOI_OPEN_DATA_HUB; } + + @Override + public UpdateType updateType() { + return FULL; + } } diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterParameters.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterParameters.java index 263987c60d0..3014d932e08 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterParameters.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/parkapi/ParkAPIUpdaterParameters.java @@ -1,5 +1,7 @@ package org.opentripplanner.ext.vehicleparking.parkapi; +import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.FULL; + import java.time.Duration; import java.time.ZoneId; import java.util.List; @@ -21,4 +23,9 @@ public record ParkAPIUpdaterParameters( VehicleParkingSourceType sourceType, ZoneId timeZone ) - implements VehicleParkingUpdaterParameters {} + implements VehicleParkingUpdaterParameters { + @Override + public UpdateType updateType() { + return FULL; + } +} diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java new file mode 100644 index 00000000000..a30249b2b92 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java @@ -0,0 +1,37 @@ +package org.opentripplanner.ext.vehicleparking.sirifm; + +import java.util.List; +import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.updater.spi.DataSource; +import org.opentripplanner.updater.vehicle_parking.AvailabiltyUpdate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SiriFmUpdater implements DataSource { + + private static final Logger LOG = LoggerFactory.getLogger(SiriFmUpdater.class); + private final SiriFmUpdaterParameters params; + + public SiriFmUpdater(SiriFmUpdaterParameters params) { + this.params = params; + } + + @Override + public String toString() { + return ToStringBuilder + .of(this.getClass()) + .addStr("url", this.params.url().toString()) + .toString(); + } + + @Override + public boolean update() { + LOG.error("RUNNING {}", this); + return true; + } + + @Override + public List getUpdates() { + return List.of(); + } +} diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java new file mode 100644 index 00000000000..ef4015029ff --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java @@ -0,0 +1,34 @@ +package org.opentripplanner.ext.vehicleparking.sirifm; + +import static org.opentripplanner.updater.vehicle_parking.VehicleParkingSourceType.SIRI_FM; +import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.AVAILABILITY; + +import java.net.URI; +import java.time.Duration; +import org.opentripplanner.ext.vehicleparking.noi.NoiUpdater; +import org.opentripplanner.updater.spi.HttpHeaders; +import org.opentripplanner.updater.vehicle_parking.VehicleParkingSourceType; +import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters; + +/** + * Class that extends {@link VehicleParkingUpdaterParameters} with parameters required by {@link + * NoiUpdater}. + */ +public record SiriFmUpdaterParameters( + String configRef, + URI url, + String feedId, + Duration frequency, + HttpHeaders httpHeaders +) + implements VehicleParkingUpdaterParameters { + @Override + public VehicleParkingSourceType sourceType() { + return SIRI_FM; + } + + @Override + public UpdateType updateType() { + return AVAILABILITY; + } +} diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java index d5dfc4ce8c1..69f7f08eaa5 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java +++ b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java @@ -239,23 +239,40 @@ public boolean hasRealTimeDataForMode( return false; } - switch (traverseMode) { - case BICYCLE: - return availability.getBicycleSpaces() != null; - case CAR: + return switch (traverseMode) { + case BICYCLE -> availability.getBicycleSpaces() != null; + case CAR -> { var places = wheelchairAccessibleCarPlaces ? availability.getWheelchairAccessibleCarSpaces() : availability.getCarSpaces(); - return places != null; - default: - return false; - } + yield places != null; + } + default -> false; + }; } + /** + * The only mutable method in this class: it allows to update the available parking spaces during + * real-time updates. + */ public void updateAvailability(VehicleParkingSpaces vehicleParkingSpaces) { this.availability = vehicleParkingSpaces; } + public void close() { + var builder = VehicleParkingSpaces.builder(); + if (hasCarPlaces()) { + builder.carSpaces(0); + } + if (hasWheelchairAccessibleCarPlaces()) { + builder.wheelchairAccessibleCarSpaces(0); + } + if (hasBicyclePlaces()) { + builder.bicycleSpaces(0); + } + updateAvailability(builder.build()); + } + @Override public int hashCode() { return Objects.hash( diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java index c687899009f..6ef8c465bc3 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java @@ -13,6 +13,7 @@ import org.opentripplanner.ext.vehicleparking.hslpark.HslParkUpdaterParameters; import org.opentripplanner.ext.vehicleparking.noi.NoiUpdaterParameters; import org.opentripplanner.ext.vehicleparking.parkapi.ParkAPIUpdaterParameters; +import org.opentripplanner.ext.vehicleparking.sirifm.SiriFmUpdaterParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.updater.vehicle_parking.VehicleParkingSourceType; import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters; @@ -100,6 +101,17 @@ public static VehicleParkingUpdaterParameters create(String updaterRef, NodeAdap .asDuration(Duration.ofMinutes(1)), HttpHeadersConfig.headers(c, V2_6) ); + case SIRI_FM -> new SiriFmUpdaterParameters( + updaterRef, + c.of("url").since(V2_6).summary("URL of the SIRI-FM Light endpoint.").asUri(), + feedId, + c + .of("frequency") + .since(V2_6) + .summary("How often to update the source.") + .asDuration(Duration.ofMinutes(1)), + HttpHeadersConfig.headers(c, V2_6) + ); }; } diff --git a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java index 103120b7ecb..4726ab8b4ff 100644 --- a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java +++ b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java @@ -25,6 +25,8 @@ import org.opentripplanner.updater.trip.MqttGtfsRealtimeUpdater; import org.opentripplanner.updater.trip.PollingTripUpdater; import org.opentripplanner.updater.trip.TimetableSnapshotSource; +import org.opentripplanner.updater.vehicle_parking.AvailabilityDatasourceFactory; +import org.opentripplanner.updater.vehicle_parking.VehicleParkingAvailabilityUpdater; import org.opentripplanner.updater.vehicle_parking.VehicleParkingDataSourceFactory; import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdater; import org.opentripplanner.updater.vehicle_position.PollingVehiclePositionUpdater; @@ -187,15 +189,32 @@ private List createUpdatersFromConfig() { ); } for (var configItem : updatersParameters.getVehicleParkingUpdaterParameters()) { - var source = VehicleParkingDataSourceFactory.create(configItem, openingHoursCalendarService); - updaters.add( - new VehicleParkingUpdater( - configItem, - source, - graph.getLinker(), - graph.getVehicleParkingService() - ) - ); + switch (configItem.updateType()) { + case AVAILABILITY -> { + var source = VehicleParkingDataSourceFactory.create( + configItem, + openingHoursCalendarService + ); + updaters.add( + new VehicleParkingUpdater( + configItem, + source, + graph.getLinker(), + graph.getVehicleParkingService() + ) + ); + } + case FULL -> { + var source = AvailabilityDatasourceFactory.create(configItem); + updaters.add( + new VehicleParkingAvailabilityUpdater( + configItem, + source, + graph.getVehicleParkingService() + ) + ); + } + } } for (var configItem : updatersParameters.getSiriAzureETUpdaterParameters()) { updaters.add( diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java new file mode 100644 index 00000000000..cb62332747b --- /dev/null +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java @@ -0,0 +1,23 @@ +package org.opentripplanner.updater.vehicle_parking; + +import org.opentripplanner.ext.vehicleparking.sirifm.SiriFmUpdater; +import org.opentripplanner.ext.vehicleparking.sirifm.SiriFmUpdaterParameters; +import org.opentripplanner.updater.spi.DataSource; + +/** + * Class that can be used to return a custom vehicle parking {@link DataSource}. + */ +public class AvailabilityDatasourceFactory { + + public static DataSource create(VehicleParkingUpdaterParameters parameters) { + return switch (parameters.sourceType()) { + case SIRI_FM -> new SiriFmUpdater((SiriFmUpdaterParameters) parameters); + case PARK_API, + BICYCLE_PARK_API, + HSL_PARK, + BIKEEP, + NOI_OPEN_DATA_HUB, + BIKELY -> throw new IllegalArgumentException("Cannot instantiate SIRI-FM data source"); + }; + } +} diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java new file mode 100644 index 00000000000..404fcb9f47b --- /dev/null +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java @@ -0,0 +1,12 @@ +package org.opentripplanner.updater.vehicle_parking; + +import org.opentripplanner.transit.model.framework.FeedScopedId; + +public sealed interface AvailabiltyUpdate { + FeedScopedId vehicleParkingId(); + + record AvailabilityUpdated(FeedScopedId vehicleParkingId, int spacesAvailable) + implements AvailabiltyUpdate {} + + record ParkingClosed(FeedScopedId vehicleParkingId) implements AvailabiltyUpdate {} +} diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java new file mode 100644 index 00000000000..cf890213d76 --- /dev/null +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java @@ -0,0 +1,114 @@ +package org.opentripplanner.updater.vehicle_parking; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; +import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.updater.GraphWriterRunnable; +import org.opentripplanner.updater.spi.DataSource; +import org.opentripplanner.updater.spi.PollingGraphUpdater; +import org.opentripplanner.updater.spi.WriteToGraphCallback; +import org.opentripplanner.updater.vehicle_parking.AvailabiltyUpdate.AvailabilityUpdated; +import org.opentripplanner.updater.vehicle_parking.AvailabiltyUpdate.ParkingClosed; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Graph updater that dynamically sets availability information on vehicle parking lots. This + * updater fetches data from a single {@link DataSource}. + */ +public class VehicleParkingAvailabilityUpdater extends PollingGraphUpdater { + + private static final Logger LOG = LoggerFactory.getLogger( + VehicleParkingAvailabilityUpdater.class + ); + private final DataSource source; + private WriteToGraphCallback saveResultOnGraph; + + private final VehicleParkingService vehicleParkingService; + + public VehicleParkingAvailabilityUpdater( + VehicleParkingUpdaterParameters parameters, + DataSource source, + VehicleParkingService vehicleParkingService + ) { + super(parameters); + this.source = source; + this.vehicleParkingService = vehicleParkingService; + + LOG.info("Creating vehicle-parking updater running every {}: {}", pollingPeriod(), source); + } + + @Override + public void setup(WriteToGraphCallback writeToGraphCallback) { + this.saveResultOnGraph = writeToGraphCallback; + } + + @Override + protected void runPolling() { + LOG.debug("Updating parking availability from {}", source); + if (!source.update()) { + LOG.debug("No updates"); + } else { + var updates = source.getUpdates(); + + var graphWriterRunnable = new VehicleParkingGraphWriterRunnable(updates); + saveResultOnGraph.execute(graphWriterRunnable); + } + } + + private class VehicleParkingGraphWriterRunnable implements GraphWriterRunnable { + + private final List updates; + private final Map parkingById; + + private VehicleParkingGraphWriterRunnable(List updates) { + this.updates = List.copyOf(updates); + this.parkingById = + vehicleParkingService + .getVehicleParkings() + .collect(Collectors.toUnmodifiableMap(VehicleParking::getId, Function.identity())); + } + + @Override + public void run(Graph graph, TransitModel ignored) { + updates.forEach(this::handleUpdate); + } + + private void handleUpdate(AvailabiltyUpdate update) { + if (!parkingById.containsKey(update.vehicleParkingId())) { + LOG.error( + "Parking with id {} does not exist. Skipping availability update.", + update.vehicleParkingId() + ); + } + var parking = parkingById.get(update.vehicleParkingId()); + + switch (update) { + case ParkingClosed closed -> parking.close(); + case AvailabilityUpdated availabilityUpdated -> { + var builder = VehicleParkingSpaces.builder(); + if (parking.hasCarPlaces()) { + builder.carSpaces(availabilityUpdated.spacesAvailable()); + } + if (parking.hasBicyclePlaces()) { + builder.bicycleSpaces(availabilityUpdated.spacesAvailable()); + } + parking.updateAvailability(builder.build()); + } + } + } + } + + @Override + public String toString() { + return ToStringBuilder.of(this.getClass()).addObj("source", source).toString(); + } +} diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java index a956fda0d87..09ecb67a54d 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingDataSourceFactory.java @@ -42,6 +42,7 @@ public static DataSource create( case BIKELY -> new BikelyUpdater((BikelyUpdaterParameters) parameters); case NOI_OPEN_DATA_HUB -> new NoiUpdater((NoiUpdaterParameters) parameters); case BIKEEP -> new BikeepUpdater((BikeepUpdaterParameters) parameters); + case SIRI_FM -> throw new IllegalArgumentException("Cannot instantiate SIRI-FM data source"); }; } } diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java index f6a28177d8e..1601245b16c 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingSourceType.java @@ -7,4 +7,5 @@ public enum VehicleParkingSourceType { BIKELY, NOI_OPEN_DATA_HUB, BIKEEP, + SIRI_FM, } diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java index 3422ec3e300..500a0ff6bcc 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java @@ -8,4 +8,10 @@ */ public interface VehicleParkingUpdaterParameters extends PollingGraphUpdaterParameters { VehicleParkingSourceType sourceType(); + UpdateType updateType(); + + enum UpdateType { + FULL, + AVAILABILITY, + } } diff --git a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java index a31b5cfb387..f49299eb4ea 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java +++ b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterTest.java @@ -54,6 +54,11 @@ public VehicleParkingSourceType sourceType() { return null; } + @Override + public UpdateType updateType() { + return UpdateType.FULL; + } + @Override public Duration frequency() { return Duration.ZERO; From 67c97e939dc84c4efe7264819361422fa51051ac Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jul 2024 14:48:01 +0200 Subject: [PATCH 24/93] Flesh out Siri importer --- .../vehicleparking/sirifm/SiriFmUpdater.java | 38 +++++++++++++++++-- .../configure/UpdaterConfigurator.java | 4 +- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java index a30249b2b92..366179d73d0 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java @@ -1,9 +1,14 @@ package org.opentripplanner.ext.vehicleparking.sirifm; import java.util.List; +import java.util.Map; +import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.updater.spi.DataSource; +import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_parking.AvailabiltyUpdate; +import org.rutebanken.siri20.util.SiriXml; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,9 +16,14 @@ public class SiriFmUpdater implements DataSource { private static final Logger LOG = LoggerFactory.getLogger(SiriFmUpdater.class); private final SiriFmUpdaterParameters params; + private final OtpHttpClient httpClient; + private final Map headers; + private List updates = List.of(); - public SiriFmUpdater(SiriFmUpdaterParameters params) { - this.params = params; + public SiriFmUpdater(SiriFmUpdaterParameters parameters) { + params = parameters; + headers = HttpHeaders.of().acceptApplicationXML().add(parameters.httpHeaders()).build().asMap(); + httpClient = new OtpHttpClientFactory().create(LOG); } @Override @@ -27,11 +37,33 @@ public String toString() { @Override public boolean update() { LOG.error("RUNNING {}", this); + + updates = + httpClient.getAndMap( + params.url(), + headers, + resp -> { + var siri = SiriXml.parseXml(resp); + + var conditions = siri + .getServiceDelivery() + .getFacilityMonitoringDeliveries() + .stream() + .flatMap(d -> d.getFacilityConditions().stream()) + .toList(); + + conditions.forEach(c -> { + LOG.error("{}", c.getFacilityRef().getValue()); + }); + + return List.of(); + } + ); return true; } @Override public List getUpdates() { - return List.of(); + return updates; } } diff --git a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java index 4726ab8b4ff..f95c485f8d2 100644 --- a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java +++ b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java @@ -190,7 +190,7 @@ private List createUpdatersFromConfig() { } for (var configItem : updatersParameters.getVehicleParkingUpdaterParameters()) { switch (configItem.updateType()) { - case AVAILABILITY -> { + case FULL -> { var source = VehicleParkingDataSourceFactory.create( configItem, openingHoursCalendarService @@ -204,7 +204,7 @@ private List createUpdatersFromConfig() { ) ); } - case FULL -> { + case AVAILABILITY -> { var source = AvailabilityDatasourceFactory.create(configItem); updaters.add( new VehicleParkingAvailabilityUpdater( From 84cd9be82570c618ef274103c8fc7327ef33a098 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jul 2024 17:33:28 +0200 Subject: [PATCH 25/93] Implement Siri code --- .../vehicleparking/sirifm/SiriFmUpdater.java | 69 +++++++++++++++---- .../sirifm/SiriFmUpdaterParameters.java | 4 +- .../configure/UpdaterConfigurator.java | 2 +- .../VehicleParkingAvailabilityUpdater.java | 27 ++++---- .../VehicleParkingUpdaterParameters.java | 2 +- 5 files changed, 75 insertions(+), 29 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java index 366179d73d0..ada96edff58 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java @@ -1,16 +1,26 @@ package org.opentripplanner.ext.vehicleparking.sirifm; +import static uk.org.siri.siri21.CountingTypeEnumeration.PRESENT_COUNT; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import java.io.InputStream; import java.util.List; import java.util.Map; +import java.util.stream.Stream; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.updater.spi.DataSource; import org.opentripplanner.updater.spi.HttpHeaders; import org.opentripplanner.updater.vehicle_parking.AvailabiltyUpdate; -import org.rutebanken.siri20.util.SiriXml; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import uk.org.siri.siri21.FacilityConditionStructure; +import uk.org.siri.siri21.Siri; public class SiriFmUpdater implements DataSource { @@ -20,6 +30,16 @@ public class SiriFmUpdater implements DataSource { private final Map headers; private List updates = List.of(); + private static final JAXBContext jaxbContext; + + static { + try { + jaxbContext = JAXBContext.newInstance(Siri.class); + } catch (JAXBException e) { + throw new RuntimeException(e); + } + } + public SiriFmUpdater(SiriFmUpdaterParameters parameters) { params = parameters; headers = HttpHeaders.of().acceptApplicationXML().add(parameters.httpHeaders()).build().asMap(); @@ -43,25 +63,50 @@ public boolean update() { params.url(), headers, resp -> { - var siri = SiriXml.parseXml(resp); + var siri = parseXml(resp); - var conditions = siri - .getServiceDelivery() - .getFacilityMonitoringDeliveries() - .stream() + return Stream + .ofNullable(siri.getServiceDelivery()) + .flatMap(sd -> sd.getFacilityMonitoringDeliveries().stream()) .flatMap(d -> d.getFacilityConditions().stream()) + .filter(this::conformsToItalianProfile) + .map(this::mapToUpdate) .toList(); - - conditions.forEach(c -> { - LOG.error("{}", c.getFacilityRef().getValue()); - }); - - return List.of(); } ); return true; } + private AvailabiltyUpdate mapToUpdate(FacilityConditionStructure c) { + var id = new FeedScopedId(params.feedId(), c.getFacilityRef().getValue()); + var available = c.getMonitoredCountings().getFirst().getCount().intValue(); + return new AvailabiltyUpdate.AvailabilityUpdated(id, available); + } + + /** + * Checks if the {@link FacilityConditionStructure} contains all the necessary information that + * are required by the Italian Siri-FM profile. + */ + private boolean conformsToItalianProfile(FacilityConditionStructure c) { + return ( + c.getFacilityRef() != null && + c.getFacilityRef().getValue() != null && + c.getMonitoredCountings().size() == 1 && + c.getMonitoredCountings().stream().anyMatch(mc -> mc.getCountingType() == PRESENT_COUNT) + ); + } + + private Siri parseXml(InputStream stream) { + try { + var xmlif = XMLInputFactory.newInstance(); + var jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + var streamReader = xmlif.createXMLStreamReader(stream); + return (Siri) jaxbUnmarshaller.unmarshal(streamReader); + } catch (JAXBException | XMLStreamException e) { + throw new RuntimeException(e); + } + } + @Override public List getUpdates() { return updates; diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java index ef4015029ff..5afdffb7067 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterParameters.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.vehicleparking.sirifm; import static org.opentripplanner.updater.vehicle_parking.VehicleParkingSourceType.SIRI_FM; -import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.AVAILABILITY; +import static org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters.UpdateType.AVAILABILITY_ONLY; import java.net.URI; import java.time.Duration; @@ -29,6 +29,6 @@ public VehicleParkingSourceType sourceType() { @Override public UpdateType updateType() { - return AVAILABILITY; + return AVAILABILITY_ONLY; } } diff --git a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java index f95c485f8d2..6662bae362b 100644 --- a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java +++ b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java @@ -204,7 +204,7 @@ private List createUpdatersFromConfig() { ) ); } - case AVAILABILITY -> { + case AVAILABILITY_ONLY -> { var source = AvailabilityDatasourceFactory.create(configItem); updaters.add( new VehicleParkingAvailabilityUpdater( diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java index cf890213d76..8d38890b16c 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java @@ -88,20 +88,21 @@ private void handleUpdate(AvailabiltyUpdate update) { "Parking with id {} does not exist. Skipping availability update.", update.vehicleParkingId() ); - } - var parking = parkingById.get(update.vehicleParkingId()); - - switch (update) { - case ParkingClosed closed -> parking.close(); - case AvailabilityUpdated availabilityUpdated -> { - var builder = VehicleParkingSpaces.builder(); - if (parking.hasCarPlaces()) { - builder.carSpaces(availabilityUpdated.spacesAvailable()); - } - if (parking.hasBicyclePlaces()) { - builder.bicycleSpaces(availabilityUpdated.spacesAvailable()); + } else { + var parking = parkingById.get(update.vehicleParkingId()); + + switch (update) { + case ParkingClosed closed -> parking.close(); + case AvailabilityUpdated availabilityUpdated -> { + var builder = VehicleParkingSpaces.builder(); + if (parking.hasCarPlaces()) { + builder.carSpaces(availabilityUpdated.spacesAvailable()); + } + if (parking.hasBicyclePlaces()) { + builder.bicycleSpaces(availabilityUpdated.spacesAvailable()); + } + parking.updateAvailability(builder.build()); } - parking.updateAvailability(builder.build()); } } } diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java index 500a0ff6bcc..bff0022383f 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingUpdaterParameters.java @@ -12,6 +12,6 @@ public interface VehicleParkingUpdaterParameters extends PollingGraphUpdaterPara enum UpdateType { FULL, - AVAILABILITY, + AVAILABILITY_ONLY, } } From e80ec16d686b554872206848e6c0fdc0b6272003 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jul 2024 17:42:25 +0200 Subject: [PATCH 26/93] Make code more robust --- .../vehicleparking/sirifm/SiriFmUpdater.java | 2 +- .../vehicle_parking/AvailabiltyUpdate.java | 9 +----- .../VehicleParkingAvailabilityUpdater.java | 28 +++++++------------ 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java index ada96edff58..1413df407e1 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java @@ -80,7 +80,7 @@ public boolean update() { private AvailabiltyUpdate mapToUpdate(FacilityConditionStructure c) { var id = new FeedScopedId(params.feedId(), c.getFacilityRef().getValue()); var available = c.getMonitoredCountings().getFirst().getCount().intValue(); - return new AvailabiltyUpdate.AvailabilityUpdated(id, available); + return new AvailabiltyUpdate(id, available); } /** diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java index 404fcb9f47b..17d273ac237 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java @@ -2,11 +2,4 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; -public sealed interface AvailabiltyUpdate { - FeedScopedId vehicleParkingId(); - - record AvailabilityUpdated(FeedScopedId vehicleParkingId, int spacesAvailable) - implements AvailabiltyUpdate {} - - record ParkingClosed(FeedScopedId vehicleParkingId) implements AvailabiltyUpdate {} -} +public record AvailabiltyUpdate(FeedScopedId vehicleParkingId, int spacesAvailable) {} diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java index 8d38890b16c..77790b1a084 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java @@ -15,8 +15,6 @@ import org.opentripplanner.updater.spi.DataSource; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.WriteToGraphCallback; -import org.opentripplanner.updater.vehicle_parking.AvailabiltyUpdate.AvailabilityUpdated; -import org.opentripplanner.updater.vehicle_parking.AvailabiltyUpdate.ParkingClosed; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,17 +57,17 @@ protected void runPolling() { } else { var updates = source.getUpdates(); - var graphWriterRunnable = new VehicleParkingGraphWriterRunnable(updates); + var graphWriterRunnable = new UpdateAvailabilities(updates); saveResultOnGraph.execute(graphWriterRunnable); } } - private class VehicleParkingGraphWriterRunnable implements GraphWriterRunnable { + private class UpdateAvailabilities implements GraphWriterRunnable { private final List updates; private final Map parkingById; - private VehicleParkingGraphWriterRunnable(List updates) { + private UpdateAvailabilities(List updates) { this.updates = List.copyOf(updates); this.parkingById = vehicleParkingService @@ -90,20 +88,14 @@ private void handleUpdate(AvailabiltyUpdate update) { ); } else { var parking = parkingById.get(update.vehicleParkingId()); - - switch (update) { - case ParkingClosed closed -> parking.close(); - case AvailabilityUpdated availabilityUpdated -> { - var builder = VehicleParkingSpaces.builder(); - if (parking.hasCarPlaces()) { - builder.carSpaces(availabilityUpdated.spacesAvailable()); - } - if (parking.hasBicyclePlaces()) { - builder.bicycleSpaces(availabilityUpdated.spacesAvailable()); - } - parking.updateAvailability(builder.build()); - } + var builder = VehicleParkingSpaces.builder(); + if (parking.hasCarPlaces()) { + builder.carSpaces(update.spacesAvailable()); + } + if (parking.hasBicyclePlaces()) { + builder.bicycleSpaces(update.spacesAvailable()); } + parking.updateAvailability(builder.build()); } } } From ad8b74d8afc193ade38cc41fb3d1698e588e9300 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jul 2024 18:07:22 +0200 Subject: [PATCH 27/93] Add test for Siri-FM parking updater --- .../sirifm/SiriFmUpdaterTest.java | 28 ++++++++++ .../ext/vehicleparking/sirifm/siri-fm.xml | 56 +++++++++++++++++++ .../vehicleparking/sirifm/SiriFmUpdater.java | 4 +- 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java create mode 100644 src/ext-test/resources/org/opentripplanner/ext/vehicleparking/sirifm/siri-fm.xml diff --git a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java b/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java new file mode 100644 index 00000000000..5078eedb427 --- /dev/null +++ b/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java @@ -0,0 +1,28 @@ +package org.opentripplanner.ext.vehicleparking.sirifm; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.Duration; +import org.junit.jupiter.api.Test; +import org.opentripplanner.test.support.ResourceLoader; +import org.opentripplanner.updater.spi.HttpHeaders; + +class SiriFmUpdaterTest { + + @Test + void parse() { + var uri = ResourceLoader.of(this).uri("siri-fm.xml"); + var parameters = new SiriFmUpdaterParameters( + "noi", + uri, + "noi", + Duration.ofSeconds(30), + HttpHeaders.empty() + ); + var updater = new SiriFmUpdater(parameters); + updater.update(); + var updates = updater.getUpdates(); + + assertEquals(4, updates.size()); + } +} diff --git a/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/sirifm/siri-fm.xml b/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/sirifm/siri-fm.xml new file mode 100644 index 00000000000..f4595488284 --- /dev/null +++ b/src/ext-test/resources/org/opentripplanner/ext/vehicleparking/sirifm/siri-fm.xml @@ -0,0 +1,56 @@ + + + 2024-07-17T11:07:40Z + RAP Alto Adige - Open Data Hub + + 2024-07-17T11:07:40Z + RAP Alto Adige - Open Data Hub + + IT:ITH10:Parking:105 + + available + + + presentCount + bays + 33 + + + + IT:ITH10:Parking:TRENTO_areaexsitviacanestrinip1 + + notAvailable + + + presentCount + bays + 300 + + + + IT:ITH10:Parking:TRENTO_autosilobuonconsigliop3 + + notAvailable + + + presentCount + bays + 633 + + + + IT:ITH10:Parking:TRENTO_cteviabomportop6 + + notAvailable + + + presentCount + bays + 250 + + + + + \ No newline at end of file diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java index 1413df407e1..d4ccefa1845 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java @@ -56,8 +56,6 @@ public String toString() { @Override public boolean update() { - LOG.error("RUNNING {}", this); - updates = httpClient.getAndMap( params.url(), @@ -92,7 +90,7 @@ private boolean conformsToItalianProfile(FacilityConditionStructure c) { c.getFacilityRef() != null && c.getFacilityRef().getValue() != null && c.getMonitoredCountings().size() == 1 && - c.getMonitoredCountings().stream().anyMatch(mc -> mc.getCountingType() == PRESENT_COUNT) + c.getMonitoredCountings().getFirst().getCountingType() == PRESENT_COUNT ); } From c228692c9518ec2d4ea4f2b1bb761393c813fd90 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jul 2024 22:04:24 +0200 Subject: [PATCH 28/93] Simplify Siri updater --- .../vehicleparking/sirifm/SiriFmUpdater.java | 33 ++++--------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java index d4ccefa1845..96e8e455185 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java @@ -2,14 +2,10 @@ import static uk.org.siri.siri21.CountingTypeEnumeration.PRESENT_COUNT; -import jakarta.xml.bind.JAXBContext; -import jakarta.xml.bind.JAXBException; -import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.stream.Stream; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; +import org.entur.siri21.util.SiriXml; import org.opentripplanner.framework.io.OtpHttpClient; import org.opentripplanner.framework.io.OtpHttpClientFactory; import org.opentripplanner.framework.tostring.ToStringBuilder; @@ -20,8 +16,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.org.siri.siri21.FacilityConditionStructure; -import uk.org.siri.siri21.Siri; +/** + * Parses SIRI 2.1 XML data into parking availability updates. The data needs to conform to the + * Italian profile of SIRI-FM. + */ public class SiriFmUpdater implements DataSource { private static final Logger LOG = LoggerFactory.getLogger(SiriFmUpdater.class); @@ -30,16 +29,6 @@ public class SiriFmUpdater implements DataSource { private final Map headers; private List updates = List.of(); - private static final JAXBContext jaxbContext; - - static { - try { - jaxbContext = JAXBContext.newInstance(Siri.class); - } catch (JAXBException e) { - throw new RuntimeException(e); - } - } - public SiriFmUpdater(SiriFmUpdaterParameters parameters) { params = parameters; headers = HttpHeaders.of().acceptApplicationXML().add(parameters.httpHeaders()).build().asMap(); @@ -61,7 +50,7 @@ public boolean update() { params.url(), headers, resp -> { - var siri = parseXml(resp); + var siri = SiriXml.parseXml(resp); return Stream .ofNullable(siri.getServiceDelivery()) @@ -94,16 +83,6 @@ private boolean conformsToItalianProfile(FacilityConditionStructure c) { ); } - private Siri parseXml(InputStream stream) { - try { - var xmlif = XMLInputFactory.newInstance(); - var jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - var streamReader = xmlif.createXMLStreamReader(stream); - return (Siri) jaxbUnmarshaller.unmarshal(streamReader); - } catch (JAXBException | XMLStreamException e) { - throw new RuntimeException(e); - } - } @Override public List getUpdates() { From 64f6fc62f0fc45f462ee0af122b8713e33ce3b39 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 19 Jul 2024 13:15:48 +0200 Subject: [PATCH 29/93] Add test for SIRI parking updater --- docs/sandbox/VehicleParking.md | 10 +- .../sirifm/SiriFmUpdaterTest.java | 2 +- ...riFmUpdater.java => SiriFmDatasource.java} | 7 +- .../vehicle_parking/VehicleParking.java | 14 --- .../AvailabilityDatasourceFactory.java | 4 +- .../vehicle_parking/AvailabiltyUpdate.java | 9 +- ...VehicleParkingAvailabilityUpdaterTest.java | 108 ++++++++++++++++++ 7 files changed, 127 insertions(+), 27 deletions(-) rename src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/{SiriFmUpdater.java => SiriFmDatasource.java} (94%) create mode 100644 src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java diff --git a/docs/sandbox/VehicleParking.md b/docs/sandbox/VehicleParking.md index a5adde1d4c2..ae83dba2b41 100644 --- a/docs/sandbox/VehicleParking.md +++ b/docs/sandbox/VehicleParking.md @@ -61,7 +61,7 @@ This will end up in the API responses as the feed id of of the parking lot. **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` **Path:** /updaters/[2] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` The source of the vehicle updates. @@ -131,7 +131,7 @@ This will end up in the API responses as the feed id of of the parking lot. **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` **Path:** /updaters/[3] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` The source of the vehicle updates. @@ -216,7 +216,7 @@ This will end up in the API responses as the feed id of of the parking lot. **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` **Path:** /updaters/[4] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` The source of the vehicle updates. @@ -281,7 +281,7 @@ This will end up in the API responses as the feed id of of the parking lot. **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` **Path:** /updaters/[5] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` The source of the vehicle updates. @@ -342,7 +342,7 @@ This will end up in the API responses as the feed id of of the parking lot. **Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` **Path:** /updaters/[14] -**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` The source of the vehicle updates. diff --git a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java b/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java index 5078eedb427..07502b597d9 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdaterTest.java @@ -19,7 +19,7 @@ void parse() { Duration.ofSeconds(30), HttpHeaders.empty() ); - var updater = new SiriFmUpdater(parameters); + var updater = new SiriFmDatasource(parameters); updater.update(); var updates = updater.getUpdates(); diff --git a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java rename to src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java index 96e8e455185..abfdf4d29be 100644 --- a/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/vehicleparking/sirifm/SiriFmDatasource.java @@ -21,15 +21,15 @@ * Parses SIRI 2.1 XML data into parking availability updates. The data needs to conform to the * Italian profile of SIRI-FM. */ -public class SiriFmUpdater implements DataSource { +public class SiriFmDatasource implements DataSource { - private static final Logger LOG = LoggerFactory.getLogger(SiriFmUpdater.class); + private static final Logger LOG = LoggerFactory.getLogger(SiriFmDatasource.class); private final SiriFmUpdaterParameters params; private final OtpHttpClient httpClient; private final Map headers; private List updates = List.of(); - public SiriFmUpdater(SiriFmUpdaterParameters parameters) { + public SiriFmDatasource(SiriFmUpdaterParameters parameters) { params = parameters; headers = HttpHeaders.of().acceptApplicationXML().add(parameters.httpHeaders()).build().asMap(); httpClient = new OtpHttpClientFactory().create(LOG); @@ -83,7 +83,6 @@ private boolean conformsToItalianProfile(FacilityConditionStructure c) { ); } - @Override public List getUpdates() { return updates; diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java index 69f7f08eaa5..b50c583c79a 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java +++ b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java @@ -259,20 +259,6 @@ public void updateAvailability(VehicleParkingSpaces vehicleParkingSpaces) { this.availability = vehicleParkingSpaces; } - public void close() { - var builder = VehicleParkingSpaces.builder(); - if (hasCarPlaces()) { - builder.carSpaces(0); - } - if (hasWheelchairAccessibleCarPlaces()) { - builder.wheelchairAccessibleCarSpaces(0); - } - if (hasBicyclePlaces()) { - builder.bicycleSpaces(0); - } - updateAvailability(builder.build()); - } - @Override public int hashCode() { return Objects.hash( diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java index cb62332747b..876cd303c78 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabilityDatasourceFactory.java @@ -1,6 +1,6 @@ package org.opentripplanner.updater.vehicle_parking; -import org.opentripplanner.ext.vehicleparking.sirifm.SiriFmUpdater; +import org.opentripplanner.ext.vehicleparking.sirifm.SiriFmDatasource; import org.opentripplanner.ext.vehicleparking.sirifm.SiriFmUpdaterParameters; import org.opentripplanner.updater.spi.DataSource; @@ -11,7 +11,7 @@ public class AvailabilityDatasourceFactory { public static DataSource create(VehicleParkingUpdaterParameters parameters) { return switch (parameters.sourceType()) { - case SIRI_FM -> new SiriFmUpdater((SiriFmUpdaterParameters) parameters); + case SIRI_FM -> new SiriFmDatasource((SiriFmUpdaterParameters) parameters); case PARK_API, BICYCLE_PARK_API, HSL_PARK, diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java index 17d273ac237..a9d352cbaf2 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/AvailabiltyUpdate.java @@ -1,5 +1,12 @@ package org.opentripplanner.updater.vehicle_parking; +import java.util.Objects; +import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.transit.model.framework.FeedScopedId; -public record AvailabiltyUpdate(FeedScopedId vehicleParkingId, int spacesAvailable) {} +public record AvailabiltyUpdate(FeedScopedId vehicleParkingId, int spacesAvailable) { + public AvailabiltyUpdate { + Objects.requireNonNull(vehicleParkingId); + IntUtils.requireNotNegative(spacesAvailable); + } +} diff --git a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java new file mode 100644 index 00000000000..60cfc3faa1c --- /dev/null +++ b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java @@ -0,0 +1,108 @@ +package org.opentripplanner.updater.vehicle_parking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; + +import com.google.common.util.concurrent.Futures; +import java.time.Duration; +import java.util.List; +import java.util.concurrent.Future; +import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.geometry.WgsCoordinate; +import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; +import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.updater.GraphUpdaterManager; +import org.opentripplanner.updater.GraphWriterRunnable; +import org.opentripplanner.updater.spi.DataSource; +import org.opentripplanner.updater.spi.GraphUpdater; + +class VehicleParkingAvailabilityUpdaterTest { + + private static final VehicleParkingUpdaterParameters PARAMETERS = new VehicleParkingUpdaterParameters() { + @Override + public VehicleParkingSourceType sourceType() { + return VehicleParkingSourceType.SIRI_FM; + } + + @Override + public UpdateType updateType() { + return UpdateType.AVAILABILITY_ONLY; + } + + @Override + public Duration frequency() { + return Duration.ZERO; + } + + @Override + public String configRef() { + return null; + } + }; + private static final FeedScopedId ID = id("parking1"); + + @Test + void updateAvailability() { + var service = new VehicleParkingService(); + + var parking = VehicleParking + .builder() + .id(ID) + .name(I18NString.of("parking")) + .coordinate(WgsCoordinate.GREENWICH) + .carPlaces(true) + .capacity(VehicleParkingSpaces.builder().carSpaces(10).build()) + .build(); + service.updateVehicleParking(List.of(parking), List.of()); + + var updater = new VehicleParkingAvailabilityUpdater(PARAMETERS, new StubDatasource(), service); + + runUpdaterOnce(updater); + + var updated = service.getVehicleParkings().toList().getFirst(); + assertEquals(ID, updated.getId()); + assertEquals(8, updated.getAvailability().getCarSpaces()); + assertNull(updated.getAvailability().getBicycleSpaces()); + } + + private void runUpdaterOnce(VehicleParkingAvailabilityUpdater updater) { + class GraphUpdaterMock extends GraphUpdaterManager { + + private static final Graph GRAPH = new Graph(); + private static final TransitModel TRANSIT_MODEL = new TransitModel(); + + public GraphUpdaterMock(List updaters) { + super(GRAPH, TRANSIT_MODEL, updaters); + } + + @Override + public Future execute(GraphWriterRunnable runnable) { + runnable.run(GRAPH, TRANSIT_MODEL); + return Futures.immediateVoidFuture(); + } + } + + var graphUpdaterManager = new GraphUpdaterMock(List.of(updater)); + graphUpdaterManager.startUpdaters(); + graphUpdaterManager.stop(false); + } + + private static class StubDatasource implements DataSource { + + @Override + public boolean update() { + return true; + } + + @Override + public List getUpdates() { + return List.of(new AvailabiltyUpdate(ID, 8)); + } + } +} From cbddcc4ca8a012e94dde7ed530acd07d8274f32b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 19 Jul 2024 15:01:01 +0200 Subject: [PATCH 30/93] Improve test --- .../VehicleParkingAvailabilityUpdater.java | 5 +- ...VehicleParkingAvailabilityUpdaterTest.java | 82 +++++++++++++++---- 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java index 77790b1a084..86e7b72c9ff 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java @@ -51,10 +51,7 @@ public void setup(WriteToGraphCallback writeToGraphCallback) { @Override protected void runPolling() { - LOG.debug("Updating parking availability from {}", source); - if (!source.update()) { - LOG.debug("No updates"); - } else { + if (source.update()) { var updates = source.getUpdates(); var graphWriterRunnable = new UpdateAvailabilities(updates); diff --git a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java index 60cfc3faa1c..713b6d01664 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java +++ b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java @@ -46,22 +46,16 @@ public String configRef() { } }; private static final FeedScopedId ID = id("parking1"); + private static final AvailabiltyUpdate DEFAULT_UPDATE = new AvailabiltyUpdate(ID, 8); @Test - void updateAvailability() { - var service = new VehicleParkingService(); - - var parking = VehicleParking - .builder() - .id(ID) - .name(I18NString.of("parking")) - .coordinate(WgsCoordinate.GREENWICH) - .carPlaces(true) - .capacity(VehicleParkingSpaces.builder().carSpaces(10).build()) - .build(); - service.updateVehicleParking(List.of(parking), List.of()); - - var updater = new VehicleParkingAvailabilityUpdater(PARAMETERS, new StubDatasource(), service); + void updateCarAvailability() { + var service = buildParkingService(VehicleParkingSpaces.builder().carSpaces(10).build()); + var updater = new VehicleParkingAvailabilityUpdater( + PARAMETERS, + new StubDatasource(DEFAULT_UPDATE), + service + ); runUpdaterOnce(updater); @@ -71,6 +65,58 @@ void updateAvailability() { assertNull(updated.getAvailability().getBicycleSpaces()); } + @Test + void updateBicycleAvailability() { + var service = buildParkingService(VehicleParkingSpaces.builder().bicycleSpaces(15).build()); + var updater = new VehicleParkingAvailabilityUpdater( + PARAMETERS, + new StubDatasource(DEFAULT_UPDATE), + service + ); + + runUpdaterOnce(updater); + + var updated = service.getVehicleParkings().toList().getFirst(); + assertEquals(ID, updated.getId()); + assertEquals(8, updated.getAvailability().getBicycleSpaces()); + assertNull(updated.getAvailability().getCarSpaces()); + } + @Test + void notFound() { + var service = buildParkingService(VehicleParkingSpaces.builder().bicycleSpaces(15).build()); + var updater = new VehicleParkingAvailabilityUpdater( + PARAMETERS, + new StubDatasource(new AvailabiltyUpdate(id("not-found"), 100)), + service + ); + + runUpdaterOnce(updater); + + var updated = service.getVehicleParkings().toList().getFirst(); + assertEquals(ID, updated.getId()); + assertNull(updated.getAvailability()); + } + + private static VehicleParkingService buildParkingService(VehicleParkingSpaces capacity) { + var service = new VehicleParkingService(); + + var parking = parkingBuilder() + .carPlaces(capacity.getCarSpaces() != null) + .bicyclePlaces(capacity.getBicycleSpaces() != null) + .capacity(capacity) + .build(); + service.updateVehicleParking(List.of(parking), List.of()); + return service; + } + + private static VehicleParking.VehicleParkingBuilder parkingBuilder() { + return VehicleParking + .builder() + .id(ID) + .name(I18NString.of("parking")) + .coordinate(WgsCoordinate.GREENWICH); + } + private void runUpdaterOnce(VehicleParkingAvailabilityUpdater updater) { class GraphUpdaterMock extends GraphUpdaterManager { @@ -95,6 +141,12 @@ public Future execute(GraphWriterRunnable runnable) { private static class StubDatasource implements DataSource { + private final AvailabiltyUpdate update; + + private StubDatasource(AvailabiltyUpdate update) { + this.update = update; + } + @Override public boolean update() { return true; @@ -102,7 +154,7 @@ public boolean update() { @Override public List getUpdates() { - return List.of(new AvailabiltyUpdate(ID, 8)); + return List.of(update); } } } From b70dc7473fcb9c3d44a1fca6d5d42b381b5f7bd2 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 19 Jul 2024 15:10:54 +0200 Subject: [PATCH 31/93] Add documentation --- doc-templates/VehicleParking.md | 9 ++ docs/RouterConfiguration.md | 6 ++ docs/sandbox/VehicleParking.md | 89 +++++++++++++++++-- .../updaters/VehicleParkingUpdaterConfig.java | 16 +++- ...VehicleParkingAvailabilityUpdaterTest.java | 1 + .../standalone/config/router-config.json | 7 ++ 6 files changed, 121 insertions(+), 7 deletions(-) diff --git a/doc-templates/VehicleParking.md b/doc-templates/VehicleParking.md index 5d149e40f9a..507894b97e8 100644 --- a/doc-templates/VehicleParking.md +++ b/doc-templates/VehicleParking.md @@ -48,6 +48,15 @@ All updaters have the following parameters in common: +## SIRI-FM + +The SIRI-FM updaters works slighly differently from the other in that it only updates the availability +of parking but does not create new lots in realtime. + +The data source must conform to the [Italian SIRI-FM](https://github.com/noi-techpark/sta-nap-export/files/15302688/240502_SpecificaSIRI_v.1.0.3.pdf) profile. + + + ## Changelog - Create initial sandbox implementation (January 2022, [#3796](https://github.com/opentripplanner/OpenTripPlanner/pull/3796)) diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index a3042e7b91f..0f91875e542 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -875,6 +875,12 @@ Used to group requests when monitoring OTP. "feedId" : "bikeep", "sourceType" : "bikeep", "url" : "https://services.bikeep.com/location/v1/public-areas/no-baia-mobility/locations" + }, + { + "type" : "vehicle-parking", + "feedId" : "parking", + "sourceType" : "siri-fm", + "url" : "https://transmodel.api.opendatahub.com/siri-lite/fm/parking" } ], "rideHailingServices" : [ diff --git a/docs/sandbox/VehicleParking.md b/docs/sandbox/VehicleParking.md index ae83dba2b41..06f520b0972 100644 --- a/docs/sandbox/VehicleParking.md +++ b/docs/sandbox/VehicleParking.md @@ -55,7 +55,7 @@ All updaters have the following parameters in common: The id of the data source, which will be the prefix of the parking lot's id. -This will end up in the API responses as the feed id of of the parking lot. +This will end up in the API responses as the feed id of the parking lot.

          sourceType

          @@ -125,7 +125,7 @@ Used for converting abstract opening hours into concrete points in time. The id of the data source, which will be the prefix of the parking lot's id. -This will end up in the API responses as the feed id of of the parking lot. +This will end up in the API responses as the feed id of the parking lot.

          sourceType

          @@ -210,7 +210,7 @@ Tags to add to the parking lots. The id of the data source, which will be the prefix of the parking lot's id. -This will end up in the API responses as the feed id of of the parking lot. +This will end up in the API responses as the feed id of the parking lot.

          sourceType

          @@ -275,7 +275,7 @@ HTTP headers to add to the request. Any header key, value can be inserted. The id of the data source, which will be the prefix of the parking lot's id. -This will end up in the API responses as the feed id of of the parking lot. +This will end up in the API responses as the feed id of the parking lot.

          sourceType

          @@ -336,7 +336,7 @@ HTTP headers to add to the request. Any header key, value can be inserted. The id of the data source, which will be the prefix of the parking lot's id. -This will end up in the API responses as the feed id of of the parking lot. +This will end up in the API responses as the feed id of the parking lot.

          sourceType

          @@ -373,6 +373,85 @@ HTTP headers to add to the request. Any header key, value can be inserted. +## SIRI-FM + +The SIRI-FM updaters works slighly differently from the other in that it only updates the availability +of parking but does not create new lots in realtime. + +The data source must conform to the [Italian SIRI-FM](https://github.com/noi-techpark/sta-nap-export/files/15302688/240502_SpecificaSIRI_v.1.0.3.pdf) profile. + + + + +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|----------------------------------|:---------------:|------------------------------------------------------------------------------|:----------:|---------------|:-----:| +| type = "vehicle-parking" | `enum` | The type of the updater. | *Required* | | 1.5 | +| [feedId](#u__15__feedId) | `string` | The id of the data source, which will be the prefix of the parking lot's id. | *Required* | | 2.2 | +| frequency | `duration` | How often to update the source. | *Optional* | `"PT1M"` | 2.6 | +| [sourceType](#u__15__sourceType) | `enum` | The source of the vehicle updates. | *Required* | | 2.2 | +| [url](#u__15__url) | `uri` | URL of the SIRI-FM Light endpoint. | *Required* | | 2.6 | +| [headers](#u__15__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.6 | + + +#### Details + +

          feedId

          + +**Since version:** `2.2` ∙ **Type:** `string` ∙ **Cardinality:** `Required` +**Path:** /updaters/[15] + +The id of the data source, which will be the prefix of the parking lot's id. + +This will end up in the API responses as the feed id of the parking lot. + +

          sourceType

          + +**Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Required` +**Path:** /updaters/[15] +**Enum values:** `park-api` | `bicycle-park-api` | `hsl-park` | `bikely` | `noi-open-data-hub` | `bikeep` | `siri-fm` + +The source of the vehicle updates. + +

          url

          + +**Since version:** `2.6` ∙ **Type:** `uri` ∙ **Cardinality:** `Required` +**Path:** /updaters/[15] + +URL of the SIRI-FM Light endpoint. + +SIRI Light means that it must be available as a HTTP GET request rather than the usual +SIRI request mechanism of HTTP POST. + +The contents must also conform to the [Italian SIRI profile](https://github.com/noi-techpark/sta-nap-export/files/15302688/240502_SpecificaSIRI_v.1.0.3.pdf). + + +

          headers

          + +**Since version:** `2.6` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` +**Path:** /updaters/[15] + +HTTP headers to add to the request. Any header key, value can be inserted. + + + +##### Example configuration + +```JSON +// router-config.json +{ + "updaters" : [ + { + "type" : "vehicle-parking", + "feedId" : "parking", + "sourceType" : "siri-fm", + "url" : "https://transmodel.api.opendatahub.com/siri-lite/fm/parking" + } + ] +} +``` + + + ## Changelog - Create initial sandbox implementation (January 2022, [#3796](https://github.com/opentripplanner/OpenTripPlanner/pull/3796)) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java index 6ef8c465bc3..60f794f2f2a 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java @@ -30,7 +30,7 @@ public static VehicleParkingUpdaterParameters create(String updaterRef, NodeAdap .of("feedId") .since(V2_2) .summary("The id of the data source, which will be the prefix of the parking lot's id.") - .description("This will end up in the API responses as the feed id of of the parking lot.") + .description("This will end up in the API responses as the feed id of the parking lot.") .asString(); return switch (sourceType) { case HSL_PARK -> new HslParkUpdaterParameters( @@ -103,7 +103,19 @@ public static VehicleParkingUpdaterParameters create(String updaterRef, NodeAdap ); case SIRI_FM -> new SiriFmUpdaterParameters( updaterRef, - c.of("url").since(V2_6).summary("URL of the SIRI-FM Light endpoint.").asUri(), + c + .of("url") + .since(V2_6) + .summary("URL of the SIRI-FM Light endpoint.") + .description( + """ + SIRI Light means that it must be available as a HTTP GET request rather than the usual + SIRI request mechanism of HTTP POST. + + The contents must also conform to the [Italian SIRI profile](https://github.com/noi-techpark/sta-nap-export/files/15302688/240502_SpecificaSIRI_v.1.0.3.pdf). + """ + ) + .asUri(), feedId, c .of("frequency") diff --git a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java index 713b6d01664..0af58378f90 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java +++ b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java @@ -81,6 +81,7 @@ void updateBicycleAvailability() { assertEquals(8, updated.getAvailability().getBicycleSpaces()); assertNull(updated.getAvailability().getCarSpaces()); } + @Test void notFound() { var service = buildParkingService(VehicleParkingSpaces.builder().bicycleSpaces(15).build()); diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 3a3ef9b4cf0..c526de423c1 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -438,6 +438,13 @@ "feedId": "bikeep", "sourceType": "bikeep", "url": "https://services.bikeep.com/location/v1/public-areas/no-baia-mobility/locations" + }, + // SIRI-FM vehicle parking updater + { + "type": "vehicle-parking", + "feedId": "parking", + "sourceType": "siri-fm", + "url": "https://transmodel.api.opendatahub.com/siri-lite/fm/parking" } ], "rideHailingServices": [ From 7363899c074dfc8bebb03caf32e166414169e073 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 2 Aug 2024 10:23:15 +0200 Subject: [PATCH 32/93] Mention SIRI 2.1 --- doc-templates/VehicleParking.md | 3 ++- docs/sandbox/VehicleParking.md | 6 ++++-- .../routerconfig/updaters/VehicleParkingUpdaterConfig.java | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/doc-templates/VehicleParking.md b/doc-templates/VehicleParking.md index 507894b97e8..9efb6b66522 100644 --- a/doc-templates/VehicleParking.md +++ b/doc-templates/VehicleParking.md @@ -53,7 +53,8 @@ All updaters have the following parameters in common: The SIRI-FM updaters works slighly differently from the other in that it only updates the availability of parking but does not create new lots in realtime. -The data source must conform to the [Italian SIRI-FM](https://github.com/noi-techpark/sta-nap-export/files/15302688/240502_SpecificaSIRI_v.1.0.3.pdf) profile. +The data source must conform to the [Italian SIRI-FM](https://github.com/5Tsrl/siri-italian-profile) profile +requires SIRI 2.1. diff --git a/docs/sandbox/VehicleParking.md b/docs/sandbox/VehicleParking.md index 06f520b0972..45a2dc28ea8 100644 --- a/docs/sandbox/VehicleParking.md +++ b/docs/sandbox/VehicleParking.md @@ -378,7 +378,8 @@ HTTP headers to add to the request. Any header key, value can be inserted. The SIRI-FM updaters works slighly differently from the other in that it only updates the availability of parking but does not create new lots in realtime. -The data source must conform to the [Italian SIRI-FM](https://github.com/noi-techpark/sta-nap-export/files/15302688/240502_SpecificaSIRI_v.1.0.3.pdf) profile. +The data source must conform to the [Italian SIRI-FM](https://github.com/5Tsrl/siri-italian-profile) profile +requires SIRI 2.1. @@ -422,7 +423,8 @@ URL of the SIRI-FM Light endpoint. SIRI Light means that it must be available as a HTTP GET request rather than the usual SIRI request mechanism of HTTP POST. -The contents must also conform to the [Italian SIRI profile](https://github.com/noi-techpark/sta-nap-export/files/15302688/240502_SpecificaSIRI_v.1.0.3.pdf). +The contents must also conform to the [Italian SIRI profile](https://github.com/5Tsrl/siri-italian-profile) +which requires SIRI 2.1.

          headers

          diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java index 60f794f2f2a..88b47aac4eb 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/VehicleParkingUpdaterConfig.java @@ -112,7 +112,8 @@ public static VehicleParkingUpdaterParameters create(String updaterRef, NodeAdap SIRI Light means that it must be available as a HTTP GET request rather than the usual SIRI request mechanism of HTTP POST. - The contents must also conform to the [Italian SIRI profile](https://github.com/noi-techpark/sta-nap-export/files/15302688/240502_SpecificaSIRI_v.1.0.3.pdf). + The contents must also conform to the [Italian SIRI profile](https://github.com/5Tsrl/siri-italian-profile) + which requires SIRI 2.1. """ ) .asUri(), From 3a76485ba656f3c6e1547c75504c8a2be93894b4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 2 Aug 2024 20:49:32 +0200 Subject: [PATCH 33/93] Update doc-templates/VehicleParking.md Co-authored-by: Joel Lappalainen --- doc-templates/VehicleParking.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc-templates/VehicleParking.md b/doc-templates/VehicleParking.md index 9efb6b66522..a8a46d7875d 100644 --- a/doc-templates/VehicleParking.md +++ b/doc-templates/VehicleParking.md @@ -50,7 +50,7 @@ All updaters have the following parameters in common: ## SIRI-FM -The SIRI-FM updaters works slighly differently from the other in that it only updates the availability +The SIRI-FM updaters works slighly differently from the others in that it only updates the availability of parking but does not create new lots in realtime. The data source must conform to the [Italian SIRI-FM](https://github.com/5Tsrl/siri-italian-profile) profile From fbca53de934767fd84f7f4f7a091fb044d20d31d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 22:42:55 +0000 Subject: [PATCH 34/93] Update jersey monorepo to v3.1.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 73ef86f3be9..a9e591f0d3a 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ 31.3 2.51.1 2.17.2 - 3.1.7 + 3.1.8 5.10.3 1.13.2 5.6.0 From 1ba10c05df1d030adc7cba3c5566aa58b893ebd4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 5 Aug 2024 14:13:04 +0200 Subject: [PATCH 35/93] Compile docs --- docs/sandbox/VehicleParking.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sandbox/VehicleParking.md b/docs/sandbox/VehicleParking.md index 45a2dc28ea8..9ca4dcc4ee3 100644 --- a/docs/sandbox/VehicleParking.md +++ b/docs/sandbox/VehicleParking.md @@ -375,7 +375,7 @@ HTTP headers to add to the request. Any header key, value can be inserted. ## SIRI-FM -The SIRI-FM updaters works slighly differently from the other in that it only updates the availability +The SIRI-FM updaters works slighly differently from the others in that it only updates the availability of parking but does not create new lots in realtime. The data source must conform to the [Italian SIRI-FM](https://github.com/5Tsrl/siri-italian-profile) profile From a2214eb5882b494c0754f097ff7694f619fbf879 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 5 Aug 2024 14:18:01 +0200 Subject: [PATCH 36/93] Rename class --- .../vehicle_parking/VehicleParkingAvailabilityUpdater.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java index 86e7b72c9ff..2a5de121893 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java @@ -54,17 +54,17 @@ protected void runPolling() { if (source.update()) { var updates = source.getUpdates(); - var graphWriterRunnable = new UpdateAvailabilities(updates); + var graphWriterRunnable = new AvailabilityUpdater(updates); saveResultOnGraph.execute(graphWriterRunnable); } } - private class UpdateAvailabilities implements GraphWriterRunnable { + private class AvailabilityUpdater implements GraphWriterRunnable { private final List updates; private final Map parkingById; - private UpdateAvailabilities(List updates) { + private AvailabilityUpdater(List updates) { this.updates = List.copyOf(updates); this.parkingById = vehicleParkingService From 1837b79b2390d4a44f4c536c1aa19d11a048c5e8 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 5 Aug 2024 16:58:20 +0200 Subject: [PATCH 37/93] Apply review suggestions --- doc-templates/VehicleParking.md | 2 +- docs/sandbox/VehicleParking.md | 2 +- .../configure/UpdaterConfigurator.java | 4 --- ...VehicleParkingAvailabilityUpdaterTest.java | 36 ++++++++----------- 4 files changed, 17 insertions(+), 27 deletions(-) diff --git a/doc-templates/VehicleParking.md b/doc-templates/VehicleParking.md index a8a46d7875d..e3fcf84dc6e 100644 --- a/doc-templates/VehicleParking.md +++ b/doc-templates/VehicleParking.md @@ -50,7 +50,7 @@ All updaters have the following parameters in common: ## SIRI-FM -The SIRI-FM updaters works slighly differently from the others in that it only updates the availability +The SIRI-FM updater works slightly differently from the others in that it only updates the availability of parking but does not create new lots in realtime. The data source must conform to the [Italian SIRI-FM](https://github.com/5Tsrl/siri-italian-profile) profile diff --git a/docs/sandbox/VehicleParking.md b/docs/sandbox/VehicleParking.md index 9ca4dcc4ee3..926a12b88a5 100644 --- a/docs/sandbox/VehicleParking.md +++ b/docs/sandbox/VehicleParking.md @@ -375,7 +375,7 @@ HTTP headers to add to the request. Any header key, value can be inserted. ## SIRI-FM -The SIRI-FM updaters works slighly differently from the others in that it only updates the availability +The SIRI-FM updater works slightly differently from the others in that it only updates the availability of parking but does not create new lots in realtime. The data source must conform to the [Italian SIRI-FM](https://github.com/5Tsrl/siri-italian-profile) profile diff --git a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java index 6662bae362b..83e0bd0fe85 100644 --- a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java +++ b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java @@ -32,8 +32,6 @@ import org.opentripplanner.updater.vehicle_position.PollingVehiclePositionUpdater; import org.opentripplanner.updater.vehicle_rental.VehicleRentalUpdater; import org.opentripplanner.updater.vehicle_rental.datasources.VehicleRentalDataSourceFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Sets up and starts all the graph updaters. @@ -44,8 +42,6 @@ */ public class UpdaterConfigurator { - private static final Logger LOG = LoggerFactory.getLogger(UpdaterConfigurator.class); - private final Graph graph; private final TransitModel transitModel; private final UpdatersParameters updatersParameters; diff --git a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java index 0af58378f90..01fdb5425ee 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java +++ b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java @@ -2,10 +2,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.opentripplanner.standalone.config.framework.json.JsonSupport.newNodeAdapterForTest; import static org.opentripplanner.transit.model._data.TransitModelForTest.id; import com.google.common.util.concurrent.Futures; -import java.time.Duration; import java.util.List; import java.util.concurrent.Future; import org.junit.jupiter.api.Test; @@ -15,6 +15,7 @@ import org.opentripplanner.routing.vehicle_parking.VehicleParking; import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; +import org.opentripplanner.standalone.config.routerconfig.updaters.VehicleParkingUpdaterConfig; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.service.TransitModel; import org.opentripplanner.updater.GraphUpdaterManager; @@ -24,27 +25,20 @@ class VehicleParkingAvailabilityUpdaterTest { - private static final VehicleParkingUpdaterParameters PARAMETERS = new VehicleParkingUpdaterParameters() { - @Override - public VehicleParkingSourceType sourceType() { - return VehicleParkingSourceType.SIRI_FM; - } - - @Override - public UpdateType updateType() { - return UpdateType.AVAILABILITY_ONLY; - } - - @Override - public Duration frequency() { - return Duration.ZERO; - } + private static final VehicleParkingUpdaterParameters PARAMETERS = VehicleParkingUpdaterConfig.create( + "ref", + newNodeAdapterForTest( + """ + { + "type" : "vehicle-parking", + "feedId" : "parking", + "sourceType" : "siri-fm", + "url" : "https://transmodel.api.opendatahub.com/siri-lite/fm/parking" + } + """ + ) + ); - @Override - public String configRef() { - return null; - } - }; private static final FeedScopedId ID = id("parking1"); private static final AvailabiltyUpdate DEFAULT_UPDATE = new AvailabiltyUpdate(ID, 8); From f2ba2c8b951a25c7eddb0b1ed889a2fd772c23b9 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 5 Aug 2024 17:23:30 +0200 Subject: [PATCH 38/93] Lower frequency --- .../vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java index 01fdb5425ee..87222eeba8f 100644 --- a/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java +++ b/src/test/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdaterTest.java @@ -33,6 +33,7 @@ class VehicleParkingAvailabilityUpdaterTest { "type" : "vehicle-parking", "feedId" : "parking", "sourceType" : "siri-fm", + "frequency": "0s", "url" : "https://transmodel.api.opendatahub.com/siri-lite/fm/parking" } """ From 42e45e19041ff6d4e350bd273dda5d71a54d2855 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jul 2024 16:11:42 +0200 Subject: [PATCH 39/93] Use original realtime pattern as key --- .../DefaultRealtimeVehicleService.java | 7 ++- .../DefaultRealtimeVehicleServiceTest.java | 55 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java b/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java index 07fa48fa84f..8b87fc432a9 100644 --- a/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java +++ b/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java @@ -8,7 +8,6 @@ import java.util.Comparator; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nonnull; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; @@ -35,6 +34,9 @@ public DefaultRealtimeVehicleService(TransitService transitService) { @Override public void setRealtimeVehicles(TripPattern pattern, List updates) { + if (pattern.getOriginalTripPattern() != null) { + pattern = pattern.getOriginalTripPattern(); + } vehicles.put(pattern, List.copyOf(updates)); } @@ -45,6 +47,9 @@ public void clearRealtimeVehicles(TripPattern pattern) { @Override public List getRealtimeVehicles(@Nonnull TripPattern pattern) { + if (pattern.getOriginalTripPattern() != null) { + pattern = pattern.getOriginalTripPattern(); + } // the list is made immutable during insertion, so we can safely return them return vehicles.getOrDefault(pattern, List.of()); } diff --git a/src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java b/src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java new file mode 100644 index 00000000000..a1c9dddaab0 --- /dev/null +++ b/src/test/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleServiceTest.java @@ -0,0 +1,55 @@ +package org.opentripplanner.service.realtimevehicles.internal; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.framework.geometry.WgsCoordinate.GREENWICH; +import static org.opentripplanner.transit.model._data.TransitModelForTest.route; +import static org.opentripplanner.transit.model._data.TransitModelForTest.tripPattern; + +import java.time.Instant; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; +import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.network.StopPattern; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.service.DefaultTransitService; +import org.opentripplanner.transit.service.TransitModel; + +class DefaultRealtimeVehicleServiceTest { + + private static final Route ROUTE = route("r1").build(); + private static final TransitModelForTest MODEL = TransitModelForTest.of(); + private static final StopPattern STOP_PATTERN = TransitModelForTest.stopPattern( + MODEL.stop("1").build(), + MODEL.stop("2").build() + ); + private static final TripPattern ORIGINAL = tripPattern("original", ROUTE) + .withStopPattern(STOP_PATTERN) + .build(); + private static final Instant TIME = Instant.ofEpochSecond(1000); + private static final List VEHICLES = List.of( + RealtimeVehicle.builder().withTime(TIME).withCoordinates(GREENWICH).build() + ); + + @Test + void originalPattern() { + var service = new DefaultRealtimeVehicleService(new DefaultTransitService(new TransitModel())); + service.setRealtimeVehicles(ORIGINAL, VEHICLES); + var updates = service.getRealtimeVehicles(ORIGINAL); + assertEquals(VEHICLES, updates); + } + + @Test + void realtimeAddedPattern() { + var service = new DefaultRealtimeVehicleService(new DefaultTransitService(new TransitModel())); + var realtimePattern = tripPattern("realtime-added", ROUTE) + .withStopPattern(STOP_PATTERN) + .withOriginalTripPattern(ORIGINAL) + .withCreatedByRealtimeUpdater(true) + .build(); + service.setRealtimeVehicles(realtimePattern, VEHICLES); + var updates = service.getRealtimeVehicles(ORIGINAL); + assertEquals(VEHICLES, updates); + } +} From e81aa53ca03884de761f4f6dcfde200a75655a5b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 6 Aug 2024 12:40:03 +0200 Subject: [PATCH 40/93] Add Javadoc --- .../internal/DefaultRealtimeVehicleService.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java b/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java index 8b87fc432a9..0058cdd9e15 100644 --- a/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java +++ b/src/main/java/org/opentripplanner/service/realtimevehicles/internal/DefaultRealtimeVehicleService.java @@ -32,6 +32,11 @@ public DefaultRealtimeVehicleService(TransitService transitService) { this.transitService = transitService; } + /** + * Stores the relationship between a list of realtime vehicles with a pattern. If the pattern is + * a realtime-added one, then the original (scheduled) one is used as the key for the map storing + * the information. + */ @Override public void setRealtimeVehicles(TripPattern pattern, List updates) { if (pattern.getOriginalTripPattern() != null) { @@ -45,6 +50,13 @@ public void clearRealtimeVehicles(TripPattern pattern) { vehicles.remove(pattern); } + /** + * Gets the realtime vehicles for a given pattern. If the pattern is a realtime-added one + * then the original (scheduled) one is used for the lookup instead, so you receive the correct + * result no matter if you use the realtime or static information. + * + * @see DefaultRealtimeVehicleService#setRealtimeVehicles(TripPattern, List) + */ @Override public List getRealtimeVehicles(@Nonnull TripPattern pattern) { if (pattern.getOriginalTripPattern() != null) { From e5044fd9ec66a1ef47919a514e4fffc3d5d4827d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 00:04:17 +0000 Subject: [PATCH 41/93] Update dependency @graphql-codegen/add to v5.0.3 --- .../opentripplanner/apis/gtfs/generated/package.json | 2 +- .../org/opentripplanner/apis/gtfs/generated/yarn.lock | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json b/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json index 6a840640ca9..6dd08bb8041 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json @@ -10,7 +10,7 @@ }, "license": "LGPL-3.0", "dependencies": { - "@graphql-codegen/add": "5.0.2", + "@graphql-codegen/add": "5.0.3", "@graphql-codegen/cli": "5.0.2", "@graphql-codegen/java": "4.0.1", "@graphql-codegen/java-resolvers": "3.0.0", diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock b/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock index 77829ecc911..41bc851882b 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock @@ -699,7 +699,15 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" -"@graphql-codegen/add@5.0.2", "@graphql-codegen/add@^5.0.2": +"@graphql-codegen/add@5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-5.0.3.tgz#1ede6bac9a93661ed7fa5808b203d079e1b1d215" + integrity sha512-SxXPmramkth8XtBlAHu4H4jYcYXM/o3p01+psU+0NADQowA8jtYkK6MW5rV6T+CxkEaNZItfSmZRPgIuypcqnA== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + tslib "~2.6.0" + +"@graphql-codegen/add@^5.0.2": version "5.0.2" resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-5.0.2.tgz#71b3ae0465a4537172dddb84531b6967ca5545f2" integrity sha512-ouBkSvMFUhda5VoKumo/ZvsZM9P5ZTyDsI8LW18VxSNWOjrTeLXBWHG8Gfaai0HwhflPtCYVABbriEcOmrRShQ== From 14e7b3a9ddc9ca29944fcf229586c06bcb29d4ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 21:51:59 +0000 Subject: [PATCH 42/93] Update slf4j monorepo to v2.0.14 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e3437b2a063..89fb83240d1 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ 5.6.0 1.5.6 9.11.1 - 2.0.13 + 2.0.14 2.0.15 1.27 4.0.5 From 2dcee7703c8caafe98f6a4ab62aafd67ba820b63 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 6 Aug 2024 12:30:11 +0200 Subject: [PATCH 43/93] Add test case --- .../ext/geocoder/LuceneIndexTest.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 3e6c2b15195..4403d44679f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -98,6 +98,10 @@ class LuceneIndexTest { .withCoordinate(52.52277, 13.41046) .build(); + static final RegularStop MERIDIAN_AVE = TEST_MODEL.stop("Meridian Ave N & N 148th").build(); + + static final RegularStop MERIDIAN_1 = TEST_MODEL.stop("Meridian N & Spencer").build(); + static LuceneIndex index; static StopClusterMapper mapper; @@ -113,7 +117,9 @@ static void setup() { LICHTERFELDE_OST_2, WESTHAFEN, ARTS_CENTER, - ARTHUR + ARTHUR, + MERIDIAN_AVE, + MERIDIAN_1 ) .forEach(stopModel::withRegularStop); List @@ -295,6 +301,15 @@ void agenciesAndFeedPublisher() { assertEquals(List.of(StopClusterMapper.toAgency(BVG)), cluster.primary().agencies()); assertEquals("A Publisher", cluster.primary().feedPublisher().name()); } + + @Test + void numbers() { + var result = index + .queryStopClusters("Meridian Ave N & N 148") + .map(s -> s.primary().name()) + .toList(); + assertEquals(List.of("Meridian Ave N & N 148th", "Meridian N & Spencer"), result); + } } private static @Nonnull Function primaryId() { From 1a641dda4b47cb01b804e90badfa7a6ea455189b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 6 Aug 2024 12:59:09 +0200 Subject: [PATCH 44/93] Flesh out tests --- .../ext/geocoder/LuceneIndexTest.java | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 4403d44679f..582fb2409d7 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -12,7 +12,6 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -98,9 +97,33 @@ class LuceneIndexTest { .withCoordinate(52.52277, 13.41046) .build(); - static final RegularStop MERIDIAN_AVE = TEST_MODEL.stop("Meridian Ave N & N 148th").build(); + static final RegularStop MERIDIAN_AVE = TEST_MODEL + .stop("Meridian Ave N & N 148th St") + .withId(FeedScopedId.parse("kcm:16340")) + .withCode("16340") + .withCoordinate(47.736145, -122.33445) + .build(); + + static final RegularStop MERIDIAN_N_1 = TEST_MODEL + .stop("Meridian N & Spencer") + .withId(FeedScopedId.parse("pierce:13268")) + .withCode("4168") + .withCoordinate(47.209366,-122.293999) + .build(); - static final RegularStop MERIDIAN_1 = TEST_MODEL.stop("Meridian N & Spencer").build(); + static final RegularStop MERIDIAN_N_2 = TEST_MODEL + .stop("Meridian N & Spencer") + .withId(FeedScopedId.parse("pierce:30976")) + .withCode("4169") + .withCoordinate(47.209316,-122.293841) + .build(); + + static final RegularStop MERIDIAN_N_3 = TEST_MODEL + .stop("N 205th St & Meridian Ave N") + .withId(FeedScopedId.parse("commtrans:490")) + .withCode("490") + .withCoordinate(47.209316,-122.293841) + .build(); static LuceneIndex index; @@ -118,8 +141,10 @@ static void setup() { WESTHAFEN, ARTS_CENTER, ARTHUR, - MERIDIAN_AVE, - MERIDIAN_1 + MERIDIAN_N_1, + MERIDIAN_N_2, + MERIDIAN_N_3, + MERIDIAN_AVE ) .forEach(stopModel::withRegularStop); List @@ -303,16 +328,13 @@ void agenciesAndFeedPublisher() { } @Test - void numbers() { - var result = index - .queryStopClusters("Meridian Ave N & N 148") - .map(s -> s.primary().name()) - .toList(); - assertEquals(List.of("Meridian Ave N & N 148th", "Meridian N & Spencer"), result); + void number() { + var names = index.queryStopClusters("Meridian Ave N & N 148").map(c -> c.primary().name()).toList(); + assertEquals(List.of(MERIDIAN_AVE.getName().toString(), MERIDIAN_N_1.getName().toString()), names); } } - private static @Nonnull Function primaryId() { + private static Function primaryId() { return c -> c.primary().id(); } } From 9c60311511a9a534bac2480b95029b0f3bc1fc01 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 6 Aug 2024 13:53:33 +0200 Subject: [PATCH 45/93] Add test for ampersand ngram --- .../geocoder/EnglishNgramAnalyzerTest.java | 34 +++++++++++++++++++ .../ext/geocoder/LuceneIndexTest.java | 16 ++++++--- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java index 615ef90cbbd..b4b145063f8 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java @@ -82,6 +82,40 @@ void ngram() throws IOException { ); } + @Test + void ampersand() throws IOException { + var analyzer = new EnglishNGramAnalyzer(); + List result = analyze("Meridian Ave N & N 148th St", analyzer); + + assertEquals( + List.of( + "Meri", + "Merid", + "Meridi", + "Meridia", + "Meridian", + "erid", + "eridi", + "eridia", + "eridian", + "ridi", + "ridia", + "ridian", + "idia", + "idian", + "dian", + "Av", + "N", + "N", + "148t", + "148th", + "48th", + "St" + ), + result + ); + } + public List analyze(String text, Analyzer analyzer) throws IOException { List result = new ArrayList<>(); TokenStream tokenStream = analyzer.tokenStream("name", text); diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 582fb2409d7..80899c9d5d8 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -108,21 +108,21 @@ class LuceneIndexTest { .stop("Meridian N & Spencer") .withId(FeedScopedId.parse("pierce:13268")) .withCode("4168") - .withCoordinate(47.209366,-122.293999) + .withCoordinate(47.209366, -122.293999) .build(); static final RegularStop MERIDIAN_N_2 = TEST_MODEL .stop("Meridian N & Spencer") .withId(FeedScopedId.parse("pierce:30976")) .withCode("4169") - .withCoordinate(47.209316,-122.293841) + .withCoordinate(47.209316, -122.293841) .build(); static final RegularStop MERIDIAN_N_3 = TEST_MODEL .stop("N 205th St & Meridian Ave N") .withId(FeedScopedId.parse("commtrans:490")) .withCode("490") - .withCoordinate(47.209316,-122.293841) + .withCoordinate(47.777632, -122.3346) .build(); static LuceneIndex index; @@ -329,8 +329,14 @@ void agenciesAndFeedPublisher() { @Test void number() { - var names = index.queryStopClusters("Meridian Ave N & N 148").map(c -> c.primary().name()).toList(); - assertEquals(List.of(MERIDIAN_AVE.getName().toString(), MERIDIAN_N_1.getName().toString()), names); + var names = index + .queryStopClusters("Meridian Ave N & N 148") + .map(c -> c.primary().name()) + .toList(); + assertEquals( + List.of(MERIDIAN_AVE.getName().toString(), MERIDIAN_N_1.getName().toString()), + names + ); } } From e61d1c187cc625cb94b9743a4f831f7be748f74e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 6 Aug 2024 15:36:17 +0200 Subject: [PATCH 46/93] Finetune fuzzyness of lucene indexing --- .../geocoder/EnglishNgramAnalyzerTest.java | 24 ++++++++++++++++++- .../ext/geocoder/LuceneIndexTest.java | 18 +++++++------- .../ext/geocoder/EnglishNGramAnalyzer.java | 2 +- .../ext/geocoder/LuceneIndex.java | 2 +- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java index b4b145063f8..a1194c46e90 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; @@ -17,9 +18,9 @@ void ngram() throws IOException { var analyzer = new EnglishNGramAnalyzer(); List result = analyze("Alexanderplatz", analyzer); - //System.out.println(result.stream().collect(Collectors.joining("\",\"", "\"", "\""))); assertEquals( List.of( + "Ale", "Alex", "Alexa", "Alexan", @@ -27,6 +28,7 @@ void ngram() throws IOException { "Alexande", "Alexander", "Alexanderp", + "lex", "lexa", "lexan", "lexand", @@ -34,6 +36,7 @@ void ngram() throws IOException { "lexander", "lexanderp", "lexanderpl", + "exa", "exan", "exand", "exande", @@ -41,6 +44,7 @@ void ngram() throws IOException { "exanderp", "exanderpl", "exanderpla", + "xan", "xand", "xande", "xander", @@ -48,6 +52,7 @@ void ngram() throws IOException { "xanderpl", "xanderpla", "xanderplat", + "and", "ande", "ander", "anderp", @@ -55,27 +60,34 @@ void ngram() throws IOException { "anderpla", "anderplat", "anderplatz", + "nde", "nder", "nderp", "nderpl", "nderpla", "nderplat", "nderplatz", + "der", "derp", "derpl", "derpla", "derplat", "derplatz", + "erp", "erpl", "erpla", "erplat", "erplatz", + "rpl", "rpla", "rplat", "rplatz", + "pla", "plat", "platz", + "lat", "latz", + "atz", "Alexanderplatz" ), result @@ -87,29 +99,39 @@ void ampersand() throws IOException { var analyzer = new EnglishNGramAnalyzer(); List result = analyze("Meridian Ave N & N 148th St", analyzer); + System.out.println(result.stream().collect(Collectors.joining("\",\"", "\"", "\""))); assertEquals( List.of( + "Mer", "Meri", "Merid", "Meridi", "Meridia", "Meridian", + "eri", "erid", "eridi", "eridia", "eridian", + "rid", "ridi", "ridia", "ridian", + "idi", "idia", "idian", + "dia", "dian", + "ian", "Av", "N", "N", + "148", "148t", "148th", + "48t", "48th", + "8th", "St" ), result diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 80899c9d5d8..e94532a0589 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -12,6 +12,7 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -259,7 +260,7 @@ void stopClustersWithTypos(String searchTerm) { @Test void fuzzyStopClusters() { var result1 = index.queryStopClusters("arts").map(primaryId()).toList(); - assertEquals(List.of(ARTS_CENTER.getId()), result1); + assertEquals(List.of(ARTS_CENTER.getId(), ARTHUR.getId()), result1); } @Test @@ -327,14 +328,15 @@ void agenciesAndFeedPublisher() { assertEquals("A Publisher", cluster.primary().feedPublisher().name()); } - @Test - void number() { - var names = index - .queryStopClusters("Meridian Ave N & N 148") - .map(c -> c.primary().name()) - .toList(); + @ParameterizedTest + @ValueSource(strings = { "Meridian Ave N & N 148th", "Meridian Ave N & N 148" }) + void shortTokens(String query) { + var names = index.queryStopClusters(query).map(c -> c.primary().name()).toList(); assertEquals( - List.of(MERIDIAN_AVE.getName().toString(), MERIDIAN_N_1.getName().toString()), + Stream + .of(MERIDIAN_AVE, MERIDIAN_N_3, MERIDIAN_N_1) + .map(s -> s.getName().toString()) + .toList(), names ); } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java b/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java index ffe46604744..26f6723a8b2 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java @@ -28,7 +28,7 @@ protected TokenStreamComponents createComponents(String fieldName) { result = new StopFilter(result, EnglishAnalyzer.ENGLISH_STOP_WORDS_SET); result = new PorterStemFilter(result); result = new CapitalizationFilter(result); - result = new NGramTokenFilter(result, 4, 10, true); + result = new NGramTokenFilter(result, 3, 10, true); return new TokenStreamComponents(src, result); } } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index fe7bef8ad13..71b80ac58a6 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -288,7 +288,7 @@ private Stream matchingDocuments( } }); } else { - var nameParser = new QueryParser(NAME, analyzer); + var nameParser = new QueryParser(NAME_NGRAM, analyzer); var nameQuery = nameParser.parse(searchTerms); var ngramNameQuery = new TermQuery( From 2c13785294270ca3e39f2fa07f96f12c5589abb9 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 6 Aug 2024 15:47:33 +0200 Subject: [PATCH 47/93] Add more test instances --- .../org/opentripplanner/ext/geocoder/LuceneIndexTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index e94532a0589..6117b56ebdd 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -329,7 +329,9 @@ void agenciesAndFeedPublisher() { } @ParameterizedTest - @ValueSource(strings = { "Meridian Ave N & N 148th", "Meridian Ave N & N 148" }) + @ValueSource( + strings = { "Meridian Ave N & N 148th", "Meridian Ave N & N 148", "Meridian Ave N N 148" } + ) void shortTokens(String query) { var names = index.queryStopClusters(query).map(c -> c.primary().name()).toList(); assertEquals( From e7ec0f78e6d4efe1be132be32e8b9115049417bb Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 6 Aug 2024 15:50:33 +0200 Subject: [PATCH 48/93] Simplify test setup --- .../ext/geocoder/LuceneIndexTest.java | 40 +++---------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 6117b56ebdd..f14faa9b274 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -98,33 +98,9 @@ class LuceneIndexTest { .withCoordinate(52.52277, 13.41046) .build(); - static final RegularStop MERIDIAN_AVE = TEST_MODEL - .stop("Meridian Ave N & N 148th St") - .withId(FeedScopedId.parse("kcm:16340")) - .withCode("16340") - .withCoordinate(47.736145, -122.33445) - .build(); - - static final RegularStop MERIDIAN_N_1 = TEST_MODEL - .stop("Meridian N & Spencer") - .withId(FeedScopedId.parse("pierce:13268")) - .withCode("4168") - .withCoordinate(47.209366, -122.293999) - .build(); - - static final RegularStop MERIDIAN_N_2 = TEST_MODEL - .stop("Meridian N & Spencer") - .withId(FeedScopedId.parse("pierce:30976")) - .withCode("4169") - .withCoordinate(47.209316, -122.293841) - .build(); - - static final RegularStop MERIDIAN_N_3 = TEST_MODEL - .stop("N 205th St & Meridian Ave N") - .withId(FeedScopedId.parse("commtrans:490")) - .withCode("490") - .withCoordinate(47.777632, -122.3346) - .build(); + static final RegularStop MERIDIAN_AVE = TEST_MODEL.stop("Meridian Ave N & N 148th St").build(); + static final RegularStop MERIDIAN_N1 = TEST_MODEL.stop("Meridian N & Spencer").build(); + static final RegularStop MERIDIAN_N2 = TEST_MODEL.stop("N 205th St & Meridian Ave N").build(); static LuceneIndex index; @@ -142,9 +118,8 @@ static void setup() { WESTHAFEN, ARTS_CENTER, ARTHUR, - MERIDIAN_N_1, - MERIDIAN_N_2, - MERIDIAN_N_3, + MERIDIAN_N1, + MERIDIAN_N2, MERIDIAN_AVE ) .forEach(stopModel::withRegularStop); @@ -335,10 +310,7 @@ void agenciesAndFeedPublisher() { void shortTokens(String query) { var names = index.queryStopClusters(query).map(c -> c.primary().name()).toList(); assertEquals( - Stream - .of(MERIDIAN_AVE, MERIDIAN_N_3, MERIDIAN_N_1) - .map(s -> s.getName().toString()) - .toList(), + Stream.of(MERIDIAN_AVE, MERIDIAN_N2, MERIDIAN_N1).map(s -> s.getName().toString()).toList(), names ); } From 5b8cdc5a877afd52ef320bb56d21b855a7986c4a Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 6 Aug 2024 17:42:46 +0200 Subject: [PATCH 49/93] Move back the debug line --- .../opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java index a1194c46e90..e859069dbca 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; @@ -18,6 +17,7 @@ void ngram() throws IOException { var analyzer = new EnglishNGramAnalyzer(); List result = analyze("Alexanderplatz", analyzer); + //System.out.println(result.stream().collect(Collectors.joining("\",\"", "\"", "\""))); assertEquals( List.of( "Ale", @@ -99,7 +99,6 @@ void ampersand() throws IOException { var analyzer = new EnglishNGramAnalyzer(); List result = analyze("Meridian Ave N & N 148th St", analyzer); - System.out.println(result.stream().collect(Collectors.joining("\",\"", "\"", "\""))); assertEquals( List.of( "Mer", From d8c31dbcfe40d008d8ef45856c3a45729baa03f5 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 7 Aug 2024 09:02:29 +0200 Subject: [PATCH 50/93] Add more test cases --- .../opentripplanner/ext/geocoder/LuceneIndexTest.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index f14faa9b274..6b9ed853ad1 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -305,7 +305,15 @@ void agenciesAndFeedPublisher() { @ParameterizedTest @ValueSource( - strings = { "Meridian Ave N & N 148th", "Meridian Ave N & N 148", "Meridian Ave N N 148" } + strings = { + "Meridian Ave N & N 148th", + "Meridian Ave N & N 148", + "Meridian Ave N N 148", + "Meridian Ave N 148", + "Meridian & N 148", + "Meridian Ave 148", + "Meridian Av 148", + } ) void shortTokens(String query) { var names = index.queryStopClusters(query).map(c -> c.primary().name()).toList(); From edea05e139f12b434bf5244e8d74e4daf432c64b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 7 Aug 2024 11:48:22 +0200 Subject: [PATCH 51/93] Tokenize number suffixes --- .../geocoder/EnglishNgramAnalyzerTest.java | 80 ++++++++++--------- .../ext/geocoder/LuceneIndexTest.java | 3 +- .../ext/geocoder/EnglishNGramAnalyzer.java | 13 ++- 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java index e859069dbca..77917399647 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java @@ -5,22 +5,21 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; class EnglishNgramAnalyzerTest { @Test - void ngram() throws IOException { - var analyzer = new EnglishNGramAnalyzer(); - List result = analyze("Alexanderplatz", analyzer); + void ngram() { + List result = tokenize("Alexanderplatz"); //System.out.println(result.stream().collect(Collectors.joining("\",\"", "\"", "\""))); assertEquals( List.of( - "Ale", "Alex", "Alexa", "Alexan", @@ -28,7 +27,6 @@ void ngram() throws IOException { "Alexande", "Alexander", "Alexanderp", - "lex", "lexa", "lexan", "lexand", @@ -36,7 +34,6 @@ void ngram() throws IOException { "lexander", "lexanderp", "lexanderpl", - "exa", "exan", "exand", "exande", @@ -44,7 +41,6 @@ void ngram() throws IOException { "exanderp", "exanderpl", "exanderpla", - "xan", "xand", "xande", "xander", @@ -52,7 +48,6 @@ void ngram() throws IOException { "xanderpl", "xanderpla", "xanderplat", - "and", "ande", "ander", "anderp", @@ -60,34 +55,27 @@ void ngram() throws IOException { "anderpla", "anderplat", "anderplatz", - "nde", "nder", "nderp", "nderpl", "nderpla", "nderplat", "nderplatz", - "der", "derp", "derpl", "derpla", "derplat", "derplatz", - "erp", "erpl", "erpla", "erplat", "erplatz", - "rpl", "rpla", "rplat", "rplatz", - "pla", "plat", "platz", - "lat", "latz", - "atz", "Alexanderplatz" ), result @@ -95,56 +83,72 @@ void ngram() throws IOException { } @Test - void ampersand() throws IOException { - var analyzer = new EnglishNGramAnalyzer(); - List result = analyze("Meridian Ave N & N 148th St", analyzer); + void ampersand() { + List result = tokenize("Meridian Ave N & N 148th St"); assertEquals( List.of( - "Mer", "Meri", "Merid", "Meridi", "Meridia", "Meridian", - "eri", "erid", "eridi", "eridia", "eridian", - "rid", "ridi", "ridia", "ridian", - "idi", "idia", "idian", - "dia", "dian", - "ian", "Av", "N", "N", "148", - "148t", - "148th", - "48t", - "48th", - "8th", "St" ), result ); } - public List analyze(String text, Analyzer analyzer) throws IOException { - List result = new ArrayList<>(); - TokenStream tokenStream = analyzer.tokenStream("name", text); - CharTermAttribute attr = tokenStream.addAttribute(CharTermAttribute.class); - tokenStream.reset(); - while (tokenStream.incrementToken()) { - result.add(attr.toString()); + @ParameterizedTest + @CsvSource( + value = { + "1st:1", + "2nd:2", + "3rd:3", + "4th:4", + "6th:6", + "148th:148", + "102nd:102", + "1003rd:1003", + "St:St", + "S3:S3", + "Aard:Aard", + }, + delimiter = ':' + ) + void numberSuffixes(String input, String expected) { + var result = tokenize(input); + assertEquals(List.of(expected), result); + } + + public List tokenize(String text) { + try (var analyzer = new EnglishNGramAnalyzer()) { + List result; + TokenStream tokenStream; + result = new ArrayList<>(); + tokenStream = analyzer.tokenStream("name", text); + CharTermAttribute attr = tokenStream.addAttribute(CharTermAttribute.class); + tokenStream.reset(); + while (tokenStream.incrementToken()) { + result.add(attr.toString()); + } + return result; + } catch (IOException e) { + throw new RuntimeException(e); } - return result; } } diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 6b9ed853ad1..f3af08f29fe 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -235,7 +235,7 @@ void stopClustersWithTypos(String searchTerm) { @Test void fuzzyStopClusters() { var result1 = index.queryStopClusters("arts").map(primaryId()).toList(); - assertEquals(List.of(ARTS_CENTER.getId(), ARTHUR.getId()), result1); + assertEquals(List.of(ARTS_CENTER.getId()), result1); } @Test @@ -313,6 +313,7 @@ void agenciesAndFeedPublisher() { "Meridian & N 148", "Meridian Ave 148", "Meridian Av 148", + "meridian av 148", } ) void shortTokens(String query) { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java b/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java index 26f6723a8b2..922108427e8 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java @@ -1,14 +1,16 @@ package org.opentripplanner.ext.geocoder; +import java.util.regex.Pattern; import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.LowerCaseFilter; import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.analysis.core.LowerCaseFilter; import org.apache.lucene.analysis.core.StopFilter; import org.apache.lucene.analysis.en.EnglishAnalyzer; import org.apache.lucene.analysis.en.EnglishPossessiveFilter; import org.apache.lucene.analysis.en.PorterStemFilter; import org.apache.lucene.analysis.miscellaneous.CapitalizationFilter; import org.apache.lucene.analysis.ngram.NGramTokenFilter; +import org.apache.lucene.analysis.pattern.PatternReplaceFilter; import org.apache.lucene.analysis.standard.StandardTokenizer; /** @@ -17,18 +19,25 @@ * of a stop name can be matched efficiently. *

          * For example the query of "exanderpl" will match the stop name "Alexanderplatz". + *

          + * It also removes number suffixes in the American street names, like "147th Street", which will + * be tokenized to "147 Street". */ class EnglishNGramAnalyzer extends Analyzer { + // matches one or more numbers followed by the English suffixes "st", "nd", "rd", "th" + private static final Pattern NUMBER_SUFFIX_PATTERN = Pattern.compile("(\\d+)[st|nd|rd|th]+"); + @Override protected TokenStreamComponents createComponents(String fieldName) { StandardTokenizer src = new StandardTokenizer(); TokenStream result = new EnglishPossessiveFilter(src); result = new LowerCaseFilter(result); + result = new PatternReplaceFilter(result, NUMBER_SUFFIX_PATTERN, "$1", true); result = new StopFilter(result, EnglishAnalyzer.ENGLISH_STOP_WORDS_SET); result = new PorterStemFilter(result); result = new CapitalizationFilter(result); - result = new NGramTokenFilter(result, 3, 10, true); + result = new NGramTokenFilter(result, 4, 10, true); return new TokenStreamComponents(src, result); } } From 25808af7b622bee1e770edf6281d526f0b2c76fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 16:55:48 +0000 Subject: [PATCH 52/93] Update Debug UI dependencies (non-major) --- client/package-lock.json | 62 ++++++++++++++++++++++++---------------- client/package.json | 4 +-- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 9e2798660ec..87139a1a909 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12,7 +12,7 @@ "bootstrap": "5.3.3", "graphql": "16.9.0", "graphql-request": "7.1.0", - "maplibre-gl": "4.5.0", + "maplibre-gl": "4.5.1", "react": "18.3.1", "react-bootstrap": "2.10.4", "react-dom": "18.3.1", @@ -40,7 +40,7 @@ "jsdom": "24.1.1", "prettier": "3.3.3", "typescript": "5.5.4", - "vite": "5.3.5", + "vite": "5.4.0", "vitest": "2.0.5" } }, @@ -3846,11 +3846,6 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "node_modules/@types/junit-report-builder": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/junit-report-builder/-/junit-report-builder-3.0.2.tgz", - "integrity": "sha512-R5M+SYhMbwBeQcNXYWNCZkl09vkVfAtcPIaCGdzIkkbeaTrVbGQ7HVgi4s+EmM/M1K4ZuWQH0jGcvMvNePfxYA==" - }, "node_modules/@types/mapbox__point-geometry": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", @@ -5701,9 +5696,10 @@ } }, "node_modules/earcut": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", - "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", + "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==", + "license": "ISC" }, "node_modules/eastasianwidth": { "version": "0.2.0", @@ -8731,9 +8727,9 @@ } }, "node_modules/maplibre-gl": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.5.0.tgz", - "integrity": "sha512-qOS1hn4d/pn2i0uva4S5Oz+fACzTkgBKq+NpwT/Tqzi4MSyzcWNtDELzLUSgWqHfNIkGCl5CZ/w7dtis+t4RCw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.5.1.tgz", + "integrity": "sha512-pKFDK8ZU2atwZWC8gdPVhN7Bf5HIPgtA+IG/iQ7J6WgmqSwCSmylc5q3stahWqXfx9PYUwVNJITrp1Hw96SUiA==", "license": "BSD-3-Clause", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", @@ -8746,22 +8742,21 @@ "@maplibre/maplibre-gl-style-spec": "^20.3.0", "@types/geojson": "^7946.0.14", "@types/geojson-vt": "3.2.5", - "@types/junit-report-builder": "^3.0.2", "@types/mapbox__point-geometry": "^0.1.4", "@types/mapbox__vector-tile": "^1.3.4", "@types/pbf": "^3.0.5", "@types/supercluster": "^7.1.3", - "earcut": "^2.2.4", + "earcut": "^3.0.0", "geojson-vt": "^4.0.2", "gl-matrix": "^3.4.3", "global-prefix": "^3.0.0", "kdbush": "^4.0.2", "murmurhash-js": "^1.0.0", - "pbf": "^3.2.1", + "pbf": "^3.3.0", "potpack": "^2.0.0", - "quickselect": "^2.0.0", + "quickselect": "^3.0.0", "supercluster": "^8.0.1", - "tinyqueue": "^2.0.3", + "tinyqueue": "^3.0.0", "vt-pbf": "^3.1.3" }, "engines": { @@ -8772,6 +8767,18 @@ "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" } }, + "node_modules/maplibre-gl/node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "license": "ISC" + }, + "node_modules/maplibre-gl/node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC" + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -9495,9 +9502,10 @@ } }, "node_modules/pbf": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", - "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", + "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", + "license": "BSD-3-Clause", "dependencies": { "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" @@ -11392,14 +11400,14 @@ } }, "node_modules/vite": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", - "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", + "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.39", + "postcss": "^8.4.40", "rollup": "^4.13.0" }, "bin": { @@ -11419,6 +11427,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -11436,6 +11445,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, diff --git a/client/package.json b/client/package.json index fe8836e8d36..74b4ae8f0a2 100644 --- a/client/package.json +++ b/client/package.json @@ -21,7 +21,7 @@ "bootstrap": "5.3.3", "graphql": "16.9.0", "graphql-request": "7.1.0", - "maplibre-gl": "4.5.0", + "maplibre-gl": "4.5.1", "react": "18.3.1", "react-bootstrap": "2.10.4", "react-dom": "18.3.1", @@ -49,7 +49,7 @@ "jsdom": "24.1.1", "prettier": "3.3.3", "typescript": "5.5.4", - "vite": "5.3.5", + "vite": "5.4.0", "vitest": "2.0.5" } } From 998df59ae9d7f4ab82d08d6a354c9bad5ef6e695 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 10:42:53 +0200 Subject: [PATCH 53/93] Group some renovate updates together [ci skip] --- renovate.json5 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 98ec1f24fbe..c544e2767c5 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -34,7 +34,7 @@ "matchFiles": ["client/package.json"], "matchUpdateTypes": ["patch", "minor"], "groupName": "Debug UI dependencies (non-major)", - "schedule": ["on the first day of the week"], + "schedule": ["on the 3rd and 17th day of the month"], "reviewers": ["testower"] }, { @@ -45,6 +45,8 @@ // some dependencies that we auto-merge release very often and even the auto-merges create a lot of // noise, so we slow it down a bit { + "description": "Automerge test dependencies in a single PR", + "groupName": "Test dependencies", "matchPackageNames": [ "org.mockito:mockito-core", "com.tngtech.archunit:archunit", @@ -57,7 +59,6 @@ "matchPackagePrefixes": [ "org.junit.jupiter:", ], - "groupName": "Test dependencies", "automerge": true, "schedule": "on the 17th day of the month" }, @@ -70,12 +71,22 @@ "automerge": true }, { + "description": "Automerge Maven plugins in a single PR", + "groupName": "Maven plugins", "matchPackageNames": [ "ch.qos.logback:logback-classic", "io.github.git-commit-id:git-commit-id-maven-plugin", - "org.apache.maven.plugins:maven-gpg-plugin" + "org.apache.maven.plugins:maven-gpg-plugin", + "org.codehaus.mojo:build-helper-maven-plugin", + "org.apache.maven.plugins:maven-source-plugin", + "com.hubspot.maven.plugins:prettier-maven-plugin", + "com.google.cloud.tools:jib-maven-plugin", + "org.apache.maven.plugins:maven-shade-plugin", + "org.apache.maven.plugins:maven-compiler-plugin", + "org.apache.maven.plugins:maven-jar-plugin", + "org.sonatype.plugins:nexus-staging-maven-plugin" ], - "schedule": "on the 19th day of the month", + "schedule": "on the 23rd day of the month", "automerge": true }, { @@ -125,18 +136,7 @@ "automerge": true }, { - "description": "automatically merge test, logging and build dependencies", - "matchPackageNames": [ - // maven plugins - "org.codehaus.mojo:build-helper-maven-plugin", - "org.apache.maven.plugins:maven-source-plugin", - "com.hubspot.maven.plugins:prettier-maven-plugin", - "com.google.cloud.tools:jib-maven-plugin", - "org.apache.maven.plugins:maven-shade-plugin", - "org.apache.maven.plugins:maven-compiler-plugin", - "org.apache.maven.plugins:maven-jar-plugin", - "org.sonatype.plugins:nexus-staging-maven-plugin" - ], + "description": "automatically merge slf4j", "matchPackagePrefixes": [ "org.slf4j:" ], From d4a95dbe29e15e51b3f6eb23b35407cc60cdaf3d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 10:51:06 +0200 Subject: [PATCH 54/93] Group code generation deps together [ci skip] --- renovate.json5 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index c544e2767c5..2c405c51b2c 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -103,18 +103,17 @@ "org.onebusaway:onebusaway-gtfs", "com.google.cloud:libraries-bom", "com.google.guava:guava", - "@graphql-codegen/add", - "@graphql-codegen/cli", - "@graphql-codegen/java", - "@graphql-codegen/java-resolvers", - "graphql", "io.micrometer:micrometer-registry-prometheus", "io.micrometer:micrometer-registry-influx" ], - // we don't use the 'monthly' preset because that only fires on the first day of the month - // when there might already other PRs open "schedule": "on the 7th through 8th day of the month" }, + { + "groupName": "Update GTFS API code generation in a single PR", + "matchFiles": ["src/main/java/org/opentripplanner/apis/gtfs/generated/package.json"], + "reviewers": ["optionsome", "leonardehrenfried"], + "schedule": "on the 11th through 12th day of the month" + }, { "description": "in order to keep review burden low, don't update these quite so frequently", "matchPackagePrefixes": [ @@ -125,6 +124,7 @@ ] }, { + "groupName": "Automerge mkdocs in a single PR", "description": "automerge mkdocs-material every quarter", "matchPackageNames": [ "mkdocs", From 3eab7363287ed9b0845af121f45a1d1167363942 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 11:09:00 +0200 Subject: [PATCH 55/93] Slow down automerging of logging dependencies [ci skip] --- renovate.json5 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 2c405c51b2c..5a56c64cccb 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -74,7 +74,6 @@ "description": "Automerge Maven plugins in a single PR", "groupName": "Maven plugins", "matchPackageNames": [ - "ch.qos.logback:logback-classic", "io.github.git-commit-id:git-commit-id-maven-plugin", "org.apache.maven.plugins:maven-gpg-plugin", "org.codehaus.mojo:build-helper-maven-plugin", @@ -124,7 +123,7 @@ ] }, { - "groupName": "Automerge mkdocs in a single PR", + "groupName": "mkdocs", "description": "automerge mkdocs-material every quarter", "matchPackageNames": [ "mkdocs", @@ -136,12 +135,14 @@ "automerge": true }, { - "description": "automatically merge slf4j", + "description": "Automerge logging dependencies in a single PR", + "groupName": "logging", "matchPackagePrefixes": [ - "org.slf4j:" + "org.slf4j:", + "ch.qos.logback:" ], "automerge": true, - "schedule": "after 11pm and before 5am every weekday" + "schedule": "on the 4th day of the month" }, { "description": "give some projects time to publish a changelog before opening the PR", From 15a5bd24cf726314ea4a71e192c26d8ef1bb88aa Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Thu, 8 Aug 2024 10:12:15 +0000 Subject: [PATCH 56/93] Upgrade debug client to version 2024/08/2024-08-08T10:11 --- src/client/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/index.html b/src/client/index.html index d1734898ca0..2d82a433279 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +

          From e4199f1225f80fd399491318a4889cab7d4bed39 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 12:14:51 +0200 Subject: [PATCH 57/93] Apply review feedback --- .../routing/vehicle_parking/VehicleParking.java | 8 ++++++-- .../VehicleParkingAvailabilityUpdater.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java index b50c583c79a..9cf198daa68 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java +++ b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java @@ -97,7 +97,7 @@ public class VehicleParking implements Serializable { /** * The currently available spaces at this vehicle parking. */ - private VehicleParkingSpaces availability; + private volatile VehicleParkingSpaces availability; /** * The vehicle parking group this parking belongs to. */ @@ -254,9 +254,13 @@ public boolean hasRealTimeDataForMode( /** * The only mutable method in this class: it allows to update the available parking spaces during * real-time updates. + * Since the entity is used both by writer threads (real-time updates) and reader threads + * (A* routing), the update process is synchronized. */ public void updateAvailability(VehicleParkingSpaces vehicleParkingSpaces) { - this.availability = vehicleParkingSpaces; + synchronized (this) { + this.availability = vehicleParkingSpaces; + } } @Override diff --git a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java index 2a5de121893..31074aafe38 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_parking/VehicleParkingAvailabilityUpdater.java @@ -79,7 +79,7 @@ public void run(Graph graph, TransitModel ignored) { private void handleUpdate(AvailabiltyUpdate update) { if (!parkingById.containsKey(update.vehicleParkingId())) { - LOG.error( + LOG.warn( "Parking with id {} does not exist. Skipping availability update.", update.vehicleParkingId() ); From 2e71dd62db8d5d88578fd26e125610f481ebb702 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 12:50:20 +0200 Subject: [PATCH 58/93] Fix spelling --- doc-templates/VehicleParking.md | 2 +- docs/sandbox/VehicleParking.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc-templates/VehicleParking.md b/doc-templates/VehicleParking.md index e3fcf84dc6e..721cbc2657a 100644 --- a/doc-templates/VehicleParking.md +++ b/doc-templates/VehicleParking.md @@ -54,7 +54,7 @@ The SIRI-FM updater works slightly differently from the others in that it only u of parking but does not create new lots in realtime. The data source must conform to the [Italian SIRI-FM](https://github.com/5Tsrl/siri-italian-profile) profile -requires SIRI 2.1. +which requires SIRI 2.1. diff --git a/docs/sandbox/VehicleParking.md b/docs/sandbox/VehicleParking.md index 926a12b88a5..db057bd9dbd 100644 --- a/docs/sandbox/VehicleParking.md +++ b/docs/sandbox/VehicleParking.md @@ -379,7 +379,7 @@ The SIRI-FM updater works slightly differently from the others in that it only u of parking but does not create new lots in realtime. The data source must conform to the [Italian SIRI-FM](https://github.com/5Tsrl/siri-italian-profile) profile -requires SIRI 2.1. +which requires SIRI 2.1. From 81985cddc98f06abfdad7a72e08290570a9559b6 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 15:34:24 +0200 Subject: [PATCH 59/93] Don't synchronize anymore --- .../routing/vehicle_parking/VehicleParking.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java index 9cf198daa68..7fc81f4d395 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java +++ b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java @@ -258,9 +258,7 @@ public boolean hasRealTimeDataForMode( * (A* routing), the update process is synchronized. */ public void updateAvailability(VehicleParkingSpaces vehicleParkingSpaces) { - synchronized (this) { - this.availability = vehicleParkingSpaces; - } + this.availability = vehicleParkingSpaces; } @Override From 93205da889567b4207994507fa829b753880f24d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 15:46:59 +0200 Subject: [PATCH 60/93] Use volatile in parking service and document its use --- .../routing/vehicle_parking/VehicleParking.java | 2 ++ .../routing/vehicle_parking/VehicleParkingService.java | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java index 7fc81f4d395..e64dc92c890 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java +++ b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java @@ -96,6 +96,8 @@ public class VehicleParking implements Serializable { private final List entrances = new ArrayList<>(); /** * The currently available spaces at this vehicle parking. + *

          + * The volatile keyword is used to ensure safe publication by clearing CPU caches. */ private volatile VehicleParkingSpaces availability; /** diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingService.java b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingService.java index 639066871be..b0c08a2309b 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingService.java +++ b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingService.java @@ -21,13 +21,17 @@ public class VehicleParkingService implements Serializable { /** * To ensure that his is thread-safe, the set stored here should always be immutable. + *

          + * The volatile keyword is used to ensure safe publication by clearing CPU caches. */ - private Set vehicleParkings = Set.of(); + private volatile Set vehicleParkings = Set.of(); /** * To ensure that his is thread-safe, {@link ImmutableListMultimap} is used. + *

          + * The volatile keyword is used to ensure safe publication by clearing CPU caches. */ - private ImmutableListMultimap vehicleParkingGroups = ImmutableListMultimap.of(); + private volatile ImmutableListMultimap vehicleParkingGroups = ImmutableListMultimap.of(); /** * Does atomic update of {@link VehicleParking} and index of {@link VehicleParkingGroup} in this From 1935ba0ff4e39a33010dc3788c13827d00897a9b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 17:24:10 +0200 Subject: [PATCH 61/93] Update docs --- .../opentripplanner/routing/vehicle_parking/VehicleParking.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java index e64dc92c890..098af909296 100644 --- a/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java +++ b/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParking.java @@ -257,7 +257,7 @@ public boolean hasRealTimeDataForMode( * The only mutable method in this class: it allows to update the available parking spaces during * real-time updates. * Since the entity is used both by writer threads (real-time updates) and reader threads - * (A* routing), the update process is synchronized. + * (A* routing), the variable holding the information is marked as volatile. */ public void updateAvailability(VehicleParkingSpaces vehicleParkingSpaces) { this.availability = vehicleParkingSpaces; From bcdd0b4cc4a9f7d8c87dd1cadc4fbdc356a6f1d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Aug 2024 04:47:17 +0000 Subject: [PATCH 62/93] Update dependency com.google.cloud:libraries-bom to v26.44.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 89fb83240d1..788bb0eeaea 100644 --- a/pom.xml +++ b/pom.xml @@ -546,7 +546,7 @@ com.google.cloud libraries-bom - 26.40.0 + 26.44.0 pom import From f0a2c6c39c29455edff0ca9dc10ab10acaed30df Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 9 Aug 2024 10:37:08 +0200 Subject: [PATCH 63/93] Improve regexes and test names --- .../ext/geocoder/EnglishNgramAnalyzerTest.java | 8 +++++++- .../org/opentripplanner/ext/geocoder/LuceneIndexTest.java | 2 +- .../ext/geocoder/EnglishNGramAnalyzer.java | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java index 77917399647..2c352e0f760 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/EnglishNgramAnalyzerTest.java @@ -135,7 +135,13 @@ void numberSuffixes(String input, String expected) { assertEquals(List.of(expected), result); } - public List tokenize(String text) { + @Test + void wordBoundary() { + var result = tokenize("1stst"); + assertEquals(List.of("1sts", "1stst", "stst"), result); + } + + private List tokenize(String text) { try (var analyzer = new EnglishNGramAnalyzer()) { List result; TokenStream tokenStream; diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index f3af08f29fe..910c5080331 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -316,7 +316,7 @@ void agenciesAndFeedPublisher() { "meridian av 148", } ) - void shortTokens(String query) { + void numericAdjectives(String query) { var names = index.queryStopClusters(query).map(c -> c.primary().name()).toList(); assertEquals( Stream.of(MERIDIAN_AVE, MERIDIAN_N2, MERIDIAN_N1).map(s -> s.getName().toString()).toList(), diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java b/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java index 922108427e8..a3ef8440a18 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java @@ -26,7 +26,7 @@ class EnglishNGramAnalyzer extends Analyzer { // matches one or more numbers followed by the English suffixes "st", "nd", "rd", "th" - private static final Pattern NUMBER_SUFFIX_PATTERN = Pattern.compile("(\\d+)[st|nd|rd|th]+"); + private static final Pattern NUMBER_SUFFIX_PATTERN = Pattern.compile("(\\d+)(st|nd|rd|th)\\b"); @Override protected TokenStreamComponents createComponents(String fieldName) { From 2f4b2d4702471e031fb7b07f494862088ef657b2 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Fri, 9 Aug 2024 10:09:00 +0000 Subject: [PATCH 64/93] Add changelog entry for #5979 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 64840e36790..c8f6a9f1800 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -53,6 +53,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Keep at least one result for min-transfers and each transit-group in itinerary-group-filter [#5919](https://github.com/opentripplanner/OpenTripPlanner/pull/5919) - Extract parking lots from NeTEx feeds [#5946](https://github.com/opentripplanner/OpenTripPlanner/pull/5946) - Filter routes and patterns by service date in GTFS GraphQL API [#5869](https://github.com/opentripplanner/OpenTripPlanner/pull/5869) +- SIRI-FM vehicle parking updates [#5979](https://github.com/opentripplanner/OpenTripPlanner/pull/5979) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.5.0 (2024-03-13) From bf02dae9470adb2e68d5088e3f93cfcfd300c09e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 9 Aug 2024 14:55:29 +0200 Subject: [PATCH 65/93] Apply review comments --- .../java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java | 2 ++ .../org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 910c5080331..de6e600037c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -310,6 +310,8 @@ void agenciesAndFeedPublisher() { "Meridian Ave N & N 148", "Meridian Ave N N 148", "Meridian Ave N 148", + "Meridian & 148 N", + "148 N & Meridian", "Meridian & N 148", "Meridian Ave 148", "Meridian Av 148", diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java b/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java index a3ef8440a18..17bf529a559 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/EnglishNGramAnalyzer.java @@ -25,7 +25,7 @@ */ class EnglishNGramAnalyzer extends Analyzer { - // matches one or more numbers followed by the English suffixes "st", "nd", "rd", "th" + // Matches one or more numbers followed by the English suffixes "st", "nd", "rd", "th" private static final Pattern NUMBER_SUFFIX_PATTERN = Pattern.compile("(\\d+)(st|nd|rd|th)\\b"); @Override From 957206fbabefbf97e9fd028001ab0fd0419597e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Aug 2024 23:33:52 +0000 Subject: [PATCH 66/93] Update dependency graphql to v16.9.0 --- .../org/opentripplanner/apis/gtfs/generated/package.json | 2 +- .../org/opentripplanner/apis/gtfs/generated/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json b/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json index 6dd08bb8041..d6cbf02d5e7 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json @@ -14,6 +14,6 @@ "@graphql-codegen/cli": "5.0.2", "@graphql-codegen/java": "4.0.1", "@graphql-codegen/java-resolvers": "3.0.0", - "graphql": "16.8.1" + "graphql": "16.9.0" } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock b/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock index 41bc851882b..25686abd94a 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock @@ -2181,10 +2181,10 @@ graphql-ws@^5.14.0: resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.14.0.tgz#766f249f3974fc2c48fae0d1fb20c2c4c79cd591" integrity sha512-itrUTQZP/TgswR4GSSYuwWUzrE/w5GhbwM2GX3ic2U7aw33jgEsayfIlvaj7/GcIvZgNMzsPTrE5hqPuFUiE5g== -graphql@16.8.1: - version "16.8.1" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07" - integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw== +graphql@16.9.0: + version "16.9.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" + integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== has-flag@^3.0.0: version "3.0.0" From 2eb5842ca2bd4f4a40329f4e8542d48353377569 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 01:26:54 +0000 Subject: [PATCH 67/93] Update dependency com.graphql-java:graphql-java to v22.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 788bb0eeaea..96b43b871a3 100644 --- a/pom.xml +++ b/pom.xml @@ -859,7 +859,7 @@ com.graphql-java graphql-java - 22.1 + 22.2 com.graphql-java From 06144296887cb6456dadaf78fc6eb3272bf2d8c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 18:47:48 +0000 Subject: [PATCH 68/93] Update google.dagger.version to v2.52 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 788bb0eeaea..e2c973107b8 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 156 31.3 - 2.51.1 + 2.52 2.17.2 3.1.8 5.10.3 From 15e960cdb909d1a8a8fe181226cdcfddec420244 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 23:00:30 +0000 Subject: [PATCH 69/93] Update Debug UI dependencies (non-major) --- client/package-lock.json | 24 ++++++++++++------------ client/package.json | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 87139a1a909..09cdf3b18a2 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12,7 +12,7 @@ "bootstrap": "5.3.3", "graphql": "16.9.0", "graphql-request": "7.1.0", - "maplibre-gl": "4.5.1", + "maplibre-gl": "4.5.2", "react": "18.3.1", "react-bootstrap": "2.10.4", "react-dom": "18.3.1", @@ -40,7 +40,7 @@ "jsdom": "24.1.1", "prettier": "3.3.3", "typescript": "5.5.4", - "vite": "5.4.0", + "vite": "5.4.1", "vitest": "2.0.5" } }, @@ -8727,9 +8727,9 @@ } }, "node_modules/maplibre-gl": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.5.1.tgz", - "integrity": "sha512-pKFDK8ZU2atwZWC8gdPVhN7Bf5HIPgtA+IG/iQ7J6WgmqSwCSmylc5q3stahWqXfx9PYUwVNJITrp1Hw96SUiA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.5.2.tgz", + "integrity": "sha512-vlWL9EY2bSGg5FAt0mKPfYqlfX15uLW5D3kKv4Xjn54nIVn01MKdfUJMAVIr+8fXVqfSX6c095Iy5XnV+T76kQ==", "license": "BSD-3-Clause", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", @@ -9543,9 +9543,9 @@ } }, "node_modules/postcss": { - "version": "8.4.40", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", - "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "dev": true, "funding": [ { @@ -11400,14 +11400,14 @@ } }, "node_modules/vite": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", - "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.1.tgz", + "integrity": "sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.40", + "postcss": "^8.4.41", "rollup": "^4.13.0" }, "bin": { diff --git a/client/package.json b/client/package.json index 74b4ae8f0a2..2dcbd623562 100644 --- a/client/package.json +++ b/client/package.json @@ -21,7 +21,7 @@ "bootstrap": "5.3.3", "graphql": "16.9.0", "graphql-request": "7.1.0", - "maplibre-gl": "4.5.1", + "maplibre-gl": "4.5.2", "react": "18.3.1", "react-bootstrap": "2.10.4", "react-dom": "18.3.1", @@ -49,7 +49,7 @@ "jsdom": "24.1.1", "prettier": "3.3.3", "typescript": "5.5.4", - "vite": "5.4.0", + "vite": "5.4.1", "vitest": "2.0.5" } } From 5b6fa5ab9063705f83d6c9da724ffa9fcb3e8ded Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 23:00:36 +0000 Subject: [PATCH 70/93] Update Test dependencies --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 252bf20ec17..f5a7972ab8e 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ 2.52 2.17.2 3.1.8 - 5.10.3 + 5.11.0 1.13.2 5.6.0 1.5.6 @@ -694,7 +694,7 @@ com.google.truth truth - 1.4.2 + 1.4.4 test @@ -923,7 +923,7 @@ org.apache.commons commons-compress - 1.26.2 + 1.27.0 test From c3d1843063cd251d5bbfd0d8809d30cb2efd6d9d Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Sat, 17 Aug 2024 06:10:17 +0000 Subject: [PATCH 71/93] Upgrade debug client to version 2024/08/2024-08-17T06:09 --- src/client/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/index.html b/src/client/index.html index 2d82a433279..84b69dd08b6 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +

          From ff838eb6ea404958a336e1beda0cd67abd195311 Mon Sep 17 00:00:00 2001 From: a-limyr Date: Mon, 19 Aug 2024 13:40:00 +0200 Subject: [PATCH 72/93] Make itinerary list more compact --- .../src/components/ItineraryList/ItineraryLegDetails.tsx | 9 +++++---- client/src/style.css | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/client/src/components/ItineraryList/ItineraryLegDetails.tsx b/client/src/components/ItineraryList/ItineraryLegDetails.tsx index 56fdf430388..488ff34f197 100644 --- a/client/src/components/ItineraryList/ItineraryLegDetails.tsx +++ b/client/src/components/ItineraryList/ItineraryLegDetails.tsx @@ -10,14 +10,14 @@ export function ItineraryLegDetails({ leg, isLast }: { leg: Leg; isLast: boolean
          {formatDistance(leg.distance)}, {formatDuration(leg.duration)}
          -
          + - -
          +
          {leg.mode}{' '} {leg.line && ( @@ -28,10 +28,11 @@ export function ItineraryLegDetails({ leg, isLast }: { leg: Leg; isLast: boolean , {leg.authority?.name} )}{' '} -
          + {leg.mode !== Mode.Foot && ( <> - {leg.fromPlace.name} →{' '} +
          + {leg.fromPlace.name} →{' '} )}{' '} {!isLast && {leg.toPlace.name}} diff --git a/client/src/style.css b/client/src/style.css index 7dd2565c449..1a24ac2c072 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -86,7 +86,7 @@ } .itinerary-leg-details .mode { - margin-top: 10px; + margin-top: 2px; } .itinerary-header-itinerary-number { From eb94184d2112867a78473531058807b636b2a567 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Mon, 19 Aug 2024 14:15:50 +0000 Subject: [PATCH 73/93] Add changelog entry for #5994 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index c8f6a9f1800..c6f16da2f0e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -54,6 +54,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Extract parking lots from NeTEx feeds [#5946](https://github.com/opentripplanner/OpenTripPlanner/pull/5946) - Filter routes and patterns by service date in GTFS GraphQL API [#5869](https://github.com/opentripplanner/OpenTripPlanner/pull/5869) - SIRI-FM vehicle parking updates [#5979](https://github.com/opentripplanner/OpenTripPlanner/pull/5979) +- Take realtime patterns into account when storing realtime vehicles [#5994](https://github.com/opentripplanner/OpenTripPlanner/pull/5994) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.5.0 (2024-03-13) From 5137512d402b49411a30c71a0b4b842480a62012 Mon Sep 17 00:00:00 2001 From: a-limyr Date: Tue, 20 Aug 2024 09:16:13 +0200 Subject: [PATCH 74/93] Make itinerary list more compact --- .../ItineraryList/ItineraryLegDetails.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/client/src/components/ItineraryList/ItineraryLegDetails.tsx b/client/src/components/ItineraryList/ItineraryLegDetails.tsx index 488ff34f197..e75813a4a45 100644 --- a/client/src/components/ItineraryList/ItineraryLegDetails.tsx +++ b/client/src/components/ItineraryList/ItineraryLegDetails.tsx @@ -10,14 +10,9 @@ export function ItineraryLegDetails({ leg, isLast }: { leg: Leg; isLast: boolean
          {formatDistance(leg.distance)}, {formatDuration(leg.duration)}
          - - - - - + + -{' '} +
          {leg.mode}{' '} {leg.line && ( @@ -28,11 +23,10 @@ export function ItineraryLegDetails({ leg, isLast }: { leg: Leg; isLast: boolean , {leg.authority?.name} )}{' '} - {leg.mode !== Mode.Foot && ( <> -
          - {leg.fromPlace.name} →{' '} +
          + {leg.fromPlace.name} →{' '} )}{' '} {!isLast && {leg.toPlace.name}} From cd9e9737810b11f073a22eccdc50f7853b60eb26 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 21 Aug 2024 12:18:38 +0200 Subject: [PATCH 75/93] Update doc/dev/decisionrecords/RecordsPOJOsBuilders.md Co-authored-by: Andrew Byrd --- doc/dev/decisionrecords/RecordsPOJOsBuilders.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/dev/decisionrecords/RecordsPOJOsBuilders.md b/doc/dev/decisionrecords/RecordsPOJOsBuilders.md index 1a836374181..e0752fc70b0 100644 --- a/doc/dev/decisionrecords/RecordsPOJOsBuilders.md +++ b/doc/dev/decisionrecords/RecordsPOJOsBuilders.md @@ -13,10 +13,8 @@ Builder initStop(Stop stop) { ### Records -You may use records, but avoid using records if you can not encapsulate it properly. Be especially -aware of arrays fields (can not be protected) and collections (remember to make a defensive copy). -If you need to override `equals` and `hashCode`, then it is probably not worth it. -The default `equals()` and `hashCode()` implementation is shallow, so all nested fields need to be records or value-objects. Consider overriding `toString`. +You may use records, but avoid using records if you cannot encapsulate them properly. Generally, records are considered appropriate and useful for throw-away compound types private to an implementation, such as hash table keys or compound values in a temporary list or set. On the other hand, records are generally not appropriate in the domain model where we insist on full encapsulation, which records cannot readily provide. Be especially +aware of array fields (which can not be protected) and collections (remember to make a defensive copy). Consider overriding `toString`. But if you need to override `equals` and `hashCode`, then it is probably not worth using a record. The implicit `equals()` and `hashCode()` implementations for records behave as if they call `equals` and `hashCode` on each field of the record, so their behavior will depend heavily on the types of these fields. ### Builders From f6d702df83df58b308091a7b75cf3c2839975108 Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Thu, 22 Aug 2024 08:36:25 +0000 Subject: [PATCH 76/93] Upgrade debug client to version 2024/08/2024-08-22T08:35 --- src/client/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/index.html b/src/client/index.html index 84b69dd08b6..42b2a26d059 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +
          From d93d231dde002059c6d64dd24acf722f8dc4e8e5 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 22 Aug 2024 08:36:40 +0000 Subject: [PATCH 77/93] Add changelog entry for #6012 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index c6f16da2f0e..453e2cc6089 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -55,6 +55,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Filter routes and patterns by service date in GTFS GraphQL API [#5869](https://github.com/opentripplanner/OpenTripPlanner/pull/5869) - SIRI-FM vehicle parking updates [#5979](https://github.com/opentripplanner/OpenTripPlanner/pull/5979) - Take realtime patterns into account when storing realtime vehicles [#5994](https://github.com/opentripplanner/OpenTripPlanner/pull/5994) +- Debug client itinerary list style improvements [#6012](https://github.com/opentripplanner/OpenTripPlanner/pull/6012) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.5.0 (2024-03-13) From 8164d41b4f9ad7e5c946dfeec4e9dd567b38e6f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 22:34:42 +0000 Subject: [PATCH 78/93] Update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f5a7972ab8e..581989f7ffa 100644 --- a/pom.xml +++ b/pom.xml @@ -1000,7 +1000,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.4 + 3.2.5 sign-artifacts From b7922d4866febea5d27e705842ccdd8b55cbe886 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 25 Aug 2024 12:17:59 +0000 Subject: [PATCH 79/93] Update dependency jsdom to v25 --- client/package-lock.json | 8 ++++---- client/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 09cdf3b18a2..cd4b33385fe 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -37,7 +37,7 @@ "eslint-plugin-react": "7.35.0", "eslint-plugin-react-hooks": "4.6.2", "eslint-plugin-react-refresh": "0.4.9", - "jsdom": "24.1.1", + "jsdom": "25.0.0", "prettier": "3.3.3", "typescript": "5.5.4", "vite": "5.4.1", @@ -8229,9 +8229,9 @@ } }, "node_modules/jsdom": { - "version": "24.1.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", - "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz", + "integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/client/package.json b/client/package.json index 2dcbd623562..ab1abcddacf 100644 --- a/client/package.json +++ b/client/package.json @@ -46,7 +46,7 @@ "eslint-plugin-react": "7.35.0", "eslint-plugin-react-hooks": "4.6.2", "eslint-plugin-react-refresh": "0.4.9", - "jsdom": "24.1.1", + "jsdom": "25.0.0", "prettier": "3.3.3", "typescript": "5.5.4", "vite": "5.4.1", From 1f611b120a98b28b7f164bd9c255511b7b73fb02 Mon Sep 17 00:00:00 2001 From: sharhio Date: Mon, 26 Aug 2024 12:19:04 +0300 Subject: [PATCH 80/93] return allowpickup value for rentalVehicles to avoid showing disabled vehicles on map --- .../mapper/DigitransitRentalVehiclePropertyMapper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java index 33e661866bc..5ef99431475 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java @@ -15,6 +15,7 @@ protected Collection map(VehicleRentalVehicle place) { var items = new ArrayList(); items.addAll(getFeedScopedIdAndNetwork(place)); items.add(new KeyValue("formFactor", place.vehicleType.formFactor.toString())); + items.add(new KeyValue("isAllowPickup", place.isAllowPickup())); return items; } } From aed76c763e2c1c90ae70d99da307839931dbdb90 Mon Sep 17 00:00:00 2001 From: sharhio Date: Mon, 26 Aug 2024 12:33:04 +0300 Subject: [PATCH 81/93] naming --- .../mapper/DigitransitRentalVehiclePropertyMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java index 5ef99431475..00ae4e5ed88 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java @@ -15,7 +15,7 @@ protected Collection map(VehicleRentalVehicle place) { var items = new ArrayList(); items.addAll(getFeedScopedIdAndNetwork(place)); items.add(new KeyValue("formFactor", place.vehicleType.formFactor.toString())); - items.add(new KeyValue("isAllowPickup", place.isAllowPickup())); + items.add(new KeyValue("pickupAllowed", place.isAllowPickup())); return items; } } From 3947581e1d4261c2dd021fbea1c59aefc52b6362 Mon Sep 17 00:00:00 2001 From: sharhio Date: Mon, 26 Aug 2024 12:41:53 +0300 Subject: [PATCH 82/93] test --- .../layers/vehiclerental/mapper/VehicleRentalLayerTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java index 34a8f28f9a4..984d4927041 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/VehicleRentalLayerTest.java @@ -38,6 +38,7 @@ public void floatingVehicle() { assertEquals("A:B", map.get("id")); assertEquals("BICYCLE", map.get("formFactor")); assertEquals("A", map.get("network")); + assertEquals(true, map.get("pickupAllowed")); assertNull(map.get("name")); } From aed7fd2c746c7d38bb97ab37ce331926acbee2ad Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Wed, 28 Aug 2024 10:58:32 +0000 Subject: [PATCH 83/93] Add changelog entry for #5932 [ci skip] --- doc/user/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/user/Changelog.md b/doc/user/Changelog.md index 453e2cc6089..5e93c90b66c 100644 --- a/doc/user/Changelog.md +++ b/doc/user/Changelog.md @@ -56,6 +56,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - SIRI-FM vehicle parking updates [#5979](https://github.com/opentripplanner/OpenTripPlanner/pull/5979) - Take realtime patterns into account when storing realtime vehicles [#5994](https://github.com/opentripplanner/OpenTripPlanner/pull/5994) - Debug client itinerary list style improvements [#6012](https://github.com/opentripplanner/OpenTripPlanner/pull/6012) +- Developer Decision Records [#5932](https://github.com/opentripplanner/OpenTripPlanner/pull/5932) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.5.0 (2024-03-13) From 7ff692cad27f02a77c0fd042ed4c0dfa5b9b54d9 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 28 Aug 2024 14:06:31 +0200 Subject: [PATCH 84/93] doc: Fix broken links in doc. --- ARCHITECTURE.md | 8 ++------ doc/dev/decisionrecords/Codestyle.md | 2 +- doc/dev/decisionrecords/NamingConventions.md | 2 +- doc/dev/decisionrecords/UseDecisionRecords.md | 14 +++++++------- doc/{user => dev}/images/ExternalToolDialog.png | Bin doc/{user => dev}/images/ServiceModelOverview.png | Bin doc/user/Developers-Guide.md | 2 +- doc/user/images/TransitTimeLine.svg | 5 ----- 8 files changed, 12 insertions(+), 21 deletions(-) rename doc/{user => dev}/images/ExternalToolDialog.png (100%) rename doc/{user => dev}/images/ServiceModelOverview.png (100%) delete mode 100644 doc/user/images/TransitTimeLine.svg diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 8df085f3b5d..4bd313c7a06 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -11,7 +11,7 @@ This document is far from complete. Hopefully it can evolve over time and become introduction to OTP architecture. The OTP project GitHub issues are a good place to look for detailed discussions on many design decisions. -We document [Decision Records](DECISION_RECORDS.md) in a log. Make sure you as a developer are familiar +We document [Decision Records](DEVELOPMENT_DECISION_RECORDS.md) in a log. Make sure you as a developer are familiar with the decisions and follow them. Reviewers should use them actively when reviewing code and may use them to ask for changes. @@ -22,7 +22,7 @@ Be sure to also read the [developer documentation](doc/user/Developers-Guide.md) The diagram shows a simplified/generic version on how we want to model the OTP components with 2 examples. The Transit model is more complex than the VehiclePosition model. -![MainModelOverview](doc/user/images/ServiceModelOverview.png) +![MainModelOverview](doc/dev/images/ServiceModelOverview.png) - `Use Case Service` A service which combine the functionality in many `Domain Services` to fulfill a use-case or set of features. It may have an api with request/response classes. These are @@ -45,10 +45,6 @@ but this is a start and we would like to expand this list in the future. The Configuration module is responsible for loading and parsing OTP configuration files and map them into Plan Old Java Objects (POJOs). These POJOs are injected into the other components. -### [REST API](src/main/java/org/opentripplanner/api/package.md) - -Short introduction to the REST API. - ### [GTFS import module](src/main/java/org/opentripplanner/gtfs/package.md) Used to import GTFS transit data files. diff --git a/doc/dev/decisionrecords/Codestyle.md b/doc/dev/decisionrecords/Codestyle.md index 3aa93c86125..f9ffc1a9056 100644 --- a/doc/dev/decisionrecords/Codestyle.md +++ b/doc/dev/decisionrecords/Codestyle.md @@ -58,7 +58,7 @@ Editor > Code Style_. Then select **Project** in the \_Scheme drop down. You can run the Prettier Maven plugin as an external tool in IntelliJ. Set it up as an `External tool` and assign a key-shortcut to the tool execution. -![External Tool Dialog](../../../doc/user/images/ExternalToolDialog.png) +![External Tool Dialog](../images/ExternalToolDialog.png) ``` Name: Prettier Format Current File diff --git a/doc/dev/decisionrecords/NamingConventions.md b/doc/dev/decisionrecords/NamingConventions.md index 3a226fa47ae..ed6175f4f4c 100644 --- a/doc/dev/decisionrecords/NamingConventions.md +++ b/doc/dev/decisionrecords/NamingConventions.md @@ -60,7 +60,7 @@ These prefixes are also "allowed", but not preferred - they have some kind of ne ## Service, Model and Repository -![MainModelOverview](doc/user/images/ServiceModelOverview.png) +![MainModelOverview](../images/ServiceModelOverview.png) diff --git a/doc/dev/decisionrecords/UseDecisionRecords.md b/doc/dev/decisionrecords/UseDecisionRecords.md index 800c8340904..a3520ea5133 100644 --- a/doc/dev/decisionrecords/UseDecisionRecords.md +++ b/doc/dev/decisionrecords/UseDecisionRecords.md @@ -1,9 +1,9 @@ # Decision Records -[TODO - Not precise] An OTP Decision Record is a justified software design choice that addresses a -significant functional or non-functional requirement. [Architectural Decision Records](https://adr.github.io/) -is a similar concept, but we have widened the scope to include any relevant decision about -OTP development. +An OTP Decision Record is a justified software design choice that addresses a significant +functional or non-functional requirement. [Architectural Decision Records](https://adr.github.io/) is a similar +concept, but we have widened the scope to include any relevant decision about OTP development. + ## Process @@ -26,12 +26,12 @@ the decision. - The final approval is done in the developer meeting, at least 3 developers representing 3 different organisations should approve it. No vote against the proposal. If the developers are not able to agree, the PLC can decide. -- References to Architectural Decision Records in reviews can be done by linking or just typing - e.g. `Use-Dependency-Injection` or [Use-Dependency-Injection](/DECISION_RECORDS.md#use-dependency-injection) +- References to Development Decision Records in reviews can be done by linking or just typing. + For example `Use-Dependency-Injection` or [Use-Dependency-Injection](../../../DEVELOPMENT_DECISION_RECORDS.md#use-dependency-injection) ### Checklist - [ ] Give it a meaningful title that quickly lets the reader understand what it is all about. - [ ] Get it approved in a developer meeting with 3 votes in favor (3 organisations). -- [ ] Add the name and description to the list in the [Decision Records](/DECISION_RECORDS.md) list. +- [ ] Add the name and description to the list in the [Development Decision Records](../../../DEVELOPMENT_DECISION_RECORDS.md) list. Maximum two sentences should be used. Try to keep it as short as possible. - [ ] Remember to link to the PR. diff --git a/doc/user/images/ExternalToolDialog.png b/doc/dev/images/ExternalToolDialog.png similarity index 100% rename from doc/user/images/ExternalToolDialog.png rename to doc/dev/images/ExternalToolDialog.png diff --git a/doc/user/images/ServiceModelOverview.png b/doc/dev/images/ServiceModelOverview.png similarity index 100% rename from doc/user/images/ServiceModelOverview.png rename to doc/dev/images/ServiceModelOverview.png diff --git a/doc/user/Developers-Guide.md b/doc/user/Developers-Guide.md index e5ebfdb5e85..368a12edb62 100644 --- a/doc/user/Developers-Guide.md +++ b/doc/user/Developers-Guide.md @@ -206,7 +206,7 @@ that have the code checked out locally. - [Architecture](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/ARCHITECTURE.md) - [Code Conventions](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/CODE_CONVENTIONS.md) - - [Development Decision Records](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/DECISION_RECORDS.md) + - [Development Decision Records](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/DEVELOPMENT_DECISION_RECORDS.md) ## Continuous Integration diff --git a/doc/user/images/TransitTimeLine.svg b/doc/user/images/TransitTimeLine.svg deleted file mode 100644 index 4924b2b3113..00000000000 --- a/doc/user/images/TransitTimeLine.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - Produced by OmniGraffle 6.6.2 2021-02-08 15:47:55 +0000Canvas 1Layer 1Bord-TimeLine 11Line 31Line 21Stop ABoard SlackBoard SlackAlight SlackAlight SlackAlight SlackTransit SlackTransit Slack«Extra Slack»«Extra Slack»Board SlackEarliest-Board-Time(Earliest-)Board-TimeStop BStop CStop DStop EStop-ArrivalStop-ArrivalStop-ArrivalStop-ArrivalStop-ArrivalOriginDestinationWait Time (Duration)Transit DurationWait Time (Duration)Transit DurationAlight-TimeAlight-Time From d2f4b2d086db6a02bc4256258b4f36cdc484863d Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Wed, 28 Aug 2024 18:23:47 +0000 Subject: [PATCH 85/93] Upgrade debug client to version 2024/08/2024-08-28T18:23 --- src/client/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/index.html b/src/client/index.html index 42b2a26d059..dd77abb4b48 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +
          From e6622b89b102518e616d3ca64c8f4467f3a96f3f Mon Sep 17 00:00:00 2001 From: Brede Date: Sun, 1 Sep 2024 21:06:43 +0200 Subject: [PATCH 86/93] Update Data-Sources.md --- doc/user/Data-Sources.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/user/Data-Sources.md b/doc/user/Data-Sources.md index bf426186f57..5ee5fea29d1 100644 --- a/doc/user/Data-Sources.md +++ b/doc/user/Data-Sources.md @@ -4,9 +4,7 @@ At the core of OpenTripPlanner is a library of Java code that finds efficient paths through multi-modal transportation networks built -from [OpenStreetMap](http://wiki.openstreetmap.org/wiki/Main_Page) -and [GTFS](https://developers.google.com/transit/gtfs/) data. It can also receive GTFS-RT (real-time) -data. +from [OpenStreetMap](http://wiki.openstreetmap.org/wiki/Main_Page), [GTFS/GTFS RT](https://gtfs.org/documentation/overview/) and [GBFS](https://gbfs.org/). In addition to GTFS, OTP can also load data in the Nordic Profile of Netex, the EU-standard transit data interchange format. The upcoming EU-wide profile was heavily influenced by the Nordic Profile From 80145706ca2dbb705b33d035ee48b3c1ae098afd Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 1 Sep 2024 22:58:26 +0200 Subject: [PATCH 87/93] Only compute the accessibility score for walking legs --- .../DecorateWithAccessibilityScoreTest.java | 36 +++++++++++++------ .../DecorateWithAccessibilityScore.java | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java b/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java index d70b9f32f62..77e8268bf92 100644 --- a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java @@ -2,20 +2,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; import java.util.List; +import java.util.function.Function; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.FieldSource; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; +import org.opentripplanner.model.plan.TestItineraryBuilder; import org.opentripplanner.routing.api.request.preference.WheelchairPreferences; -public class DecorateWithAccessibilityScoreTest implements PlanTestConstants { +class DecorateWithAccessibilityScoreTest implements PlanTestConstants { private static final int ID = 1; + private static final DecorateWithAccessibilityScore DECORATOR = new DecorateWithAccessibilityScore( + WheelchairPreferences.DEFAULT.maxSlope() + ); static List accessibilityScoreTestCase() { return List.of( @@ -48,17 +55,26 @@ static List accessibilityScoreTestCase() { @ParameterizedTest @MethodSource("accessibilityScoreTestCase") - public void accessibilityScoreTest(Itinerary itinerary, float expectedAccessibilityScore) { - var filter = new DecorateWithAccessibilityScore(WheelchairPreferences.DEFAULT.maxSlope()); - - filter.decorate(itinerary); + void accessibilityScoreTest(Itinerary itinerary, float expectedAccessibilityScore) { + DECORATOR.decorate(itinerary); assertEquals(expectedAccessibilityScore, itinerary.getAccessibilityScore()); - itinerary - .getLegs() - .forEach(l -> { - assertNotNull(l.accessibilityScore()); - }); + itinerary.getLegs().forEach(l -> assertNotNull(l.accessibilityScore())); + } + + private static final List> nonWalkingCases = List.of( + b -> b.bicycle(10, 20, B), + b -> b.drive(10, 20, B), + b -> b.rentedBicycle(10, 20, B) + ); + + @FieldSource("nonWalkingCases") + @ParameterizedTest + void onlyWalking(Function modifier) { + var itinerary = modifier.apply(newItinerary(A, 0)).build(); + DECORATOR.decorate(itinerary); + assertNull(itinerary.getAccessibilityScore()); + itinerary.getLegs().forEach(l -> assertNull(l.accessibilityScore())); } } diff --git a/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java b/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java index 51a138b9f9c..d95f2c4c0cd 100644 --- a/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java +++ b/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java @@ -116,7 +116,7 @@ private Itinerary addAccessibilityScore(Itinerary i) { .map(leg -> { if (leg instanceof ScheduledTransitLeg transitLeg) { return transitLeg.withAccessibilityScore(compute(transitLeg)); - } else if (leg instanceof StreetLeg streetLeg) { + } else if (leg instanceof StreetLeg streetLeg && leg.isWalkingLeg()) { return streetLeg.withAccessibilityScore(compute(streetLeg)); } else { return leg; From 8928178d7f121ee2a2e832fc1c84ba0e05086886 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 2 Sep 2024 10:21:23 +0200 Subject: [PATCH 88/93] Improve test --- .../DecorateWithAccessibilityScoreTest.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java b/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java index 77e8268bf92..27c10c08129 100644 --- a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java @@ -9,7 +9,6 @@ import java.util.function.Function; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.FieldSource; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; @@ -63,15 +62,17 @@ void accessibilityScoreTest(Itinerary itinerary, float expectedAccessibilityScor itinerary.getLegs().forEach(l -> assertNotNull(l.accessibilityScore())); } - private static final List> nonWalkingCases = List.of( - b -> b.bicycle(10, 20, B), - b -> b.drive(10, 20, B), - b -> b.rentedBicycle(10, 20, B) - ); + private static List> nonWalkingCases() { + return List.of( + b -> b.bicycle(10, 20, B), + b -> b.drive(10, 20, B), + b -> b.rentedBicycle(10, 20, B) + ); + } - @FieldSource("nonWalkingCases") + @MethodSource("nonWalkingCases") @ParameterizedTest - void onlyWalking(Function modifier) { + void noScoreForNonWalking(Function modifier) { var itinerary = modifier.apply(newItinerary(A, 0)).build(); DECORATOR.decorate(itinerary); assertNull(itinerary.getAccessibilityScore()); From f3fe10c3e9cc0eebb0ef867ab8ce824b276beb04 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 2 Sep 2024 11:12:27 +0200 Subject: [PATCH 89/93] Update group name [ci skip] --- renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renovate.json5 b/renovate.json5 index 5a56c64cccb..c1807ee1d51 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -136,7 +136,7 @@ }, { "description": "Automerge logging dependencies in a single PR", - "groupName": "logging", + "groupName": "logging dependencies", "matchPackagePrefixes": [ "org.slf4j:", "ch.qos.logback:" From eae71634082ccd9de612f2e1da34330409d16608 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 07:59:06 +0000 Subject: [PATCH 90/93] Update Debug UI dependencies (non-major) --- client/package-lock.json | 351 ++++++++++++++++++++++++--------------- client/package.json | 14 +- 2 files changed, 228 insertions(+), 137 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index cd4b33385fe..4632899b38f 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12,7 +12,7 @@ "bootstrap": "5.3.3", "graphql": "16.9.0", "graphql-request": "7.1.0", - "maplibre-gl": "4.5.2", + "maplibre-gl": "4.6.0", "react": "18.3.1", "react-bootstrap": "2.10.4", "react-dom": "18.3.1", @@ -23,8 +23,8 @@ "@graphql-codegen/client-preset": "4.3.3", "@graphql-codegen/introspection": "4.0.3", "@parcel/watcher": "2.4.1", - "@testing-library/react": "16.0.0", - "@types/react": "18.3.3", + "@testing-library/react": "16.0.1", + "@types/react": "18.3.5", "@types/react-dom": "18.3.0", "@typescript-eslint/eslint-plugin": "7.18.0", "@typescript-eslint/parser": "7.18.0", @@ -32,15 +32,15 @@ "@vitest/coverage-v8": "2.0.5", "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", - "eslint-plugin-import": "2.29.1", + "eslint-plugin-import": "2.30.0", "eslint-plugin-jsx-a11y": "6.9.0", - "eslint-plugin-react": "7.35.0", + "eslint-plugin-react": "7.35.1", "eslint-plugin-react-hooks": "4.6.2", - "eslint-plugin-react-refresh": "0.4.9", + "eslint-plugin-react-refresh": "0.4.11", "jsdom": "25.0.0", "prettier": "3.3.3", "typescript": "5.5.4", - "vite": "5.4.1", + "vite": "5.4.2", "vitest": "2.0.5" } }, @@ -3010,9 +3010,9 @@ } }, "node_modules/@maplibre/maplibre-gl-style-spec": { - "version": "20.3.0", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.3.0.tgz", - "integrity": "sha512-eSiQ3E5LUSxAOY9ABXGyfNhout2iEa6mUxKeaQ9nJ8NL1NuaQYU7zKqzx/LEYcXe1neT4uYAgM1wYZj3fTSXtA==", + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.3.1.tgz", + "integrity": "sha512-5ueL4UDitzVtceQ8J4kY+Px3WK+eZTsmGwha3MBKHKqiHvKrjWWwBCIl1K8BuJSc5OFh83uI8IFNoFvQxX2uUw==", "license": "ISC", "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", @@ -3022,7 +3022,7 @@ "quickselect": "^2.0.0", "rw": "^1.3.3", "sort-object": "^3.0.3", - "tinyqueue": "^2.0.3" + "tinyqueue": "^3.0.0" }, "bin": { "gl-style-format": "dist/gl-style-format.mjs", @@ -3537,174 +3537,236 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", - "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", + "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", - "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", + "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", - "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", + "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", - "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", + "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", - "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", + "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", + "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", - "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", + "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", - "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", + "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", + "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", - "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", + "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", + "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", - "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", + "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", - "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", + "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", - "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", + "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", - "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", + "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", - "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", + "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, "node_modules/@swc/helpers": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.7.tgz", @@ -3734,9 +3796,9 @@ } }, "node_modules/@testing-library/react": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.0.tgz", - "integrity": "sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.1.tgz", + "integrity": "sha512-dSmwJVtJXmku+iocRhWOUFbrERC76TX2Mnf0ATODz8brzAZrMBbzLwQixlBSanZxR6LddK3eiwpSFZgDET1URg==", "dev": true, "license": "MIT", "dependencies": { @@ -3889,9 +3951,9 @@ "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", + "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -6070,10 +6132,11 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", + "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -6096,26 +6159,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", "dev": true, + "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", "tsconfig-paths": "^3.15.0" }, @@ -6131,6 +6196,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6141,6 +6207,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -6150,6 +6217,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -6162,6 +6230,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6245,9 +6314,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.35.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", - "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", + "version": "7.35.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.1.tgz", + "integrity": "sha512-B5ok2JgbaaWn/zXbKCGgKDNL2tsID3Pd/c/yvjcpsd9HQDwyYc/TQv3AZMmOvrJgCs3AnYNUHRCQEMMQAYJ7Yg==", "dev": true, "license": "MIT", "dependencies": { @@ -6290,9 +6359,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.9.tgz", - "integrity": "sha512-QK49YrBAo5CLNLseZ7sZgvgTy21E6NEw22eZqc4teZfH8pxV3yXc9XXOYfUI6JNpw7mfHNkAeWtBxrTyykB6HA==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.11.tgz", + "integrity": "sha512-wrAKxMbVr8qhXTtIKfXqAn5SAtRZt0aXxe5P23Fh4pUAdC6XEsybGLB8P0PI4j1yYqOgUEUlzKAGDfo7rJOjcw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -7062,27 +7131,41 @@ } }, "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "license": "MIT", "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=16" + } + }, + "node_modules/global-prefix/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "engines": { + "node": ">=16" } }, "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "license": "ISC", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "which": "bin/which" + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/globals": { @@ -7533,9 +7616,13 @@ "dev": true }, "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, "node_modules/inquirer": { "version": "8.2.6", @@ -7693,12 +7780,16 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8094,7 +8185,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/isobject": { "version": "3.0.1", @@ -8727,9 +8819,9 @@ } }, "node_modules/maplibre-gl": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.5.2.tgz", - "integrity": "sha512-vlWL9EY2bSGg5FAt0mKPfYqlfX15uLW5D3kKv4Xjn54nIVn01MKdfUJMAVIr+8fXVqfSX6c095Iy5XnV+T76kQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.6.0.tgz", + "integrity": "sha512-zobZK+fE+XM+7K81fk5pSBYWZlTGjGT0P96y2fR4DV2ry35ZBfAd0uWNatll69EgYeE+uOhN1MvEk+z1PCuyOQ==", "license": "BSD-3-Clause", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", @@ -8739,7 +8831,7 @@ "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^1.3.1", "@mapbox/whoots-js": "^3.1.0", - "@maplibre/maplibre-gl-style-spec": "^20.3.0", + "@maplibre/maplibre-gl-style-spec": "^20.3.1", "@types/geojson": "^7946.0.14", "@types/geojson-vt": "3.2.5", "@types/mapbox__point-geometry": "^0.1.4", @@ -8749,7 +8841,7 @@ "earcut": "^3.0.0", "geojson-vt": "^4.0.2", "gl-matrix": "^3.4.3", - "global-prefix": "^3.0.0", + "global-prefix": "^4.0.0", "kdbush": "^4.0.2", "murmurhash-js": "^1.0.0", "pbf": "^3.3.0", @@ -8773,12 +8865,6 @@ "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", "license": "ISC" }, - "node_modules/maplibre-gl/node_modules/tinyqueue": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", - "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", - "license": "ISC" - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -10077,10 +10163,11 @@ } }, "node_modules/rollup": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", - "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -10092,19 +10179,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.13.0", - "@rollup/rollup-android-arm64": "4.13.0", - "@rollup/rollup-darwin-arm64": "4.13.0", - "@rollup/rollup-darwin-x64": "4.13.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", - "@rollup/rollup-linux-arm64-gnu": "4.13.0", - "@rollup/rollup-linux-arm64-musl": "4.13.0", - "@rollup/rollup-linux-riscv64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-musl": "4.13.0", - "@rollup/rollup-win32-arm64-msvc": "4.13.0", - "@rollup/rollup-win32-ia32-msvc": "4.13.0", - "@rollup/rollup-win32-x64-msvc": "4.13.0", + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", "fsevents": "~2.3.2" } }, @@ -10911,9 +11001,10 @@ } }, "node_modules/tinyqueue": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", - "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC" }, "node_modules/tinyrainbow": { "version": "1.2.0", @@ -11400,15 +11491,15 @@ } }, "node_modules/vite": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.1.tgz", - "integrity": "sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz", + "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.41", - "rollup": "^4.13.0" + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" diff --git a/client/package.json b/client/package.json index ab1abcddacf..5b26215fe5f 100644 --- a/client/package.json +++ b/client/package.json @@ -21,7 +21,7 @@ "bootstrap": "5.3.3", "graphql": "16.9.0", "graphql-request": "7.1.0", - "maplibre-gl": "4.5.2", + "maplibre-gl": "4.6.0", "react": "18.3.1", "react-bootstrap": "2.10.4", "react-dom": "18.3.1", @@ -32,8 +32,8 @@ "@graphql-codegen/client-preset": "4.3.3", "@graphql-codegen/introspection": "4.0.3", "@parcel/watcher": "2.4.1", - "@testing-library/react": "16.0.0", - "@types/react": "18.3.3", + "@testing-library/react": "16.0.1", + "@types/react": "18.3.5", "@types/react-dom": "18.3.0", "@typescript-eslint/eslint-plugin": "7.18.0", "@typescript-eslint/parser": "7.18.0", @@ -41,15 +41,15 @@ "@vitest/coverage-v8": "2.0.5", "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", - "eslint-plugin-import": "2.29.1", + "eslint-plugin-import": "2.30.0", "eslint-plugin-jsx-a11y": "6.9.0", - "eslint-plugin-react": "7.35.0", + "eslint-plugin-react": "7.35.1", "eslint-plugin-react-hooks": "4.6.2", - "eslint-plugin-react-refresh": "0.4.9", + "eslint-plugin-react-refresh": "0.4.11", "jsdom": "25.0.0", "prettier": "3.3.3", "typescript": "5.5.4", - "vite": "5.4.1", + "vite": "5.4.2", "vitest": "2.0.5" } } From 690c8ec7f8059c820e1c417ee3da2d3411f33e4b Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Tue, 3 Sep 2024 08:19:36 +0000 Subject: [PATCH 91/93] Upgrade debug client to version 2024/09/2024-09-03T08:18 --- src/client/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/index.html b/src/client/index.html index dd77abb4b48..aa609bb0696 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +
          From c2b3d2c53b9225a5f8ec2248b935ca9b2a1dccdc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 22:46:38 +0000 Subject: [PATCH 92/93] fix(deps): update logging dependencies --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 940d8de5f94..81ecd08210a 100644 --- a/pom.xml +++ b/pom.xml @@ -65,9 +65,9 @@ 5.11.0 1.13.2 5.6.0 - 1.5.6 + 1.5.7 9.11.1 - 2.0.14 + 2.0.16 2.0.15 1.27 4.0.5 From f2d8a1e85cef82ec4e10ccb21359a32d6fd59111 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 10:30:22 +0200 Subject: [PATCH 93/93] Finetune renovate config [ci skip] --- renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renovate.json5 b/renovate.json5 index c1807ee1d51..b672797d48f 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -34,7 +34,7 @@ "matchFiles": ["client/package.json"], "matchUpdateTypes": ["patch", "minor"], "groupName": "Debug UI dependencies (non-major)", - "schedule": ["on the 3rd and 17th day of the month"], + "schedule": ["after 6pm on the 3rd and 17th day of the month"], "reviewers": ["testower"] }, {