+ String url = "/policy_status?instance=id";
+ String rsp = restClient().get(url).block();
+ assertThat(rsp.equals("OK")).isTrue();
+
+ // GET non existing policy status
+ url = "/policy_status?instance=XXX";
+ testErrorCode(restClient().get(url), HttpStatus.NOT_FOUND);
+ }
+
+ private Policy addPolicy(String id, String typeName, String service, String ric) throws ServiceException {
+ addRic(ric);
+ Policy p = ImmutablePolicy.builder().id(id) //
+ .json(jsonString()) //
+ .ownerServiceName(service) //
+ .ric(rics.getRic(ric)) //
+ .type(addPolicyType(typeName, ric)) //
+ .lastModified("lastModified").build();
+ policies.put(p);
+ return p;
+ }
+
+ private Policy addPolicy(String id, String typeName, String service) throws ServiceException {
+ return addPolicy(id, typeName, service, "ric");
+ }
+
+ private String createServiceJson(String name) {
+ ServiceRegistrationInfo service = new ServiceRegistrationInfo(name, 1, "callbackUrl");
+
+ String json = gson.toJson(service);
+ return json;
+ }
+
+ private void putService(String name) {
+ String url = "/service";
+ restClient().put(url, createServiceJson(name)).block();
+ }
+
+ private String baseUrl() {
+ return "http://localhost:" + port;
+ }
+
+ private String jsonString() {
+ return "{\n \"servingCellNrcgi\": \"1\"\n }";
+ }
+
+ private static class ConcurrencyTestRunnable implements Runnable {
+ private final RestTemplate restTemplate = new RestTemplate();
+ private final String baseUrl;
+ static AtomicInteger nextCount = new AtomicInteger(0);
+ private final int count;
+ private final RepositorySupervision supervision;
+
+ ConcurrencyTestRunnable(String baseUrl, RepositorySupervision supervision) {
+ this.baseUrl = baseUrl;
+ this.count = nextCount.incrementAndGet();
+ this.supervision = supervision;
+ }
+
+ @Override
+ public void run() {
+ for (int i = 0; i < 100; ++i) {
+ if (i % 10 == 0) {
+ this.supervision.checkAllRics();
+ }
+ String name = "policy:" + count + ":" + i;
+ putPolicy(name);
+ deletePolicy(name);
+ }
+ }
+
+ private void putPolicy(String name) {
+ String putUrl = baseUrl + "/policy?type=type1&instance=" + name + "&ric=ric1&service=service1";
+ restTemplate.put(putUrl, createJsonHttpEntity("{}"));
+ }
+
+ private void deletePolicy(String name) {
+ String deleteUrl = baseUrl + "/policy?instance=" + name;
+ restTemplate.delete(deleteUrl);
+ }
+ }
+
+ @Test
+ public void testConcurrency() throws Exception {
+ final Instant startTime = Instant.now();
+ List<Thread> threads = new ArrayList<>();
+ addRic("ric1");
+ addPolicyType("type1", "ric1");
+
+ for (int i = 0; i < 100; ++i) {
+ Thread t = new Thread(new ConcurrencyTestRunnable(baseUrl(), this.supervision), "TestThread_" + i);
+ t.start();
+ threads.add(t);
+ }
+ for (Thread t : threads) {
+ t.join();
+ }
+ assertThat(policies.size()).isEqualTo(0);
+ System.out.println("Concurrency test took " + Duration.between(startTime, Instant.now()));
+ }
+
+ private AsyncRestClient restClient() {
+ return new AsyncRestClient(baseUrl());
+ }
+
+ private void testErrorCode(Mono<?> request, HttpStatus expStatus) {
+ StepVerifier.create(request) //
+ .expectSubscription() //
+ .expectErrorMatches(t -> checkWebClientError(t, expStatus)) //
+ .verify();
+ }
+
+ private boolean checkWebClientError(Throwable t, HttpStatus expStatus) {
+ assertTrue(t instanceof WebClientResponseException);
+ WebClientResponseException e = (WebClientResponseException) t;
+ assertThat(e.getStatusCode()).isEqualTo(expStatus);
+ return true;
+ }
+
+ private MockA1Client getA1Client(String ricName) throws ServiceException {
+ return a1ClientFactory.getOrCreateA1Client(ricName);
+ }
+
+ private PolicyType addPolicyType(String policyTypeName, String ricName) {
+ PolicyType type = ImmutablePolicyType.builder() //
+ .name(policyTypeName) //
+ .schema("{\"title\":\"" + policyTypeName + "\"}") //
+ .build();
+
+ policyTypes.put(type);
+ addRic(ricName).addSupportedPolicyType(type);
+ return type;
+ }
+
+ private Ric addRic(String ricName) {
+ return addRic(ricName, null);
+ }
+
+ private Ric addRic(String ricName, String managedElement) {
+ if (rics.get(ricName) != null) {
+ return rics.get(ricName);
+ }
+ List<String> mes = new ArrayList<>();
+ if (managedElement != null) {
+ mes.add(managedElement);
+ }
+ RicConfig conf = ImmutableRicConfig.builder() //
+ .name(ricName) //
+ .baseUrl(ricName) //
+ .managedElementIds(mes) //
+ .build();
+ Ric ric = new Ric(conf);
+ ric.setState(Ric.RicState.IDLE);
+ this.rics.put(ric);
+ return ric;
+ }
+
+ private static HttpEntity<String> createJsonHttpEntity(String content) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ return new HttpEntity<String>(content, headers);