Ejemplo n.º 1
0
ErrorCode SharableProxy::EndArbitrate(
    AsyncOperationSPtr const & operation,
    SiteNode & /*siteNode*/,
    __out ArbitrationReplyBody & result)
{
    SharableProxy::AribtrateAsyncOperation *op = AsyncOperation::Get<SharableProxy::AribtrateAsyncOperation>(operation);
    ErrorCode error = op->End(operation);
    if (error.IsSuccess())
    {
        result = op->Result;
    }
    else
    {
        result = ArbitrationReplyBody(TimeSpan::MaxValue, false);
    }

    return error;
}
ErrorCode HostingQueryManager::GetServicePackages(
    Application2SPtr const & applicationEntry,
    wstring const & filterServiceManifestName,
    ActivityId const & activityId,
    __out vector<ServicePackage2SPtr> & servicePackages)
{
    VersionedApplicationSPtr versionApplication = applicationEntry->GetVersionedApplication();
    if (!versionApplication)
    {
        WriteInfo(
            TraceType,
            Root.TraceId,
            "{0}: GetVersionedApplication for ApplicationName {1} failed",
            activityId,
            applicationEntry->AppName);
        return ErrorCodeValue::ApplicationNotFound;
    }

    ErrorCode error;

    if (filterServiceManifestName.empty())
    {
        error = versionApplication->GetAllServicePackageInstances(servicePackages);
    }
    else
    {
        error = versionApplication->GetInstancesOfServicePackage(filterServiceManifestName, servicePackages);
    }

    if (!error.IsSuccess())
    {
        WriteInfo(
            TraceType,
            Root.TraceId,
            "{0}: GetServicePackages for ApplicationName {1} failed with error {2}",
            activityId,
            applicationEntry->AppName,
            error);
        return ReplaceErrorIf(error, ErrorCodeValue::ObjectClosed, ErrorCodeValue::ApplicationNotFound);
    }

    return ErrorCode::Success();
}
ErrorCode FileStoreServiceReplica::GetServiceLocationSequenceNumber(__out int64 & sequenceNumber)
{
    ErrorCode error;
    ManualResetEvent operationDone;

    propertyManagmentClient_->BeginGetPropertyMetadata(
        NamingUri(serviceName_),
        this->PartitionId.ToString(),
        FileStoreServiceConfig::GetConfig().NamingOperationTimeout,
        [this, &error, &operationDone, &sequenceNumber] (AsyncOperationSPtr const & operation)
    {
        NamePropertyMetadataResult metadataResult;
        error = propertyManagmentClient_->EndGetPropertyMetadata(operation, metadataResult);
        WriteInfo(
            TraceComponent,
            this->TraceId,
            "GetServiceLocationSequenceNumber: SequenceNumber:{0}, Error:{1}",            
            metadataResult.SequenceNumber,
            error);

        if(error.IsSuccess())
        {
            sequenceNumber = metadataResult.SequenceNumber;
        }
        else
        {
            // If the property is not found, then complete with success
            if(error.IsError(ErrorCodeValue::PropertyNotFound))
            {
                // -1 indicates that sequence check should not be done
                sequenceNumber = -1;
                error = ErrorCodeValue::Success;
            }
        }

        operationDone.Set();
    },
        this->CreateAsyncOperationRoot());

    operationDone.WaitOne();

    return error;
}
Common::ErrorCode DeployedApplicationEntityHealthInformation::GenerateNodeId()
{
    Federation::NodeId nodeId;
    ErrorCode error = Federation::NodeIdGenerator::GenerateFromString(nodeName_, nodeId);
    if (!error.IsSuccess())
    {
        Trace.WriteInfo(TraceSource, "Error generating NodeId from NodeName {0}: {1}", nodeName_, error);
        return error;
    }

    if (nodeId != nodeId_)
    {
        Trace.WriteInfo(TraceSource, "Generate NodeId from NodeName {0}: {1} (previous {2})", nodeName_, nodeId, nodeId_);
        nodeId_ = nodeId.IdValue;
        entityId_.clear();
    }

    return ErrorCode::Success();
}
 void EntreeService::ResolvePartitionAsyncOperation::CompleteOrRetry(
     AsyncOperationSPtr const & thisSPtr, 
     ErrorCode const & error)
 {
     if (error.IsSuccess() || !this->IsRetryable(error))
     {
         this->TryComplete(thisSPtr, error);
     }
     else
     {
         WriteInfo(
             TraceComponent,
             "{0}: resolve returned error {1}, retry (timeout left={2})",
             TraceId,
             error,
             this->RemainingTime);
         this->HandleRetryStart(thisSPtr);
     }
 }
