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