blob: 5cdc5a96ba75c58201982f30ccdd6afb3d4da873 [file] [log] [blame]
Madan Jampani15b8ef52016-02-02 17:35:05 -08001/*
2 * Copyright 2016 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.store.primitives.impl;
17
18import io.atomix.catalyst.serializer.Serializer;
19import io.atomix.catalyst.transport.Address;
20import io.atomix.resource.ResourceType;
21import io.atomix.variables.DistributedLong;
22
23import java.io.File;
24import java.util.Collection;
25import java.util.Optional;
26import java.util.concurrent.CompletableFuture;
27import java.util.concurrent.atomic.AtomicBoolean;
28
29import org.onosproject.cluster.ClusterService;
30import org.onosproject.cluster.ControllerNode;
Madan Jampani15b8ef52016-02-02 17:35:05 -080031import org.onosproject.cluster.NodeId;
32import org.onosproject.cluster.Partition;
Madan Jampani33547452016-02-29 16:45:04 -080033import org.onosproject.cluster.PartitionId;
Madan Jampani15b8ef52016-02-02 17:35:05 -080034import org.onosproject.store.cluster.messaging.MessagingService;
35import org.onosproject.store.primitives.resources.impl.AtomixConsistentMap;
Madan Jampani39fff102016-02-14 13:17:28 -080036import org.onosproject.store.primitives.resources.impl.AtomixLeaderElector;
Madan Jampanie14a09c2016-02-11 10:43:21 -080037import org.onosproject.store.service.PartitionInfo;
Madan Jampani15b8ef52016-02-02 17:35:05 -080038
39import com.google.common.collect.Collections2;
40import com.google.common.collect.ImmutableSet;
41
42/**
43 * Storage partition.
44 */
Madan Jampani33547452016-02-29 16:45:04 -080045public class StoragePartition implements Managed<StoragePartition> {
Madan Jampani15b8ef52016-02-02 17:35:05 -080046
47 private final AtomicBoolean isOpened = new AtomicBoolean(false);
48 private final AtomicBoolean isClosed = new AtomicBoolean(false);
49 private final Serializer serializer;
50 private final MessagingService messagingService;
51 private final ClusterService clusterService;
52 private final File logFolder;
Madan Jampani33547452016-02-29 16:45:04 -080053 private Partition partition;
Madan Jampani15b8ef52016-02-02 17:35:05 -080054 private static final Collection<ResourceType> RESOURCE_TYPES = ImmutableSet.of(
55 new ResourceType(DistributedLong.class),
Madan Jampani39fff102016-02-14 13:17:28 -080056 new ResourceType(AtomixLeaderElector.class),
Madan Jampani15b8ef52016-02-02 17:35:05 -080057 new ResourceType(AtomixConsistentMap.class));
58
59 private NodeId localNodeId;
Madan Jampani33547452016-02-29 16:45:04 -080060 private StoragePartitionServer server;
Madan Jampani15b8ef52016-02-02 17:35:05 -080061 private StoragePartitionClient client;
62
63 public StoragePartition(Partition partition,
64 MessagingService messagingService,
65 ClusterService clusterService,
66 Serializer serializer,
67 File logFolder) {
Madan Jampani33547452016-02-29 16:45:04 -080068 this.partition = partition;
Madan Jampani15b8ef52016-02-02 17:35:05 -080069 this.messagingService = messagingService;
70 this.clusterService = clusterService;
71 this.localNodeId = clusterService.getLocalNode().id();
72 this.serializer = serializer;
73 this.logFolder = logFolder;
74 }
75
Madan Jampani3a9911c2016-02-21 11:25:45 -080076 /**
77 * Returns the partition client instance.
78 * @return client
79 */
Madan Jampani15b8ef52016-02-02 17:35:05 -080080 public StoragePartitionClient client() {
81 return client;
82 }
83
84 @Override
85 public CompletableFuture<Void> open() {
Madan Jampani33547452016-02-29 16:45:04 -080086 openServer();
Madan Jampanic94b4852016-02-23 18:18:37 -080087 return openClient().thenAccept(v -> isOpened.set(true))
Madan Jampani15b8ef52016-02-02 17:35:05 -080088 .thenApply(v -> null);
89 }
90
91 @Override
92 public CompletableFuture<Void> close() {
Madan Jampani33547452016-02-29 16:45:04 -080093 // We do not explicitly close the server and instead let the cluster
94 // deal with this as an unclean exit.
95 return closeClient().thenAccept(v -> isClosed.set(true))
Madan Jampani15b8ef52016-02-02 17:35:05 -080096 .thenApply(v -> null);
97 }
98
Madan Jampani33547452016-02-29 16:45:04 -080099 /**
100 * Returns the identifier of the {@link Partition partition} associated with this instance.
101 * @return partition identifier
102 */
103 public PartitionId getId() {
104 return partition.getId();
Madan Jampani15b8ef52016-02-02 17:35:05 -0800105 }
106
Madan Jampani33547452016-02-29 16:45:04 -0800107 /**
108 * Returns the identifiers of partition members.
109 * @return partition member instance ids
110 */
111 public Collection<NodeId> getMembers() {
112 return partition.getMembers();
113 }
114
115 /**
116 * Returns the {@link Address addresses} of partition members.
117 * @return partition member addresses
118 */
119 public Collection<Address> getMemberAddresses() {
120 return Collections2.transform(partition.getMembers(), this::toAddress);
121 }
122
123 private CompletableFuture<Void> openServer() {
124 if (!partition.getMembers().contains(localNodeId) || server != null) {
Madan Jampani15b8ef52016-02-02 17:35:05 -0800125 return CompletableFuture.completedFuture(null);
126 }
127 StoragePartitionServer server = new StoragePartitionServer(toAddress(localNodeId),
128 this,
129 serializer,
130 () -> new CopycatTransport(CopycatTransport.Mode.SERVER,
Madan Jampani33547452016-02-29 16:45:04 -0800131 partition.getId(),
Madan Jampani15b8ef52016-02-02 17:35:05 -0800132 messagingService),
133 RESOURCE_TYPES,
134 logFolder);
Madan Jampani33547452016-02-29 16:45:04 -0800135 return server.open().thenRun(() -> this.server = server);
Madan Jampani15b8ef52016-02-02 17:35:05 -0800136 }
137
138 private CompletableFuture<StoragePartitionClient> openClient() {
139 client = new StoragePartitionClient(this,
140 serializer,
141 new CopycatTransport(CopycatTransport.Mode.CLIENT,
Madan Jampani33547452016-02-29 16:45:04 -0800142 partition.getId(),
Madan Jampani15b8ef52016-02-02 17:35:05 -0800143 messagingService),
144 RESOURCE_TYPES);
145 return client.open().thenApply(v -> client);
146 }
147
Madan Jampani33547452016-02-29 16:45:04 -0800148 /**
149 * Closes the partition server if it was previously opened.
150 * @return future that is completed when the operation completes
151 */
152 public CompletableFuture<Void> closeServer() {
153 return server != null ? server.closeAndExit() : CompletableFuture.completedFuture(null);
154 }
155
156 @Override
157 public boolean isOpen() {
158 return isOpened.get() && !isClosed.get();
159 }
160
161 @Override
162 public boolean isClosed() {
163 return isClosed.get();
Madan Jampani15b8ef52016-02-02 17:35:05 -0800164 }
165
166 private CompletableFuture<Void> closeClient() {
167 if (client != null) {
168 return client.close();
169 }
170 return CompletableFuture.completedFuture(null);
171 }
172
173 private Address toAddress(NodeId nodeId) {
174 ControllerNode node = clusterService.getNode(nodeId);
175 return new Address(node.ip().toString(), node.tcpPort());
176 }
177
Madan Jampanie14a09c2016-02-11 10:43:21 -0800178 /**
179 * Returns the partition information if this partition is locally managed i.e.
180 * this node is a active member of the partition.
181 * @return partition info
182 */
183 public Optional<PartitionInfo> info() {
Madan Jampani33547452016-02-29 16:45:04 -0800184 return server != null ? Optional.of(server.info()) : Optional.empty();
185 }
186
187 public void onUpdate(Partition partition) {
188 this.partition = partition;
189 if (partition.getMembers().contains(localNodeId)) {
190 openServer();
191 } else if (!partition.getMembers().contains(localNodeId)) {
192 closeServer();
193 }
Madan Jampanie14a09c2016-02-11 10:43:21 -0800194 }
Madan Jampani15b8ef52016-02-02 17:35:05 -0800195}