1 package com.atlassian.asap.core.keys.publickey;
2
3 import com.atlassian.asap.api.exception.CannotRetrieveKeyException;
4 import com.atlassian.asap.core.exception.PublicKeyNotFoundException;
5 import com.atlassian.asap.core.keys.KeyProvider;
6 import com.atlassian.asap.core.validator.ValidatedKeyId;
7 import com.google.common.annotations.VisibleForTesting;
8 import com.google.common.collect.ImmutableList;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 import java.security.PublicKey;
13 import java.util.Iterator;
14 import java.util.List;
15
16
17
18
19
20
21 public class MirroredKeyProvider implements KeyProvider<PublicKey> {
22 private static final Logger logger = LoggerFactory.getLogger(MirroredKeyProvider.class);
23
24 private final List<KeyProvider<PublicKey>> mirrors;
25
26 @VisibleForTesting
27 MirroredKeyProvider(List<KeyProvider<PublicKey>> mirrors) {
28 this.mirrors = ImmutableList.copyOf(mirrors);
29 }
30
31
32
33
34
35
36
37
38
39
40 public static KeyProvider<PublicKey> createMirroredKeyProvider(List<KeyProvider<PublicKey>> mirrors) {
41
42
43 if (mirrors.size() == 1) {
44 return mirrors.get(0);
45 } else {
46 return new MirroredKeyProvider(mirrors);
47 }
48 }
49
50 @Override
51 public PublicKey getKey(ValidatedKeyId validatedKeyId) throws CannotRetrieveKeyException {
52 for (Iterator<KeyProvider<PublicKey>> keyProviderIterator = mirrors.iterator(); keyProviderIterator.hasNext(); ) {
53 try {
54 return keyProviderIterator.next().getKey(validatedKeyId);
55 } catch (PublicKeyNotFoundException ex) {
56
57
58 throw ex;
59 } catch (CannotRetrieveKeyException ex) {
60 if (keyProviderIterator.hasNext()) {
61 logger.debug("Error communicating with a key provider, going to try next mirror", ex);
62 } else {
63 logger.error("Error communicating with all key providers: {}", mirrors, ex);
64 throw new CannotRetrieveKeyException("Error communicating with all key providers", ex);
65 }
66 }
67
68 }
69 throw new CannotRetrieveKeyException("There are no mirrors available");
70 }
71
72 public List<KeyProvider<PublicKey>> getMirrors() {
73 return mirrors;
74 }
75
76 @Override
77 public String toString() {
78 return this.getClass().getSimpleName() + "{" + mirrors + '}';
79 }
80 }