cbb444a09398c3fbe1191cc8ed4f244e0800f232
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
7  * ================================================================================
8  * Update Copyright (C) 2021 Samsung Electronics Intellectual Property. All rights reserved.
9  * =================================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *     http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END=========================================================
22  *
23  */
24 package org.onap.ccsdk.features.sdnr.wt.dataprovider.dblib.test;
25
26 import ch.vorburger.exec.ManagedProcessException;
27 import java.io.File;
28 import java.io.IOException;
29 import java.nio.file.Files;
30 import java.sql.SQLException;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.concurrent.TimeUnit;
38 import org.json.JSONArray;
39 import org.json.JSONException;
40 import org.json.JSONObject;
41 import org.junit.AfterClass;
42 import static org.junit.Assert.assertEquals;
43 import static org.junit.Assert.assertNotNull;
44 import static org.junit.Assert.assertTrue;
45 import static org.junit.Assert.fail;
46 import org.junit.BeforeClass;
47 import org.junit.Test;
48 import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.SqlDBClient;
49 import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data.SqlDBDataProvider;
50 import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.database.SqlDBReaderWriter;
51 import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.query.DeleteQuery;
52 import org.onap.ccsdk.features.sdnr.wt.dataprovider.dblib.test.util.MariaDBTestBase;
53 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMaintenance;
54 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager;
55 import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapper;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmNotificationType;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmSourceIndicator;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmlogBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CmlogEntity;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ConnectionLogStatus;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ConnectionlogBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ConnectionlogEntity;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerInputBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMediatorServerOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateNetworkElementConnectionOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMaintenanceInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMaintenanceInputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMediatorServerInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteMediatorServerInputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteNetworkElementConnectionInput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.DeleteNetworkElementConnectionInputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EntityInput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.EventlogEntity;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentEntity;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultlogEntity;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.MaintenanceEntity;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementConnectionBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementConnectionEntity;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementDeviceType;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.PmdataEntity;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadCmlogListOutputBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadConnectionlogListOutputBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadEventlogListOutputBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultcurrentListInputBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultcurrentListOutputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadFaultlogListOutputBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadGuiCutThroughEntryOutputBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadInventoryDeviceListOutputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadInventoryListOutputBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMaintenanceListOutputBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadMediatorServerListOutputBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadNetworkElementConnectionListOutputBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mDeviceListOutputBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mListOutputBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata15mLtpListOutputBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hDeviceListOutputBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hListOutputBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadPmdata24hLtpListOutputBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.ReadStatusOutputBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMaintenanceInput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMaintenanceInputBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMediatorServerInput;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateMediatorServerInputBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionInput;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionInputBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.Filter;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.FilterBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.FilterKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.entity.input.PaginationBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.network.element.connection.list.output.Data;
125 import org.opendaylight.yangtools.yang.common.Uint32;
126 import org.opendaylight.yangtools.yang.common.Uint64;
127
128 public class TestMariaDataProvider {
129
130
131     private static final String NODEID1 = "node1";
132     private static final String NODEID2 = "node2";
133     private static final String NODEID22 = "node22";
134     private static final String NODEID3 = "node3";
135     private static final String NODEID4 = "node4";
136     private static final String NODEID5 = "node5";
137     private static final String PROBLEM1 = "problem1";
138     private static final String TIME1 = "2021-05-25T05:12:55.0Z";
139     private static final String TIME2 = "2021-05-25T05:12:56.0Z";
140     private static final String TIME3 = "2021-05-25T05:12:57.0Z";
141     private static final String PROBLEM2 = "problem2";
142     private static final String URI1 = "http://localhost:8181";
143     private static final String URI2 = "http://localhost:8181";
144     private static final String URI3 = "http://localhost:8181";
145     private static final String PATH = "https://samsung.com/3GPP/simulation/network-function/ves";
146     private static final String USERNAME = "admin";
147     private static MariaDBTestBase testBase;
148     private static SqlDBDataProvider dbProvider;
149     private static SqlDBDataProvider dbProviderOverall;
150     private static SqlDBClient dbClient;
151     private static String CONTROLLERID;
152
153     @BeforeClass
154     public static void init() throws Exception {
155
156         testBase = new MariaDBTestBase();
157         dbProvider = testBase.getDbProvider();
158         dbProvider.waitForDatabaseReady(30, TimeUnit.SECONDS);
159         dbClient = testBase.createRawClient();
160         MariaDBTestBase.testCreateTableStructure(dbClient);
161         dbProvider.setControllerId();
162         CONTROLLERID = dbProvider.getControllerId();
163         dbProviderOverall = testBase.getOverallDbProvider();
164
165     }
166
167     @AfterClass
168     public static void close() {
169         try {
170             testBase.close();
171         } catch (ManagedProcessException e) {
172             e.printStackTrace();
173         }
174     }
175
176     @Test
177     public void testFaultcurrent() {
178         dbProvider.clearFaultsCurrentOfNode(NODEID1);
179         ReadFaultcurrentListOutputBuilder faultCurrents =
180                 dbProvider.readFaultCurrentList(createInput("node-id", NODEID1, 1, 20));
181         assertEquals(0, faultCurrents.getData().size());
182         FaultcurrentEntity faultCurrent1 = new FaultcurrentBuilder().setNodeId(NODEID1).setCounter(1).setObjectId("obj")
183                 .setProblem(PROBLEM1).setTimestamp(DateAndTime.getDefaultInstance(TIME1))
184                 .setSeverity(SeverityType.Major).setId(String.format("%s/%s", NODEID1, PROBLEM1)).build();
185         dbProvider.updateFaultCurrent(faultCurrent1);
186         FaultcurrentEntity faultCurrent2 = new FaultcurrentBuilder().setNodeId(NODEID1).setCounter(1).setObjectId("obj")
187                 .setProblem(PROBLEM2).setTimestamp(DateAndTime.getDefaultInstance(TIME1))
188                 .setSeverity(SeverityType.Minor).setId(String.format("%s/%s", NODEID1, PROBLEM2)).build();
189         dbProvider.updateFaultCurrent(faultCurrent2);
190         faultCurrents = dbProvider.readFaultCurrentList(createInput("node-id", NODEID1, 1, 20));
191         assertEquals(2, faultCurrents.getData().size());
192         ReadStatusOutputBuilder status = null;
193         try {
194             EntityInput input = null;
195             status = dbProvider.readStatus(input);
196         } catch (IOException e) {
197             e.printStackTrace();
198             fail("failed to read status");
199         }
200         assertEquals(0, status.getData().get(0).getFaults().getCriticals().intValue());
201         assertEquals(1, status.getData().get(0).getFaults().getMajors().intValue());
202         assertEquals(1, status.getData().get(0).getFaults().getMinors().intValue());
203         assertEquals(0, status.getData().get(0).getFaults().getWarnings().intValue());
204
205         List<String> nodeList = dbProvider.getAllNodesWithCurrentAlarms();
206         assertTrue(nodeList.contains(NODEID1));
207         assertEquals(1, nodeList.size());
208
209         faultCurrent1 = new FaultcurrentBuilder().setNodeId(NODEID1).setCounter(1).setObjectId("obj")
210                 .setProblem(PROBLEM1).setTimestamp(DateAndTime.getDefaultInstance(TIME1))
211                 .setSeverity(SeverityType.NonAlarmed).setId(String.format("%s/%s", NODEID1, PROBLEM1)).build();
212         dbProvider.updateFaultCurrent(faultCurrent1);
213         faultCurrents = dbProvider.readFaultCurrentList(createInput("node-id", NODEID1, 1, 20));
214         assertEquals(1, faultCurrents.getData().size());
215
216
217     }
218
219     @Test
220     public void testSerializeDeserialize() {
221
222         try {
223             CreateNetworkElementConnectionOutputBuilder necon = dbProvider.createNetworkElementConnection(
224                     new NetworkElementConnectionBuilder().setNodeId(NODEID1).setIsRequired(Boolean.TRUE).build());
225             List<Data> netestList =
226                     dbProvider.readNetworkElementConnectionList(createInput("node-id", NODEID1, 1, 20)).getData();
227
228             assertNotNull(necon);
229             assertEquals(1, netestList.size());
230             assertTrue(netestList.get(0).getIsRequired());
231             SqlDBReaderWriter<Data> dbrw = new SqlDBReaderWriter<>(dbClient, Entity.NetworkelementConnection,
232                     MariaDBTestBase.SUFFIX,
233                     Data.class,
234                     CONTROLLERID);
235             Data e = dbrw.read(NODEID1);
236             assertNotNull(e);
237
238         } catch (IOException e) {
239             e.printStackTrace();
240             fail(e.getMessage());
241         }
242     }
243
244     @Test
245     public void testFaultlog() {
246         try {
247             dbClient.delete(new DeleteQuery(Entity.Faultcurrent, null).toSql());
248         } catch (SQLException e) {
249             e.printStackTrace();
250             fail("problem clearing faultlog");
251         }
252         ReadFaultlogListOutputBuilder faultlogs = dbProvider.readFaultLogList(createInput(1, 20));
253         assertEquals(0, faultlogs.getData().size());
254         FaultlogEntity fault1 = new FaultlogBuilder().setCounter(1).setNodeId(NODEID1).setObjectId("obj")
255                 .setProblem(PROBLEM1).setSeverity(SeverityType.Major).setSourceType(SourceType.Netconf)
256                 .setTimestamp(DateAndTime.getDefaultInstance(TIME1)).build();
257         dbProvider.writeFaultLog(fault1);
258         FaultlogEntity fault2 = new FaultlogBuilder().setCounter(2).setNodeId(NODEID1).setObjectId("obj")
259                 .setProblem(PROBLEM2).setSeverity(SeverityType.Major).setSourceType(SourceType.Netconf)
260                 .setTimestamp(DateAndTime.getDefaultInstance(TIME1)).build();
261         dbProvider.writeFaultLog(fault2);
262         faultlogs = dbProvider.readFaultLogList(createInput("node-id", NODEID1, 1, 20));
263         assertEquals(2, faultlogs.getData().size());
264
265     }
266
267     @Test
268     public void testCMlog() {
269         ReadCmlogListOutputBuilder cmlogs = dbProvider.readCMLogList(createInput(1, 20));
270         assertEquals(0, cmlogs.getData().size());
271
272         CmlogEntity cm1 =
273                 new CmlogBuilder().setNodeId(NODEID2).setCounter(1).setTimestamp(DateAndTime.getDefaultInstance(TIME1))
274                         .setObjectId("obj").setNotificationType(CmNotificationType.NotifyMOIChanges)
275                         .setNotificationId("1").setSourceIndicator(CmSourceIndicator.MANAGEMENTOPERATION).setPath(PATH)
276                         .setValue("pnf-registration: true").build();
277         CmlogEntity cm2 =
278                 new CmlogBuilder().setNodeId(NODEID2).setCounter(2).setTimestamp(DateAndTime.getDefaultInstance(TIME2))
279                         .setObjectId("obj").setNotificationType(CmNotificationType.NotifyMOIChanges)
280                         .setNotificationId("2").setSourceIndicator(CmSourceIndicator.UNKNOWN).setPath(PATH)
281                         .setValue("pnf-registration: false").build();
282
283         dbProvider.writeCMLog(cm1);
284         dbProvider.writeCMLog(cm2);
285         cmlogs = dbProvider.readCMLogList(createInput("node-id", NODEID2, 1, 20));
286         assertEquals(2, cmlogs.getData().size());
287
288         List<CmlogEntity> cmLogEntityList = List.of(cm1, cm2);
289         assertEquals("node2", cmLogEntityList.get(0).getNodeId());
290         assertEquals("obj", cmLogEntityList.get(0).getObjectId());
291         assertEquals(CmNotificationType.NotifyMOIChanges, cmLogEntityList.get(0).getNotificationType());
292         assertEquals("2", cmLogEntityList.get(1).getNotificationId());
293
294     }
295
296     @Test
297     public void testConnectionlog() {
298         try {
299             dbClient.delete(new DeleteQuery(Entity.Connectionlog, null).toSql());
300         } catch (SQLException e) {
301             e.printStackTrace();
302             fail("problem clearing faultlog");
303         }
304         ReadConnectionlogListOutputBuilder logs = dbProvider.readConnectionlogList(createInput(1, 20));
305         assertEquals(0, logs.getData().size());
306         ConnectionlogEntity log1 = new ConnectionlogBuilder().setNodeId(NODEID1)
307                 .setTimestamp(DateAndTime.getDefaultInstance(TIME1)).setStatus(ConnectionLogStatus.Mounted).build();
308         dbProvider.writeConnectionLog(log1);
309         ConnectionlogEntity log2 = new ConnectionlogBuilder().setNodeId(NODEID1)
310                 .setTimestamp(DateAndTime.getDefaultInstance(TIME2)).setStatus(ConnectionLogStatus.Connecting).build();
311         dbProvider.writeConnectionLog(log2);
312         ConnectionlogEntity log3 = new ConnectionlogBuilder().setNodeId(NODEID1)
313                 .setTimestamp(DateAndTime.getDefaultInstance(TIME3)).setStatus(ConnectionLogStatus.Connected).build();
314         dbProvider.writeConnectionLog(log3);
315         logs = dbProvider.readConnectionlogList(createInput(1, 20));
316         assertEquals(3, logs.getData().size());
317     }
318
319     @Test
320     public void testEventlog() {
321         try {
322             dbClient.delete(new DeleteQuery(Entity.Eventlog, null).toSql());
323         } catch (SQLException e) {
324             e.printStackTrace();
325             fail("problem clearing faultlog");
326         }
327         ReadEventlogListOutputBuilder logs = null;
328         try {
329             logs = dbProvider.readEventlogList(createInput(1, 20));
330         } catch (IOException e) {
331             e.printStackTrace();
332             fail(e.getMessage());
333         }
334         assertEquals(0, logs.getData().size());
335         EventlogEntity log1 = new EventlogBuilder().setCounter(1).setNodeId(NODEID1).setObjectId("obj")
336                 .setTimestamp(DateAndTime.getDefaultInstance(TIME1)).setAttributeName("attr").setNewValue("new-value")
337                 .setSourceType(SourceType.Netconf).build();
338         dbProvider.writeEventLog(log1);
339         EventlogEntity log2 = new EventlogBuilder().setCounter(1).setNodeId(NODEID1).setObjectId("obj")
340                 .setTimestamp(DateAndTime.getDefaultInstance(TIME2)).setAttributeName("attr").setNewValue("new-value2")
341                 .setSourceType(SourceType.Netconf).build();
342         dbProvider.writeEventLog(log2);
343         EventlogEntity log3 = new EventlogBuilder().setCounter(1).setNodeId(NODEID1).setObjectId("obj")
344                 .setTimestamp(DateAndTime.getDefaultInstance(TIME3)).setAttributeName("attr").setNewValue("new-value3")
345                 .setSourceType(SourceType.Netconf).build();
346         dbProvider.writeEventLog(log3);
347         try {
348             logs = dbProvider.readEventlogList(createInput(1, 20));
349         } catch (IOException e) {
350             e.printStackTrace();
351             fail(e.getMessage());
352         }
353         assertEquals(3, logs.getData().size());
354     }
355
356     @Test
357     public void testGuicutthrough() {
358         try {
359             dbClient.delete(new DeleteQuery(Entity.Guicutthrough, null).toSql());
360         } catch (SQLException e) {
361             e.printStackTrace();
362             fail("problem clearing faultlog");
363         }
364         Guicutthrough gc1 = new GuicutthroughBuilder().setName(NODEID1).setWeburi(URI1).build();
365         dbProvider.writeGuiCutThroughData(gc1, NODEID1);
366         Guicutthrough gc2 = new GuicutthroughBuilder().setName(NODEID2).setWeburi(URI2).build();
367         dbProvider.writeGuiCutThroughData(gc2, NODEID2);
368         Guicutthrough gc3 = new GuicutthroughBuilder().setName(NODEID3).setWeburi(URI3).build();
369         dbProvider.writeGuiCutThroughData(gc3, NODEID3);
370         ReadGuiCutThroughEntryOutputBuilder data = dbProvider.readGuiCutThroughEntry(createInput(1, 20));
371         assertEquals(3, data.getData().size());
372         data = dbProvider.readGuiCutThroughEntry(createInput("name", NODEID1, 1, 20));
373         assertEquals(1, data.getData().size());
374
375     }
376
377     @Test
378     public void testInventory() {
379         try {
380             dbClient.delete(new DeleteQuery(Entity.Inventoryequipment, null).toSql());
381         } catch (SQLException e) {
382             e.printStackTrace();
383             fail("problem clearing faultlog");
384         }
385         ReadInventoryListOutputBuilder data = dbProvider.readInventoryList(createInput(1, 20));
386         assertEquals(0, data.getData().size());
387         List<Inventory> list = null;
388         try {
389             list = loadListFile("/inventory.json", Inventory.class);
390         } catch (IOException e) {
391             e.printStackTrace();
392             fail("problem loading inventory data");
393
394         }
395         dbProvider.writeInventory(NODEID1, list);
396         data = dbProvider.readInventoryList(createInput(1, 50));
397         assertEquals(22, data.getData().size());
398         ReadInventoryDeviceListOutputBuilder data2 = dbProvider.readInventoryDeviceList(createInput(1, 20));
399         assertEquals(2, data2.getData().size());
400         assertTrue(data2.getData().contains("sim1") && data2.getData().contains("sim2"));
401         data = dbProvider.readInventoryList(createInput("tree-level", "0", 1, 50));
402         assertEquals(5, data.getData().size());
403
404         try {
405             dbProvider.writeInventory("sim3", loadListFile("/inventory2.json", Inventory.class));
406         } catch (IOException e) {
407             fail("problem loading inventory data2");
408         }
409         data2 = dbProvider.readInventoryDeviceList(createInput(1, 20));
410         assertEquals(3, data2.getData().size());
411         assertTrue(data2.getData().contains("sim1") && data2.getData().contains("sim2") &&
412                 data2.getData().contains("sim3"));
413     }
414
415     @Test
416     public void testInventoryWithComplexTypes() {
417         try {
418             dbClient.delete(new DeleteQuery(Entity.Inventoryequipment, null).toSql());
419         } catch (SQLException e) {
420             e.printStackTrace();
421             fail("problem clearing inventoryequipment");
422         }
423         ReadInventoryListOutputBuilder data = dbProvider.readInventoryList(createInput(1, 20));
424         assertEquals(0, data.getData().size());
425         try {
426             Inventory inventory = new InventoryBuilder()
427                     .setContainedHolder(new HashSet<>(
428                             Arrays.asList("STM1-1", "Radio-2A", "LAN-3-SFP", "Radio-1A", "STM1-2", "LAN-4-SFP")))
429                     .setSerial("14209652001003620").setDescription("INDOOR UNIT ALCPlus2e")
430                     .setTreeLevel(Uint32.valueOf(0)).setNodeId("NTS_ONF14").build();
431             dbProvider.writeInventory(NODEID1, new ArrayList<Inventory>(Arrays.asList(inventory)));
432         } catch (Exception e) {
433             e.printStackTrace();
434             fail("problem loading inventory data");
435
436         }
437         data = dbProvider.readInventoryList(createInput(1, 50));
438         assertEquals(1, data.getData().size());
439     }
440
441     @Test
442     public void testMaintenance() {
443         try {
444             dbClient.delete(new DeleteQuery(Entity.Maintenancemode, null).toSql());
445         } catch (SQLException e) {
446             e.printStackTrace();
447             fail("problem clearing faultlog");
448         }
449         ReadMaintenanceListOutputBuilder data = dbProvider.readMaintenanceList(createInput(1, 20));
450         assertEquals(0, data.getData().size());
451         CreateMaintenanceInput maint1 = new CreateMaintenanceInputBuilder().setId(NODEID1).setNodeId(NODEID1)
452                 .setActive(true).setDescription("desc").setObjectIdRef("ref").setProblem("problem")
453                 .setStart(DateAndTime.getDefaultInstance(TIME1)).setEnd(DateAndTime.getDefaultInstance(TIME3)).build();
454         CreateMaintenanceInput maint2 = new CreateMaintenanceInputBuilder().setId(NODEID2).setNodeId(NODEID2)
455                 .setActive(true).setDescription("desc").setObjectIdRef("ref").setProblem("problem2")
456                 .setStart(DateAndTime.getDefaultInstance(TIME1)).setEnd(DateAndTime.getDefaultInstance(TIME3)).build();
457         CreateMaintenanceInput maint3 = new CreateMaintenanceInputBuilder().setId(NODEID3).setNodeId(NODEID3)
458                 .setActive(true).setDescription("desc").setObjectIdRef("ref").setProblem("problem3")
459                 .setStart(DateAndTime.getDefaultInstance(TIME1)).setEnd(DateAndTime.getDefaultInstance(TIME3)).build();
460         try {
461             dbProvider.createMaintenance(maint1);
462             dbProvider.createMaintenance(maint2);
463             dbProvider.createMaintenance(maint3);
464         } catch (IOException e) {
465             e.printStackTrace();
466             fail("unable to create maintenance data");
467         }
468         data = dbProvider.readMaintenanceList(createInput(1, 20));
469         assertEquals(3, data.getData().size());
470
471         UpdateMaintenanceInput update1 =
472                 new UpdateMaintenanceInputBuilder().setId(NODEID1).setNodeId(NODEID1).setActive(false).build();
473         try {
474             dbProvider.updateMaintenance(update1);
475         } catch (IOException e) {
476             e.printStackTrace();
477             fail("unable to update maintenance data");
478         }
479         data = dbProvider.readMaintenanceList(createInput("active", "false", 1, 20));
480         assertEquals(1, data.getData().size());
481         DeleteMaintenanceInput delete1 = new DeleteMaintenanceInputBuilder().setId(NODEID1).build();
482         try {
483             dbProvider.deleteMaintenance(delete1);
484         } catch (IOException e) {
485             e.printStackTrace();
486             fail("unable to delete maintenance data");
487         }
488         data = dbProvider.readMaintenanceList(createInput(1, 20));
489         assertEquals(2, data.getData().size());
490         try {
491             dbClient.delete(new DeleteQuery(Entity.Maintenancemode, null).toSql());
492         } catch (SQLException e) {
493             e.printStackTrace();
494             fail("problem clearing faultlog");
495         }
496         final String nodeId = "maint_node1";
497         HtDatabaseMaintenance maintenanceService = dbProvider.getHtDatabaseMaintenance();
498         MaintenanceEntity e = maintenanceService.createIfNotExists(nodeId);
499         assertNotNull(e);
500         assertEquals(nodeId, e.getNodeId());
501         MaintenanceEntity e2 = new CreateMaintenanceInputBuilder(e).setActive(true).build();
502         e = maintenanceService.setMaintenance(e2);
503         assertNotNull(e);
504         assertEquals(nodeId, e.getNodeId());
505         assertTrue(e.getActive());
506         maintenanceService.deleteIfNotRequired(nodeId);
507         data = dbProvider.readMaintenanceList(createInput("node-id", nodeId, 1, 20));
508         assertEquals(0, data.getData().size());
509
510     }
511
512     @Test
513     public void testMediatorserver() {
514         try {
515             dbClient.delete(new DeleteQuery(Entity.MediatorServer, null).toSql());
516         } catch (SQLException e) {
517             e.printStackTrace();
518             fail("problem clearing mediator server");
519         }
520         ReadMediatorServerListOutputBuilder data = dbProvider.readMediatorServerList(createInput(1, 20));
521         assertEquals(0, data.getData().size());
522         CreateMediatorServerInput mediator1 =
523                 new CreateMediatorServerInputBuilder().setName("server1").setUrl("http://10.20.30.40:7070").build();
524         CreateMediatorServerInput mediator2 =
525                 new CreateMediatorServerInputBuilder().setName("server2").setUrl("http://10.20.30.42:7070").build();
526         CreateMediatorServerInput mediator3 =
527                 new CreateMediatorServerInputBuilder().setName("server3").setUrl("http://10.20.30.43:7070").build();
528         CreateMediatorServerOutputBuilder output1 = null, output2 = null;
529         try {
530             output1 = dbProvider.createMediatorServer(mediator1);
531             output2 = dbProvider.createMediatorServer(mediator2);
532             dbProvider.createMediatorServer(mediator3);
533         } catch (IOException e) {
534             e.printStackTrace();
535             fail("problem creating mediator servers");
536         }
537         data = dbProvider.readMediatorServerList(createInput(1, 20));
538         assertEquals(3, data.getData().size());
539         UpdateMediatorServerInput update1 = new UpdateMediatorServerInputBuilder().setId(output1.getId())
540                 .setName("server1").setUrl("http://10.20.30.40:7071").build();
541         try {
542             dbProvider.updateMediatorServer(update1);
543         } catch (IOException e) {
544             e.printStackTrace();
545             fail("failed to update mediator server");
546         }
547         data = dbProvider.readMediatorServerList(createInput("id", output1.getId(), 1, 20));
548         assertEquals(1, data.getData().size());
549         assertEquals(output1.getId(), data.getData().get(0).getId());
550         assertEquals("server1", data.getData().get(0).getName());
551         assertEquals("http://10.20.30.40:7071", data.getData().get(0).getUrl());
552
553         DeleteMediatorServerInput delete2 = new DeleteMediatorServerInputBuilder().setId(output2.getId()).build();
554         try {
555             dbProvider.deleteMediatorServer(delete2);
556         } catch (IOException e) {
557             e.printStackTrace();
558             fail("unable to delete mediator server");
559         }
560         data = dbProvider.readMediatorServerList(createInput("id", output2.getId(), 1, 20));
561         assertEquals(0, data.getData().size());
562         data = dbProvider.readMediatorServerList(createInput(1, 20));
563         assertEquals(2, data.getData().size());
564     }
565
566     @Test
567     public void testNeConnection() {
568         try {
569             dbClient.delete(new DeleteQuery(Entity.NetworkelementConnection, null).toSql());
570         } catch (SQLException e) {
571             e.printStackTrace();
572             fail("problem clearing neconnection");
573         }
574         ReadNetworkElementConnectionListOutputBuilder data =
575                 dbProvider.readNetworkElementConnectionList(createInput(1, 20));
576         assertEquals(0, data.getData().size());
577         NetworkElementConnectionEntity ne1 = new NetworkElementConnectionBuilder().setNodeId(NODEID1)
578                 .setHost("10.20.30.50").setPort(Uint32.valueOf(8300)).setIsRequired(true).setUsername("user")
579                 .setPassword("passwd").build();
580         NetworkElementConnectionEntity ne2 = new NetworkElementConnectionBuilder().setNodeId(NODEID2)
581                 .setHost("10.20.30.55").setPort(Uint32.valueOf(8300)).setIsRequired(false).setUsername("user")
582                 .setPassword("passwd").setStatus(ConnectionLogStatus.Connecting).build();
583         NetworkElementConnectionEntity ne22 = new NetworkElementConnectionBuilder().setNodeId(NODEID22)
584                 .setHost("10.20.30.55").setPort(Uint32.valueOf(8300)).setIsRequired(false).setUsername("user")
585                 .setPassword("passwd").setStatus(ConnectionLogStatus.Connected).build();
586         NetworkElementConnectionEntity ne3 = new NetworkElementConnectionBuilder().setNodeId(NODEID3)
587                 .setHost("10.20.30.55").setPort(Uint32.valueOf(8300)).setIsRequired(false).setUsername("user")
588                 .setPassword("passwd").setStatus(ConnectionLogStatus.Connecting).build();
589         try {
590             dbProvider.createNetworkElementConnection(ne1);
591             dbProvider.createNetworkElementConnection(ne2);
592             dbProvider.createNetworkElementConnection(ne22);
593             dbProvider.updateNetworkConnection22(ne3, NODEID3);
594         } catch (IOException e) {
595             e.printStackTrace();
596             fail("problem creating neconnection");
597         }
598         data = dbProvider.readNetworkElementConnectionList(createInput(1, 20));
599         assertEquals(4, data.getData().size());
600         NetworkElementConnectionEntity update1 = new NetworkElementConnectionBuilder()
601                 .setStatus(ConnectionLogStatus.Connected).setDeviceType(NetworkElementDeviceType.ORAN).build();
602         dbProvider.updateNetworkConnectionDeviceType(update1, NODEID1);
603         data = dbProvider.readNetworkElementConnectionList(createInput("node-id", NODEID1, 1, 20));
604         assertEquals(1, data.getData().size());
605         assertEquals(NetworkElementDeviceType.ORAN, data.getData().get(0).getDeviceType());
606         assertEquals(true, data.getData().get(0).getIsRequired());
607         UpdateNetworkElementConnectionInput update2 = new UpdateNetworkElementConnectionInputBuilder().setId(NODEID2)
608                 .setHost("10.20.55.44").setIsRequired(true).build();
609         try {
610             dbProvider.updateNetworkElementConnection(update2);
611         } catch (IOException e) {
612             e.printStackTrace();
613             fail("failed to update neconnection");
614         }
615         data = dbProvider.readNetworkElementConnectionList(createInput("node-id", NODEID2, 1, 20));
616         assertEquals(1, data.getData().size());
617         assertEquals("10.20.55.44", data.getData().get(0).getHost());
618         assertEquals(true, data.getData().get(0).getIsRequired());
619
620         ReadStatusOutputBuilder status = null;
621         try {
622             EntityInput input = null;
623             status = dbProvider.readStatus(input);
624         } catch (IOException e) {
625             e.printStackTrace();
626             fail("failed to read status");
627         }
628         assertEquals(2, status.getData().get(0).getNetworkElementConnections().getConnected().intValue());
629         assertEquals(2, status.getData().get(0).getNetworkElementConnections().getConnecting().intValue());
630         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getDisconnected().intValue());
631         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getMounted().intValue());
632         assertEquals(4, status.getData().get(0).getNetworkElementConnections().getTotal().intValue());
633         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUnableToConnect().intValue());
634         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUndefined().intValue());
635         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUnmounted().intValue());
636
637         ReadStatusOutputBuilder status2 = null;
638         try {
639             EntityInput input = createInput("node-id", "node2*", 1, 20);
640             status = dbProvider.readStatus(input);
641             status2 = dbProviderOverall.readStatus(input);
642         } catch (IOException e) {
643             e.printStackTrace();
644             fail("failed to read status");
645         }
646         assertEquals(1, status.getData().get(0).getNetworkElementConnections().getConnected().intValue());
647         assertEquals(1, status.getData().get(0).getNetworkElementConnections().getConnecting().intValue());
648         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getDisconnected().intValue());
649         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getMounted().intValue());
650         assertEquals(2, status.getData().get(0).getNetworkElementConnections().getTotal().intValue());
651         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUnableToConnect().intValue());
652         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUndefined().intValue());
653         assertEquals(0, status.getData().get(0).getNetworkElementConnections().getUnmounted().intValue());
654
655         assertEquals(1, status2.getData().get(0).getNetworkElementConnections().getConnected().intValue());
656         assertEquals(1, status2.getData().get(0).getNetworkElementConnections().getConnecting().intValue());
657         assertEquals(0, status2.getData().get(0).getNetworkElementConnections().getDisconnected().intValue());
658         assertEquals(0, status2.getData().get(0).getNetworkElementConnections().getMounted().intValue());
659         assertEquals(2, status2.getData().get(0).getNetworkElementConnections().getTotal().intValue());
660         assertEquals(0, status2.getData().get(0).getNetworkElementConnections().getUnableToConnect().intValue());
661         assertEquals(0, status2.getData().get(0).getNetworkElementConnections().getUndefined().intValue());
662         assertEquals(0, status2.getData().get(0).getNetworkElementConnections().getUnmounted().intValue());
663
664         DeleteNetworkElementConnectionInput delete1 =
665                 new DeleteNetworkElementConnectionInputBuilder().setId(NODEID1).build();
666         try {
667             dbProvider.deleteNetworkElementConnection(delete1);
668         } catch (IOException e) {
669             e.printStackTrace();
670             fail("failed to delete neconnection");
671         }
672         data = dbProvider.readNetworkElementConnectionList(createInput("node-id", NODEID1, 1, 20));
673         assertEquals(0, data.getData().size());
674         data = dbProvider.readNetworkElementConnectionList(createInput(1, 20));
675         assertEquals(3, data.getData().size());
676
677     }
678
679     @Test
680     public void testUserdata() {
681         HtUserdataManager mgr = dbProvider.getUserManager();
682         String userdata = mgr.getUserdata(USERNAME);
683         assertEquals("{}", userdata);
684         JSONObject o = new JSONObject();
685         o.put("key1", false);
686         o.put("key2", "value2");
687         boolean result = mgr.setUserdata(USERNAME, o.toString());
688         assertTrue(result);
689         userdata = mgr.getUserdata(USERNAME);
690         o = new JSONObject(userdata);
691         assertEquals(false, o.getBoolean("key1"));
692         assertEquals("value2", o.getString("key2"));
693         o = new JSONObject();
694         o.put("enabled", true);
695         o.put("name", "abcdef");
696         result = mgr.setUserdata(USERNAME, "app1", o.toString());
697         assertTrue(result);
698         userdata = mgr.getUserdata(USERNAME);
699         o = new JSONObject(userdata);
700         assertEquals(false, o.getBoolean("key1"));
701         assertEquals("value2", o.getString("key2"));
702         JSONObject app = o.getJSONObject("app1");
703         assertNotNull(app);
704         assertEquals(true, app.getBoolean("enabled"));
705         assertEquals("abcdef", app.getString("name"));
706
707     }
708
709     @Test
710     public void testpm15m() {
711         try {
712             dbClient.delete(new DeleteQuery(Entity.Historicalperformance15min, null).toSql());
713         } catch (SQLException e) {
714             e.printStackTrace();
715             fail("problem clearing pmdata15m");
716         }
717         ReadPmdata15mListOutputBuilder data = dbProvider.readPmdata15mList(createInput(1, 20));
718         assertEquals(0, data.getData().size());
719         List<PmdataEntity> list = null;
720         try {
721             list = loadListFile("/pmdata15m.json", PmdataEntity.class);
722         } catch (JSONException | IOException e) {
723             e.printStackTrace();
724             fail("failed to load pmdata15m");
725         }
726         dbProvider.doWritePerformanceData(list);
727         data = dbProvider.readPmdata15mList(createInput(1, 20));
728         assertEquals(10, data.getData().size());
729         ReadPmdata15mLtpListOutputBuilder ltpdata = null;
730         try {
731             ltpdata = dbProvider.readPmdata15mLtpList(createInput("node-name", "sim12600", 1, 20));
732         } catch (IOException e) {
733             e.printStackTrace();
734             fail("failed to read pmdata15m ltp list");
735         }
736         assertEquals(3, ltpdata.getData().size());
737         ReadPmdata15mDeviceListOutputBuilder devicedata = null;
738         try {
739             devicedata = dbProvider.readPmdata15mDeviceList(createInput(1, 20));
740         } catch (IOException e) {
741             e.printStackTrace();
742             fail("failed to read pmdata15m devices list");
743         }
744         assertEquals(1, devicedata.getData().size());
745     }
746
747     @Test
748     public void testpm24h() {
749         try {
750             dbClient.delete(new DeleteQuery(Entity.Historicalperformance24h, null).toSql());
751         } catch (SQLException e) {
752             e.printStackTrace();
753             fail("problem clearing pmdata24h");
754         }
755         ReadPmdata24hListOutputBuilder data = dbProvider.readPmdata24hList(createInput(1, 20));
756         assertEquals(0, data.getData().size());
757         List<PmdataEntity> list = null;
758         try {
759             list = loadListFile("/pmdata24h.json", PmdataEntity.class);
760         } catch (JSONException | IOException e) {
761             e.printStackTrace();
762             fail("failed to load pmdata24h");
763         }
764         dbProvider.doWritePerformanceData(list);
765         data = dbProvider.readPmdata24hList(createInput(1, 20));
766         assertEquals(1, data.getData().size());
767         ReadPmdata24hLtpListOutputBuilder ltpdata = null;
768         try {
769             ltpdata = dbProvider.readPmdata24hLtpList(createInput("node-name", "test", 1, 20));
770         } catch (IOException e) {
771             e.printStackTrace();
772             fail("failed to read pmdata15m ltp list");
773         }
774         assertEquals(1, ltpdata.getData().size());
775         ReadPmdata24hDeviceListOutputBuilder devicedata = null;
776         try {
777             devicedata = dbProvider.readPmdata24hDeviceList(createInput(1, 20));
778         } catch (IOException e) {
779             e.printStackTrace();
780             fail("failed to read pmdata15m devices list");
781         }
782         assertEquals(1, devicedata.getData().size());
783     }
784
785     static EntityInput createInput(int page, int size) {
786         return createInput(null, null, page, size);
787     }
788
789     private static <T> List<T> loadListFile(String filename, Class<T> clazz) throws JSONException, IOException {
790         List<T> list = new ArrayList<>();
791         JSONArray a = new JSONArray(loadFile(filename));
792         for (int i = 0; i < a.length(); i++) {
793             list.add(loadData(a.getJSONObject(i).toString(), clazz));
794         }
795         return list;
796     }
797
798     private static <T> T loadData(String content, Class<T> clazz) throws IOException {
799         YangToolsMapper mapper = new YangToolsMapper();
800         return mapper.readValue(content, clazz);
801     }
802
803     private static String loadFile(String filename) throws IOException {
804         return String.join("\n",
805                 Files.readAllLines(new File(TestMariaDataProvider.class.getResource(filename).getFile()).toPath()));
806
807     }
808
809     static EntityInput createInput(String filter, String filterValue, int page, int size) {
810         ReadFaultcurrentListInputBuilder builder = new ReadFaultcurrentListInputBuilder().setPagination(
811                 new PaginationBuilder().setPage(Uint64.valueOf(page)).setSize(Uint32.valueOf(size)).build());
812         if (filter != null && filterValue != null) {
813             Filter f = new FilterBuilder().setProperty(filter).setFiltervalue(filterValue).build();
814             Map<FilterKey, Filter> fmap = new HashMap<>();
815             fmap.put(f.key(), f);
816             builder.setFilter(fmap);
817         }
818         return builder.build();
819     }
820
821 }