diff --git a/goofy-client/README.md b/goofy-client/README.md index 6cb2e945e04e50251918ead6d95149284b89f04a..531d493c2a5696aa0b53cc73536d436b036697f8 100644 --- a/goofy-client/README.md +++ b/goofy-client/README.md @@ -1,5 +1,12 @@ # GoofyClient +## Client starten +Um den Client zum laufen zu bekommen, muss zunächst ein `npm install` ausgeführt werden. <br> +-> nach dem Ausführen sollte sich ein `node_modules` Ordner im Verzeichnis befinden. <br> +Im Anschluß wird der Client über `npm start` gestartet. + +# + ## Common information to Nx from Nx This project was generated using [Nx](https://nx.dev). @@ -35,10 +42,9 @@ Libraries are sharable across libraries and applications. They can be imported f Run `ng g component my-component --project=my-app` to generate a new component. -</br> # -</br> + ## Allgemein Man kann mit Hilfe von `nx --help` eine Liste von Befehlen mit kurzen Erläuterung bekommen. diff --git a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-list/vorgang-list-ea.search.e2e-spec.ts b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-list/vorgang-list-ea.search.e2e-spec.ts index fbe7f20e1bf47e9dff4e2f86c58b6a4c26bd0989..c70dbf808963165d2a7f389f4b4ec1fd4ddfa970 100644 --- a/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-list/vorgang-list-ea.search.e2e-spec.ts +++ b/goofy-client/apps/goofy-e2e/src/integration/einheitlicher-ansprechpartner/vorgang-list/vorgang-list-ea.search.e2e-spec.ts @@ -51,9 +51,10 @@ describe('VorgangList Suche for EA User', () => { reload(); + exist(vorgangList.getRoot()); + vorgangList.waitForSpinnerToDisappear(); - exist(vorgangList.getRoot()); exist(vorgangStayInList.getRoot()); notExist(vorgangDisappearInList.getRoot()); }) diff --git a/goofy-client/apps/goofy/src/app/app.component.ts b/goofy-client/apps/goofy/src/app/app.component.ts index bbd18e5366bec44583282643616ef7a28426cab4..b94ea9f48a04e38b55fd2e487044ed8d397bf4b6 100644 --- a/goofy-client/apps/goofy/src/app/app.component.ts +++ b/goofy-client/apps/goofy/src/app/app.component.ts @@ -10,6 +10,7 @@ import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks'; import { Environment } from 'libs/environment-shared/src/lib/environment.model'; import { Observable } from 'rxjs'; import { AppService } from '@goofy-client/app-shared'; +import { Title } from '@angular/platform-browser'; @Component({ selector: 'goofy-client-root', @@ -33,6 +34,7 @@ export class AppComponent implements OnInit { private iconService: IconService, private oAuthService: OAuthService, private appService: AppService, + private titleService: Title, @Inject(ENVIRONMENT_CONFIG) private envConfig: Environment ) { this.iconService.registerIcons(); @@ -73,5 +75,9 @@ export class AppComponent implements OnInit { requireHttps: false }; } + + public setTitle(newTitle: string) { + this.titleService.setTitle(newTitle); + } } diff --git a/goofy-client/libs/navigation/src/lib/header-container/header/header.component.html b/goofy-client/libs/navigation/src/lib/header-container/header/header.component.html index 5fc6466bc6778ae57450209d51fdd1c3f9bd86fd..b3ce91e25db98c98dc43419ed1dc0f9fe30850ce 100644 --- a/goofy-client/libs/navigation/src/lib/header-container/header/header.component.html +++ b/goofy-client/libs/navigation/src/lib/header-container/header/header.component.html @@ -3,7 +3,7 @@ <goofy-client-icon-button-with-spinner icon="menu" toolTip="Hauptmenü umschalten" (clickEmitter)="toggleMenuEvent.emit(!this.navigationCollapse)"> </goofy-client-icon-button-with-spinner> <a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }"> - <img src="/assets/img/logo.svg" alt="Goofy Logo" /> + <img src="/assets/img/logo.svg" alt="Goofy Logo"/> <div class="title" data-test-id='title'>Goofy</div> </a> </div> @@ -16,7 +16,8 @@ <goofy-client-settings [darkMode]="darkMode" (darkModeEmitter)="darkModeEmitter.emit($event)"></goofy-client-settings> - <button mat-icon-button [matMenuTriggerFor]="accountMenu" class="big-button" aria-label="Benutzerkonto" data-test-id="user-icon-button"> + <button mat-icon-button [matMenuTriggerFor]="accountMenu" class="big-button" aria-label="Benutzerkonto" data-test-id="user-icon-button" + matTooltip="Benutzerkonto Icon/Initialen"> <goofy-client-user-icon></goofy-client-user-icon> </button> diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-header/vorgang-detail-header.component.scss b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-header/vorgang-detail-header.component.scss index dfa7756d1e4f960ebeb28f99d0ed2a9293dafc6c..91e7c6ae8ef4d1d7ff988dcb52ef04ef32c124a4 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-header/vorgang-detail-header.component.scss +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-header/vorgang-detail-header.component.scss @@ -85,12 +85,12 @@ h2 { } .name { order: 2; - width: calc(100% - 460px); + width: calc(100% - 470px); padding-left: 0; } .initial-date { order: 3; - width: 240px; + width: 250px; } .aktenzeichen { order: 4; diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/status-dot/status-dot.component.html b/goofy-client/libs/vorgang-shared-ui/src/lib/status-dot/status-dot.component.html index 4e6d6a814cf88b3c514345307bd8a9f24c6cbd1c..99a15f5fa81426d50ca154c5d8a395c09d475b63 100644 --- a/goofy-client/libs/vorgang-shared-ui/src/lib/status-dot/status-dot.component.html +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/status-dot/status-dot.component.html @@ -1,2 +1,2 @@ -<div class="dot" [style.width]="diameter + 'px'" [style.height]="diameter + 'px'" [ngClass]="status | lowercase"></div> +<div class="dot" aria-hidden="true" [style.width]="diameter + 'px'" [style.height]="diameter + 'px'" [ngClass]="status | lowercase"></div> <div class="status-name" data-test-id="status">{{ status | enumToLabel: vorgangStatusLabel }}</div> diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.html b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.html index e266bed718a9efe95e157c1f8a2f2297a1a9e838..137fd876b53bb36a51177635b7c44966870b4a32 100644 --- a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.html +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.component.html @@ -7,6 +7,7 @@ <input #searchInput placeholder="Eingangskennzeichen" + aria-label="Vorgänge nach Eingangskennzeichen durchsuchen" type="text" autofocus maxlength="32" diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.html b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.html index d8a0701c0b33d33c5b04bad22306aae4a67ce7b8..5da7458e21f653fa10eb9115eac46365a776050c 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.html +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.html @@ -1,4 +1,7 @@ -<a class="list-item" routerLink="/vorgang/{{ vorgang | toResourceUri: vorgangLinkRel.VORGANG_WITH_EINGANG }}" [attr.data-test-id]="'vorgang-list-item-' + vorgang.name | convertForDataTest"> +<a class="list-item" + [attr.aria-label]="'Vorgang: ' + vorgang.name + ', Aktenzeichen: ' + vorgang.aktenzeichen + ', Status: ' + vorgang.status + ', Eingang: ' + (vorgang.createdAt | formatDateWithTimePipe)" + routerLink="/vorgang/{{ vorgang | toResourceUri: vorgangLinkRel.VORGANG_WITH_EINGANG }}" + [attr.data-test-id]="'vorgang-list-item-' + vorgang.name | convertForDataTest"> <goofy-client-status-dot [status]="vorgang.status" diameter="12" data-test-class="status" class="status"></goofy-client-status-dot> <goofy-client-vorgang-next-frist-button *ngIf="vorgang | hasLink: vorgangLinkRel.WIEDERVORLAGEN" [vorgang]="vorgang" class="wiedervorlagen"></goofy-client-vorgang-next-frist-button> diff --git a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list.component.html b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list.component.html index f12c998432bd4b2ecc320e99b232bbca69c9d940..6cb29f05ea020254ac05566d7ab9936b5a831119 100644 --- a/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list.component.html +++ b/goofy-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list.component.html @@ -4,6 +4,7 @@ <goofy-client-empty-list *ngIf="!vorgangListPageResource.loading && !(vorgaenge && vorgaenge.length)" + role="status" [searchString]="searchString" data-test-id="empty-list"> </goofy-client-empty-list> diff --git a/goofy-client/pom.xml b/goofy-client/pom.xml index db548c553e57d0b85e7fefad9ff936e1ba651194..119254801be8bf0ad4db083cc5c55adcb9552965 100644 --- a/goofy-client/pom.xml +++ b/goofy-client/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>de.itvsh.ozg</groupId> <artifactId>goofy</artifactId> - <version>0.18.0-SNAPSHOT</version> + <version>0.19.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/goofy-server/pom.xml b/goofy-server/pom.xml index a703a5a230b1bfa5ed238532d64875a901202537..587b145027136cc551f45e75a4673183ee29ea26 100644 --- a/goofy-server/pom.xml +++ b/goofy-server/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>de.itvsh.ozg</groupId> <artifactId>goofy</artifactId> - <version>0.18.0-SNAPSHOT</version> + <version>0.19.0-SNAPSHOT</version> </parent> <artifactId>goofy-server</artifactId> @@ -85,7 +85,7 @@ <groupId>de.itvsh.ozg.pluto</groupId> <artifactId>pluto-interface</artifactId> </dependency> - + <!-- tools --> <dependency> <groupId>org.mapstruct</groupId> diff --git a/goofy-server/src/main/java/de/itvsh/goofy/CallBeanFactoryPostProcessor.java b/goofy-server/src/main/java/de/itvsh/goofy/CallBeanFactoryPostProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..db33c9e24ab38389d39a3f26b91e9892d57e49a6 --- /dev/null +++ b/goofy-server/src/main/java/de/itvsh/goofy/CallBeanFactoryPostProcessor.java @@ -0,0 +1,19 @@ +package de.itvsh.goofy; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class CallBeanFactoryPostProcessor implements BeanFactoryPostProcessor { + + private final CallScope callScope; + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + beanFactory.registerScope(CallScope.SCOPE_NAME, callScope); + } + +} diff --git a/goofy-server/src/main/java/de/itvsh/goofy/CallScope.java b/goofy-server/src/main/java/de/itvsh/goofy/CallScope.java new file mode 100644 index 0000000000000000000000000000000000000000..c8be95b7938284d7b952e2b4ffb842a75a468d41 --- /dev/null +++ b/goofy-server/src/main/java/de/itvsh/goofy/CallScope.java @@ -0,0 +1,67 @@ +package de.itvsh.goofy; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.config.Scope; +import org.springframework.core.NamedInheritableThreadLocal; + +import lombok.extern.log4j.Log4j2; + +@Log4j2 +public class CallScope implements Scope { + + public static final String SCOPE_NAME = "call"; + + private static final ThreadLocal<Map<String, Object>> scopedObjectsHolder = new NamedInheritableThreadLocal<>("Call Context"); + private static final ThreadLocal<Map<String, Runnable>> destructionCallbacksHolder = new NamedInheritableThreadLocal<>( + "Call Context Desctruction Callbacks"); + + public void startScope() { + LOG.info("START Call-Scope"); + scopedObjectsHolder.set(new ConcurrentHashMap<>()); + destructionCallbacksHolder.set(new ConcurrentHashMap<>()); + } + + public void endScope() { + scopedObjectsHolder.remove(); + callAllDestructionCallbacks(); + destructionCallbacksHolder.remove(); + } + + private void callAllDestructionCallbacks() { + destructionCallbacksHolder.get().values().forEach(Runnable::run); + } + + @Override + public Object get(String name, ObjectFactory<?> objectFactory) { + if (!scopedObjectsHolder.get().containsKey(name)) { + scopedObjectsHolder.get().put(name, objectFactory.getObject()); + } + + return scopedObjectsHolder.get().get(name); + } + + @Override + public Object remove(String name) { + destructionCallbacksHolder.get().remove(name); + return scopedObjectsHolder.get().remove(name); + } + + @Override + public void registerDestructionCallback(String name, Runnable callback) { + destructionCallbacksHolder.get().put(name, callback); + + } + + @Override + public Object resolveContextualObject(String key) { + return scopedObjectsHolder.get().get(key); + } + + @Override + public String getConversationId() { + return Thread.currentThread().getName(); + } +} diff --git a/goofy-server/src/main/java/de/itvsh/goofy/GoofyServerApplication.java b/goofy-server/src/main/java/de/itvsh/goofy/GoofyServerApplication.java index e4bd4e21483ff2b7f0b4fd26cc59bbdfd42ed69f..8f6e5480ccb83616586267b632d7237dbf1c133f 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/GoofyServerApplication.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/GoofyServerApplication.java @@ -2,17 +2,22 @@ package de.itvsh.goofy; import java.util.TimeZone; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.security.concurrent.DelegatingSecurityContextRunnable; import org.springframework.web.filter.ForwardedHeaderFilter; @SpringBootApplication @EnableAsync @EnableAspectJAutoProxy(proxyTargetClass = true) +@ComponentScan({ "de.itvsh.*" }) public class GoofyServerApplication { public static void main(String[] args) { @@ -26,4 +31,23 @@ public class GoofyServerApplication { bean.setFilter(new ForwardedHeaderFilter()); return bean; } + + @Bean + public ThreadPoolTaskExecutor threadPoolTaskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + + executor.setThreadNamePrefix("async-"); + executor.setTaskDecorator(DelegatingSecurityContextRunnable::new); + return executor; + } + + @Bean + public CallScope callScope() { + return new CallScope(); + } + + @Bean + public BeanFactoryPostProcessor beanFactoryPostProcessor(CallScope callScope) { + return new CallBeanFactoryPostProcessor(callScope); + } } \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/RequestAttributes.java b/goofy-server/src/main/java/de/itvsh/goofy/RequestAttributes.java index b9af1b034aaac0c03625627824364bb66b3e7912..d8ef7e2d4ff56bf4b820b1eec0a5425cce89cd81 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/RequestAttributes.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/RequestAttributes.java @@ -13,7 +13,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; @Component -@Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) +@Scope(scopeName = "call", proxyMode = ScopedProxyMode.TARGET_CLASS) @Getter @Builder @AllArgsConstructor(access = AccessLevel.PRIVATE) diff --git a/goofy-server/src/main/java/de/itvsh/goofy/RequestIdFilter.java b/goofy-server/src/main/java/de/itvsh/goofy/RequestIdFilter.java index c673c64ecd82e2addfb3fdea44717f9ca219a940..f95422d82da67bc1b1f5e699f94592e0517e7500 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/RequestIdFilter.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/RequestIdFilter.java @@ -22,15 +22,20 @@ class RequestIdFilter extends OncePerRequestFilter { @Autowired private RequestAttributes reqAttributes; + @Autowired + private CallScope callScope; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + callScope.startScope(); try (CloseableThreadContext.Instance ctc = CloseableThreadContext.put(REQUEST_ID_KEY, reqAttributes.getRequestId())) { LOG.info("START of Request with ID '{}'.", reqAttributes.getRequestId()); filterChain.doFilter(request, response); + } finally { LOG.info("END of Request with ID '{}'", reqAttributes.getRequestId()); + callScope.endScope(); } } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/SecurityConfiguration.java b/goofy-server/src/main/java/de/itvsh/goofy/SecurityConfiguration.java index 109df5fa37eda76c06760bde9108be835d468a93..d31bce8bfb98f2bee98d7b431200c670ff78d5e9 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/SecurityConfiguration.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/SecurityConfiguration.java @@ -10,7 +10,6 @@ import org.springframework.security.config.annotation.method.configuration.Enabl import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; @@ -30,7 +29,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); - SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL); http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/LinkedResourceDesiralizer.java b/goofy-server/src/main/java/de/itvsh/goofy/common/LinkedResourceDesiralizer.java index 8ed6eb0b54adf438037dbcabefd1c7d9cca5d773..e1a280ba4bd83f63f0278f5adad81a8078c1255e 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/LinkedResourceDesiralizer.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/LinkedResourceDesiralizer.java @@ -22,8 +22,8 @@ import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.deser.ContextualDeserializer; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import de.itvsh.goofy.common.datatypes.StringBasedValue; -import de.itvsh.goofy.common.errorhandling.TechnicalException; +import de.itvsh.kop.common.datatype.StringBasedValue; +import de.itvsh.kop.common.errorhandling.TechnicalException; public class LinkedResourceDesiralizer extends StdDeserializer<Object> implements ContextualDeserializer { diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/LinkedResourceSerializer.java b/goofy-server/src/main/java/de/itvsh/goofy/common/LinkedResourceSerializer.java index 1b767f79a29e1deb6baa2cefd14fb87ae70e2259..5f692a770c1ec26cf712e408b5eeb8c92a2bff73 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/LinkedResourceSerializer.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/LinkedResourceSerializer.java @@ -14,7 +14,7 @@ import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.ContextualSerializer; -import de.itvsh.goofy.common.errorhandling.TechnicalException; +import de.itvsh.kop.common.errorhandling.TechnicalException; import lombok.NoArgsConstructor; @NoArgsConstructor diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileController.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileController.java index fbfce83de79966c815add6de9dd8d0ae89a8713d..f2f9819e5d32850deb67be73888856f7414c407e 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileController.java @@ -23,9 +23,9 @@ import org.springframework.web.multipart.MultipartFile; import com.google.protobuf.ByteString; -import de.itvsh.goofy.common.errorhandling.TechnicalException; import de.itvsh.goofy.common.file.OzgFile; import de.itvsh.goofy.common.file.OzgFileData; +import de.itvsh.kop.common.errorhandling.TechnicalException; @RestController @RequestMapping(BinaryFileController.PATH) diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/FileId.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/FileId.java index ee7702928ce028e2c33d363216d067292cd6ef5a..f24d3f5127ac3794d70ac04f5fda6083f220c6a5 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/FileId.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/FileId.java @@ -2,7 +2,7 @@ package de.itvsh.goofy.common.binaryfile; import java.util.UUID; -import de.itvsh.goofy.common.datatypes.StringBasedValue; +import de.itvsh.kop.common.datatype.StringBasedValue; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/datatypes/StringBasedValue.java b/goofy-server/src/main/java/de/itvsh/goofy/common/datatypes/StringBasedValue.java deleted file mode 100644 index 619b7a199c84389fd087690ead00e01aacd3c947..0000000000000000000000000000000000000000 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/datatypes/StringBasedValue.java +++ /dev/null @@ -1,33 +0,0 @@ -package de.itvsh.goofy.common.datatypes; - -import java.io.Serializable; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import lombok.EqualsAndHashCode; - -@EqualsAndHashCode -public abstract class StringBasedValue implements Serializable { - - private static final long serialVersionUID = 1L; - - @JsonProperty - private String value; - - protected StringBasedValue(String value) { - this.value = value; - } - - protected StringBasedValue() { - } - - void setValue(String value) { - this.value = value; - } - - @Override - public String toString() { - return value; - } - -} diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenService.java index 92bd55e740be49785c000886e98603658183f982..639d8c64a0bb0d3c060d286d9f77a22c1f161532 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenService.java @@ -13,9 +13,9 @@ import org.springframework.stereotype.Service; import com.auth0.jwt.exceptions.JWTVerificationException; import de.itvsh.goofy.JwtTokenUtil; -import de.itvsh.goofy.common.errorhandling.TechnicalException; import de.itvsh.goofy.common.user.CurrentUserService; import de.itvsh.goofy.common.user.GoofyUser; +import de.itvsh.kop.common.errorhandling.TechnicalException; import lombok.extern.log4j.Log4j2; @Log4j2 diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ExceptionController.java b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ExceptionController.java index cb928b70607df9dbbee7a73b49f26de4ed929e92..111fe5d3c81daaea1f62b0d413370ea3e82d4dd9 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ExceptionController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ExceptionController.java @@ -24,6 +24,8 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import de.itvsh.goofy.common.user.keycloak.KeycloakUnavailableException; +import de.itvsh.kop.common.errorhandling.ExceptionUtil; +import de.itvsh.kop.common.errorhandling.TechnicalException; import lombok.extern.log4j.Log4j2; @ControllerAdvice diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ExceptionUtil.java b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ExceptionUtil.java deleted file mode 100644 index e966eb98e0017f073674d0bc347ad4dbe725fbe7..0000000000000000000000000000000000000000 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ExceptionUtil.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.itvsh.goofy.common.errorhandling; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -class ExceptionUtil { - - private static final String MESSAGE_WITH_EXCEPTION_ID_TEMPLATE = "%s (ExceptionId: %s)"; - - public static String formatMessageWithExceptionId(String message, String exceptionId) { - return String.format(ExceptionUtil.MESSAGE_WITH_EXCEPTION_ID_TEMPLATE, message, exceptionId); - } -} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/FunctionalErrorCode.java b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/FunctionalErrorCode.java deleted file mode 100644 index 1f205d74e68ce9ff4eb7ee72f8b4bf862e0ca385..0000000000000000000000000000000000000000 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/FunctionalErrorCode.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.itvsh.goofy.common.errorhandling; - -@FunctionalInterface -public interface FunctionalErrorCode { - - String getErrorCode(); - -} diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/FunctionalException.java b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/FunctionalException.java index 53db8aa25b5eb41ef2f5aa33ff203930b106efa3..3eefe51b6c7c80d2c88365a620245dfaeae87d6d 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/FunctionalException.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/FunctionalException.java @@ -2,6 +2,10 @@ package de.itvsh.goofy.common.errorhandling; import java.util.UUID; +import de.itvsh.kop.common.errorhandling.ExceptionUtil; +import de.itvsh.kop.common.errorhandling.FunctionalErrorCode; +import de.itvsh.kop.common.errorhandling.IdentifiableException; + public class FunctionalException extends RuntimeException implements IdentifiableException { private static final long serialVersionUID = 1L; diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/GrpcExceptionController.java b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/GrpcExceptionController.java index 36dc50da6e5ca97374be87a2d2fccb40ee80fde9..13b0beda9c0c794ea29ad055d510d1e7c5d7bbe7 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/GrpcExceptionController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/GrpcExceptionController.java @@ -13,6 +13,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; +import de.itvsh.kop.common.errorhandling.ExceptionUtil; +import de.itvsh.kop.common.errorhandling.FunctionalErrorCode; import io.grpc.Metadata; import io.grpc.Metadata.Key; import io.grpc.Status; diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/IdentifiableException.java b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/IdentifiableException.java deleted file mode 100644 index bf193c62401eb999e816f045e2ab07b421911ba1..0000000000000000000000000000000000000000 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/IdentifiableException.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.itvsh.goofy.common.errorhandling; - -public interface IdentifiableException { - - String getExceptionId(); -} diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ResourceNotFoundException.java b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ResourceNotFoundException.java index 4c1cac30dc8ab83603f984ace876f8fca014eb9b..73c9d48e3af9102f511433fa9b803872604cac10 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ResourceNotFoundException.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/ResourceNotFoundException.java @@ -1,5 +1,6 @@ package de.itvsh.goofy.common.errorhandling; +import de.itvsh.kop.common.errorhandling.FunctionalErrorCode; import lombok.Getter; @Getter diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/TechnicalException.java b/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/TechnicalException.java deleted file mode 100644 index 860ecd064ff714a1ef6ccc908f8999965742c9d4..0000000000000000000000000000000000000000 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/errorhandling/TechnicalException.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.itvsh.goofy.common.errorhandling; - -import java.util.UUID; - -public class TechnicalException extends RuntimeException implements IdentifiableException { - - private static final long serialVersionUID = 1L; - - private final String exceptionId; - - public TechnicalException(String msg, Throwable cause) { - super(msg, cause); - - this.exceptionId = UUID.randomUUID().toString(); - } - - @Override - public String getMessage() { - return ExceptionUtil.formatMessageWithExceptionId(super.getMessage(), exceptionId); - } - - @Override - public String getExceptionId() { - return exceptionId; - } -} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/logging/AspectLoggingUtils.java b/goofy-server/src/main/java/de/itvsh/goofy/common/logging/AspectLoggingUtils.java deleted file mode 100644 index ca8e03a014f12fab6d63ce2b24f6d7568b954030..0000000000000000000000000000000000000000 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/logging/AspectLoggingUtils.java +++ /dev/null @@ -1,146 +0,0 @@ -package de.itvsh.goofy.common.logging; - -import java.util.Collection; -import java.util.Objects; -import java.util.StringJoiner; - -import org.apache.commons.lang3.ArrayUtils; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.reflect.MethodSignature; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import de.itvsh.goofy.common.datatypes.StringBasedValue; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.extern.log4j.Log4j2; - -@Log4j2 -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class AspectLoggingUtils { - - private static final String LOGGING_TEMPLATE = "%s: %s"; - - private static final String LOGGING_CALL_TEMPLATE = "%s(%s)"; - private static final String LOGGING_RESULT_TEMPLATE = "%s => %s"; - - static void log(final JoinPoint joinPoint) { - try { - MethodSignature sig = (MethodSignature) joinPoint.getSignature(); - var log = getLogger(joinPoint); - if (log.isDebugEnabled()) { - log.debug(String.format(LOGGING_CALL_TEMPLATE, sig.getName(), formatDebuggingParameter(joinPoint))); - } else { - log.info(String.format(LOGGING_CALL_TEMPLATE, sig.getName(), formatInfoParameters(joinPoint))); - } - } catch (RuntimeException e) { - LOG.error("Error on generating log output for " + joinPoint, e); - } - } - - static void logException(JoinPoint joinPoint, Exception exception) { - try { - var log = getLogger(joinPoint); - if (log.isWarnEnabled()) { - log.warn(String.format(LOGGING_TEMPLATE, exception.getClass().getSimpleName(), exception.getMessage())); - } - if (log.isDebugEnabled()) { - log.debug(exception.getMessage(), exception); - } - } catch (RuntimeException e) { - LOG.error("Error on generating log on exception.", e); - LOG.error("Original exception log", exception); - } - } - - static void logReturnValue(JoinPoint joinPoint, Object returnValue) { - try { - - MethodSignature sig = (MethodSignature) joinPoint.getSignature(); - var log = getLogger(joinPoint); - if (log.isInfoEnabled()) { - log.info(String.format(LOGGING_RESULT_TEMPLATE, sig.getName(), - sig.getReturnType() == Void.TYPE ? "<Void>" : formatInfoParameter(returnValue))); - } - } catch (RuntimeException e) { - LOG.error("Error on generating log for returnValue.", e); - } - } - - private static Logger getLogger(final JoinPoint joinPoint) { - return LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringType()); - } - - private static String formatInfoParameters(final JoinPoint joinPoint) { - String[] paramNames = getSignature(joinPoint).getParameterNames(); - Object[] paramValues = joinPoint.getArgs(); - - var stringJoiner = new StringJoiner(", "); - - for (int n = 0; n < paramValues.length; n++) { - if (Objects.nonNull(paramNames)) { - stringJoiner.add(String.format(LOGGING_TEMPLATE, paramNames[n], formatInfoParameter(paramValues[n]))); - } else { - stringJoiner.add(formatInfoParameter(paramValues[n])); - } - } - - return stringJoiner.toString(); - } - - private static String formatInfoParameter(Object value) { - if (Objects.nonNull(value) && printValueOnInfoLevel(value.getClass())) { - return formatParameter(value); - } else if (Objects.nonNull(value)) { - var sb = new StringBuilder(); - sb.append("<").append(value.getClass().getSimpleName()); - if (value.getClass().isArray()) { - sb.deleteCharAt(sb.length() - 1); - sb.append(ArrayUtils.getLength(value)).append("]"); - } - sb.append(">"); - return sb.toString(); - } else { - return "-null-"; - } - } - - private static boolean printValueOnInfoLevel(Class<?> paramClass) { - return paramClass.isPrimitive() || // - StringBasedValue.class.isAssignableFrom(paramClass) || // - String.class.isAssignableFrom(paramClass) || // - Number.class.isAssignableFrom(paramClass); - } - - private static String formatDebuggingParameter(final JoinPoint joinPoint) { - String[] paramNames = getSignature(joinPoint).getParameterNames(); - Object[] paramValues = joinPoint.getArgs(); - - var sb = new StringBuilder(); - for (int n = 0; n < paramValues.length; n++) { - if (n > 0) { - sb.append(", "); - } - if (paramNames != null) { - sb.append(paramNames[n]).append(": "); - } - sb.append(formatParameter(paramValues[n])); - } - return sb.toString(); - } - - private static String formatParameter(final Object param) { - if (param == null) { - return "NULL"; - } - if (Collection.class.isAssignableFrom(param.getClass())) { - return "Collection with size " + ((Collection<?>) param).size(); - } else { - return param.toString(); - } - } - - private static MethodSignature getSignature(final JoinPoint joinPoint) { - return (MethodSignature) joinPoint.getSignature(); - } -} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/logging/AspectPointcuts.java b/goofy-server/src/main/java/de/itvsh/goofy/common/logging/AspectPointcuts.java deleted file mode 100644 index fede81de07d709a210205b324b9309e54acffcbe..0000000000000000000000000000000000000000 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/logging/AspectPointcuts.java +++ /dev/null @@ -1,27 +0,0 @@ -package de.itvsh.goofy.common.logging; - -import org.aspectj.lang.annotation.Pointcut; - -public class AspectPointcuts { - - @Pointcut("execution(public * *(..))") - void anyPublicMethods() { - // aspect pointcut - no implementation needed - } - - @Pointcut("within(de.itvsh..*)") - void anythingInKOP() { - // aspect pointcut - no implementation needed - } - - @Pointcut("anyPublicMethods() && anythingInKOP()") - void anyPublicMethodInKOP() { - // aspect pointcut - no implementation needed - } - - @Pointcut("anyPublicMethodInKOP() && @target(org.springframework.stereotype.Service)") - void anyPublicServiceMethod() { - // aspect pointcut - no implementation needed - } - -} diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/logging/KopLoggingAspect.java b/goofy-server/src/main/java/de/itvsh/goofy/common/logging/KopLoggingAspect.java deleted file mode 100644 index f2880b3520571f07bbfee0ba751e624857bc8fe8..0000000000000000000000000000000000000000 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/logging/KopLoggingAspect.java +++ /dev/null @@ -1,28 +0,0 @@ -package de.itvsh.goofy.common.logging; - -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.annotation.AfterReturning; -import org.aspectj.lang.annotation.AfterThrowing; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.springframework.stereotype.Component; - -@Aspect -@Component -public class KopLoggingAspect extends AspectPointcuts { - - @Before("anyPublicServiceMethod()") - public void onServiceMethod(JoinPoint joinPoint) { - AspectLoggingUtils.log(joinPoint); - } - - @AfterThrowing(pointcut = "anyPublicServiceMethod()", throwing = "ex") - public void afterExceptionInServiceMethod(JoinPoint joinPoint, Exception ex) { - AspectLoggingUtils.logException(joinPoint, ex); - } - - @AfterReturning(pointcut = "anyPublicServiceMethod()", returning = "returnValue") - public void afterServiceMethod(JoinPoint joinPoint, Object returnValue) { - AspectLoggingUtils.logReturnValue(joinPoint, returnValue); - } -} diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/user/UserId.java b/goofy-server/src/main/java/de/itvsh/goofy/common/user/UserId.java index bd3e18528400f4cbc04d106987f0c7f00e495d2a..f76a8935b9ce462c2dd0eefdd973207d24408c3e 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/user/UserId.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/user/UserId.java @@ -2,7 +2,7 @@ package de.itvsh.goofy.common.user; import java.util.UUID; -import de.itvsh.goofy.common.datatypes.StringBasedValue; +import de.itvsh.kop.common.datatype.StringBasedValue; import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/user/keycloak/KeycloakUnavailableException.java b/goofy-server/src/main/java/de/itvsh/goofy/common/user/keycloak/KeycloakUnavailableException.java index e59a6baf2e14ad7393c708cdcf741a6648b845e0..585b6f8d73f4813067a97607d5799de0661a9341 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/user/keycloak/KeycloakUnavailableException.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/user/keycloak/KeycloakUnavailableException.java @@ -1,6 +1,6 @@ package de.itvsh.goofy.common.user.keycloak; -import de.itvsh.goofy.common.errorhandling.TechnicalException; +import de.itvsh.kop.common.errorhandling.TechnicalException; public class KeycloakUnavailableException extends TechnicalException { diff --git a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailService.java b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailService.java index eb390c50eaa851cbdb9920e9c85b14a3529a39fd..789ebe855ae3446f964e90868a9ace0def327e1a 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachMailService.java @@ -4,6 +4,7 @@ import java.util.Objects; import java.util.stream.Stream; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import de.itvsh.goofy.common.errorhandling.ResourceNotFoundException; @@ -18,8 +19,7 @@ class PostfachMailService { @Autowired private PostfachMailRemoteService remoteService; - // FIXME - reenable async sending -// @Async + @Async public void sendPostfachMail(String commandId, PostfachMail postfachMail) { try { remoteService.sendPostfachMail(commandId, postfachMail); @@ -39,8 +39,7 @@ class PostfachMailService { } - // FIXME - reenable async sending -// @Async + @Async public void resendPostfachMail(String commandId, String postfachMailId) { try { remoteService.resendPostfachMail(commandId, postfachMailId); diff --git a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachNachrichtId.java b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachNachrichtId.java index 1581ba364a276c134ff642384cbf93d32d960d62..046d8023f16612fe87f5fe44baf1211b6e63d1b4 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachNachrichtId.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/postfach/PostfachNachrichtId.java @@ -1,6 +1,6 @@ package de.itvsh.goofy.postfach; -import de.itvsh.goofy.common.datatypes.StringBasedValue; +import de.itvsh.kop.common.datatype.StringBasedValue; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) diff --git a/goofy-server/src/test/java/de/itvsh/goofy/RequestIdFilterTest.java b/goofy-server/src/test/java/de/itvsh/goofy/RequestIdFilterTest.java index 337a9fc3167bbbdba7c16d437b0a1c0ff47586be..e4ba57cc4d4a68aa067dfe8083eb15aec444d90d 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/RequestIdFilterTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/RequestIdFilterTest.java @@ -1,5 +1,7 @@ package de.itvsh.goofy; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.io.IOException; @@ -24,6 +26,8 @@ class RequestIdFilterTest { private HttpServletRequest request; @Mock private HttpServletResponse response; + @Mock + private CallScope callScope; @Spy private RequestAttributes attributes; @@ -35,6 +39,22 @@ class RequestIdFilterTest { verify(filterChain).doFilter(request, response); } + @Test + void shouldStartCallScope() { + callDoFilterInternal(); + + verify(callScope).startScope(); + } + + @Test + void shouldEndCallScopeAfterException() throws IOException, ServletException { + doThrow(RuntimeException.class).when(filterChain).doFilter(any(), any()); + + assertThrows(RuntimeException.class, this::callDoFilterInternal); + + verify(callScope).endScope(); + } + private void callDoFilterInternal() { try { filter.doFilterInternal(request, response, filterChain); diff --git a/goofy-server/src/test/java/de/itvsh/goofy/TestUtils.java b/goofy-server/src/test/java/de/itvsh/goofy/TestUtils.java deleted file mode 100644 index 49b5432360c36a49ae4423d50283efb34f079e3b..0000000000000000000000000000000000000000 --- a/goofy-server/src/test/java/de/itvsh/goofy/TestUtils.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.itvsh.goofy; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Objects; -import java.util.function.Consumer; - -import org.apache.commons.io.IOUtils; - -public class TestUtils { - - public static final Consumer<Object> DUMMY_CONSUMER = t -> { - }; - - private TestUtils() { - } - - public static InputStream loadFile(final String fileName) { - InputStream stream = TestUtils.class.getClassLoader().getResourceAsStream(fileName); - if (stream == null) { - throw new RuntimeException("File '" + fileName + "' not found."); // NOSONAR - } - return stream; - } - - public static String loadTextFile(final String fileName) { - try { - return IOUtils.toString(loadFile(fileName), "UTF-8"); - } catch (IOException e) { - throw new RuntimeException(e); // NOSONAR - } - } - - public static String loadTextFile(final String fileName, final String... args) { - return String.format(loadTextFile(fileName), (Object[]) args); - } - - public static String addQuote(String str) { - return Objects.isNull(str) ? "null" : String.format("\"%s\"", str); - } -} diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandControllerTest.java index f067ff566c3267325f8c5ff8283fe5074f42e8f8..d236cc09f36a31403d08c3ca6fbc5073c93c79bd 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandControllerTest.java @@ -22,7 +22,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import de.itvsh.goofy.TestUtils; import de.itvsh.goofy.common.command.CommandController.CommandByRelationController; import de.itvsh.goofy.common.errorhandling.ExceptionController; import de.itvsh.goofy.postfach.PostfachMail; @@ -31,6 +30,7 @@ import de.itvsh.goofy.postfach.PostfachMailTestFactory; import de.itvsh.goofy.vorgang.VorgangController; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; import de.itvsh.goofy.vorgang.VorgangWithEingangTestFactory; +import de.itvsh.kop.common.test.TestUtils; class CommandControllerTest { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandITCase.java index 42bca1dedefdcb21b6d4b8df4c3acd557ba1dc05..d47c6f5b90cfe820caa07e4cad0b9721c261cf97 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/command/CommandITCase.java @@ -1,6 +1,5 @@ package de.itvsh.goofy.common.command; -import static de.itvsh.goofy.TestUtils.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -29,6 +28,7 @@ import de.itvsh.goofy.vorgang.RedirectRequestTestFactory; import de.itvsh.goofy.vorgang.VorgangController; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; import de.itvsh.goofy.vorgang.VorgangWithEingangTestFactory; +import de.itvsh.kop.common.test.TestUtils; @AutoConfigureMockMvc @SpringBootTest @@ -62,8 +62,9 @@ public class CommandITCase { } private void createCommand() throws Exception { - String content = loadTextFile("jsonTemplates/command/createCommandWithBody.json.tmpl", CommandOrder.ASSIGN_USER.name(), - loadTextFile("jsonTemplates/command/commandAssignedToBody", addQuote("/api/users/" + UserTestFactory.ID.toString()))); + String content = TestUtils.loadTextFile("jsonTemplates/command/createCommandWithBody.json.tmpl", CommandOrder.ASSIGN_USER.name(), + TestUtils.loadTextFile("jsonTemplates/command/commandAssignedToBody", + TestUtils.addQuote("/api/users/" + UserTestFactory.ID.toString()))); String url = String.format("/api/vorgangs/%s/relations/%s/%d/commands", VorgangHeaderTestFactory.ID, VorgangHeaderTestFactory.ID, VorgangHeaderTestFactory.VERSION); @@ -162,7 +163,8 @@ public class CommandITCase { @Test void shouldReturnErrorOnNullSubject() throws Exception { - String content = PostfachMailTestFactory.buildSendPostfachMailContent(PostfachMailTestFactory.createBuilder().subject(null).build()); + String content = PostfachMailTestFactory + .buildSendPostfachMailContent(PostfachMailTestFactory.createBuilder().subject(null).build()); doRequest(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) @@ -186,7 +188,8 @@ public class CommandITCase { @Test void shouldReturnErrorOnNull() throws Exception { - String content = PostfachMailTestFactory.buildSendPostfachMailContent(PostfachMailTestFactory.createBuilder().mailBody(null).build()); + String content = PostfachMailTestFactory + .buildSendPostfachMailContent(PostfachMailTestFactory.createBuilder().mailBody(null).build()); doRequest(content).andExpect(status().isUnprocessableEntity()) .andExpect(jsonPath("$.issues.length()").value(1)) diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenServiceTest.java index 13c5c483a75aa5e85dab7a49d1283ca3923549ed..7a30c57dbfa929d39f5d3fe4f0a04689de3386e4 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/downloadtoken/DownloadTokenServiceTest.java @@ -18,10 +18,10 @@ import org.mockito.Mock; import com.auth0.jwt.exceptions.JWTVerificationException; import de.itvsh.goofy.JwtTokenUtil; -import de.itvsh.goofy.common.errorhandling.TechnicalException; import de.itvsh.goofy.common.user.CurrentUserService; import de.itvsh.goofy.common.user.GoofyUser; import de.itvsh.goofy.common.user.UserTestFactory; +import de.itvsh.kop.common.errorhandling.TechnicalException; class DownloadTokenServiceTest { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/ExceptionControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/ExceptionControllerTest.java index b31d8aebfcb24aa4cfd07c3de46ab2e60e93ab9a..f66d2f8125f74314f2aaf02c921696a5e89fd093 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/ExceptionControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/ExceptionControllerTest.java @@ -20,6 +20,7 @@ import org.springframework.security.access.AccessDeniedException; import com.thedeanda.lorem.LoremIpsum; import de.itvsh.goofy.common.user.keycloak.KeycloakUnavailableException; +import de.itvsh.kop.common.errorhandling.TechnicalException; class ExceptionControllerTest { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/ExceptionUtilTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/ExceptionUtilTest.java deleted file mode 100644 index 8427a151cbb15a98ec2a5e3d76f8835beee35436..0000000000000000000000000000000000000000 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/ExceptionUtilTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.itvsh.goofy.common.errorhandling; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.Test; - -class ExceptionUtilTest { - - @Test - void shouldFormatMessage() { - var formattedMessage = ExceptionUtil.formatMessageWithExceptionId("Test message", "42"); - - assertThat(formattedMessage).isEqualTo("Test message (ExceptionId: 42)"); - } -} \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/TechnicalExceptionTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/TechnicalExceptionTest.java deleted file mode 100644 index 97d801daef37369a8c6a90e0f9d20441073910e6..0000000000000000000000000000000000000000 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/errorhandling/TechnicalExceptionTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.itvsh.goofy.common.errorhandling; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.Test; - -import com.thedeanda.lorem.LoremIpsum; - -class TechnicalExceptionTest { - - private final String MESSAGE = LoremIpsum.getInstance().getWords(5); - - @Test - void shouldIncludeExceptionId() { - var exception = new TechnicalException(MESSAGE, new Throwable()); - - assertThat(exception.getMessage()).contains(exception.getExceptionId()); - assertThat(exception.getExceptionId()).isNotNull(); - } -} \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/user/UserProfileServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/user/UserProfileServiceTest.java index 722745c05c161f312d8a7764b966636ac96619a5..614dcb1c460bc7f5471f7813ffb11524b19aef3a 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/user/UserProfileServiceTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/user/UserProfileServiceTest.java @@ -13,8 +13,8 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import de.itvsh.goofy.TestUtils; import de.itvsh.goofy.common.errorhandling.ResourceNotFoundException; +import de.itvsh.kop.common.test.TestUtils; class UserProfileServiceTest { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandTestFactory.java index fa97738c1788b0fb6276d936708cd283c7d45bce..bc63fa6ddad582ece5e180fbb984507bd1fc0af2 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/kommentar/KommentarCommandTestFactory.java @@ -2,9 +2,9 @@ package de.itvsh.goofy.kommentar; import java.util.Objects; -import de.itvsh.goofy.TestUtils; import de.itvsh.goofy.common.command.CommandOrder; import de.itvsh.goofy.common.command.CommandTestFactory; +import de.itvsh.kop.common.test.TestUtils; public class KommentarCommandTestFactory { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailITCase.java index a677b42957289cf2f8f6c4ac6df124e83178e4a0..307738b87ea4cd29579b2845be5be1d0356e9bf6 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailITCase.java @@ -6,11 +6,15 @@ import static org.mockito.Mockito.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.util.ReflectionTestUtils; +import de.itvsh.goofy.CallScope; import de.itvsh.goofy.common.command.CommandTestFactory; import de.itvsh.goofy.vorgang.EingangTestFactory; import de.itvsh.goofy.vorgang.VorgangController; @@ -24,23 +28,33 @@ public class PostfachMailITCase { @Autowired private PostfachMailController controller; - @MockBean + @SpyBean private PostfachMailRemoteService postfachRemoteService; - @MockBean + @Mock private PostfachServiceBlockingStub serviceStub; @MockBean private VorgangController vorgangController; + @Autowired + private CallScope callScope; + + @BeforeEach + void initTest() { + ReflectionTestUtils.setField(postfachRemoteService, "serviceStub", serviceStub); + + callScope.startScope(); + } + @Nested @WithMockUser class TestSendeMail { @Test void shouldCallPostfachGrpc() throws InterruptedException { + controller.sendPostfachMail(CommandTestFactory.ID, PostfachMailTestFactory.createLikeFromClient()); - Thread.sleep(2000); - verify(postfachRemoteService).sendPostfachMail(anyString(), any()); + verify(serviceStub, after(2000)).sendPostfachMail(any()); } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailTestFactory.java index 804953464a9522c20b9583d0ed6adee3a99dbfcf..4a5be66b3c81fa2a0d6a5e340820b57fb90ca085 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/postfach/PostfachMailTestFactory.java @@ -1,20 +1,18 @@ package de.itvsh.goofy.postfach; -import static de.itvsh.goofy.TestUtils.*; - import java.time.ZonedDateTime; import java.util.List; import java.util.UUID; import com.thedeanda.lorem.LoremIpsum; -import de.itvsh.goofy.TestUtils; import de.itvsh.goofy.common.binaryfile.FileId; import de.itvsh.goofy.common.command.CommandOrder; import de.itvsh.goofy.common.user.UserId; import de.itvsh.goofy.common.user.UserTestFactory; import de.itvsh.goofy.postfach.PostfachMail.Direction; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; +import de.itvsh.kop.common.test.TestUtils; public class PostfachMailTestFactory { @@ -74,8 +72,8 @@ public class PostfachMailTestFactory { public static String buildSendPostfachMailContent(PostfachMail postfachMail) { return TestUtils.loadTextFile("jsonTemplates/command/createCommandWithPostfachMail.json.tmpl", CommandOrder.SEND_POSTFACH_MAIL.name(), postfachMail.getReplyOption().name(), - addQuote(postfachMail.getSubject()), - addQuote(postfachMail.getMailBody())); + TestUtils.addQuote(postfachMail.getSubject()), + TestUtils.addQuote(postfachMail.getMailBody())); } public static String buildResendPostfachMailContent() { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/RedirectRequestTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/RedirectRequestTestFactory.java index 961a1b7246eb7e6902284413a4b56388ab29002e..dc35eb9d4e7624ea5983e5c7af3f441d1c4ea5c2 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/RedirectRequestTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/RedirectRequestTestFactory.java @@ -1,9 +1,7 @@ package de.itvsh.goofy.vorgang; -import static de.itvsh.goofy.TestUtils.*; - -import de.itvsh.goofy.TestUtils; import de.itvsh.goofy.common.command.CreateCommand; +import de.itvsh.kop.common.test.TestUtils; public class RedirectRequestTestFactory { @@ -23,7 +21,7 @@ public class RedirectRequestTestFactory { public static String createRedirectRequestContent(CreateCommand command) { return TestUtils.loadTextFile("jsonTemplates/command/createCommandWithRedirectRequest.json.tmpl", command.getOrder().name(), - addQuote(command.getRedirectRequest().getEmail()), - addQuote(command.getRedirectRequest().getPassword())); + TestUtils.addQuote(command.getRedirectRequest().getEmail()), + TestUtils.addQuote(command.getRedirectRequest().getPassword())); } } \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandTestFactory.java index 0e9132895543034f69788c940bb32b3776bbfdb7..286f8abac1ec525e47d68f2a88da9517d00c3961 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/wiedervorlage/WiedervorlageCommandTestFactory.java @@ -5,9 +5,9 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; -import de.itvsh.goofy.TestUtils; import de.itvsh.goofy.common.command.CommandOrder; import de.itvsh.goofy.common.command.CommandTestFactory; +import de.itvsh.kop.common.test.TestUtils; public class WiedervorlageCommandTestFactory { diff --git a/pom.xml b/pom.xml index 96afcf5a773f68b6675131a36eb2f99740cd376d..c6684fb949beeefdd234fa2e659ef0bf8cbeb693 100644 --- a/pom.xml +++ b/pom.xml @@ -5,14 +5,14 @@ <groupId>de.itvsh.ozg</groupId> <artifactId>goofy</artifactId> - <version>0.18.0-SNAPSHOT</version> + <version>0.19.0-SNAPSHOT</version> <name>Goofy Parent</name> <packaging>pom</packaging> <parent> <groupId>de.itvsh.kop.common</groupId> <artifactId>kop-common-parent</artifactId> - <version>0.0.1-SNAPSHOT</version> + <version>1.0.0</version> </parent> <modules> @@ -24,7 +24,7 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> - <pluto.version>0.18.0-SNAPSHOT</pluto.version> + <pluto.version>0.18.0</pluto.version> </properties> <dependencyManagement>