ErrorCode UnreliableTransportHelper::GetTransportBehaviors(
    QueryArgumentMap const &,
    ActivityId const &,
    __out QueryResult & queryResult)
{
    vector <pair<wstring, wstring>> parameters;
    ErrorCode errorCode = GetTransportBehaviors(parameters);
    if (errorCode.IsSuccess())
    {
        vector<wstring> tranportBehaviors;
        tranportBehaviors.reserve(parameters.size());
        for (auto& behavior : parameters)
        {
            tranportBehaviors.emplace_back(behavior.first + L"=" + behavior.second);
        }
        queryResult = QueryResult(move(tranportBehaviors));
    }
    return errorCode;
}
Ejemplo n.º 7
0
ErrorCode LTSendBuffer::Prepare()
{
    sendingLength_ = 0;
    preparedBuffers_.resize(0);
#ifdef PLATFORM_UNIX
    firstBufferToSend_ = 0;
#endif

    StopwatchTime now = Stopwatch::Now();
    ErrorCode error;
    for (auto cur = messageQueue_.begin(); cur != messageQueue_.end(); ++cur)
    {
        // cap large sends
        if ((sendingLength_ >= sendBatchLimitInBytes_) || (preparedBuffers_.size() >= SendBatchBufferCountLimit))
        {
            break;
        }

        if (!cur->Message())
        {
            continue; // message had been dropped due to expiration
        }

        if (cur->HasExpired(now))
        {
            DropExpiredMessage(*cur);
            continue;
        }

        error = cur->PrepareForSending(*this);
        if (!error.IsSuccess())
        {
            //TcpConnection Send Method Acuires lock before calling Prepare on SendBuffer.
            connection_->Close_CallerHoldingLock(true,error);
            return error;
        }
    }

    perfCounters_->AverageTcpSendSizeBase.Increment();
    perfCounters_->AverageTcpSendSize.IncrementBy(sendingLength_);
    return error;
}
    void EntreeService::ResolvePartitionAsyncOperation::OnFMResolved(
        AsyncOperationSPtr const & asyncOperation,
        bool expectedCompletedSynchronously)
    {
        if (asyncOperation->CompletedSynchronously != expectedCompletedSynchronously)
        {
            return;
        }

        Reliability::ServiceTableEntry serviceTableEntry;
        GenerationNumber unused;
        ErrorCode error = Properties.Resolver.EndResolveFMService(asyncOperation, /*out*/serviceTableEntry, /*out*/unused);

        if (error.IsSuccess())
        {
            Reply = NamingMessage::GetResolvePartitionReply(serviceTableEntry);
        }

        CompleteOrRetry(asyncOperation->Parent, error);
    }
void Replicator::ChangeRoleAsyncOperation::ScheduleOpenPrimaryAndUpdateEpoch(Common::AsyncOperationSPtr const & thisSPtr)
{
    ErrorCode error = primaryCopy_->Open();
    if (!error.IsSuccess())
    {
        TryComplete(thisSPtr, error);
    }
    else
    {
        auto inner = CreateAndStart<UpdateEpochAsyncOperation>(
            parent_,
            epoch_,
            [this](AsyncOperationSPtr const & asyncOperation)
            {
                this->FinishUpdatePrimaryEpoch(asyncOperation, false);
            },
            thisSPtr);
        FinishUpdatePrimaryEpoch(inner, true);
    }
}
HRESULT ComInfrastructureServiceAgentFactory::CreateFabricInfrastructureServiceAgent(
    /* [in] */ __RPC__in REFIID riid,
    /* [out, retval] */ __RPC__deref_out_opt void ** fabricInfrastructureServiceAgent)
{
    if (riid != IID_IFabricInfrastructureServiceAgent) { return ComUtility::OnPublicApiReturn(E_NOINTERFACE); }
    if (fabricInfrastructureServiceAgent == NULL) { return ComUtility::OnPublicApiReturn(E_POINTER); }

    IInfrastructureServiceAgentPtr agentPtr;
    ErrorCode error = impl_->CreateInfrastructureServiceAgent(agentPtr);

    if (!error.IsSuccess()) 
    {
        return ComUtility::OnPublicApiReturn(error.ToHResult());
    }

    ComPointer<IFabricInfrastructureServiceAgent> agentCPtr = WrapperFactory::create_com_wrapper(agentPtr);

    *fabricInfrastructureServiceAgent = agentCPtr.DetachNoRelease();

    return ComUtility::OnPublicApiReturn(S_OK);
}
ErrorCode Replicator::ChangeRoleAsyncOperation::CreateInitialSecondary()
{
    AcquireWriteLock lock(parent_.lock_);
    ASSERT_IF(
        parent_.primary_ || parent_.secondary_, 
        "{0}: The primary and secondary shouldn't exist when changing role to IDLE", 
        parent_.ToString());

    ErrorCode error;
    if (newRole_ == ::FABRIC_REPLICA_ROLE_ACTIVE_SECONDARY)
    {
        error = parent_.state_.TransitionToSecondaryActive();
    }
    else
    {
        error = parent_.state_.TransitionToSecondaryIdle();
    }

    if (!error.IsSuccess())
    {
        return error;
    }

    parent_.secondary_ = move(SecondaryReplicator::CreateSecondary(
        parent_.config_,
        parent_.perfCounters_,
        parent_.replicaId_,
        parent_.hasPersistedState_,
        parent_.endpointUniqueId_,
        parent_.stateProvider_,
        parent_.partition_,
        parent_.version_,
        parent_.transport_,
        parent_.partitionId_,
        parent_.healthClient_,
        parent_.apiMonitor_));

    return ErrorCode(Common::ErrorCodeValue::Success);
}
void ServiceCache::DeleteServiceAsyncOperation::StartDeleteService(AsyncOperationSPtr const& thisSPtr)
{
    ErrorCode error = serviceCache_.GetLockedService(serviceName_, lockedServiceInfo_);
    if (!error.IsSuccess())
    {
        TryComplete(thisSPtr, error);
        return;
    }

    if (lockedServiceInfo_->IsDeleted)
    {
        TryComplete(thisSPtr, ErrorCodeValue::FMServiceDoesNotExist);
        return;
    }
    else if (lockedServiceInfo_->IsToBeDeleted)
    {
        if (lockedServiceInfo_->IsForceDelete || !isForce_) // Allow convert normal deletion to forceful one
        {
            lockedServiceInfo_->AddDeleteOperation(thisSPtr);
            lockedServiceInfo_.Release();
            return;
        }
    }
    else if (serviceInstance_ < lockedServiceInfo_->Instance)
    {
        TryComplete(thisSPtr, ErrorCodeValue::StaleRequest);
        return;
    }

    newServiceInfo_ = make_shared<ServiceInfo>(*lockedServiceInfo_);
    newServiceInfo_->IsToBeDeleted = true;
    newServiceInfo_->IsForceDelete = isForce_;
    newServiceInfo_->AddDeleteOperation(thisSPtr);

    serviceCache_.fmStore_.BeginUpdateData(
        *newServiceInfo_,
        [this](AsyncOperationSPtr const& updateOperation) { OnStoreUpdateCompleted(updateOperation); },
        thisSPtr);
}
    void StoreService::ProcessUpdateServiceRequestAsyncOperation::OnUpdateServiceComplete(
        AsyncOperationSPtr const & operation,
        bool expectedCompletedSynchronously)
    {
        if (operation->CompletedSynchronously != expectedCompletedSynchronously)
        {
            return;
        }

        AsyncOperationSPtr const & thisSPtr = operation->Parent;

        ErrorCode error = UpdateServiceAtAuthorityAsyncOperation::End(operation);

        if (error.IsSuccess())
        {
            this->TryComplete(thisSPtr, move(validationError_));
        }
        else
        {
            this->CompleteOrScheduleRetry(thisSPtr, move(error),
                [this](AsyncOperationSPtr const & thisSPtr) { this->FinishUpdateService(thisSPtr); });
        }
    }
    void StoreService::ProcessUpdateServiceRequestAsyncOperation::OnResolveNameOwnerComplete(
        Common::AsyncOperationSPtr const & operation,
        bool expectedCompletedSynchronously)
    {
        if (expectedCompletedSynchronously != operation->CompletedSynchronously)
        {
            return;
        }

        AsyncOperationSPtr const & thisSPtr = operation->Parent;

        ErrorCode error = EndResolveNameLocation(operation, nameOwnerLocation_);

        if (!error.IsSuccess())
        {
            this->CompleteOrScheduleRetry(thisSPtr, move(error),
                [this](AsyncOperationSPtr const & thisSPtr) { this->StartResolveNameOwner(thisSPtr); });
        }
        else
        {
            this->StartRequestToNameOwner(thisSPtr);
        }
    }
