Convert mdsal-binding-dom-codec to a JPMS module
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / test / java / org / opendaylight / mdsal / binding / dom / adapter / query / QueryPerformanceTest.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.dom.adapter.query;
9
10 import static org.hamcrest.CoreMatchers.instanceOf;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14
15 import com.google.common.base.Stopwatch;
16 import com.google.common.util.concurrent.FluentFuture;
17 import java.util.Optional;
18 import java.util.ServiceLoader;
19 import java.util.concurrent.ExecutionException;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.junit.AfterClass;
22 import org.junit.BeforeClass;
23 import org.junit.Test;
24 import org.opendaylight.mdsal.binding.api.DataBroker;
25 import org.opendaylight.mdsal.binding.api.QueryReadTransaction;
26 import org.opendaylight.mdsal.binding.api.ReadTransaction;
27 import org.opendaylight.mdsal.binding.api.WriteTransaction;
28 import org.opendaylight.mdsal.binding.api.query.QueryExpression;
29 import org.opendaylight.mdsal.binding.api.query.QueryFactory;
30 import org.opendaylight.mdsal.binding.api.query.QueryResult;
31 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractDataBrokerTest;
32 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
33 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
34 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
35 import org.opendaylight.yang.gen.v1.mdsal.query.norev.Foo;
36 import org.opendaylight.yang.gen.v1.mdsal.query.norev.FooBuilder;
37 import org.opendaylight.yang.gen.v1.mdsal.query.norev.first.grp.System;
38 import org.opendaylight.yang.gen.v1.mdsal.query.norev.first.grp.SystemBuilder;
39 import org.opendaylight.yang.gen.v1.mdsal.query.norev.first.grp.SystemKey;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class QueryPerformanceTest extends AbstractDataBrokerTest {
46     private static final Logger LOG = LoggerFactory.getLogger(QueryPerformanceTest.class);
47     private static final int SYSTEM_COUNT = 1_000_000;
48     private static Foo FOO;
49
50     private QueryFactory factory;
51
52     @BeforeClass
53     public static void beforeClass() {
54         final Stopwatch sw = Stopwatch.createStarted();
55         final BindingMap.Builder<SystemKey, System> builder = BindingMap.builder(SYSTEM_COUNT);
56
57         for (int i = 0; i < SYSTEM_COUNT; ++i) {
58             builder.add(new SystemBuilder().setName("name" + i).setAlias("alias" + i).build());
59         }
60
61         FOO = new FooBuilder().setSystem(builder.build()).build();
62         LOG.info("Test data with {} items built in {}", SYSTEM_COUNT, sw);
63     }
64
65     @AfterClass
66     public static void afterClass() {
67         FOO = null;
68     }
69
70     @Override
71     protected void setupWithRuntimeContext(final BindingRuntimeContext runtimeContext) {
72         super.setupWithRuntimeContext(runtimeContext);
73         factory = new DefaultQueryFactory(ServiceLoader.load(BindingCodecTreeFactory.class).findFirst().orElseThrow()
74             .create(runtimeContext));
75     }
76
77     @Override
78     protected void setupWithDataBroker(final DataBroker dataBroker) {
79         final Stopwatch sw = Stopwatch.createStarted();
80         WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
81         wtx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Foo.class), FOO);
82         assertCommit(wtx.commit());
83         LOG.info("Test data with {} items populated in {}", SYSTEM_COUNT, sw);
84     }
85
86     @Test
87     public void queryLessThanAlarm() throws InterruptedException, ExecutionException {
88         final String needle = "alias" + (SYSTEM_COUNT - 1);
89
90         final Stopwatch sw = Stopwatch.createStarted();
91         final QueryExpression<System> query = factory.querySubtree(InstanceIdentifier.create(Foo.class))
92             .extractChild(System.class)
93                 .matching()
94                     .leaf(System::getAlias).valueEquals(needle)
95                 .build();
96         LOG.info("Query built in {}", sw);
97
98         sw.reset().start();
99         final FluentFuture<QueryResult<@NonNull System>> future;
100         try (ReadTransaction rtx = getDataBroker().newReadOnlyTransaction()) {
101             assertThat(rtx, instanceOf(QueryReadTransaction.class));
102             future = ((QueryReadTransaction) rtx).execute(LogicalDatastoreType.CONFIGURATION, query);
103         }
104
105         final QueryResult<@NonNull System> result = future.get();
106         LOG.info("Query executed {} in {}", future, sw);
107
108         assertTrue(result.stream().findAny().isPresent());
109         LOG.info("Query result in {}", sw);
110     }
111
112     @Test
113     public void searchLessThanAlarm() throws InterruptedException, ExecutionException {
114         final String needle = "alias" + (SYSTEM_COUNT - 1);
115
116         final Stopwatch sw = Stopwatch.createStarted();
117         final FluentFuture<Optional<Foo>> future;
118         try (ReadTransaction rtx = getDataBroker().newReadOnlyTransaction()) {
119             future = rtx.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Foo.class));
120         }
121
122         final Foo haystack = future.get().orElseThrow();
123         LOG.info("Read executed in {}", sw);
124
125         Object result = null;
126         for (System system : haystack.nonnullSystem().values()) {
127             if (needle.equals(system.getAlias())) {
128                 result = system;
129                 break;
130             }
131         }
132
133         LOG.info("Search found {} in {}", result, sw);
134         assertNotNull(result);
135     }
136 }