This the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

UI

FactCast-Server UI

The FactCast-Server UI is an easy to use UI based on Vaadin, that optionally can be plugged into FactCast. It allows to conveniently query for facts, without requiring knowledge of a query language or database access.

FactCast-Server UI

Learn here how to set it up in your environment.

1 - Setup

Setup and configuration of the Server UI

This section will walk you through the many options of how to setup and operate FactCast-Server-UI.

First, decide for a deployment-option and configure the necessary Vaadin property.

Also there are several options regarding Security.

1.1 - Deployment Options

Options for deploying the FactCast server-ui.

The FactCast Server-UI can be deployed in different ways:

Option 1: as part of the factcast server

Just add the dependency factcast-server-ui to your server project (next to server-grpc), so that you can use the UI directly from within the Server. In this configuration, the UI uses the (process-local) FactStore interface to talk to your store, and (almost) no additional configuration is needed.

(!) Beware that this way, the UI is vulnerable to anyone, who can access the Server via HTTP, obviously.

Option 2: as a standalone instance accessing the Database

You can add a new project to your landscape that just acts as a UI Server. In this configuration you don’t even need the gRPC layer (factcast-server-grpc) because it uses a jdbc connection to your database directly. The config is basically the same than with your FactCast Server (in terms of how to access the backing database), but additionally, you may want to set the role of this instance to readOnly by setting factcast.store.readOnlyModeEnabled=true.

Option 3: as standalone instance facilitating an existing factcast-server over gRPC

This is useful when you don’t want to publish the UI (much recommended) and also cannot / don’t want to access the Database directly. This way, the server-ui is basically just another client talking to the FactCast Server, and the configuration is done accordingly.

Security

The UI uses spring-security. Some helpful settings are documented here. If security is disabled you can log in with any username and security_disabled as password.

1.2 - Properties

Properties you want to use to configure FactCast UI.

UI

This setting should be set in every instance that factcast-server-ui is part of.

PropertyDescriptionDefault
vaadin.productionModeShould be set to true, otherwise vaadin tries to generate a dev bundle which is not necessary, and probably will fail.false

1.3 - Security

Authentication & Authorization

By default, the FactCast-Server UI supports the same authentication/authorization approach as the GRPC server explained here.

However, you might want to make UI accessible via a centrally managed Active Directory. Luckily, we use Spring Security under the hood and all this is possible.

OIDC Example

The following example shows an OIDC integration:

  1. You have to exclude the standard configuration, that configures Spring Security & Vaadin to support the default authentication/authorization approach.
@SpringBootApplication(exclude = {FactCastServerUISecurityAutoConfiguration.class})
  1. Add necessary Spring Security dependencies and configurations:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
  1. Implement custom security configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig extends VaadinWebSecurity {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.oauth2Login(Customizer.withDefaults()); // enable oauth2 login
    super.configure(http);
  }
}
  1. Implement a OAuth2UserService that maps from a OidcUser to a FactCastOidcUser which is usable by the FactCast-Server UI.
@Component
public class FactCastUserService implements OAuth2UserService<OidcUserRequest, OidcUser> {
  private final OidcUserService oidcUserService = new OidcUserService();

  @Override
  public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
    // that gives you a fully authenticated user via your OAuth/OIDC provider
    OidcUser user = oidcUserService.loadUser(userRequest);

    // either create the account yourself or reuse factcast-access.json here
    FactCastAccount account = new FactCastAccount(user.getEmail(), List.of());

    return new FactCastOidcUser(account, "unused", user);
  }
}

with this being the FactCastOidcUser

public class FactCastOidcUser extends FactCastUser implements OidcUser {
  private final OidcUser user;

  public FactCastOidcUser(FactCastAccount account, String secret, OidcUser user) {
    super(account, secret);
    this.user = user;
  }

  @Override
  public Map<String, Object> getClaims() {
    return user.getClaims();
  }

  @Override
  public OidcUserInfo getUserInfo() {
    return user.getUserInfo();
  }

  @Override
  public OidcIdToken getIdToken() {
    return user.getIdToken();
  }

  @Override
  public Map<String, Object> getAttributes() {
    return user.getAttributes();
  }

  @Override
  public String getName() {
    return user.getName();
  }
}

1.4 - Plugins

Plugins to enrich visual representation of data

FactCast Server UI is extensible using Plugins. Those plugins can be handy for enriching the plain fact information you see.

Scenario

Consider you have the following Events:

  • UserRegistered
  • UserLogin

where UserRegistered has a UserId and a UserName, and UserLogin is emitted after a succesful login, having just the UserId.

Now, when you look at UserLogin Events through the UI, the UserId is all you see, because thats all the json there is to your fact payload. However it might be nice to know the UserName for a UserId when you look at it. Also it would be cool, to ‘annotate’ the Json with that information. This can be done by building custom Plugins.

A plugin provides you an API to inspect and annotate the Json that will be displayed to the User. As part of a plugin, you could for instance build a projection that consumes all the UserRegistered Events to provide a queryable Map<UserId, UserName>, and use this data to annotate the UserName to every UserId.

Getting started

Take a look at HeaderMetaTimestampToDatePlugin as an example of the simplest Plugin possible. It just turns the meta._ts attribute of the fact header into a human readable DateTime. header-meta-timestamp-to-date-plugin.png