Ejemplo n.º 15
0
ErrorCode LTSendBuffer::Frame::PrepareForSending(LTSendBuffer & sendBuffer)
{
    Invariant(!preparedForSending_);
    preparedForSending_ = true;

    ErrorCode error = EncryptIfNeeded(sendBuffer);
    if (!error.IsSuccess())
    {
        return error;
    }

    if (!encrypted_.empty())
    {
        Invariant(shouldEncrypt_);
        sendBuffer.preparedBuffers_.emplace_back(ConstBuffer(encrypted_.data(), encrypted_.size()));
        sendBuffer.sendingLength_ += encrypted_.size();
        return error;
    }

    // add frame header
    if (message_->Actor != Actor::SecurityContext)
    {
        sendBuffer.preparedBuffers_.emplace_back(ConstBuffer(&header_, sizeof(header_)));
        sendBuffer.sendingLength_ += sizeof(header_);
    }

    // add message body
    for (BufferIterator chunk = message_->BeginBodyChunks(); chunk != message_->EndBodyChunks(); ++chunk)
    {
        if (chunk->size() == 0) continue;

        sendBuffer.preparedBuffers_.emplace_back(ConstBuffer(chunk->cbegin(), chunk->size()));
        sendBuffer.sendingLength_ += chunk->size();
    }

    return error;
}
void ServiceCache::ProcessPLBSafetyCheckAsyncOperation::OnStart(AsyncOperationSPtr const& thisSPtr)
{
    LockedApplicationInfo lockedAppInfo;
    ErrorCode error = serviceCache_.GetLockedApplication(appId, lockedAppInfo);
    if (!error.IsSuccess())
    {
        TryComplete(thisSPtr, error);
        return;
    }

    ApplicationUpgradeUPtr const& upgrade = lockedAppInfo->Upgrade;
    //only if there is an upgrade ongoing
    if (upgrade)
    {
        //plb safety check is done
        ApplicationUpgradeUPtr newUpgrade = make_unique<ApplicationUpgrade>(*upgrade, true);
        ApplicationUpgradeUPtr newRollback =
            (lockedAppInfo->Rollback ? make_unique<ApplicationUpgrade>(*lockedAppInfo->Rollback) : nullptr);
        ApplicationInfoSPtr newAppInfo = make_shared<ApplicationInfo>(*lockedAppInfo, move(newUpgrade), move(newRollback));
        serviceCache_.BeginUpdateApplication(
            move(lockedAppInfo),
            move(newAppInfo),
            false,
            [this](AsyncOperationSPtr const& operation)
            {
                OnApplicationUpdateCompleted(operation);
            },
            thisSPtr);
    }
    //we received an update from PLB even though this application is not in upgrade or we still did not commit the upgrade
    else
    {
        error = ErrorCodeValue::ApplicationNotUpgrading;
        TryComplete(thisSPtr, error);
        return;
    }
}
void ReplicaUpProcessingOperation::OnCompleted(FailoverManager & failoverManager)
{
    if (!error_.IsSuccess())
    {
        failoverManager.WriteWarning(TraceReplicaUp, wformatString(from_.Id),
            "Process ReplicaUp from {0} failed with {1}",
            from_, error_);

        SendReplicaUpReply(false, failoverManager);
    }
    else if (isLastReplicaUpMessageFromRA_)
    {
		auto thisRoot = shared_from_this();
        failoverManager.NodeCacheObj.BeginReplicaUploaded(
            from_,
            [this, thisRoot, &failoverManager](AsyncOperationSPtr const & operation) mutable
            {
                ErrorCode error = failoverManager.NodeCacheObj.EndReplicaUploaded(operation);

                if (!error.IsSuccess())
                {
                    failoverManager.WriteWarning(TraceReplicaUp, wformatString(from_.Id),
                        "Process last ReplicaUp from {0} failed with {1}",
                        from_, error);
                    return;
                }

                SendReplicaUpReply(true, failoverManager);
            },
            failoverManager.CreateAsyncOperationRoot());
    }
	else
	{
		SendReplicaUpReply(false, failoverManager);
	}
}
    void EntreeService::ResolvePartitionAsyncOperation::OnRequestComplete(
        AsyncOperationSPtr const & asyncOperation,
        bool expectedCompletedSynchronously)
    {
        if (asyncOperation->CompletedSynchronously != expectedCompletedSynchronously)
        {
            return;
        }

        std::vector<Reliability::ServiceTableEntry> entries;
        GenerationNumber unused;
        ErrorCode error = Properties.Resolver.EndResolveServicePartition(asyncOperation, /*out*/entries, /*out*/unused);

        if (error.IsSuccess())
        {
            ASSERT_IFNOT(
                entries.size() == static_cast<size_t>(1),
                "entries.size() == static_cast<size_t>(1)");

            Reply = NamingMessage::GetResolvePartitionReply(entries[0]);
        }

        CompleteOrRetry(asyncOperation->Parent, error);
    }
