Expose NetconfKeystoreService
[netconf.git] / keystore / keystore-legacy / src / main / java / org / opendaylight / netconf / keystore / legacy / impl / ConfigListener.java
1 /*
2  * Copyright (c) 2024 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.netconf.keystore.legacy.impl;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.Stopwatch;
13 import java.util.List;
14 import org.eclipse.jdt.annotation.NonNullByDefault;
15 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
16 import org.opendaylight.mdsal.binding.api.DataTreeModification;
17 import org.opendaylight.netconf.keystore.legacy.impl.DefaultNetconfKeystoreService.ConfigStateBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKey;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 @NonNullByDefault
25 record ConfigListener(DefaultNetconfKeystoreService keystore) implements DataTreeChangeListener<Keystore> {
26     private static final Logger LOG = LoggerFactory.getLogger(ConfigListener.class);
27
28     ConfigListener {
29         requireNonNull(keystore);
30     }
31
32     @Override
33     public void onInitialData() {
34         keystore.runUpdate(builder -> {
35             builder.privateKeys().clear();
36             builder.trustedCertificates().clear();
37         });
38     }
39
40     @Override
41     public void onDataTreeChanged(final List<DataTreeModification<Keystore>> changes) {
42         LOG.debug("Starting update with {} changes", changes.size());
43         final var sw = Stopwatch.createStarted();
44         keystore.runUpdate(builder -> onDataTreeChanged(builder, changes));
45         LOG.debug("Update finished in {}", sw);
46     }
47
48     private static void onDataTreeChanged(final ConfigStateBuilder builder,
49             final List<DataTreeModification<Keystore>> changes) {
50         for (var change : changes) {
51             LOG.debug("Processing change {}", change);
52             final var rootNode = change.getRootNode();
53
54             for (var mod : rootNode.getModifiedChildren(PrivateKey.class)) {
55                 switch (mod.modificationType()) {
56                     case SUBTREE_MODIFIED, WRITE -> {
57                         final var privateKey = mod.dataAfter();
58                         builder.privateKeys().put(privateKey.requireName(), privateKey);
59                     }
60                     case DELETE -> builder.privateKeys().remove(mod.dataBefore().requireName());
61                     default -> {
62                         // no-op
63                     }
64                 }
65             }
66             for (var mod : rootNode.getModifiedChildren(TrustedCertificate.class)) {
67                 switch (mod.modificationType()) {
68                     case SUBTREE_MODIFIED, WRITE -> {
69                         final var trustedCertificate = mod.dataAfter();
70                         builder.trustedCertificates().put(trustedCertificate.requireName(), trustedCertificate);
71                     }
72                     case DELETE -> builder.trustedCertificates().remove(mod.dataBefore().requireName());
73                     default -> {
74                         // no-op
75                     }
76                 }
77             }
78         }
79     }
80 }