Loading src/main/java/org/etsi/osl/secretcontroller/CatalogClient.java +14 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller; import org.etsi.osl.tmf.so641.model.ServiceOrderUpdate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.jms.core.JmsClient; Loading @@ -19,6 +20,9 @@ public class CatalogClient { @Value("${topics.CATALOG_UPD_RESOURCE}") private String CATALOG_UPD_RESOURCE; @Value("${topics.CATALOG_UPD_SERVICE_ORDER}") private String CATALOG_UPD_SERVICE_ORDER; @Autowired public CatalogClient(JmsClient jmsClient, ObjectMapper objectMapper) { this.jmsClient = jmsClient; Loading Loading @@ -46,4 +50,14 @@ public class CatalogClient { jmsClient.destination(CATALOG_UPD_RESOURCE) .send(payload, map); } public void updateServiceOrder(String orderId, ServiceOrderUpdate svcOrderUpdate) { final var map = new HashMap<String, Object>(); map.put("orderid", orderId); final var payload = this.objectMapper.writeValueAsString(svcOrderUpdate); jmsClient.destination(CATALOG_UPD_SERVICE_ORDER) .send(payload, map); } } src/main/java/org/etsi/osl/secretcontroller/ServiceRulesService.java +6 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,12 @@ public class ServiceRulesService { return new ServiceRulesApplier(this.ruleEvaluatorService, Optional.ofNullable(rule)); } public ServiceRulesApplier getServiceRules(org.etsi.osl.tmf.so641.model.ServiceRestriction svc) { final var name = svc.getName(); final var rule = this.rulesConfig.getServiceRules().get(name); return new ServiceRulesApplier(this.ruleEvaluatorService, Optional.ofNullable(rule)); } public static class ServiceRulesApplier { private final Optional<ServiceRule> rule; private final RuleEvaluatorService ruleEvaluatorService; Loading src/main/java/org/etsi/osl/secretcontroller/VaultService.java +2 −2 Original line number Diff line number Diff line Loading @@ -32,8 +32,8 @@ public class VaultService { this.vaultBaseSecretUri = String.format("%s/v1/%s/data/", vaultUri, kvPath); } public String getVaultKey(String namespace, String key) { return String.format("%s/%s", namespace, key); public String getVaultKey(String namespace, String... keys) { return String.format("%s/%s", namespace, String.join("/", keys)); } public String getVaultUri(String secretKey) { Loading src/main/java/org/etsi/osl/secretcontroller/listeners/ServiceOrderEventsListener.java 0 → 100644 +122 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller.listeners; import org.etsi.osl.secretcontroller.CatalogClient; import org.etsi.osl.secretcontroller.SecretApplyResult; import org.etsi.osl.secretcontroller.ServiceRulesService; import org.etsi.osl.secretcontroller.VaultService; import org.etsi.osl.tmf.so641.model.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; import tools.jackson.databind.ObjectMapper; import java.util.HashMap; @Component public class ServiceOrderEventsListener { private static final String SECRET_NAMESPACE = "service-order"; private final VaultService vaultService; private final CatalogClient catalogClient; private final ServiceRulesService serviceRulesService; private final ObjectMapper objectMapper; @Autowired public ServiceOrderEventsListener( VaultService vaultService, CatalogClient catalogClient, ServiceRulesService serviceRulesService, ObjectMapper objectMapper ) { this.vaultService = vaultService; this.catalogClient = catalogClient; this.serviceRulesService = serviceRulesService; this.objectMapper = objectMapper; } @JmsListener(destination = "${topics.EVENT_SERVICE_ORDER_CREATE}", containerFactory = "topicJmsListenerContainerFactory") public void processServiceCreate(String content) { final var res = this.objectMapper.readValue(content, ServiceOrderCreateNotification.class); this.processServiceOrder(res.getEvent().getServiceOrder()); } @JmsListener(destination = "${topics.EVENT_SERVICE_ORDER_ATTRIBUTE_VALUE_CHANGED}", containerFactory = "topicJmsListenerContainerFactory") public void processServiceAttributeChange(String content) { final var res = this.objectMapper.readValue(content, ServiceOrderAttributeValueChangeNotification.class); this.processServiceOrder(res.getEvent().getServiceOrder()); } private void processServiceOrder(ServiceOrder serviceOrder) { final var svcOrderUpdate = new ServiceOrderUpdate(); var isDirty = false; for (final var orderItem : serviceOrder.getOrderItem()) { if (orderItem.getService() == null) continue; final var ruleApplier = this.serviceRulesService.getServiceRules(orderItem.getService()); final var svc = new ServiceRestriction(); final var secretData = new HashMap<String, String>(); final var vaultKey = this.vaultService.getVaultKey(SECRET_NAMESPACE, "services", orderItem.getId()); final var secretURI = this.vaultService.getVaultUri(vaultKey); var svcIsDirty = false; for (final var characteristic : orderItem.getService().getServiceCharacteristic()) { // Characteristic was already stored, ignore it if (this.vaultService.isAlreadySecret(characteristic.getValue().getValue())) continue; final var storeSecret = ruleApplier.saveCharacteristic(characteristic); if (storeSecret.action != SecretApplyResult.Action.Ignore) svcIsDirty = true; switch (storeSecret.action) { case Replace -> { secretData.put(characteristic.getName(), storeSecret.getValue()); characteristic.getValue().setValue(secretURI); svc.addServiceCharacteristicItem(characteristic); } case Erase -> { characteristic.getValue().setValue("Erased by secret controller"); svc.addServiceCharacteristicItem(characteristic); } } } if (!svcIsDirty) continue; if (!secretData.isEmpty()) this.vaultService.upsertSecret(vaultKey, secretData); final var updOrderItem = new ServiceOrderItem(); updOrderItem.setUuid(updOrderItem.getUuid()); updOrderItem.setService(svc); svcOrderUpdate.addOrderItemItem(orderItem); isDirty = true; } if (!isDirty) return; this.catalogClient.updateServiceOrder(serviceOrder.getId(), svcOrderUpdate); } @JmsListener(destination = "${topics.EVENT_SERVICE_ORDER_DELETE}", containerFactory = "topicJmsListenerContainerFactory") public void processServiceDelete(String content) { final var res = this.objectMapper.readValue(content, ServiceOrderDeleteNotification.class); final var svcOrder = res.getEvent().getServiceOrder(); for (final var orderItem : svcOrder.getOrderItem()) { final var vaultKey = this.vaultService.getVaultKey(SECRET_NAMESPACE, "services", orderItem.getId()); this.vaultService.deleteSecret(vaultKey); } } } src/main/resources/application.yml +5 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,11 @@ topics: EVENT_RESOURCE_ATTRIBUTE_VALUE_CHANGED: "EVENT.RESOURCE.ATTRCHANGED" EVENT_RESOURCE_DELETE: "EVENT.RESOURCE.DELETE" CATALOG_UPD_SERVICE_ORDER: "CATALOG.UPD.SERVICEORDER_BY_ID" EVENT_SERVICE_ORDER_CREATE: "EVENT.SERVICEORDER.CREATE" EVENT_SERVICE_ORDER_ATTRIBUTE_VALUE_CHANGED: "EVENT.SERVICEORDER.ATTRCHANGED" EVENT_SERVICE_ORDER_DELETE: "EVENT.SERVICEORDER.DELETE" app: service-rules: { } resource-rules: { } Loading
src/main/java/org/etsi/osl/secretcontroller/CatalogClient.java +14 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller; import org.etsi.osl.tmf.so641.model.ServiceOrderUpdate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.jms.core.JmsClient; Loading @@ -19,6 +20,9 @@ public class CatalogClient { @Value("${topics.CATALOG_UPD_RESOURCE}") private String CATALOG_UPD_RESOURCE; @Value("${topics.CATALOG_UPD_SERVICE_ORDER}") private String CATALOG_UPD_SERVICE_ORDER; @Autowired public CatalogClient(JmsClient jmsClient, ObjectMapper objectMapper) { this.jmsClient = jmsClient; Loading Loading @@ -46,4 +50,14 @@ public class CatalogClient { jmsClient.destination(CATALOG_UPD_RESOURCE) .send(payload, map); } public void updateServiceOrder(String orderId, ServiceOrderUpdate svcOrderUpdate) { final var map = new HashMap<String, Object>(); map.put("orderid", orderId); final var payload = this.objectMapper.writeValueAsString(svcOrderUpdate); jmsClient.destination(CATALOG_UPD_SERVICE_ORDER) .send(payload, map); } }
src/main/java/org/etsi/osl/secretcontroller/ServiceRulesService.java +6 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,12 @@ public class ServiceRulesService { return new ServiceRulesApplier(this.ruleEvaluatorService, Optional.ofNullable(rule)); } public ServiceRulesApplier getServiceRules(org.etsi.osl.tmf.so641.model.ServiceRestriction svc) { final var name = svc.getName(); final var rule = this.rulesConfig.getServiceRules().get(name); return new ServiceRulesApplier(this.ruleEvaluatorService, Optional.ofNullable(rule)); } public static class ServiceRulesApplier { private final Optional<ServiceRule> rule; private final RuleEvaluatorService ruleEvaluatorService; Loading
src/main/java/org/etsi/osl/secretcontroller/VaultService.java +2 −2 Original line number Diff line number Diff line Loading @@ -32,8 +32,8 @@ public class VaultService { this.vaultBaseSecretUri = String.format("%s/v1/%s/data/", vaultUri, kvPath); } public String getVaultKey(String namespace, String key) { return String.format("%s/%s", namespace, key); public String getVaultKey(String namespace, String... keys) { return String.format("%s/%s", namespace, String.join("/", keys)); } public String getVaultUri(String secretKey) { Loading
src/main/java/org/etsi/osl/secretcontroller/listeners/ServiceOrderEventsListener.java 0 → 100644 +122 −0 Original line number Diff line number Diff line package org.etsi.osl.secretcontroller.listeners; import org.etsi.osl.secretcontroller.CatalogClient; import org.etsi.osl.secretcontroller.SecretApplyResult; import org.etsi.osl.secretcontroller.ServiceRulesService; import org.etsi.osl.secretcontroller.VaultService; import org.etsi.osl.tmf.so641.model.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; import tools.jackson.databind.ObjectMapper; import java.util.HashMap; @Component public class ServiceOrderEventsListener { private static final String SECRET_NAMESPACE = "service-order"; private final VaultService vaultService; private final CatalogClient catalogClient; private final ServiceRulesService serviceRulesService; private final ObjectMapper objectMapper; @Autowired public ServiceOrderEventsListener( VaultService vaultService, CatalogClient catalogClient, ServiceRulesService serviceRulesService, ObjectMapper objectMapper ) { this.vaultService = vaultService; this.catalogClient = catalogClient; this.serviceRulesService = serviceRulesService; this.objectMapper = objectMapper; } @JmsListener(destination = "${topics.EVENT_SERVICE_ORDER_CREATE}", containerFactory = "topicJmsListenerContainerFactory") public void processServiceCreate(String content) { final var res = this.objectMapper.readValue(content, ServiceOrderCreateNotification.class); this.processServiceOrder(res.getEvent().getServiceOrder()); } @JmsListener(destination = "${topics.EVENT_SERVICE_ORDER_ATTRIBUTE_VALUE_CHANGED}", containerFactory = "topicJmsListenerContainerFactory") public void processServiceAttributeChange(String content) { final var res = this.objectMapper.readValue(content, ServiceOrderAttributeValueChangeNotification.class); this.processServiceOrder(res.getEvent().getServiceOrder()); } private void processServiceOrder(ServiceOrder serviceOrder) { final var svcOrderUpdate = new ServiceOrderUpdate(); var isDirty = false; for (final var orderItem : serviceOrder.getOrderItem()) { if (orderItem.getService() == null) continue; final var ruleApplier = this.serviceRulesService.getServiceRules(orderItem.getService()); final var svc = new ServiceRestriction(); final var secretData = new HashMap<String, String>(); final var vaultKey = this.vaultService.getVaultKey(SECRET_NAMESPACE, "services", orderItem.getId()); final var secretURI = this.vaultService.getVaultUri(vaultKey); var svcIsDirty = false; for (final var characteristic : orderItem.getService().getServiceCharacteristic()) { // Characteristic was already stored, ignore it if (this.vaultService.isAlreadySecret(characteristic.getValue().getValue())) continue; final var storeSecret = ruleApplier.saveCharacteristic(characteristic); if (storeSecret.action != SecretApplyResult.Action.Ignore) svcIsDirty = true; switch (storeSecret.action) { case Replace -> { secretData.put(characteristic.getName(), storeSecret.getValue()); characteristic.getValue().setValue(secretURI); svc.addServiceCharacteristicItem(characteristic); } case Erase -> { characteristic.getValue().setValue("Erased by secret controller"); svc.addServiceCharacteristicItem(characteristic); } } } if (!svcIsDirty) continue; if (!secretData.isEmpty()) this.vaultService.upsertSecret(vaultKey, secretData); final var updOrderItem = new ServiceOrderItem(); updOrderItem.setUuid(updOrderItem.getUuid()); updOrderItem.setService(svc); svcOrderUpdate.addOrderItemItem(orderItem); isDirty = true; } if (!isDirty) return; this.catalogClient.updateServiceOrder(serviceOrder.getId(), svcOrderUpdate); } @JmsListener(destination = "${topics.EVENT_SERVICE_ORDER_DELETE}", containerFactory = "topicJmsListenerContainerFactory") public void processServiceDelete(String content) { final var res = this.objectMapper.readValue(content, ServiceOrderDeleteNotification.class); final var svcOrder = res.getEvent().getServiceOrder(); for (final var orderItem : svcOrder.getOrderItem()) { final var vaultKey = this.vaultService.getVaultKey(SECRET_NAMESPACE, "services", orderItem.getId()); this.vaultService.deleteSecret(vaultKey); } } }
src/main/resources/application.yml +5 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,11 @@ topics: EVENT_RESOURCE_ATTRIBUTE_VALUE_CHANGED: "EVENT.RESOURCE.ATTRCHANGED" EVENT_RESOURCE_DELETE: "EVENT.RESOURCE.DELETE" CATALOG_UPD_SERVICE_ORDER: "CATALOG.UPD.SERVICEORDER_BY_ID" EVENT_SERVICE_ORDER_CREATE: "EVENT.SERVICEORDER.CREATE" EVENT_SERVICE_ORDER_ATTRIBUTE_VALUE_CHANGED: "EVENT.SERVICEORDER.ATTRCHANGED" EVENT_SERVICE_ORDER_DELETE: "EVENT.SERVICEORDER.DELETE" app: service-rules: { } resource-rules: { }