2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.groupbasedpolicy.renderer.opflex;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.ScheduledExecutorService;
14 import java.util.concurrent.atomic.AtomicReference;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
20 import org.opendaylight.groupbasedpolicy.renderer.opflex.jsonrpc.JsonRpcEndpoint;
21 import org.opendaylight.groupbasedpolicy.renderer.opflex.jsonrpc.RpcMessage;
23 import com.google.common.util.concurrent.CheckedFuture;
26 * A context for managing a related set of operations to the Endpoint Registry's
27 * lists of Endpoints. It also keeps state from messaging that initiated the
28 * Endpoint Registry interaction, so that notifications from the registry can be
29 * used to send responses
33 public class EprContext implements Runnable, EprOperation.EprOpCallback {
35 private EprCtxCallback cb;
36 private final DataBroker dataProvider;
37 private final ScheduledExecutorService executor;
38 private final JsonRpcEndpoint peer;
39 private final RpcMessage request;
40 private final List<EprOperation> operations = new ArrayList<>();
41 private AtomicReference<Integer> completedOperations;
42 private CheckedFuture<Void, TransactionCommitFailedException> f;
44 public EprContext(JsonRpcEndpoint peer, RpcMessage request, DataBroker dataProvider,
45 ScheduledExecutorService executor) {
46 this.dataProvider = dataProvider;
47 this.executor = executor;
49 this.request = request;
53 * Add an operation to this context. This is not thread-safe.
57 public void addOperation(EprOperation operation) {
58 if (operation != null) {
59 operations.add(operation);
63 public List<EprOperation> getOperations() {
64 return this.operations;
67 public JsonRpcEndpoint getPeer() {
72 * Provides a callback that is invoked in response to a transaction with the
77 public static interface EprCtxCallback {
79 public void callback(EprContext ctx);
82 public void setCallback(EprCtxCallback callback) {
86 public RpcMessage getRequest() {
91 * Create an Endpoint in the Endopint Registry. This can only be called in
92 * response to an {@link org.opendaylight.groupbasedpolicy.renderer.opflex.lib.messages.EndpointDeclareRequest} message
94 public void createEp() {
96 WriteTransaction wt = dataProvider.newWriteOnlyTransaction();
99 * Add each of the create/update operations to a single transaction
101 for (EprOperation eo : operations) {
105 f.addListener(this, executor);
110 * Delete an Endpoint in the Endpoint Registry. This can only be called in
111 * response to an {@link org.opendaylight.groupbasedpolicy.renderer.opflex.lib.messages.EndpointUndeclareRequest} message
113 public void deleteEp() {
115 WriteTransaction wt = dataProvider.newWriteOnlyTransaction();
118 * Add each of the delete operations to a single transaction
120 for (EprOperation eo : operations) {
124 f.addListener(this, executor);
128 * Look up an endpoint in the Endpoint Registry. This can only be called in
129 * response to an {@link org.opendaylight.groupbasedpolicy.renderer.opflex.lib.messages.EndpointResolveRequest} message. It initiates all
130 * of the reads, one by one, and invokes the callback when all of them have
133 public void lookupEndpoint() {
136 * Each read operation requires it's own transaction. We add a callback
137 * for each operation, so we can determine when all of the read
138 * operations have completed.
140 this.completedOperations = new AtomicReference<Integer>(Integer.valueOf(0));
141 for (EprOperation eo : operations) {
142 ReadOnlyTransaction rot = dataProvider.newReadOnlyTransaction();
144 eo.setCallback(this);
145 eo.read(rot, executor);
150 * This implements the callback for the create and delete operations, from
157 } catch (Exception e) {
158 // TODO: Don't use Exception
164 * This implements the callback for the lookup operation.
167 public void callback(EprOperation op) {
169 * Add this to the list of operations that have completed, and if
170 * finished, invoke our callback
172 completedOperations.set(completedOperations.get().intValue() + 1);
173 if (completedOperations.get() >= operations.size()) {
175 // TODO: way to ensure it doesn't get invoked multiple times