Adjust to RPC method signature update
[netconf.git] / netconf / sal-netconf-connector / src / main / java / org / opendaylight / netconf / sal / connect / util / NetconfSalKeystoreService.java
1 /*
2  * Copyright (c) 2017 Cisco Systems, Inc. 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
9 package org.opendaylight.netconf.sal.connect.util;
10
11 import com.google.common.util.concurrent.CheckedFuture;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import com.google.common.util.concurrent.SettableFuture;
17 import java.util.List;
18 import java.util.stream.Collectors;
19 import javax.annotation.Nullable;
20 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryOutputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyOutput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyOutputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateOutputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.KeystoreBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.NetconfKeystoreService;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryOutputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateOutputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKeyKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateKey;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54 import org.opendaylight.yangtools.yang.common.RpcResult;
55 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59 public class NetconfSalKeystoreService implements NetconfKeystoreService {
60
61     private static final Logger LOG = LoggerFactory.getLogger(NetconfSalKeystoreService.class);
62
63     private final DataBroker dataBroker;
64     private final AAAEncryptionService encryptionService;
65
66     private final InstanceIdentifier<Keystore> keystoreIid = InstanceIdentifier.create(Keystore.class);
67
68     public NetconfSalKeystoreService(final DataBroker dataBroker,
69                                      final AAAEncryptionService encryptionService) {
70         LOG.info("Starting NETCONF keystore service.");
71
72         this.dataBroker = dataBroker;
73         this.encryptionService = encryptionService;
74
75         initKeystore();
76     }
77
78     private void initKeystore() {
79         final Keystore keystore = new KeystoreBuilder().build();
80
81         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
82         writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, keystoreIid, keystore);
83
84         final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
85
86         try {
87             submit.checkedGet();
88             LOG.debug("init keystore done");
89         } catch (TransactionCommitFailedException exception) {
90             LOG.error("Unable to initialize Netconf key-pair store.", exception);
91         }
92     }
93
94     @Override
95     public ListenableFuture<RpcResult<RemoveKeystoreEntryOutput>> removeKeystoreEntry(
96             final RemoveKeystoreEntryInput input) {
97         LOG.debug("Removing keypairs: {}", input);
98
99         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
100         final List<String> ids = input.getKeyId();
101
102         for (final String id : ids) {
103             writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
104                     keystoreIid.child(KeyCredential.class, new KeyCredentialKey(id)));
105         }
106
107         final SettableFuture<RpcResult<RemoveKeystoreEntryOutput>> rpcResult = SettableFuture.create();
108
109         final ListenableFuture<Void> submit = writeTransaction.submit();
110         Futures.addCallback(submit, new FutureCallback<Void>() {
111             @Override
112             public void onSuccess(@Nullable final Void result) {
113                 LOG.debug("remove-key-pair success. Input: {}");
114                 rpcResult.set(RpcResultBuilder.success(new RemoveKeystoreEntryOutputBuilder().build()).build());
115             }
116
117             @Override
118             public void onFailure(final Throwable throwable) {
119                 LOG.warn("remove-key-pair failed. Input: {}", input, throwable);
120                 rpcResult.setException(throwable);
121             }
122         }, MoreExecutors.directExecutor());
123
124         return rpcResult;
125     }
126
127     @Override
128     public ListenableFuture<RpcResult<AddKeystoreEntryOutput>> addKeystoreEntry(final AddKeystoreEntryInput input) {
129         LOG.debug("Adding keypairs: {}", input);
130
131         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
132         final List<KeyCredential> keypairs = input.getKeyCredential().stream().map(keypair ->
133                 new KeyCredentialBuilder(keypair)
134                         .setPrivateKey(encryptionService.encrypt(keypair.getPrivateKey()))
135                         .setPassphrase(encryptionService.encrypt(keypair.getPassphrase()))
136                         .build()).collect(Collectors.toList());
137
138         for (KeyCredential keypair : keypairs) {
139             writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
140                     keystoreIid.child(KeyCredential.class, keypair.getKey()), keypair);
141         }
142
143         final SettableFuture<RpcResult<AddKeystoreEntryOutput>> rpcResult = SettableFuture.create();
144
145         final ListenableFuture<Void> submit = writeTransaction.submit();
146         Futures.addCallback(submit, new FutureCallback<Void>() {
147             @Override
148             public void onSuccess(@Nullable final Void result) {
149                 LOG.debug("add-key-pair success. Input: {}");
150                 rpcResult.set(RpcResultBuilder.success(new AddKeystoreEntryOutputBuilder().build()).build());
151             }
152
153             @Override
154             public void onFailure(final Throwable throwable) {
155                 LOG.warn("add-key-pair failed. Input: {}", input, throwable);
156                 rpcResult.setException(throwable);
157             }
158         }, MoreExecutors.directExecutor());
159
160         return rpcResult;
161     }
162
163     @Override
164     public ListenableFuture<RpcResult<AddTrustedCertificateOutput>> addTrustedCertificate(
165             final AddTrustedCertificateInput input) {
166         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
167
168         for (TrustedCertificate certificate : input.getTrustedCertificate()) {
169             writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
170                     keystoreIid.child(TrustedCertificate.class, certificate.getKey()), certificate);
171         }
172
173         final SettableFuture<RpcResult<AddTrustedCertificateOutput>> rpcResult = SettableFuture.create();
174
175         final ListenableFuture<Void> submit = writeTransaction.submit();
176         Futures.addCallback(submit, new FutureCallback<Void>() {
177             @Override
178             public void onSuccess(@Nullable final Void result) {
179                 LOG.debug("add-trusted-certificate success. Input: {}", input);
180                 rpcResult.set(RpcResultBuilder.success(new AddTrustedCertificateOutputBuilder().build()).build());
181             }
182
183             @Override
184             public void onFailure(final Throwable throwable) {
185                 LOG.warn("add-trusted-certificate failed. Input: {}", input, throwable);
186                 rpcResult.setException(throwable);
187             }
188         }, MoreExecutors.directExecutor());
189
190         return rpcResult;
191     }
192
193     @Override
194     public ListenableFuture<RpcResult<RemoveTrustedCertificateOutput>> removeTrustedCertificate(
195             final RemoveTrustedCertificateInput input) {
196         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
197         final List<String> names = input.getName();
198
199         for (final String name : names) {
200             writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
201                     keystoreIid.child(TrustedCertificate.class, new TrustedCertificateKey(name)));
202         }
203
204         final SettableFuture<RpcResult<RemoveTrustedCertificateOutput>> rpcResult = SettableFuture.create();
205
206         final ListenableFuture<Void> submit = writeTransaction.submit();
207         Futures.addCallback(submit, new FutureCallback<Void>() {
208             @Override
209             public void onSuccess(@Nullable final Void result) {
210                 LOG.debug("remove-trusted-certificate success. Input: {}", input);
211                 rpcResult.set(RpcResultBuilder.success(new RemoveTrustedCertificateOutputBuilder().build()).build());
212             }
213
214             @Override
215             public void onFailure(final Throwable throwable) {
216                 LOG.warn("remove-trusted-certificate failed. Input: {}", input, throwable);
217                 rpcResult.setException(throwable);
218             }
219         }, MoreExecutors.directExecutor());
220
221         return rpcResult;
222     }
223
224     @Override
225     public ListenableFuture<RpcResult<AddPrivateKeyOutput>> addPrivateKey(final AddPrivateKeyInput input) {
226         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
227
228         for (PrivateKey key: input.getPrivateKey()) {
229             writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
230                     keystoreIid.child(PrivateKey.class, key.getKey()), key);
231         }
232
233         final SettableFuture<RpcResult<AddPrivateKeyOutput>> rpcResult = SettableFuture.create();
234
235         final ListenableFuture<Void> submit = writeTransaction.submit();
236         Futures.addCallback(submit, new FutureCallback<Void>() {
237             @Override
238             public void onSuccess(@Nullable final Void result) {
239                 LOG.debug("add-private-key success. Input: {}", input);
240                 rpcResult.set(RpcResultBuilder.success(new AddPrivateKeyOutputBuilder().build()).build());
241             }
242
243             @Override
244             public void onFailure(final Throwable throwable) {
245                 LOG.warn("add-private-key failed. Input: {}", input, throwable);
246                 rpcResult.setException(throwable);
247             }
248         }, MoreExecutors.directExecutor());
249
250         return rpcResult;
251     }
252
253     @Override
254     public ListenableFuture<RpcResult<RemovePrivateKeyOutput>> removePrivateKey(final RemovePrivateKeyInput input) {
255         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
256         final List<String> names = input.getName();
257
258         for (final String name : names) {
259             writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
260                     keystoreIid.child(PrivateKey.class, new PrivateKeyKey(name)));
261         }
262
263         final SettableFuture<RpcResult<RemovePrivateKeyOutput>> rpcResult = SettableFuture.create();
264
265         final ListenableFuture<Void> submit = writeTransaction.submit();
266         Futures.addCallback(submit, new FutureCallback<Void>() {
267             @Override
268             public void onSuccess(@Nullable final Void result) {
269                 LOG.debug("remove-private-key success. Input: {}", input);
270                 rpcResult.set(RpcResultBuilder.success(new RemovePrivateKeyOutputBuilder().build()).build());
271             }
272
273             @Override
274             public void onFailure(final Throwable throwable) {
275                 LOG.warn("remove-private-key failed. Input: {}", input, throwable);
276                 rpcResult.setException(throwable);
277             }
278         }, MoreExecutors.directExecutor());
279
280         return rpcResult;
281     }
282 }