Commit | Line | Data |
---|---|---|
6beab33f | 1 | /** @file |
e0080b78 | 2 | * @brief Serviceholder class implementation. This class holds Service and OldService lists. |
6beab33f BS |
3 | * |
4 | * | |
5 | * | |
6 | * @copyright Intra2net AG | |
7 | * @license GPLv2 | |
8 | */ | |
9 | ||
10 | #include "serviceholder.h" | |
11 | ||
ca5d6889 | 12 | #include <fstream> |
e0080b78 | 13 | |
ca5d6889 | 14 | #include <boost/foreach.hpp> |
e0080b78 | 15 | #include <boost/filesystem.hpp> |
ca5d6889 | 16 | |
104fe37d | 17 | #define OBJECT_FILE "/var/local/bpdyndnsd/objects.ser" |
88a594e8 | 18 | |
6beab33f BS |
19 | using namespace std; |
20 | ||
ca5d6889 BS |
21 | namespace fs = boost::filesystem; |
22 | ||
6beab33f BS |
23 | |
24 | /** | |
31af6a2e BS |
25 | * Default constructor. |
26 | */ | |
27 | Serviceholder::Serviceholder() | |
28 | :Log(new Logger) | |
29 | ,IPAddrHelp() | |
30 | { | |
31 | } | |
32 | ||
33 | ||
34 | /** | |
35 | * Constructor with Logger object. | |
6beab33f | 36 | */ |
e0080b78 | 37 | Serviceholder::Serviceholder(Logger::Ptr _log) |
9a0aff44 | 38 | :Log(_log) |
20399847 | 39 | ,IPAddrHelp() |
6beab33f BS |
40 | { |
41 | } | |
42 | ||
43 | ||
44 | /** | |
45 | * Default destructor. While serializing and deserializing we use boost/shared_ptr, the resources are managed correctly. | |
46 | */ | |
47 | Serviceholder::~Serviceholder() | |
48 | { | |
49 | } | |
50 | ||
51 | ||
52 | /** | |
e0080b78 BS |
53 | * This function serializes all Service objects in Services and OldServices (where the update Timeout isn't expired) into a specified file. |
54 | * @return 0 if all is fine, -1 if output file could not be opened for reading or error while serializing. | |
6beab33f | 55 | */ |
e0080b78 | 56 | int Serviceholder::serialize_services() |
6beab33f | 57 | { |
e0080b78 BS |
58 | // Put Services and OldServices into Serviceholder. |
59 | SerializeServiceContainer::Ptr service_container(new SerializeServiceContainer); | |
60 | ||
61 | BOOST_FOREACH(Service::Ptr &service, Services) | |
62 | { | |
63 | service_container->add_service(service); | |
64 | } | |
65 | ||
62df5f33 | 66 | time_t current_time = time(NULL); |
e0080b78 BS |
67 | |
68 | BOOST_FOREACH(Service::Ptr &service, OldServices) | |
69 | { | |
c1b8cb79 | 70 | if ( ( service->get_last_updates().front() + (service->get_update_interval()*60) ) >= current_time ) // UpdateInterval timeout of service isn't expired. |
e0080b78 BS |
71 | service_container->add_service(service); |
72 | } | |
73 | ||
20399847 | 74 | // Serialize SerializeServiceContainer and IPAddrHelper into file. |
e0080b78 BS |
75 | ofstream ofs(OBJECT_FILE); |
76 | if ( ofs.is_open() ) | |
77 | { | |
78 | SerializeServiceContainer* _service_container = service_container.get(); | |
20399847 | 79 | IPAddrHelper* _ip_addr_helper = IPAddrHelp.get(); |
e0080b78 BS |
80 | try |
81 | { | |
82 | boost::archive::text_oarchive oa(ofs); | |
20399847 | 83 | oa << _service_container << _ip_addr_helper; |
e0080b78 BS |
84 | } |
85 | catch( boost::archive::archive_exception e ) | |
86 | { | |
87 | Log->print_exception_serialize(e.what()); | |
88 | ofs.close(); | |
89 | return -1; | |
90 | } | |
91 | ||
92 | ofs.close(); | |
93 | } | |
94 | else | |
95 | { | |
96 | Log->print_error_opening_rw(OBJECT_FILE); | |
97 | return -1; | |
98 | } | |
99 | ||
100 | Log->print_serialized_objects_success(); | |
101 | ||
102 | return 0; | |
6beab33f BS |
103 | } |
104 | ||
105 | ||
106 | /** | |
e0080b78 BS |
107 | * This function de-serializes the SerializeServiceContainer (containing Services) from the object file. |
108 | * @return 0 if all is fine, -1 if object file couldn't be opened for reading or error while de-serializing. | |
109 | */ | |
110 | int Serviceholder::deserialize_services() | |
111 | { | |
112 | // test if OBJECT_FILE exists | |
113 | fs::path object_file = fs::system_complete(fs::path(OBJECT_FILE)); | |
114 | if ( !fs::exists(object_file) ) | |
115 | { | |
116 | // There is no object file, possibly first program start, continue without recovering old Services' state. | |
117 | Log->print_no_object_file(OBJECT_FILE); | |
118 | return 0; | |
119 | } | |
120 | ||
121 | ifstream ifs(OBJECT_FILE); | |
122 | if ( ifs.is_open() ) | |
123 | { | |
124 | // deserialize SerializeServiceContainer | |
125 | SerializeServiceContainer* _service_container; | |
20399847 | 126 | IPAddrHelper* _ip_addr_helper; |
e0080b78 BS |
127 | try |
128 | { | |
129 | boost::archive::text_iarchive ia(ifs); | |
20399847 | 130 | ia >> _service_container >> _ip_addr_helper; |
e0080b78 BS |
131 | } |
132 | catch( boost::archive::archive_exception e ) | |
133 | { | |
134 | Log->print_exception_deserialize(e.what()); | |
135 | ifs.close(); | |
136 | return -1; | |
137 | } | |
138 | SerializeServiceContainer::Ptr service_container(_service_container); | |
c3c84086 | 139 | IPAddrHelp = IPAddrHelper::Ptr(_ip_addr_helper); |
e0080b78 BS |
140 | ifs.close(); |
141 | ||
142 | // Get the list of old Services from de-serialized SerializeServiceContainer object. | |
143 | list<Service::Ptr> _old_services = service_container->get_containing_services(); | |
144 | ||
145 | // Put all de-serialized Services into OldServices member and | |
146 | // compare new Services (generated from config file and cmd) with old Services (de-serialized from object file) | |
147 | // if identical Service was found, adopt the value from old Service to recover Services' state. | |
148 | BOOST_FOREACH(Service::Ptr &old_service, _old_services) | |
149 | { | |
150 | OldServices.push_back(old_service); | |
d5a516ba | 151 | Log->print_service_object("Deserialized following Service object:", old_service->get_protocol(), old_service->get_hostname(), old_service->get_login() ,old_service->get_password(), old_service->get_update_interval(), old_service->get_max_updates_within_interval(), old_service->get_dns_cache_ttl() , old_service->get_actual_ip(), old_service->get_last_updates()); |
e0080b78 BS |
152 | BOOST_FOREACH(Service::Ptr &service, Services) |
153 | { | |
154 | if ( *service == *old_service ) | |
155 | { | |
156 | service->set_last_updates(old_service->get_last_updates()); | |
157 | service->set_actual_ip(old_service->get_actual_ip()); | |
d5a516ba | 158 | Log->print_service_object("New Service object with adopted values:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates()); |
e0080b78 BS |
159 | // We have adopted the values of the old_service. Just set lastupdated and timeout to 0, so this old_service wont be serialized. |
160 | old_service->set_update_interval(0); | |
161 | } | |
162 | } | |
163 | } | |
164 | Log->print_deserialized_objects_success(); | |
165 | } | |
166 | else | |
167 | { | |
168 | Log->print_error_opening_r(OBJECT_FILE); | |
169 | return -1; | |
170 | } | |
171 | ||
172 | return 0; | |
173 | } | |
174 | ||
175 | ||
176 | /** | |
177 | * Add service to internal service list. | |
178 | * @param service Shared pointer to service object. | |
6beab33f | 179 | */ |
88a594e8 | 180 | void Serviceholder::add_service(Service::Ptr service) |
6beab33f | 181 | { |
e0080b78 BS |
182 | Services.push_back(service); |
183 | } | |
184 | ||
185 | ||
186 | /** | |
187 | * Resets all shared Service pointers and clears the Services list. | |
188 | */ | |
189 | void Serviceholder::delete_services() | |
190 | { | |
191 | BOOST_FOREACH( Service::Ptr &service, Services ) | |
192 | { | |
193 | service.reset(); | |
194 | } | |
195 | Services.clear(); | |
196 | ||
197 | BOOST_FOREACH( Service::Ptr &service, OldServices ) | |
198 | { | |
199 | service.reset(); | |
200 | } | |
201 | OldServices.clear(); | |
20399847 BS |
202 | |
203 | IPAddrHelp.reset(); | |
6beab33f BS |
204 | } |
205 | ||
206 | ||
207 | /** | |
e0080b78 BS |
208 | * Getter for member Services |
209 | * @return List with shared Service pointers. | |
6beab33f | 210 | */ |
e0080b78 | 211 | std::list<Service::Ptr> Serviceholder::get_services() const |
6beab33f | 212 | { |
e0080b78 | 213 | return Services; |
6beab33f | 214 | } |
20399847 BS |
215 | |
216 | ||
217 | /** | |
218 | * Set member IPAddrHelp | |
219 | * @param _ip_addr_helper The IPAddrHelper. | |
220 | */ | |
221 | void Serviceholder::set_ip_addr_helper(IPAddrHelper::Ptr _ip_addr_helper) | |
222 | { | |
223 | IPAddrHelp = _ip_addr_helper; | |
224 | } | |
225 | ||
226 | ||
227 | /** | |
228 | * Get member IPAddrHelp | |
229 | * @return IPAddrHelp | |
230 | */ | |
231 | IPAddrHelper::Ptr Serviceholder::get_ip_addr_helper() const | |
232 | { | |
233 | return IPAddrHelp; | |
234 | } |