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