ErrorCode CodePackageDescription::WriteToXml(XmlWriterUPtr const & xmlWriter)
{
	//<CodePackage>
	ErrorCode er = xmlWriter->WriteStartElement(*SchemaNames::Element_CodePackage, L"", *SchemaNames::Namespace);
	if (!er.IsSuccess())
	{
		return er;
	}
	er = xmlWriter->WriteAttribute(*SchemaNames::Attribute_Name, this->Name);
	if (!er.IsSuccess())
	{
		return er;
	}
	er = xmlWriter->WriteAttribute(*SchemaNames::Attribute_Version, this->Version);
	if (!er.IsSuccess())
	{
		return er;
	}
	er = xmlWriter->WriteBooleanAttribute(*SchemaNames::Attribute_IsShared,
		this->IsShared);
	if (!er.IsSuccess())
	{
		return er;
	}
	if (this->HasSetupEntryPoint)
	{
		er = WriteSetupEntryPoint(xmlWriter);
		if (!er.IsSuccess())
		{
			return er;
		}
	}

	er = WriteEntryPoint(xmlWriter);
	if (!er.IsSuccess())
	{
		return er;
	}
	//</CodePackage>
	return xmlWriter->WriteEndElement();
}
Ejemplo n.º 20
0
ErrorCode SecurityUser::SetupGroupMembershipForNewUser()
{
    ErrorCode error = SecurityPrincipalHelper::AddMemberToLocalGroup(FabricConstants::WindowsFabricAllowedUsersGroupName, AccountName);

    ASSERT_IF(error.IsError(ErrorCodeValue::AlreadyExists) && 
        AccountType == SecurityPrincipalAccountType::LocalUser,
        "AddMemberToLocalGroup cannot return AlreadyExists after a new account was created");

    if (!error.IsSuccess() &&
        !error.IsError(ErrorCodeValue::AlreadyExists))
    {
        return error;
    }

    error = BufferedSid::CreateSPtr(AccountName, sid_);
    if (!error.IsSuccess())
    {
        return error;
    }

    // Add the user to the desired groups
    for (auto it = parentApplicationGroups_.begin(); it != parentApplicationGroups_.end(); ++it)
    {
        // The group should have been created previously
        // by the app environment manager
        error = SecurityPrincipalHelper::AddMemberToLocalGroup(
            *it /*parentGroup*/, 
            AccountName /*memberToAdd*/);
        if (!error.IsSuccess() &&
            !error.IsError(ErrorCodeValue::AlreadyExists))
        {
            return error;
        }
    }

    for (auto it = parentSystemGroups_.begin(); it != parentSystemGroups_.end(); ++it)
    {
        if(AccountHelper::GroupAllowsMemberAddition(*it))
        {
            error = SecurityPrincipalHelper::AddMemberToLocalGroup(
                *it /*parentGroup*/, 
                AccountName /*memberToAdd*/);
            if (!error.IsSuccess() &&
                !error.IsError(ErrorCodeValue::AlreadyExists))
            {
                return error;
            }
        }
        else
        {
            WriteInfo(
                TraceSecurityUser,
                "Skip adding account {0} to group {1} since members cannot be added",
                AccountName,
                *it);
            error = BufferedSid::CreateSPtr(WinLocalSid, sidToAdd_);
            if(!error.IsSuccess())
            {
                return error;
            }
        }
    }
    return ErrorCode(ErrorCodeValue::Success);
}
void ReplicasUpdateOperation::ProcessReplica(
    ReplicasUpdateOperationSPtr const & thisSPtr,
    FailoverManager & failoverManager,
    FailoverUnitInfo && failoverUnitInfo,
    bool isDropped)
{
    failoverManager.FTEvents.FTReplicaUpdateReceive(failoverUnitInfo.FailoverUnitDescription.FailoverUnitId.Guid, failoverUnitInfo, isDropped);

    ASSERT_IF(
        failoverManager.IsMaster != (failoverUnitInfo.FailoverUnitDescription.FailoverUnitId.Guid == Constants::FMServiceGuid),
        "Invalid FailoverUnit in ReplicaUp: {0}", failoverUnitInfo);

    auto serviceInfo = failoverManager.ServiceCacheObj.GetService(failoverUnitInfo.ServiceDescription.Name);
    if (serviceInfo)
    {
        if (serviceInfo->ServiceDescription.Instance > failoverUnitInfo.ServiceDescription.Instance)
        {
            failoverManager.WriteInfo(
                "ReplicaUpdate", wformatString(failoverUnitInfo.FailoverUnitDescription.FailoverUnitId),
                "Ignoring report for {0} as a newer version of the service exists.\r\nExisting: {1}\r\nIncoming: {2}",
                failoverUnitInfo.FailoverUnitDescription.FailoverUnitId, serviceInfo->ServiceDescription, failoverUnitInfo.ServiceDescription);

            AddResult(failoverManager, move(failoverUnitInfo), true);
            return;
        }
        else if (serviceInfo->ServiceDescription.Instance == failoverUnitInfo.ServiceDescription.Instance &&
                 serviceInfo->ServiceDescription.UpdateVersion < failoverUnitInfo.ServiceDescription.UpdateVersion)
        {
            ServiceDescription serviceDescription = failoverUnitInfo.ServiceDescription;
            ErrorCode error = failoverManager.ServiceCacheObj.UpdateService(move(serviceDescription));
            if (!error.IsSuccess())
            {
                AddRetry(failoverManager, move(failoverUnitInfo));
                return;
            }
        }
    }

    if (isDropped)
    {
        if (failoverUnitInfo.LocalReplica.IsUp || !failoverUnitInfo.LocalReplica.IsDropped)
        {
            TRACE_AND_TESTASSERT(
                failoverManager.WriteError,
                "ReplicaUpdate", wformatString(failoverUnitInfo.FailoverUnitDescription.FailoverUnitId),
                "Invalid Dropped replica from {0}: {1}", from_, failoverUnitInfo);

            return;
        }
    }

    FailoverUnitId failoverUnitId = failoverUnitInfo.FailoverUnitDescription.FailoverUnitId;
    ReplicaUpdateTask* pTask = new ReplicaUpdateTask(thisSPtr, failoverManager, move(failoverUnitInfo), isDropped, from_); 
    DynamicStateMachineTaskUPtr task(pTask);

    while (task)
    {
        bool result = failoverManager.FailoverUnitCacheObj.TryProcessTaskAsync(failoverUnitId, task, from_, false);
        if (!result)
        {
            ErrorCode error = pTask->ProcessMissingFailoverUnit();
            if (!error.IsError(ErrorCodeValue::FMFailoverUnitAlreadyExists))
            {
                if (!error.IsSuccess())
                {
                    SetError(error, failoverManager, failoverUnitId);
                }

                task = nullptr;
            }
        }
    }
}
void Replicator::ChangeRoleAsyncOperation::OnStart(
    AsyncOperationSPtr const & thisSPtr)
{
    ErrorCode error;
    bool shouldComplete = false;
    FABRIC_SEQUENCE_NUMBER cachedProgress = Constants::NonInitializedLSN;
    ReplicatorState::Action nextAction;
    FABRIC_REPLICA_ROLE presentRole;
        
    {
        AcquireWriteLock lock(parent_.lock_);

        presentRole = parent_.state_.role_;
        error = parent_.state_.TransitionToChangingRole(newRole_, nextAction);
        if (!error.IsSuccess())
        {
            ReplicatorEventSource::Events->ReplicatorChangeRoleInvalid(
                parent_.partitionId_,
                parent_.endpointUniqueId_,
                static_cast<int>(presentRole),
                static_cast<int>(newRole_));
            shouldComplete = true;
        }
        else
        {
            ReplicatorEventSource::Events->ReplicatorChangeRole(
                parent_.partitionId_,
                parent_.endpointUniqueId_, 
                static_cast<int>(presentRole),
                static_cast<int>(newRole_), 
                epoch_.DataLossNumber,
                epoch_.ConfigurationNumber);
            
            // Make a copy of all data structures needed outside the lock
            cachedProgress = parent_.stateProviderInitialProgress_;
            secondaryCopy_ = parent_.secondary_;
            primaryCopy_ = parent_.primary_;
        }
    }

    if (shouldComplete)
    {
        TryComplete(thisSPtr, error);
        return;
    }
    else if (nextAction == ReplicatorState::None)
    {
        error = parent_.state_.TransitionToRoleNone();
        TryComplete(thisSPtr, error);
        return;
    }

    switch (nextAction)
    {
    case ReplicatorState::CreateInitialPrimary:
        CreateInitialPrimary(cachedProgress, thisSPtr);
        break;
    case ReplicatorState::CreateInitialSecondary:
        error = CreateInitialSecondary();
        TryComplete(thisSPtr, error);
        break;
    case ReplicatorState::PromoteSecondaryToPrimary:
        // Promote Idle/Active Secondary to Primary
        // Old secondary must be closed;
        // after close, the new primary will be created using the secondary queue
        CloseSecondary(thisSPtr, true);
        break;
    case ReplicatorState::DemotePrimaryToSecondary:
        // Promote Primary to secondary
        // Old primary must be closed, and a secondary will be created
        ClosePrimary(thisSPtr, true);
        break;
    case ReplicatorState::PromoteIdleToActive:
        PromoteIdleToActive(thisSPtr);
        break;
    case ReplicatorState::ClosePrimary:
        ASSERT_IFNOT(parent_.state_.Role == FABRIC_REPLICA_ROLE_NONE, "{0}: Replicator ChangeRole can close the primary only when transitioning to role NONE", parent_.endpointUniqueId_);
        ClosePrimary(thisSPtr);
        break;
    case ReplicatorState::CloseSecondary:
        CloseSecondary(thisSPtr);
        break;
    default:
        // Nothing to do
        break;
    }
}
void Replicator::ChangeRoleAsyncOperation::FinishCloseSecondary(AsyncOperationSPtr const & asyncOperation, bool createPrimary)
{
    ErrorCode error = secondaryCopy_->EndClose(asyncOperation);
    bool reportFault = false;

    {
        AcquireWriteLock lock(parent_.lock_);
        if (error.IsSuccess())
        {
            if (createPrimary)
            {
                // Promote Secondary -> Primary
                // Pass the specified epoch instead of the secondary one,
                // since the secondary only keeps the invalidated epoch
                error = parent_.state_.TransitionToPrimary();
                if (error.IsSuccess())
                {
                    secondaryCopy_->CreatePrimary(
                        epoch_,
                        parent_.perfCounters_,
                        parent_.healthClient_,
                        parent_.apiMonitor_,
                        /*out*/parent_.primary_);

                    primaryCopy_ = parent_.primary_;
                    parent_.secondary_ = nullptr;
                }
            }
            else
            {
                error = parent_.state_.TransitionToRoleNone();
                if (error.IsSuccess())
                {
                    parent_.secondary_ = nullptr;
                }
            }
        }

        if (parent_.secondary_ != nullptr)
        {
            parent_.state_.TransitionToFaulted();
            reportFault = true;
        }
    }

    if (primaryCopy_)
    {
        Threadpool::Post([this, asyncOperation]()
        {
            this->ScheduleOpenPrimaryAndUpdateEpoch(asyncOperation->Parent);
        });
    }
    else
    {
        if (reportFault)
        {
            secondaryCopy_->SetReportedFault(error, L"FinishCloseSecondary");
        }

        this->TryComplete(asyncOperation->Parent, error);
    }
}
Ejemplo n.º 24
0
HRESULT ComTestStoreService::BeginOpen( 
    /* [in] */ FABRIC_REPLICA_OPEN_MODE openMode,
    /* [in] */ IFabricStatefulServicePartition *statefulServicePartition,
    /* [in] */ IFabricAsyncOperationCallback *callback,
    /* [retval][out] */ IFabricAsyncOperationContext **context)
{
    UNREFERENCED_PARAMETER(openMode);

    if (statefulServicePartition == NULL || callback == NULL || context == NULL) { return E_POINTER; }

    TestSession::FailTestIfNot(openMode == FABRIC_REPLICA_OPEN_MODE::FABRIC_REPLICA_OPEN_MODE_NEW, "Wrong open mode is passed in for volatile service");

    ComPointer<IFabricStatefulServicePartition3> partition;
    // TODO: tempPartition below is used for replicator only, remove when everything is switched to IFabricStatefulServicePartition1 interface (RDBug 3114076)
    ComPointer<IFabricStatefulServicePartition> tempPartition;
    partition.SetAndAddRef((IFabricStatefulServicePartition3*)statefulServicePartition);
    tempPartition.SetAndAddRef(statefulServicePartition);

    CheckForReportFaultsAndDelays(tempPartition, ApiFaultHelper::Service, L"BeginOpen");


    if (testStoreService_.ShouldFailOn(ApiFaultHelper::Service, L"BeginOpen")) 
    {
        return E_FAIL;
    }

    ComPointer<ComCompletedAsyncOperationContext> operation = make_com<ComCompletedAsyncOperationContext>();
    HRESULT hr = E_FAIL;
    bool streamFaultsAndRequireServiceAckEnabled = false;

    if (testStoreService_.ShouldFailOn(ApiFaultHelper::Service, L"EndOpen")) 
    {
        hr = operation->Initialize(E_FAIL, ApiFaultHelper::Get().GetAsyncCompleteDelayTime(), root_, callback);
    }
    else
    {
        Common::ScopedHeap heap;
        ComPointer<IFabricStateReplicator> stateReplicator;
        ComPointer<IFabricReplicator> replicationEngine;
        FABRIC_REPLICATOR_SETTINGS replicatorSettings = { 0 };
        FABRIC_REPLICATOR_SETTINGS_EX1 replicatorSettingsEx1 = { 0 };
        FABRIC_REPLICATOR_SETTINGS_EX2 replicatorSettingsEx2 = { 0 };
        FABRIC_REPLICATOR_SETTINGS_EX3 replicatorSettingsEx3 = { 0 };
        FABRIC_REPLICATOR_SETTINGS_EX4 replicatorSettingsEx4 = { 0 };

        replicatorSettings.Flags = FABRIC_REPLICATOR_SETTINGS_NONE; // no memory limit, default number of items limit = 1024.
        replicatorSettings.Reserved = &replicatorSettingsEx1;
        replicatorSettingsEx1.Reserved = &replicatorSettingsEx2;
        replicatorSettingsEx2.Reserved = &replicatorSettingsEx3;
        replicatorSettingsEx3.Reserved = &replicatorSettingsEx4;
        replicatorSettingsEx4.Reserved = NULL;

		ReplicatorSettingServiceInitDataParser rsParser(testStoreService_.InitDataString);
        auto inputReplicatorSettings = rsParser.CreateReplicatorSettings(testStoreService_.InitDataString, testStoreService_.GetPartitionId());
        inputReplicatorSettings->ToPublicApi(heap, replicatorSettings);

        HRESULT result = partition->CreateReplicator(this, &replicatorSettings, replicationEngine.InitializationAddress(), stateReplicator.InitializationAddress());
        TestSession::FailTestIfNot(result == S_OK, "GetReplicator did not return success");
        TestSession::FailTestIfNot((bool) stateReplicator, "stateReplicator is null");
        TestSession::FailTestIfNot((bool) replicationEngine, "replicationEngine is null");

        ComPointer<ComTestReplicator> testReplicator = make_com<ComTestReplicator>(replicationEngine, tempPartition, false, testStoreService_.ServiceName, testStoreService_.NodeId);
        result = testReplicator->QueryInterface(IID_IFabricReplicator, reinterpret_cast<void**>(replicationEngine_.InitializationAddress()));
        TestSession::FailTestIfNot(result == S_OK, "testReplicator->QueryInterface did not return success");

        ErrorCode error = testStoreService_.OnOpen(partition, stateReplicator, streamFaultsAndRequireServiceAckEnabled);
        TestSession::FailTestIfNot(error.IsSuccess(), "testStoreService_.OnOpen failed with error {0}", error);

        hr = operation->Initialize(root_, callback);
    }

    TestSession::FailTestIf(FAILED(hr), "operation->Initialize should not fail");
    return ComAsyncOperationContext::StartAndDetach<ComCompletedAsyncOperationContext>(std::move(operation), context);
}
void ProcessReportRequestAsyncOperation::HandleRequest(Common::AsyncOperationSPtr const & thisSPtr)
{
    if (this->Request.Action != HealthManagerTcpMessage::ReportHealthAction)   
    {
        TRACE_LEVEL_AND_TESTASSERT(
            this->WriteInfo,
            TraceComponent,
            "{0}: ProcessReportRequestAsyncOperation received action {1}, not supported",
            this->TraceId,
            this->Request.Action);

        TryComplete(thisSPtr, ErrorCode(ErrorCodeValue::InvalidMessage));
        return;
    }

    ReportHealthMessageBody messageBody;
    if (!this->Request.GetBody(messageBody))
    {
        TRACE_LEVEL_AND_TESTASSERT(this->WriteInfo, TraceComponent, "{0}: Error getting ReportHealthMessageBody", this->TraceId);

        TryComplete(thisSPtr, ErrorCode(ErrorCodeValue::InvalidMessage));
        return;
    }

    auto requests = messageBody.MoveEntries();
    auto sequenceStreamsInfo = messageBody.MoveSequenceStreamInfo();

    vector<SequenceStreamRequestContext> ssContexts;
    map<SequenceStreamId, ErrorCodeValue::Enum> rejectedSequences;
    
    for (auto it = sequenceStreamsInfo.begin(); it != sequenceStreamsInfo.end(); ++it)
    {
        SequenceStreamId id(it->Kind, it->SourceId);
        ErrorCode error = this->EntityManager.AcceptSequenceStream(currentNestedActivityId_, id, it->Instance, it->UpToLsn);
        if (error.IsSuccess())
        {
            auto pendingCount = it->ReportCount;
            if (pendingCount == 0)
            {
                currentNestedActivityId_.IncrementIndex();
                ssContexts.push_back(
                    SequenceStreamRequestContext(
                        Store::ReplicaActivityId(this->ReplicaActivityId.PartitionedReplicaId, currentNestedActivityId_), 
                        thisSPtr, 
                        *this, 
                        move(*it)));
            }
            else
            {
                sequenceStreams_.push_back(SequenceStreamWithPendingCountPair(move(*it), pendingCount));
            }
        }
        else
        {
            this->WriteInfo(
                TraceComponent,
                "{0}: Rejecting sequence stream {1}: {2}",
                this->TraceId,
                *it,
                error);
            rejectedSequences[id] = error.ReadValue();
        }
    }

    // Create request contexts and pass them to the cache manager.
    // If any of the requests are accepted, wait for them to be processed.
    // The context will keep track of this async operation and notify it with the result of the processing.
    vector<ReportRequestContext> contexts;
    uint64 reportIndex = 0;
    this->EntityManager.HealthManagerCounters->OnHealthReportsReceived(requests.size());

    for (auto it = requests.begin(); it != requests.end(); ++it)
    {
        // Create a health report result which takes the primary key from the report.
        // For node, it uses the node id generated on the client. For server processing, 
        // the report node id is re-computed to use the server configure generated data.
        HealthReportResult result(*it);

        if (it->SequenceNumber <= FABRIC_INVALID_SEQUENCE_NUMBER)
        {
            // If the new report has invalid LSN, reject immediately
            HMEvents::Trace->DropReportInvalidSourceLSN(this->TraceId, *it);
            result.Error = ErrorCodeValue::HealthStaleReport;
        }
        else
        {
            SequenceStreamId id(it->Kind, it->SourceId);
            auto itReject = rejectedSequences.find(id);
            if (itReject != rejectedSequences.end())
            {
                result.Error = itReject->second;
            }
            else
            {
                // Check whether there is a sequence stream associated with this context
                FABRIC_SEQUENCE_NUMBER fromLsn = FABRIC_INVALID_SEQUENCE_NUMBER;
                FABRIC_SEQUENCE_NUMBER upToLsn = FABRIC_INVALID_SEQUENCE_NUMBER;
                for (auto itSS = sequenceStreams_.begin(); itSS != sequenceStreams_.end(); ++itSS)
                {
                    if (itSS->first.IsHealthInformationRelevant(*it))
                    {
                        fromLsn = itSS->first.FromLsn;
                        upToLsn = itSS->first.UpToLsn;
                        break;
                    }
                }

                // Create a context that will be given to the cache entity manager
                // for processing
                currentNestedActivityId_.IncrementIndex();
                if (HealthEntityKind::CanAccept(it->Kind))
                {
                    contexts.push_back(ReportRequestContext(
                        Store::ReplicaActivityId(this->ReplicaActivityId.PartitionedReplicaId, currentNestedActivityId_),
                        thisSPtr,
                        *this,
                        reportIndex,
                        move(*it),
                        fromLsn,
                        upToLsn));                  
                }
                else
                {
                    WriteInfo(TraceComponent, "{0}: Invalid context kind {1}", currentNestedActivityId_, it->Kind);
                    // Complete the report with error
                    result.Error = ErrorCodeValue::InvalidArgument;
                }
            }
        }

        // Remember the entry in the vector of results.
        // The error code will be set after the request is processed.
        // The correlation is done using the reportIndex.
        // Add under the lock, as it may race with the timeout timer
        // if a very small timeout is provided.
        { // lock
            AcquireExclusiveLock lock(lock_);
            reportResults_.push_back(move(result));
        } // endlock

        ++reportIndex;
    }

    requestCount_ = static_cast<uint64>(contexts.size());
    uint64 initialCount = requestCount_;
    if (!ssContexts.empty())
    {
        // Increment number of requests that need to complete in order
        // to consider the work for this async operation done.
        requestCount_ += ssContexts.size();
        // Remember request count before changed in callback by contexts being completed
        initialCount = requestCount_;
    }

    // Start timer after everything is initialized, to prevent races when the timeout is really small
    // and fires before the global variables are initialized.
    TimedAsyncOperation::OnStart(thisSPtr);

    for (auto && ssContext : ssContexts)
    {
        this->EntityManager.AddSequenceStreamContext(move(ssContext));
    }

    this->EntityManager.AddReports(move(contexts));
    CheckIfAllRequestsProcessed(thisSPtr, initialCount);    
}
    void RemoveServiceAtNameOwnerAsyncOperation::StartRemoveService(AsyncOperationSPtr const & thisSPtr)
    {
        TransactionSPtr txSPtr;
        ErrorCode error = store_.CreateTransaction(this->ActivityHeader, txSPtr);

        if (!error.IsSuccess())
        {
            this->TryComplete(thisSPtr, error);
            return;
        }

        auto nameString = name_.ToString();

        NameData nameData;
        _int64 nameSequenceNumber = -1;

        error = store_.TryReadData(
            txSPtr,
            Constants::NonHierarchyNameEntryType, 
            nameString,
            nameData,
            nameSequenceNumber);

        if (!error.IsSuccess())
        {
            WriteInfo(
                TraceComponent,
                "{0} cannot read name {1} for delete service: error = {2}",
                this->TraceId,
                name_,
                error);

            if (error.IsError(ErrorCodeValue::NotFound))
            {
                error = ErrorCodeValue::NameNotFound;
            }
        }

        if (error.IsSuccess() &&  nameData.ServiceState == UserServiceState::None)
        {
            WriteInfo(
                TraceComponent,
                "{0} user service not found at name owner for {1}",
                this->TraceId,
                name_);

            error = ErrorCodeValue::UserServiceNotFound;
        }

        if (error.IsSuccess())
        {
            if (!isDeletionComplete_)
            {
                if (UserServiceState::IsDeleting(nameData.ServiceState))
                {
                    // Optimization: dont' re-write tentative state
                    NamingStore::CommitReadOnly(move(txSPtr));
                    this->TryComplete(thisSPtr, ErrorCodeValue::Success);
                    return;
                }
                else
                {
                    nameData.ServiceState = UserServiceState::Deleting;
                }
            }
            else
            {
                nameData.ServiceState = UserServiceState::None;
            }

            error = store_.TryWriteData<NameData>(
                txSPtr,
                nameData,
                Constants::NonHierarchyNameEntryType,
                nameString,
                nameSequenceNumber);
        }

        if (error.IsSuccess() && isDeletionComplete_)
        {
            wstring const & storeType = Constants::UserServiceDataType;
            _int64 psdSequenceNumber = -1;

            error = store_.TryGetCurrentSequenceNumber(txSPtr, storeType, nameString, psdSequenceNumber);

            if (error.IsSuccess())
            {
                error = store_.DeleteFromStore(txSPtr, storeType, nameString, psdSequenceNumber);
            }
            else if (error.IsError(ErrorCodeValue::NotFound))
            {
                error = ErrorCodeValue::Success;
            }
        }

        if (error.IsSuccess())
        {
            auto operation = NamingStore::BeginCommit(
                move(txSPtr),
                timeoutHelper_.GetRemainingTime(),
                [this](AsyncOperationSPtr const & operation) { this->OnCommitComplete(operation, false); },
                thisSPtr);
            this->OnCommitComplete(operation, true);
        }
        else
        {
            txSPtr.reset();
            this->TryComplete(thisSPtr, error);
        }
    }
