blob: 876cebc238acb3b4963df04bb4e0c2bb57cead8c [file] [log] [blame]
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Lijing Wangb95c6a52016-12-25 14:45:17 -08003 * Copyright (c) 2013-2017, Regents of the University of California.
Alexander Afanasyev026eaf32013-02-23 16:37:14 -08004 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08005 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
Alexander Afanasyev026eaf32013-02-23 16:37:14 -08006 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08007 * ChronoShare is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080010 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080011 * ChronoShare is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080014 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080015 * You should have received copies of the GNU General Public License along with
16 * ChronoShare, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080019 */
20
21#ifndef STATE_SERVER_H
22#define STATE_SERVER_H
23
Lijing Wangb95c6a52016-12-25 14:45:17 -080024#include "core/chronoshare-common.hpp"
25
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080026#include "action-log.hpp"
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080027#include "object-db.hpp"
28#include "object-manager.hpp"
Lijing Wangb95c6a52016-12-25 14:45:17 -080029
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080030#include <map>
31#include <set>
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080032
Alexander Afanasyeve1c95042013-02-27 01:02:36 -080033#include "../contrib/json_spirit/json_spirit_value.h"
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080034#include "../contrib/json_spirit/json_spirit_writer_template.h"
Alexander Afanasyeve1c95042013-02-27 01:02:36 -080035
36#ifndef JSON_SPIRIT_VALUE_ENABLED
37#error Please define JSON_SPIRIT_VALUE_ENABLED for the Value type to be enabled
38#endif
39
Lijing Wangb95c6a52016-12-25 14:45:17 -080040namespace ndn {
41namespace chronoshare {
42
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080043/**
44 * @brief Class serving state information from ChronoShare
45 *
46 * Eventually, the same info/actions can be made available via a global scope prefix
47 *
48 * Information available:
49 *
Lijing Wangb95c6a52016-12-25 14:45:17 -080050 * For now serving only locally(using <PREFIX> =
51 * ndn:/localhop/<user's-device-name>/"chronoshare"/<FOLDER>/"info")
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080052 *
Lijing Wangb95c6a52016-12-25 14:45:17 -080053 * - state: get list of SyncNodes, their sequence numbers, and forwarding hint(almost the same as
54 * RECOVERY interest)
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080055 *
Lijing Wangb95c6a52016-12-25 14:45:17 -080056 * <PREFIX_INFO>/"state" (@todo: authentification code or authentication code should in addition
57 * somewhere)
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080058 *
59 * - action
60 *
Lijing Wangb95c6a52016-12-25 14:45:17 -080061 * Get list of actions for a folder(for all files under this folder)
Alexander Afanasyev95f9f552013-02-26 23:05:20 -080062 *
Lijing Wangb95c6a52016-12-25 14:45:17 -080063 * <PREFIX_INFO>/"actions"/"folder"/<offset> (all actions)
Alexander Afanasyev95f9f552013-02-26 23:05:20 -080064 * or
Alexander Afanasyev3c95c852013-03-01 18:58:50 -080065 * <PREFIX_INFO>/"actions"/"folder"/<one-component-relative-file-name>/<offset>
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080066 *
Lijing Wangb95c6a52016-12-25 14:45:17 -080067 * Actions are ordered in decreasing order(latest will go first).
Alexander Afanasyev026eaf32013-02-23 16:37:14 -080068 *
Alexander Afanasyev95f9f552013-02-26 23:05:20 -080069 * Each data packet contains up to 100 actions.
Alexander Afanasyeve1c95042013-02-27 01:02:36 -080070 *
Lijing Wangb95c6a52016-12-25 14:45:17 -080071 * TEMPORARILY LIMIT IS REDUCED TO 10 !(for debug purposes)
72 * (may be even not temporarily...)
Alexander Afanasyeve1c95042013-02-27 01:02:36 -080073 *
Alexander Afanasyev95f9f552013-02-26 23:05:20 -080074 * If more items are available, application data will specify URL for the next packet
75 *
Lijing Wangb95c6a52016-12-25 14:45:17 -080076 * Format of returned data(JSON):
Alexander Afanasyeve1c95042013-02-27 01:02:36 -080077 * {
78 * "actions": [
79 * {
80 * "id": {
81 * "userName": "<NDN-NAME-OF-THE-USER>",
82 * "seqNo": "<SEQ_NO_OF_THE_ACTION>"
83 * },
84 * "timestamp": "<ACTION-TIMESTAMP>",
85 * "filename": "<FILENAME>",
86 *
87 * "action": "UPDATE | DELETE",
88 *
89 * // only if update
90 * "update": {
91 * "hash": "<FILE-HASH>",
92 * "timestamp": "<FILE-TIMESTAMP>",
93 * "chmod": "<FILE-MODE>",
Lijing Wangb95c6a52016-12-25 14:45:17 -080094 * "segNum": "<NUMBER-OF-SEGMENTS(~file size)>"
Alexander Afanasyeve1c95042013-02-27 01:02:36 -080095 * },
96 *
97 * // if parent_device_name is set
98 * "parentId": {
99 * "userName": "<NDN-NAME-OF-THE-USER>",
100 * "seqNo": "<SEQ_NO_OF_THE_ACTION>"
101 * };
102 * },
103 *
104 * // only if there are more actions available
Alexander Afanasyev3c95c852013-03-01 18:58:50 -0800105 * "more": "next segment number"
Alexander Afanasyeve1c95042013-02-27 01:02:36 -0800106 * }
107 *
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800108 *
109 * - file
110 *
Lijing Wangb95c6a52016-12-25 14:45:17 -0800111 * <PREFIX_INFO>/"files"/"folder"/<offset> (full filestate)
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800112 * or
Alexander Afanasyev3c95c852013-03-01 18:58:50 -0800113 * <PREFIX_INFO>/"files"/"folder"/<one-component-relative-folder-name>/<offset>
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800114 *
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800115 * Each Data packets contains a list of up to 100 files.
116 * If more items are available, application data will specify URL for the next packet
117 *
Lijing Wangb95c6a52016-12-25 14:45:17 -0800118 * TEMPORARILY LIMIT IS REDUCED TO 10 !(for debug purposes)
119 * (may be even not temporarily...)
Alexander Afanasyev94240b52013-02-27 11:57:29 -0800120 *
Lijing Wangb95c6a52016-12-25 14:45:17 -0800121 * Format of returned data(JSON):
Alexander Afanasyev94240b52013-02-27 11:57:29 -0800122 * {
123 * "files": [
124 * {
125 * "filename": "<FILENAME>",
126 * "owner": {
127 * "userName": "<NDN-NAME-OF-THE-USER>",
128 * "seqNo": "<SEQ_NO_OF_THE_ACTION>"
129 * },
130 *
131 * "hash": "<FILE-HASH>",
132 * "timestamp": "<FILE-TIMESTAMP>",
133 * "chmod": "<FILE-MODE>",
Lijing Wangb95c6a52016-12-25 14:45:17 -0800134 * "segNum": "<NUMBER-OF-SEGMENTS(~file size)>"
Alexander Afanasyev94240b52013-02-27 11:57:29 -0800135 * }, ...,
136 * ]
137 *
138 * // only if there are more actions available
Alexander Afanasyev3c95c852013-03-01 18:58:50 -0800139 * "more": "next segment number"
Alexander Afanasyev94240b52013-02-27 11:57:29 -0800140 * }
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800141 *
142 * Commands available:
143 *
Lijing Wangb95c6a52016-12-25 14:45:17 -0800144 * For now serving only locally(using <PREFIX_CMD> =
145 * ndn:/localhop/<user's-device-name>/"chronoshare"/<FOLDER>/"cmd")
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800146 *
147 * - restore version of the file
148 *
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800149 * <PREFIX_CMD>/"restore"/"file"/<one-component-relative-file-name>/<version>
150 * or
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800151 * <PREFIX_CMD>/"restore"/"file"/<one-component-relative-file-name>/<version>/<file-hash>
152 *
153 * - clean state log
Lijing Wangb95c6a52016-12-25 14:45:17 -0800154 * (this may not need to be here, if we implement periodic cleaning)
155 * - ? flatten action log(should be supported eventually, but not supported now)
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800156 */
157class StateServer
158{
159public:
Lijing Wangb95c6a52016-12-25 14:45:17 -0800160 StateServer(Face& face, ActionLogPtr actionLog, const boost::filesystem::path& rootDir,
161 const Name& userName, const std::string& sharedFolderName, const name::Component& appName,
162 ObjectManager& objectManager, KeyChain& keyChain,
163 time::milliseconds freshness = time::seconds(5));
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800164 ~StateServer();
165
166private:
167 void
Lijing Wangb95c6a52016-12-25 14:45:17 -0800168 info_actions_folder(const InterestFilter&, const Interest&);
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800169
170 void
Lijing Wangb95c6a52016-12-25 14:45:17 -0800171 info_actions_file(const InterestFilter&, const Interest&);
Alexander Afanasyev39dbc4b2013-03-01 10:39:23 -0800172
173 void
Lijing Wangb95c6a52016-12-25 14:45:17 -0800174 info_actions_fileOrFolder_Execute(const Name& interest, bool isFolder = true);
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800175
176 void
Lijing Wangb95c6a52016-12-25 14:45:17 -0800177 info_files_folder(const InterestFilter&, const Interest&);
Alexander Afanasyev95f9f552013-02-26 23:05:20 -0800178
179 void
Lijing Wangb95c6a52016-12-25 14:45:17 -0800180 info_files_folder_Execute(const Name& interest);
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800181
182 void
Lijing Wangb95c6a52016-12-25 14:45:17 -0800183 cmd_restore_file(const InterestFilter&, const Interest&);
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800184
185 void
Lijing Wangb95c6a52016-12-25 14:45:17 -0800186 cmd_restore_file_Execute(const Name& interest);
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800187
188private:
189 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800190 registerPrefixes();
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800191
192 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800193 deregisterPrefixes();
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800194
Alexander Afanasyeve1c95042013-02-27 01:02:36 -0800195 static void
Lijing Wangb95c6a52016-12-25 14:45:17 -0800196 formatActionJson(json_spirit::Array& actions, const Name& name, sqlite3_int64 seq_no,
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800197 const ActionItem& action);
Alexander Afanasyeve1c95042013-02-27 01:02:36 -0800198
Alexander Afanasyev94240b52013-02-27 11:57:29 -0800199 static void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800200 formatFilestateJson(json_spirit::Array& files, const FileItem& file);
Alexander Afanasyev94240b52013-02-27 11:57:29 -0800201
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800202private:
Lijing Wangb95c6a52016-12-25 14:45:17 -0800203 Face& m_face;
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800204 ActionLogPtr m_actionLog;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800205 ObjectManager& m_objectManager;
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800206
Lijing Wangb95c6a52016-12-25 14:45:17 -0800207 Name m_PREFIX_INFO;
208 Name m_PREFIX_CMD;
209
210 const RegisteredPrefixId* actionsFolderId;
211 const RegisteredPrefixId* actionsFileId;
212 const RegisteredPrefixId* filesFolderId;
213 const RegisteredPrefixId* restoreFileId;
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800214
215 boost::filesystem::path m_rootDir;
Lijing Wangb95c6a52016-12-25 14:45:17 -0800216 time::milliseconds m_freshness;
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800217
Lijing Wangb95c6a52016-12-25 14:45:17 -0800218 Name m_userName;
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800219 std::string m_sharedFolderName;
Lijing Wangb95c6a52016-12-25 14:45:17 -0800220 name::Component m_appName;
221 KeyChain& m_keyChain;
222
223 boost::asio::io_service& m_ioService;
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800224};
Lijing Wangb95c6a52016-12-25 14:45:17 -0800225
226} // namespace chronoshare
227} // namespace ndn
228
Alexander Afanasyev026eaf32013-02-23 16:37:14 -0800229#endif // CONTENT_SERVER_H