reverted varianttype
[profile/ivi/automotive-message-broker.git] / ambd / pluginloader.cpp
1 /*
2 Copyright (C) 2012 Intel Corporation
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19
20 #include "pluginloader.h"
21 #include "glibmainloop.h"
22 #include "core.h"
23 #include <json.h>
24 #include <iostream>
25 #include <stdexcept>
26 #include <boost/concept_check.hpp>
27
28 std::string get_file_contents(const char *filename)
29 {
30         //FILE *in = fopen(filename,"r");
31
32         std::ifstream in(filename, std::ios::in);
33         std::string output;
34         std::string line;
35         while(in.good())
36         {
37                 getline(in,line);
38                 output.append(line);
39         }
40         return output;
41 }
42
43 PluginLoader::PluginLoader(string configFile, int argc, char** argv): f_create(NULL), routingEngine(nullptr), mMainLoop(nullptr)
44 {
45         DebugOut()<<"Loading config file: "<<configFile<<endl;
46         json_object *rootobject;
47         json_tokener *tokener = json_tokener_new();
48         std::string configBuffer = get_file_contents(configFile.c_str());
49         if(configBuffer == "")
50         {
51                 throw std::runtime_error("No config or config empty");
52         }
53         enum json_tokener_error err;
54         do
55         {
56                 rootobject = json_tokener_parse_ex(tokener, configBuffer.c_str(),configBuffer.length());
57         } while ((err = json_tokener_get_error(tokener)) == json_tokener_continue);
58         if (err != json_tokener_success)
59         {
60                 fprintf(stderr, "Error: %s\n", json_tokener_error_desc(err));
61                 // Handle errors, as appropriate for your application.
62                 throw std::runtime_error("Invalid config");
63         }
64         if (tokener->char_offset < configFile.length()) // XXX shouldn't access internal fields
65         {
66                 // Handle extra characters after parsed object as desired.
67                 // e.g. issue an error, parse another object from that point, etc...
68         }
69
70         json_object *coreobject = json_object_object_get(rootobject,"routingEngine");
71         if (coreobject)
72         {
73                 /// there is a mainloop entry.  Load the plugin:
74
75                 string restr = string(json_object_get_string(coreobject));
76
77                 routingEngine = loadRoutingEngine(restr);
78
79                 if(!routingEngine)
80                 {
81                         DebugOut(DebugOut::Warning)<<"Failed to load routing engine plugin: "<<restr<<endl;
82                 }
83         }
84
85         if(!routingEngine)
86         {
87                 /// there is no mainloop entry, use default glib
88                 DebugOut()<<"No routing engine specified in config.  Using built-in 'core' routing engine by default."<<endl;
89
90                 /// core wants some specific configuration settings:
91                 std::map<std::string,std::string> settings;
92
93                 json_object *lpq = json_object_object_get(rootobject,"lowPriorityQueueSize");
94                 if (lpq)
95                 {
96                         /// there is a mainloop entry.  Load the plugin:
97
98                         string restr = string(json_object_get_string(lpq));
99                         settings["lowPriorityQueueSize"] = restr;
100                 }
101
102                 json_object *npq = json_object_object_get(rootobject,"normalPriorityQueueSize");
103                 if (npq)
104                 {
105                         /// there is a mainloop entry.  Load the plugin:
106
107                         string restr = string(json_object_get_string(npq));
108                         settings["normalPriorityQueueSize"] = restr;
109                 }
110
111                 json_object *hpq = json_object_object_get(rootobject,"highPriorityQueueSize");
112                 if (hpq)
113                 {
114                         /// there is a mainloop entry.  Load the plugin:
115
116                         string restr = string(json_object_get_string(hpq));
117                         settings["highPriorityQueueSize"] = restr;
118                 }
119
120                 routingEngine = new Core(settings);
121         }
122
123
124
125         json_object *mainloopobject = json_object_object_get(rootobject,"mainloop");
126         if (mainloopobject)
127         {
128                 /// there is a mainloop entry.  Load the plugin:
129
130                 string mainloopstr = string(json_object_get_string(mainloopobject));
131
132                 mMainLoop = loadMainLoop(mainloopstr,argc, argv);
133
134                 if(!mMainLoop)
135                 {
136                         DebugOut(DebugOut::Warning)<<"Failed to load main loop plugin."<<endl;
137                 }
138         }
139         else if(!mMainLoop)
140         {
141                 /// there is no mainloop entry, use default glib
142                 DebugOut()<<"No mainloop specified in config.  Using glib by default."<<endl;
143                 mMainLoop = new GlibMainLoop(argc,argv);
144         }
145
146         json_object *sourcesobject = json_object_object_get(rootobject,"sources");
147
148         if(!sourcesobject)
149         {
150                 DebugOut()<<"Error getting sources member: "<<endl;
151                 throw std::runtime_error("Error getting sources member");
152         }
153
154         //g_assert(json_reader_is_array(reader));
155         g_assert(json_object_get_type(sourcesobject)==json_type_array);
156
157
158         array_list *sourceslist = json_object_get_array(sourcesobject);
159         if (!sourceslist)
160         {
161                 DebugOut() << "Error getting source list" << endl;
162                 throw std::runtime_error("Error getting sources list");
163         }
164
165         for(int i=0; i < array_list_length(sourceslist); i++)
166         {
167                 json_object *obj = (json_object*)array_list_get_idx(sourceslist,i); //This is an object
168
169                 std::map<std::string, std::string> configurationMap;
170                 json_object_object_foreach(obj, key, val)
171                 {
172                         string valstr = json_object_get_string(val);
173                         DebugOut() << "plugin config key: " << key << "value:" << valstr << endl;
174                         configurationMap[key] = valstr;
175                 }
176
177                 string path = configurationMap["path"];
178
179                 if(!loadPlugin(path,configurationMap))
180                         DebugOut(DebugOut::Warning) << "Failed to load plugin: " << path <<endl;
181         }
182
183         //json_object_put(sourcesobject);
184         ///read the sinks:
185
186         json_object *sinksobject = json_object_object_get(rootobject,"sinks");
187
188         if (!sinksobject)
189         {
190                 DebugOut() << "Error getting sink object" << endl;
191                 throw std::runtime_error("Error getting sink object");
192         }
193
194         array_list *sinkslist = json_object_get_array(sinksobject);
195
196
197         if (!sinkslist)
198         {
199                 DebugOut() << "Error getting sink list" << endl;
200                 throw std::runtime_error("Error getting sink list");
201         }
202
203
204         for(int i=0; i < array_list_length(sinkslist); i++)
205         {
206                 json_object *obj = (json_object*)array_list_get_idx(sinkslist,i);
207
208                 std::map<std::string, std::string> configurationMap;
209
210                 json_object_object_foreach(obj, key, val)
211                 {
212                         string valstr = json_object_get_string(val);
213                         DebugOut() << "plugin config key: " << key << "value:" << valstr << endl;
214                         configurationMap[key] = valstr;
215                 }
216
217
218                 string path = configurationMap["path"];
219
220                 loadPlugin(path, configurationMap);
221         }
222
223         //json_object_put(sinksobject);
224         json_object_put(rootobject);
225         json_tokener_free(tokener);
226
227         Core* core = static_cast<Core*>(routingEngine);
228         if( core != nullptr )
229         {
230                 core->inspectSupported();
231         }
232 }
233
234 PluginLoader::~PluginLoader()
235 {
236         for(auto handle : openHandles)
237                 dlclose(handle);
238 }
239
240 IMainLoop *PluginLoader::mainloop()
241 {
242         return mMainLoop;
243 }
244
245 std::string PluginLoader::errorString()
246 {
247         return mErrorString;
248 }
249