public OfferProposal SaveOfferProposal(string receivingSubscriptionId, string sendingSubscriptionId, Offer offer, string demandId = null, Proposal.StateEnum state = Proposal.StateEnum.InitialEnum) { if (this.SubscriptionProposals.ContainsKey(receivingSubscriptionId) && this.Subscriptions[receivingSubscriptionId] is DemandSubscription) { var offerProposal = new OfferProposal() { Id = "" + Guid.NewGuid(), InternalId = this.GetNextProposalInternalId(), ReceivingSubscriptionId = receivingSubscriptionId, SendingSubscriptionId = sendingSubscriptionId, DemandId = demandId, Offer = offer, State = state }; this.SubscriptionProposals[receivingSubscriptionId].Add(offerProposal); this.OfferProposals[offerProposal.Id] = offerProposal; return(offerProposal); } else { throw new Exception($"Demand Subscription Id {receivingSubscriptionId} does not exist!"); } }
public Agreement CreateAgreement(Demand demand, OfferProposal offerProposal) { if (this.Agreements.ContainsKey(offerProposal.Id)) { throw new Exception($"Agreement Id {offerProposal.Id} already exists!"); } var agreement = new Agreement() { Id = offerProposal.Id, Offer = offerProposal.Offer, Demand = demand, State = AgreementState.New }; this.Agreements[agreement.Id] = agreement; return(agreement); }
public Agreement CreateAgreement(DemandProposal demandProposal, OfferProposal offerProposal, DateTime validTo) { if (this.Agreements.ContainsKey(offerProposal.Id)) { throw new Exception($"Agreement Id {offerProposal.Id} already exists!"); } var agreement = new Agreement() { Id = offerProposal.Id, OfferProposal = offerProposal, DemandProposal = demandProposal, State = AgreementState.Proposal, ValidTo = validTo }; this.Agreements[agreement.Id] = agreement; return(agreement); }
public async Task InMemoryActivityProcessor_Integration_SimplePositiveScenario() { // Test scenario var demand = new Demand() { Constraints = "", NodeId = "DummyRequestorNode1", Properties = new Dictionary <string, string>() }; var offer = new OfferProposal() { DemandId = "dummyDemandId", Id = "DummyProposalId", InternalId = 1, Offer = new Offer() { Constraints = "", NodeId = "DummyProviderNode1", Properties = new Dictionary <string, string>() } }; var agreement = this.AgreementRepository.CreateAgreement(demand, offer); // 1. Create Activity in a known, negotiated agreement var activity = this.RequestorProcessor.CreateActivity(agreement.Id); var provEvents = await this.ProviderProcessor.CollectActivityEventsAsync(offer.Offer.NodeId, 1000); // 2. Send a sample ExeScript command batch var batchId = this.RequestorProcessor.ExecAsync(activity.Id, new ExeScript() { Text = "DEPLOY\nSTART\n" }); // 2.1. Simulate ExeScript execution on Provider side Task.Run(async() => { bool isActivityDestroyed = false; do { provEvents = await this.ProviderProcessor.CollectActivityEventsAsync(offer.Offer.NodeId, 1000); foreach (var provEvent in provEvents) { switch (provEvent.EventType) { case ActivityProviderEvent.ActivityProviderEventType.Exec: var commands = provEvent.ExeScript.Text.Split('\n'); foreach (var command in commands) { if (string.IsNullOrWhiteSpace(command)) { continue; } if (command.Contains("DEPLOY")) { this.ActivityRepository.SetActivityState(activity.Id, ActivityState.Deploying); Thread.Sleep(1000); this.ActivityRepository.SetActivityState(activity.Id, ActivityState.Ready); } if (command.Contains("START")) { this.ActivityRepository.SetActivityState(activity.Id, ActivityState.Starting); Thread.Sleep(1000); this.ActivityRepository.SetActivityState(activity.Id, ActivityState.Terminated); } activity = this.ActivityRepository.GetActivity(activity.Id); this.ProviderProcessor.SendActivityExecResult(activity.Id, batchId, new ActivityExecResult() { CurrentState = activity.State, Result = ActivityExecResult.ActivityExecResultEnum.OK }); } break; case ActivityProviderEvent.ActivityProviderEventType.DestroyActivity: isActivityDestroyed = true; break; } } }while (isActivityDestroyed != true); }); // 2.2. Process the ExeScript results on Requestor side bool isActivityFinished = false; do { var reqEvents = await this.RequestorProcessor.GetExecBatchResultsAsync(batchId, 1000); foreach (var reqEvent in reqEvents) { Assert.AreEqual(ActivityExecResult.ActivityExecResultEnum.OK, reqEvent.ExecResult.Result); if (reqEvent.ExecResult.CurrentState == ActivityState.Terminated) { isActivityFinished = true; } } }while (!isActivityFinished); // 3. Destroy Activity this.RequestorProcessor.DestroyActivity(activity.Id); }
public async Task <OfferProposal> DoSimpleOfferNegotiation(DemandSubscription demandSubscription, OfferSubscription offerSubscription, OfferProposal offerProposal) { // OK, we got an offer proposal, we can now send a direct Demand counterproposal var counterDemand = new Demand() { Constraints = @"(&" + @"(golem.srv.comp.container.docker.image=golemfactory/ffmpeg)" + @"(golem.srv.comp.container.docker.benchmark{golemfactory/ffmpeg}>300)" + @"(golem.com.payment.scheme=after)" + @"(golem.usage.vector=[golem.usage.duration_sec])" + @"(golem.com.pricing.model=linear)" + @"(golem.com.pricing.model.linear.coeffs=*)" + //@"(golem.com.pricing.est{[30]}<125)" + @")", NodeId = "RequestorA", // must be assigned from the outside Properties = new Dictionary <string, string>() }; var counterDemandProposal = RequestorProcessor.CreateDemandProposal(demandSubscription.Id, offerProposal.Id, counterDemand); // At this point, the Provider should be able to read the Demand Proposal on the Offer subscription var provEvents = await ProviderProcessor.CollectProviderEventsAsync(offerSubscription.Id, 1000, 10); Assert.IsTrue(provEvents.Any()); Assert.AreEqual(counterDemandProposal.Id, provEvents.First().DemandProposal.Id); Assert.AreEqual(offerProposal.Id, provEvents.First().DemandProposal.OfferId); // ...if we call again - there should be no proposals, so a timeout is expected after 100ms var provEvents2 = await ProviderProcessor.CollectProviderEventsAsync(offerSubscription.Id, 100, 10); Assert.IsFalse(provEvents2.Any()); // Now test the blocking logic of Collect - hang on Collect on Requestor side, while Provider sends counter-offer ICollection <MarketRequestorEvent> reqEvents2 = null; Task.Run(async() => { reqEvents2 = await RequestorProcessor.CollectRequestorEventsAsync(demandSubscription.Id, 5000, 10); Assert.IsTrue(reqEvents2.Any()); }); // ...and prepare counter-offer with price var counterOffer = new Offer() { Constraints = "()", NodeId = "ProviderB", Properties = new Dictionary <string, string>() { { "golem.srv.comp.container.docker.image", @"[""golemfactory/ffmpeg""]" }, { "golem.srv.comp.container.docker.benchmark{golemfactory/ffmpeg}", @"723" }, { "golem.srv.comp.container.docker.benchmark{*}", null }, { "golem.inf.cpu.cores", @"4" }, { "golem.inf.cpu.threads", @"8" }, { "golem.inf.mem.gib", @"16" }, { "golem.inf.storage.gib", @"30" }, { "golem.usage.vector", @"[""golem.usage.duration_sec""]" }, { "golem.com.payment.scheme", @"""after""" }, { "golem.com.pricing.model", @"""linear""" }, { "golem.com.pricing.model.linear.coeffs", @"[0, 0.2]" }, { "golem.com.pricing.est{*}", null }, } }; var counterOfferProposal = ProviderProcessor.CreateOfferProposal(offerSubscription.Id, provEvents.First().DemandProposal.Id, counterOffer); Thread.Sleep(1000); Assert.IsTrue(reqEvents2.Any()); Assert.AreEqual(counterDemandProposal.Id, reqEvents2.First().OfferProposal.DemandId); return(reqEvents2.First().OfferProposal); }