Client Side Negotiation Example

In the scenario described at Negotiation Scenario, the negotiation process is driven by the consumer. Please refer to Sample Negotiator Client for detailed implementation.

  1. Pre-negotiation - In this phase we describe all required steps, which need to be done before the negotiation step can be started.
    1. First all agreement factories are loaded and then an agreement factory having "SAMPLE-INSTANCE-1" resource id is selected.
      AgreementFactoryClient[] factories = getAgreementFactoryClients();
      AgreementFactoryClient factory = null;
      
      if(factories[0].getResourceId().equals(FACTORY_RESOURCE_ID)) {
          factory = getAgreementFactoryClients()[0];
      }
      else {
          factory = getAgreementFactoryClients()[1];
      }
      
    2. Now we create a negotiation context that defines the roles and obligations of the negotiating parties and specifies the type of the negotiation process.
      NegotiationContextDocument negContextDoc = NegotiationContextDocument.Factory.newInstance();
      NegotiationContextType negContext = negContextDoc.addNewNegotiationContext();
      negContext.setAgreementFactoryEPR(factory.getEndpoint());
      negContext.setAgreementResponder(NegotiationRoleType.NEGOTIATION_RESPONDER);
      GregorianCalendar expireDate = new GregorianCalendar();
      expireDate.add(Calendar.HOUR, 1);
      negContext.setExpirationTime(expireDate);
      
    3. After creating the negotiation context, we have to set the nature of the negotiation process (e.g. negotiation or re-negotiation of already created agreement).
      NegotiationType negotiationType = negContext.addNewNegotiationType();
      negotiationType.addNewNegotiation();
      
    4. Then we can create a negotiation instance based on a negotiation context from a selected agreement factory.
      NegotiationClient negotiation = factory.initiateNegotiation(negContext);
      
    5. To start the negotiation process, we have to retrieve the agreement templates for which negotiation is supported, and select the one we are interested to negotiate SLA, for instance the one with the template name "SAMPLE-TEMPLATE".
      AgreementTemplateType[] negotiableTemplates = negotiation.getNegotiableTemplates();
      AgreementTemplateType template = null;
      
      for (int i = 0; i < negotiableTemplates.length; i++) {
          AgreementTemplateType agreementTemplate = negotiableTemplates[i];
      
          if(agreementTemplate.getName().equals(TEMPLATE_NAME)) {
              template = agreementTemplate;
          }
      }
      
    6. The "SAMPLE-TEMPLATE" template exposes the current availability of computing resources by a resource provider.
      SampleAgreementTemplate negotiationTemplate = new SampleAgreementTemplate(template);
      String offerID = negotiationTemplate.getContext().getTemplateId() + "-" + negotiationTemplate.getName();
      
  2. First negotiation iteration - In the first iteration of the negotiation process, we have to use the created template and define all our requirements. Such definitions are exposed as Service Description Terms (SDT).
    1. This template includes the SDT 'RESOURCE_SDT' with a JSDL document describing the available compute resources.
      <wsag:ServiceDescriptionTerm wsag:Name="RESOURCE_STD" wsag:ServiceName="SAMPLE-NEGOTIATION_SERVICE">
        <jsdl:JobDefinition xmlns:jsdl="http://schemas.ggf.org/jsdl/2005/11/jsdl">
          <jsdl:JobDescription>
            <jsdl:Resources>
              <jsdl:CandidateHosts>
                <jsdl:HostName>some_host</jsdl:HostName>
              </jsdl:CandidateHosts>
              <jsdl:TotalResourceCount>
                <jsdl:Exact>$TOTALRESOURCES</jsdl:Exact>
              </jsdl:TotalResourceCount>
            </jsdl:Resources>
          </jsdl:JobDescription>
        </jsdl:JobDefinition>
      </wsag:ServiceDescriptionTerm>
      

      We negotiate 5 resources (*TotalResourceCount*).

      ResourcesType jobResources_1 = negotiationTemplate.getResourceDefinition();
      
      RangeValueType totalCountRange_1 = RangeValueType.Factory.newInstance();
      totalCountRange_1.addNewExact().setDoubleValue(5);
      jobResources_1.setTotalResourceCount(totalCountRange_1);
      
    2. The SDT 'TIME_CONSTRAINT_SDT' defines the time frame during which the resources are available.
      <wsag:ServiceDescriptionTerm wsag:Name="TIME_CONSTRAINT_SDT" wsag:ServiceName="SAMPLE-NEGOTIATION_SERVICE">
           <wsag4jt:TimeConstraint xmlns:wsag4jt="http://schemas.wsag4j.org/2009/07/wsag4j-scheduling-extensions">
             <wsag4jt:StartTime>$STARTTIME</wsag4jt:StartTime>
             <wsag4jt:EndTime>$ENDTIME</wsag4jt:EndTime>
             <wsag4jt:Duration>$DURATION</wsag4jt:Duration>
           </wsag4jt:TimeConstraint>
      </wsag:ServiceDescriptionTerm>
      

      We specify the start time (*StartTime*) as 5 minute ahead of the current time and end time (*EndTime*) after 60 minutes (based on the start time) and the effective duration (*Duration*) of the advance reservation is 15 minutes.

      TimeConstraintType timeConstraint_1 = negotiationTemplate.getTimeConstraint();
      
      Calendar startTime_1 = (Calendar) timeConstraint_1.getStartTime().clone();
      timeConstraint_1.setStartTime(startTime_1);
      
      Calendar endTime_1 = (Calendar) timeConstraint_1.getEndTime().clone();
      timeConstraint_1.setEndTime(endTime_1);
      
      timeConstraint_1.setDuration(15);
      
    3. Now we create a negotiation offer from a negotiable template for the reservation of required resources to fulfill the application execution requirements.
      SampleNegotiationOffer negotiationOffer_1 = negotiationTemplate.getNegotiationOffer();
      negotiationOffer_1.setOfferId(offerID);
      
    4. Creating negotiation offer context.
      NegotiationOfferContextType negOfferContext = NegotiationOfferContextType.Factory.newInstance();
      
      negOfferContext.setCreator(NegotiationRoleType.NEGOTIATION_INITIATOR);
      
      GregorianCalendar expireDate = new GregorianCalendar();
      expireDate.add(Calendar.MINUTE, 5);
      negOfferContext.setExpirationTime(expireDate);
      
      NegotiationOfferStateType negOfferState = NegotiationOfferStateType.Factory.newInstance();
      negOfferState.addNewAdvisory();
      
      negOfferContext.setState(negOfferState);
      negOfferContext.setCounterOfferTo(offerID);
      
      negotiationOffer_1.setNegotiationOfferContext(negOfferContext);
      
    5. One negotiation constraint is added that basically define the preferred time frame window within which the user would like to have the reservation of resources (say within first 45 minutes).
      String CONSTRAINT_ITEM_NAME = "TimeConstraintSDT_TimeConstraint_START_TIME";
      String CONSTRAINT_XPATH = "declare namespace wsag-tc='http://schemas.wsag4j.org/2009/07/wsag4j-scheduling-extensions';" +
                                "declare namespace wsag='http://schemas.ggf.org/graap/2007/03/ws-agreement';" +
                                "$this/wsag:Terms/wsag:All/wsag:ServiceDescriptionTerm[@wsag:Name = 'TIME_CONSTRAINT_SDT']/wsag4jt:TimeConstraint";
      
      NegotiationConstraintSectionType constraints_1 = NegotiationConstraintSectionType.Factory.newInstance();
      
      NegotiationOfferItemType offerItem = constraints.addNewItem();
      offerItem.setName(CONSTRAINT_ITEM_NAME);
      offerItem.setLocation(CONSTRAINT_XPATH);
      
      ItemConstraint constraint = offerItem.addNewItemConstraint();
      
      constraint.addNewMinInclusive().setValue(XmlDateTime.Factory.newValue(timeConstraint_1.getStartTime()));
      Calendar preferredEndTime = (Calendar) timeConstraint_1.getStartTime().clone();
      preferredEndTime.add(Calendar.MINUTE, 45);
      constraint.addNewMaxInclusive().setValue(XmlDateTime.Factory.newValue(preferredEndTime));
      
      negotiationOffer_1.setNegotiationConstraints(constraints_1);
      
    6. Service description terms 'RESOURCE_SDT' and 'TIME_CONSTRAINT_SDT' are updated in a negotiation offer.
      ServiceDescriptionTermType resourcesSDT = null;
      ServiceDescriptionTermType[] sdts = negotiationOffer.getTerms().getAll().getServiceDescriptionTermArray();
      
      if(sdts != null) {
              for (int i = 0; i < sdts.length; i++) {
                      if(sdts[i].getName().equals(resourcesSDTName)) {
                              resourcesSDT = sdts[i];
                          break;
                      }
              }
      }
      
      JobDefinitionDocument resourcesDoc = JobDefinitionDocument.Factory.newInstance();
      resourcesDoc.addNewJobDefinition().addNewJobDescription().addNewResources();
      resourcesDoc.getJobDefinition().getJobDescription().getResources().set(jobResources);
      resourcesSDT.set(resourcesDoc);
      
      String name = resourcesSDT.getName();
      resourcesSDT.setName(name);
      String serviceName = resourcesSDT.getServiceName();
      resourcesSDT.setServiceName(serviceName);
      
      
      ServiceDescriptionTermType timeConstraintSDT = null;
      ServiceDescriptionTermType[] sdts = negotiationOffer.getTerms().getAll().getServiceDescriptionTermArray();
      
      if(sdts != null) {
              for (int i = 0; i < sdts.length; i++) {
                      if(sdts[i].getName().equals(timeConstraintSDTName)) {
                              timeConstraintSDT = sdts[i];
                          break;
                      }
              }
      }
      
      TimeConstraintDocument timeConstraintDoc = TimeConstraintDocument.Factory.newInstance();
      timeConstraintDoc.addNewTimeConstraint();
      timeConstraintDoc.getTimeConstraint().set(timeConstraint);
      timeConstraintSDT.set(timeConstraintDoc);
      
      String name = timeConstraintSDT.getName();
      timeConstraintSDT.setName(name);
      
      String serviceName = timeConstraintSDT.getServiceName();
      timeConstraintSDT.setServiceName(serviceName);
      
    7. Invoking negotiate method from Negotiation instance and in return counter offers are received.
      NegotiationOfferType[] negotiationOfferTypes_1 = {negotiationOffer_1.getXMLObject()};
      NegotiationOfferType[] counterOffers_1 = negotiation.negotiate(negotiationOfferTypes_1);
      
    8. First check whether the negotiation (counter) offer is rejected.
      NegotiationOfferType counterOffer_1 = counterOffers_1[0];
      if(counterOffer_1.getNegotiationOfferContext().getState().isSetRejected()) {
              ... do something ...
      }
      
    9. We receive 2 counter offers with different resource availability.
      1. CounterOffer_1: 5 resources for 20 minutes duration with a time frame as startTime = current + 5, endTime = startTime + 20.
      2. CounterOffer_2: 5 resources for 15 minutes duration with a time frame as startTime = current + 10, endTime = startTime + 30.
  3. Second negotiation iteration
    1. Since both counter offers are not sufficient to fulfill our requirements. Therefore, we create another negotiation offer with 10 resource with 2 CPUs for 30 minutes CPU time. Therefore we use the first returned counter offer.
      SampleNegotiationOffer negotiationOffer_2 = new SampleNegotiationOffer(counterOffer_1);
      
      ResourcesType jobResources_2 = negotiationOffer_2.getResourceDefinition();
      RangeValueType totalCountRange_2 = RangeValueType.Factory.newInstance();
      totalCountRange_2.addNewExact().setDoubleValue(5);
      jobResources_2.setTotalResourceCount(totalCountRange_2);
      
      TimeConstraintType timeConstraint_2 = negotiationOffer_2.getTimeConstraint();
      Calendar startTime_2 = (Calendar) timeConstraint_2.getStartTime().clone();
      startTime_2.add(Calendar.MINUTE, 10);
      timeConstraint_2.setStartTime(startTime_2);
      
      Calendar endTime_2 = (Calendar) startTime_2.clone();
      endTime_2.add(Calendar.MINUTE, 20);
      timeConstraint_2.setEndTime(endTime_2);
      
      timeConstraint_2.setDuration(15);
      
    2. Service description terms 'RESOURCE_SDT' and 'TIME_CONSTRAINT_SDT' are updated in the new offer, which is based on the selected counter offer.
    3. Invoking negotiate method from initial created negotiation instance and in return new counter offers are received. The new created counter offers depend on the passed, new offer we created.
      NegotiationOfferType[] negotiationOfferTypes_2 = {negotiationOffer_2.getXMLObject()};
      NegotiationOfferType[] counterOffers_2 = negotiation.negotiate(negotiationOfferTypes_2);
      
    4. Re-check whether the negotiation (counter) offer is rejected.
      NegotiationOfferType counterOffer_2 = counterOffers_2[0];
      if(counterOffer_2.getNegotiationOfferContext().getState().isSetRejected()) {
              ... do something ...
      }
      
    5. Re-check the counter offers and pick one, that satisfy the requirements. If this is not the case, then we need to start a third iteration or cancel the negotiation process.
      NegotiationOfferType selectedCounterOffer = counterOffers_2[0];
      
    6. Create the agreement based on the selected negotiated offer.
      AgreementOffer offer = new AgreementOfferType(selectedCounterOffer);
      AgreementClient agreement = factory.createAgreement(offer);
      
    7. Finally terminate the negotiation process.
      negotiation.terminate();