diff options
author | bmiklos <miklos.baranyak@est.tech> | 2022-07-14 17:15:43 +0200 |
---|---|---|
committer | bmiklos <miklos.baranyak@est.tech> | 2022-07-20 11:39:35 +0200 |
commit | 71e676dd1cd2ed4ae348cb686dfd6ed96a4fc5b4 (patch) | |
tree | ab0c2e1c7e742f2da31624c5e5dd7f6343de3288 /cps-ncmp-service | |
parent | 21c17c999c4787f3d11e69b246143e86a10a62df (diff) |
Refractor code to use the new LcmEvent schema
-Old schema deleted and comments from tests are removed
-EventDateTimeFormatter utility added
-From LcmEventsCreator.populateLcmEvent the NcmpServiceCmHandle param
removed and tests are fixed accordingly
-Changes made in test of the LcmEventsCreator for payload testing
to make it more clear
Issue-ID: CPS-1147
Change-Id: Id87c81f2755a6617a0fc68ba92a3d0e3170fd20f
Signed-off-by: bmiklos <miklos.baranyak@est.tech>
Diffstat (limited to 'cps-ncmp-service')
10 files changed, 124 insertions, 104 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java index 111d5dcd58..650251f5ae 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java @@ -32,7 +32,7 @@ import org.onap.cps.ncmp.api.inventory.CmHandleState; import org.onap.cps.ncmp.api.inventory.CompositeStateUtils; import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; -import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent; +import org.onap.ncmp.cmhandle.event.lcm.LcmEvent; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -96,7 +96,7 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState final NcmpServiceCmHandle ncmpServiceCmHandle = YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelCmHandle); final String cmHandleId = ncmpServiceCmHandle.getCmHandleId(); - final NcmpEvent ncmpEvent = lcmEventsCreator.populateLcmEvent(cmHandleId, ncmpServiceCmHandle); - lcmEventsService.publishLcmEvent(cmHandleId, ncmpEvent); + final LcmEvent lcmEvent = lcmEventsCreator.populateLcmEvent(cmHandleId); + lcmEventsService.publishLcmEvent(cmHandleId, lcmEvent); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreator.java index 783b299511..085494aef2 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreator.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreator.java @@ -20,14 +20,11 @@ package org.onap.cps.ncmp.api.impl.event.lcm; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; import java.util.UUID; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; -import org.onap.ncmp.cmhandle.lcm.event.Event; -import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent; +import org.onap.cps.ncmp.api.impl.utils.EventDateTimeFormatter; +import org.onap.ncmp.cmhandle.event.lcm.Event; +import org.onap.ncmp.cmhandle.event.lcm.LcmEvent; import org.springframework.stereotype.Component; @@ -38,42 +35,38 @@ import org.springframework.stereotype.Component; @Component public class LcmEventsCreator { - /** - * Populate NcmpEvent. + * Populate LcmEvent. * - * @param cmHandleId Cm Handle Identifier - * @param ncmpServiceCmHandle Ncmp CmHandle Data - * @return Populated NcmpEvent + * @param cmHandleId Cm Handle Identifier + * @return Populated Lcm Event */ - public NcmpEvent populateLcmEvent(final String cmHandleId, final NcmpServiceCmHandle ncmpServiceCmHandle) { - return createLcmEvent(cmHandleId, ncmpServiceCmHandle); + public LcmEvent populateLcmEvent(final String cmHandleId) { + return createLcmEvent(cmHandleId); } - private NcmpEvent createLcmEvent(final String cmHandleId, final NcmpServiceCmHandle ncmpServiceCmHandle) { - final NcmpEvent ncmpEvent = lcmEventHeader(cmHandleId); - ncmpEvent.setEvent(lcmEventPayload(cmHandleId, ncmpServiceCmHandle)); - return ncmpEvent; + private LcmEvent createLcmEvent(final String cmHandleId) { + final LcmEvent lcmEvent = lcmEventHeader(cmHandleId); + lcmEvent.setEvent(lcmEventPayload(cmHandleId)); + return lcmEvent; } - private Event lcmEventPayload(final String eventCorrelationId, final NcmpServiceCmHandle ncmpServiceCmHandle) { + private Event lcmEventPayload(final String eventCorrelationId) { final Event event = new Event(); event.setCmHandleId(eventCorrelationId); - event.setCmhandleState( - Event.CmhandleState.fromValue(ncmpServiceCmHandle.getCompositeState().getCmHandleState().toString())); - event.setCmhandleProperties(List.of(ncmpServiceCmHandle.getPublicProperties())); return event; } - private NcmpEvent lcmEventHeader(final String eventCorrelationId) { - final NcmpEvent ncmpEvent = new NcmpEvent(); - ncmpEvent.setEventId(UUID.randomUUID().toString()); - ncmpEvent.setEventCorrelationId(eventCorrelationId); - ncmpEvent.setEventTime(ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"))); - ncmpEvent.setEventSource("org.onap.ncmp"); - ncmpEvent.setEventType("org.onap.ncmp.cmhandle-lcm-event"); - ncmpEvent.setEventSchema("org.onap.ncmp:cmhandle-lcm-event:v1"); - return ncmpEvent; + private LcmEvent lcmEventHeader(final String eventCorrelationId) { + final LcmEvent lcmEvent = new LcmEvent(); + lcmEvent.setEventId(UUID.randomUUID().toString()); + lcmEvent.setEventCorrelationId(eventCorrelationId); + lcmEvent.setEventTime(EventDateTimeFormatter.getCurrentDateTime()); + lcmEvent.setEventSource("org.onap.ncmp"); + lcmEvent.setEventType("org.onap.ncmp.cmhandle-lcm-event"); + lcmEvent.setEventSchema("org.onap.ncmp:cmhandle-lcm-event"); + lcmEvent.setEventSchemaVersion("v1"); + return lcmEvent; } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisher.java index 2a946b1008..eda881767d 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisher.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisher.java @@ -22,7 +22,7 @@ package org.onap.cps.ncmp.api.impl.event.lcm; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent; +import org.onap.ncmp.cmhandle.event.lcm.LcmEvent; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.support.SendResult; import org.springframework.stereotype.Service; @@ -38,18 +38,18 @@ import org.springframework.util.concurrent.ListenableFutureCallback; @RequiredArgsConstructor public class LcmEventsPublisher { - private final KafkaTemplate<String, NcmpEvent> lcmEventKafkaTemplate; + private final KafkaTemplate<String, LcmEvent> lcmEventKafkaTemplate; /** * LCM Event publisher. * * @param topicName valid topic name * @param eventKey message key - * @param ncmpEvent message payload + * @param lcmEvent message payload */ - public void publishEvent(final String topicName, final String eventKey, final NcmpEvent ncmpEvent) { - final ListenableFuture<SendResult<String, NcmpEvent>> lcmEventFuture = - lcmEventKafkaTemplate.send(topicName, eventKey, ncmpEvent); + public void publishEvent(final String topicName, final String eventKey, final LcmEvent lcmEvent) { + final ListenableFuture<SendResult<String, LcmEvent>> lcmEventFuture = + lcmEventKafkaTemplate.send(topicName, eventKey, lcmEvent); lcmEventFuture.addCallback(new ListenableFutureCallback<>() { @Override @@ -58,9 +58,9 @@ public class LcmEventsPublisher { } @Override - public void onSuccess(final SendResult<String, NcmpEvent> result) { - log.debug("Successfully published event to topic : {} , NcmpEvent : {}", - result.getRecordMetadata().topic(), result.getProducerRecord().value()); + public void onSuccess(final SendResult<String, LcmEvent> sendResult) { + log.debug("Successfully published event to topic : {} , LcmEvent : {}", + sendResult.getRecordMetadata().topic(), sendResult.getProducerRecord().value()); } }); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsService.java index d9c9b9a1ce..762b21ef34 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsService.java @@ -22,12 +22,12 @@ package org.onap.cps.ncmp.api.impl.event.lcm; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent; +import org.onap.ncmp.cmhandle.event.lcm.LcmEvent; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; /** - * NcmpEventService to call the publisher and publish on the dedicated topic. + * LcmEventsService to call the publisher and publish on the dedicated topic. */ @Slf4j @@ -44,14 +44,14 @@ public class LcmEventsService { private boolean notificationsEnabled; /** - * Publish the NcmpEvent to the public topic. + * Publish the LcmEvent to the public topic. * * @param cmHandleId Cm Handle Id - * @param ncmpEvent Ncmp Event + * @param lcmEvent Lcm Event */ - public void publishLcmEvent(final String cmHandleId, final NcmpEvent ncmpEvent) { + public void publishLcmEvent(final String cmHandleId, final LcmEvent lcmEvent) { if (notificationsEnabled) { - lcmEventsPublisher.publishEvent(topicName, cmHandleId, ncmpEvent); + lcmEventsPublisher.publishEvent(topicName, cmHandleId, lcmEvent); } else { log.debug("Notifications disabled."); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatter.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatter.java new file mode 100644 index 0000000000..acc4057d9d --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatter.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.api.impl.utils; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class EventDateTimeFormatter { + + private static final String DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + + /** + * Gets current date time. + * + * @return the current date time + */ + public static String getCurrentDateTime() { + return ZonedDateTime.now() + .format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)); + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreatorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreatorSpec.groovy index b578700a21..aa79d634f8 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreatorSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCreatorSpec.groovy @@ -20,10 +20,6 @@ package org.onap.cps.ncmp.api.impl.event.lcm -import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCreator -import org.onap.cps.ncmp.api.inventory.CmHandleState -import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder -import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle import spock.lang.Specification class LcmEventsCreatorSpec extends Specification { @@ -31,17 +27,16 @@ class LcmEventsCreatorSpec extends Specification { def objectUnderTest = new LcmEventsCreator() def cmHandleId = 'test-cm-handle' - def 'Map the LcmEvent for operation #operation'() { - given: 'NCMP cm handle details' - def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, compositeState: new CompositeStateBuilder().withCmHandleState(CmHandleState.READY).build(), - publicProperties: ['publicProperty1': 'value1', 'publicProperty2': 'value2']) + def 'Map the LcmEvent'() { when: 'the event is populated' - def result = objectUnderTest.populateLcmEvent(cmHandleId, ncmpServiceCmHandle) + def result = objectUnderTest.populateLcmEvent(cmHandleId) then: 'event header is mapped correctly' assert result.eventSource == 'org.onap.ncmp' assert result.eventCorrelationId == cmHandleId - and: 'event payload is mapped correctly' - assert result.event.cmhandleProperties.size() == 1 - assert result.event.cmhandleProperties[0] == ['publicProperty1': 'value1', 'publicProperty2': 'value2'] + and: 'the result has the correct cm handle id' + assert result.event.cmHandleId == cmHandleId + and: 'the old and new values are not set yet' + assert result.event.oldValues == null + assert result.event.newValues == null } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy index 8b9addc119..f2cd2b51f7 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy @@ -26,8 +26,8 @@ import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsPublisher import org.onap.cps.ncmp.api.utils.MessagingSpec import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.utils.JsonObjectMapper -import org.onap.ncmp.cmhandle.lcm.event.Event -import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent +import org.onap.ncmp.cmhandle.event.lcm.Event +import org.onap.ncmp.cmhandle.event.lcm.LcmEvent import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -46,40 +46,38 @@ class LcmEventsPublisherSpec extends MessagingSpec { def testTopic = 'ncmp-events-test' @SpringBean - LcmEventsPublisher ncmpEventsPublisher = new LcmEventsPublisher(kafkaTemplate) + LcmEventsPublisher lcmEventsPublisher = new LcmEventsPublisher(kafkaTemplate) @Autowired JsonObjectMapper jsonObjectMapper - def 'Produce and Consume Ncmp Event'() { + def 'Produce and Consume Lcm Event'() { given: 'event key and event data' - def eventKey = 'ncmp' - def eventData = new NcmpEvent(eventId: 'test-uuid', + def eventKey = 'lcm' + def eventData = new LcmEvent( + eventId: 'test-uuid', eventCorrelationId: 'cmhandle-as-correlationid', - eventSchema: URI.create('org.onap.ncmp.cmhandle.lcm.event:v1'), - eventSource: URI.create('org.onap.ncmp'), + eventSource: 'org.onap.ncmp', eventTime: '2022-12-31T20:30:40.000+0000', eventType: 'org.onap.ncmp.cmhandle.lcm.event', - event: new Event(cmHandleId: 'cmhandle-test', cmhandleState: 'READY', cmhandleProperties: [['publicProperty1': 'value1'], ['publicProperty2': 'value2']])) - and: 'we have an expected NcmpEvent' - def expectedJsonString = TestUtils.getResourceFileContent('expectedNcmpEvent.json') - def expectedNcmpEvent = jsonObjectMapper.convertJsonString(expectedJsonString, NcmpEvent.class) + eventSchema: 'org.onap.ncmp.cmhandle.lcm.event', + eventSchemaVersion: 'v1', + event: new Event(cmHandleId: 'cmhandle-test')) and: 'consumer has a subscription' kafkaConsumer.subscribe([testTopic] as List<String>) when: 'an event is published' - ncmpEventsPublisher.publishEvent(testTopic, eventKey, eventData) + lcmEventsPublisher.publishEvent(testTopic, eventKey, eventData) and: 'topic is polled' def records = kafkaConsumer.poll(Duration.ofMillis(1500)) - then: 'no exception is thrown' - noExceptionThrown() - and: 'poll returns one record' + then: 'poll returns one record' assert records.size() == 1 and: 'record key matches the expected event key' def record = records.iterator().next() assert eventKey == record.key and: 'record matches the expected event' - assert expectedNcmpEvent == jsonObjectMapper.convertJsonString(record.value, NcmpEvent.class) - + def expectedJsonString = TestUtils.getResourceFileContent('expectedLcmEvent.json') + def expectedLcmEvent = jsonObjectMapper.convertJsonString(expectedJsonString, LcmEvent.class) + assert expectedLcmEvent == jsonObjectMapper.convertJsonString(record.value, LcmEvent.class) } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsServiceSpec.groovy index 3dab5aff17..1eae357bb6 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsServiceSpec.groovy @@ -20,7 +20,7 @@ package org.onap.cps.ncmp.api.impl.event.lcm -import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent +import org.onap.ncmp.cmhandle.event.lcm.LcmEvent import spock.lang.Specification class LcmEventsServiceSpec extends Specification { @@ -30,15 +30,15 @@ class LcmEventsServiceSpec extends Specification { def objectUnderTest = new LcmEventsService(mockLcmEventsPublisher) def 'Create and Publish lcm event where events are #scenario'() { - given: 'a cm handle id and Ncmp Event' + given: 'a cm handle id and Lcm Event' def cmHandleId = 'test-cm-handle-id' - def ncmpEvent = new NcmpEvent(eventId: UUID.randomUUID().toString(), eventCorrelationId: cmHandleId) - and: 'notifications enabled is #notificationsEnabled' + def lcmEvent = new LcmEvent(eventId: UUID.randomUUID().toString(), eventCorrelationId: cmHandleId) + and: 'notificationsEnabled is #notificationsEnabled and it will be true as default' objectUnderTest.notificationsEnabled = notificationsEnabled when: 'service is called to publish lcm event' - objectUnderTest.publishLcmEvent('test-cm-handle-id', ncmpEvent) + objectUnderTest.publishLcmEvent('test-cm-handle-id', lcmEvent) then: 'publisher is called #expectedTimesMethodCalled times' - expectedTimesMethodCalled * mockLcmEventsPublisher.publishEvent(_, cmHandleId, ncmpEvent) + expectedTimesMethodCalled * mockLcmEventsPublisher.publishEvent(_, cmHandleId, lcmEvent) where: 'the following values are used' scenario | notificationsEnabled || expectedTimesMethodCalled 'enabled' | true || 1 diff --git a/cps-ncmp-service/src/test/resources/expectedLcmEvent.json b/cps-ncmp-service/src/test/resources/expectedLcmEvent.json new file mode 100644 index 0000000000..1db16ee82a --- /dev/null +++ b/cps-ncmp-service/src/test/resources/expectedLcmEvent.json @@ -0,0 +1,12 @@ +{ + "eventId": "test-uuid", + "eventCorrelationId": "cmhandle-as-correlationid", + "eventTime": "2022-12-31T20:30:40.000+0000", + "eventSource": "org.onap.ncmp", + "eventType": "org.onap.ncmp.cmhandle.lcm.event", + "eventSchema": "org.onap.ncmp.cmhandle.lcm.event", + "eventSchemaVersion": "v1", + "event": { + "cmHandleId": "cmhandle-test" + } +}
\ No newline at end of file diff --git a/cps-ncmp-service/src/test/resources/expectedNcmpEvent.json b/cps-ncmp-service/src/test/resources/expectedNcmpEvent.json deleted file mode 100644 index 3d457a0a3d..0000000000 --- a/cps-ncmp-service/src/test/resources/expectedNcmpEvent.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "eventId": "test-uuid", - "eventCorrelationId": "cmhandle-as-correlationid", - "eventTime": "2022-12-31T20:30:40.000+0000", - "eventSource": "org.onap.ncmp", - "eventType": "org.onap.ncmp.cmhandle.lcm.event", - "eventSchema": "org.onap.ncmp.cmhandle.lcm.event:v1", - "event": { - "cmHandleId": "cmhandle-test", - "cmhandle-state": "READY", - "cmhandle-properties": [ - { - "publicProperty1": "value1" - }, - { - "publicProperty2": "value2" - } - ] - } -}
\ No newline at end of file |