Bump odlparent to 5.0.0
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / FrontendMetadata.java
1 /*
2  * Copyright (c) 2016 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 package org.opendaylight.controller.cluster.datastore;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.Collections2;
12 import com.google.common.collect.Maps;
13 import java.util.HashMap;
14 import java.util.Map;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
17 import org.opendaylight.controller.cluster.access.concepts.FrontendIdentifier;
18 import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
19 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
20 import org.opendaylight.controller.cluster.datastore.persisted.FrontendClientMetadata;
21 import org.opendaylight.controller.cluster.datastore.persisted.FrontendShardDataTreeSnapshotMetadata;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * Frontend state as observed by a shard follower. This class is responsible for maintaining metadata state
27  * so that this can be used to seed {@link LeaderFrontendState} with proper state so that the frontend/backend
28  * conversation can continue where it left off. This class is NOT thread-safe.
29  *
30  * @author Robert Varga
31  */
32 final class FrontendMetadata extends ShardDataTreeMetadata<FrontendShardDataTreeSnapshotMetadata> {
33     private static final Logger LOG = LoggerFactory.getLogger(FrontendMetadata.class);
34
35     private final Map<FrontendIdentifier, FrontendClientMetadataBuilder> clients = new HashMap<>();
36     private final String shardName;
37
38     FrontendMetadata(final String shardName) {
39         this.shardName = Preconditions.checkNotNull(shardName);
40     }
41
42     @Override
43     Class<FrontendShardDataTreeSnapshotMetadata> getSupportedType() {
44         return FrontendShardDataTreeSnapshotMetadata.class;
45     }
46
47     @Override
48     void reset() {
49         LOG.debug("{}: clearing clients {}", shardName, clients);
50         clients.clear();
51     }
52
53     @Override
54     void doApplySnapshot(final FrontendShardDataTreeSnapshotMetadata snapshot) {
55         LOG.debug("{}: applying snapshot {} over clients {}", shardName, snapshot, clients);
56         clients.clear();
57
58         for (FrontendClientMetadata m : snapshot.getClients()) {
59             LOG.debug("{}: applying metadata {}", shardName, m);
60             final FrontendClientMetadataBuilder b = new FrontendClientMetadataBuilder(shardName, m);
61             final FrontendIdentifier client = m.getIdentifier().getFrontendId();
62
63             LOG.debug("{}: client {} updated to {}", shardName, client, b);
64             clients.put(client, b);
65         }
66     }
67
68     @Override
69     FrontendShardDataTreeSnapshotMetadata toSnapshot() {
70         return new FrontendShardDataTreeSnapshotMetadata(Collections2.transform(clients.values(),
71             FrontendClientMetadataBuilder::build));
72     }
73
74     private FrontendClientMetadataBuilder ensureClient(final ClientIdentifier id) {
75         final FrontendClientMetadataBuilder existing = clients.get(id.getFrontendId());
76         if (existing != null && id.equals(existing.getIdentifier())) {
77             return existing;
78         }
79
80         final FrontendClientMetadataBuilder client = new FrontendClientMetadataBuilder(shardName, id);
81         final FrontendClientMetadataBuilder previous = clients.put(id.getFrontendId(), client);
82         if (previous != null) {
83             LOG.debug("{}: Replaced client {} with {}", shardName, previous, client);
84         } else {
85             LOG.debug("{}: Added client {}", shardName, client);
86         }
87         return client;
88     }
89
90     @Override
91     void onHistoryCreated(final LocalHistoryIdentifier historyId) {
92         ensureClient(historyId.getClientId()).onHistoryCreated(historyId);
93     }
94
95     @Override
96     void onHistoryClosed(final LocalHistoryIdentifier historyId) {
97         ensureClient(historyId.getClientId()).onHistoryClosed(historyId);
98     }
99
100     @Override
101     void onHistoryPurged(final LocalHistoryIdentifier historyId) {
102         ensureClient(historyId.getClientId()).onHistoryPurged(historyId);
103     }
104
105     @Override
106     void onTransactionAborted(final TransactionIdentifier txId) {
107         ensureClient(txId.getHistoryId().getClientId()).onTransactionAborted(txId);
108     }
109
110     @Override
111     void onTransactionCommitted(final TransactionIdentifier txId) {
112         ensureClient(txId.getHistoryId().getClientId()).onTransactionCommitted(txId);
113     }
114
115     @Override
116     void onTransactionPurged(final TransactionIdentifier txId) {
117         ensureClient(txId.getHistoryId().getClientId()).onTransactionPurged(txId);
118     }
119
120     /**
121      * Transform frontend metadata into an active leader state map.
122      *
123      * @return Leader frontend state
124      */
125     @NonNull Map<FrontendIdentifier, LeaderFrontendState> toLeaderState(final @NonNull Shard shard) {
126         return new HashMap<>(Maps.transformValues(clients, meta -> meta.toLeaderState(shard)));
127     }
128 }