Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
25c33bc
Update to Spring Boot 2.5.14
thomaskrause Nov 3, 2022
bffdbed
Upgrade to Spring Booot 2.7.5
thomaskrause Nov 3, 2022
f342428
Don't configure kotlin stdlib manually
thomaskrause Nov 3, 2022
403ed4e
Configure OpenApi to generate the Spring WebClient (does not compile …
thomaskrause Nov 3, 2022
b0d0e37
Fix more of the compilation issues from changing to Spring WebClient
thomaskrause Nov 9, 2022
811d77c
Use WebClientResponseException
thomaskrause Nov 9, 2022
00b4bb6
Add block() to several of the more straight forward synchronous calls…
thomaskrause Nov 9, 2022
b8ad22a
Replace some of the occurences of "collectList().block()" with "toIte…
thomaskrause Nov 11, 2022
d6861a7
Fix remaining compilation issues regarding the new WebClient
thomaskrause Nov 11, 2022
8aaf12a
Merge branch 'main' into feature/refresh-jwt-token
thomaskrause Dec 9, 2022
7e10ed0
Add a "patched" CorpusApi implementation that allows to get the list …
thomaskrause Dec 9, 2022
db60d7a
Use the patched API where the corpus list is fetched
thomaskrause Dec 9, 2022
9aee36f
Use the patched API where the file list is fetched
thomaskrause Dec 12, 2022
da4c948
Attempt to configure a WebClient bean with authentfication
thomaskrause Dec 13, 2022
1151b20
Fix compilation issues
thomaskrause Dec 16, 2022
b4e1fa0
Formatting
thomaskrause Dec 16, 2022
ee9ff55
Merge branch 'feature/refresh-jwt-token'
thomaskrause May 22, 2023
651e265
Excplicitly set the H2 dialect
thomaskrause May 22, 2023
6355049
Removed double dependency entry for the salt-api
thomaskrause May 22, 2023
4361714
Use webclient in ApiClient
thomaskrause May 22, 2023
aa98f78
Send find query as body
thomaskrause May 22, 2023
5f94243
Update openapi and spring dependencies and use the raw webclient API …
thomaskrause May 23, 2023
6159897
Disable special XML handling
thomaskrause May 23, 2023
9051953
Use asynchronous webclient functionality to get the count result
thomaskrause Jul 13, 2023
965ba87
Use jackson do deserialize parsing error message.
thomaskrause Jul 13, 2023
f0bdcfd
Recompile online help with mdbook 0.4.32
thomaskrause Jul 25, 2023
0f3e3d1
Remove AuthenticationSuccessListener and AutoTokenRefreshClient
thomaskrause Jul 27, 2023
4e8d5c6
Remove OpenAPI client with WebClient in Helper class
thomaskrause Jul 27, 2023
b7bf79c
Merge branch 'main' into feature/use-webclient
thomaskrause Jul 27, 2023
ba51ca5
Fix compilation error
thomaskrause Jul 27, 2023
a74eb01
Use DataBuffer when trying to find subresults for metadata check
thomaskrause Jul 27, 2023
56cf8a5
Remove PatchedCorporaApi helper class
thomaskrause Jul 27, 2023
e435736
Remove other usages of the PatchedCorporaApi helper
thomaskrause Jul 27, 2023
8b4cf57
Use WebClient for getting the segmentation names in the search options
thomaskrause Jul 27, 2023
6a22e92
Use WebClient for HTML visualizer
thomaskrause Jul 27, 2023
4e5afb7
Replace usage of subgraph queries with WebClient
thomaskrause Jul 27, 2023
147529a
Fetch document_browser.json with WebClient
thomaskrause Jul 27, 2023
22b4da2
Specify "bearer" auth mode in desktop mode
thomaskrause Jul 27, 2023
f34f140
Use WebClient when getting the annotations for the query builders
thomaskrause Jul 27, 2023
89bb035
Delete corpora using WebClient
thomaskrause Jul 27, 2023
0898a11
Use WebClient to find results in exporters
thomaskrause Jul 27, 2023
dff3e85
Remove depricated WebSecurityConfigurerAdapter
thomaskrause Jul 28, 2023
284fb71
Use WebClient for frequency query
thomaskrause Jul 27, 2023
0d38717
Use WebClient when importing a corpus
thomaskrause Jul 27, 2023
fdfbc83
Use WebClient in group management
thomaskrause Jul 28, 2023
98bb53c
Reduce complexity of the filter creation logic
thomaskrause Jul 28, 2023
ad753a2
Do not use background thread to query corpus list in background
thomaskrause Jul 28, 2023
c0b8b6b
Use long polling as push strategy because there are issues with the s…
thomaskrause Jul 28, 2023
ab35323
Use Flux API to get the corpus configurations in the background
thomaskrause Jul 31, 2023
c4113df
Use Flux API to get example queries
thomaskrause Jul 31, 2023
fc5245c
Use Flux API for initial result page
thomaskrause Jul 31, 2023
538b9d7
Remove last usages of ApiClient
thomaskrause Aug 1, 2023
abe52e7
Use query controller to update find search for paging
thomaskrause Aug 1, 2023
0ace0a3
Relocate some classes so the "beans" package is not needed anymore
thomaskrause Aug 1, 2023
cd277b6
Reorganize class structure and remove some interfaces with only one i…
thomaskrause Aug 1, 2023
904e696
Use Flux API in CorpusBrowserPanel
thomaskrause Aug 2, 2023
5aa7d02
Get metadata in corpus browser via Flux API
thomaskrause Aug 4, 2023
afc60b8
Do not execute adapted Flux APIs calls in background thread
thomaskrause Aug 4, 2023
dda4549
Do not attempt to get edge annotations for components with an empty name
thomaskrause Aug 4, 2023
7704b34
Avoid detached UI in CorpusListPanel
thomaskrause Aug 4, 2023
1a36b35
Use blocking call to get corpus explorer content
thomaskrause Aug 7, 2023
2289c2c
Remove progress bar from corpus explorer window
thomaskrause Aug 7, 2023
805a8e2
Avoid storing reference to UI in result view panel
thomaskrause Aug 7, 2023
4233d17
Visualizer creation background job needs to have a reference to the UI
thomaskrause Aug 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,299 changes: 651 additions & 648 deletions pom.xml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/main/java/org/corpus_tools/annis/gui/AnnisBaseUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.util.TreeSet;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.commons.lang3.StringUtils;
import org.corpus_tools.annis.gui.objects.InstanceConfig;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;

Expand Down
54 changes: 24 additions & 30 deletions src/main/java/org/corpus_tools/annis/gui/AnnisUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
*/
package org.corpus_tools.annis.gui;

import static org.corpus_tools.annis.gui.Helper.DEFAULT_CONFIG;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.vaadin.annotations.Push;
Expand All @@ -27,32 +25,35 @@
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinSession;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.shared.ui.ui.Transport;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.spring.navigator.SpringViewProvider;
import com.vaadin.ui.Component;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import javax.servlet.ServletContext;
import org.corpus_tools.annis.ApiClient;
import org.corpus_tools.annis.api.model.CorpusConfiguration;
import org.corpus_tools.annis.gui.admin.AdminView;
import org.corpus_tools.annis.gui.components.ExceptionDialog;
import org.corpus_tools.annis.gui.components.MainToolbar;
import org.corpus_tools.annis.gui.controller.QueryController;
import org.corpus_tools.annis.gui.exporter.ExporterPlugin;
import org.corpus_tools.annis.gui.objects.QueryUIState;
import org.corpus_tools.annis.gui.query_references.UrlShortener;
import org.corpus_tools.annis.gui.querybuilder.QueryBuilderPlugin;
import org.corpus_tools.annis.gui.querybuilder.tiger.QueryBuilderPlugin;
import org.corpus_tools.annis.gui.requesthandler.BinaryRequestHandler;
import org.corpus_tools.annis.gui.security.AuthenticationSuccessListener;
import org.corpus_tools.annis.gui.security.AutoTokenRefreshClient;
import org.corpus_tools.annis.gui.security.SecurityConfiguration;
import org.corpus_tools.annis.gui.util.Helper;
import org.corpus_tools.annis.gui.visualizers.VisualizerPlugin;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.web.reactive.function.client.WebClient;

/**
* GUI for searching in corpora.
Expand All @@ -62,7 +63,7 @@
@Theme("annis")
@Widgetset("org.corpus_tools.annis.gui.widgets.gwt.AnnisWidgetSet")
@SpringUI(path = "/*")
@Push(value = PushMode.AUTOMATIC)
@Push(value = PushMode.AUTOMATIC, transport = Transport.LONG_POLLING)
public class AnnisUI extends CommonUI implements ErrorHandler, ViewChangeListener {

private static final Profiles DESKTOP_PROFILES = Profiles.of("desktop & !test");
Expand All @@ -75,7 +76,8 @@ public class AnnisUI extends CommonUI implements ErrorHandler, ViewChangeListene

private QueryController queryController;

private SearchView searchView;
@Autowired
SpringViewProvider viewProvider;

@Autowired
private List<VisualizerPlugin> visualizerPlugins;
Expand All @@ -92,7 +94,10 @@ public class AnnisUI extends CommonUI implements ErrorHandler, ViewChangeListene
@Autowired
private UIConfig config;

private final AuthenticationSuccessListener authListener;
@Autowired
private WebClient webClient;

private SearchView searchView;

private AdminView adminView;

Expand All @@ -113,10 +118,8 @@ public class AnnisUI extends CommonUI implements ErrorHandler, ViewChangeListene
*/
private MainToolbar toolbar;

@Autowired
public AnnisUI(ServiceStarter serviceStarter, AuthenticationSuccessListener authListener) {
super("", serviceStarter, authListener);
this.authListener = authListener;
public AnnisUI(ServiceStarter serviceStarter) {
super("", serviceStarter);
initTransients();
}

Expand All @@ -130,11 +133,11 @@ public boolean beforeViewChange(ViewChangeEvent event) {
// make sure the toolbar is removed from the old view
searchView.setToolbar(null);
adminView.setToolbar(null);
toolbar.setSidebar(null);
toolbar.setSearchView(null);

if (event.getNewView() == searchView) {
searchView.setToolbar(toolbar);
toolbar.setSidebar(searchView);
toolbar.setSearchView(searchView);
toolbar.setNavigationTarget(MainToolbar.NavigationTarget.ADMIN, AnnisUI.this);
} else if (event.getNewView() == adminView) {
adminView.setToolbar(toolbar);
Expand Down Expand Up @@ -182,12 +185,7 @@ public CorpusConfiguration getCorpusConfigWithCache(String corpus) {
if (corpusConfigCache != null) {
config = corpusConfigCache.getIfPresent(corpus);
if (config == null) {
if (corpus.equals(DEFAULT_CONFIG)) {
config = Helper.getDefaultCorpusConfig();
} else {
config = Helper.getCorpusConfig(corpus, AnnisUI.this);
}

config = Helper.getCorpusConfig(corpus, AnnisUI.this).block();
corpusConfigCache.put(corpus, config);
}
}
Expand Down Expand Up @@ -227,11 +225,11 @@ protected void init(VaadinRequest request) {
setErrorHandler(this);

adminView = new AdminView(AnnisUI.this);
searchView = new SearchView(AnnisUI.this);

toolbar = new MainToolbar(getConfig(), oauth2Clients);
toolbar.setQueryController(queryController);

this.searchView = new SearchView(this);
this.queryController = new QueryController(this, searchView, queryState);

toolbar.addLoginListener(searchView);
Expand All @@ -246,10 +244,10 @@ protected void init(VaadinRequest request) {

loadInstanceFonts();

if (Helper.getUser(this).isPresent()) {
if (Helper.getUser().isPresent()) {
getToolbar().onLogin();
}

Object fragmentToRestore =
VaadinSession.getCurrent().getAttribute(SecurityConfiguration.FRAGMENT_TO_RESTORE);
if (fragmentToRestore instanceof String) {
Expand All @@ -260,8 +258,8 @@ protected void init(VaadinRequest request) {
}

@Override
public ApiClient getClient() {
return new AutoTokenRefreshClient(this, this.getAuthListener());
public WebClient getWebClient() {
return webClient;
}


Expand Down Expand Up @@ -319,8 +317,4 @@ public ServletContext getServletContext() {
public OAuth2ClientProperties getOauth2ClientProperties() {
return this.oauth2Clients;
}

public AuthenticationSuccessListener getAuthListener() {
return authListener;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

Expand Down
49 changes: 19 additions & 30 deletions src/main/java/org/corpus_tools/annis/gui/CommonUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@
import java.util.Map;
import java.util.Optional;
import javax.servlet.ServletContext;
import org.corpus_tools.annis.ApiClient;
import org.corpus_tools.annis.ApiException;
import org.corpus_tools.annis.gui.components.SettingsStorage;
import org.corpus_tools.annis.gui.objects.FontConfig;
import org.corpus_tools.annis.gui.objects.InstanceConfig;
import org.corpus_tools.annis.gui.requesthandler.ResourceRequestHandler;
import org.corpus_tools.annis.gui.security.AuthenticationSuccessListener;
import org.corpus_tools.annis.gui.security.SecurityConfiguration;
import org.corpus_tools.annis.gui.util.Helper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;

/**
*
Expand All @@ -49,18 +51,14 @@ public abstract class CommonUI extends AnnisBaseUI {

private InstanceConfig instanceConfig;

private SecurityContext securityContext;

protected CommonUI(String urlPrefix, ServiceStarter serviceStarter,
AuthenticationSuccessListener authListener) {
this.urlPrefix = urlPrefix;
Optional<Authentication> desktopAuth = serviceStarter.getDesktopUserToken();
if (desktopAuth.isPresent()) {
// Login the provided desktop user
getSecurityContext().setAuthentication(desktopAuth.get());
authListener.setToken(desktopAuth.get().getCredentials().toString());
}
}
protected CommonUI(String urlPrefix, ServiceStarter serviceStarter) {
this.urlPrefix = urlPrefix;
Optional<Authentication> userToken = serviceStarter.getDesktopUserToken();
if(userToken.isPresent()) {
// Login with the static desktop token
SecurityContextHolder.getContext().setAuthentication(userToken.get());
}
}


public InstanceConfig getInstanceConfig() {
Expand Down Expand Up @@ -173,9 +171,7 @@ public String getUrlPrefix() {
return urlPrefix;
}

public abstract ApiClient getClient();


public abstract WebClient getWebClient();

/**
* Handle common errors like database/service connection problems and display a unified error
Expand All @@ -194,10 +190,10 @@ public boolean handleCommonError(Throwable ex, String action) {
rootCause = rootCause.getCause();
}

if (rootCause instanceof ApiException) {
ApiException apiEx = (ApiException) rootCause;
if (rootCause instanceof WebClientResponseException) {
WebClientResponseException apiEx = (WebClientResponseException) rootCause;

if (apiEx.getCode() == 503) {
if (apiEx.getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE) {
// database connection error
Notification n = new Notification(
"Can't execute " + (action == null ? "" : "\"" + action + "\"")
Expand All @@ -214,7 +210,7 @@ public boolean handleCommonError(Throwable ex, String action) {

n.show(this.getPage());
return true;
} else if (apiEx.getCode() == 401) {
} else if (apiEx.getStatusCode() == HttpStatus.UNAUTHORIZED) {
redirectToLogin();
return true;
}
Expand All @@ -225,13 +221,6 @@ public boolean handleCommonError(Throwable ex, String action) {

public abstract ServletContext getServletContext();

public SecurityContext getSecurityContext() {
if (this.securityContext == null) {
this.securityContext = SecurityContextHolder.getContext();
}
return securityContext;
}

public abstract OAuth2ClientProperties getOauth2ClientProperties();

public abstract UIConfig getConfig();
Expand Down
Loading