blob: 39c4ada1497c4a1e93c6758711d6480ea2939694 [file] [log] [blame]
Andrew Brown3f2521a2015-01-17 22:10:15 -08001/*
2 * File name: Client.java
3 *
4 * Purpose: Provide a client to simplify information retrieval over the NDN
5 * network.
6 *
7 * © Copyright Intel Corporation. All rights reserved.
8 * Intel Corporation, 2200 Mission College Boulevard,
9 * Santa Clara, CA 95052-8119, USA
10 */
11package com.intel.jndn.utils;
12
13import java.io.IOException;
14import net.named_data.jndn.Data;
15import net.named_data.jndn.Face;
Andrew Brown3f2521a2015-01-17 22:10:15 -080016import net.named_data.jndn.Interest;
17import net.named_data.jndn.Name;
18import net.named_data.jndn.OnData;
Andrew Brown3f2521a2015-01-17 22:10:15 -080019import net.named_data.jndn.OnTimeout;
20import net.named_data.jndn.encoding.EncodingException;
Andrew Brown3f2521a2015-01-17 22:10:15 -080021import org.apache.logging.log4j.LogManager;
22import org.apache.logging.log4j.Logger;
23
24/**
Andrew Brown070dc892015-01-21 09:55:12 -080025 * Provide a client to simplify information retrieval over the NDN network.
Andrew Brown3f2521a2015-01-17 22:10:15 -080026 *
27 * @author Andrew Brown <andrew.brown@intel.com>
28 */
29public class Client {
30
Andrew Brown7b1daf32015-01-19 16:36:01 -080031 public static final long DEFAULT_SLEEP_TIME = 20;
32 public static final long DEFAULT_TIMEOUT = 2000;
33 private static final Logger logger = LogManager.getLogger();
Andrew Brown070dc892015-01-21 09:55:12 -080034 private static Client defaultInstance;
35
36 /**
37 * Singleton access for simpler client use
38 *
39 * @return
40 */
41 public static Client getDefault() {
42 if (defaultInstance == null) {
43 defaultInstance = new Client();
44 }
45 return defaultInstance;
46 }
Andrew Brown3f2521a2015-01-17 22:10:15 -080047
Andrew Brown7b1daf32015-01-19 16:36:01 -080048 /**
49 * Synchronously retrieve the Data for an Interest; this will block until
50 * complete (i.e. either data is received or the interest times out).
51 *
52 * @param face
53 * @param interest
54 * @return Data packet or null
55 */
56 public Data getSync(Face face, Interest interest) {
57 // setup event
58 long startTime = System.currentTimeMillis();
Andrew Browna450fad2015-01-22 11:24:40 -080059 final NDNEvent event = new NDNEvent(); // this event is used without observer/observables for speed; just serves as a final reference into the callbacks
Andrew Brown3f2521a2015-01-17 22:10:15 -080060
Andrew Brown7b1daf32015-01-19 16:36:01 -080061 // send interest
62 try {
63 face.expressInterest(interest, new OnData() {
64 @Override
65 public void onData(Interest interest, Data data) {
Andrew Brown070dc892015-01-21 09:55:12 -080066 event.fromPacket(data);
Andrew Brown7b1daf32015-01-19 16:36:01 -080067 }
68 }, new OnTimeout() {
69 @Override
70 public void onTimeout(Interest interest) {
Andrew Brown070dc892015-01-21 09:55:12 -080071 event.fromPacket(new Exception("Interest timed out: " + interest.getName().toUri()));
Andrew Brown7b1daf32015-01-19 16:36:01 -080072 }
73 });
74 } catch (IOException e) {
75 logger.warn("IO failure while sending interest.", e);
76 return null;
77 }
Andrew Brown3f2521a2015-01-17 22:10:15 -080078
Andrew Brown070dc892015-01-21 09:55:12 -080079 // process eventCount until a response is received or timeout
Andrew Brown7b1daf32015-01-19 16:36:01 -080080 while (event.getPacket() == null) {
81 try {
82 synchronized (face) {
83 face.processEvents();
84 }
85 } catch (IOException | EncodingException e) {
86 logger.warn("Failed to process events.", e);
87 return null;
88 }
89 sleep();
90 }
Andrew Brown3f2521a2015-01-17 22:10:15 -080091
Andrew Brown7b1daf32015-01-19 16:36:01 -080092 // return
93 logger.debug("Request time (ms): " + (event.getTimestamp() - startTime));
94 return (event.isSuccess()) ? (Data) event.getPacket() : null;
95 }
Andrew Brown3f2521a2015-01-17 22:10:15 -080096
Andrew Brown7b1daf32015-01-19 16:36:01 -080097 /**
98 * Synchronously retrieve the Data for a Name using a default interest (e.g. 2
99 * second timeout); this will block until complete (i.e. either data is
100 * received or the interest times out).
101 *
102 * @param face
103 * @param name
104 * @return
105 */
106 public Data getSync(Face face, Name name) {
107 return getSync(face, getDefaultInterest(name));
108 }
Andrew Brown3f2521a2015-01-17 22:10:15 -0800109
Andrew Brown7b1daf32015-01-19 16:36:01 -0800110 /**
111 * Asynchronously retrieve the Data for a given interest; use the returned
Andrew Browna450fad2015-01-22 11:24:40 -0800112 NDNObserver to handle the Data when it arrives. For example (with lambdas):
Andrew Brown070dc892015-01-21 09:55:12 -0800113 * <pre><code>
114 * Client.getDefault().get(face, interest).then((event) -> doSomething(event));
115 * </code></pre>
116 *
117 * If you want to block until the response returns, try something like:
118 * <pre><code>
Andrew Browna450fad2015-01-22 11:24:40 -0800119 NDNObserver observer = Client.getDefault().get(face, interest);
120 while(observer.eventCount() == 0){
121 Thread.sleep(50);
122 }
123 doSomething(observer.getFirst());
124 </code></pre>
Andrew Brown7b1daf32015-01-19 16:36:01 -0800125 *
126 * @param face
127 * @param interest
128 * @return
129 */
Andrew Browna450fad2015-01-22 11:24:40 -0800130 public NDNObserver get(final Face face, final Interest interest) {
Andrew Brown7b1daf32015-01-19 16:36:01 -0800131 // setup observer
Andrew Browna450fad2015-01-22 11:24:40 -0800132 final NDNObserver observer = new NDNObserver();
133 final NDNObservable eventHandler = new NDNObservable();
Andrew Brown7b1daf32015-01-19 16:36:01 -0800134 eventHandler.addObserver(observer);
Andrew Brown3f2521a2015-01-17 22:10:15 -0800135
Andrew Brown7b1daf32015-01-19 16:36:01 -0800136 // setup background thread
137 Thread backgroundThread = new Thread(new Runnable() {
138 @Override
139 public void run() {
140 // send interest
141 try {
142 face.expressInterest(interest, eventHandler, eventHandler);
143 } catch (IOException e) {
144 logger.warn("IO failure while sending interest.", e);
145 eventHandler.notify(e);
146 }
Andrew Brown3f2521a2015-01-17 22:10:15 -0800147
Andrew Brown070dc892015-01-21 09:55:12 -0800148 // process eventCount until a response is received or timeout
149 while (observer.dataCount() == 0 && observer.errorCount() == 0 && !observer.mustStop()) {
Andrew Brown7b1daf32015-01-19 16:36:01 -0800150 try {
151 synchronized (face) {
152 face.processEvents();
153 }
154 } catch (IOException | EncodingException e) {
155 logger.warn("Failed to process events.", e);
156 eventHandler.notify(e);
157 }
158 sleep();
159 }
Andrew Brown070dc892015-01-21 09:55:12 -0800160
Andrew Brown7b1daf32015-01-19 16:36:01 -0800161 // finished
162 logger.trace("Received response; stopping thread.");
163 }
164 });
165 backgroundThread.setName(String.format("Client.get(%s)", interest.getName().toUri()));
166 backgroundThread.setDaemon(true);
167 backgroundThread.start();
Andrew Brown3f2521a2015-01-17 22:10:15 -0800168
Andrew Brown7b1daf32015-01-19 16:36:01 -0800169 // return
170 return observer;
171 }
Andrew Brown3f2521a2015-01-17 22:10:15 -0800172
Andrew Brown7b1daf32015-01-19 16:36:01 -0800173 /**
174 * Asynchronously retrieve the Data for a Name using default Interest
175 * parameters; see get(Face, Interest) for examples.
176 *
177 * @param face
178 * @param name
179 * @return
180 */
Andrew Browna450fad2015-01-22 11:24:40 -0800181 public NDNObserver get(Face face, Name name) {
Andrew Brown7b1daf32015-01-19 16:36:01 -0800182 return get(face, getDefaultInterest(name));
183 }
Andrew Brown3f2521a2015-01-17 22:10:15 -0800184
Andrew Brown7b1daf32015-01-19 16:36:01 -0800185 /**
Andrew Brown7b1daf32015-01-19 16:36:01 -0800186 * Put the current thread to sleep to allow time for IO
187 */
188 protected void sleep() {
189 try {
190 Thread.currentThread().sleep(DEFAULT_SLEEP_TIME);
191 } catch (InterruptedException e) {
192 logger.error("Event loop interrupted.", e);
193 }
194 }
195
196 /**
197 * Create a default interest for a given Name using some common settings: -
198 * lifetime: 2 seconds
199 *
200 * @param name
201 * @return
202 */
203 public Interest getDefaultInterest(Name name) {
204 Interest interest = new Interest(name, DEFAULT_TIMEOUT);
205 return interest;
206 }
Andrew Brown3f2521a2015-01-17 22:10:15 -0800207}