Statistics
| Branch: | Tag: | Revision:

one / src / market / MarketPlaceManagerDriver.cc @ fed93cda

History | View | Annotate | Download (12.6 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
#include "MarketPlaceManagerDriver.h"
18
#include "Nebula.h"
19
#include <sstream>
20

    
21
/* ************************************************************************** */
22
/* Driver ASCII Protocol Implementation                                       */
23
/* ************************************************************************** */
24

    
25
void MarketPlaceManagerDriver::importapp(int oid, const std::string& msg) const
26
{
27
    std::ostringstream os;
28

    
29
    os << "IMPORT " << oid << " " << msg << endl;
30

    
31
    write(os);
32
}
33

    
34
/* -------------------------------------------------------------------------- */
35

    
36
void MarketPlaceManagerDriver::deleteapp(int oid, const std::string& msg) const
37
{
38
    std::ostringstream os;
39

    
40
    os << "DELETE " << oid << " " << msg << endl;
41

    
42
    write(os);
43
}
44

    
45
/* -------------------------------------------------------------------------- */
46

    
47
void MarketPlaceManagerDriver::monitor(int oid, const std::string& msg) const
48
{
49
    std::ostringstream os;
50

    
51
    os << "MONITOR " << oid << " " << msg << endl;
52

    
53
    write(os);
54
}
55

    
56
/* ************************************************************************** */
57
/* MAD Interface                                                              */
58
/* ************************************************************************** */
59

    
60
static void monitor_action(
61
        std::istringstream&  is,
62
        MarketPlacePool *    marketpool,
63
        MarketPlaceAppPool * apppool,
64
        MarketPlaceManager * marketm,
65
        int                  id,
66
        const std::string&   result)
67
{
68
    std::string  info64;
69
    std::string* info = 0;
70

    
71
    std::ostringstream oss;
72

    
73
    getline (is, info64);
74

    
75
    if (is.fail())
76
    {
77
        oss << "Error monitoring marketplace " << id << ". Bad monitor data: "
78
            << info64;
79

    
80
        NebulaLog::log("MKP", Log::ERROR, oss);
81
        return;
82
    }
83

    
84
    if (result != "SUCCESS")
85
    {
86
        oss << "Error monitoring marketplace " << id << ": " << info64;
87
        NebulaLog::log("MKP", Log::ERROR, oss);
88

    
89
        delete info;
90
        return;
91
    }
92

    
93
    info = one_util::base64_decode(info64);
94

    
95
    if (info == 0)
96
    {
97
        oss << "Error monitoring marketplace " << id << ". Bad monitor data: "
98
            << info64;
99

    
100
        NebulaLog::log("MKP", Log::ERROR, oss);
101
        return;
102
    }
103

    
104

    
105
    Template monitor_data;
106

    
107
    char * error_msg;
108
    int    rc = monitor_data.parse(*info, &error_msg);
109

    
110
    delete info;
111

    
112
    if ( rc != 0 )
113
    {
114
        oss << "Error parsing marketplace information: " << error_msg
115
            << ". Monitoring information: " << endl << info64;
116

    
117
        NebulaLog::log("MKP", Log::ERROR, oss);
118

    
119
        free(error_msg);
120
        return;
121
    }
122

    
123
    std::string   name;
124
    MarketPlace * market = marketpool->get(id, true);
125

    
126
    if (market == 0 )
127
    {
128
        return;
129
    }
130

    
131
    name    = market->get_name();
132

    
133
    market->update_monitor(monitor_data);
134

    
135
    marketpool->update(market);
136

    
137
    market->unlock();
138

    
139
    std::vector<SingleAttribute *> apps;
140
    std::string err;
141

    
142
    int num = monitor_data.get("APP", apps);
143

    
144
    for (int i=0; i< num ; i++)
145
    {
146
        int rc = apppool->import(apps[i]->value(), id, name, err);
147

    
148
        if ( rc == -1 )
149
        {
150
            NebulaLog::log("MKP", Log::ERROR, "Error importing app: " + err);
151
        }
152
        else if ( rc >= 0 ) //-2 means app already imported
153
        {
154
            MarketPlace * market = marketpool->get(id, true);
155

    
156
            if ( market != 0 )
157
            {
158
                market->add_marketapp(rc);
159

    
160
                marketpool->update(market);
161

    
162
                market->unlock();
163
            }
164
        }
165
    }
166
    MarketPlaceApp *mp_app = nullptr;
167
    std::string error;
168
    std::string source;
169
    int rc_del;
170
    market = marketpool->get(id, true);
171
    set<int> apps_mp = market->get_marketapp_ids();
172
    market->unlock();
173

    
174
    for (set<int>::iterator i = apps_mp.begin(); i != apps_mp.end(); i++) {
175
        mp_app = apppool->get(*i, true);
176
        if ( mp_app != 0 )
177
        {
178
            if(apppool->test_map_check(mp_app->get_name())){ //delete app
179
                market = marketpool->get(id, true);
180

    
181
                source = mp_app->get_source();
182
                rc_del = apppool->drop(mp_app, error);
183

    
184
                market->del_marketapp(*i);
185
                marketpool->update(market);
186

    
187
                market->unlock();
188
                if ( rc_del < 0 )
189
                {
190
                    oss << " Error removing app from DB: " << error
191
                        << ". Remove app manually, source is: " << source;
192
                }
193
            }
194
        }
195
        mp_app->unlock();
196
    }
197

    
198
    oss << "Marketplace " << name << " (" << id << ") successfully monitored.";
199

    
200
    NebulaLog::log("MKP", Log::DEBUG, oss);
201

    
202
    return;
203
}
204

    
205
/* -------------------------------------------------------------------------- */
206
/* Helper functions for failure and error conditions                          */
207
/* -------------------------------------------------------------------------- */
208

    
209
static void set_failure_response(
210
        std::istringstream * is,
211
        PoolObjectSQL *     obj,
212
        const std::string&  msg)
213
{
214
    std::ostringstream oss;
215
    std::string        info;
216

    
217
    oss << msg;
218

    
219
    getline(*is, info);
220

    
221
    if (!info.empty() && (info[0] != '-'))
222
    {
223
        oss << ": " << info;
224
    }
225

    
226
    if (obj != 0)
227
    {
228
        obj->set_template_error_message(oss.str());
229
    }
230

    
231
    NebulaLog::log("MKP", Log::ERROR, oss);
232
}
233

    
234
static void app_failure_action(
235
        std::istringstream * is,
236
        MarketPlaceAppPool * apppool,
237
        int                  id,
238
        const std::string&   msg)
239
{
240
    MarketPlaceApp * app = apppool->get(id, true);
241

    
242
    if (app == 0)
243
    {
244
        return;
245
    }
246

    
247
    if ( is == 0)
248
    {
249
        app->set_template_error_message(msg);
250

    
251
        NebulaLog::log("MKP", Log::ERROR, msg);
252
    }
253
    else
254
    {
255
        set_failure_response(is, app, msg);
256
    }
257

    
258
    app->set_state(MarketPlaceApp::ERROR);
259

    
260
    apppool->update(app);
261

    
262
    app->unlock();
263
}
264

    
265
/* -------------------------------------------------------------------------- */
266
/* -------------------------------------------------------------------------- */
267

    
268
static int import_action(
269
        std::istringstream&  is,
270
        MarketPlaceAppPool * apppool,
271
        MarketPlaceManager * marketm,
272
        int                  id,
273
        const std::string&   result)
274
{
275
    bool rc;
276
    int  rci;
277

    
278
    std::string   error;
279
    std::string   info64;
280
    std::string * info;
281

    
282
    MarketPlaceApp *       app;
283
    MarketPlaceAppTemplate tmpl;
284

    
285
    std::string source;
286
    std::string checksum;
287
    std::string format;
288
    long long   size_mb;
289

    
290
    marketm->release_app_resources(id);
291

    
292
    if ( result == "FAILURE" )
293
    {
294
        app_failure_action(&is, apppool, id, "Error importing app into marketplace");
295
        return -1;
296
    }
297

    
298
    getline(is, info64);
299

    
300
    if (is.fail())
301
    {
302
        goto error_parse;
303
    }
304

    
305
    info = one_util::base64_decode(info64);
306

    
307
    if ( info == 0 )
308
    {
309
        goto error_decode64;
310
    }
311

    
312
    rci = tmpl.parse_str_or_xml(*info, error);
313

    
314
    delete info;
315

    
316
    if ( rci != 0 )
317
    {
318
        goto error_parse_template;
319
    }
320

    
321
    tmpl.get("SOURCE", source);
322
    tmpl.get("MD5", checksum);
323
    tmpl.get("FORMAT", format);
324
    rc = tmpl.get("SIZE", size_mb);
325

    
326
    if ( source.empty() || checksum.empty() || format.empty() || rc == false )
327
    {
328
        goto error_attributes;
329
    }
330

    
331
    app = apppool->get(id, true);
332

    
333
    if (app == 0)
334
    {
335
        goto error_app;
336
    }
337

    
338
    app->set_source(source);
339
    app->set_md5(checksum);
340
    app->set_size(size_mb);
341
    app->set_format(format);
342

    
343
    app->set_state(MarketPlaceApp::READY);
344

    
345
    apppool->update(app);
346

    
347
    app->unlock();
348

    
349
    NebulaLog::log("MKP", Log::INFO, "Marketplace app successfully imported");
350

    
351
    return 0;
352

    
353
error_parse:
354
    app_failure_action(0, apppool, id,
355
        "Error importing app into marketplace. Wrong message from driver.");
356
    return -1;
357

    
358
error_decode64:
359
    app_failure_action(0, apppool, id,
360
        "Error importing app into marketplace. Bad base64 encoding.");
361
    return -1;
362

    
363
error_parse_template:
364
    app_failure_action(0, apppool, id,
365
        "Error importing app into marketplace. Parse error: " + error);
366
    return -1;
367

    
368
error_attributes:
369
    app_failure_action(0, apppool, id,
370
        "Error importing app into marketplace. Missing app attributes.");
371
    return -1;
372

    
373
error_app:
374
    NebulaLog::log("MKP", Log::ERROR, "Marketplace app successfully imported "
375
        "but it no longer exists. You may need to manually remove: " + source);
376
    return -1;
377
}
378

    
379
/* -------------------------------------------------------------------------- */
380
/* -------------------------------------------------------------------------- */
381

    
382
static int delete_action(
383
        std::istringstream&  is,
384
        MarketPlaceAppPool * apppool,
385
        MarketPlaceManager * marketm,
386
        int                  id,
387
        const std::string&   result)
388
{
389
    int rc;
390

    
391
    std::string source;
392
    std::string error;
393

    
394
    std::ostringstream eoss("Error removing app from marketplace", std::ios::ate);
395

    
396
    MarketPlaceApp * app = apppool->get(id, true);
397

    
398
    if ( app == 0 )
399
    {
400
        return -1;
401
    }
402

    
403
    source = app->get_source();
404

    
405
    rc = apppool->drop(app, error);
406

    
407
    app->unlock();
408

    
409
    if ( result == "FAILURE" )
410
    {
411
        std::string info;
412

    
413
        getline(is, info);
414

    
415
        if (!info.empty() && (info[0] != '-'))
416
        {
417
            eoss << ": " << info;
418
        }
419

    
420
        eoss << ".";
421
    }
422

    
423
    if ( rc < 0 )
424
    {
425
        eoss << " Error removing app from DB: " << error
426
             << ". Remove app manually, source is: " << source;
427
    }
428

    
429
    if ( rc < 0 || result == "FAILURE" )
430
    {
431
        NebulaLog::log("MKP", Log::ERROR, eoss.str());
432
    }
433
    else
434
    {
435
        NebulaLog::log("MKP",Log::INFO,"Marketplace app successfully removed.");
436
    }
437

    
438
    return rc;
439
}
440

    
441
/* -------------------------------------------------------------------------- */
442
/* -------------------------------------------------------------------------- */
443

    
444
void MarketPlaceManagerDriver::protocol(const string& message) const
445
{
446
    std::istringstream is(message);
447
    std::ostringstream oss;
448

    
449
    std::string action;
450
    std::string result;
451
    std::string info;
452

    
453
    int id;
454

    
455
    oss << "Message received: " << message;
456
    NebulaLog::log("MKP", Log::DDEBUG, oss);
457

    
458
    // --------------------- Parse the driver message --------------------------
459

    
460
    if ( is.good() )
461
        is >> action >> ws;
462
    else
463
        return;
464

    
465
    if ( is.good() )
466
        is >> result >> ws;
467
    else
468
        return;
469

    
470
    if ( is.good() )
471
    {
472
        is >> id >> ws;
473

    
474
        if ( is.fail() )
475
        {
476
            if ( action == "LOG" )
477
            {
478
                is.clear();
479
                getline(is,info);
480

    
481
                NebulaLog::log("MKP",log_type(result[0]), info.c_str());
482
            }
483

    
484
            return;
485
        }
486
    }
487
    else
488
        return;
489

    
490
    if (action == "IMPORT")
491
    {
492
        import_action(is, apppool, marketm, id, result);
493
    }
494
    else if (action == "DELETE")
495
    {
496
        delete_action(is, apppool, marketm, id, result);
497
    }
498
    else if (action == "MONITOR")
499
    {
500
        monitor_action(is, marketpool, apppool, marketm, id, result);
501
    }
502
    else if (action == "LOG")
503
    {
504
        getline(is,info);
505
        NebulaLog::log("MKP", log_type(result[0]), info.c_str());
506
    }
507

    
508
    return;
509
}
510

    
511
/* -------------------------------------------------------------------------- */
512
/* -------------------------------------------------------------------------- */
513

    
514
void MarketPlaceManagerDriver::recover()
515
{
516
    NebulaLog::log("MKP",Log::INFO,"Recovering MarketPlace drivers");
517
}
518