ResponseCode Shadow::HandleUpdateResponse()

in src/shadow/Shadow.cpp [210:283]


    ResponseCode Shadow::HandleUpdateResponse(ShadowResponseType response_type, util::JsonDocument &payload) {
        ResponseCode rc = ResponseCode::SHADOW_REQUEST_ACCEPTED;
        if (ShadowResponseType::Rejected == response_type) {
            AWS_LOG_WARN(SHADOW_LOG_TAG, "Update request rejected for shadow : %s", thing_name_.c_str());
            rc = ResponseCode::SHADOW_REQUEST_REJECTED;
        } else if (!payload.IsObject() || !payload.HasMember(SHADOW_DOCUMENT_STATE_KEY)) {
            // Validate payload
            rc = ResponseCode::SHADOW_UNEXPECTED_RESPONSE_PAYLOAD;
        } else {
            uint32_t payload_version;
            ResponseCode rc_parser = util::JsonParser::GetUint32Value(payload, SHADOW_DOCUMENT_VERSION_KEY,
                                                                      payload_version);
            // Either key should exist or it shouldn't but no other errors should occur
            if (ResponseCode::SUCCESS != rc_parser && ResponseCode::JSON_PARSE_KEY_NOT_FOUND_ERROR != rc_parser) {
                rc = rc_parser;
            } else if (payload_version <= cur_shadow_version_) {
                rc = ResponseCode::SHADOW_RECEIVED_OLD_VERSION_UPDATE;
            } else {
                bool own_request = false;
                if (payload.HasMember(SHADOW_DOCUMENT_CLIENT_TOKEN_KEY)) {
                    util::String received_client_token;
                    util::JsonParser::GetStringValue((const util::JsonDocument &)payload, SHADOW_DOCUMENT_CLIENT_TOKEN_KEY, received_client_token);
                    own_request = (0 == client_token_.compare(received_client_token));
                }
                if (ShadowResponseType::Delta == response_type) {
                    if (!own_request) {
                        AWS_LOG_DEBUG(SHADOW_LOG_TAG, "Delta received for shadow : %s", thing_name_.c_str());
                        rc = ResponseCode::SHADOW_RECEIVED_DELTA;
                        if (!cur_server_state_document_.HasMember(SHADOW_DOCUMENT_STATE_KEY)) {
                            util::JsonParser::InitializeFromJsonString(cur_server_state_document_,
                                                                       SHADOW_DOCUMENT_EMPTY_STRING);
                        }

                        if (!cur_server_state_document_[SHADOW_DOCUMENT_STATE_KEY].HasMember(SHADOW_DOCUMENT_DESIRED_KEY)) {
                            util::JsonDocument empty_doc;
                            util::JsonParser::InitializeFromJsonString(empty_doc, SHADOW_DOCUMENT_EMPTY_STRING);
                            util::JsonParser::MergeValues(cur_server_state_document_[SHADOW_DOCUMENT_STATE_KEY],
                                                          empty_doc[SHADOW_DOCUMENT_STATE_KEY],
                                                          cur_server_state_document_.GetAllocator());
                        }
                        util::JsonParser::MergeValues(cur_server_state_document_[SHADOW_DOCUMENT_STATE_KEY][SHADOW_DOCUMENT_DESIRED_KEY],
                                                      payload[SHADOW_DOCUMENT_STATE_KEY],
                                                      cur_server_state_document_.GetAllocator());
                        cur_shadow_version_ = payload_version;
                    } else {
                        AWS_LOG_DEBUG(SHADOW_LOG_TAG,
                                      "Delta received for own update request for shadow %s, ignoring in favor of processing in accepted",
                                      thing_name_.c_str());
                        rc = ResponseCode::SHADOW_RECEIVED_DELTA;
                    }
                } else {
                    AWS_LOG_DEBUG(SHADOW_LOG_TAG, "Update Accepted for shadow %s!!", thing_name_.c_str());
                    util::JsonParser::MergeValues(cur_server_state_document_, payload,
                                                  cur_server_state_document_.GetAllocator());
                    cur_shadow_version_ = payload_version;
                }
            }
        }

        ShadowRequestType shadow_req_type = ShadowRequestType::Update;
        if (ShadowResponseType::Delta == response_type) {
            shadow_req_type = ShadowRequestType::Delta;
        }

        util::Map<ShadowRequestType, RequestHandlerPtr>::iterator request_itr
            = request_mapping_.find(shadow_req_type);
        if (request_itr != request_mapping_.end() && nullptr != request_itr->second) {
            RequestHandlerPtr ptr = request_itr->second;
            ResponseCode rc_handler = ptr(thing_name_, shadow_req_type, response_type, payload);
            IOT_UNUSED(rc_handler);
        }

        return rc;
    }