ErrorCode ApplicationManifestDescription::WriteToXml(XmlWriterUPtr const & xmlWriter)
{
	//<ApplicationManifest>
	ErrorCode er = xmlWriter->WriteStartElement(*SchemaNames::Element_ApplicationManifest, L"", *SchemaNames::Namespace);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	er = xmlWriter->WriteAttribute(*SchemaNames::Attribute_ApplicationTypeName, this->Name);
	if (!er.IsSuccess())
	{
		return er;
	}
	er = xmlWriter->WriteAttribute(*SchemaNames::Attribute_ApplicationTypeVersion, this->Version);
	if (!er.IsSuccess())
	{
		return er;
	}

	if (!this->ManifestId.empty())
	{
		er = xmlWriter->WriteAttribute(*SchemaNames::Attribute_ManifestId, this->ManifestId);
		if (!er.IsSuccess())
		{
			return er;
		}
	}

	er = xmlWriter->WriteElementWithContent(*SchemaNames::Element_Description, this->Description, L"", *SchemaNames::Namespace);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	er = WriteParameters(xmlWriter);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	for (auto i = 0; i < ServiceManifestImports.size(); i++)
	{
		er = ServiceManifestImports[i].WriteToXml(xmlWriter);
		if (!er.IsSuccess())
		{
			return er;
		}
	}
	xmlWriter->Flush();
	
	er = WriteServiceTemplates(xmlWriter);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	er = WriteDefaultServices(xmlWriter);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	er = Principals.WriteToXml(xmlWriter);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	er = Policies.WriteToXml(xmlWriter);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	er = Diagnostics.WriteToXml(xmlWriter);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	er = WriteCertificates(xmlWriter);
	if (!er.IsSuccess())
	{
		return er;
	}
	xmlWriter->Flush();
	er = xmlWriter->WriteEndElement();
	if (!er.IsSuccess())
	{
		return er;
	}
	//</ApplicationManifest>
	return xmlWriter->Flush();
}