Bug 7521: Convert DatastoreSnapshot.ShardSnapshot to store Snapshot
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / persisted / DatastoreSnapshot.java
1 /*
2  * Copyright (c) 2015 Brocade Communications 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.persisted;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ImmutableList;
12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
13 import java.io.Externalizable;
14 import java.io.IOException;
15 import java.io.ObjectInput;
16 import java.io.ObjectOutput;
17 import java.io.Serializable;
18 import java.util.ArrayList;
19 import java.util.List;
20 import javax.annotation.Nonnull;
21 import javax.annotation.Nullable;
22 import org.opendaylight.controller.cluster.raft.persisted.Snapshot;
23
24 /**
25  * Stores a snapshot of the internal state of a data store.
26  *
27  * @author Thomas Pantelis
28  */
29 public class DatastoreSnapshot implements Serializable {
30     private static final long serialVersionUID = 1L;
31
32     private static final class Proxy implements Externalizable {
33         private static final long serialVersionUID = 1L;
34
35         private DatastoreSnapshot datastoreSnapshot;
36
37         // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
38         // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
39         @SuppressWarnings("checkstyle:RedundantModifier")
40         public Proxy() {
41             // For Externalizable
42         }
43
44         Proxy(final DatastoreSnapshot datastoreSnapshot) {
45             this.datastoreSnapshot = datastoreSnapshot;
46         }
47
48         @Override
49         public void writeExternal(ObjectOutput out) throws IOException {
50             out.writeObject(datastoreSnapshot.type);
51             out.writeObject(datastoreSnapshot.shardManagerSnapshot);
52
53             out.writeInt(datastoreSnapshot.shardSnapshots.size());
54             for (ShardSnapshot shardSnapshot: datastoreSnapshot.shardSnapshots) {
55                 out.writeObject(shardSnapshot);
56             }
57         }
58
59         @Override
60         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
61             String type = (String)in.readObject();
62             byte[] shardManagerSnapshot = (byte[]) in.readObject();
63
64             int size = in.readInt();
65             List<ShardSnapshot> shardSnapshots = new ArrayList<>(size);
66             for (int i = 0; i < size; i++) {
67                 shardSnapshots.add((ShardSnapshot) in.readObject());
68             }
69
70             datastoreSnapshot = new DatastoreSnapshot(type, shardManagerSnapshot, shardSnapshots);
71         }
72
73         private Object readResolve() {
74             return datastoreSnapshot;
75         }
76     }
77
78     private final String type;
79     private final byte[] shardManagerSnapshot;
80     private final List<ShardSnapshot> shardSnapshots;
81
82     @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Stores a reference to an externally mutable byte[] "
83             + "object but this is OK since this class is merely a DTO and does not process byte[] internally. "
84             + "Also it would be inefficient to create a return copy as the byte[] could be large.")
85     public DatastoreSnapshot(@Nonnull String type, @Nullable byte[] shardManagerSnapshot,
86             @Nonnull List<ShardSnapshot> shardSnapshots) {
87         this.type = Preconditions.checkNotNull(type);
88         this.shardManagerSnapshot = shardManagerSnapshot;
89         this.shardSnapshots = ImmutableList.copyOf(Preconditions.checkNotNull(shardSnapshots));
90     }
91
92     @Nonnull
93     public String getType() {
94         return type;
95     }
96
97     @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "Exposes a mutable object stored in a field but "
98             + "this is OK since this class is merely a DTO and does not process byte[] internally. "
99             + "Also it would be inefficient to create a return copy as the byte[] could be large.")
100     @Nullable
101     public byte[] getShardManagerSnapshot() {
102         return shardManagerSnapshot;
103     }
104
105     @Nonnull
106     public List<ShardSnapshot> getShardSnapshots() {
107         return shardSnapshots;
108     }
109
110     @SuppressWarnings("static-method")
111     private Object writeReplace() {
112         return new Proxy(this);
113     }
114
115     public static class ShardSnapshot implements Serializable {
116         private static final long serialVersionUID = 1L;
117
118         private static final class Proxy implements Externalizable {
119             private static final long serialVersionUID = 1L;
120
121             private ShardSnapshot shardSnapshot;
122
123             // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
124             // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
125             @SuppressWarnings("checkstyle:RedundantModifier")
126             public Proxy() {
127                 // For Externalizable
128             }
129
130             Proxy(final ShardSnapshot shardSnapshot) {
131                 this.shardSnapshot = shardSnapshot;
132             }
133
134             @Override
135             public void writeExternal(ObjectOutput out) throws IOException {
136                 out.writeObject(shardSnapshot.name);
137                 out.writeObject(shardSnapshot.snapshot);
138             }
139
140             @Override
141             public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
142                 shardSnapshot = new ShardSnapshot((String)in.readObject(), (Snapshot) in.readObject());
143             }
144
145             private Object readResolve() {
146                 return shardSnapshot;
147             }
148         }
149
150         private final String name;
151         private final Snapshot snapshot;
152
153         public ShardSnapshot(@Nonnull String name, @Nonnull Snapshot snapshot) {
154             this.name = Preconditions.checkNotNull(name);
155             this.snapshot = Preconditions.checkNotNull(snapshot);
156         }
157
158         @Nonnull
159         public String getName() {
160             return name;
161         }
162
163         @Nonnull
164         public Snapshot getSnapshot() {
165             return snapshot;
166         }
167
168         @SuppressWarnings("static-method")
169         private Object writeReplace() {
170             return new Proxy(this);
171         }
172     }
173 }