Skip to content

Commit

Permalink
Merge branch 'master' into MODCON-159
Browse files Browse the repository at this point in the history
  • Loading branch information
azizbekxm authored Oct 10, 2024
2 parents 2378d4b + 24e5bcb commit c9eeca8
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 21 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## 1.2.0 - Unreleased
### Stories
* [MODLD-450](https://folio-org.atlassian.net/browse/MODLD-450) - ECS support for Linked Data

## 1.1.0 - Released (Quesnelia R1 2024)
The focus of this release was to implement ECS tenant soft delete functionality and fix bugs
Expand Down
31 changes: 18 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,24 @@ requires and provides, the permissions, and the additional module metadata.

### Environment variables

| Name | Default value | Description |
|:---------------------|:---------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------|
| DB_HOST | postgres | Postgres hostname |
| DB_PORT | 5432 | Postgres port |
| DB_USERNAME | folio_admin | Postgres username |
| DB_PASSWORD | - | Postgres username password |
| DB_DATABASE | okapi_modules | Postgres database name |
| KAFKA_HOST | kafka | Kafka broker hostname |
| KAFKA_PORT | 9092 | Kafka broker port |
| ENV | folio | Logical name of the deployment, must be set if Kafka/Elasticsearch are shared for environments, `a-z (any case)`, `0-9`, `-`, `_` symbols only allowed |
| OKAPI_URL | http://okapi:9130 | Okapi url |
| SYSTEM_USER_NAME | consortia-system-user | Username of the system user |
| SYSTEM_USER_PASSWORD | - | Password of the system user |
| Name | Default value | Description |
|:------------------------------|:---------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| DB_HOST | postgres | Postgres hostname |
| DB_PORT | 5432 | Postgres port |
| DB_USERNAME | folio_admin | Postgres username |
| DB_PASSWORD | - | Postgres username password |
| DB_DATABASE | okapi_modules | Postgres database name |
| KAFKA_HOST | kafka | Kafka broker hostname |
| KAFKA_PORT | 9092 | Kafka broker port |
| KAFKA_SECURITY_PROTOCOL | PLAINTEXT | Kafka security protocol used to communicate with brokers (SSL or PLAINTEXT) |
| KAFKA_SSL_KEYSTORE_LOCATION | - | The location of the Kafka key store file. This is optional for client and can be used for two-way authentication for client. |
| KAFKA_SSL_KEYSTORE_PASSWORD | - | The store password for the Kafka key store file. This is optional for client and only needed if 'ssl.keystore.location' is configured. |
| KAFKA_SSL_TRUSTSTORE_LOCATION | - | The location of the Kafka trust store file. |
| KAFKA_SSL_TRUSTSTORE_PASSWORD | - | The password for the Kafka trust store file. If a password is not set, trust store file configured will still be used, but integrity checking is disabled. |
| ENV | folio | Logical name of the deployment, must be set if Kafka/Elasticsearch are shared for environments, `a-z (any case)`, `0-9`, `-`, `_` symbols only allowed |
| OKAPI_URL | http://okapi:9130 | Okapi url |
| SYSTEM_USER_NAME | consortia-system-user | Username of the system user |
| SYSTEM_USER_PASSWORD | - | Password of the system user |

## Additional information

Expand Down
33 changes: 32 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
{
"id": "inventory",
"version": "13.0"
"version": "14.0"
}
],
"provides": [
Expand Down Expand Up @@ -387,6 +387,7 @@
"consortia.user-tenants.item.delete",
"consortia.consortia-configuration.item.post",
"consortia.inventory.share.local.instance",
"consortia.inventory.update.ownership",
"consortia.sync-primary-affiliations.item.post",
"consortia.create-primary-affiliations.item.post",
"consortia.sharing-instances.item.post",
Expand Down Expand Up @@ -502,6 +503,16 @@
],
"visible": true
},
{
"permissionName": "consortia.inventory.update.ownership",
"displayName": "Inventory: Update ownership",
"description": "Inventory: Update ownership",
"subPermissions": [
"inventory.holdings.update-ownership.item.post",
"inventory.items.update-ownership.item.post"
],
"visible": true
},
{
"permissionName": "consortia.sharing-instances.item.post",
"displayName": "create sharing instance",
Expand Down Expand Up @@ -588,6 +599,26 @@
"name": "KAFKA_PORT",
"value": "9092"
},
{
"name": "KAFKA_SECURITY_PROTOCOL",
"value": "PLAINTEXT"
},
{
"name": "KAFKA_SSL_KEYSTORE_LOCATION",
"value": ""
},
{
"name": "KAFKA_SSL_KEYSTORE_PASSWORD",
"value": ""
},
{
"name": "KAFKA_SSL_TRUSTSTORE_LOCATION",
"value": ""
},
{
"name": "KAFKA_SSL_TRUSTSTORE_PASSWORD",
"value": ""
},
{
"name": "OKAPI_URL",
"value": "http://okapi:9130"
Expand Down
7 changes: 2 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@

<!-- test dependencies -->
<wiremock-standalone.version>3.0.1</wiremock-standalone.version>
<testcontainers.version>1.19.3</testcontainers.version>
<testcontainers.version>1.20.1</testcontainers.version>
<snakeyaml.version>2.2</snakeyaml.version>
<testcontainers-bom.version>1.19.3</testcontainers-bom.version>
<maven-checkstyle-plugin.version>3.3.1</maven-checkstyle-plugin.version>
</properties>

Expand All @@ -70,7 +69,7 @@
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>${testcontainers-bom.version}</version>
<version>${testcontainers.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down Expand Up @@ -204,13 +203,11 @@
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public UserTenant convert(UserTenantEntity source) {
userTenant.setIsPrimary(source.getIsPrimary());
if (Objects.nonNull(source.getTenant())) {
userTenant.setTenantId(source.getTenant().getId());
userTenant.setTenantName(source.getTenant().getName());
}
return userTenant;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.folio.consortia.repository.SharingInstanceRepository.Specifications.constructSpecification;
import static org.folio.consortia.utils.HelperUtils.CONSORTIUM_FOLIO_INSTANCE_SOURCE;
import static org.folio.consortia.utils.HelperUtils.CONSORTIUM_LINKED_DATA_INSTANCE_SOURCE;
import static org.folio.consortia.utils.HelperUtils.CONSORTIUM_MARC_INSTANCE_SOURCE;
import static org.folio.consortia.utils.TenantContextUtils.prepareContextForTenant;

Expand Down Expand Up @@ -88,6 +89,7 @@ public SharingInstance start(UUID consortiumId, SharingInstance sharingInstance)
String source = switch (inventoryInstance.get("source").asText().toLowerCase()) {
case "folio" -> CONSORTIUM_FOLIO_INSTANCE_SOURCE;
case "marc" -> CONSORTIUM_MARC_INSTANCE_SOURCE;
case "linked_data" -> CONSORTIUM_LINKED_DATA_INSTANCE_SOURCE;
default -> throw new IllegalStateException("source is not recognized");
};
var updatedInventoryInstance = ((ObjectNode) inventoryInstance).set("source", new TextNode(source));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ private UserTenantEntity toEntity(UserTenant userTenantDto, UUID consortiumId, U
UserTenantEntity entity = new UserTenantEntity();
TenantEntity tenant = new TenantEntity();
tenant.setId(userTenantDto.getTenantId());
tenant.setName(userTenantDto.getTenantName());
tenant.setConsortiumId(consortiumId);

if (Objects.nonNull(userTenantDto.getId())) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/folio/consortia/utils/HelperUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class HelperUtils {

public static final String CONSORTIUM_FOLIO_INSTANCE_SOURCE = "CONSORTIUM-FOLIO";
public static final String CONSORTIUM_MARC_INSTANCE_SOURCE = "CONSORTIUM-MARC";
public static final String CONSORTIUM_LINKED_DATA_INSTANCE_SOURCE = "CONSORTIUM-LINKED_DATA";
public static final String CONSORTIUM_SETTING_SOURCE = "consortium";
public static final String LOCAL_SETTING_SOURCE = "local";

Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ spring:
url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_DATABASE:okapi_modules}
kafka:
bootstrap-servers: ${KAFKA_HOST:localhost}:${KAFKA_PORT:9092}
security:
protocol: ${KAFKA_SECURITY_PROTOCOL:PLAINTEXT}
ssl:
key-store-password: ${KAFKA_SSL_KEYSTORE_PASSWORD:}
key-store-location: ${KAFKA_SSL_KEYSTORE_LOCATION:}
trust-store-password: ${KAFKA_SSL_TRUSTSTORE_PASSWORD:}
trust-store-location: ${KAFKA_SSL_TRUSTSTORE_LOCATION:}
sql:
init:
continue-on-error: true
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/swagger.api/schemas/userTenant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ UserTenant:
type: string
tenantId:
type: string
tenantName:
type: string
isPrimary:
type: boolean
centralTenantId:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.folio.consortia.utils.EntityUtils.ACTION_ID;
import static org.folio.consortia.utils.HelperUtils.CONSORTIUM_FOLIO_INSTANCE_SOURCE;
import static org.folio.consortia.utils.EntityUtils.CONSORTIUM_ID;
import static org.folio.consortia.utils.HelperUtils.CONSORTIUM_LINKED_DATA_INSTANCE_SOURCE;
import static org.folio.consortia.utils.HelperUtils.CONSORTIUM_MARC_INSTANCE_SOURCE;
import static org.folio.consortia.utils.EntityUtils.createSharingInstance;
import static org.folio.consortia.utils.EntityUtils.createSharingInstanceEntity;
import static org.mockito.ArgumentMatchers.any;
Expand All @@ -22,6 +25,7 @@
import java.util.Optional;
import java.util.UUID;

import com.fasterxml.jackson.databind.node.TextNode;
import org.folio.consortia.config.kafka.KafkaService;
import org.folio.consortia.domain.dto.SharingInstance;
import org.folio.consortia.domain.dto.Status;
Expand All @@ -33,6 +37,8 @@
import org.folio.spring.integration.XOkapiHeaders;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
Expand Down Expand Up @@ -279,6 +285,57 @@ void shouldPromoteSharingInstanceWithErrorStatus() throws JsonProcessingExceptio
verify(sharingInstanceRepository, times(1)).save(any());
}

@ParameterizedTest
@CsvSource(value = {
"folio, " + CONSORTIUM_FOLIO_INSTANCE_SOURCE,
"marc, " + CONSORTIUM_MARC_INSTANCE_SOURCE,
"linked_data, " + CONSORTIUM_LINKED_DATA_INSTANCE_SOURCE
})
void shouldChangeInventoryRecordSourceToConsortium(String initial, String expected) {
var centralTenant = "mobius";
var targetTenant = "college";
var sharingInstanceEntity = new SharingInstanceEntity();

when(consortiumRepository.existsById(any())).thenReturn(true);
doNothing().when(tenantService).checkTenantExistsOrThrow(anyString());
when(folioExecutionContext.getOkapiHeaders()).thenReturn(headers);
when(tenantService.getCentralTenantId()).thenReturn(centralTenant);
when(conversionService.convert(any(), eq(SharingInstance.class))).thenReturn(toDto(sharingInstanceEntity));
when(sharingInstanceRepository.save(any())).thenReturn(sharingInstanceEntity);

var inventoryInstance = new ObjectMapper().createObjectNode().set("source", new TextNode(initial));
when(inventoryService.getById(any())).thenReturn(inventoryInstance);
doNothing().when(inventoryService).saveInstance(anyString());

sharingInstanceService.start(UUID.randomUUID(), createSharingInstance(instanceIdentifier, centralTenant, targetTenant));
assertThat(inventoryInstance.get("source").textValue()).isEqualTo(expected);
}

@Test
void shouldFailWhenSourceIsNotRecognized() {
var centralTenant = "mobius";
var targetTenant = "college";
var sharingInstance = createSharingInstance(instanceIdentifier, centralTenant, targetTenant);
var sharingInstanceEntity = new SharingInstanceEntity();

when(consortiumRepository.existsById(any())).thenReturn(true);
doNothing().when(tenantService).checkTenantExistsOrThrow(anyString());
when(folioExecutionContext.getOkapiHeaders()).thenReturn(headers);
when(tenantService.getCentralTenantId()).thenReturn(centralTenant);
when(conversionService.convert(any(), eq(SharingInstance.class))).thenReturn(toDto(sharingInstanceEntity));
when(sharingInstanceRepository.save(any())).thenReturn(sharingInstanceEntity);

var inventoryInstance = new ObjectMapper().createObjectNode().set("source", new TextNode("invalid_source"));
when(inventoryService.getById(any())).thenReturn(inventoryInstance);
sharingInstanceService.start(UUID.randomUUID(), sharingInstance);

assertThat(sharingInstance.getStatus()).isEqualTo(Status.ERROR);
assertThat(sharingInstance.getError()).contains("Failed to post inventory instance with reason");
verify(sharingInstanceRepository).findByInstanceAndTenantIds(
sharingInstance.getInstanceIdentifier(), centralTenant, targetTenant);
verify(sharingInstanceRepository).save(any());
}

/* Negative cases */
@Test
void shouldThrowResourceNotFoundExceptionWhenTryingToGetSharingInstanceById() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,7 @@ private ConsortiumEntity createConsortiumEntity() {
private UserTenant createUserTenantDtoEntity() {
UserTenant tenant = new UserTenant();
tenant.setTenantId("diku");
tenant.setTenantName("diku");
tenant.setUserId(UUID.randomUUID());
tenant.setId(UUID.randomUUID());
tenant.setUsername("Test");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.kafka.KafkaContainer;
import org.testcontainers.utility.DockerImageName;

public class KafkaContainerExtension implements BeforeAllCallback, AfterAllCallback {
private static final String SPRING_PROPERTY_NAME = "spring.kafka.bootstrap-servers";
private static final DockerImageName KAFKA_IMAGE = parse("confluentinc/cp-kafka:7.0.3");
private static final DockerImageName KAFKA_IMAGE = parse("apache/kafka-native:3.8.0");
private static final KafkaContainer CONTAINER = new KafkaContainer(KAFKA_IMAGE)
.withEnv("KAFKA_AUTO_CREATE_TOPICS_ENABLE", "false");

Expand Down

0 comments on commit c9eeca8

Please sign in to comment.