- name: type
in: query
description: type
- required: true
+ required: false
type: string
responses:
'200':
description: RIC or policy type is not found
schema:
type: string
- '405':
- description: Change is not allowed
- schema:
- type: string
'423':
description: RIC is locked
schema:
schema:
type: string
deprecated: false
+ /policy_ids:
+ get:
+ tags:
+ - A1 Policy Management
+ summary: 'Query policies, only IDs returned'
+ operationId: getPolicyIdsUsingGET
+ produces:
+ - '*/*'
+ parameters:
+ - name: ric
+ in: query
+ description: ric
+ required: false
+ type: string
+ - name: service
+ in: query
+ description: service
+ required: false
+ type: string
+ - name: type
+ in: query
+ description: type
+ required: false
+ type: string
+ responses:
+ '200':
+ description: Policy ids
+ schema:
+ type: array
+ items:
+ type: string
+ '401':
+ description: Unauthorized
+ '403':
+ description: Forbidden
+ '404':
+ description: RIC or type not found
+ schema:
+ type: string
+ deprecated: false
/policy_schema:
get:
tags:
post:
tags:
- Service registry and supervision
- summary: Keep the policies alive for a service
+ summary: Heartbeat from a serice
operationId: keepAliveServiceUsingPOST
consumes:
- application/json
type: string
responses:
'200':
- description: Policies timeout supervision refreshed
+ description: 'Service supervision timer refreshed, OK'
schema:
type: string
'201':
properties:
callbackUrl:
type: string
- description: callback for notifying of RIC recovery
+ description: callback for notifying of RIC synchronization
keepAliveIntervalSeconds:
type: integer
format: int64
- description: keep alive interval for policies owned by the service. 0 means no timeout supervision. Polcies that are not refreshed within this time are removed
+ description: 'keep alive interval for the service. This is a heartbeat supervision of the service, which in regular intevals must invoke a ''keepAlive'' REST call. When a service does not invoke this call within the given time, it is considered unavailble. An unavailable service will be automatically deregistered and its policies will be deleted. Value 0 means no timeout supervision.'
serviceName:
type: string
description: identity of the service
properties:
callbackUrl:
type: string
- description: callback for notifying of RIC recovery
+ description: callback for notifying of RIC synchronization
keepAliveIntervalSeconds:
type: integer
format: int64
serviceName:
type: string
description: identity of the service
- timeSincePingSeconds:
+ timeSinceLastActivitySeconds:
type: integer
format: int64
description: time since last invocation by the service
title: ServiceStatus
-
public enum A1ProtocolType {
UNKNOWN, //
- STD_V1, //
STD_V1_1, // version 1.1
OSC_V1, //
SDNC_OSC, //
}
A1Client createClient(Ric ric, A1ProtocolType version) {
- if (version == A1ProtocolType.STD_V1) {
+ if (version == A1ProtocolType.STD_V1_1) {
return new StdA1ClientVersion1(ric.getConfig());
- } else if (version == A1ProtocolType.STD_V1_1) {
- return new StdA1ClientVersion2(ric.getConfig());
} else if (version == A1ProtocolType.OSC_V1) {
return new OscA1Client(ric.getConfig());
} else if (version == A1ProtocolType.SDNC_OSC) {
private Mono<A1Client.A1ProtocolType> getProtocolVersion(Ric ric) {
if (ric.getProtocolVersion() == A1ProtocolType.UNKNOWN) {
- return fetchVersion(createClient(ric, A1ProtocolType.STD_V1)) //
- .onErrorResume(notUsed -> fetchVersion(createClient(ric, A1ProtocolType.STD_V1_1))) //
+ return fetchVersion(createClient(ric, A1ProtocolType.STD_V1_1)) //
.onErrorResume(notUsed -> fetchVersion(createClient(ric, A1ProtocolType.OSC_V1))) //
.onErrorResume(notUsed -> fetchVersion(createClient(ric, A1ProtocolType.SDNC_OSC))) //
.onErrorResume(notUsed -> fetchVersion(createClient(ric, A1ProtocolType.SDNC_ONAP))) //
.doOnNext(ric::setProtocolVersion)
- .doOnNext(version -> logger.debug("Recover ric: {}, protocol version:{}", ric.name(), version)) //
+ .doOnNext(version -> logger.debug("Established protocol version:{} for Ric: {}", version, ric.name())) //
.doOnError(notUsed -> logger.warn("Could not get protocol version from RIC: {}", ric.name())); //
} else {
return Mono.just(ric.getProtocolVersion());
package org.oransc.policyagent.clients;
import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
import java.util.List;
import org.oransc.policyagent.configuration.RicConfig;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+@SuppressWarnings("squid:S2629") // Invoke method(s) only conditionally
public class SdncOscA1Client implements A1Client {
- private static final String URL_PREFIX = "/A1-ADAPTER-API:";
+ private static final String URL_PREFIX = "/A1-ADAPTER-API:";
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
private final String a1ControllerUsername;
private final String a1ControllerPassword;
private final RicConfig ricConfig;
public SdncOscA1Client(RicConfig ricConfig, String baseUrl, String username, String password) {
this(ricConfig, username, password, new AsyncRestClient(baseUrl + "/restconf/operations"));
- if (logger.isDebugEnabled()) {
- logger.debug("SdncOscA1Client for ric: {}, a1ControllerBaseUrl: {}", ricConfig.name(), baseUrl);
- }
+ logger.debug("SdncOscA1Client for ric: {}, a1ControllerBaseUrl: {}", ricConfig.name(), baseUrl);
}
public SdncOscA1Client(RicConfig ricConfig, String username, String password, AsyncRestClient restClient) {
@Override
public Mono<List<String>> getPolicyTypeIdentities() {
- SdncOscAdapterInput inputParams = ImmutableSdncOscAdapterInput.builder() //
- .nearRtRicUrl(ricConfig.baseUrl()) //
- .build();
- String inputJsonString = JsonHelper.createInputJsonString(inputParams);
- logger.debug("POST getPolicyTypeIdentities inputJsonString = {}", inputJsonString);
-
- return restClient
- .postWithAuthHeader(URL_PREFIX + "getPolicyTypeIdentities", inputJsonString, a1ControllerUsername,
- a1ControllerPassword) //
- .flatMap(response -> JsonHelper.getValueFromResponse(response, "policy-type-id-list")) //
- .flatMapMany(JsonHelper::parseJsonArrayOfString) //
- .collectList();
+ return Mono.just(Arrays.asList(""));
}
@Override
@Override
public Mono<String> getPolicyTypeSchema(String policyTypeId) {
- SdncOscAdapterInput inputParams = ImmutableSdncOscAdapterInput.builder() //
- .nearRtRicUrl(ricConfig.baseUrl()) //
- .policyTypeId(policyTypeId) //
- .build();
- String inputJsonString = JsonHelper.createInputJsonString(inputParams);
- logger.debug("POST getPolicyType inputJsonString = {}", inputJsonString);
-
- return restClient
- .postWithAuthHeader(URL_PREFIX + "getPolicyType", inputJsonString, a1ControllerUsername,
- a1ControllerPassword) //
- .flatMap(response -> JsonHelper.getValueFromResponse(response, "policy-type")) //
- .flatMap(JsonHelper::extractPolicySchema);
+ return Mono.just("{}");
}
@Override
.policy(policy.json()) //
.build();
String inputJsonString = JsonHelper.createInputJsonString(inputParams);
- logger.debug("POST putPolicy inputJsonString = {}", inputJsonString);
-
return restClient
.postWithAuthHeader(URL_PREFIX + "putPolicy", inputJsonString, a1ControllerUsername, a1ControllerPassword)
.flatMap(response -> JsonHelper.getValueFromResponse(response, "returned-policy")) //
@Override
public Mono<A1ProtocolType> getProtocolVersion() {
- return getPolicyTypeIdentities() //
+ return getPolicyIdentities() //
.flatMap(x -> Mono.just(A1ProtocolType.SDNC_OSC));
}
.nearRtRicUrl(ricConfig.baseUrl()) //
.build();
String inputJsonString = JsonHelper.createInputJsonString(inputParams);
- logger.debug("POST getPolicyIdentities inputJsonString = {}", inputJsonString);
-
return restClient
.postWithAuthHeader(URL_PREFIX + "getPolicyIdentities", inputJsonString, a1ControllerUsername,
a1ControllerPassword) //
.build();
String inputJsonString = JsonHelper.createInputJsonString(inputParams);
- logger.debug("POST deletePolicy inputJsonString = {}", inputJsonString);
-
return restClient.postWithAuthHeader(URL_PREFIX + "deletePolicy", inputJsonString, a1ControllerUsername,
a1ControllerPassword);
}
package org.oransc.policyagent.clients;
+import java.util.Arrays;
import java.util.List;
import org.oransc.policyagent.configuration.RicConfig;
import reactor.core.publisher.Mono;
public class StdA1ClientVersion1 implements A1Client {
- private static final String URL_PREFIX = "/A1-P/v1";
-
- private static final String POLICY_TYPES_URI = "/policytypes";
- private static final String POLICY_TYPE_ID = "policyTypeId";
-
- private static final String POLICIES_URI = "/policies";
-
- private static final UriComponentsBuilder POLICY_TYPE_SCHEMA_URI =
- UriComponentsBuilder.fromPath("/policytypes/{policy-type-name}");
-
- private static final UriComponentsBuilder POLICY_URI =
- UriComponentsBuilder.fromPath("/policies/{policy-id}").queryParam(POLICY_TYPE_ID, "{policy-type-name}");
-
- private static final UriComponentsBuilder POLICY_DELETE_URI =
- UriComponentsBuilder.fromPath("/policies/{policy-id}");
-
- private static final UriComponentsBuilder POLICY_STATUS_URI =
- UriComponentsBuilder.fromPath("/policies/{policy-id}/status");
-
private final AsyncRestClient restClient;
public StdA1ClientVersion1(RicConfig ricConfig) {
- String baseUrl = ricConfig.baseUrl() + URL_PREFIX;
+ final String urlPrefix = "/A1-P/v1";
+ String baseUrl = ricConfig.baseUrl() + urlPrefix;
this.restClient = new AsyncRestClient(baseUrl);
}
@Override
public Mono<String> putPolicy(Policy policy) {
- String uri = POLICY_URI.buildAndExpand(policy.id(), policy.type().name()).toUriString();
+ final UriComponentsBuilder policyUri = UriComponentsBuilder.fromPath("/policies/{policy-id}");
+ final String uri = policyUri.buildAndExpand(policy.id()).toUriString();
return restClient.put(uri, policy.json()) //
.flatMap(JsonHelper::validateJson);
}
@Override
public Mono<List<String>> getPolicyTypeIdentities() {
- return restClient.get(POLICY_TYPES_URI) //
- .flatMapMany(JsonHelper::parseJsonArrayOfString) //
- .collectList();
+ return Mono.just(Arrays.asList(""));
}
@Override
public Mono<String> getPolicyTypeSchema(String policyTypeId) {
- String uri = POLICY_TYPE_SCHEMA_URI.buildAndExpand(policyTypeId).toUriString();
- return restClient.get(uri) //
- .flatMap(JsonHelper::extractPolicySchema);
+ return Mono.just("{}");
}
@Override
@Override
public Mono<A1ProtocolType> getProtocolVersion() {
- return getPolicyTypeIdentities() //
- .flatMap(x -> Mono.just(A1ProtocolType.STD_V1));
+ return getPolicyIdentities() //
+ .flatMap(x -> Mono.just(A1ProtocolType.STD_V1_1));
}
@Override
public Mono<String> getPolicyStatus(Policy policy) {
- String uri = POLICY_STATUS_URI.buildAndExpand(policy.id()).toUriString();
+ final UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/policies/{policy-id}/status");
+ String uri = builder.buildAndExpand(policy.id()).toUriString();
return restClient.get(uri);
}
private Flux<String> getPolicyIds() {
- return restClient.get(POLICIES_URI) //
+ final String uri = "/policies";
+ return restClient.get(uri) //
.flatMapMany(JsonHelper::parseJsonArrayOfString);
}
private Mono<String> deletePolicyById(String policyId) {
- String uri = POLICY_DELETE_URI.buildAndExpand(policyId).toUriString();
+ final UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/policies/{policy-id}");
+ String uri = builder.buildAndExpand(policyId).toUriString();
return restClient.delete(uri);
}
}
+++ /dev/null
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * 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.oransc.policyagent.clients;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.oransc.policyagent.configuration.RicConfig;
-import reactor.core.publisher.Mono;
-
-public class StdA1ClientVersion2 extends StdA1ClientVersion1 {
-
- public StdA1ClientVersion2(RicConfig ricConfig) {
- super(ricConfig);
- }
-
- public StdA1ClientVersion2(AsyncRestClient restClient) {
- super(restClient);
- }
-
- @Override
- public Mono<List<String>> getPolicyTypeIdentities() {
- return Mono.just(Arrays.asList(""));
- }
-
- @Override
- public Mono<String> getPolicyTypeSchema(String policyTypeId) {
- return Mono.just("{}");
- }
-
- @Override
- public Mono<A1ProtocolType> getProtocolVersion() {
- return getPolicyIdentities() //
- .flatMap(x -> Mono.just(A1ProtocolType.STD_V1_1));
- }
-}
policy = policies.getPolicy(id);
keepServiceAlive(policy.ownerServiceName());
if (policy.ric().getState() != Ric.RicState.IDLE) {
- return Mono.just(new ResponseEntity<>("Busy, recovering", HttpStatus.LOCKED));
+ return Mono.just(new ResponseEntity<>("Busy, synchronizing", HttpStatus.LOCKED));
}
Ric ric = policy.ric();
return ric.getLock().lock(LockType.SHARED) // //
}
return ric == null || type == null ? Mono.just(new ResponseEntity<>(HttpStatus.NOT_FOUND))
- : Mono.just(new ResponseEntity<>(HttpStatus.LOCKED)); // Recovering
+ : Mono.just(new ResponseEntity<>(HttpStatus.LOCKED)); // Synchronizing
}
@SuppressWarnings({"unchecked"})
return new ResponseEntity<>("RIC not found", HttpStatus.NOT_FOUND);
}
synchronized (policies) {
- Collection<Policy> result = null;
-
- if (type != null) {
- result = policies.getForType(type);
- result = filter(result, null, ric, service);
- } else if (service != null) {
- result = policies.getForService(service);
- result = filter(result, type, ric, null);
- } else if (ric != null) {
- result = filter(policies.getForRic(ric), type, null, service);
- } else {
- result = policies.getAll();
- }
+ String filteredPolicies = policiesToJson(filter(type, ric, service));
+ return new ResponseEntity<>(filteredPolicies, HttpStatus.OK);
+ }
+ }
- String policiesJson;
- try {
- policiesJson = policiesToJson(result);
- } catch (ServiceException e) {
- return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
- }
- return new ResponseEntity<>(policiesJson, HttpStatus.OK);
+ @GetMapping("/policy_ids")
+ @ApiOperation(value = "Query policies, only IDs returned")
+ @ApiResponses(
+ value = {@ApiResponse(code = 200, message = "Policy ids", response = String.class, responseContainer = "List"),
+ @ApiResponse(code = 404, message = "RIC or type not found", response = String.class)})
+ public ResponseEntity<String> getPolicyIds( //
+ @RequestParam(name = "type", required = false) String type, //
+ @RequestParam(name = "ric", required = false) String ric, //
+ @RequestParam(name = "service", required = false) String service) //
+ {
+ if ((type != null && this.policyTypes.get(type) == null)) {
+ return new ResponseEntity<>("Policy type not found", HttpStatus.NOT_FOUND);
+ }
+ if ((ric != null && this.rics.get(ric) == null)) {
+ return new ResponseEntity<>("RIC not found", HttpStatus.NOT_FOUND);
+ }
+ synchronized (policies) {
+ String policyIdsJson = toPolicyIdsJson(filter(type, ric, service));
+ return new ResponseEntity<>(policyIdsJson, HttpStatus.OK);
}
}
return filtered;
}
- private String policiesToJson(Collection<Policy> policies) throws ServiceException {
+ private Collection<Policy> filter(String type, String ric, String service) {
+ synchronized (policies) {
+ if (type != null) {
+ return filter(policies.getForType(type), null, ric, service);
+ } else if (service != null) {
+ return filter(policies.getForService(service), type, ric, null);
+ } else if (ric != null) {
+ return filter(policies.getForRic(ric), type, null, service);
+ } else {
+ return policies.getAll();
+ }
+ }
+ }
+
+ private String policiesToJson(Collection<Policy> policies) {
List<PolicyInfo> v = new ArrayList<>(policies.size());
for (Policy p : policies) {
PolicyInfo policyInfo = new PolicyInfo();
policyInfo.service = p.ownerServiceName();
policyInfo.lastModified = p.lastModified();
if (!policyInfo.validate()) {
- throw new ServiceException("BUG, all fields must be set");
+ throw new NullPointerException("BUG, all fields must be set");
}
v.add(policyInfo);
}
return gson.toJson(v);
}
+ private String toPolicyIdsJson(Collection<Policy> policies) {
+ List<String> v = new ArrayList<>(policies.size());
+ for (Policy p : policies) {
+ v.add(p.id());
+ }
+ return gson.toJson(v);
+ }
+
private String getTimeStampUtc() {
return java.time.Instant.now().toString();
}
@ApiOperation(value = "Register a service")
@ApiResponses(
value = { //
- @ApiResponse(code = 200, message = "OK", response = String.class),
+ @ApiResponse(code = 200, message = "Service updated", response = String.class),
+ @ApiResponse(code = 201, message = "Service created", response = String.class), //
@ApiResponse(code = 400, message = "Cannot parse the ServiceRegistrationInfo", response = String.class)})
@PutMapping("/service")
public ResponseEntity<String> putService(//
@RequestBody ServiceRegistrationInfo registrationInfo) {
try {
validateRegistrationInfo(registrationInfo);
+ final boolean isCreate = this.services.get(registrationInfo.serviceName) == null;
this.services.put(toService(registrationInfo));
- return new ResponseEntity<>("OK", HttpStatus.OK);
+ return new ResponseEntity<>("OK", isCreate ? HttpStatus.CREATED : HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
@SerializedName("keepAliveIntervalSeconds")
public long keepAliveIntervalSeconds = 0;
- @ApiModelProperty(value = "callback for notifying of RIC recovery", required = false, allowEmptyValue = true)
+ @ApiModelProperty(value = "callback for notifying of RIC synchronization", required = false, allowEmptyValue = true)
@SerializedName("callbackUrl")
public String callbackUrl = "";
@ApiModelProperty(value = "time since last invocation by the service")
public final long timeSinceLastActivitySeconds;
- @ApiModelProperty(value = "callback for notifying of RIC recovery")
+ @ApiModelProperty(value = "callback for notifying of RIC synchronization")
public String callbackUrl;
ServiceStatus(String name, long keepAliveIntervalSeconds, long timeSincePingSeconds, String callbackUrl) {
HttpStatus status) {
DmaapResponseMessage dmaapResponseMessage = ImmutableDmaapResponseMessage.builder() //
.status(status.toString()) //
- .message(response) //
+ .message(response == null ? "" : response) //
.type("response") //
- .correlationId(dmaapRequestMessage.correlationId()) //
- .originatorId(dmaapRequestMessage.originatorId()) //
- .requestId(dmaapRequestMessage.requestId()) //
- .timestamp(dmaapRequestMessage.timestamp()) //
+ .correlationId(dmaapRequestMessage.correlationId() == null ? "" : dmaapRequestMessage.correlationId()) //
+ .originatorId(dmaapRequestMessage.originatorId() == null ? "" : dmaapRequestMessage.originatorId()) //
+ .requestId(dmaapRequestMessage.requestId() == null ? "" : dmaapRequestMessage.requestId()) //
+ .timestamp(dmaapRequestMessage.timestamp() == null ? "" : dmaapRequestMessage.timestamp()) //
.build();
String str = gson.toJson(dmaapResponseMessage);
return Mono.just(str);
}
private Flux<Object> startSynchronization(Ric ric, A1Client a1Client) {
- Flux<PolicyType> recoverTypes = synchronizePolicyTypes(ric, a1Client);
+ Flux<PolicyType> synchronizedTypes = synchronizePolicyTypes(ric, a1Client);
Flux<?> policiesDeletedInRic = a1Client.deleteAllPolicies();
Flux<?> policiesRecreatedInRic = recreateAllPoliciesInRic(ric, a1Client);
- return Flux.concat(recoverTypes, policiesDeletedInRic, policiesRecreatedInRic);
+ return Flux.concat(synchronizedTypes, policiesDeletedInRic, policiesRecreatedInRic);
}
private void onSynchronizationComplete(Ric ric) {
// If synchronization fails, try to remove all instances
deleteAllPoliciesInRepository(ric);
- Flux<PolicyType> recoverTypes = this.a1ClientFactory.createA1Client(ric) //
+ Flux<PolicyType> synchronizedTypes = this.a1ClientFactory.createA1Client(ric) //
.flatMapMany(a1Client -> synchronizePolicyTypes(ric, a1Client));
Flux<?> deletePoliciesInRic = this.a1ClientFactory.createA1Client(ric) //
.flatMapMany(A1Client::deleteAllPolicies) //
.doOnComplete(() -> deleteAllPoliciesInRepository(ric));
- Flux.concat(recoverTypes, deletePoliciesInRic) //
- .subscribe(x -> logger.debug("Brute recover: {}", x), //
- throwable -> onRecoveryError(ric, throwable), //
+ Flux.concat(synchronizedTypes, deletePoliciesInRic) //
+ .subscribe(x -> logger.debug("Brute recovery of failed synchronization: {}", x), //
+ throwable -> onSynchronizationRecoveryError(ric, throwable), //
() -> onSynchronizationComplete(ric));
}
- private void onRecoveryError(Ric ric, Throwable t) {
+ private void onSynchronizationRecoveryError(Ric ric, Throwable t) {
logger.warn("Synchronization failure recovery failed for ric: {}, reason: {}", ric.name(), t.getMessage());
ric.setState(RicState.UNDEFINED);
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
+import reactor.util.annotation.Nullable;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
}
@Test
- public void testRecovery() throws Exception {
+ public void testSynchronization() throws Exception {
addRic("ric").setState(Ric.RicState.UNDEFINED);
String ricName = "ric";
Policy policy2 = addPolicy("policyId2", "typeName", "service", ricName);
testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
}
+ @Test
+ public void testGetPolicyIdsFilter() throws Exception {
+ addPolicy("id1", "type1", "service1", "ric1");
+ addPolicy("id2", "type1", "service2", "ric1");
+ addPolicy("id3", "type2", "service1", "ric1");
+
+ String url = "/policy_ids?type=type1";
+ String rsp = restClient().get(url).block();
+ logger.info(rsp);
+ assertThat(rsp).contains("id1");
+ assertThat(rsp).contains("id2");
+ assertThat(rsp.contains("id3")).isFalse();
+
+ url = "/policy_ids?type=type1&service=service1&ric=ric1";
+ rsp = restClient().get(url).block();
+ assertThat(rsp).isEqualTo("[\"id1\"]");
+
+ // Test get policy ids for non existing type
+ url = "/policy_ids?type=type1XXX";
+ testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
+
+ // Test get policy ids for non existing RIC
+ url = "/policy_ids?ric=XXX";
+ testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
+ }
+
@Test
public void testPutAndGetService() throws Exception {
// PUT
- putService("name", 0);
+ putService("name", 0, HttpStatus.CREATED);
+ putService("name", 0, HttpStatus.OK);
// GET one service
String url = "/services?name=name";
@Test
public void testServiceSupervision() throws Exception {
- putService("service1", 1);
+ putService("service1", 1, HttpStatus.CREATED);
addPolicyType("type1", "ric1");
String url = putPolicyUrl("service1", "ric1", "type1", "instance1");
}
private void putService(String name) {
- putService(name, 0);
+ putService(name, 0, null);
}
- private void putService(String name, long keepAliveIntervalSeconds) {
+ private void putService(String name, long keepAliveIntervalSeconds, @Nullable HttpStatus expectedStatus) {
String url = "/service";
String body = createServiceJson(name, keepAliveIntervalSeconds);
- restClient().put(url, body).block();
+ ResponseEntity<String> resp = restClient().putForEntity(url, body).block();
+ if (expectedStatus != null) {
+ assertEquals(expectedStatus, resp.getStatusCode(), "");
+ }
}
private String baseUrl() {
@LocalServerPort
private int port;
- private void keepServerAlive() {
+ private void keepServerAlive() throws InterruptedException {
logger.info("Keeping server alive!");
- try {
- synchronized (this) {
- this.wait();
- }
- } catch (Exception ex) {
- logger.error("Unexpected: " + ex);
+
+ synchronized (this) {
+ this.wait();
}
+
}
private static String title(String jsonSchema) {
}
@Test
- @SuppressWarnings("squid:S2699") // Tests should include assertions. This test is only for keeping the server alive,
+ @SuppressWarnings("squid:S2699") // Tests should include assertions. This test is only for keeping the server
+ // alive,
// so it will only be confusing to add an assertion.
public void runMock() throws Exception {
keepServerAlive();
@Mock
A1Client clientMock4;
- @Mock
- A1Client clientMock5;
-
private ImmutableRicConfig ricConfig =
ImmutableRicConfig.builder().name(RIC_NAME).baseUrl("baseUrl").managedElementIds(new Vector<>()).build();
private Ric ric = new Ric(ricConfig);
@Test
public void getProtocolVersion_ok() {
whenGetProtocolVersionThrowException(clientMock1);
- whenGetProtocolVersionReturn(clientMock2, A1ProtocolType.STD_V1);
+ whenGetProtocolVersionReturn(clientMock2, A1ProtocolType.STD_V1_1);
doReturn(clientMock1, clientMock2).when(factoryUnderTest).createClient(any(), any());
A1Client client = factoryUnderTest.createA1Client(ric).block();
assertEquals(clientMock2, client, "Not correct client returned");
- assertEquals(A1ProtocolType.STD_V1, ric.getProtocolVersion(), "Not correct protocol");
+ assertEquals(A1ProtocolType.STD_V1_1, ric.getProtocolVersion(), "Not correct protocol");
}
@Test
public void getProtocolVersion_ok_Last() {
- whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3, clientMock4);
- whenGetProtocolVersionReturn(clientMock5, A1ProtocolType.STD_V1_1);
- doReturn(clientMock1, clientMock2, clientMock3, clientMock4, clientMock5).when(factoryUnderTest)
- .createClient(any(), any());
+ whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3);
+ whenGetProtocolVersionReturn(clientMock4, A1ProtocolType.STD_V1_1);
+ doReturn(clientMock1, clientMock2, clientMock3, clientMock4).when(factoryUnderTest).createClient(any(), any());
A1Client client = factoryUnderTest.createA1Client(ric).block();
- assertEquals(clientMock5, client, "Not correct client returned");
+ assertEquals(clientMock4, client, "Not correct client returned");
assertEquals(A1ProtocolType.STD_V1_1, ric.getProtocolVersion(), "Not correct protocol");
}
@Test
public void getProtocolVersion_error() {
- whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3, clientMock4, clientMock5);
- doReturn(clientMock1, clientMock2, clientMock3, clientMock4, clientMock5).when(factoryUnderTest)
- .createClient(any(), any());
+ whenGetProtocolVersionThrowException(clientMock1, clientMock2, clientMock3, clientMock4);
+ doReturn(clientMock1, clientMock2, clientMock3, clientMock4).when(factoryUnderTest).createClient(any(), any());
StepVerifier.create(factoryUnderTest.createA1Client(ric)) //
.expectSubscription() //
@Test
public void create_check_types() {
- assertTrue(createClient(A1ProtocolType.STD_V1) instanceof StdA1ClientVersion1);
- assertTrue(createClient(A1ProtocolType.STD_V1_1) instanceof StdA1ClientVersion2);
+ assertTrue(createClient(A1ProtocolType.STD_V1_1) instanceof StdA1ClientVersion1);
assertTrue(createClient(A1ProtocolType.OSC_V1) instanceof OscA1Client);
assertTrue(createClient(A1ProtocolType.SDNC_ONAP) instanceof SdncOnapA1Client);
assertTrue(createClient(A1ProtocolType.SDNC_OSC) instanceof SdncOscA1Client);
private static final String CONTROLLER_USERNAME = "username";
private static final String CONTROLLER_PASSWORD = "password";
private static final String RIC_1_URL = "RicUrl";
- private static final String POLICY_TYPES_IDENTITIES_URL = "/A1-ADAPTER-API:getPolicyTypeIdentities";
private static final String POLICY_IDENTITIES_URL = "/A1-ADAPTER-API:getPolicyIdentities";
- private static final String POLICY_TYPES_URL = "/A1-ADAPTER-API:getPolicyType";
private static final String PUT_POLICY_URL = "/A1-ADAPTER-API:putPolicy";
private static final String DELETE_POLICY_URL = "/A1-ADAPTER-API:deletePolicy";
-
private static final String POLICY_TYPE_1_ID = "type1";
- private static final String POLICY_TYPE_2_ID = "type2";
- private static final String POLICY_TYPE_SCHEMA_VALID = "{\"type\":\"type1\"}";
- private static final String POLICY_TYPE_SCHEMA_INVALID = "\"type\":\"type1\"}";
private static final String POLICY_1_ID = "policy1";
private static final String POLICY_2_ID = "policy2";
private static final String POLICY_JSON_VALID = "{\"scope\":{\"ueId\":\"ue1\"}}";
@Test
public void testGetPolicyTypeIdentities() {
- SdncOscAdapterInput inputParams = ImmutableSdncOscAdapterInput.builder() //
- .nearRtRicUrl(RIC_1_URL) //
- .build();
- String inputJsonString = A1ClientHelper.createInputJsonString(inputParams);
-
- List<String> policyTypeIds = Arrays.asList(POLICY_TYPE_1_ID, POLICY_TYPE_2_ID);
- Mono<String> policyTypeIdsResp =
- A1ClientHelper.createOutputJsonResponse("policy-type-id-list", policyTypeIds.toString());
- whenAsyncPostThenReturn(policyTypeIdsResp);
-
- Mono<List<String>> returnedMono = clientUnderTest.getPolicyTypeIdentities();
-
- verify(asyncRestClientMock).postWithAuthHeader(POLICY_TYPES_IDENTITIES_URL, inputJsonString,
- CONTROLLER_USERNAME, CONTROLLER_PASSWORD);
- StepVerifier.create(returnedMono).expectNext(policyTypeIds).expectComplete().verify();
+ List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
+ assertEquals(1, policyTypeIds.size(), "should hardcoded to one");
+ assertEquals("", policyTypeIds.get(0), "should hardcoded to empty");
}
@Test
@Test
public void testGetValidPolicyType() {
- SdncOscAdapterInput inputParams = ImmutableSdncOscAdapterInput.builder() //
- .nearRtRicUrl(RIC_1_URL) //
- .policyTypeId(POLICY_TYPE_1_ID) //
- .build();
- String inputJsonString = A1ClientHelper.createInputJsonString(inputParams);
-
- String policyType = "{\"policySchema\": " + POLICY_TYPE_SCHEMA_VALID + ", \"statusSchema\": {} }";
- Mono<String> policyTypeResp = A1ClientHelper.createOutputJsonResponse("policy-type", policyType);
- whenAsyncPostThenReturn(policyTypeResp);
-
- Mono<String> returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID);
-
- verify(asyncRestClientMock).postWithAuthHeader(POLICY_TYPES_URL, inputJsonString, CONTROLLER_USERNAME,
- CONTROLLER_PASSWORD);
- StepVerifier.create(returnedMono).expectNext(POLICY_TYPE_SCHEMA_VALID).expectComplete().verify();
- }
-
- @Test
- public void testGetInvalidPolicyType() {
- SdncOscAdapterInput inputParams = ImmutableSdncOscAdapterInput.builder() //
- .nearRtRicUrl(RIC_1_URL) //
- .policyTypeId(POLICY_TYPE_1_ID) //
- .build();
- String inputJsonString = A1ClientHelper.createInputJsonString(inputParams);
-
- String policyType = "{\"policySchema\": " + POLICY_TYPE_SCHEMA_INVALID + ", \"statusSchema\": {} }";
- Mono<String> policyTypeResp = A1ClientHelper.createOutputJsonResponse("policy-type", policyType);
- whenAsyncPostThenReturn(policyTypeResp);
-
- Mono<String> returnedMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_ID);
-
- verify(asyncRestClientMock).postWithAuthHeader(POLICY_TYPES_URL, inputJsonString, CONTROLLER_USERNAME,
- CONTROLLER_PASSWORD);
- StepVerifier.create(returnedMono).expectErrorMatches(throwable -> throwable instanceof JSONException).verify();
+ String policyType = clientUnderTest.getPolicyTypeSchema("").block();
+ assertEquals("{}", policyType, "");
}
@Test
package org.oransc.policyagent.clients;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Arrays;
+import java.util.List;
import org.json.JSONException;
import org.junit.jupiter.api.BeforeEach;
@ExtendWith(MockitoExtension.class)
public class StdA1ClientTest {
private static final String RIC_URL = "RicUrl";
- private static final String POLICY_TYPES_IDENTITIES_URL = "/policytypes";
private static final String POLICIES_IDENTITIES_URL = "/policies";
- private static final String POLICY_TYPES_URL = "/policytypes/";
private static final String POLICIES_URL = "/policies/";
-
private static final String POLICY_TYPE_1_NAME = "type1";
- private static final String POLICY_TYPE_2_NAME = "type2";
- private static final String POLICY_TYPE_SCHEMA_VALID = "{\"type\":\"type1\"}";
- private static final String POLICY_TYPE_SCHEMA_INVALID = "\"type\":\"type1\"}";
private static final String POLICY_1_ID = "policy1";
private static final String POLICY_2_ID = "policy2";
private static final String POLICY_JSON_VALID = "{\"policyId\":\"policy1\"}";
@Test
public void testGetPolicyTypeIdentities() {
- Mono<String> policyTypeIds = Mono.just(Arrays.asList(POLICY_TYPE_1_NAME, POLICY_TYPE_2_NAME).toString());
- when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeIds);
-
- Mono<?> policyTypeIdsFlux = clientUnderTest.getPolicyTypeIdentities();
-
- verify(asyncRestClientMock).get(POLICY_TYPES_IDENTITIES_URL);
- StepVerifier.create(policyTypeIdsFlux).expectNextCount(1).expectComplete().verify();
+ List<String> policyTypeIds = clientUnderTest.getPolicyTypeIdentities().block();
+ assertEquals(1, policyTypeIds.size(), "should hardcoded to one");
+ assertEquals("", policyTypeIds.get(0), "should hardcoded to empty");
}
@Test
Mono<String> policyIds = Mono.just(Arrays.asList(POLICY_1_ID, POLICY_2_ID).toString());
when(asyncRestClientMock.get(anyString())).thenReturn(policyIds);
- Mono<?> policyIdsFlux = clientUnderTest.getPolicyIdentities();
+ List<String> result = clientUnderTest.getPolicyIdentities().block();
+ assertEquals(2, result.size(), "");
verify(asyncRestClientMock).get(POLICIES_IDENTITIES_URL);
- StepVerifier.create(policyIdsFlux).expectNextCount(1).expectComplete().verify();
}
@Test
public void testGetValidPolicyType() {
- Mono<String> policyTypeResp =
- Mono.just("{\"policySchema\": " + POLICY_TYPE_SCHEMA_VALID + ", \"statusSchema\": {} }");
-
- when(asyncRestClientMock.get(anyString())).thenReturn(policyTypeResp);
-
- Mono<String> policyTypeMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_NAME);
-
- verify(asyncRestClientMock).get(POLICY_TYPES_URL + POLICY_TYPE_1_NAME);
- StepVerifier.create(policyTypeMono).expectNext(POLICY_TYPE_SCHEMA_VALID).expectComplete().verify();
- }
-
- @Test
- public void testGetInvalidPolicyType() {
- when(asyncRestClientMock.get(anyString())).thenReturn(Mono.just(POLICY_TYPE_SCHEMA_INVALID));
-
- Mono<String> policyTypeMono = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_NAME);
-
- verify(asyncRestClientMock).get(POLICY_TYPES_URL + POLICY_TYPE_1_NAME);
- StepVerifier.create(policyTypeMono).expectErrorMatches(throwable -> throwable instanceof JSONException)
- .verify();
+ String policyType = clientUnderTest.getPolicyTypeSchema(POLICY_TYPE_1_NAME).block();
+ assertEquals("{}", policyType, "");
}
@Test
Mono<String> policyMono = clientUnderTest
.putPolicy(A1ClientHelper.createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE));
- verify(asyncRestClientMock).put(POLICIES_URL + POLICY_1_ID + "?policyTypeId=" + POLICY_TYPE, POLICY_JSON_VALID);
+ verify(asyncRestClientMock).put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID);
StepVerifier.create(policyMono).expectNext(POLICY_JSON_VALID).expectComplete().verify();
}
private A1ClientFactory a1ClientFactory;
@Mock
- private RicSynchronizationTask recoveryTaskMock;
+ private RicSynchronizationTask synchronizationTaskMock;
private final PolicyTypes types = new PolicyTypes();
private Policies policies = new Policies();
}
@Test
- public void whenRicIdleAndNoChangedPoliciesOrPolicyTypes_thenNoRecovery() {
+ public void whenRicIdleAndNoChangedPoliciesOrPolicyTypes_thenNoSynchronization() {
RIC_1.setState(RicState.IDLE);
RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
rics.put(RIC_1);
}
@Test
- public void whenRicUndefined_thenRecovery() {
+ public void whenRicUndefined_thenSynchronization() {
RIC_1.setState(RicState.UNDEFINED);
rics.put(RIC_1);
RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
- doReturn(recoveryTaskMock).when(supervisorUnderTest).createSynchronizationTask();
+ doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
supervisorUnderTest.checkAllRics();
verify(supervisorUnderTest).checkAllRics();
verify(supervisorUnderTest).createSynchronizationTask();
- verify(recoveryTaskMock).run(RIC_1);
+ verify(synchronizationTaskMock).run(RIC_1);
verifyNoMoreInteractions(supervisorUnderTest);
}
@Test
- public void whenRicRecovering_thenNoRecovery() {
+ public void whenRicSynchronizing_thenNoSynchronization() {
RIC_1.setState(RicState.SYNCHRONIZING);
rics.put(RIC_1);
}
@Test
- public void whenRicIdleAndErrorGettingPolicyIdentities_thenNoRecovery() {
+ public void whenRicIdleAndErrorGettingPolicyIdentities_thenNoSynchronization() {
RIC_1.setState(RicState.IDLE);
RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
rics.put(RIC_1);
}
@Test
- public void whenRicIdleAndNotSameAmountOfPolicies_thenRecovery() {
+ public void whenRicIdleAndNotSameAmountOfPolicies_thenSynchronization() {
RIC_1.setState(RicState.IDLE);
rics.put(RIC_1);
RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
- doReturn(recoveryTaskMock).when(supervisorUnderTest).createSynchronizationTask();
+ doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
supervisorUnderTest.checkAllRics();
verify(supervisorUnderTest).checkAllRics();
verify(supervisorUnderTest).createSynchronizationTask();
- verify(recoveryTaskMock).run(RIC_1);
+ verify(synchronizationTaskMock).run(RIC_1);
verifyNoMoreInteractions(supervisorUnderTest);
}
@Test
- public void whenRicIdleAndSameAmountOfPoliciesButNotSamePolicies_thenRecovery() {
+ public void whenRicIdleAndSameAmountOfPoliciesButNotSamePolicies_thenSynchronization() {
RIC_1.setState(RicState.IDLE);
rics.put(RIC_1);
RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
- doReturn(recoveryTaskMock).when(supervisorUnderTest).createSynchronizationTask();
+ doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
supervisorUnderTest.checkAllRics();
verify(supervisorUnderTest).checkAllRics();
verify(supervisorUnderTest).createSynchronizationTask();
- verify(recoveryTaskMock).run(RIC_1);
+ verify(synchronizationTaskMock).run(RIC_1);
verifyNoMoreInteractions(supervisorUnderTest);
}
@Test
- public void whenRicIdleAndErrorGettingPolicyTypes_thenNoRecovery() {
+ public void whenRicIdleAndErrorGettingPolicyTypes_thenNoSynchronization() {
RIC_1.setState(RicState.IDLE);
RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
rics.put(RIC_1);
}
@Test
- public void whenRicIdleAndNotSameAmountOfPolicyTypes_thenRecovery() {
+ public void whenRicIdleAndNotSameAmountOfPolicyTypes_thenSynchronization() {
RIC_1.setState(RicState.IDLE);
RIC_1.addSupportedPolicyType(POLICY_TYPE_1);
rics.put(RIC_1);
RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
- doReturn(recoveryTaskMock).when(supervisorUnderTest).createSynchronizationTask();
+ doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
supervisorUnderTest.checkAllRics();
verify(supervisorUnderTest).checkAllRics();
verify(supervisorUnderTest).createSynchronizationTask();
- verify(recoveryTaskMock).run(RIC_1);
+ verify(synchronizationTaskMock).run(RIC_1);
verifyNoMoreInteractions(supervisorUnderTest);
}
@Test
- public void whenRicIdleAndSameAmountOfPolicyTypesButNotSameTypes_thenRecovery() {
+ public void whenRicIdleAndSameAmountOfPolicyTypesButNotSameTypes_thenSynchronization() {
PolicyType policyType2 = ImmutablePolicyType.builder() //
.name("policyType2") //
.schema("") //
RicSupervision supervisorUnderTest = spy(new RicSupervision(rics, policies, a1ClientFactory, types, null));
- doReturn(recoveryTaskMock).when(supervisorUnderTest).createSynchronizationTask();
+ doReturn(synchronizationTaskMock).when(supervisorUnderTest).createSynchronizationTask();
supervisorUnderTest.checkAllRics();
verify(supervisorUnderTest).checkAllRics();
verify(supervisorUnderTest).createSynchronizationTask();
- verify(recoveryTaskMock).run(RIC_1);
+ verify(synchronizationTaskMock).run(RIC_1);
verifyNoMoreInteractions(supervisorUnderTest);
}
@Override
public Mono<A1ProtocolType> getProtocolVersion() {
- return Mono.just(A1ProtocolType.STD_V1);
+ return Mono.just(A1ProtocolType.STD_V1_1);
}
@Override
* @return the base url
*/
public String getBaseUrl(final String nearRtRicUrl) {
- String baseUrl = nearRtRicUrl + "/A1-P/v1";
- return UriComponentsBuilder.fromUriString(baseUrl).build().toString();
+ return nearRtRicUrl + "/A1-P/v1";
}
/**
* @return the policies url
*/
public String policiesUrl(final String nearRtRicUrl) {
- return UriComponentsBuilder.fromUriString(getBaseUrl(nearRtRicUrl)).pathSegment("policies").build().toString();
+ return getBaseUrl(nearRtRicUrl) + "/policies";
}
/**
* @return the putPolicy url
*/
public String putPolicyUrl(final String nearRtRicUrl, final String policyId, final String policyTypeId) {
- return UriComponentsBuilder.fromUriString(policiesUrl(nearRtRicUrl))
- .pathSegment(policyId + "?policyTypeId=" + policyTypeId).build().toString();
+ UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(policiesUrl(nearRtRicUrl)).pathSegment(policyId);
+
+ if (!policyTypeId.isEmpty()) {
+ builder.queryParam("policyTypeId", policyTypeId);
+ }
+ return builder.build().toString();
}
/**