

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Scenario di esempio
<a name="java-flow-making-changes-example-scenario"></a>

Esiste una classe di modifiche del codice che è considerata non retrocompatibile. Queste modifiche includono gli aggiornamenti che modificano il numero, il tipo o l'ordine dei task pianificati. Considera il seguente esempio:

Scrivi un codice del decisore per pianificare due task di timer. Avvii un'esecuzione ed esegui una decisione. Di conseguenza, vengono pianificate due attività con timer, con IDs `1` e. `2`

Se aggiorni il codice del decisore per pianificare un solo timer prima che venga eseguita la decisione successiva, nel prossimo task di decisione il framework non riuscirà a riprodurre il secondo evento `TimerFired`, perché l'ID `2` non corrisponde a nessun task di timer prodotto dal codice.

## Struttura dello scenario
<a name="example-scenario-outline"></a>

La struttura seguente mostra le fasi di questo scenario. L'obiettivo finale dello scenario è quello di effettuare la migrazione a un sistema che pianifichi solo un timer ma che non comprometta le esecuzioni avviate prima della migrazione.

1. La versione iniziale del decisore

   1. Scrivi il decisore.

   1. Avvia il decisore.

   1. Il decisore pianifica due timer.

   1. Il decisore avvia cinque esecuzioni.

   1. Arresta il decisore.

1. Una modifica del decisore non retrocompatibile

   1. Modifica il decisore.

   1. Avvia il decisore.

   1. Il decisore pianifica un timer.

   1. Il decisore avvia cinque esecuzioni.

La seguente sezione include esempi di un codice Java che mostrano come implementare questo scenario. Gli esempi di codice nella sezione [Soluzioni](java-flow-making-changes-solutions.md) mostrano vari modi per correggere le modifiche non retrocompatibili.

