1 /*
2 // Copyright (c) 2018 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain 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 #include <logging.h>
17 
18 #include <error_messages.hpp>
19 
20 namespace redfish
21 {
22 
23 namespace messages
24 {
25 
26 static void addMessageToErrorJson(nlohmann::json& target,
27                                   const nlohmann::json& message)
28 {
29     auto& error = target["error"];
30 
31     // If this is the first error message, fill in the information from the
32     // first error message to the top level struct
33     if (!error.is_object())
34     {
35         auto messageIdIterator = message.find("MessageId");
36         if (messageIdIterator == message.end())
37         {
38             BMCWEB_LOG_CRITICAL
39                 << "Attempt to add error message without MessageId";
40             return;
41         }
42 
43         auto messageFieldIterator = message.find("Message");
44         if (messageFieldIterator == message.end())
45         {
46             BMCWEB_LOG_CRITICAL
47                 << "Attempt to add error message without Message";
48             return;
49         }
50         error = {{"code", *messageIdIterator},
51                  {"message", *messageFieldIterator}};
52     }
53     else
54     {
55         // More than 1 error occurred, so the message has to be generic
56         error["code"] = std::string(messageVersionPrefix) + "GeneralError";
57         error["message"] = "A general error has occurred. See Resolution for "
58                            "information on how to resolve the error.";
59     }
60 
61     // This check could technically be done in in the default construction
62     // branch above, but because we need the pointer to the extended info field
63     // anyway, it's more efficient to do it here.
64     auto& extendedInfo = error[messages::messageAnnotation];
65     if (!extendedInfo.is_array())
66     {
67         extendedInfo = nlohmann::json::array();
68     }
69 
70     extendedInfo.push_back(message);
71 }
72 
73 static void addMessageToJsonRoot(nlohmann::json& target,
74                                  const nlohmann::json& message)
75 {
76     if (!target[messages::messageAnnotation].is_array())
77     {
78         // Force object to be an array
79         target[messages::messageAnnotation] = nlohmann::json::array();
80     }
81 
82     target[messages::messageAnnotation].push_back(message);
83 }
84 
85 static void addMessageToJson(nlohmann::json& target,
86                              const nlohmann::json& message,
87                              const std::string& fieldPath)
88 {
89     std::string extendedInfo(fieldPath + messages::messageAnnotation);
90 
91     if (!target[extendedInfo].is_array())
92     {
93         // Force object to be an array
94         target[extendedInfo] = nlohmann::json::array();
95     }
96 
97     // Object exists and it is an array so we can just push in the message
98     target[extendedInfo].push_back(message);
99 }
100 
101 /**
102  * @internal
103  * @brief Formats ResourceInUse message into JSON
104  *
105  * See header file for more information
106  * @endinternal
107  */
108 nlohmann::json resourceInUse(void)
109 {
110     return nlohmann::json{
111         {"@odata.type", "#Message.v1_0_0.Message"},
112         {"MessageId", "Base.1.4.0.ResourceInUse"},
113         {"Message", "The change to the requested resource failed because "
114                     "the resource is in use or in transition."},
115         {"MessageArgs", nlohmann::json::array()},
116         {"Severity", "Warning"},
117         {"Resolution", "Remove the condition and resubmit the request if "
118                        "the operation failed."}};
119 }
120 
121 void resourceInUse(crow::Response& res)
122 {
123     res.result(boost::beast::http::status::service_unavailable);
124     addMessageToErrorJson(res.jsonValue, resourceInUse());
125 }
126 
127 /**
128  * @internal
129  * @brief Formats MalformedJSON message into JSON
130  *
131  * See header file for more information
132  * @endinternal
133  */
134 nlohmann::json malformedJSON(void)
135 {
136     return nlohmann::json{
137         {"@odata.type", "#Message.v1_0_0.Message"},
138         {"MessageId", "Base.1.4.0.MalformedJSON"},
139         {"Message", "The request body submitted was malformed JSON and "
140                     "could not be parsed by the receiving service."},
141         {"MessageArgs", nlohmann::json::array()},
142         {"Severity", "Critical"},
143         {"Resolution", "Ensure that the request body is valid JSON and "
144                        "resubmit the request."}};
145 }
146 
147 void malformedJSON(crow::Response& res)
148 {
149     res.result(boost::beast::http::status::bad_request);
150     addMessageToErrorJson(res.jsonValue, malformedJSON());
151 }
152 
153 /**
154  * @internal
155  * @brief Formats ResourceMissingAtURI message into JSON
156  *
157  * See header file for more information
158  * @endinternal
159  */
160 nlohmann::json resourceMissingAtURI(const std::string& arg1)
161 {
162     return nlohmann::json{
163         {"@odata.type", "#Message.v1_0_0.Message"},
164         {"MessageId", "Base.1.4.0.ResourceMissingAtURI"},
165         {"Message", "The resource at the URI " + arg1 + " was not found."},
166         {"MessageArgs", {arg1}},
167         {"Severity", "Critical"},
168         {"Resolution", "Place a valid resource at the URI or correct the "
169                        "URI and resubmit the request."}};
170 }
171 
172 void resourceMissingAtURI(crow::Response& res, const std::string& arg1)
173 {
174     res.result(boost::beast::http::status::bad_request);
175     addMessageToErrorJson(res.jsonValue, resourceMissingAtURI(arg1));
176 }
177 
178 /**
179  * @internal
180  * @brief Formats ActionParameterValueFormatError message into JSON
181  *
182  * See header file for more information
183  * @endinternal
184  */
185 nlohmann::json actionParameterValueFormatError(const std::string& arg1,
186                                                const std::string& arg2,
187                                                const std::string& arg3)
188 {
189     return nlohmann::json{
190         {"@odata.type", "#Message.v1_0_0.Message"},
191         {"MessageId", "Base.1.4.0.ActionParameterValueFormatError"},
192         {"Message",
193          "The value " + arg1 + " for the parameter " + arg2 +
194              " in the action " + arg3 +
195              " is of a different format than the parameter can accept."},
196         {"MessageArgs", {arg1, arg2, arg3}},
197         {"Severity", "Warning"},
198         {"Resolution",
199          "Correct the value for the parameter in the request body and "
200          "resubmit the request if the operation failed."}};
201 }
202 
203 void actionParameterValueFormatError(crow::Response& res,
204                                      const std::string& arg1,
205                                      const std::string& arg2,
206                                      const std::string& arg3)
207 {
208     res.result(boost::beast::http::status::bad_request);
209     addMessageToErrorJson(res.jsonValue,
210                           actionParameterValueFormatError(arg1, arg2, arg3));
211 }
212 
213 /**
214  * @internal
215  * @brief Formats InternalError message into JSON
216  *
217  * See header file for more information
218  * @endinternal
219  */
220 nlohmann::json internalError(void)
221 {
222     return nlohmann::json{
223         {"@odata.type", "#Message.v1_0_0.Message"},
224         {"MessageId", "Base.1.4.0.InternalError"},
225         {"Message", "The request failed due to an internal service error.  "
226                     "The service is still operational."},
227         {"MessageArgs", nlohmann::json::array()},
228         {"Severity", "Critical"},
229         {"Resolution", "Resubmit the request.  If the problem persists, "
230                        "consider resetting the service."}};
231 }
232 
233 void internalError(crow::Response& res)
234 {
235     res.result(boost::beast::http::status::internal_server_error);
236     addMessageToErrorJson(res.jsonValue, internalError());
237 }
238 
239 /**
240  * @internal
241  * @brief Formats UnrecognizedRequestBody message into JSON
242  *
243  * See header file for more information
244  * @endinternal
245  */
246 nlohmann::json unrecognizedRequestBody(void)
247 {
248     return nlohmann::json{
249         {"@odata.type", "#Message.v1_0_0.Message"},
250         {"MessageId", "Base.1.4.0.UnrecognizedRequestBody"},
251         {"Message", "The service detected a malformed request body that it "
252                     "was unable to interpret."},
253         {"MessageArgs", nlohmann::json::array()},
254         {"Severity", "Warning"},
255         {"Resolution", "Correct the request body and resubmit the request "
256                        "if it failed."}};
257 }
258 
259 void unrecognizedRequestBody(crow::Response& res)
260 {
261     res.result(boost::beast::http::status::bad_request);
262     addMessageToErrorJson(res.jsonValue, unrecognizedRequestBody());
263 }
264 
265 /**
266  * @internal
267  * @brief Formats ResourceAtUriUnauthorized message into JSON
268  *
269  * See header file for more information
270  * @endinternal
271  */
272 nlohmann::json resourceAtUriUnauthorized(const std::string& arg1,
273                                          const std::string& arg2)
274 {
275     return nlohmann::json{
276         {"@odata.type", "#Message.v1_0_0.Message"},
277         {"MessageId", "Base.1.4.0.ResourceAtUriUnauthorized"},
278         {"Message", "While accessing the resource at " + arg1 +
279                         ", the service received an authorization error " +
280                         arg2 + "."},
281         {"MessageArgs", {arg1, arg2}},
282         {"Severity", "Critical"},
283         {"Resolution", "Ensure that the appropriate access is provided for "
284                        "the service in order for it to access the URI."}};
285 }
286 
287 void resourceAtUriUnauthorized(crow::Response& res, const std::string& arg1,
288                                const std::string& arg2)
289 {
290     res.result(boost::beast::http::status::unauthorized);
291     addMessageToErrorJson(res.jsonValue, resourceAtUriUnauthorized(arg1, arg2));
292 }
293 
294 /**
295  * @internal
296  * @brief Formats ActionParameterUnknown message into JSON
297  *
298  * See header file for more information
299  * @endinternal
300  */
301 nlohmann::json actionParameterUnknown(const std::string& arg1,
302                                       const std::string& arg2)
303 {
304     return nlohmann::json{
305         {"@odata.type", "#Message.v1_0_0.Message"},
306         {"MessageId", "Base.1.4.0.ActionParameterUnknown"},
307         {"Message", "The action " + arg1 +
308                         " was submitted with the invalid parameter " + arg2 +
309                         "."},
310         {"MessageArgs", {arg1, arg2}},
311         {"Severity", "Warning"},
312         {"Resolution", "Correct the invalid parameter and resubmit the "
313                        "request if the operation failed."}};
314 }
315 
316 void actionParameterUnknown(crow::Response& res, const std::string& arg1,
317                             const std::string& arg2)
318 {
319     res.result(boost::beast::http::status::bad_request);
320     addMessageToErrorJson(res.jsonValue, actionParameterUnknown(arg1, arg2));
321 }
322 
323 /**
324  * @internal
325  * @brief Formats ResourceCannotBeDeleted message into JSON
326  *
327  * See header file for more information
328  * @endinternal
329  */
330 nlohmann::json resourceCannotBeDeleted(void)
331 {
332     return nlohmann::json{
333         {"@odata.type", "#Message.v1_0_0.Message"},
334         {"MessageId", "Base.1.4.0.ResourceCannotBeDeleted"},
335         {"Message", "The delete request failed because the resource "
336                     "requested cannot be deleted."},
337         {"MessageArgs", nlohmann::json::array()},
338         {"Severity", "Critical"},
339         {"Resolution", "Do not attempt to delete a non-deletable resource."}};
340 }
341 
342 void resourceCannotBeDeleted(crow::Response& res)
343 {
344     res.result(boost::beast::http::status::forbidden);
345     addMessageToErrorJson(res.jsonValue, resourceCannotBeDeleted());
346 }
347 
348 /**
349  * @internal
350  * @brief Formats PropertyDuplicate message into JSON
351  *
352  * See header file for more information
353  * @endinternal
354  */
355 nlohmann::json propertyDuplicate(const std::string& arg1)
356 {
357     return nlohmann::json{
358         {"@odata.type", "#Message.v1_0_0.Message"},
359         {"MessageId", "Base.1.4.0.PropertyDuplicate"},
360         {"Message", "The property " + arg1 + " was duplicated in the request."},
361         {"MessageArgs", {arg1}},
362         {"Severity", "Warning"},
363         {"Resolution",
364          "Remove the duplicate property from the request body and resubmit "
365          "the request if the operation failed."}};
366 }
367 
368 void propertyDuplicate(crow::Response& res, const std::string& arg1)
369 {
370     res.result(boost::beast::http::status::bad_request);
371     addMessageToJson(res.jsonValue, propertyDuplicate(arg1), arg1);
372 }
373 
374 /**
375  * @internal
376  * @brief Formats ServiceTemporarilyUnavailable message into JSON
377  *
378  * See header file for more information
379  * @endinternal
380  */
381 nlohmann::json serviceTemporarilyUnavailable(const std::string& arg1)
382 {
383     return nlohmann::json{
384         {"@odata.type", "#Message.v1_0_0.Message"},
385         {"MessageId", "Base.1.4.0.ServiceTemporarilyUnavailable"},
386         {"Message", "The service is temporarily unavailable.  Retry in " +
387                         arg1 + " seconds."},
388         {"MessageArgs", {arg1}},
389         {"Severity", "Critical"},
390         {"Resolution", "Wait for the indicated retry duration and retry "
391                        "the operation."}};
392 }
393 
394 void serviceTemporarilyUnavailable(crow::Response& res, const std::string& arg1)
395 {
396     res.addHeader("Retry-After", arg1);
397     res.result(boost::beast::http::status::service_unavailable);
398     addMessageToErrorJson(res.jsonValue, serviceTemporarilyUnavailable(arg1));
399 }
400 
401 /**
402  * @internal
403  * @brief Formats ResourceAlreadyExists message into JSON
404  *
405  * See header file for more information
406  * @endinternal
407  */
408 nlohmann::json resourceAlreadyExists(const std::string& arg1,
409                                      const std::string& arg2,
410                                      const std::string& arg3)
411 {
412     return nlohmann::json{
413         {"@odata.type", "#Message.v1_0_0.Message"},
414         {"MessageId", "Base.1.4.0.ResourceAlreadyExists"},
415         {"Message", "The requested resource of type " + arg1 +
416                         " with the property " + arg2 + " with the value " +
417                         arg3 + " already exists."},
418         {"MessageArgs", {arg1, arg2, arg3}},
419         {"Severity", "Critical"},
420         {"Resolution", "Do not repeat the create operation as the resource "
421                        "has already been created."}};
422 }
423 
424 void resourceAlreadyExists(crow::Response& res, const std::string& arg1,
425                            const std::string& arg2, const std::string& arg3)
426 {
427     res.result(boost::beast::http::status::bad_request);
428     addMessageToJson(res.jsonValue, resourceAlreadyExists(arg1, arg2, arg3),
429                      arg2);
430 }
431 
432 /**
433  * @internal
434  * @brief Formats AccountForSessionNoLongerExists message into JSON
435  *
436  * See header file for more information
437  * @endinternal
438  */
439 nlohmann::json accountForSessionNoLongerExists(void)
440 {
441     return nlohmann::json{
442         {"@odata.type", "#Message.v1_0_0.Message"},
443         {"MessageId", "Base.1.4.0.AccountForSessionNoLongerExists"},
444         {"Message", "The account for the current session has been removed, "
445                     "thus the current session has been removed as well."},
446         {"MessageArgs", nlohmann::json::array()},
447         {"Severity", "OK"},
448         {"Resolution", "Attempt to connect with a valid account."}};
449 }
450 
451 void accountForSessionNoLongerExists(crow::Response& res)
452 {
453     res.result(boost::beast::http::status::forbidden);
454     addMessageToErrorJson(res.jsonValue, accountForSessionNoLongerExists());
455 }
456 
457 /**
458  * @internal
459  * @brief Formats CreateFailedMissingReqProperties message into JSON
460  *
461  * See header file for more information
462  * @endinternal
463  */
464 nlohmann::json createFailedMissingReqProperties(const std::string& arg1)
465 {
466     return nlohmann::json{
467         {"@odata.type", "#Message.v1_0_0.Message"},
468         {"MessageId", "Base.1.4.0.CreateFailedMissingReqProperties"},
469         {"Message",
470          "The create operation failed because the required property " + arg1 +
471              " was missing from the request."},
472         {"MessageArgs", {arg1}},
473         {"Severity", "Critical"},
474         {"Resolution",
475          "Correct the body to include the required property with a valid "
476          "value and resubmit the request if the operation failed."}};
477 }
478 
479 void createFailedMissingReqProperties(crow::Response& res,
480                                       const std::string& arg1)
481 {
482     res.result(boost::beast::http::status::bad_request);
483     addMessageToJson(res.jsonValue, createFailedMissingReqProperties(arg1),
484                      arg1);
485 }
486 
487 /**
488  * @internal
489  * @brief Formats PropertyValueFormatError message into JSON for the specified
490  * property
491  *
492  * See header file for more information
493  * @endinternal
494  */
495 nlohmann::json propertyValueFormatError(const std::string& arg1,
496                                         const std::string& arg2)
497 {
498     return nlohmann::json{
499         {"@odata.type", "#Message.v1_0_0.Message"},
500         {"MessageId", "Base.1.4.0.PropertyValueFormatError"},
501         {"Message",
502          "The value " + arg1 + " for the property " + arg2 +
503              " is of a different format than the property can accept."},
504         {"MessageArgs", {arg1, arg2}},
505         {"Severity", "Warning"},
506         {"Resolution",
507          "Correct the value for the property in the request body and "
508          "resubmit the request if the operation failed."}};
509 }
510 
511 void propertyValueFormatError(crow::Response& res, const std::string& arg1,
512                               const std::string& arg2)
513 {
514     res.result(boost::beast::http::status::bad_request);
515     addMessageToJson(res.jsonValue, propertyValueFormatError(arg1, arg2), arg2);
516 }
517 
518 /**
519  * @internal
520  * @brief Formats PropertyValueNotInList message into JSON for the specified
521  * property
522  *
523  * See header file for more information
524  * @endinternal
525  */
526 nlohmann::json propertyValueNotInList(const std::string& arg1,
527                                       const std::string& arg2)
528 {
529     return nlohmann::json{
530         {"@odata.type", "#Message.v1_0_0.Message"},
531         {"MessageId", "Base.1.4.0.PropertyValueNotInList"},
532         {"Message", "The value " + arg1 + " for the property " + arg2 +
533                         " is not in the list of acceptable values."},
534         {"MessageArgs", {arg1, arg2}},
535         {"Severity", "Warning"},
536         {"Resolution", "Choose a value from the enumeration list that "
537                        "the implementation "
538                        "can support and resubmit the request if the "
539                        "operation failed."}};
540 }
541 
542 void propertyValueNotInList(crow::Response& res, const std::string& arg1,
543                             const std::string& arg2)
544 {
545     res.result(boost::beast::http::status::bad_request);
546     addMessageToJson(res.jsonValue, propertyValueNotInList(arg1, arg2), arg2);
547 }
548 
549 /**
550  * @internal
551  * @brief Formats ResourceAtUriInUnknownFormat message into JSON
552  *
553  * See header file for more information
554  * @endinternal
555  */
556 nlohmann::json resourceAtUriInUnknownFormat(const std::string& arg1)
557 {
558     return nlohmann::json{
559         {"@odata.type", "#Message.v1_0_0.Message"},
560         {"MessageId", "Base.1.4.0.ResourceAtUriInUnknownFormat"},
561         {"Message", "The resource at " + arg1 +
562                         " is in a format not recognized by the service."},
563         {"MessageArgs", {arg1}},
564         {"Severity", "Critical"},
565         {"Resolution", "Place an image or resource or file that is "
566                        "recognized by the service at the URI."}};
567 }
568 
569 void resourceAtUriInUnknownFormat(crow::Response& res, const std::string& arg1)
570 {
571     res.result(boost::beast::http::status::bad_request);
572     addMessageToErrorJson(res.jsonValue, resourceAtUriInUnknownFormat(arg1));
573 }
574 
575 /**
576  * @internal
577  * @brief Formats ServiceInUnknownState message into JSON
578  *
579  * See header file for more information
580  * @endinternal
581  */
582 nlohmann::json serviceInUnknownState(void)
583 {
584     return nlohmann::json{
585         {"@odata.type", "#Message.v1_0_0.Message"},
586         {"MessageId", "Base.1.4.0.ServiceInUnknownState"},
587         {"Message",
588          "The operation failed because the service is in an unknown state "
589          "and can no longer take incoming requests."},
590         {"MessageArgs", nlohmann::json::array()},
591         {"Severity", "Critical"},
592         {"Resolution", "Restart the service and resubmit the request if "
593                        "the operation failed."}};
594 }
595 
596 void serviceInUnknownState(crow::Response& res)
597 {
598     res.result(boost::beast::http::status::service_unavailable);
599     addMessageToErrorJson(res.jsonValue, serviceInUnknownState());
600 }
601 
602 /**
603  * @internal
604  * @brief Formats EventSubscriptionLimitExceeded message into JSON
605  *
606  * See header file for more information
607  * @endinternal
608  */
609 nlohmann::json eventSubscriptionLimitExceeded(void)
610 {
611     return nlohmann::json{
612         {"@odata.type", "#Message.v1_0_0.Message"},
613         {"MessageId", "Base.1.4.0.EventSubscriptionLimitExceeded"},
614         {"Message",
615          "The event subscription failed due to the number of simultaneous "
616          "subscriptions exceeding the limit of the implementation."},
617         {"MessageArgs", nlohmann::json::array()},
618         {"Severity", "Critical"},
619         {"Resolution",
620          "Reduce the number of other subscriptions before trying to "
621          "establish the event subscription or increase the limit of "
622          "simultaneous subscriptions (if supported)."}};
623 }
624 
625 void eventSubscriptionLimitExceeded(crow::Response& res)
626 {
627     res.result(boost::beast::http::status::forbidden);
628     addMessageToErrorJson(res.jsonValue, eventSubscriptionLimitExceeded());
629 }
630 
631 /**
632  * @internal
633  * @brief Formats ActionParameterMissing message into JSON
634  *
635  * See header file for more information
636  * @endinternal
637  */
638 nlohmann::json actionParameterMissing(const std::string& arg1,
639                                       const std::string& arg2)
640 {
641     return nlohmann::json{
642         {"@odata.type", "#Message.v1_0_0.Message"},
643         {"MessageId", "Base.1.4.0.ActionParameterMissing"},
644         {"Message", "The action " + arg1 + " requires the parameter " + arg2 +
645                         " to be present in the request body."},
646         {"MessageArgs", {arg1, arg2}},
647         {"Severity", "Critical"},
648         {"Resolution",
649          "Supply the action with the required parameter in the request "
650          "body when the request is resubmitted."}};
651 }
652 
653 void actionParameterMissing(crow::Response& res, const std::string& arg1,
654                             const std::string& arg2)
655 {
656     res.result(boost::beast::http::status::bad_request);
657     addMessageToErrorJson(res.jsonValue, actionParameterMissing(arg1, arg2));
658 }
659 
660 /**
661  * @internal
662  * @brief Formats StringValueTooLong message into JSON
663  *
664  * See header file for more information
665  * @endinternal
666  */
667 nlohmann::json stringValueTooLong(const std::string& arg1, const int& arg2)
668 {
669     return nlohmann::json{
670         {"@odata.type", "#Message.v1_0_0.Message"},
671         {"MessageId", "Base.1.4.0.StringValueTooLong"},
672         {"Message", "The string " + arg1 + " exceeds the length limit " +
673                         std::to_string(arg2) + "."},
674         {"MessageArgs", {arg1, std::to_string(arg2)}},
675         {"Severity", "Warning"},
676         {"Resolution",
677          "Resubmit the request with an appropriate string length."}};
678 }
679 
680 void stringValueTooLong(crow::Response& res, const std::string& arg1,
681                         const int& arg2)
682 {
683     res.result(boost::beast::http::status::bad_request);
684     addMessageToErrorJson(res.jsonValue, stringValueTooLong(arg1, arg2));
685 }
686 
687 /**
688  * @internal
689  * @brief Formats SessionTerminated message into JSON
690  *
691  * See header file for more information
692  * @endinternal
693  */
694 nlohmann::json sessionTerminated(void)
695 {
696     return nlohmann::json{
697         {"@odata.type", "#Message.v1_0_0.Message"},
698         {"MessageId", "Base.1.4.0.SessionTerminated"},
699         {"Message", "The session was successfully terminated."},
700         {"MessageArgs", nlohmann::json::array()},
701         {"Severity", "OK"},
702         {"Resolution", "No resolution is required."}};
703 }
704 
705 void sessionTerminated(crow::Response& res)
706 {
707     res.result(boost::beast::http::status::ok);
708     addMessageToJsonRoot(res.jsonValue, sessionTerminated());
709 }
710 
711 /**
712  * @internal
713  * @brief Formats ResourceTypeIncompatible message into JSON
714  *
715  * See header file for more information
716  * @endinternal
717  */
718 nlohmann::json resourceTypeIncompatible(const std::string& arg1,
719                                         const std::string& arg2)
720 {
721     return nlohmann::json{
722         {"@odata.type", "#Message.v1_0_0.Message"},
723         {"MessageId", "Base.1.4.0.ResourceTypeIncompatible"},
724         {"Message", "The @odata.type of the request body " + arg1 +
725                         " is incompatible with the @odata.type of the "
726                         "resource which is " +
727                         arg2 + "."},
728         {"MessageArgs", {arg1, arg2}},
729         {"Severity", "Critical"},
730         {"Resolution", "Resubmit the request with a payload compatible "
731                        "with the resource's schema."}};
732 }
733 
734 void resourceTypeIncompatible(crow::Response& res, const std::string& arg1,
735                               const std::string& arg2)
736 {
737     res.result(boost::beast::http::status::bad_request);
738     addMessageToErrorJson(res.jsonValue, resourceTypeIncompatible(arg1, arg2));
739 }
740 
741 /**
742  * @internal
743  * @brief Formats PropertyValueTypeError message into JSON for the specified
744  * property
745  *
746  * See header file for more information
747  * @endinternal
748  */
749 nlohmann::json propertyValueTypeError(const std::string& arg1,
750                                       const std::string& arg2)
751 {
752     return nlohmann::json{
753         {"@odata.type", "#Message.v1_0_0.Message"},
754         {"MessageId", "Base.1.4.0.PropertyValueTypeError"},
755         {"Message",
756          "The value " + arg1 + " for the property " + arg2 +
757              " is of a different type than the property can accept."},
758         {"MessageArgs", {arg1, arg2}},
759         {"Severity", "Warning"},
760         {"Resolution",
761          "Correct the value for the property in the request body and "
762          "resubmit the request if the operation failed."}};
763 }
764 
765 void propertyValueTypeError(crow::Response& res, const std::string& arg1,
766                             const std::string& arg2)
767 {
768     res.result(boost::beast::http::status::bad_request);
769     addMessageToJson(res.jsonValue, propertyValueTypeError(arg1, arg2), arg2);
770 }
771 
772 /**
773  * @internal
774  * @brief Formats ResourceNotFound message into JSON
775  *
776  * See header file for more information
777  * @endinternal
778  */
779 nlohmann::json resourceNotFound(const std::string& arg1,
780                                 const std::string& arg2)
781 {
782     return nlohmann::json{
783         {"@odata.type", "#Message.v1_0_0.Message"},
784         {"MessageId", "Base.1.4.0.ResourceNotFound"},
785         {"Message", "The requested resource of type " + arg1 + " named " +
786                         arg2 + " was not found."},
787         {"MessageArgs", {arg1, arg2}},
788         {"Severity", "Critical"},
789         {"Resolution",
790          "Provide a valid resource identifier and resubmit the request."}};
791 }
792 
793 void resourceNotFound(crow::Response& res, const std::string& arg1,
794                       const std::string& arg2)
795 {
796     res.result(boost::beast::http::status::not_found);
797     addMessageToErrorJson(res.jsonValue, resourceNotFound(arg1, arg2));
798 }
799 
800 /**
801  * @internal
802  * @brief Formats CouldNotEstablishConnection message into JSON
803  *
804  * See header file for more information
805  * @endinternal
806  */
807 nlohmann::json couldNotEstablishConnection(const std::string& arg1)
808 {
809     return nlohmann::json{
810         {"@odata.type", "#Message.v1_0_0.Message"},
811         {"MessageId", "Base.1.4.0.CouldNotEstablishConnection"},
812         {"Message",
813          "The service failed to establish a Connection with the URI " + arg1 +
814              "."},
815         {"MessageArgs", {arg1}},
816         {"Severity", "Critical"},
817         {"Resolution",
818          "Ensure that the URI contains a valid and reachable node name, "
819          "protocol information and other URI components."}};
820 }
821 
822 void couldNotEstablishConnection(crow::Response& res, const std::string& arg1)
823 {
824     res.result(boost::beast::http::status::not_found);
825     addMessageToErrorJson(res.jsonValue, couldNotEstablishConnection(arg1));
826 }
827 
828 /**
829  * @internal
830  * @brief Formats PropertyNotWritable message into JSON for the specified
831  * property
832  *
833  * See header file for more information
834  * @endinternal
835  */
836 nlohmann::json propertyNotWritable(const std::string& arg1)
837 {
838     return nlohmann::json{
839         {"@odata.type", "#Message.v1_0_0.Message"},
840         {"MessageId", "Base.1.4.0.PropertyNotWritable"},
841         {"Message", "The property " + arg1 +
842                         " is a read only property and cannot be "
843                         "assigned a value."},
844         {"MessageArgs", {arg1}},
845         {"Severity", "Warning"},
846         {"Resolution", "Remove the property from the request body and "
847                        "resubmit the request if the operation failed."}};
848 }
849 
850 void propertyNotWritable(crow::Response& res, const std::string& arg1)
851 {
852     res.result(boost::beast::http::status::forbidden);
853     addMessageToJson(res.jsonValue, propertyNotWritable(arg1), arg1);
854 }
855 
856 /**
857  * @internal
858  * @brief Formats QueryParameterValueTypeError message into JSON
859  *
860  * See header file for more information
861  * @endinternal
862  */
863 nlohmann::json queryParameterValueTypeError(const std::string& arg1,
864                                             const std::string& arg2)
865 {
866     return nlohmann::json{
867         {"@odata.type", "#Message.v1_0_0.Message"},
868         {"MessageId", "Base.1.4.0.QueryParameterValueTypeError"},
869         {"Message",
870          "The value " + arg1 + " for the query parameter " + arg2 +
871              " is of a different type than the parameter can accept."},
872         {"MessageArgs", {arg1, arg2}},
873         {"Severity", "Warning"},
874         {"Resolution",
875          "Correct the value for the query parameter in the request and "
876          "resubmit the request if the operation failed."}};
877 }
878 
879 void queryParameterValueTypeError(crow::Response& res, const std::string& arg1,
880                                   const std::string& arg2)
881 {
882     res.result(boost::beast::http::status::bad_request);
883     addMessageToErrorJson(res.jsonValue,
884                           queryParameterValueTypeError(arg1, arg2));
885 }
886 
887 /**
888  * @internal
889  * @brief Formats ServiceShuttingDown message into JSON
890  *
891  * See header file for more information
892  * @endinternal
893  */
894 nlohmann::json serviceShuttingDown(void)
895 {
896     return nlohmann::json{
897         {"@odata.type", "#Message.v1_0_0.Message"},
898         {"MessageId", "Base.1.4.0.ServiceShuttingDown"},
899         {"Message", "The operation failed because the service is shutting "
900                     "down and can no longer take incoming requests."},
901         {"MessageArgs", nlohmann::json::array()},
902         {"Severity", "Critical"},
903         {"Resolution", "When the service becomes available, resubmit the "
904                        "request if the operation failed."}};
905 }
906 
907 void serviceShuttingDown(crow::Response& res)
908 {
909     res.result(boost::beast::http::status::service_unavailable);
910     addMessageToErrorJson(res.jsonValue, serviceShuttingDown());
911 }
912 
913 /**
914  * @internal
915  * @brief Formats ActionParameterDuplicate message into JSON
916  *
917  * See header file for more information
918  * @endinternal
919  */
920 nlohmann::json actionParameterDuplicate(const std::string& arg1,
921                                         const std::string& arg2)
922 {
923     return nlohmann::json{
924         {"@odata.type", "#Message.v1_0_0.Message"},
925         {"MessageId", "Base.1.4.0.ActionParameterDuplicate"},
926         {"Message",
927          "The action " + arg1 +
928              " was submitted with more than one value for the parameter " +
929              arg2 + "."},
930         {"MessageArgs", {arg1, arg2}},
931         {"Severity", "Warning"},
932         {"Resolution",
933          "Resubmit the action with only one instance of the parameter in "
934          "the request body if the operation failed."}};
935 }
936 
937 void actionParameterDuplicate(crow::Response& res, const std::string& arg1,
938                               const std::string& arg2)
939 {
940     res.result(boost::beast::http::status::bad_request);
941     addMessageToErrorJson(res.jsonValue, actionParameterDuplicate(arg1, arg2));
942 }
943 
944 /**
945  * @internal
946  * @brief Formats ActionParameterNotSupported message into JSON
947  *
948  * See header file for more information
949  * @endinternal
950  */
951 nlohmann::json actionParameterNotSupported(const std::string& arg1,
952                                            const std::string& arg2)
953 {
954     return nlohmann::json{
955         {"@odata.type", "#Message.v1_0_0.Message"},
956         {"MessageId", "Base.1.4.0.ActionParameterNotSupported"},
957         {"Message", "The parameter " + arg1 + " for the action " + arg2 +
958                         " is not supported on the target resource."},
959         {"MessageArgs", {arg1, arg2}},
960         {"Severity", "Warning"},
961         {"Resolution", "Remove the parameter supplied and resubmit the "
962                        "request if the operation failed."}};
963 }
964 
965 void actionParameterNotSupported(crow::Response& res, const std::string& arg1,
966                                  const std::string& arg2)
967 {
968     res.result(boost::beast::http::status::bad_request);
969     addMessageToErrorJson(res.jsonValue,
970                           actionParameterNotSupported(arg1, arg2));
971 }
972 
973 /**
974  * @internal
975  * @brief Formats SourceDoesNotSupportProtocol message into JSON
976  *
977  * See header file for more information
978  * @endinternal
979  */
980 nlohmann::json sourceDoesNotSupportProtocol(const std::string& arg1,
981                                             const std::string& arg2)
982 {
983     return nlohmann::json{
984         {"@odata.type", "#Message.v1_0_0.Message"},
985         {"MessageId", "Base.1.4.0.SourceDoesNotSupportProtocol"},
986         {"Message", "The other end of the Connection at " + arg1 +
987                         " does not support the specified protocol " + arg2 +
988                         "."},
989         {"MessageArgs", {arg1, arg2}},
990         {"Severity", "Critical"},
991         {"Resolution", "Change protocols or URIs. "}};
992 }
993 
994 void sourceDoesNotSupportProtocol(crow::Response& res, const std::string& arg1,
995                                   const std::string& arg2)
996 {
997     res.result(boost::beast::http::status::bad_request);
998     addMessageToErrorJson(res.jsonValue,
999                           sourceDoesNotSupportProtocol(arg1, arg2));
1000 }
1001 
1002 /**
1003  * @internal
1004  * @brief Formats AccountRemoved message into JSON
1005  *
1006  * See header file for more information
1007  * @endinternal
1008  */
1009 nlohmann::json accountRemoved(void)
1010 {
1011     return nlohmann::json{{"@odata.type", "#Message.v1_0_0.Message"},
1012                           {"MessageId", "Base.1.4.0.AccountRemoved"},
1013                           {"Message", "The account was successfully removed."},
1014                           {"MessageArgs", nlohmann::json::array()},
1015                           {"Severity", "OK"},
1016                           {"Resolution", "No resolution is required."}};
1017 }
1018 
1019 void accountRemoved(crow::Response& res)
1020 {
1021     res.result(boost::beast::http::status::ok);
1022     addMessageToJsonRoot(res.jsonValue, accountRemoved());
1023 }
1024 
1025 /**
1026  * @internal
1027  * @brief Formats AccessDenied message into JSON
1028  *
1029  * See header file for more information
1030  * @endinternal
1031  */
1032 nlohmann::json accessDenied(const std::string& arg1)
1033 {
1034     return nlohmann::json{
1035         {"@odata.type", "#Message.v1_0_0.Message"},
1036         {"MessageId", "Base.1.4.0.AccessDenied"},
1037         {"Message", "While attempting to establish a Connection to " + arg1 +
1038                         ", the service denied access."},
1039         {"MessageArgs", {arg1}},
1040         {"Severity", "Critical"},
1041         {"Resolution", "Attempt to ensure that the URI is correct and that "
1042                        "the service has the appropriate credentials."}};
1043 }
1044 
1045 void accessDenied(crow::Response& res, const std::string& arg1)
1046 {
1047     res.result(boost::beast::http::status::forbidden);
1048     addMessageToErrorJson(res.jsonValue, accessDenied(arg1));
1049 }
1050 
1051 /**
1052  * @internal
1053  * @brief Formats QueryNotSupported message into JSON
1054  *
1055  * See header file for more information
1056  * @endinternal
1057  */
1058 nlohmann::json queryNotSupported(void)
1059 {
1060     return nlohmann::json{
1061         {"@odata.type", "#Message.v1_0_0.Message"},
1062         {"MessageId", "Base.1.4.0.QueryNotSupported"},
1063         {"Message", "Querying is not supported by the implementation."},
1064         {"MessageArgs", nlohmann::json::array()},
1065         {"Severity", "Warning"},
1066         {"Resolution", "Remove the query parameters and resubmit the "
1067                        "request if the operation failed."}};
1068 }
1069 
1070 void queryNotSupported(crow::Response& res)
1071 {
1072     res.result(boost::beast::http::status::bad_request);
1073     addMessageToErrorJson(res.jsonValue, queryNotSupported());
1074 }
1075 
1076 /**
1077  * @internal
1078  * @brief Formats CreateLimitReachedForResource message into JSON
1079  *
1080  * See header file for more information
1081  * @endinternal
1082  */
1083 nlohmann::json createLimitReachedForResource(void)
1084 {
1085     return nlohmann::json{
1086         {"@odata.type", "#Message.v1_0_0.Message"},
1087         {"MessageId", "Base.1.4.0.CreateLimitReachedForResource"},
1088         {"Message", "The create operation failed because the resource has "
1089                     "reached the limit of possible resources."},
1090         {"MessageArgs", nlohmann::json::array()},
1091         {"Severity", "Critical"},
1092         {"Resolution",
1093          "Either delete resources and resubmit the request if the "
1094          "operation failed or do not resubmit the request."}};
1095 }
1096 
1097 void createLimitReachedForResource(crow::Response& res)
1098 {
1099     res.result(boost::beast::http::status::bad_request);
1100     addMessageToErrorJson(res.jsonValue, createLimitReachedForResource());
1101 }
1102 
1103 /**
1104  * @internal
1105  * @brief Formats GeneralError message into JSON
1106  *
1107  * See header file for more information
1108  * @endinternal
1109  */
1110 nlohmann::json generalError(void)
1111 {
1112     return nlohmann::json{{"@odata.type", "#Message.v1_0_0.Message"},
1113                           {"MessageId", "Base.1.4.0.GeneralError"},
1114                           {"Message",
1115                            "A general error has occurred. See Resolution for "
1116                            "information on how to resolve the error."},
1117                           {"MessageArgs", nlohmann::json::array()},
1118                           {"Severity", "Critical"},
1119                           {"Resolution", "None."}};
1120 }
1121 
1122 void generalError(crow::Response& res)
1123 {
1124     res.result(boost::beast::http::status::internal_server_error);
1125     addMessageToErrorJson(res.jsonValue, generalError());
1126 }
1127 
1128 /**
1129  * @internal
1130  * @brief Formats Success message into JSON
1131  *
1132  * See header file for more information
1133  * @endinternal
1134  */
1135 nlohmann::json success(void)
1136 {
1137     return nlohmann::json{{"@odata.type", "#Message.v1_0_0.Message"},
1138                           {"MessageId", "Base.1.4.0.Success"},
1139                           {"Message", "Successfully Completed Request"},
1140                           {"MessageArgs", nlohmann::json::array()},
1141                           {"Severity", "OK"},
1142                           {"Resolution", "None"}};
1143 }
1144 
1145 void success(crow::Response& res)
1146 {
1147     // don't set res.result here because success is the default and any
1148     // error should overwrite the default
1149     addMessageToJsonRoot(res.jsonValue, success());
1150 }
1151 
1152 /**
1153  * @internal
1154  * @brief Formats Created message into JSON
1155  *
1156  * See header file for more information
1157  * @endinternal
1158  */
1159 nlohmann::json created(void)
1160 {
1161     return nlohmann::json{
1162         {"@odata.type", "#Message.v1_0_0.Message"},
1163         {"MessageId", "Base.1.4.0.Created"},
1164         {"Message", "The resource has been created successfully"},
1165         {"MessageArgs", nlohmann::json::array()},
1166         {"Severity", "OK"},
1167         {"Resolution", "None"}};
1168 }
1169 
1170 void created(crow::Response& res)
1171 {
1172     res.result(boost::beast::http::status::created);
1173     addMessageToJsonRoot(res.jsonValue, created());
1174 }
1175 
1176 /**
1177  * @internal
1178  * @brief Formats NoOperation message into JSON
1179  *
1180  * See header file for more information
1181  * @endinternal
1182  */
1183 nlohmann::json noOperation(void)
1184 {
1185     return nlohmann::json{
1186         {"@odata.type", "#Message.v1_0_0.Message"},
1187         {"MessageId", "Base.1.4.0.NoOperation"},
1188         {"Message", "The request body submitted contain no data to act "
1189                     "upon and no changes to the resource took place."},
1190         {"MessageArgs", nlohmann::json::array()},
1191         {"Severity", "Warning"},
1192         {"Resolution",
1193          "Add properties in the JSON object and resubmit the request."}};
1194 }
1195 
1196 void noOperation(crow::Response& res)
1197 {
1198     res.result(boost::beast::http::status::bad_request);
1199     addMessageToErrorJson(res.jsonValue, noOperation());
1200 }
1201 
1202 /**
1203  * @internal
1204  * @brief Formats PropertyUnknown message into JSON for the specified
1205  * property
1206  *
1207  * See header file for more information
1208  * @endinternal
1209  */
1210 nlohmann::json propertyUnknown(const std::string& arg1)
1211 {
1212     return nlohmann::json{
1213         {"@odata.type", "#Message.v1_0_0.Message"},
1214         {"MessageId", "Base.1.4.0.PropertyUnknown"},
1215         {"Message", "The property " + arg1 +
1216                         " is not in the list of valid properties for "
1217                         "the resource."},
1218         {"MessageArgs", {arg1}},
1219         {"Severity", "Warning"},
1220         {"Resolution", "Remove the unknown property from the request "
1221                        "body and resubmit "
1222                        "the request if the operation failed."}};
1223 }
1224 
1225 void propertyUnknown(crow::Response& res, const std::string& arg1)
1226 {
1227     res.result(boost::beast::http::status::bad_request);
1228     addMessageToJson(res.jsonValue, propertyUnknown(arg1), arg1);
1229 }
1230 
1231 /**
1232  * @internal
1233  * @brief Formats NoValidSession message into JSON
1234  *
1235  * See header file for more information
1236  * @endinternal
1237  */
1238 nlohmann::json noValidSession(void)
1239 {
1240     return nlohmann::json{
1241         {"@odata.type", "#Message.v1_0_0.Message"},
1242         {"MessageId", "Base.1.4.0.NoValidSession"},
1243         {"Message",
1244          "There is no valid session established with the implementation."},
1245         {"MessageArgs", nlohmann::json::array()},
1246         {"Severity", "Critical"},
1247         {"Resolution",
1248          "Establish as session before attempting any operations."}};
1249 }
1250 
1251 void noValidSession(crow::Response& res)
1252 {
1253     res.result(boost::beast::http::status::forbidden);
1254     addMessageToErrorJson(res.jsonValue, noValidSession());
1255 }
1256 
1257 /**
1258  * @internal
1259  * @brief Formats InvalidObject message into JSON
1260  *
1261  * See header file for more information
1262  * @endinternal
1263  */
1264 nlohmann::json invalidObject(const std::string& arg1)
1265 {
1266     return nlohmann::json{
1267         {"@odata.type", "#Message.v1_0_0.Message"},
1268         {"MessageId", "Base.1.4.0.InvalidObject"},
1269         {"Message", "The object at " + arg1 + " is invalid."},
1270         {"MessageArgs", {arg1}},
1271         {"Severity", "Critical"},
1272         {"Resolution",
1273          "Either the object is malformed or the URI is not correct.  "
1274          "Correct the condition and resubmit the request if it failed."}};
1275 }
1276 
1277 void invalidObject(crow::Response& res, const std::string& arg1)
1278 {
1279     res.result(boost::beast::http::status::bad_request);
1280     addMessageToErrorJson(res.jsonValue, invalidObject(arg1));
1281 }
1282 
1283 /**
1284  * @internal
1285  * @brief Formats ResourceInStandby message into JSON
1286  *
1287  * See header file for more information
1288  * @endinternal
1289  */
1290 nlohmann::json resourceInStandby(void)
1291 {
1292     return nlohmann::json{
1293         {"@odata.type", "#Message.v1_0_0.Message"},
1294         {"MessageId", "Base.1.4.0.ResourceInStandby"},
1295         {"Message", "The request could not be performed because the "
1296                     "resource is in standby."},
1297         {"MessageArgs", nlohmann::json::array()},
1298         {"Severity", "Critical"},
1299         {"Resolution", "Ensure that the resource is in the correct power "
1300                        "state and resubmit the request."}};
1301 }
1302 
1303 void resourceInStandby(crow::Response& res)
1304 {
1305     res.result(boost::beast::http::status::service_unavailable);
1306     addMessageToErrorJson(res.jsonValue, resourceInStandby());
1307 }
1308 
1309 /**
1310  * @internal
1311  * @brief Formats ActionParameterValueTypeError message into JSON
1312  *
1313  * See header file for more information
1314  * @endinternal
1315  */
1316 nlohmann::json actionParameterValueTypeError(const std::string& arg1,
1317                                              const std::string& arg2,
1318                                              const std::string& arg3)
1319 {
1320     return nlohmann::json{
1321         {"@odata.type", "#Message.v1_0_0.Message"},
1322         {"MessageId", "Base.1.4.0.ActionParameterValueTypeError"},
1323         {"Message",
1324          "The value " + arg1 + " for the parameter " + arg2 +
1325              " in the action " + arg3 +
1326              " is of a different type than the parameter can accept."},
1327         {"MessageArgs", {arg1, arg2, arg3}},
1328         {"Severity", "Warning"},
1329         {"Resolution",
1330          "Correct the value for the parameter in the request body and "
1331          "resubmit the request if the operation failed."}};
1332 }
1333 
1334 void actionParameterValueTypeError(crow::Response& res, const std::string& arg1,
1335                                    const std::string& arg2,
1336                                    const std::string& arg3)
1337 {
1338     res.result(boost::beast::http::status::bad_request);
1339     addMessageToErrorJson(res.jsonValue,
1340                           actionParameterValueTypeError(arg1, arg2, arg3));
1341 }
1342 
1343 /**
1344  * @internal
1345  * @brief Formats SessionLimitExceeded message into JSON
1346  *
1347  * See header file for more information
1348  * @endinternal
1349  */
1350 nlohmann::json sessionLimitExceeded(void)
1351 {
1352     return nlohmann::json{
1353         {"@odata.type", "#Message.v1_0_0.Message"},
1354         {"MessageId", "Base.1.4.0.SessionLimitExceeded"},
1355         {"Message", "The session establishment failed due to the number of "
1356                     "simultaneous sessions exceeding the limit of the "
1357                     "implementation."},
1358         {"MessageArgs", nlohmann::json::array()},
1359         {"Severity", "Critical"},
1360         {"Resolution", "Reduce the number of other sessions before trying "
1361                        "to establish the session or increase the limit of "
1362                        "simultaneous sessions (if supported)."}};
1363 }
1364 
1365 void sessionLimitExceeded(crow::Response& res)
1366 {
1367     res.result(boost::beast::http::status::service_unavailable);
1368     addMessageToErrorJson(res.jsonValue, sessionLimitExceeded());
1369 }
1370 
1371 /**
1372  * @internal
1373  * @brief Formats ActionNotSupported message into JSON
1374  *
1375  * See header file for more information
1376  * @endinternal
1377  */
1378 nlohmann::json actionNotSupported(const std::string& arg1)
1379 {
1380     return nlohmann::json{
1381         {"@odata.type", "#Message.v1_0_0.Message"},
1382         {"MessageId", "Base.1.4.0.ActionNotSupported"},
1383         {"Message",
1384          "The action " + arg1 + " is not supported by the resource."},
1385         {"MessageArgs", {arg1}},
1386         {"Severity", "Critical"},
1387         {"Resolution",
1388          "The action supplied cannot be resubmitted to the implementation. "
1389          " Perhaps the action was invalid, the wrong resource was the "
1390          "target or the implementation documentation may be of "
1391          "assistance."}};
1392 }
1393 
1394 void actionNotSupported(crow::Response& res, const std::string& arg1)
1395 {
1396     res.result(boost::beast::http::status::bad_request);
1397     addMessageToErrorJson(res.jsonValue, actionNotSupported(arg1));
1398 }
1399 
1400 /**
1401  * @internal
1402  * @brief Formats InvalidIndex message into JSON
1403  *
1404  * See header file for more information
1405  * @endinternal
1406  */
1407 nlohmann::json invalidIndex(const int& arg1)
1408 {
1409     return nlohmann::json{
1410         {"@odata.type", "#Message.v1_0_0.Message"},
1411         {"MessageId", "Base.1.4.0.InvalidIndex"},
1412         {"Message", "The index " + std::to_string(arg1) +
1413                         " is not a valid offset into the array."},
1414         {"MessageArgs", {std::to_string(arg1)}},
1415         {"Severity", "Warning"},
1416         {"Resolution", "Verify the index value provided is within the "
1417                        "bounds of the array."}};
1418 }
1419 
1420 void invalidIndex(crow::Response& res, const int& arg1)
1421 {
1422     res.result(boost::beast::http::status::bad_request);
1423     addMessageToErrorJson(res.jsonValue, invalidIndex(arg1));
1424 }
1425 
1426 /**
1427  * @internal
1428  * @brief Formats EmptyJSON message into JSON
1429  *
1430  * See header file for more information
1431  * @endinternal
1432  */
1433 nlohmann::json emptyJSON(void)
1434 {
1435     return nlohmann::json{
1436         {"@odata.type", "#Message.v1_0_0.Message"},
1437         {"MessageId", "Base.1.4.0.EmptyJSON"},
1438         {"Message", "The request body submitted contained an empty JSON "
1439                     "object and the service is unable to process it."},
1440         {"MessageArgs", nlohmann::json::array()},
1441         {"Severity", "Warning"},
1442         {"Resolution",
1443          "Add properties in the JSON object and resubmit the request."}};
1444 }
1445 
1446 void emptyJSON(crow::Response& res)
1447 {
1448     res.result(boost::beast::http::status::bad_request);
1449     addMessageToErrorJson(res.jsonValue, emptyJSON());
1450 }
1451 
1452 /**
1453  * @internal
1454  * @brief Formats QueryNotSupportedOnResource message into JSON
1455  *
1456  * See header file for more information
1457  * @endinternal
1458  */
1459 nlohmann::json queryNotSupportedOnResource(void)
1460 {
1461     return nlohmann::json{
1462         {"@odata.type", "#Message.v1_0_0.Message"},
1463         {"MessageId", "Base.1.4.0.QueryNotSupportedOnResource"},
1464         {"Message", "Querying is not supported on the requested resource."},
1465         {"MessageArgs", nlohmann::json::array()},
1466         {"Severity", "Warning"},
1467         {"Resolution", "Remove the query parameters and resubmit the "
1468                        "request if the operation failed."}};
1469 }
1470 
1471 void queryNotSupportedOnResource(crow::Response& res)
1472 {
1473     res.result(boost::beast::http::status::forbidden);
1474     addMessageToErrorJson(res.jsonValue, queryNotSupportedOnResource());
1475 }
1476 
1477 /**
1478  * @internal
1479  * @brief Formats InsufficientPrivilege message into JSON
1480  *
1481  * See header file for more information
1482  * @endinternal
1483  */
1484 nlohmann::json insufficientPrivilege(void)
1485 {
1486     return nlohmann::json{
1487         {"@odata.type", "#Message.v1_0_0.Message"},
1488         {"MessageId", "Base.1.4.0.InsufficientPrivilege"},
1489         {"Message", "There are insufficient privileges for the account or "
1490                     "credentials associated with the current session to "
1491                     "perform the requested operation."},
1492         {"MessageArgs", nlohmann::json::array()},
1493         {"Severity", "Critical"},
1494         {"Resolution",
1495          "Either abandon the operation or change the associated access "
1496          "rights and resubmit the request if the operation failed."}};
1497 }
1498 
1499 void insufficientPrivilege(crow::Response& res)
1500 {
1501     res.result(boost::beast::http::status::forbidden);
1502     addMessageToErrorJson(res.jsonValue, insufficientPrivilege());
1503 }
1504 
1505 /**
1506  * @internal
1507  * @brief Formats PropertyValueModified message into JSON
1508  *
1509  * See header file for more information
1510  * @endinternal
1511  */
1512 nlohmann::json propertyValueModified(const std::string& arg1,
1513                                      const std::string& arg2)
1514 {
1515     return nlohmann::json{
1516         {"@odata.type", "#Message.v1_0_0.Message"},
1517         {"MessageId", "Base.1.4.0.PropertyValueModified"},
1518         {"Message", "The property " + arg1 + " was assigned the value " + arg2 +
1519                         " due to modification by the service."},
1520         {"MessageArgs", {arg1, arg2}},
1521         {"Severity", "Warning"},
1522         {"Resolution", "No resolution is required."}};
1523 }
1524 
1525 void propertyValueModified(crow::Response& res, const std::string& arg1,
1526                            const std::string& arg2)
1527 {
1528     res.result(boost::beast::http::status::ok);
1529     addMessageToJson(res.jsonValue, propertyValueModified(arg1, arg2), arg1);
1530 }
1531 
1532 /**
1533  * @internal
1534  * @brief Formats AccountNotModified message into JSON
1535  *
1536  * See header file for more information
1537  * @endinternal
1538  */
1539 nlohmann::json accountNotModified(void)
1540 {
1541     return nlohmann::json{
1542         {"@odata.type", "#Message.v1_0_0.Message"},
1543         {"MessageId", "Base.1.4.0.AccountNotModified"},
1544         {"Message", "The account modification request failed."},
1545         {"MessageArgs", nlohmann::json::array()},
1546         {"Severity", "Warning"},
1547         {"Resolution", "The modification may have failed due to permission "
1548                        "issues or issues with the request body."}};
1549 }
1550 
1551 void accountNotModified(crow::Response& res)
1552 {
1553     res.result(boost::beast::http::status::bad_request);
1554     addMessageToErrorJson(res.jsonValue, accountNotModified());
1555 }
1556 
1557 /**
1558  * @internal
1559  * @brief Formats QueryParameterValueFormatError message into JSON
1560  *
1561  * See header file for more information
1562  * @endinternal
1563  */
1564 nlohmann::json queryParameterValueFormatError(const std::string& arg1,
1565                                               const std::string& arg2)
1566 {
1567     return nlohmann::json{
1568         {"@odata.type", "#Message.v1_0_0.Message"},
1569         {"MessageId", "Base.1.4.0.QueryParameterValueFormatError"},
1570         {"Message",
1571          "The value " + arg1 + " for the parameter " + arg2 +
1572              " is of a different format than the parameter can accept."},
1573         {"MessageArgs", {arg1, arg2}},
1574         {"Severity", "Warning"},
1575         {"Resolution",
1576          "Correct the value for the query parameter in the request and "
1577          "resubmit the request if the operation failed."}};
1578 }
1579 
1580 void queryParameterValueFormatError(crow::Response& res,
1581                                     const std::string& arg1,
1582                                     const std::string& arg2)
1583 {
1584     res.result(boost::beast::http::status::bad_request);
1585     addMessageToErrorJson(res.jsonValue,
1586                           queryParameterValueFormatError(arg1, arg2));
1587 }
1588 
1589 /**
1590  * @internal
1591  * @brief Formats PropertyMissing message into JSON for the specified
1592  * property
1593  *
1594  * See header file for more information
1595  * @endinternal
1596  */
1597 nlohmann::json propertyMissing(const std::string& arg1)
1598 {
1599     return nlohmann::json{
1600         {"@odata.type", "#Message.v1_0_0.Message"},
1601         {"MessageId", "Base.1.4.0.PropertyMissing"},
1602         {"Message", "The property " + arg1 +
1603                         " is a required property and must be included in "
1604                         "the request."},
1605         {"MessageArgs", {arg1}},
1606         {"Severity", "Warning"},
1607         {"Resolution",
1608          "Ensure that the property is in the request body and has a "
1609          "valid "
1610          "value and resubmit the request if the operation failed."}};
1611 }
1612 
1613 void propertyMissing(crow::Response& res, const std::string& arg1)
1614 {
1615     res.result(boost::beast::http::status::bad_request);
1616     addMessageToJson(res.jsonValue, propertyMissing(arg1), arg1);
1617 }
1618 
1619 /**
1620  * @internal
1621  * @brief Formats ResourceExhaustion message into JSON
1622  *
1623  * See header file for more information
1624  * @endinternal
1625  */
1626 nlohmann::json resourceExhaustion(const std::string& arg1)
1627 {
1628     return nlohmann::json{
1629         {"@odata.type", "#Message.v1_0_0.Message"},
1630         {"MessageId", "Base.1.4.0.ResourceExhaustion"},
1631         {"Message", "The resource " + arg1 +
1632                         " was unable to satisfy the request due to "
1633                         "unavailability of resources."},
1634         {"MessageArgs", {arg1}},
1635         {"Severity", "Critical"},
1636         {"Resolution", "Ensure that the resources are available and "
1637                        "resubmit the request."}};
1638 }
1639 
1640 void resourceExhaustion(crow::Response& res, const std::string& arg1)
1641 {
1642     res.result(boost::beast::http::status::service_unavailable);
1643     addMessageToErrorJson(res.jsonValue, resourceExhaustion(arg1));
1644 }
1645 
1646 /**
1647  * @internal
1648  * @brief Formats AccountModified message into JSON
1649  *
1650  * See header file for more information
1651  * @endinternal
1652  */
1653 nlohmann::json accountModified(void)
1654 {
1655     return nlohmann::json{{"@odata.type", "#Message.v1_0_0.Message"},
1656                           {"MessageId", "Base.1.4.0.AccountModified"},
1657                           {"Message", "The account was successfully modified."},
1658                           {"MessageArgs", nlohmann::json::array()},
1659                           {"Severity", "OK"},
1660                           {"Resolution", "No resolution is required."}};
1661 }
1662 
1663 void accountModified(crow::Response& res)
1664 {
1665     res.result(boost::beast::http::status::ok);
1666     addMessageToErrorJson(res.jsonValue, accountModified());
1667 }
1668 
1669 /**
1670  * @internal
1671  * @brief Formats QueryParameterOutOfRange message into JSON
1672  *
1673  * See header file for more information
1674  * @endinternal
1675  */
1676 nlohmann::json queryParameterOutOfRange(const std::string& arg1,
1677                                         const std::string& arg2,
1678                                         const std::string& arg3)
1679 {
1680     return nlohmann::json{
1681         {"@odata.type", "#Message.v1_0_0.Message"},
1682         {"MessageId", "Base.1.4.0.QueryParameterOutOfRange"},
1683         {"Message", "The value " + arg1 + " for the query parameter " + arg2 +
1684                         " is out of range " + arg3 + "."},
1685         {"MessageArgs", {arg1, arg2, arg3}},
1686         {"Severity", "Warning"},
1687         {"Resolution",
1688          "Reduce the value for the query parameter to a value that is "
1689          "within range, such as a start or count value that is within "
1690          "bounds of the number of resources in a collection or a page that "
1691          "is within the range of valid pages."}};
1692 }
1693 
1694 void queryParameterOutOfRange(crow::Response& res, const std::string& arg1,
1695                               const std::string& arg2, const std::string& arg3)
1696 {
1697     res.result(boost::beast::http::status::bad_request);
1698     addMessageToErrorJson(res.jsonValue,
1699                           queryParameterOutOfRange(arg1, arg2, arg3));
1700 }
1701 
1702 /**
1703  * @internal
1704  * @brief Formats PasswordChangeRequired message into JSON
1705  *
1706  * See header file for more information
1707  * @endinternal
1708  */
1709 void passwordChangeRequired(crow::Response& res, const std::string& arg1)
1710 {
1711     messages::addMessageToJsonRoot(
1712         res.jsonValue,
1713         nlohmann::json{
1714             {"@odata.type", "/redfish/v1/$metadata#Message.v1_5_0.Message"},
1715             {"MessageId", "Base.1.5.0.PasswordChangeRequired"},
1716             {"Message", "The password provided for this account must be "
1717                         "changed before access is granted.  PATCH the "
1718                         "'Password' property for this account located at "
1719                         "the target URI '" +
1720                             arg1 + "' to complete this process."},
1721             {"MessageArgs", {arg1}},
1722             {"Severity", "Critical"},
1723             {"Resolution", "Change the password for this account using "
1724                            "a PATCH to the 'Password' property at the URI "
1725                            "provided."}});
1726 }
1727 
1728 } // namespace messages
1729 
1730 } // namespace redfish
1731