From bad7324bcc4900dfe3a31b4856da67aa3b6f6eeb Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Tue, 3 Nov 2020 12:44:55 +0100 Subject: Minor API changes The callback registerred at service registration is formalized, documented and tested. Change-Id: Idb135ddcec1862da486c4abd287fd5c7a757d8eb Issue-ID: CCSDK-2502 Signed-off-by: PatrikBuhr --- .../clients/A1ClientFactory.java | 3 +- .../controllers/ServiceCallbackInfo.java | 61 ++++++++++++++++ .../controllers/ServiceCallbacks.java | 85 ++++++++++++++++++++++ .../controllers/v1/ServiceController.java | 2 +- .../controllers/v2/PolicyController.java | 2 +- .../controllers/v2/PolicyInfo.java | 4 +- .../controllers/v2/PolicyTypeIdList.java | 6 +- .../controllers/v2/PolicyTypeInfo.java | 2 +- .../controllers/v2/RicInfo.java | 4 +- .../controllers/v2/ServiceRegistrationInfo.java | 3 +- .../repository/Service.java | 17 ++--- .../tasks/RicSynchronizationTask.java | 25 ++----- 12 files changed, 173 insertions(+), 41 deletions(-) create mode 100644 a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbackInfo.java create mode 100644 a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbacks.java (limited to 'a1-policy-management/src/main/java') diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java index 0ca3a45d..642385aa 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java @@ -79,7 +79,8 @@ public class A1ClientFactory { } else if (version == A1ProtocolType.OSC_V1) { assertNoControllerConfig(ric, version); return new OscA1Client(ric.getConfig(), this.restClientFactory); - } else if (version == A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1 || version == A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1 + } else if (version == A1ProtocolType.CCSDK_A1_ADAPTER_STD_V1_1 + || version == A1ProtocolType.CCSDK_A1_ADAPTER_OSC_V1 || version == A1ProtocolType.CCSDK_A1_ADAPTER_STD_V2_0_0) { return new CcsdkA1AdapterClient(version, ric.getConfig(), getControllerConfig(ric), this.restClientFactory); } else { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbackInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbackInfo.java new file mode 100644 index 00000000..7d5f003a --- /dev/null +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbackInfo.java @@ -0,0 +1,61 @@ +/*- + * ========================LICENSE_START================================= + * ONAP : ccsdk oran + * ====================================================================== + * Copyright (C) 2020 Nordix Foundation. All rights reserved. + * ====================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +package org.onap.ccsdk.oran.a1policymanagementservice.controllers; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import org.immutables.gson.Gson; + +@Gson.TypeAdapters +@ApiModel(value = "service_callback_info_v2", + description = "Information transferred as in Service callbacks (callback_url)") +public class ServiceCallbackInfo { + + private static final String EVENT_TYPE_DESCRIPTION = "values:\n" // + + "AVAILABLE: the Near-RT RIC has become available for A1 Policy management"; + + @Gson.TypeAdapters + @ApiModel(value = "event_type_v2", description = EVENT_TYPE_DESCRIPTION) + public enum EventType { + AVAILABLE + } + + @ApiModelProperty(value = "identity of a Near-RT RIC", required = true) + @SerializedName("ric_id") + @JsonProperty(value = "ric_id", required = true) + public String ricId; + + @ApiModelProperty(value = EVENT_TYPE_DESCRIPTION, required = true) + @SerializedName("event_type") + @JsonProperty(value = "event_type", required = true) + public EventType eventType; + + public ServiceCallbackInfo(String ricId, EventType eventType) { + this.ricId = ricId; + this.eventType = eventType; + } + + public ServiceCallbackInfo() {} +} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbacks.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbacks.java new file mode 100644 index 00000000..d6286eed --- /dev/null +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/ServiceCallbacks.java @@ -0,0 +1,85 @@ +/*- + * ========================LICENSE_START================================= + * ONAP : ccsdk oran + * ====================================================================== + * Copyright (C) 2020 Nordix Foundation. All rights reserved. + * ====================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +package org.onap.ccsdk.oran.a1policymanagementservice.controllers; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.lang.invoke.MethodHandles; + +import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric; +import org.onap.ccsdk.oran.a1policymanagementservice.repository.Service; +import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * Callbacks to the Service + */ +@SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string .. +public class ServiceCallbacks { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private static Gson gson = new GsonBuilder().create(); + + private final AsyncRestClient restClient; + + public ServiceCallbacks(AsyncRestClientFactory restClientFactory) { + this.restClient = restClientFactory.createRestClient(""); + } + + public void notifyServicesRicSynchronized(Ric ric, Services services) { + createTask(ric, services).subscribe(numberOfServices -> logger.debug("Services {} notified", numberOfServices), + throwable -> logger.error("Service notification failed, cause: {}", throwable.getMessage()), + () -> logger.debug("All services notified")); + + } + + private Mono createTask(Ric ric, Services services) { + return Flux.fromIterable(services.getAll()) // + .flatMap(service -> notifyServiceRicSynchronized(ric, service)) // + .collectList() // + .flatMap(okResponses -> Mono.just(Integer.valueOf(okResponses.size()))); // + } + + private Mono notifyServiceRicSynchronized(Ric ric, Service service) { + if (service.getCallbackUrl().isEmpty()) { + return Mono.empty(); + } + + ServiceCallbackInfo request = new ServiceCallbackInfo(ric.id(), ServiceCallbackInfo.EventType.AVAILABLE); + String body = gson.toJson(request); + + return restClient.post(service.getCallbackUrl(), body) + .doOnNext(resp -> logger.debug("Invoking service {} callback, ric: {}", service.getName(), ric.id())) + .onErrorResume(throwable -> { + logger.error("Service: {}, callback: {} failed: {}", service.getName(), service.getCallbackUrl(), + throwable.toString()); + return Mono.empty(); + }); + } + +} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v1/ServiceController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v1/ServiceController.java index e9a95e1a..548f4fe1 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v1/ServiceController.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v1/ServiceController.java @@ -100,7 +100,7 @@ public class ServiceController { throw new ServiceException("Missing mandatory parameter 'serviceName'"); } if (registrationInfo.keepAliveIntervalSeconds < 0) { - throw new ServiceException("Keepalive interval shoul be greater or equal to 0"); + throw new ServiceException("Keepalive interval should be greater or equal to 0"); } if (!registrationInfo.callbackUrl.isEmpty()) { new URL(registrationInfo.callbackUrl); diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java index 13568dbc..256b4782 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java @@ -283,7 +283,7 @@ public class PolicyController { "Returns a list of A1 policies matching given search criteria.
" // + "If several query parameters are defined, the policies matching all conditions are returned."; - @GetMapping(path = Consts.V2_API_ROOT + "/policy_instances", produces = MediaType.APPLICATION_JSON_VALUE) + @GetMapping(path = Consts.V2_API_ROOT + "/policy-instances", produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation(value = "Query for A1 policy instances", notes = GET_POLICIES_QUERY_DETAILS) @ApiResponses(value = { // @ApiResponse(code = 200, message = "Policies", response = PolicyInfoList.class), diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfo.java index 594cf786..c032e3ad 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyInfo.java @@ -38,8 +38,8 @@ public class PolicyInfo { public String policyId; @ApiModelProperty(value = "identity of the policy type", required = true) - @JsonProperty(value = "policy_type_id", required = true) - @SerializedName("policy_type_id") + @JsonProperty(value = "policytype_id", required = true) + @SerializedName("policytype_id") public String policyTypeId; @ApiModelProperty(value = "identity of the target Near-RT RIC", required = true) diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeIdList.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeIdList.java index 5ecc7277..ede69d5d 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeIdList.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeIdList.java @@ -31,12 +31,12 @@ import java.util.Collection; import org.immutables.gson.Gson; @Gson.TypeAdapters -@ApiModel(value = "policy_type_id_list_v2", description = "Information about policy types") +@ApiModel(value = "policytype_id_list_v2", description = "Information about policy types") public class PolicyTypeIdList { @ApiModelProperty(value = "Policy type identities") - @SerializedName("policy_type_ids") - @JsonProperty("policy_type_ids") + @SerializedName("policytype_ids") + @JsonProperty("policytype_ids") public final Collection policyTypesIds; public PolicyTypeIdList(Collection ids) { diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeInfo.java index ff979650..b97730e6 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyTypeInfo.java @@ -31,7 +31,7 @@ import io.swagger.annotations.ApiModelProperty; import org.immutables.gson.Gson; @Gson.TypeAdapters -@ApiModel(value = "policy_type_v2", description = "Policy type") +@ApiModel(value = "policytype_v2", description = "Policy type") public class PolicyTypeInfo { @ApiModelProperty( diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfo.java index 938d5106..85983080 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/RicInfo.java @@ -57,8 +57,8 @@ public class RicInfo { public final Collection managedElementIds; @ApiModelProperty(value = "supported policy types") - @SerializedName("policy_type_ids") - @JsonProperty("policy_type_ids") + @SerializedName("policytype_ids") + @JsonProperty("policytype_ids") public final Collection policyTypeIds; @ApiModelProperty(value = STATE_DESCRIPTION, name = "state") diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceRegistrationInfo.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceRegistrationInfo.java index 68afc384..88711164 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceRegistrationInfo.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceRegistrationInfo.java @@ -46,7 +46,8 @@ public class ServiceRegistrationInfo { @JsonProperty("keep_alive_interval_seconds") public long keepAliveIntervalSeconds = 0; - @ApiModelProperty(value = "callback for notifying of RIC synchronization", required = false, allowEmptyValue = true) + @ApiModelProperty(value = "callback for notifying of Near-RT RIC state changes", required = false, + allowEmptyValue = true) @SerializedName("callback_url") @JsonProperty("callback_url") public String callbackUrl = ""; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Service.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Service.java index 823490ce..3c7c53a1 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Service.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Service.java @@ -24,13 +24,20 @@ import java.time.Duration; import java.time.Instant; import lombok.Getter; +import lombok.Setter; public class Service { @Getter private final String name; + + @Getter private final Duration keepAliveInterval; + private Instant lastPing; - private final String callbackUrl; + + @Getter + @Setter // For test + private String callbackUrl; public Service(String name, Duration keepAliveInterval, String callbackUrl) { this.name = name; @@ -39,10 +46,6 @@ public class Service { keepAlive(); } - public synchronized Duration getKeepAliveInterval() { - return this.keepAliveInterval; - } - public synchronized void keepAlive() { this.lastPing = Instant.now(); } @@ -55,8 +58,4 @@ public class Service { return Duration.between(this.lastPing, Instant.now()); } - public synchronized String getCallbackUrl() { - return this.callbackUrl; - } - } diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java index 88d99232..825418b5 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RicSynchronizationTask.java @@ -24,8 +24,8 @@ import static org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric.RicSt import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; -import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.controllers.ServiceCallbacks; import org.onap.ccsdk.oran.a1policymanagementservice.repository.ImmutablePolicyType; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Lock.LockType; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; @@ -33,7 +33,6 @@ import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyType; import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyTypes; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric; -import org.onap.ccsdk.oran.a1policymanagementservice.repository.Service; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -132,22 +131,7 @@ public class RicSynchronizationTask { private void onSynchronizationComplete(Ric ric) { logger.debug("Synchronization completed for: {}", ric.id()); ric.setState(RicState.AVAILABLE); - notifyAllServices("Synchronization completed for:" + ric.id()); - } - - private void notifyAllServices(String body) { - for (Service service : services.getAll()) { - String url = service.getCallbackUrl(); - if (url.length() > 0) { - createNotificationClient(url) // - .put("", body) // - .subscribe( // - notUsed -> logger.debug("Service {} notified", service.getName()), - throwable -> logger.warn("Service notification failed for service: {}. Cause: {}", - service.getName(), throwable.getMessage()), - () -> logger.debug("All services notified")); - } - } + notifyServices(ric); } private Flux deleteAllPolicyInstances(Ric ric, Throwable t) { @@ -163,8 +147,9 @@ public class RicSynchronizationTask { return Flux.concat(synchronizedTypes, deletePoliciesInRic); } - AsyncRestClient createNotificationClient(final String url) { - return restClientFactory.createRestClient(url); + void notifyServices(Ric ric) { + ServiceCallbacks callbacks = new ServiceCallbacks(this.restClientFactory); + callbacks.notifyServicesRicSynchronized(ric, services); } private Flux synchronizePolicyTypes(Ric ric, A1Client a1Client) { -- cgit 1.2.3-korg