**Nota**  
Puoi utilizzare la versione più recente di [AWS SDK per Java](https://aws.amazon.com/sdk-for-java/) per eseguire questo codice.

## Codice comune
<a name="common-code"></a>

Il seguente codice Java non cambia tra gli esempi di questo scenario.

`SampleBase.java`

```
package sample;
 
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
 
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
import com.amazonaws.services.simpleworkflow.flow.JsonDataConverter;
import com.amazonaws.services.simpleworkflow.model.DescribeWorkflowExecutionRequest;
import com.amazonaws.services.simpleworkflow.model.DomainAlreadyExistsException;
import com.amazonaws.services.simpleworkflow.model.RegisterDomainRequest;
import com.amazonaws.services.simpleworkflow.model.Run;
import com.amazonaws.services.simpleworkflow.model.StartWorkflowExecutionRequest;
import com.amazonaws.services.simpleworkflow.model.TaskList;
import com.amazonaws.services.simpleworkflow.model.WorkflowExecution;
import com.amazonaws.services.simpleworkflow.model.WorkflowExecutionDetail;
import com.amazonaws.services.simpleworkflow.model.WorkflowType;
 
public class SampleBase {
 
    protected String domain = "DeciderChangeSample";
    protected String taskList = "DeciderChangeSample-" + UUID.randomUUID().toString();
    protected AmazonSimpleWorkflow service = AmazonSimpleWorkflowClientBuilder.defaultClient();
    {
        try {
            AmazonSimpleWorkflowClientBuilder.defaultClient().registerDomain(new RegisterDomainRequest().withName(domain).withDescription("desc").withWorkflowExecutionRetentionPeriodInDays("7"));
        } catch (DomainAlreadyExistsException e) {
        }
    }
 
    protected List<WorkflowExecution> workflowExecutions = new ArrayList<>();
 
    protected void startFiveExecutions(String workflow, String version, Object input) {
        for (int i = 0; i < 5; i++) {
            String id = UUID.randomUUID().toString();
            Run startWorkflowExecution = service.startWorkflowExecution(
                    new StartWorkflowExecutionRequest().withDomain(domain).withTaskList(new TaskList().withName(taskList)).withInput(new JsonDataConverter().toData(new Object[] { input })).withWorkflowId(id).withWorkflowType(new WorkflowType().withName(workflow).withVersion(version)));
            workflowExecutions.add(new WorkflowExecution().withWorkflowId(id).withRunId(startWorkflowExecution.getRunId()));
            sleep(1000);
        }
    }
 
    protected void printExecutionResults() {
        waitForExecutionsToClose();
        System.out.println("\nResults:");
        for (WorkflowExecution wid : workflowExecutions) {
            WorkflowExecutionDetail details = service.describeWorkflowExecution(new DescribeWorkflowExecutionRequest().withDomain(domain).withExecution(wid));
            System.out.println(wid.getWorkflowId() + " " + details.getExecutionInfo().getCloseStatus());
        }
    }
 
    protected void waitForExecutionsToClose() {
        loop: while (true) {
            for (WorkflowExecution wid : workflowExecutions) {
                WorkflowExecutionDetail details = service.describeWorkflowExecution(new DescribeWorkflowExecutionRequest().withDomain(domain).withExecution(wid));
                if ("OPEN".equals(details.getExecutionInfo().getExecutionStatus())) {
                    sleep(1000);
                    continue loop;
                }
            }
            return;
        }
    }
 
    protected void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
 
}
```

`Input.java`

```
package sample;
 
public class Input {
 
    private Boolean skipSecondTimer;
 
    public Input() {
    }
 
    public Input(Boolean skipSecondTimer) {
        this.skipSecondTimer = skipSecondTimer;
    }
 
    public Boolean getSkipSecondTimer() {
        return skipSecondTimer != null && skipSecondTimer;
    }
 
    public Input setSkipSecondTimer(Boolean skipSecondTimer) {
        this.skipSecondTimer = skipSecondTimer;
        return this;
    }
 
}
```

## Scrivere il codice iniziale del decisore
<a name="writing-initial-decider-code"></a>

Di seguito è riportato il codice Java iniziale del decisore. Viene registrato come versione `1` e pianifica due task di timer da cinque secondi.

`InitialDecider.java`

```
package sample.v1;
 
import com.amazonaws.services.simpleworkflow.flow.DecisionContext;
import com.amazonaws.services.simpleworkflow.flow.DecisionContextProviderImpl;
import com.amazonaws.services.simpleworkflow.flow.WorkflowClock;
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute;
import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow;
import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions;
 
import sample.Input;
 
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60, defaultTaskStartToCloseTimeoutSeconds = 5)
public interface Foo {
 
    @Execute(version = "1")
    public void sample(Input input);
 
    public static class Impl implements Foo {
 
        private DecisionContext decisionContext = new DecisionContextProviderImpl().getDecisionContext();
        private WorkflowClock clock = decisionContext.getWorkflowClock();
 
        @Override
        public void sample(Input input) {
            System.out.println("Decision (V1) WorkflowId: " + decisionContext.getWorkflowContext().getWorkflowExecution().getWorkflowId());
            clock.createTimer(5);
            clock.createTimer(5);
        }
 
    }
}
```

## Simulazione di una modifica non retrocompatibile
<a name="simulate-non-backwards-compatible-change"></a>

Il seguente codice Java modificato del decisore è un buon esempio di modifica non retrocompatibile. Il codice è ancora registrato come versione `1`, ma pianifica solo un timer.

`ModifiedDecider.java`

```
package sample.v1.modified;
 
import com.amazonaws.services.simpleworkflow.flow.DecisionContext;
import com.amazonaws.services.simpleworkflow.flow.DecisionContextProviderImpl;
import com.amazonaws.services.simpleworkflow.flow.WorkflowClock;
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute;
import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow;
import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions;
 
import sample.Input;
 
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60, defaultTaskStartToCloseTimeoutSeconds = 5)
public interface Foo {
 
    @Execute(version = "1")
    public void sample(Input input);
 
    public static class Impl implements Foo {
 
        private DecisionContext decisionContext = new DecisionContextProviderImpl().getDecisionContext();
        private WorkflowClock clock = decisionContext.getWorkflowClock();
 
        @Override
        public void sample(Input input) {
            System.out.println("Decision (V1 modified) WorkflowId: " + decisionContext.getWorkflowContext().getWorkflowExecution().getWorkflowId());
            clock.createTimer(5);
        }
 
    }
}
```

Il seguente codice Java ti permette di simulare il problema di apportare modifiche non retrocompatibili eseguendo il decisore modificato.

`RunModifiedDecider.java`

```
package sample;
 
import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker;
 
public class BadChange extends SampleBase {
 
    public static void main(String[] args) throws Exception {
        new BadChange().run();
    }
 
    public void run() throws Exception {
        // Start the first version of the decider
        WorkflowWorker before = new WorkflowWorker(service, domain, taskList);
        before.addWorkflowImplementationType(sample.v1.Foo.Impl.class);
        before.start();
 
        // Start a few executions
        startFiveExecutions("Foo.sample", "1", new Input());
 
        // Stop the first decider worker and wait a few seconds 
        // for its pending pollers to match and return
        before.suspendPolling();
        sleep(2000);
 
        // At this point, three executions are still open, with more decisions to make
 
        // Start the modified version of the decider
        WorkflowWorker after = new WorkflowWorker(service, domain, taskList);
        after.addWorkflowImplementationType(sample.v1.modified.Foo.Impl.class);
        after.start();
 
        // Start a few more executions
        startFiveExecutions("Foo.sample", "1", new Input());
 
        printExecutionResults();
    }
 
}
```

Quando esegui il programma, le tre esecuzioni che non vanno a buon fine sono quelle avviate secondo la versione iniziale del decisore e proseguite dopo la migrazione.