From 73936e41eceeba4e40e2c2c7f84a3d266a9a076e Mon Sep 17 00:00:00 2001 From: "Smokowski, Steven" Date: Tue, 1 Oct 2019 09:40:18 -0400 Subject: Improve fall out case handling Update Openstack adapter to handle fall out cases with greater stability Issue-ID: SO-2376 Signed-off-by: Benjamin, Max (mb388a) Change-Id: I20116cbd3b63bb29c9bf4ed99e92bd5f2b691da5 --- .../java/org/onap/so/client/exception/ExceptionBuilder.java | 12 ++++++++---- .../validations/CloudRegionOrchestrationValidator.java | 3 ++- .../adapter/network/mapper/NetworkAdapterObjectMapper.java | 3 ++- .../so/client/adapter/vnf/mapper/VnfAdapterObjectMapper.java | 2 +- .../adapter/vnf/mapper/VnfAdapterVfModuleObjectMapper.java | 2 +- .../network/mapper/NetworkAdapterObjectMapperTest.java | 2 +- .../adapter/vnf/mapper/VnfAdapterObjectMapperTest.java | 5 ++--- .../BuildingBlocks/NetworkMapper/createNetworkRequest.json | 2 +- .../vnfAdapterCreateVfModuleAddonRequest.json | 2 +- .../vnfAdapterCreateVfModuleRequest.json | 2 +- .../vnfAdapterCreateVfModuleRequestDhcpDisabled.json | 2 +- .../vnfAdapterCreateVfModuleRequestMultipleDhcp.json | 2 +- .../vnfAdapterCreateVfModuleRequestNoUserParams.json | 2 +- .../vnfAdapterCreateVfModuleRequestTrueBackout.json | 2 +- .../vnfAdapterCreateVfModuleRequestWithCloudResources.json | 2 +- ...apterCreateVfModuleRequestWithSingleAvailabilityZone.json | 2 +- ...teVfModuleWithNoEnvironmentAndWorkloadContextRequest.json | 2 +- .../vnfAdapterCreateVfModuleWithVolumeGroupRequest.json | 2 +- 18 files changed, 28 insertions(+), 23 deletions(-) (limited to 'bpmn') diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java index c26a1cfecc..903280ce05 100644 --- a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java @@ -26,25 +26,25 @@ import java.io.IOException; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.onap.so.logger.LoggingAnchor; import org.camunda.bpm.engine.delegate.BpmnError; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.onap.aai.domain.yang.LInterface; import org.onap.aai.domain.yang.Vserver; +import org.onap.logging.filter.base.ONAPComponents; +import org.onap.logging.filter.base.ONAPComponentsList; import org.onap.so.bpmn.common.BuildingBlockExecution; import org.onap.so.bpmn.common.DelegateExecutionImpl; import org.onap.so.bpmn.core.WorkflowException; -import org.onap.so.logger.ErrorCode; import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule; import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey; import org.onap.so.bpmn.servicedecomposition.tasks.ExtractPojosForBB; import org.onap.so.client.aai.AAIObjectType; import org.onap.so.client.graphinventory.GraphInventoryCommonObjectMapperProvider; +import org.onap.so.logger.ErrorCode; +import org.onap.so.logger.LoggingAnchor; import org.onap.so.logger.MessageEnum; import org.onap.so.objects.audit.AAIObjectAudit; import org.onap.so.objects.audit.AAIObjectAuditList; -import org.onap.logging.filter.base.ONAPComponentsList; -import org.onap.logging.filter.base.ONAPComponents; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -187,6 +187,10 @@ public class ExceptionBuilder { buildAndThrowWorkflowException(execution, errorCode, msg, extSystemErrorSource); } + /** + * @deprecated Please utilize method that specifies where the failure occured + */ + @Deprecated public void buildAndThrowWorkflowException(BuildingBlockExecution execution, int errorCode, String errorMessage) { if (execution instanceof DelegateExecutionImpl) { buildAndThrowWorkflowException(((DelegateExecutionImpl) execution).getDelegateExecution(), errorCode, diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/validations/CloudRegionOrchestrationValidator.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/validations/CloudRegionOrchestrationValidator.java index 52d294955a..11cac08f57 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/validations/CloudRegionOrchestrationValidator.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/validations/CloudRegionOrchestrationValidator.java @@ -22,6 +22,7 @@ package org.onap.so.bpmn.infrastructure.validations; import java.util.Optional; import java.util.regex.Pattern; +import org.onap.logging.filter.base.ONAPComponents; import org.onap.so.bpmn.common.BuildingBlockExecution; import org.onap.so.bpmn.common.listener.validation.PreBuildingBlockValidator; import org.onap.so.bpmn.servicedecomposition.bbobjects.CloudRegion; @@ -62,7 +63,7 @@ public class CloudRegionOrchestrationValidator implements PreBuildingBlockValida } } catch (Exception e) { logger.error("failed to validate", e); - exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, e); + exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, e, ONAPComponents.SO); } return Optional.empty(); } diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapper.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapper.java index 173e776af9..d78fa69680 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapper.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapper.java @@ -269,6 +269,7 @@ public class NetworkAdapterObjectMapper { org.onap.so.openstack.beans.Subnet.class) == null) { PropertyMap personMap = new PropertyMap() { + @Override protected void configure() { map().setSubnetName(source.getSubnetName()); map(source.getSubnetId(), destination.getSubnetId()); @@ -387,7 +388,7 @@ public class NetworkAdapterObjectMapper { createNetworkRequest.setSkipAAI(true); createNetworkRequest.setBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled())); // TODO confirm value - false by default - createNetworkRequest.setFailIfExists(true); + createNetworkRequest.setFailIfExists(false); // NetworkTechnology(NetworkTechnology.NEUTRON); NOOP - default return createNetworkRequest; } diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterObjectMapper.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterObjectMapper.java index a78870afc4..ebebae3cce 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterObjectMapper.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterObjectMapper.java @@ -78,7 +78,7 @@ public class VnfAdapterObjectMapper { createVolumeGroupRequest.setSkipAAI(true); createVolumeGroupRequest.setSuppressBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled())); - createVolumeGroupRequest.setFailIfExists(true); + createVolumeGroupRequest.setFailIfExists(false); createVolumeGroupRequest.setMsoRequest(createMsoRequest(requestContext, serviceInstance)); diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterVfModuleObjectMapper.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterVfModuleObjectMapper.java index 8c13c9be97..685531e9a7 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterVfModuleObjectMapper.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterVfModuleObjectMapper.java @@ -150,7 +150,7 @@ public class VnfAdapterVfModuleObjectMapper { createVfModuleRequest.setSkipAAI(true); createVfModuleRequest.setBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled())); - createVfModuleRequest.setFailIfExists(true); + createVfModuleRequest.setFailIfExists(false); MsoRequest msoRequest = buildMsoRequest(requestContext, serviceInstance); createVfModuleRequest.setMsoRequest(msoRequest); diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapperTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapperTest.java index d6485bd57f..109dc55294 100644 --- a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapperTest.java +++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/adapter/network/mapper/NetworkAdapterObjectMapperTest.java @@ -106,7 +106,7 @@ public class NetworkAdapterObjectMapperTest extends TestDataSetup { expectedCreateNetworkRequest.setNetworkName(l3Network.getNetworkName()); expectedCreateNetworkRequest.setNetworkType(l3Network.getNetworkType()); expectedCreateNetworkRequest.setBackout(false); - expectedCreateNetworkRequest.setFailIfExists(true); + expectedCreateNetworkRequest.setFailIfExists(false); expectedCreateNetworkRequest.setNetworkTechnology("CONTRAIL"); MsoRequest msoRequest = new MsoRequest(); msoRequest.setRequestId(requestContext.getMsoRequestId()); diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterObjectMapperTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterObjectMapperTest.java index 4450e4a9f4..2e77023757 100644 --- a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterObjectMapperTest.java +++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/adapter/vnf/mapper/VnfAdapterObjectMapperTest.java @@ -34,7 +34,6 @@ import java.util.List; import java.util.Map; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @@ -135,7 +134,7 @@ public class VnfAdapterObjectMapperTest { expectedCreateVolumeGroupRequest.setSkipAAI(true); expectedCreateVolumeGroupRequest .setSuppressBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled())); - expectedCreateVolumeGroupRequest.setFailIfExists(true); + expectedCreateVolumeGroupRequest.setFailIfExists(false); MsoRequest msoRequest = new MsoRequest(); msoRequest.setRequestId(requestContext.getMsoRequestId()); @@ -215,7 +214,7 @@ public class VnfAdapterObjectMapperTest { expectedCreateVolumeGroupRequest.setSkipAAI(true); expectedCreateVolumeGroupRequest .setSuppressBackout(Boolean.TRUE.equals(orchestrationContext.getIsRollbackEnabled())); - expectedCreateVolumeGroupRequest.setFailIfExists(true); + expectedCreateVolumeGroupRequest.setFailIfExists(false); MsoRequest msoRequest = new MsoRequest(); msoRequest.setRequestId(requestContext.getMsoRequestId()); diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/NetworkMapper/createNetworkRequest.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/NetworkMapper/createNetworkRequest.json index d7e282dda7..19d42dddb9 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/NetworkMapper/createNetworkRequest.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/NetworkMapper/createNetworkRequest.json @@ -33,7 +33,7 @@ "policyFqdns": [], "routeTableFqdns": [] }, - "failIfExists": true, + "failIfExists": false, "backout": false, "msoRequest": { "requestId": "6cfde724-76c7-4747-bcb3-67a59a46ca95", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleAddonRequest.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleAddonRequest.json index f655e9aa13..5975cb21fe 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleAddonRequest.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleAddonRequest.json @@ -12,7 +12,7 @@ "baseVfModuleStackId": "baseVfModuleStackId", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequest.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequest.json index 3387b6d87e..19acec0373 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequest.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequest.json @@ -10,7 +10,7 @@ "modelCustomizationUuid": "vfModuleModelCustomizationUuid", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestDhcpDisabled.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestDhcpDisabled.json index 8721bdc865..aa4ada059d 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestDhcpDisabled.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestDhcpDisabled.json @@ -10,7 +10,7 @@ "modelCustomizationUuid": "vfModuleModelCustomizationUuid", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestMultipleDhcp.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestMultipleDhcp.json index 04f64790c4..f7fb1e9f44 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestMultipleDhcp.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestMultipleDhcp.json @@ -10,7 +10,7 @@ "modelCustomizationUuid": "vfModuleModelCustomizationUuid", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestNoUserParams.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestNoUserParams.json index 1b57fcd33c..e06f9cbf36 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestNoUserParams.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestNoUserParams.json @@ -10,7 +10,7 @@ "modelCustomizationUuid": "vfModuleModelCustomizationUuid", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestTrueBackout.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestTrueBackout.json index a13740cf80..b97bab4149 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestTrueBackout.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestTrueBackout.json @@ -10,7 +10,7 @@ "modelCustomizationUuid": "vfModuleModelCustomizationUuid", "skipAAI": true, "backout": true, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestWithCloudResources.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestWithCloudResources.json index 5468e21ee3..7b78510f56 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestWithCloudResources.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestWithCloudResources.json @@ -10,7 +10,7 @@ "modelCustomizationUuid": "vfModuleModelCustomizationUuid", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestWithSingleAvailabilityZone.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestWithSingleAvailabilityZone.json index dd8e62c0a0..83ba299914 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestWithSingleAvailabilityZone.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleRequestWithSingleAvailabilityZone.json @@ -10,7 +10,7 @@ "modelCustomizationUuid": "vfModuleModelCustomizationUuid", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleWithNoEnvironmentAndWorkloadContextRequest.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleWithNoEnvironmentAndWorkloadContextRequest.json index d44b1924cc..aaee92b083 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleWithNoEnvironmentAndWorkloadContextRequest.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleWithNoEnvironmentAndWorkloadContextRequest.json @@ -10,7 +10,7 @@ "modelCustomizationUuid": "vfModuleModelCustomizationUuid", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleWithVolumeGroupRequest.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleWithVolumeGroupRequest.json index 0d103926b9..a419c2ee59 100644 --- a/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleWithVolumeGroupRequest.json +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/BuildingBlocks/VnfAndVfModuleMapper/vnfAdapterCreateVfModuleWithVolumeGroupRequest.json @@ -12,7 +12,7 @@ "volumeGroupStackId": "volumeGroupStackId", "skipAAI": true, "backout": false, - "failIfExists": true, + "failIfExists": false, "msoRequest": { "requestId": "requestId", -- cgit 1.2.3-korg