This section will walk you through the many options of how to setup and operate FactCast.
This the multi-page printable view of this section. Click here to print.
Setup
- 1: Prerequisites
- 2: fat-jar
- 3: fat-jar (TLS)
- 4: Ports
- 5: Security
- 6: gRPC Client
- 6.1: gRPC BasicAuth
- 6.2: gRPC KeepAlive
- 6.3: gRPC Resilience
- 7: Compression
- 8: Properties
- 9: Docker
1 - Prerequisites
Postgres
In order to run the FactCast server, you have to provide a Postgres database at least in version 15. The following example shows the configuration with one user.
spring.datasource.username="user" //that user has to be provided
spring.datasource.password="password"
The user has to be a superuser, as he will also install Postgres modules like uuid-ossp.
If you don’t want to provide a superuser
If you don’t want to provide a superuser, you have to consider the following points:
1.) The database user needs at least the permission to query the pg_roles view. According to the documentation it’s publicly accessible, so that shouldn’t be a problem.
2.) The FactCast needs the Postgres module uuid-ossp. You have to install that module manually. The server will recognize the already installed module and it won’t throw an error caused by missing privileges. Login into your Postgres console and execute the following command as superuser:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
2 - fat-jar
Building
First of all, build factcast completely if not yet done by running
mvn install
In order to run a simple example FactCast server, you could enter the project factcast-examples/factcast-example-server and run
mvn spring-boot:run
or run it in your IDE. Note that it will use TestContainer to start an ephemeral postgres instance for you. That means, you need to have a runnable Docker installed on your machine.
In case you want to use your local Postgres instead, take a look at ExampleServerWithPostgresContainer to find out how what is necessary to use a pgsql. After all, this is just a very simple Spring Boot application using JDBC.
As expected, running
mvn package
will create a standard spring boot fat jar target/factcast.jar
that can be run instantly.
3 - fat-jar (TLS)
Non-Encrypted
In order to run a simple example FactCast server, you could enter the project factcast-examples/factcast-example-server, see fatjar
TLS Server
There is an extra example project that demonstrates the usage of TLS for your server that can be found factcast-example-tls-server
We tried to stick as close as possible to what we have in factcast-examples/factcast-example-server to demonstrate the necessary changes and nothing more.
Obviously, for running a TLS Server, you need a certificate. We packaged a snakeoil localhost certificate for you to test. This cert can be found in src/etc/certificates/. In order to create your own selfsigned certificate, there is a shell script you can use as a starting point.
obviously, you should use proper trusted certificates when you run FactCast in production - you have been warned
In order to run the TLS Server, go to factcast-examples/factcast-example-tls-server and run
mvn spring-boot:run
4 - Ports
The default TCP-Port exposed is 9090. As usual, you can set it via environment variables.
Standard ports used:
Port | Protocol | Component | Property |
---|---|---|---|
9090 | HTTP2 | factcast-server-grpc | grpc.server.port (for the bind address: grpc.server.host, defaults to 0.0.0.0) |
5 - Security
Authentication & Authorization
In order to control access the FactCast Server supports a very basic way of defining which client is allowed to do what.
The security feature is enabled by default, but can be disabled (for integration tests for example) by
setting factcast.security.enabled
to false.
In order to make use of the security features, a Bean of type FactCastAccessConfig
must be defined. This is done
either by providing one
in your FactCast Server’s context, or by using the dead-simple approach to put a factcast-access.json
on the root of
your classpath or at /config/
to deserialize it from there.
Example below.
Now, that you’ve defined the access configuration, you also need to define the secrets for each account. Again, you can do that programmatically by providing a FactCastSecretsProperties, or by defining a property for each account like this:
factcast.access.secrets.brain=world
factcast.access.secrets.pinky=narf
factcast.access.secrets.snowball=grim
The catch with this simple approach of course is, that credentials are stored in plaintext in the server’s classpath, but remember it is just a dead-simple approach to get you started. Nobody says, that you cannot provide this information with a layer of your docker container, pull it from the AWS Parameter Store etc…
If FactCast misses a secret for a configured account on startup, it will stop immediately. On the other hand, if there is a secret defined for a non-existing account, this is just logged (WARNING-Level).
The contents of factcast-access.json might look like:
{
"accounts": [
{
"id": "brain",
"roles": ["anything"]
},
{
"id": "pinky",
"roles": ["anything", "limited"]
},
{
"id": "snowball",
"roles": ["readOnlyWithoutAudit"]
}
],
"roles": [
{
"id": "anything",
"read": {
"include": ["*"]
},
"write": {
"include": ["*"]
}
},
{
"id": "limited",
"read": {
"include": ["*"],
"exclude": ["secret"]
},
"write": {
"exclude": ["audit*"]
}
},
{
"id": "readOnlyWithoutAudit",
"read": {
"include": ["*"],
"exclude": ["audit*", "secret"]
},
"write": {
"exclude": ["*"]
}
}
]
}
Where pinky
& brain
are authorized to use the full FactStore’s functionality (with ‘pinky’ not being able to write
to namespaces that start with ‘audit’) whereas snowball
can only read everything but ‘audit’-namespaces, but not write
anything.
In case of conflicting information:
- explicit wins over implicit
- exclude wins over include
Note, there is no fancy wildcard handling other than a trailing ‘*’.
see module examples/factcast-example-server-basicauth for an example
Using BasicAuth from a client
From a client’s perspective, all you need to do is to provide credentials. Once the credentials are configured, they are used on every request in a Basic-Auth fashion (added header to request).
factcast.grpc.client.user
and factcast.grpc.client.password
are the properties to set.
You can always use environment variables or a -D
switch in order to inject the credentials.
see module examples/factcast-example-client-basicauth for an example
Customizing Credential Loading
If you dont want to configure your passwords via properties, you can provide either a custom FactCastSecretProperties
bean or an implementation of a UserDetailsService
.
That’s a simple interface coming from Spring Security which provides a mapping method from username
to user. In our
case we have to return a FactCastUser
.
If you want to externalize secret loading but want to keep the factcast-access.json
file for managing authorization an
implementation of such a UserDetailsService
could look like this:
@Bean
UserDetailsService userDetailsService(FactCastAccessConfiguration cc, PasswordEncoder passwordEncoder) {
return username -> {
// fetching account info from fact-access.json
Optional<FactCastAccount> account = cc.findAccountById(username);
// your way to fetch the user + password
User user = loadUserByName(username);
return account
.map(acc -> new FactCastUser(acc, passwordEncoder.encode(user.getPassword())))
.orElseThrow(() -> new UsernameNotFoundException(username));
};
}
6 - gRPC Client
GRPC Clients
In order to talk to a - not in process - factstore (which is the usual setup for non-test applications), GRPC is the communication protocol used.
Using FactCast client in Spring boot via GRPC
If you use Spring take the easy path in your Spring Boot Application by adding the appropriate dependencies to your application:
<dependency>
<groupId>org.factcast</groupId>
<artifactId>factcast-client-grpc</artifactId>
</dependency>
<dependency>
<groupId>org.factcast</groupId>
<artifactId>factcast-spring-boot-autoconfigure</artifactId>
</dependency>
There are example projects: factcast-examples/factcast-example-client-spring-boot2 and factcast-examples/factcast-example-client-spring-boot1 respectively, that you can use as a template.
Note that factcast-client-grpc is built on top of (https://github.com/yidongnan/grpc-spring-boot-starter). If you are looking for the basic configuration properties, that is where you can find the latest version.
At the time of writing, the most relevant are:
Name | Example Value | required |
---|---|---|
grpc.client.factstore.address | static://localhost:9090 | yes |
grpc.client.factstore.negotiationType | PLAINTEXT | no |
grpc.client.factstore.enable-keep-alive | true | no |
6.1 - gRPC BasicAuth
Using BasicAuth from a client
From a client’s perspective, all you need to do is to provide credentials. Once the credentials are configured, they are used on every request in a Basic-Auth fashion (added header to request).
In order to define credentials, just set the appropriate property to a value of the format ‘username:password’, just as you would type them into your browser when a basic-auth popup appears.
# if this property is set with a value of the format 'username:password', basicauth will be used.
grpc.client.factstore.credentials=myUserName:mySecretPassword
You can always use environment variables or a -D
switch in order to inject the credentials.
see module examples/factcast-example-client-basicauth for an example
6.2 - gRPC KeepAlive
keep-alive settings
Here are some good settings for an initial configuration of a SpringBoot FactCast client/server setup in case you ran into gRPC related client server communication troubles.
Sending keep-alive HTTP/2 PINGs on the connection is useful in case you are running on infrastructure that doesn’t support configurable idle timeouts, and therefore closes connections.
The proposed values are defining a scenario where the client sends keep-alive HTTP/2 PINGs every 300s and the server accepts this behavior without sending
GO_AWAY ENHANCE_YOUR_CALM
to the client. Please adapt to your specific needs.
Client side
Property | Description | Recommended | Default |
---|---|---|---|
grpc.client.factstore.enable-keep-alive | Configures whether keepAlive should be enabled. | true | false |
grpc.client.factstore.keep-alive-time | The default delay before sending keepAlives. Please note that shorter intervals increase the network burden for the server. | 300 | 60 |
grpc.client.factstore.keep-alive-without-calls | Configures whether keepAlive will be performed when there are no outstanding RPCs on a connection. | true | false |
Further details can be found here : net.devh.boot.grpc.client.config.GrpcChannelProperties
.
Server side
Property | Description | Recommended | Default |
---|---|---|---|
grpc.server.permit-keep-alive-without-calls | Configures whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the connection. | true | false |
grpc.server.permit-keep-alive-time | Specifies the most aggressive keep-alive time in seconds clients are permitted to configure. | 100 | 300 |
Further details can be found here : net.devh.boot.grpc.server.config.GrpcServerProperties
.
6.3 - gRPC Resilience
Resilience approach
In order to make it easier for clients to deal with errors, we try to mitigate connection or network errors, or RetryableExceptions in general by just retrying. There are two types of gRPC communications within the FactCast gRPC API:
- synchronous, request / response
- asynchronous, request / streaming response
While the first can be mitigated easily by retrying the call, things get more complicated in an asynchronous, streaming scenario. Imagine a subscription to particular facts (let’s say 10) from scratch, where after 5 successfully received facts the network connection fails. Now simply retrying would mean to receive those 5 facts again, which is not only wasteful, but also hard to handle, as you’d need to skip those rather than process them a second time. Here the FactCast gRPC client keeps track of the facts successfully processed and resubscribes to the ones missing. In this example, it’ll try to subscribe to the same factstream but starting after the fifth fact.
Resilience is supposed to “just work” and let you deal with just the non-transient errors. This is why it is enabled by default with sane defaults.
If you want to disable it completely for any reason, you always can use
factcast.grpc.client.resilience.enabled=false
See properties for the defaults.
7 - Compression
Why ?
Wherever there is network communication, the question of compression comes up. The FactCast server currently supports three compressors out of the box:
- LZ4
- Snappy
- GZip
Unfortunately, GRPC does not support stream-compression, but only message-compression. This means that the efficiency of the compression is dependent on the message size. We’ll get to that…
Client chooses
In order to agree on which compressor to use, there is an initial handshake when the client connects to the server, in which the available compressors on client and server are compared, and the server selects the one to use.
The server send a list of what he accepts, and the client picks his favorite compressor out of that list in the order shown above (LZ4 first, then snappy, GZip as a fallback).
As the client should be low on dependencies and assumptions, Gzip (as supported by the JDK) is the default compressor every client supports.
In order to prefer snappy or LZ4, you’d need to add one or both of the following dependencies (or later versions) to your client and server. Once they are on the classpath on both sides, the client will pick them up automatically, and the server will prefer them over GZip. It is advised, that you use as many codecs as you possibly want to support in the server, and just the preferred one on the client side.
For obvious reasons, extra dependencies to factcast-grpc-myCompressionAlgorithm
may bring new transitive dependencies
(like commons-compress
or net.jpountz
for example). As always: please check for potential conflicts.
<dependency>
<groupId>org.factcast</groupId>
<artifactId>factcast-grpc-lz4</artifactId>
<version>${factcast.version}</version>
</dependency>
<dependency>
<groupId>org.factcast</groupId>
<artifactId>factcast-grpc-snappy</artifactId>
<version>${factcast.version}</version>
</dependency>
For versions before 0.7.9 the respective dependencies were
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.1.8.4</version>
</dependency>
<dependency>
<groupId>net.jpountz.lz4</groupId>
<artifactId>lz4</artifactId>
<version>1.3.0</version>
</dependency>
org.xerial.snappy
and net.jpountz.lz4
are deprecated now and will be removed in 0.8.
Compressor efficiency
As there currently is no stream-compression in GRPC, the server compresses each message transferred to the client separately. The smaller this message is, the less efficient the compression can be. For this reason it is important (during the catchup phase, where you expect a lot of messages) to allow the server to bundle facts into a batch that it will compress and send as one message. The default maximum message size is 3.5MB, but it can be configured up to 32MB.
See factcast.grpc.client.max-inbound-message-size
In the follow phase, this setting is not important, as you don’t want to wait for your batch to fill up before you receive the latest publications from the server. Latency is more important than compression efficiency in that case.
8 - Properties
Schemaregistry
Property | Description | Default |
---|---|---|
factcast.store.schemaRegistryUrl | if a schemaRegistryUrl is defined, FactCast goes into validating mode. The only protocols allowed here are “http”, “https”, “classpath” and “file”. Note that http(s) and file always require two slashes after the colon, e.g. “https://someserver/…” or “file:///root/folder/…”. | |
factcast.store.validationEnabled | Can be used for disabling Fact validation if a schemaRegistryUrl is defined. Useful for mass data ingestion. | true |
factcast.store.persistentRegistry | if fetched Schema and Transformation Documents are persisted into Postgres | false |
factcast.store.allowUnvalidatedPublish | If validation is enabled, this controls if publishing facts, that are not validatable (due to missing meta-data or due to missing schema in the registry) are allowed to be published or should be rejected. | false |
factcast.store.schemaStoreRefreshCron | defines the cron schedule for refreshing the SchemaRegistry by querying for the latest remote changes | */60 * * * * * |
factcast.store.allowSchemaReplace | If a schema can be replaced by an updated version from the registry (not a good idea in production environments) | false |
Transformation-Registry
Property | Description | Default |
---|---|---|
factcast.store.persistentTransformationCache | if Transformed Fact payloads are persistently cached into Postgres | false |
factcast.store.inMemTransformationCacheCapacity | when using the inmem impl of the transformation cache, this is the max number of entries cached. The minimum value here is 100. | 100 |
factcast.store.deleteTransformationsStaleForDays | when using the persistent impl of the transformation cache, this is the min number of days a transformation result is not read in order to be considered stale. This should free some space in a regular cleanup job. Must be a positive number. | 14 |
factcast.store.transformationCacheCompactCron | defines the cron schedule for compacting the transformation result cache | 0 0 0 * * * (at midnight) |
Performance / Reliability
Property | Description | Default |
---|---|---|
factcast.store.factNotificationBlockingWaitTimeInMillis | Controls how long to block waiting for new notifications from the database (Postgres LISTEN/ NOTIFY mechanism). When this time exceeds the notifications is repeated. Minimum value is 5000. | 15000 (15sec) |
factcast.store.factNotificationMaxRoundTripLatencyInMillis | When FactCast did not receive any notifications after factNotificationBlockingWaitTimeInMillis milliseconds it validates the health of the database connection. For this purpose it sends an internal notification to the database and waits for the given time to receive back an answer. If the time is exceeded the database connection is renewed. Minimum value is 50. | 200 |
factcast.store.factNotificationNewConnectionWaitTimeInMillis | how much time to wait between invalidating and acquiring a new connection. note: This parameter is only applied in the part of FactCast which deals with receiving and forwarding database notifications. Minimum value is 10. | 100 |
factcast.store.page-size | How many Facts to fetch from the database in one go. Higher values mean more memory usage. Must be positive. | 50 |
factcast.store.indexCheckCron | Cron expression defining a routine check for index validity | 0 0 3 * * * (3 am) |
factcast.store.tailIndexingEnabled | enable/ disable tail indexing | false |
factcast.store.tailManagementCron | cron schedule when tail rotation should be carried out | 0 0 0 * * * |
factcast.store.tailGenerationsToKeep | the number of tail indexes to keep. The higher the number, the slower the inserts. Probably 2 or 3 is a good value unless you have a very high tail rebuild frequency and not permanently connected applications (like offline clients for instance). Must be a positive number, maximum is 128. | 3 |
factcast.store.minimumTailAge | minimum age of the youngest tail index, before a new one is created | 7 days |
factcast.store.tailCreationTimeout | Index creation can hang for a long time in case of many open transactions. To avoid this, you can specify a timeout. We will subtract 5 seconds from the given duration before applying it to setTimeout. | 1d |
factcast.store.transformationCachePageSize | Defines the max number of Facts being scheduled for transformation in one go. Must be positive and not exceed 32000. | |
factcast.store.sizeOfThreadPoolForSubscriptions | This is the number of threads we create for handling new subscriptions requests. It’s implemented via a fixed thread pool. As soon as the subscription request finishes or enters phase 3 (follow) the thread is freed up again. In earlier versions we used the common FJP which limits the parallelism to the number of cores - 1. If you ever encounter too much database load or too high waiting time for subscriptions this can be an option. | |
factcast.store.sizeOfThreadPoolForBufferedTransformations | This is the number of threads we create for handling buffered transformations. It’s implemented via work stealing thread pool. In early versions we used the common FJP which limits the parallelism to the number of cores - 1. | |
factcast.store.readOnlyModeEnabled | Configures FactCast to work in read-only mode. You cannot publish any events in this mode and certain functionality like tail index generation or state token generation is disabled. You can still use a persistent schema store or transformation cache, however they will work in read-only mode. Additionally, liquibase is disabled. | false |
factcast.store.enumerationDirectModeEnabled | Despite of a Schema-Registry being defined or not, if set to true, enumeration of types or namespace will examine the data in the store directly, so that you only see data from already published facts. | false |
Snapshots
InMem-Snapshots
Property | Description | Default |
---|---|---|
factcast.snapshot.local.mem.deleteSnapshotStaleForDays | min number of days a snapshot is kept even though it is not read anymore. Must be a positive number. | 90 |
InMemAndDisk-Snapshots
Property | Description | Default |
---|---|---|
factcast.snapshot.local.disk.pathToSnapshots | path to store the snapshots in the file system. | java.io.tmpdir |
factcast.snapshot.local.disk.maxDiskSpace | max disk space to be used by the SnapshotDiskRepository. The oldest Snapshots will start to be removed after reaching 90% of the allocated space, never reaching 100%. Use 0 for unlimited disk space | 0 |
RedisSnapshots
Property | Description | Default |
---|---|---|
factcast.snapshot.redis.deleteSnapshotStaleForDays | min number of days a snapshot is kept even though it is not read anymore. Must be a positive number. | 90 |
factcast.snapshot.redis.snapshotCacheRedissonCodec | optional configuration of the codec used for serializing objects from and into the snapshot. When set to RedissonDefault | MarshallingCodec |
JDBC-Snapshots
Property | Description | Default |
---|---|---|
factcast.snapshot.jdbc.deleteSnapshotStaleForDays | min number of days a snapshot is kept even though it is not read anymore. Must be a positive number. | 90 |
factcast.snapshot.jdbc.snapshotTableName | optional name of the table for the snapshots. When not provided the default will be used | factcast_snapshot |
Snapshot Serializers
Property | Description | Default |
---|---|---|
factcast.factus.snapshot.compress | Compress serialized snapshots before sending them to the snapshot-cache | true |
gRPC
Properties you can use to configure gRPC:
gRPC Client
Property | Description | Default | Example |
---|---|---|---|
grpc.client.factstore.credentials | Deprecated. Please use factcast.grpc.client.user and factcast.grpc.client.password instead | none | myUserName:mySecretPassword |
grpc.client.factstore.address | the address(es) fo the factcast server | none | static://localhost:9090 |
grpc.client.factstore.negotiationType | Usage of TLS or Plaintext? | TLS | PLAINTEXT |
grpc.client.factstore.enable-keep-alive | Configures whether keepAlive should be enabled. Recommended for long running (follow) subscriptions | false | true |
grpc.client.factstore.keep-alive-time | The default delay before sending keepAlives. Defaults to 60s. Please note that shorter intervals increase the network burden for the server. | 300 | |
grpc.client.factstore.keep-alive-without-calls | Configures whether keepAlive will be performed when there are no outstanding RPCs on a connection. | false | true |
gRPC Client recommended settings
grpc.client.factstore.enable-keep-alive=true
grpc.client.factstore.keep-alive-time=300
grpc.client.factstore.keep-alive-without-calls=true
Further details can be found here : net.devh.boot.grpc.client.config.GrpcChannelProperties
.
FactCast client specific
Property | Description | Default | Example |
---|---|---|---|
factcast.grpc.client.id | Server-side logging mentions this optional id if set in order to help with debugging. If this property is not set, it falls back to the value of spring.application.name | ${spring.application.name} | myClient |
factcast.grpc.client.user | User if factcast-security is enabled. | myUser | |
factcast.grpc.client.password | Password if factcast-security is enabled. | myPassword | |
factcast.grpc.client.enable-fast-forward | If the server supports it, enables fast forwarding. This is supposed to speedup frequent queries that cluster around the end of the global Fact-Stream and thus can use dedicated temporary rolling indexes. | true | false |
factcast.grpc.client.max-inbound-message-size | The GRPC server will chunk messages to not exceed this. Note that one message might contain up to 1000 facts. This value disregards compression. The maximum for this value is 32MB, the minimum is 2 MB. Note that this also limits the maximum transaction bulk size. | 3682304 | 16m |
factcast.grpc.client.resilience.enabled | Enables resilience mode for subscriptions. If enabled, subscriptions that fail due to networking errors will be transparently resubscribed. (since 0.5.5) | true | false |
factcast.grpc.client.resilience.window | Defines the window in which a maximum of retries is defined. (since 0.5.5) | PT30S (30 seconds) | PT2M (2 Minutes) |
factcast.grpc.client.resilience.attempts | Defines the maximum number of attempts that will be done (within a time window defined by resilience.window) before failing and escalating the last exception to the application. (since 0.5.5) | 10 | 25 |
factcast.grpc.client.resilience.interval | Defines the wait time between two attempts. (since 0.5.5) | PT0.1S (100 millis) | PT0.5S |
factcast.grpc.client.ignore-duplicate-facts | Ignores and skips duplicate exceptions during publishing (does not include conditional publishing when using locks). This might be convenient in cases where you published to a factcast server and get a connection error back (you cannot possibly know if the publish on the server succeeded or not). If you have resilience enabled, the publish would be retried and might (if the first was successful) result in a DuplicateFactException. Setting this to true will make factcast just ignore the exception and go on. There might be a performance problem resulting from this: If you publish a batch of facts and a DuplicateFactException is recieved, factcast will fall back to publishing every single Fact from the batch one-by-one in order to make sure, that after your call, all Facts that are not duplicates will be published. | false | true |
grpc Server
Property | Description | Default | Example |
---|---|---|---|
grpc.server.permit-keep-alive-without-calls | Configures whether clients are allowed to send keep-alive HTTP/2 PINGs even if there are no outstanding RPCs on the connection | false | true |
grpc.server.permit-keep-alive-time | Specifies the most aggressive keep-alive time in seconds clients are permitted to configure. Defaults to 5min. | 300 | 100 |
factcast.grpc.bandwith.numberOfFollowRequestsAllowedPerClientPerMinute | after the given number of follow requests from the same client per minute, subscriptions are rejected with RESOURCE_EXHAUSTED | 5 | 5 |
factcast.grpc.bandwith.initialNumberOfFollowRequestsAllowedPerClient | ramp-up to compensate for client startup | 50 | 50 |
factcast.grpc.bandwith.numberOfCatchupRequestsAllowedPerClientPerMinute | after the given number of catchup requests from the same client per minute, subscriptions are rejected with RESOURCE_EXHAUSTED | 6000 | 6000 |
factcast.grpc.bandwith.initialNumberOfCatchupRequestsAllowedPerClient | ramp-up to compensate for client startup | 36000 | 36000 |
factcast.grpc.bandwith.disabled | completely disables checking if set to true | false | true |
gRPC Server recommended settings
grpc.server.permit-keep-alive-without-calls=true
grpc.server.permit-keep-alive-time=100
Blacklist
Property | Description | Default | Example |
---|---|---|---|
factcast.blacklist.type | Configures where the list of blacklisted facts is retrieved from. One of [POSTGRES, RESOURCE]. | POSTGRES | — |
factcast.blacklist.location | Only required if type=RESOURCE. Specifies the URL where the JSON file containing the blacklist is located. | classpath:blacklist.json | file:/some/path/blocked-facts.json |
Testing
Property | Description | Default |
---|---|---|
factcast.store.integrationTestMode | when set to true, disables all non-essential memory-internal caches, timing might differ to production of course. | false |
UI
Property | Description | Default |
---|---|---|
vaadin.productionMode | Should be set to true, otherwise vaadin tries to generate a dev bundle which is not necessary, and probably will fail. | false |
Further details can be found here : net.devh.boot.grpc.server.config.GrpcServerProperties
.
9 - Docker
Building
In order to build a standard docker container from source, enter the project factcast-docker and run
mvn docker:build
This will create a docker container as factcast/factcast and needs nothing more than the database URL to run.
Usage:
The docker container can be started
docker run -e"SPRING_DATASOURCE_URL=jdbc:postgresql://<POSTGRES-SERVER>/<DATABASENAME>?user=<USERNAME>&password=<PASSWORD>" -p 9090:9090 factcast/factcast
Note, that the resulting server is optimized and supposed to be used for integration testing only. Do not use it in production