Skip to content

Commit 4f563ff

Browse files
authored
Merge pull request #192 from esuomi/refactor_local_dev
Refactor local development environment
2 parents 40f0f69 + 5646f23 commit 4f563ff

File tree

6 files changed

+258
-68
lines changed

6 files changed

+258
-68
lines changed

README.md

Lines changed: 115 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -45,33 +45,115 @@ Tiamat also includes a diff tool. This is used to compare and show the differenc
4545

4646
## Build
4747

48-
`mvn clean install`
48+
```shell
49+
mvn clean install
50+
```
4951

5052
You need the directory `/deployments/data` with rights for the user who
5153
performs the build.
5254

53-
54-
55-
5655
## Integration tests
5756
Tiamat uses testcontainers to run integration tests against a real database. To run Testcontainers-based tests, you need a Docker-API compatible container runtime
5857
for more detail see https://www.testcontainers.org/supported_docker_environment/
5958

6059
(default profiles are set in application.properties)
6160

61+
## Running the service
62+
63+
There are several options for running the service depending on what you need.
64+
65+
- [Run locally for development](#run-locally-for-development) is for people intending to maintain, modify and improve
66+
tiamat's source code
67+
- [Run tiamat with Docker compose](#run-tiamat-with-docker-compose) if you just need to get the service running
68+
- [Run with external properties file and PostgreSQL](#run-with-external-properties-file-and-postgresql) for low
69+
level debugging
70+
71+
> **Note!** Each of these configurations use unique port numbers and such, be sure to read the provided documentation
72+
> and configuration files for more details.
73+
74+
## Run locally for development
75+
76+
Local development is a combination of using Docker Compose based configuration for starting up the supporting
77+
services and running Spring Boot with at least `local` profile enabled.
78+
79+
When running,
80+
81+
- tiamat will be available at `http://localhost:37888`
82+
- PostGIS will be available at `localhost:37432`
83+
84+
### 1. Start Local Environment through Docker Compose
85+
86+
Tiamat has [docker-compose.yml](./docker-compose.yml) which contains all necessary dependent services for running tiamat in
87+
various configurations. It is assumed this environment is always running when the service is being run locally
88+
(see below).
89+
90+
> **Note!** This uses the compose version included with modern versions of Docker, not the separately installable
91+
> `docker-compose` command.
92+
93+
All Docker Compose commands run in relation to the `docker-compose.yml` file located in the same directory in which the
94+
command is executed.
95+
96+
```shell
97+
# run with defaults - use ^C to shutdown containers
98+
docker compose up
99+
# run with additional profiles, e.g. with LocalStack based AWS simulator
100+
docker compose --profile aws up
101+
# run in background
102+
docker compose up -d # or --detach
103+
# shutdown containers
104+
docker compose down
105+
# shutdown containers included in specific profile
106+
docker compose --profile aws down
107+
```
108+
109+
See [Docker Compose reference](https://docs.docker.com/compose/reference/) for more details.
110+
111+
### 2. Run the Service
112+
113+
#### Available Profiles
114+
115+
> **Note!** You must choose at least one of the options from each category below!
116+
117+
> **Note!** `local` profile must always be included!
118+
119+
##### Storage
120+
121+
| profile | description |
122+
|:------------------|--------------------------------------------------|
123+
| `gcs-blobstore` | GCP GCS implementation of tiamat's blob storage |
124+
| `local-blobstore` | Use local directory as backing storage location. |
125+
126+
##### Changelog
127+
128+
| profile | description |
129+
|:------------------|--------------------------------------------------------------------|
130+
| `local-changelog` | Simple local implementation which logs the sent events to `stdout` |
131+
| `activemq` | JMS based ActiveMQ implementation. |
132+
| `google-pubsub` | GCP PubSub implementation for publishing tiamat entity changes. |
133+
134+
#### Run It!
135+
136+
**IntelliJ**: Right-click on `TiamatApplication.java` and choose Run (or Cmd+Shift+F10). Open Run -> Edit
137+
configurations, choose the correct configuration (Spring Boot -> App), and add a comma separated list of desired
138+
profiles (e.g. `local,local-blobstore,activemq`) to Active profiles. Save the configuration.
139+
140+
**Command line**: `mvn spring-boot:run`
141+
62142
## Run tiamat with Docker compose
63143
To run Tiamat with Docker compose, you need to have a docker-compose.yml file. In docker-compose folder you will find a compose.yml file.:
64-
```
144+
145+
```shell
65146
docker compose up
66147
```
148+
67149
This will start Tiamat with PostgreSQL and Hazelcast. and you can access Tiamat on http://localhost:1888 and the database on http://localhost:5433
68150
and graphiql on http://localhost:8777/services/stop_places/graphql , At start up tiamat copy empty schema to the database. Spring properties are set in application.properties.
69151
Security is disabled in this setup.
70152

71153
## Run with external properties file and PostgreSQL
72-
To run with PostgreSQL you ned an external application.properties.
73-
Below is an example of application.properties:
74-
```
154+
To run with PostgreSQL you need an external `application.properties`. Below is an example of `application.properties`:
155+
156+
```properties
75157
spring.jpa.database=POSTGRESQL
76158
spring.datasource.platform=postgres
77159
spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor=org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
@@ -82,13 +164,11 @@ spring.http.gzip.enabled=true
82164

83165
#spring.jpa.properties.hibernate.format_sql=true
84166

85-
86167
spring.jpa.properties.hibernate.order_updates=true
87168
spring.jpa.properties.hibernate.batch_versioned_data=true
88169

89170
spring.flyway.enabled=true
90-
spring.flyway.table =schema_version
91-
171+
spring.flyway.table=schema_version
92172

93173
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
94174

@@ -112,39 +192,30 @@ spring.jpa.properties.hibernate.jdbc.batch_size=20
112192
spring.jpa.properties.hibernate.default_batch_fetch_size=16
113193
spring.jpa.properties.hibernate.generate_statistics=false
114194

115-
116-
117195
changelog.publish.enabled=false
118196

119-
120197
jettyMaxThreads=10
121198
jettyMinThreads=1
122199

123200
spring.datasource.hikari.maximumPoolSize=40
124201
spring.datasource.hikari.leakDetectionThreshold=30000
125202

126-
127-
128203
tiamat.locals.language.default=eng
129204

130205
tariffZoneLookupService.resetReferences=true
131206

132-
133-
debug=true
207+
debug=true
134208

135209
# Disable feature detection by this undocumented parameter. Check the org.hibernate.engine.jdbc.internal.JdbcServiceImpl.configure method for more details.
136210
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
137211

138212
# Because detection is disabled you have to set correct dialect by hand.
139213
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
140214

141-
142215
tariffzoneLookupService.resetReferences=true
143216

144-
145217
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect
146218

147-
148219
spring.database.driverClassName=org.postgresql.Driver
149220
spring.datasource.url=jdbc:postgresql://localhost:5436/tiamat
150221
spring.datasource.username=tiamat
@@ -157,15 +228,10 @@ tiamat.oauth2.resourceserver.auth0.ror.claim.namespace=role_assignments
157228

158229
spring.cloud.gcp.pubsub.enabled=false
159230

160-
161-
162-
163231
aspect.enabled=true
164232

165233
netex.id.valid.prefix.list={TopographicPlace:{'KVE','WOF','OSM','ENT','LAN'},TariffZone:{'*'},FareZone:{'*'},GroupOfTariffZones:{'*'}}
166234

167-
168-
169235
server.port=1888
170236

171237
blobstore.gcs.blob.path=exports
@@ -178,26 +244,14 @@ management.security.enabled=false
178244
authorization.enabled = true
179245
rutebanken.kubernetes.enabled=false
180246

181-
182-
183-
184-
185-
186247
async.export.path=/tmp
187248

188-
189249
publicationDeliveryUnmarshaller.validateAgainstSchema=false
190250
publicationDeliveryStreamingOutput.validateAgainstSchema=false
191251
netex.validPrefix=NSR
192252
netex.profile.version=1.12:NO-NeTEx-stops:1.4
193253
blobstore.local.folder=/tmp/local-gcs-storage/tiamat/export
194254
spring.profiles.active=local-blobstore,activemq
195-
196-
197-
198-
199-
200-
201255
```
202256

203257
To start Tiamat with this configuration, specify **spring.config.location**:
@@ -210,13 +264,6 @@ To start Tiamat with this configuration, specify **spring.config.location**:
210264
Tiamat is using HikariCP. Most properties should be be possible to be specified in in application.properties, like `spring.datasource.initializationFailFast=false`. More information here. https://github.com/brettwooldridge/HikariCP/wiki/Configuration
211265
See also http://stackoverflow.com/a/26514779
212266

213-
### Postgres
214-
215-
#### Run postgres/gis for tiamat in docker for development
216-
```
217-
docker run -it -d -p 5435:5432 --name postgress-13 -e POSTGRES_USER=tiamat -e POSTGRES_PASSWORD="tiamat" -e POSTGRES_INITDB_ARGS="-d" postgis/postgis:13-master
218-
```
219-
220267
## ID Generation
221268
### Background
222269
During the implementation of Tiamat was desirable to produce NeTEx IDs for stop places more or less gap less.
@@ -240,7 +287,7 @@ A detailed guide on how to setup Keycloak can be found [here](./Keycloak_Setup_G
240287

241288
It is possible to configure if tiamat should validate incoming and outgoing NeTEx xml when unmarshalling or marshalling publication deliveries.
242289
Default values are true. Can be deactivated with setting properties to false.
243-
```
290+
```properties
244291
publicationDeliveryStreamingOutput.validateAgainstSchema=false
245292
publicationDeliveryUnmarshaller.validateAgainstSchema=true
246293
```
@@ -250,45 +297,45 @@ It is possible to export stop places and topographic places directly to NeTEx fo
250297
https://api.dev.entur.io/stop-places/v1/netex
251298

252299
### Query by name example:
253-
```
254-
https://api.dev.entur.io/stop-places/v1/netex?q=Arne%20Garborgs%20vei
300+
```http request
301+
GET https://api.dev.entur.io/stop-places/v1/netex?q=Arne%20Garborgs%20vei
255302
```
256303

257304
### Query by ids that contains the number 3115
258-
```
259-
https://api.dev.entur.io/stop-places/v1/netex?q=3115
260-
```
305+
```http request
306+
GET https://api.dev.entur.io/stop-places/v1/netex?q=3115
307+
```
261308

262309
### Query by stop place type
263-
```
264-
https://api.dev.entur.io/stop-places/v1/netex?stopPlaceType=RAIL_STATION
310+
```http request
311+
GET https://api.dev.entur.io/stop-places/v1/netex?stopPlaceType=RAIL_STATION
265312
```
266313
It is also possible with multiple types.
267314

268315
### Query by municipality ID
269-
```
270-
https://api.dev.entur.io/stop-places/v1/netex?municipalityReference=KVE:TopographicPlace:1003
316+
```http request
317+
GET https://api.dev.entur.io/stop-places/v1/netex?municipalityReference=KVE:TopographicPlace:1003
271318
```
272319

273320
### Query by county ID
274-
```
275-
https://api.dev.entur.io/stop-places/v1/netex?countyReference=KVE:TopographicPlace:11
321+
```http request
322+
GET https://api.dev.entur.io/stop-places/v1/netex?countyReference=KVE:TopographicPlace:11
276323
```
277324

278325
### Limit size of results
279-
```
280-
https://api.dev.entur.io/stop-places/v1/netex?size=1000
326+
```http request
327+
GET https://api.dev.entur.io/stop-places/v1/netex?size=1000
281328
```
282329

283330
### Page
284-
```
285-
https://api.dev.entur.io/stop-places/v1/netex?page=1
331+
```http request
332+
GET https://api.dev.entur.io/stop-places/v1/netex?page=1
286333
```
287334

288335
### ID list
289336
You can specify a list of NSR stop place IDs to return
290-
```
291-
https://api.dev.entur.io/stop-places/v1/netex?idList=NSR:StopPlace:3378&idList=NSR:StopPlace:123
337+
```http request
338+
GET https://api.dev.entur.io/stop-places/v1/netex?idList=NSR:StopPlace:3378&idList=NSR:StopPlace:123
292339
```
293340

294341
### All Versions
@@ -375,17 +422,18 @@ This NeTEx file should not contain NSR ID. (The NSR prefix is configurable in th
375422

376423
Tiamat will return the modified NeTEx structure with it's own NSR IDs. Original IDs will be present in key value list on each object.
377424

378-
```
379-
curl -XPOST -H"Content-Type: application/xml" -d@my-nice-netex-file.xml http://localhost:1997/services/stop_places/netex
425+
```shell
426+
curl -XPOST -H"Content-Type: application/xml" -d@my-nice-netex-file.xml http://localhost:1997/services/stop_places/netex
380427
```
381428

382429
### Importing with importType=INITIAL
383430

384431
When importing with _importType=INITIAL_, a parallel stream will be created, spawning the original process. During import, user authorizations is checked, thus accessing SecurityContextHolder.
385432
By default, SecurityContextHolder use DEFAULT\_LOCAL\_STRATEGY. When using INITIAL importType, you should tell Spring to use MODE\_INHERITABLETHREADLOCAL for SecurityContextHolder, allowing Spring to duplicate Security Context in spawned threads.
386433
This can be done setting env variable :
387-
388-
-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL
434+
```shell
435+
-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL
436+
```
389437

390438
If not, the application may complain about user not being authenticated if Spring tries to check authorization in a spawned process
391439

docker-compose.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: 'tiamat'
2+
3+
services:
4+
db:
5+
container_name: '${COMPOSE_PROJECT_NAME}_postgis13'
6+
image: 'postgis/postgis:13-master'
7+
hostname: postgres
8+
platform: linux/amd64
9+
restart: always
10+
environment:
11+
POSTGRES_USER: tiamat
12+
POSTGRES_PASSWORD: tiamat
13+
POSTGRES_HOST: postgres
14+
ports:
15+
- "37432:5432"
16+
volumes:
17+
- postgres-data:/var/lib/postgresql
18+
networks:
19+
- tiamat-net
20+
21+
volumes:
22+
postgres-data:
23+
24+
networks:
25+
tiamat-net:

pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,9 @@
429429
<artifactId>spring-boot-maven-plugin</artifactId>
430430
<configuration>
431431
<mainClass>org.rutebanken.tiamat.TiamatApplication</mainClass>
432+
<profiles>
433+
<profile>local,local-blobstore,local-changelog</profile>
434+
</profiles>
432435
</configuration>
433436
<executions>
434437
<execution>

src/main/java/org/rutebanken/tiamat/changelog/EntityChangedEventLocalPublisher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
@Component
2727
@Transactional
28-
@Profile("test")
28+
@Profile("local-changelog | test")
2929
public class EntityChangedEventLocalPublisher extends EntityChangedEventPublisher implements EntityChangedListener {
3030
public static final Logger logger = LoggerFactory.getLogger(EntityChangedEventLocalPublisher.class);
3131

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.rutebanken.tiamat.changelog;
2+
3+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
4+
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
5+
import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration;
6+
import org.springframework.context.annotation.Configuration;
7+
import org.springframework.context.annotation.Profile;
8+
9+
/**
10+
* This configuration disables conflicting autoconfiguration used by other variants of the changelog feature.
11+
*/
12+
@Configuration
13+
@EnableAutoConfiguration(exclude = {JmsAutoConfiguration.class, ActiveMQAutoConfiguration.class})
14+
@Profile("local-changelog")
15+
public class LocalChangelogConfiguration {
16+
// intentionally left blank
17+
}

0 commit comments

Comments
 (0)