REST API to fetch Node Property
[controller.git] / opendaylight / md-sal / samples / toaster-provider / src / main / java / org / opendaylight / controller / sample / toaster / provider / OpendaylightToaster.java
1 /*
2  * Copyright (c) 2014 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.sample.toaster.provider;
9
10 import java.util.Collections;
11 import java.util.concurrent.Callable;
12 import java.util.concurrent.ExecutionException;
13 import java.util.concurrent.ExecutorService;
14 import java.util.concurrent.Executors;
15 import java.util.concurrent.Future;
16 import java.util.concurrent.atomic.AtomicLong;
17
18 import org.opendaylight.controller.config.yang.config.toaster_provider.impl.ToasterProviderRuntimeMXBean;
19 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
20 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
21 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
22 import org.opendaylight.controller.sal.common.util.Rpcs;
23 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.DisplayString;
24 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput;
25 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastDone.ToastStatus;
26 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastDoneBuilder;
27 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster;
28 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster.ToasterStatus;
29 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterBuilder;
30 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterData;
31 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.opendaylight.yangtools.yang.common.RpcError;
34 import org.opendaylight.yangtools.yang.common.RpcResult;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import com.google.common.util.concurrent.Futures;
39
40 public class OpendaylightToaster implements ToasterData, ToasterService, ToasterProviderRuntimeMXBean, AutoCloseable {
41
42     private static final Logger log = LoggerFactory.getLogger(OpendaylightToaster.class);
43     private static final InstanceIdentifier<Toaster>  toasterIID = InstanceIdentifier.builder(Toaster.class).build();
44
45     private static final DisplayString toasterManufacturer = new DisplayString("Opendaylight");
46     private static final DisplayString toasterModelNumber = new DisplayString("Model 1 - Binding Aware");
47
48     private NotificationProviderService notificationProvider;
49     private DataBrokerService dataProvider;
50     private final ExecutorService executor;
51
52     private Future<RpcResult<Void>> currentTask;
53
54     public OpendaylightToaster() {
55         executor = Executors.newFixedThreadPool(1);
56     }
57
58     @Override
59     public synchronized Toaster getToaster() {
60         ToasterBuilder tb = new ToasterBuilder();
61         tb //
62         .setToasterManufacturer(toasterManufacturer) //
63         .setToasterModelNumber(toasterModelNumber) //
64         .setToasterStatus(currentTask == null ? ToasterStatus.Up : ToasterStatus.Down);
65
66         return tb.build();
67     }
68
69     @Override
70     public synchronized Future<RpcResult<Void>> cancelToast() {
71         if (currentTask != null) {
72             cancelToastImpl();
73         }
74         return null;
75     }
76
77     @Override
78     public synchronized Future<RpcResult<Void>> makeToast(MakeToastInput input) {
79         log.debug("makeToast - Received input for toast");
80         logToastInput(input);
81         if (currentTask != null) {
82             return inProgressError();
83         }
84         currentTask = executor.submit(new MakeToastTask(input));
85         updateStatus();
86         return currentTask;
87     }
88
89     private Future<RpcResult<Void>> inProgressError() {
90         RpcResult<Void> result = Rpcs.<Void> getRpcResult(false, null, Collections.<RpcError> emptySet());
91         return Futures.immediateFuture(result);
92     }
93
94     private void cancelToastImpl() {
95         currentTask.cancel(true);
96         ToastDoneBuilder toastDone = new ToastDoneBuilder();
97         toastDone.setToastStatus(ToastStatus.Cancelled);
98         notificationProvider.publish(toastDone.build());
99     }
100
101     public void setNotificationProvider(NotificationProviderService salService) {
102         this.notificationProvider = salService;
103     }
104
105     public void setDataProvider(DataBrokerService salDataProvider) {
106         this.dataProvider = salDataProvider;
107         updateStatus();
108     }
109
110     private void logToastInput(MakeToastInput input) {
111         String toastType = input.getToasterToastType().getName();
112         String toastDoneness = input.getToasterDoneness().toString();
113         log.trace("Toast: {} doneness: {}", toastType, toastDoneness);
114     }
115
116     private final AtomicLong toastsMade = new AtomicLong(0);
117
118     @Override
119     public Long getToastsMade() {
120         return toastsMade.get();
121     }
122
123     private void updateStatus() {
124         if (dataProvider != null) {
125             final DataModificationTransaction t = dataProvider.beginTransaction();
126             t.removeOperationalData(toasterIID);
127             t.putOperationalData(toasterIID, getToaster());
128
129             try {
130                 t.commit().get();
131             } catch (InterruptedException | ExecutionException e) {
132                 log.warn("Failed to update toaster status, operational otherwise", e);
133             }
134         } else {
135             log.trace("No data provider configured, not updating status");
136         }
137     }
138
139     @Override
140     public void close() throws ExecutionException, InterruptedException {
141         if (dataProvider != null) {
142             final DataModificationTransaction t = dataProvider.beginTransaction();
143             t.removeOperationalData(toasterIID);
144             t.commit().get();
145         }
146     }
147
148     private class MakeToastTask implements Callable<RpcResult<Void>> {
149
150         final MakeToastInput toastRequest;
151
152         public MakeToastTask(MakeToastInput toast) {
153             toastRequest = toast;
154         }
155
156         @Override
157         public RpcResult<Void> call() throws InterruptedException {
158             Thread.sleep(1000 * toastRequest.getToasterDoneness());
159
160             ToastDoneBuilder notifyBuilder = new ToastDoneBuilder();
161             notifyBuilder.setToastStatus(ToastStatus.Done);
162             notificationProvider.publish(notifyBuilder.build());
163             log.debug("Toast Done");
164             logToastInput(toastRequest);
165
166             currentTask = null;
167             toastsMade.incrementAndGet();
168             updateStatus();
169
170             return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
171         }
172     }
173 }