blob: 66bf26bf947da3b852685a03cbe0711d31fe547e [file] [log] [blame]
Zhenkai Zhue42b4572013-01-22 15:57:54 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
19 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
20 */
21
22#include "content-server.h"
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080023#include "logging.h"
24#include <boost/lexical_cast.hpp>
25
26INIT_LOGGER ("ContentServer");
Zhenkai Zhue42b4572013-01-22 15:57:54 -080027
28using namespace Ccnx;
29using namespace std;
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080030using namespace boost;
Zhenkai Zhue42b4572013-01-22 15:57:54 -080031
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080032ContentServer::ContentServer(CcnxWrapperPtr ccnx, ActionLogPtr actionLog,
33 const boost::filesystem::path &rootDir,
34 const Ccnx::Name &deviceName, const std::string &sharedFolderName,
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080035 const std::string &appName,
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080036 int freshness)
37 : m_ccnx(ccnx)
38 , m_actionLog(actionLog)
39 , m_dbFolder(rootDir / ".chronoshare")
40 , m_freshness(freshness)
41 , m_executor (1)
42 , m_deviceName (deviceName)
43 , m_sharedFolderName (sharedFolderName)
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080044 , m_appName (appName)
Zhenkai Zhue42b4572013-01-22 15:57:54 -080045{
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080046 m_executor.start ();
Zhenkai Zhue42b4572013-01-22 15:57:54 -080047}
48
49ContentServer::~ContentServer()
50{
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080051 m_executor.shutdown ();
52
53 ScopedLock lock (m_mutex);
Zhenkai Zhue42b4572013-01-22 15:57:54 -080054 for (PrefixIt it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
55 {
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080056 Name filePrefix = Name (*it)(m_appName)("file");
57 Name actionPrefix = Name (*it)(m_appName)(m_sharedFolderName)("action");
58
59 m_ccnx->clearInterestFilter(filePrefix);
60 m_ccnx->clearInterestFilter(actionPrefix);
Zhenkai Zhue42b4572013-01-22 15:57:54 -080061 }
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080062
63 m_prefixes.clear ();
Zhenkai Zhue42b4572013-01-22 15:57:54 -080064}
65
66void
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080067ContentServer::registerPrefix(const Name &forwardingHint)
Zhenkai Zhue42b4572013-01-22 15:57:54 -080068{
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080069 // Format for files: /<forwarding-hint>/<appname>/file/<hash>/<device_name>/<segment>
70 // Format for actions: /<forwarding-hint>/<appname>/<shared-folder>/action/<device_name>/<action-seq>
Zhenkai Zhub74e1e92013-01-25 14:36:18 -080071
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080072 Name filePrefix = Name (forwardingHint)(m_appName)("file");
73 Name actionPrefix = Name (forwardingHint)(m_appName)(m_sharedFolderName)("action");
74
75 m_ccnx->setInterestFilter (filePrefix, bind(&ContentServer::serve_File, this, forwardingHint, filePrefix, _1));
76 m_ccnx->setInterestFilter (actionPrefix, bind(&ContentServer::serve_Action, this, forwardingHint, actionPrefix, _1));
77
78 _LOG_DEBUG (">> content server: register FILE " << filePrefix);
79 _LOG_DEBUG (">> content server: register ACTION " << actionPrefix);
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080080
81 ScopedLock lock (m_mutex);
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080082 m_prefixes.insert(forwardingHint);
Zhenkai Zhue42b4572013-01-22 15:57:54 -080083}
84
85void
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080086ContentServer::deregisterPrefix (const Name &forwardingHint)
Zhenkai Zhue42b4572013-01-22 15:57:54 -080087{
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080088 Name filePrefix = Name (forwardingHint)(m_appName)("file");
89 Name actionPrefix = Name (forwardingHint)(m_appName)(m_sharedFolderName)("action");
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080090
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080091 m_ccnx->clearInterestFilter(filePrefix);
92 m_ccnx->clearInterestFilter(actionPrefix);
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080093
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080094 _LOG_DEBUG ("<< content server: deregister FILE " << filePrefix);
95 _LOG_DEBUG ("<< content server: deregister ACTION " << actionPrefix);
96
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -080097 ScopedLock lock (m_mutex);
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080098 m_prefixes.erase (forwardingHint);
Zhenkai Zhue42b4572013-01-22 15:57:54 -080099}
100
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800101// void
102// ContentServer::serve(Name forwardingHint, const Name &interest)
103// {
104// // /forwardingHint/app-name/device-name/action/shared-folder/action-seq
105// // /forwardingHint/app-name/device-name/file/file-hash/segment
Zhenkai Zhuc3a27872013-01-25 19:21:25 -0800106
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800107// Name name = interest.getPartialName(forwardingHint.size());
108// if (name.size() > 3)
109// {
110// string type = name.getCompAsString(name.size() - 3);
111// if (type == "action")
112// {
113// serve_Action (forwardingHint, interest);
114// }
115// else if (type == "file")
116// {
117// serve_File (forwardingHint, interest);
118// }
119// }
120// }
Zhenkai Zhuc3a27872013-01-25 19:21:25 -0800121
122void
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800123ContentServer::serve_Action (Name forwardingHint, Name locatorPrefix, Name interest)
Zhenkai Zhue42b4572013-01-22 15:57:54 -0800124{
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800125 _LOG_DEBUG (">> content server serving ACTION, hint: " << forwardingHint << ", locatorPrefix: " << locatorPrefix << ", interest: " << interest);
126 m_executor.execute (bind (&ContentServer::serve_Action_Execute, this, forwardingHint, locatorPrefix, interest));
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800127 // need to unlock ccnx mutex... or at least don't lock it
128}
129
130void
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800131ContentServer::serve_File (Name forwardingHint, Name locatorPrefix, Name interest)
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800132{
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800133 _LOG_DEBUG (">> content server serving FILE, hint: " << forwardingHint << ", locatorPrefix: " << locatorPrefix << ", interest: " << interest);
134
135 m_executor.execute (bind (&ContentServer::serve_File_Execute, this, forwardingHint, locatorPrefix, interest));
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800136 // need to unlock ccnx mutex... or at least don't lock it
137}
138
139void
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800140ContentServer::serve_File_Execute (Name forwardingHint, Name locatorPrefix, Name interest)
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800141{
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800142 // forwardingHint: /<forwarding-hint>
143 // locatorPrefix: /<forwarding-hint>/<appname>/file
144 // interest: /<forwarding-hint>/<appname>/file/<hash>/<device_name>/<segment>
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800145
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800146 Name pureInterest = interest.getPartialName (locatorPrefix.size ());
147 // pureInterest: /<hash>/<device_name>/<segment>
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800148
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800149 int64_t segment = pureInterest.getCompFromBackAsInt (0);
150 Name deviceName = pureInterest.getPartialName (1, pureInterest.size () - 2);
151 Hash hash (head(pureInterest.getComp (0)), pureInterest.getComp (0).size());
152
153 _LOG_DEBUG (" server FILE for device: " << deviceName << ", file_hash: " << hash.shortHash () << " segment: " << segment);
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800154
155 string hashStr = lexical_cast<string> (hash);
156 if (ObjectDb::DoesExist (m_dbFolder, deviceName, hashStr)) // this is kind of overkill, as it counts available segments
Zhenkai Zhue42b4572013-01-22 15:57:54 -0800157 {
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800158 ObjectDb db (m_dbFolder, hashStr);
159 // may do prefetching
160
161 BytesPtr co = db.fetchSegment (deviceName, segment);
162 if (co)
Zhenkai Zhue42b4572013-01-22 15:57:54 -0800163 {
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800164 if (forwardingHint.size () == 0)
165 {
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800166 _LOG_DEBUG (ParsedContentObject (*co).name ());
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800167 m_ccnx->putToCcnd (*co);
168 }
169 else
170 {
171 if (m_freshness > 0)
172 {
173 m_ccnx->publishData(interest, *co, m_freshness);
174 }
175 else
176 {
177 m_ccnx->publishData(interest, *co);
178 }
179 }
180
181 }
182 else
183 {
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800184 _LOG_ERROR ("ObjectDd exists, but no segment " << segment << " for device: " << deviceName << ", file_hash: " << hash.shortHash ());
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800185 }
186 }
187 else
188 {
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800189 _LOG_ERROR ("ObjectDd doesn't exist for device: " << deviceName << ", file_hash: " << hash.shortHash ());
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800190 }
191
192}
193
194void
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800195ContentServer::serve_Action_Execute (Name forwardingHint, Name locatorPrefix, Name interest)
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800196{
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800197 // forwardingHint: /<forwarding-hint>
198 // locatorPrefix: /<forwarding-hint>/<appname>/<shared-folder>/action
199 // interest: /<forwarding-hint>/<appname>/<shared-folder>/action/<device_name>/<action-seq>
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800200
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800201 Name pureInterest = interest.getPartialName (locatorPrefix.size ());
202 // pureInterest: /<device_name>/<action-seq>
203
204 int64_t seqno = pureInterest.getCompFromBackAsInt (0);
205 Name deviceName = pureInterest.getPartialName (0, pureInterest.size () - 1);
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800206
207 _LOG_DEBUG (" server ACTION for device: " << deviceName << " and seqno: " << seqno);
208
209 PcoPtr pco = m_actionLog->LookupActionPco (deviceName, seqno);
210 if (pco)
211 {
212 if (forwardingHint.size () == 0)
213 {
214 m_ccnx->putToCcnd (pco->buf ());
215 }
216 else
217 {
218 const Bytes &content = pco->buf ();
219 if (m_freshness > 0)
Zhenkai Zhubc738572013-01-23 22:46:11 -0800220 {
221 m_ccnx->publishData(interest, content, m_freshness);
222 }
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800223 else
Zhenkai Zhubc738572013-01-23 22:46:11 -0800224 {
225 m_ccnx->publishData(interest, content);
226 }
Zhenkai Zhue42b4572013-01-22 15:57:54 -0800227 }
Zhenkai Zhue42b4572013-01-22 15:57:54 -0800228 }
Alexander Afanasyev28ca3ed2013-01-24 23:17:15 -0800229 else
230 {
231 _LOG_ERROR ("ACTION not found for device: " << deviceName << " and seqno: " << seqno);
232 }
Zhenkai Zhue42b4572013-01-22 15:57:54 -0800233}