softwarecontainer  0.18.0-739e8d7 2017-05-04
servicemanifestfileloader.cpp
1 /*
2  * Copyright (C) 2017 Pelagicore AB
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
9  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
11  * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
12  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
13  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
14  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15  * SOFTWARE.
16  *
17  * For further information see LICENSE
18  */
19 
20 #include "servicemanifestfileloader.h"
21 #include <glibmm/fileutils.h>
22 
23 namespace softwarecontainer {
24 
25 ServiceManifestFileLoader::ServiceManifestFileLoader(const std::string &source) :
26  ServiceManifestLoader(source)
27 {
28 }
29 
31 {
32  std::string errorMessage;
33 
34  if (m_source.empty()) {
35  //File path is empty, this is ok
36  log_debug() << "Path to service manifests is empty";
37  } else if (m_source.compare("/") == 0) {
38  errorMessage = "Searching for configuration files from root dir not allowed";
39  log_error() << errorMessage;
40  throw ServiceManifestPathError(errorMessage);
41  } else if (isDirectory(m_source)) {
42  log_debug() << "Path to service manifests is a directory";
43  loadServiceManifestDir();
44  } else if (isFile(m_source)) {
45  log_debug() << "Path to service manifest is a file";
46  if (isJsonFile(m_source)) {
47  loadServiceManifestFile(m_source);
48  } else {
49  errorMessage = "Path to service manifest is not a json file";
50  log_debug() << errorMessage;
51  throw ServiceManifestPathError(errorMessage);
52  }
53  } else {
54  errorMessage = "The path to the service manifest(s) is not a directory or file: \""
55  + m_source + "\"";
56  log_error() << errorMessage;
57  throw ServiceManifestPathError(errorMessage);
58  }
59  return m_content;
60 }
61 
62 void ServiceManifestFileLoader::loadServiceManifestDir()
63 {
64  std::string errorMessage;
65 
66  if (isDirectoryEmpty(m_source)) {
67  log_warning() << "The service manifest directory is empty: " << m_source;
68  return;
69  }
70 
71  std::vector<std::string> files = fileList();
72 
73  if (files.empty()) {
74  log_info() << "No configuration files found: " << m_source;
75  return;
76  }
77 
78  for (std::string file : files) {
79  std::string filePath = buildPath(m_source, file);
80  loadServiceManifestFile(filePath);
81  }
82 }
83 
84 void ServiceManifestFileLoader::loadServiceManifestFile(const std::string &filePath)
85 {
86  std::string errorMessage;
87 
88  log_debug() << "Loading service manifest file: " << filePath;
89 
90  json_error_t error;
91  json_t *fileroot = json_load_file(filePath.c_str(), 0, &error);
92 
93  if (nullptr == fileroot) {
94  errorMessage = "Could not parse the service manifest: "
95  + filePath + ":" + std::to_string(error.line) + " : " + std::string(error.text);
96  log_error() << errorMessage;
97  throw ServiceManifestParseError(errorMessage);
98  } else if (!json_is_object(fileroot)) {
99  errorMessage = "The service manifest root is not a json object: "
100  + filePath + ":" + std::to_string(error.line) + " : " + std::string(error.text);
101  log_error() << errorMessage;
102  throw ServiceManifestParseError(errorMessage);
103  }
104 
105  log_debug() << "Loaded service manifest: " << filePath;
106 
107  m_content.push_back(fileroot);
108 }
109 
110 
111 /****************
112  * Help functions
113  */
114 
115 std::vector<std::string> ServiceManifestFileLoader::fileList()
116 {
117  std::vector<std::string> files;
118  try {
119  Glib::Dir dir(m_source);
120 
121  std::string filename;
122  while ((filename = dir.read_name()) != "") {
123  if (isJsonFile(filename)) {
124  files.push_back(filename);
125  }
126  }
127  dir.close();
128  } catch (Glib::FileError &err) {
129  log_error() << "Could not read files in directory: " << m_source;
130  }
131 
132  return files;
133 }
134 
135 bool ServiceManifestFileLoader::isJsonFile(const std::string &filename)
136 {
137 
138  if (filename.size() <= 5) {
139  // Even if the file name is ".json" we will not classify this as a json file
140  return false;
141  }
142  return filename.substr(filename.size()-5) == ".json";
143 }
144 
145 } // namespace softwarecontainer
An error occured in ConfigStore relating to the path to the Service Manifest(s)
bool isDirectoryEmpty(const std::string &path)
isDirectoryEmpty Check if path is empty
An error occured in ConfigStore when parsing a Service Manifest.
virtual std::vector< json_t * > loadContent() override
Loads the json content from the Service Manifest(s)
bool isDirectory(const std::string &path)
isDirectory Check if path is a directory
bool isFile(const std::string &path)
isFile Check if path is a file
Developers guide to adding a config item: