re base code
[sdc.git] / openecomp-be / backend / openecomp-sdc-vendor-software-product-manager / src / test / java / org / openecomp / sdc / vendorsoftwareproduct / impl / NicManagerImplTest.java
1 /*
2  * Copyright © 2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 package org.openecomp.sdc.vendorsoftwareproduct.impl;
18
19 import org.mockito.InjectMocks;
20 import org.mockito.Mock;
21 import org.mockito.MockitoAnnotations;
22 import org.mockito.Spy;
23 import org.openecomp.sdc.common.errors.CoreException;
24 import org.openecomp.sdc.vendorsoftwareproduct.CompositionEntityDataManager;
25 import org.openecomp.sdc.vendorsoftwareproduct.NetworkManager;
26 import org.openecomp.sdc.vendorsoftwareproduct.dao.NicDao;
27 import org.openecomp.sdc.vendorsoftwareproduct.dao.VendorSoftwareProductInfoDao;
28 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.NetworkEntity;
29 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.NicEntity;
30 import org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductErrorCodes;
31 import org.openecomp.sdc.vendorsoftwareproduct.types.CompositionEntityResponse;
32 import org.openecomp.sdc.vendorsoftwareproduct.types.QuestionnaireResponse;
33 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityType;
34 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityValidationData;
35 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.NetworkType;
36 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
37 import org.openecomp.sdc.versioning.dao.types.Version;
38 import org.openecomp.sdc.versioning.errors.VersioningErrorCodes;
39 import org.testng.Assert;
40 import org.testng.annotations.AfterMethod;
41 import org.testng.annotations.BeforeMethod;
42 import org.testng.annotations.Test;
43
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.Collection;
47
48 import static org.mockito.Matchers.anyObject;
49 import static org.mockito.Mockito.*;
50
51 public class NicManagerImplTest {
52
53   private static final String NIC_NOT_EXIST_MSG =
54       "Vendor Software Product NIC with Id nic1 does not exist for Vendor Software Product with " +
55           "id VSP_ID and version version_id";
56
57   private static final String VSP_ID = "VSP_ID";
58   private static final Version VERSION = new Version("version_id");
59   private static final String COMPONENT_ID = "COMPONENT_ID";
60   private static final String NIC1_ID = "nic1";
61   private static final String NIC2_ID = "nic2";
62   private static final String NETWORK1_ID = "network1";
63   private static final String NETWORK2_ID = "network2";
64
65   @Mock
66   private NicDao nicDao;
67   @Mock
68   private CompositionEntityDataManager compositionEntityDataManagerMock;
69   @Mock
70   private NetworkManager networkManagerMock;
71   @Mock
72   private VendorSoftwareProductInfoDao vspInfoDao;
73   @InjectMocks
74   @Spy
75   private NicManagerImpl nicManager;
76
77   @BeforeMethod
78   public void setUp() throws Exception {
79     MockitoAnnotations.initMocks(this);
80   }
81
82   @AfterMethod
83   public void tearDown() {
84     nicManager = null;
85   }
86
87   @Test
88   public void testListWhenNone() {
89     Collection<NicEntity> nics = nicManager.listNics(VSP_ID, VERSION, COMPONENT_ID);
90     Assert.assertEquals(nics.size(), 0);
91   }
92
93   @Test
94   public void testList() {
95     doReturn(Arrays.asList(
96         createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID),
97         createNic(VSP_ID, VERSION, COMPONENT_ID, NIC2_ID, NETWORK2_ID)))
98         .when(nicDao).list(anyObject());
99
100     NetworkEntity network1 = NetworkManagerImplTest.createNetwork(VSP_ID, VERSION, NETWORK1_ID);
101     NetworkEntity network2 = NetworkManagerImplTest.createNetwork(VSP_ID, VERSION, NETWORK2_ID);
102     doReturn(Arrays.asList(network1, network2))
103         .when(networkManagerMock).listNetworks(VSP_ID, VERSION);
104
105     Collection<NicEntity> nics = nicManager.listNics(VSP_ID, VERSION, COMPONENT_ID);
106     Assert.assertEquals(nics.size(), 2);
107     for (NicEntity nic : nics) {
108       Assert.assertEquals(nic.getNicCompositionData().getNetworkName(),
109           NIC1_ID.equals(nic.getId())
110               ? network1.getNetworkCompositionData().getName()
111               : network2.getNetworkCompositionData().getName());
112     }
113   }
114
115   @Test
116   public void testCreate() {
117     NicEntity nicEntity = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
118     Nic nic = nicEntity.getNicCompositionData();
119     nic.setNetworkType(NetworkType.Internal);
120     nicEntity.setNicCompositionData(nic);
121     doReturn(true).when(vspInfoDao).isManual(anyObject(), anyObject());
122     Collection<NicEntity> nicEntities = new ArrayList<>();
123     doReturn(nicEntities).when(nicDao).list(anyObject());
124     doReturn(nicEntity).when(compositionEntityDataManagerMock).createNic(anyObject());
125
126     NicEntity created = nicManager.createNic(nicEntity);
127     Assert.assertNotNull(created);
128   }
129
130   @Test
131   public void testCreateWithIncorrectNicNameFormat() {
132     NicEntity nicEntity = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
133     Nic nic = nicEntity.getNicCompositionData();
134     nic.setNetworkType(NetworkType.Internal);
135     nicEntity.setNicCompositionData(nic);
136     doReturn(true).when(vspInfoDao).isManual(anyObject(), anyObject());
137     Collection<NicEntity> nicEntities = new ArrayList<>();
138
139     NicEntity nicEntityDiffName = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
140     Nic newNameNic = nicEntityDiffName.getNicCompositionData();
141     newNameNic.setName(NIC1_ID + "_Name/*");
142     nicEntityDiffName.setNicCompositionData(newNameNic);
143     nicEntities.add(nicEntityDiffName);
144     doReturn(nicEntities).when(nicDao).list(anyObject());
145     doReturn(nicEntity).when(compositionEntityDataManagerMock).createNic(anyObject());
146
147     try {
148       NicEntity created = nicManager.createNic(nicEntity);
149     } catch (CoreException exception) {
150       Assert.assertEquals(VendorSoftwareProductErrorCodes.NIC_NAME_FORMAT_NOT_ALLOWED,
151           exception.code().id());
152     }
153   }
154
155   @Test
156   public void testCreateWithDupNicName() {
157     NicEntity nicEntity = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
158     Nic nic = nicEntity.getNicCompositionData();
159     nic.setNetworkType(NetworkType.Internal);
160     nicEntity.setNicCompositionData(nic);
161     doReturn(true).when(vspInfoDao).isManual(anyObject(), anyObject());
162     Collection<NicEntity> nicEntities = new ArrayList<>();
163
164     NicEntity nicEntityDiffName = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
165     Nic newNameNic = nicEntityDiffName.getNicCompositionData();
166     newNameNic.setName(NIC1_ID + "_Name");
167     nicEntityDiffName.setNicCompositionData(newNameNic);
168     nicEntities.add(nicEntityDiffName);
169     doReturn(nicEntities).when(nicDao).list(anyObject());
170     doReturn(nicEntity).when(compositionEntityDataManagerMock).createNic(anyObject());
171
172     try {
173       NicEntity created = nicManager.createNic(nicEntity);
174     } catch (CoreException exception) {
175       Assert.assertEquals("Invalid request, NIC with name " + nic.getName() +
176               " already exist for component with ID " + nicEntity.getComponentId() + ".",
177           exception.code().message());
178       Assert.assertEquals(VendorSoftwareProductErrorCodes.DUPLICATE_NIC_NAME_NOT_ALLOWED,
179           exception.code().id());
180     }
181   }
182
183   @Test
184   public void testCreateWithExternalNetworkType() {
185     NicEntity nicEntity = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
186     Nic nic = nicEntity.getNicCompositionData();
187     nic.setNetworkType(NetworkType.External);
188     nicEntity.setNicCompositionData(nic);
189     doReturn(true).when(vspInfoDao).isManual(anyObject(), anyObject());
190     Collection<NicEntity> nicEntities = new ArrayList<>();
191     doReturn(nicEntities).when(nicDao).list(anyObject());
192     doReturn(nicEntity).when(compositionEntityDataManagerMock).createNic(anyObject());
193
194     try {
195       NicEntity created = nicManager.createNic(nicEntity);
196     } catch (CoreException exception) {
197       Assert.assertEquals("Invalid request,NetworkId not allowed for External Networks",
198           exception.code().message());
199       Assert
200           .assertEquals(VendorSoftwareProductErrorCodes.NETWORKID_NOT_ALLOWED_FOR_EXTERNAL_NETWORK,
201               exception.code().id());
202     }
203   }
204
205   @Test
206   public void testCreateWithNetworkDesc() {
207     NicEntity nicEntity = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
208     Nic nic = nicEntity.getNicCompositionData();
209     nic.setNetworkType(NetworkType.Internal);
210     nic.setNetworkDescription(NIC1_ID);
211     nicEntity.setNicCompositionData(nic);
212     doReturn(true).when(vspInfoDao).isManual(anyObject(), anyObject());
213     Collection<NicEntity> nicEntities = new ArrayList<>();
214     doReturn(nicEntities).when(nicDao).list(anyObject());
215     doReturn(nicEntity).when(compositionEntityDataManagerMock).createNic(anyObject());
216
217     try {
218       NicEntity created = nicManager.createNic(nicEntity);
219     } catch (CoreException exception) {
220       Assert.assertEquals("Invalid request, Network Description not allowed for Internal Networks",
221           exception.code().message());
222       Assert.assertEquals(VendorSoftwareProductErrorCodes
223           .NETWORK_DESCRIPTION_NOT_ALLOWED_FOR_INTERNAL_NETWORK, exception.code().id());
224     }
225   }
226
227   @Test
228   public void testDeleteNic() {
229     NicEntity nicEntity = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
230     doReturn(true).when(vspInfoDao).isManual(anyObject(), anyObject());
231     doReturn(nicEntity).when(nicDao).get(anyObject());
232
233     nicManager.deleteNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
234
235   }
236
237   @Test
238   public void testUpdateNicQuestionnaire() {
239     NicEntity nicEntity = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
240
241     doReturn(nicEntity).when(nicDao).get(anyObject());
242     doReturn("{}").when(nicManager).getNicCompositionSchema(anyObject());
243
244     nicManager
245         .updateNicQuestionnaire(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, "Ques");
246
247     verify(nicDao).updateQuestionnaireData(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, "Ques");
248   }
249
250 //    @Test(dependsOnMethods = "testListWhenNone")
251 //    public void testCreate() {
252 //        NIC1_ID = testCreate(VSP_ID, COMPONENT_ID, NETWORK1_ID, NETWORK1_ID.getNetworkCompositionData().getName());
253 //    }
254
255 /*    @Test(dependsOnMethods = {"testCreate"})
256     public void testCreateWithExistingName_negative() {
257         NicEntity nic = new NicEntity(VSP_ID, null, COMPONENT_ID, null);
258         Nic nicData = new Nic();
259         nicData.setName("nic1 name");
260         nic.setNicCompositionData(nicData);
261         testCreate_negative(nic, UniqueValueUtil.UNIQUE_VALUE_VIOLATION);
262     }*/
263
264 //    @Test(dependsOnMethods = {"testCreate"})
265 //    public void testCreateWithExistingNameUnderOtherComponent() {
266 //        ComponentEntity component12 = new ComponentEntity(VSP_ID, null, null);
267 //        ComponentData compData12 = new ComponentData();
268 //        compData12.setName("comp12 name");
269 //        compData12.setDescription("comp12 desc");
270 //        component12.setComponentCompositionData(compData12);
271 //
272 //        String component12Id = nicManager.createComponent(component12).getId();
273 //        testCreate(VSP_ID, component12Id, NETWORK1_ID, NETWORK1_ID.getNetworkCompositionData().getName());
274 //    }
275
276 //    @Test(dependsOnMethods = {"testCreate"})
277 //    public void testCreateWithExistingNameUnderOtherVsp() {
278 //        testCreate(vsp2Id, component21Id, network2.getId(), network2.getNetworkCompositionData().getName());
279 //    }
280
281   @Test
282   public void testCreateOnUploadVsp_negative() {
283
284     testCreate_negative(new NicEntity(VSP_ID, VERSION, COMPONENT_ID, null),
285         VendorSoftwareProductErrorCodes.ADD_NIC_NOT_ALLOWED_IN_HEAT_ONBOARDING);
286   }
287
288   @Test
289   public void testUpdateNonExistingNicId_negative() {
290     doReturn(null).when(nicDao).get(anyObject());
291
292     testUpdate_negative(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID,
293         VersioningErrorCodes.VERSIONABLE_SUB_ENTITY_NOT_FOUND);
294   }
295
296   @Test
297   public void testUpdateOnUploadVsp() {
298     doReturn(createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID))
299         .when(nicDao).get(anyObject());
300
301     doReturn(new CompositionEntityValidationData(CompositionEntityType.nic, NIC1_ID))
302         .when(compositionEntityDataManagerMock)
303         .validateEntity(anyObject(), anyObject(), anyObject());
304
305     NicEntity nicEntity = new NicEntity(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
306     Nic nicData = new Nic();
307     nicData.setName(NIC1_ID + " name");
308     nicData.setDescription(NIC1_ID + " desc updated");
309     nicData.setNetworkId(NETWORK1_ID);
310     nicEntity.setNicCompositionData(nicData);
311
312     CompositionEntityValidationData validationData =
313         nicManager.updateNic(nicEntity);
314     Assert.assertTrue(validationData == null || validationData.getErrors() == null);
315     verify(nicDao).update(nicEntity);
316   }
317
318   @Test
319   public void testIllegalUpdateOnUploadVsp() {
320     doReturn(createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID))
321         .when(nicDao).get(anyObject());
322
323     CompositionEntityValidationData toBeReturned =
324         new CompositionEntityValidationData(CompositionEntityType.nic, NIC1_ID);
325     toBeReturned.setErrors(Arrays.asList("error1", "error2"));
326     doReturn(toBeReturned)
327         .when(compositionEntityDataManagerMock)
328         .validateEntity(anyObject(), anyObject(), anyObject());
329
330     NicEntity nicEntity = new NicEntity(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
331     Nic nicData = new Nic();
332     nicData.setName(NIC1_ID + "_name_updated");
333     nicData.setDescription(NIC1_ID + " desc updated");
334     nicData.setNetworkId(NETWORK1_ID);
335     nicEntity.setNicCompositionData(nicData);
336
337     CompositionEntityValidationData validationData = nicManager.updateNic(nicEntity);
338     Assert.assertNotNull(validationData);
339     Assert.assertEquals(validationData.getErrors().size(), 2);
340
341     verify(nicDao, never()).update(nicEntity);
342   }
343
344   @Test
345   public void testUpdateIncorrectNameFormat() {
346     doReturn(createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID))
347         .when(nicDao).get(anyObject());
348
349     CompositionEntityValidationData toBeReturned =
350         new CompositionEntityValidationData(CompositionEntityType.nic, NIC1_ID);
351     toBeReturned.setErrors(Arrays.asList("Field does not conform to predefined criteria:name : must match [a-zA-Z0-9_]*$"));
352     doReturn(toBeReturned)
353         .when(compositionEntityDataManagerMock)
354         .validateEntity(anyObject(), anyObject(), anyObject());
355     doReturn(true).when(vspInfoDao).isManual(anyObject(), anyObject());
356
357     NicEntity nicEntity = new NicEntity(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
358     Nic nicData = new Nic();
359     nicData.setName(NIC1_ID + "_name_updated/*");
360     nicData.setDescription(NIC1_ID + " desc updated");
361     nicData.setNetworkId(NETWORK1_ID);
362     nicEntity.setNicCompositionData(nicData);
363
364     CompositionEntityValidationData output = nicManager.updateNic(nicEntity);
365     Assert.assertEquals(output.getErrors(),toBeReturned.getErrors());
366
367   }
368
369
370   @Test
371   public void testGetNonExistingNicId_negative() {
372     testGet_negative(VSP_ID, VERSION, COMPONENT_ID, "non existing nic id",
373         VersioningErrorCodes.VERSIONABLE_SUB_ENTITY_NOT_FOUND);
374   }
375
376
377   @Test
378   public void testGet() {
379     NicEntity expected = createNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, NETWORK1_ID);
380     doReturn(expected).when(nicDao).get(anyObject());
381     String compositionSchema = "schema string";
382     doReturn(compositionSchema).when(nicManager).getNicCompositionSchema(anyObject());
383
384     CompositionEntityResponse<Nic> response =
385         nicManager.getNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
386     Assert.assertEquals(response.getId(), expected.getId());
387     Assert.assertEquals(response.getData(), expected.getNicCompositionData());
388     Assert.assertEquals(response.getSchema(), compositionSchema);
389   }
390
391 /*
392     @Test(dependsOnMethods = {"testUpdateOnUploadVsp", "testList"})
393     public void testCreateWithRemovedName() {
394         testCreate(VSP_ID, COMPONENT_ID);
395     }
396
397     @Test
398     public void testDeleteNonExistingNicId_negative() {
399         testDelete_negative(VSP_ID, COMPONENT_ID, "non existing nic id", VersioningErrorCodes.VERSIONABLE_SUB_ENTITY_NOT_FOUND);
400     }
401
402     @Test(dependsOnMethods = "testList")
403     public void testDeleteNonExistingComponentId_negative() {
404         testDelete_negative(VSP_ID, "non existing component id", NIC1_ID, VersioningErrorCodes.VERSIONABLE_SUB_ENTITY_NOT_FOUND);
405     }*/
406
407 /*
408     @Test(dependsOnMethods = "testList")
409     public void testDelete() {
410         nicManager.deleteNic(VSP_ID, COMPONENT_ID, NIC1_ID);
411         NicEntity actual = vendorSoftwareProductDao.getNic(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
412         Assert.assertNull(actual);
413     }*/
414
415   @Test
416   public void testDeleteOnUploadVsp_negative() {
417     testDelete_negative(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID,
418         VendorSoftwareProductErrorCodes.DELETE_NIC_NOT_ALLOWED);
419   }
420
421   @Test(expectedExceptions = CoreException.class,
422       expectedExceptionsMessageRegExp = NIC_NOT_EXIST_MSG)
423   public void testGetNonExistingNicQuestionnaire() throws Exception {
424     nicManager.getNicQuestionnaire(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
425   }
426
427   @Test
428   public void testGetQuestionnaire() throws Exception {
429     NicEntity nic = new NicEntity(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
430     nic.setQuestionnaireData("{}");
431     doReturn(nic).when(nicDao).getQuestionnaireData(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
432
433     String schema = "schema string";
434     doReturn(schema).when(nicManager).getNicQuestionnaireSchema(anyObject());
435
436     QuestionnaireResponse questionnaire =
437         nicManager.getNicQuestionnaire(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID);
438     Assert.assertNotNull(questionnaire);
439     Assert.assertEquals(questionnaire.getData(), nic.getQuestionnaireData());
440     Assert.assertEquals(questionnaire.getSchema(), schema);
441     Assert.assertNull(questionnaire.getErrorMessage());
442   }
443
444   @Test(expectedExceptions = CoreException.class,
445       expectedExceptionsMessageRegExp = NIC_NOT_EXIST_MSG)
446   public void testUpdateNonExistingNicQuestionnaire() throws Exception {
447     doReturn(null).when(nicDao).get(anyObject());
448     nicManager
449         .updateNicQuestionnaire(VSP_ID, VERSION, COMPONENT_ID, NIC1_ID, "questionnaire data");
450   }
451
452   @Test
453   public void testUpdateQuestionnaire() throws Exception {
454
455   }
456
457   private void testCreate_negative(NicEntity nic, String expectedErrorCode) {
458     try {
459       nicManager.createNic(nic);
460       Assert.fail();
461     } catch (CoreException exception) {
462       Assert.assertEquals(exception.code().id(), expectedErrorCode);
463     }
464   }
465
466   private void testGet_negative(String vspId, Version version, String componentId, String nicId,
467                                 String expectedErrorCode) {
468     try {
469       nicManager.getNic(vspId, version, componentId, nicId);
470       Assert.fail();
471     } catch (CoreException exception) {
472       Assert.assertEquals(exception.code().id(), expectedErrorCode);
473     }
474   }
475
476   private void testUpdate_negative(String vspId, Version version, String componentId, String nicId,
477                                    String expectedErrorCode) {
478     try {
479       nicManager.updateNic(new NicEntity(vspId, version, componentId, nicId));
480       Assert.fail();
481     } catch (CoreException exception) {
482       Assert.assertEquals(exception.code().id(), expectedErrorCode);
483     }
484   }
485
486   private void testDelete_negative(String vspId, Version version, String componentId, String nicId,
487                                    String expectedErrorCode) {
488     try {
489       nicManager.deleteNic(vspId, version, componentId, nicId);
490       Assert.fail();
491     } catch (CoreException exception) {
492       Assert.assertEquals(exception.code().id(), expectedErrorCode);
493     }
494   }
495
496   static NicEntity createNic(String vspId, Version version, String compId, String nicId,
497                              String networkId) {
498     NicEntity nicEntity = new NicEntity(vspId, version, compId, nicId);
499     Nic nicData = new Nic();
500     nicData.setName(nicId + "_name");
501     nicData.setDescription(nicId + " desc");
502     nicData.setNetworkId(networkId);
503     nicEntity.setNicCompositionData(nicData);
504     return nicEntity;
505   }
506
507
508 }