Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## v8.0.0 YYYY-mm-DD
### Breaking changes
* Update QuickMARC to use generation field from SRS for optimistic locking ([MODQM-478](https://folio-org.atlassian.net/browse/MODQM-478))
* Upgrade module to SpringBoot 4.0.x and Spring 7.0.x ([MODQM-487](https://folio-org.atlassian.net/browse/MODQM-487))

### New APIs versions
* Provides `API_NAME vX.Y`
Expand Down
24 changes: 12 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.7</version>
<version>4.0.2</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

Expand All @@ -23,7 +23,7 @@
<records-editor-async.yaml.file>${project.basedir}/src/main/resources/swagger.api/records-editor-async.yaml</records-editor-async.yaml.file>
<marc-specifications.yaml.file>${project.basedir}/src/main/resources/swagger.api/marc-specifications.yaml</marc-specifications.yaml.file>

<folio-spring-support.version>10.0.0-SNAPSHOT</folio-spring-support.version>
<folio-spring-support.version>10.0.0-RC1</folio-spring-support.version>
<folio-service-tools.version>5.1.0-SNAPSHOT</folio-service-tools.version>
<mod-record-specifications-validator.version>2.1.0-SNAPSHOT</mod-record-specifications-validator.version>
<marc4j.version>2.9.6</marc4j.version>
Expand All @@ -39,7 +39,7 @@
<maven-failsafe-plugin.version>3.5.4</maven-failsafe-plugin.version>
<maven-release-plugin.version>3.3.1</maven-release-plugin.version>
<maven-checkstyle-plugin.version>3.6.0</maven-checkstyle-plugin.version>
<checkstyle.version>12.1.2</checkstyle.version>
<checkstyle.version>13.0.0</checkstyle.version>
<folio-java-checkstyle.version>1.2.0</folio-java-checkstyle.version>

<sonar.exclusions>
Expand Down Expand Up @@ -85,18 +85,13 @@
</dependency>

<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-kafka</artifactId>
</dependency>

<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
Expand Down Expand Up @@ -141,6 +136,11 @@
</exclusions>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
</dependency>

<dependency>
<groupId>org.folio</groupId>
<artifactId>folio-spring-testing</artifactId>
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/org/folio/qm/ModQuickMarcApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
@EnableFeignClients
public class ModQuickMarcApplication {

public static void main(String[] args) {
Expand Down
19 changes: 9 additions & 10 deletions src/main/java/org/folio/qm/client/ChangeManagerClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,27 @@
import org.folio.qm.client.model.ParsedRecordDto;
import org.folio.qm.client.model.ProfileInfo;
import org.folio.qm.client.model.RawRecordsDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PostExchange;
import org.springframework.web.service.annotation.PutExchange;

@FeignClient(value = "change-manager")
@HttpExchange(url = "change-manager", contentType = MediaType.APPLICATION_JSON_VALUE)
public interface ChangeManagerClient {

@PutMapping(value = "/parsedRecords/{id}")
void putParsedRecordByInstanceId(@PathVariable("id") UUID id, ParsedRecordDto recordDto);
@PutExchange(value = "/parsedRecords/{id}")
void putParsedRecordByInstanceId(@PathVariable("id") UUID id, @RequestBody ParsedRecordDto recordDto);

@PostMapping(value = "/jobExecutions", produces = MediaType.APPLICATION_JSON_VALUE)
@PostExchange(value = "/jobExecutions")
InitJobExecutionsRsDto postJobExecution(@RequestBody InitJobExecutionsRqDto jobExecutionDto);

@PutMapping(value = "/jobExecutions/{jobExecutionId}/jobProfile", produces = MediaType.APPLICATION_JSON_VALUE)
@PutExchange(value = "/jobExecutions/{jobExecutionId}/jobProfile")
void putJobProfileByJobExecutionId(@PathVariable("jobExecutionId") UUID jobExecutionId,
@RequestBody ProfileInfo jobProfile);

@PostMapping(value = "/jobExecutions/{jobExecutionId}/records",
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE})
@PostExchange(value = "/jobExecutions/{jobExecutionId}/records")
void postRawRecordsByJobExecutionId(@PathVariable("jobExecutionId") UUID jobExecutionId,
@RequestBody RawRecordsDto rawRecords);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.folio.qm.client;

import org.folio.qm.client.model.MarcFieldProtectionSettingsCollection;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;

@FeignClient(value = "field-protection-settings")
@HttpExchange(url = "field-protection-settings", accept = MediaType.APPLICATION_JSON_VALUE)
public interface FieldProtectionSettingsClient {

@GetMapping(value = "/marc?limit=1000", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE})
@GetExchange(value = "/marc?limit=1000")
MarcFieldProtectionSettingsCollection getFieldProtectionSettings();
}
8 changes: 4 additions & 4 deletions src/main/java/org/folio/qm/client/LinkingRulesClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import java.util.List;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;

@FeignClient(value = "linking-rules", dismiss404 = true)
@HttpExchange(url = "linking-rules", accept = MediaType.APPLICATION_JSON_VALUE)
public interface LinkingRulesClient {

@GetMapping(value = "instance-authority", produces = MediaType.APPLICATION_JSON_VALUE)
@GetExchange(value = "instance-authority")
List<LinkingRuleDto> fetchLinkingRules();

@Data
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/org/folio/qm/client/LinksClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PutExchange;

@FeignClient(value = "links", dismiss404 = true)
@HttpExchange(url = "links", contentType = MediaType.APPLICATION_JSON_VALUE)
public interface LinksClient {

@GetMapping(value = "/instances/{instanceId}", produces = MediaType.APPLICATION_JSON_VALUE)
@GetExchange(value = "/instances/{instanceId}")
Optional<InstanceLinks> fetchLinksByInstanceId(@PathVariable("instanceId") UUID instanceId);

@PutMapping("/instances/{instanceId}")
void putLinksByInstanceId(@PathVariable("instanceId") UUID instanceId, InstanceLinks instanceLinks);
@PutExchange("/instances/{instanceId}")
void putLinksByInstanceId(@PathVariable("instanceId") UUID instanceId, @RequestBody InstanceLinks instanceLinks);

record InstanceLinks(List<InstanceLink> links, Integer totalRecords) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import org.folio.qm.client.model.EntitiesLinksSuggestions;
import org.folio.qm.domain.dto.AuthoritySearchParameter;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.HttpExchange;

@FeignClient(value = "links-suggestions", dismiss404 = true)
@HttpExchange(url = "links-suggestions", accept = MediaType.APPLICATION_JSON_VALUE)
public interface LinksSuggestionsClient {

@PostMapping("/marc")
@HttpExchange("/marc")
EntitiesLinksSuggestions postLinksSuggestions(EntitiesLinksSuggestions srsMarcRecord,
@RequestParam AuthoritySearchParameter authoritySearchParameter,
@RequestParam Boolean ignoreAutoLinkingEnabled);
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/org/folio/qm/client/SourceStorageClient.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package org.folio.qm.client;

import java.util.Optional;
import org.folio.qm.client.model.SourceRecord;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;

@FeignClient(value = "source-storage")
@HttpExchange(url = "source-storage", accept = MediaType.APPLICATION_JSON_VALUE)
public interface SourceStorageClient {

@GetMapping(value = "/source-records/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
SourceRecord getSourceRecord(@PathVariable("id") String id, @RequestParam("idType") IdType idType);
@GetExchange(value = "/source-records/{id}")
Optional<SourceRecord> getSourceRecord(@PathVariable("id") String id, @RequestParam("idType") IdType idType);

enum IdType {
EXTERNAL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@
import java.util.UUID;
import org.folio.rspec.domain.dto.SpecificationDto;
import org.folio.rspec.domain.dto.SpecificationDtoCollection;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;

@FeignClient(value = "specification-storage")
@HttpExchange(url = "specification-storage", contentType = MediaType.APPLICATION_JSON_VALUE)
public interface SpecificationStorageClient {

@GetMapping(value = "/specifications?family=MARC&include=all&limit=1",
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE})
@GetExchange(value = "/specifications?family=MARC&include=all&limit=1")
SpecificationDtoCollection getSpecifications(@RequestParam("profile") String profile);

@GetMapping(value = "/specifications/{specificationId}?include=all",
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE})
@GetExchange(value = "/specifications/{specificationId}?include=all")
SpecificationDto getSpecification(@PathVariable("specificationId") UUID specificationId);
}
8 changes: 4 additions & 4 deletions src/main/java/org/folio/qm/client/UsersClient.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package org.folio.qm.client;

import java.util.Optional;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;

@FeignClient(value = "users", dismiss404 = true)
@HttpExchange(url = "users", accept = MediaType.APPLICATION_JSON_VALUE)
public interface UsersClient {

@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@GetExchange(value = "/{id}")
Optional<UserDto> fetchUserById(@PathVariable("id") String id);

record UserDto(String id, String username, UserPersonal personal) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/folio/qm/config/CacheConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.ArrayList;
import java.util.Collection;
import org.folio.qm.config.properties.CustomCacheProperties;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.cache.autoconfigure.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
Expand Down
57 changes: 57 additions & 0 deletions src/main/java/org/folio/qm/config/HttpClientConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.folio.qm.config;

import org.folio.qm.client.ChangeManagerClient;
import org.folio.qm.client.FieldProtectionSettingsClient;
import org.folio.qm.client.LinkingRulesClient;
import org.folio.qm.client.LinksClient;
import org.folio.qm.client.LinksSuggestionsClient;
import org.folio.qm.client.SourceStorageClient;
import org.folio.qm.client.SpecificationStorageClient;
import org.folio.qm.client.UsersClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;

@Configuration
public class HttpClientConfiguration {

@Bean
public ChangeManagerClient changeManagerClient(HttpServiceProxyFactory factory) {
return factory.createClient(ChangeManagerClient.class);
}

@Bean
public FieldProtectionSettingsClient fieldProtectionSettingsClient(HttpServiceProxyFactory factory) {
return factory.createClient(FieldProtectionSettingsClient.class);
}

@Bean
public LinkingRulesClient linkingRulesClient(HttpServiceProxyFactory factory) {
return factory.createClient(LinkingRulesClient.class);
}

@Bean
public LinksClient linksClient(HttpServiceProxyFactory factory) {
return factory.createClient(LinksClient.class);
}

@Bean
public LinksSuggestionsClient linksSuggestionsClient(HttpServiceProxyFactory factory) {
return factory.createClient(LinksSuggestionsClient.class);
}

@Bean
public SourceStorageClient sourceStorageClient(HttpServiceProxyFactory factory) {
return factory.createClient(SourceStorageClient.class);
}

@Bean
public SpecificationStorageClient specificationStorageClient(HttpServiceProxyFactory factory) {
return factory.createClient(SpecificationStorageClient.class);
}

@Bean
public UsersClient usersClient(HttpServiceProxyFactory factory) {
return factory.createClient(UsersClient.class);
}
}
12 changes: 6 additions & 6 deletions src/main/java/org/folio/qm/config/KafkaConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
import org.folio.qm.messaging.domain.QmCompletedEventPayload;
import org.folio.rspec.domain.dto.SpecificationUpdatedEvent;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.boot.kafka.autoconfigure.KafkaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.support.serializer.JsonDeserializer;
import org.springframework.kafka.support.serializer.JacksonJsonDeserializer;

@Configuration
@EnableKafka
Expand All @@ -33,7 +33,7 @@ public String kafkaEnvId(@Value("${ENV:folio}") String envId) {
public ConsumerFactory<String, DataImportEventPayload> dataImportConsumerFactory(KafkaProperties kafkaProperties,
Deserializer<DataImportEventPayload>
deserializer) {
Map<String, Object> consumerProperties = new HashMap<>(kafkaProperties.buildConsumerProperties(null));
Map<String, Object> consumerProperties = new HashMap<>(kafkaProperties.buildConsumerProperties());
consumerProperties.put(KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
consumerProperties.put(VALUE_DESERIALIZER_CLASS_CONFIG, deserializer);
return new DefaultKafkaConsumerFactory<>(consumerProperties, new StringDeserializer(), deserializer);
Expand All @@ -52,7 +52,7 @@ public ConsumerFactory<String, DataImportEventPayload> dataImportConsumerFactory
public ConsumerFactory<String, QmCompletedEventPayload> quickMarcConsumerFactory(KafkaProperties kafkaProperties,
Deserializer<QmCompletedEventPayload>
deserializer) {
Map<String, Object> consumerProperties = new HashMap<>(kafkaProperties.buildConsumerProperties(null));
Map<String, Object> consumerProperties = new HashMap<>(kafkaProperties.buildConsumerProperties());
consumerProperties.put(KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
consumerProperties.put(VALUE_DESERIALIZER_CLASS_CONFIG, deserializer);
return new DefaultKafkaConsumerFactory<>(consumerProperties, new StringDeserializer(), deserializer);
Expand All @@ -70,8 +70,8 @@ public ConsumerFactory<String, QmCompletedEventPayload> quickMarcConsumerFactory
@Bean
public ConsumerFactory<String, SpecificationUpdatedEvent> specificationUpdatedConsumerFactory(
KafkaProperties kafkaProperties) {
var deserializer = new JsonDeserializer<>(SpecificationUpdatedEvent.class, false);
Map<String, Object> consumerProperties = new HashMap<>(kafkaProperties.buildConsumerProperties(null));
var deserializer = new JacksonJsonDeserializer<>(SpecificationUpdatedEvent.class, false);
Map<String, Object> consumerProperties = new HashMap<>(kafkaProperties.buildConsumerProperties());
consumerProperties.put(KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
consumerProperties.put(VALUE_DESERIALIZER_CLASS_CONFIG, deserializer);
return new DefaultKafkaConsumerFactory<>(consumerProperties, new StringDeserializer(), deserializer);
Expand Down
Loading
Loading