From ccf72b37d15930a8ede20ec4391b776cc60bf3c5 Mon Sep 17 00:00:00 2001 From: liamfallon Date: Thu, 7 Nov 2019 21:33:12 +0000 Subject: Fix vCPE example apex-pdp policy The changes in policy-models for appclcm had knock-on impacts on the apex-pdp example policies. This patch fixes the vCPE policy to comply with the new APPCLCM POJOs. Issue-ID: POLICY-2043 Change-Id: Ieebc2cf97a05efde560a2f5a819924ff63dfd695 Signed-off-by: liamfallon --- .../examples/config/ONAPvCPE/ApexConfig.json | 8 ---- .../examples/config/ONAPvCPE/ApexConfigStdin.json | 8 ---- .../examples/config/ONAPvCPE/ApexConfig_Sim.json | 8 ---- .../config/ONAPvCPE/ApexConfig_Sim_StdIO.json | 8 ---- .../resources/logic/APPCRestartVNFRequestTask.js | 46 +++++++++++++--------- .../resources/logic/APPCRestartVNFResponseTask.js | 44 +++++++++++++++------ .../src/main/resources/logic/ControlLoopLogTask.js | 2 +- .../main/resources/policy/ONAPvCPEPolicyModel.apex | 4 +- .../domains/onap/vcpe/AppcResponseCreator.java | 32 ++++++--------- .../domains/onap/vcpe/OnapVCpeSimEndpoint.java | 11 ++++-- 10 files changed, 82 insertions(+), 89 deletions(-) (limited to 'examples') diff --git a/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig.json b/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig.json index 862bba296..ce97eeb09 100644 --- a/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig.json +++ b/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig.json @@ -24,14 +24,6 @@ "Instant": { "adaptedClass": "java.time.Instant", "adaptorClass": "org.onap.policy.controlloop.util.Serialization$GsonInstantAdapter" - }, - "APPC_LCM_REQUEST": { - "adaptedClass": "org.onap.policy.appclcm.LcmRequest", - "adaptorClass": "org.onap.policy.appclcm.util.Serialization$RequestAdapter" - }, - "APPC_LCM_RESPONSE": { - "adaptedClass": "org.onap.policy.appclcm.LcmResponse", - "adaptorClass": "org.onap.policy.appclcm.util.Serialization$ResponseAdapter" } } } diff --git a/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfigStdin.json b/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfigStdin.json index 12d72bccb..aa37f7ab2 100644 --- a/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfigStdin.json +++ b/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfigStdin.json @@ -24,14 +24,6 @@ "Instant": { "adaptedClass": "java.time.Instant", "adaptorClass": "org.onap.policy.controlloop.util.Serialization$GsonInstantAdapter" - }, - "APPC_LCM_REQUEST": { - "adaptedClass": "org.onap.policy.appclcm.LcmRequest", - "adaptorClass": "org.onap.policy.appclcm.util.Serialization$RequestAdapter" - }, - "APPC_LCM_RESPONSE": { - "adaptedClass": "org.onap.policy.appclcm.LcmResponse", - "adaptorClass": "org.onap.policy.appclcm.util.Serialization$ResponseAdapter" } } } diff --git a/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig_Sim.json b/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig_Sim.json index 5bae09e7e..46c03af05 100644 --- a/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig_Sim.json +++ b/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig_Sim.json @@ -24,14 +24,6 @@ "Instant": { "adaptedClass": "java.time.Instant", "adaptorClass": "org.onap.policy.controlloop.util.Serialization$GsonInstantAdapter" - }, - "APPC_LCM_REQUEST": { - "adaptedClass": "org.onap.policy.appclcm.LcmRequest", - "adaptorClass": "org.onap.policy.appclcm.util.Serialization$RequestAdapter" - }, - "APPC_LCM_RESPONSE": { - "adaptedClass": "org.onap.policy.appclcm.LcmResponse", - "adaptorClass": "org.onap.policy.appclcm.util.Serialization$ResponseAdapter" } } } diff --git a/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig_Sim_StdIO.json b/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig_Sim_StdIO.json index a903cb3c2..052568111 100644 --- a/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig_Sim_StdIO.json +++ b/examples/examples-onap-vcpe/src/main/resources/examples/config/ONAPvCPE/ApexConfig_Sim_StdIO.json @@ -24,14 +24,6 @@ "Instant": { "adaptedClass": "java.time.Instant", "adaptorClass": "org.onap.policy.controlloop.util.Serialization$GsonInstantAdapter" - }, - "APPC_LCM_REQUEST": { - "adaptedClass": "org.onap.policy.appclcm.LcmRequest", - "adaptorClass": "org.onap.policy.appclcm.util.Serialization$RequestAdapter" - }, - "APPC_LCM_RESPONSE": { - "adaptedClass": "org.onap.policy.appclcm.LcmResponse", - "adaptorClass": "org.onap.policy.appclcm.util.Serialization$ResponseAdapter" } } } diff --git a/examples/examples-onap-vcpe/src/main/resources/logic/APPCRestartVNFRequestTask.js b/examples/examples-onap-vcpe/src/main/resources/logic/APPCRestartVNFRequestTask.js index 7d17e25bc..dd69dcb1d 100644 --- a/examples/examples-onap-vcpe/src/main/resources/logic/APPCRestartVNFRequestTask.js +++ b/examples/examples-onap-vcpe/src/main/resources/logic/APPCRestartVNFRequestTask.js @@ -21,34 +21,44 @@ executor.logger.info(executor.subject.id); executor.logger.info(executor.inFields); -var appcRequest = new org.onap.policy.appclcm.LcmRequestWrapper; -appcRequest.setBody(new org.onap.policy.appclcm.LcmRequest); -appcRequest.getBody().setCommonHeader(new org.onap.policy.appclcm.LcmCommonHeader); +var appcRequest = new org.onap.policy.appclcm.AppcLcmDmaapWrapper; +appcRequest.setBody(new org.onap.policy.appclcm.AppcLcmBody); +appcRequest.getBody().setInput(new org.onap.policy.appclcm.AppcLcmInput); +appcRequest.getBody().getInput().setCommonHeader( + new org.onap.policy.appclcm.AppcLcmCommonHeader); appcRequest.setVersion("2.0.0"); appcRequest.setRpcName("restart"); appcRequest.setCorrelationId(executor.inFields.get("requestID")); appcRequest.setType("request"); -var vcpeClosedLoopStatus = executor.getContextAlbum("VCPEClosedLoopStatusAlbum").get(executor.inFields.get("vnfID").toString()); +var vcpeClosedLoopStatus = executor + .getContextAlbum("VCPEClosedLoopStatusAlbum").get( + executor.inFields.get("vnfID").toString()); -appcRequest.getBody().getCommonHeader().setTimeStamp(java.time.Instant.now()); -appcRequest.getBody().getCommonHeader().setApiVer("2.00"); -appcRequest.getBody().getCommonHeader().setOriginatorId(executor.inFields.get("requestID").toString()); -appcRequest.getBody().getCommonHeader().setRequestId(executor.inFields.get("requestID")); -appcRequest.getBody().getCommonHeader().setSubRequestId("1"); -appcRequest.getBody().getCommonHeader().getFlags().put("ttl", "10000"); -appcRequest.getBody().getCommonHeader().getFlags().put("force", "TRUE"); -appcRequest.getBody().getCommonHeader().getFlags().put("mode", "EXCLUSIVE"); +appcRequest.getBody().getInput().getCommonHeader().setTimeStamp(java.time.Instant.now()); +appcRequest.getBody().getInput().getCommonHeader().setApiVer("2.00"); +appcRequest.getBody().getInput().getCommonHeader().setOriginatorId( + executor.inFields.get("requestID").toString()); +appcRequest.getBody().getInput().getCommonHeader().setRequestId( + executor.inFields.get("requestID")); +appcRequest.getBody().getInput().getCommonHeader().setSubRequestId("1"); +appcRequest.getBody().getInput().getCommonHeader().getFlags().put("ttl", "10000"); +appcRequest.getBody().getInput().getCommonHeader().getFlags().put("force", "TRUE"); +appcRequest.getBody().getInput().getCommonHeader().getFlags().put("mode", "EXCLUSIVE"); -appcRequest.getBody().setAction("Restart"); -appcRequest.getBody().setActionIdentifiers(new java.util.HashMap()); -appcRequest.getBody().getActionIdentifiers().put("vnf-id", executor.inFields.get("vnfID").toString()); +appcRequest.getBody().getInput().setAction("Restart"); +appcRequest.getBody().getInput().setActionIdentifiers(new java.util.HashMap()); +appcRequest.getBody().getInput().getActionIdentifiers().put("vnf-id", + executor.inFields.get("vnfID").toString()); -executor.getContextAlbum("RequestIDVNFIDAlbum").put(executor.inFields.get("requestID").toString(), executor.inFields.get("vnfID")); +executor.getContextAlbum("RequestIDVNFIDAlbum").put( + executor.inFields.get("requestID").toString(), + executor.inFields.get("vnfID")); -vcpeClosedLoopStatus.put("notification", "OPERATION"); -vcpeClosedLoopStatus.put("notificationTime", java.lang.System.currentTimeMillis()); +vcpeClosedLoopStatus.put("notification", "OPERATION"); +vcpeClosedLoopStatus.put("notificationTime", java.lang.System + .currentTimeMillis()); executor.outFields.put("APPCLCMRequestEvent", appcRequest); diff --git a/examples/examples-onap-vcpe/src/main/resources/logic/APPCRestartVNFResponseTask.js b/examples/examples-onap-vcpe/src/main/resources/logic/APPCRestartVNFResponseTask.js index afaa72536..75ab6a3af 100644 --- a/examples/examples-onap-vcpe/src/main/resources/logic/APPCRestartVNFResponseTask.js +++ b/examples/examples-onap-vcpe/src/main/resources/logic/APPCRestartVNFResponseTask.js @@ -32,29 +32,46 @@ var appcResponse = executor.inFields.get("APPCLCMResponseEvent"); var requestIDString = appcResponse.getCorrelationId().substr(0, 36); executor.logger.info("requestIDString = " + requestIDString); -var vnfID = executor.getContextAlbum("RequestIDVNFIDAlbum").get(requestIDString); -executor.logger.info("Size of RequestIDVNFIDAlbum = " + executor.getContextAlbum("RequestIDVNFIDAlbum").size()); +var vnfID = executor.getContextAlbum("RequestIDVNFIDAlbum") + .get(requestIDString); +executor.logger.info("Size of RequestIDVNFIDAlbum = " + + executor.getContextAlbum("RequestIDVNFIDAlbum").size()); executor.logger.info("vnfID = " + vnfID); var returnValue = executor.isTrue; if (vnfID != null) { - var vcpeClosedLoopStatus = executor.getContextAlbum("VCPEClosedLoopStatusAlbum").get(vnfID.toString()); - var requestId = java.util.UUID.fromString(vcpeClosedLoopStatus.get("requestID")); + var vcpeClosedLoopStatus = executor.getContextAlbum( + "VCPEClosedLoopStatusAlbum").get(vnfID.toString()); + var requestId = java.util.UUID.fromString(vcpeClosedLoopStatus + .get("requestID")); - vcpeClosedLoopStatus.put("notificationTime", java.lang.System.currentTimeMillis()); + vcpeClosedLoopStatus.put("notificationTime", java.lang.System + .currentTimeMillis()); - executor.logger.info("Got from APPC code: " + org.onap.policy.appclcm.LcmResponseCode.toResponseValue(appcResponse.getBody().getStatus().getCode())); + executor.logger.info("Got from APPC code: " + + org.onap.policy.appclcm.AppcLcmResponseCode + .toResponseValue(appcResponse.getBody().getOutput() + .getStatus().getCode())); - if (org.onap.policy.appclcm.LcmResponseCode.toResponseValue(appcResponse.getBody().getStatus().getCode()) == org.onap.policy.appclcm.LcmResponseCode.SUCCESS) { + if (org.onap.policy.appclcm.AppcLcmResponseCode + .toResponseValue(appcResponse.getBody().getOutput().getStatus() + .getCode()) == org.onap.policy.appclcm.AppcLcmResponseCode.SUCCESS) { vcpeClosedLoopStatus.put("notification", "OPERATION_SUCCESS"); vcpeClosedLoopStatus.put("message", "vCPE restarted"); executor.getContextAlbum("RequestIDVNFIDAlbum").remove(requestIDString); - } else if (org.onap.policy.appclcm.LcmResponseCode.toResponseValue(appcResponse.getBody().getStatus().getCode()) == "ACCEPTED" || - org.onap.policy.appclcm.LcmResponseCode.toResponseValue(appcResponse.getBody().getStatus().getCode()) == "REJECT" ) { - executor.logger.info("Got ACCEPTED 100 or REJECT 312, keep the context, wait for next response. Code is: " + org.onap.policy.appclcm.LcmResponseCode.toResponseValue(appcResponse.getBody().getStatus().getCode())); - } - else { + } else if (org.onap.policy.appclcm.AppcLcmResponseCode + .toResponseValue(appcResponse.getBody().getOutput().getStatus() + .getCode()) == "ACCEPTED" + || org.onap.policy.appclcm.AppcLcmResponseCode + .toResponseValue(appcResponse.getBody().getOutput() + .getStatus().getCode()) == "REJECT") { + executor.logger + .info("Got ACCEPTED 100 or REJECT 312, keep the context, wait for next response. Code is: " + + org.onap.policy.appclcm.AppcLcmResponseCode + .toResponseValue(appcResponse.getBody() + .getOutput().getStatus().getCode())); + } else { executor.getContextAlbum("RequestIDVNFIDAlbum").remove(requestIDString); vcpeClosedLoopStatus.put("notification", "OPERATION_FAILURE"); vcpeClosedLoopStatus.put("message", "vCPE restart failed"); @@ -63,7 +80,8 @@ if (vnfID != null) { executor.outFields.put("requestID", requestId); executor.outFields.put("vnfID", vnfID); } else { - executor.message = "VNF ID not found in context album for request ID " + requestIDString; + executor.message = "VNF ID not found in context album for request ID " + + requestIDString; returnValue = executor.isFalse; } diff --git a/examples/examples-onap-vcpe/src/main/resources/logic/ControlLoopLogTask.js b/examples/examples-onap-vcpe/src/main/resources/logic/ControlLoopLogTask.js index d42aef9d0..aa816ca95 100644 --- a/examples/examples-onap-vcpe/src/main/resources/logic/ControlLoopLogTask.js +++ b/examples/examples-onap-vcpe/src/main/resources/logic/ControlLoopLogTask.js @@ -39,7 +39,7 @@ clNotification.setClosedLoopAlarmEnd(java.time.Instant.ofEpochMilli(vcpeClosedLo clNotification.setClosedLoopEventClient(vcpeClosedLoopStatus.get("closedLoopEventClient")); clNotification.setVersion(vcpeClosedLoopStatus.get("version")); clNotification.setRequestId(java.util.UUID.fromString(vcpeClosedLoopStatus.get("requestID"))); -clNotification.setTargetType(org.onap.policy.controlloop.ControlLoopTargetType.toType(vcpeClosedLoopStatus.get("target_type"))); +clNotification.setTargetType(vcpeClosedLoopStatus.get("target_type")); clNotification.setTarget(org.onap.policy.controlloop.ControlLoopEventStatus.toStatus(vcpeClosedLoopStatus.get("target"))); clNotification.setFrom(vcpeClosedLoopStatus.get("from")); clNotification.setPolicyScope(vcpeClosedLoopStatus.get("policyScope")); diff --git a/examples/examples-onap-vcpe/src/main/resources/policy/ONAPvCPEPolicyModel.apex b/examples/examples-onap-vcpe/src/main/resources/policy/ONAPvCPEPolicyModel.apex index 490c4ad7c..571cea9cc 100644 --- a/examples/examples-onap-vcpe/src/main/resources/policy/ONAPvCPEPolicyModel.apex +++ b/examples/examples-onap-vcpe/src/main/resources/policy/ONAPvCPEPolicyModel.apex @@ -31,8 +31,8 @@ schema create name=VirtualControlLoopNotificationType flavour=Java schema=org.on schema create name=AAIServiceNamedQueryRequestType flavour=Java schema=org.onap.policy.aai.AaiNqRequest schema create name=AAIServiceNamedQueryResponseType flavour=Java schema=org.onap.policy.aai.AaiNqResponse -schema create name=APPCLCMRequestType flavour=Java schema=org.onap.policy.appclcm.LcmRequestWrapper -schema create name=APPCLCMResponseType flavour=Java schema=org.onap.policy.appclcm.LcmResponseWrapper +schema create name=APPCLCMRequestType flavour=Java schema=org.onap.policy.appclcm.AppcLcmDmaapWrapper +schema create name=APPCLCMResponseType flavour=Java schema=org.onap.policy.appclcm.AppcLcmDmaapWrapper schema create name=GuardDecisionAttributesType flavour=Avro schema=LS #MACROFILE:"src/main/resources/schemas/GuardDecisionAttributesType.avsc" diff --git a/examples/examples-onap-vcpe/src/test/java/org/onap/policy/apex/domains/onap/vcpe/AppcResponseCreator.java b/examples/examples-onap-vcpe/src/test/java/org/onap/policy/apex/domains/onap/vcpe/AppcResponseCreator.java index 10f425302..d989ba361 100644 --- a/examples/examples-onap-vcpe/src/test/java/org/onap/policy/apex/domains/onap/vcpe/AppcResponseCreator.java +++ b/examples/examples-onap-vcpe/src/test/java/org/onap/policy/apex/domains/onap/vcpe/AppcResponseCreator.java @@ -20,24 +20,24 @@ package org.onap.policy.apex.domains.onap.vcpe; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.time.Instant; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.BlockingQueue; +import org.onap.policy.appclcm.AppcLcmBody; import org.onap.policy.appclcm.AppcLcmDmaapWrapper; import org.onap.policy.appclcm.AppcLcmInput; import org.onap.policy.appclcm.AppcLcmOutput; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.slf4j.ext.XLogger; -import org.slf4j.ext.XLoggerFactory; +import org.onap.policy.controlloop.util.Serialization; /** * Respond to an APPC request with a given delay. */ public class AppcResponseCreator { - private static final XLogger LOGGER = XLoggerFactory.getXLogger(AppcResponseCreator.class); - // The request from APPC private final String jsonRequestString; @@ -47,6 +47,9 @@ public class AppcResponseCreator { // The timer task for response generation private final Timer appcTimer; + private static final Gson gson = new GsonBuilder() + .registerTypeAdapter(Instant.class, new Serialization.GsonInstantAdapter()).create(); + /** * Respond to the given APPC request after the given amount of milliseconds. * @@ -70,15 +73,8 @@ public class AppcResponseCreator { @Override public void run() { - StandardCoder standardCoder = new StandardCoder(); - AppcLcmDmaapWrapper requestWrapper = null; - try { - requestWrapper = standardCoder.decode(jsonRequestString, AppcLcmDmaapWrapper.class); - } catch (CoderException e) { - LOGGER.warn("decoding of the APPC request message failed", e); - return; - } + requestWrapper = gson.fromJson(jsonRequestString, AppcLcmDmaapWrapper.class); AppcLcmInput request = requestWrapper.getBody().getInput(); @@ -87,6 +83,7 @@ public class AppcResponseCreator { response.getStatus().setMessage("Restart Successful"); AppcLcmDmaapWrapper responseWrapper = new AppcLcmDmaapWrapper(); + responseWrapper.setBody(new AppcLcmBody()); responseWrapper.getBody().setOutput(response); responseWrapper.setVersion(requestWrapper.getVersion()); @@ -94,12 +91,7 @@ public class AppcResponseCreator { responseWrapper.setCorrelationId(requestWrapper.getCorrelationId()); responseWrapper.setType(requestWrapper.getType()); - try { - appcResponseQueue.add(standardCoder.encode(responseWrapper)); - } catch (CoderException e) { - LOGGER.warn("encoding of the APPC request message failed", e); - return; - } + appcResponseQueue.add(gson.toJson(responseWrapper)); } } } diff --git a/examples/examples-onap-vcpe/src/test/java/org/onap/policy/apex/domains/onap/vcpe/OnapVCpeSimEndpoint.java b/examples/examples-onap-vcpe/src/test/java/org/onap/policy/apex/domains/onap/vcpe/OnapVCpeSimEndpoint.java index 936c319a9..f08bf010c 100644 --- a/examples/examples-onap-vcpe/src/test/java/org/onap/policy/apex/domains/onap/vcpe/OnapVCpeSimEndpoint.java +++ b/examples/examples-onap-vcpe/src/test/java/org/onap/policy/apex/domains/onap/vcpe/OnapVCpeSimEndpoint.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertTrue; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import java.time.Instant; import java.util.Map; import java.util.Random; import java.util.concurrent.BlockingQueue; @@ -46,6 +47,7 @@ import org.onap.policy.aai.AaiNqRequest; import org.onap.policy.aai.AaiNqResponse; import org.onap.policy.aai.AaiNqVfModule; import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.controlloop.util.Serialization; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; @@ -64,6 +66,9 @@ public class OnapVCpeSimEndpoint { private static AtomicInteger statMessagesReceived = new AtomicInteger(); private static AtomicInteger getMessagesReceived = new AtomicInteger(); + private static final Gson gson = new GsonBuilder() + .registerTypeAdapter(Instant.class, new Serialization.GsonInstantAdapter()).create(); + /** * Service get stats. * @@ -121,7 +126,7 @@ public class OnapVCpeSimEndpoint { LOGGER.info("\n*** AAI REQUEST START ***\n" + jsonString + "\n *** AAI REQUEST END ***"); - AaiNqRequest request = new Gson().fromJson(jsonString, AaiNqRequest.class); + AaiNqRequest request = gson.fromJson(jsonString, AaiNqRequest.class); String vnfId = request.getInstanceFilters().getInstanceFilter().iterator().next().get("generic-vnf") .get("vnf-id"); String vnfSuffix = vnfId.substring(vnfId.length() - 4); @@ -295,7 +300,7 @@ public class OnapVCpeSimEndpoint { postMessagesReceived.incrementAndGet(); @SuppressWarnings("unchecked") - final Map jsonMap = new Gson().fromJson(jsonString, Map.class); + final Map jsonMap = gson.fromJson(jsonString, Map.class); assertTrue(jsonMap.containsKey("name")); assertEquals("0.0.1", jsonMap.get("version")); assertEquals("org.onap.policy.apex.sample.events", jsonMap.get("nameSpace")); @@ -330,7 +335,7 @@ public class OnapVCpeSimEndpoint { putMessagesReceived.incrementAndGet(); @SuppressWarnings("unchecked") - final Map jsonMap = new Gson().fromJson(jsonString, Map.class); + final Map jsonMap = gson.fromJson(jsonString, Map.class); assertTrue(jsonMap.containsKey("name")); assertEquals("0.0.1", jsonMap.get("version")); assertEquals("org.onap.policy.apex.sample.events", jsonMap.get("nameSpace")); -- cgit 1.2.3-korg