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