atomic-storage: remove type dependency at segment level I/O
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / main / java / org / opendaylight / controller / cluster / raft / RaftActorDelegatingPersistentDataProvider.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.raft;
9
10 import static java.util.Objects.requireNonNull;
11
12 import akka.japi.Procedure;
13 import org.opendaylight.controller.cluster.DataPersistenceProvider;
14 import org.opendaylight.controller.cluster.DelegatingPersistentDataProvider;
15 import org.opendaylight.controller.cluster.PersistentDataProvider;
16 import org.opendaylight.controller.cluster.raft.messages.Payload;
17 import org.opendaylight.controller.cluster.raft.messages.PersistentPayload;
18
19 /**
20  * The DelegatingPersistentDataProvider used by RaftActor to override the configured persistent provider to
21  * persist ReplicatedLogEntry's based on whether or not the payload is a PersistentPayload instance.
22  *
23  * @author Thomas Pantelis
24  */
25 class RaftActorDelegatingPersistentDataProvider extends DelegatingPersistentDataProvider {
26     private final PersistentDataProvider persistentProvider;
27
28     RaftActorDelegatingPersistentDataProvider(final DataPersistenceProvider delegate,
29             final PersistentDataProvider persistentProvider) {
30         super(delegate);
31         this.persistentProvider = requireNonNull(persistentProvider);
32     }
33
34     @Override
35     public <T> void persist(final T entry, final Procedure<T> procedure) {
36         doPersist(entry, procedure, false);
37     }
38
39     @Override
40     public <T> void persistAsync(final T entry, final Procedure<T> procedure) {
41         doPersist(entry, procedure, true);
42     }
43
44     private <T> void doPersist(final T entry, final Procedure<T> procedure, final boolean async) {
45         if (getDelegate().isRecoveryApplicable()) {
46             persistSuper(entry, procedure, async);
47         } else {
48             if (entry instanceof ReplicatedLogEntry) {
49                 Payload payload = ((ReplicatedLogEntry)entry).getData();
50                 if (payload instanceof PersistentPayload) {
51                     // We persist the Payload but not the ReplicatedLogEntry to avoid gaps in the journal indexes
52                     // on recovery if data persistence is later enabled.
53                     if (async) {
54                         persistentProvider.persistAsync(payload, p -> procedure.apply(entry));
55                     } else {
56                         persistentProvider.persist(payload, p -> procedure.apply(entry));
57                     }
58                 } else {
59                     persistSuper(entry, procedure, async);
60                 }
61             } else {
62                 persistSuper(entry, procedure, async);
63             }
64         }
65     }
66
67     private <T> void persistSuper(final T object, final Procedure<T> procedure, final boolean async) {
68         if (async) {
69             super.persistAsync(object, procedure);
70         } else {
71             super.persist(object, procedure);
72         }
73     }
74 }