<commit_before>== Welche Pattern kann ich für eine explizite Versionierung verwenden?

=== Anbieten des Services

=== URI Versioning

[%step]
* Rest und SOAP
* Beispiel http://www.ehmkah.de/v1/service
* Beispiel http://www.ehmkah.de/v2/service
* Vorteil: für SOAP fühlt sich natürlich an
* Nachteil: Passt nicht zu REST Paradigma

[NOTE.speaker]
--
* Nachteil: siehe http://www.baeldung.com/rest-versioning
--

=== URI Versioning (DEMO)

* DEMO (soap_service_impl_v1)
[source, java]
----
@Bean("endpointServiceV1")
  public Endpoint endpointServiceV1(SpringBus springBus) {
    EndpointImpl result = new EndpointImpl(springBus, serviceV1);
    result.setWsdlLocation("classpath:/wsdl/serviceDefinitionV1.wsdl");
    result.publish("/v1/service");

    return result;
  }
----

=== Media Type Versioning

* nur REST
* Beispiel: Header enthält individuellen Mediatype, "Accept": "application/vnd.ehmkah.app-1.0+json"
* Fehler, wenn es nicht passt 406 Not Acceptable

=== Media Type Versioning (DEMO)

* DEMO (rest_service_impl_media_type_versioning)
[source, java]
----
@RequestMapping(method = RequestMethod.GET, produces = "application/vnd.ehmkah.app-1.0+json")
  public ResponseEntity<List<Object>> list(
          @ApiParam(value = "Tags used to filter the result")
  ...
----

=== Unsere Entscheidung

* URI-Versioning
* Grund: viele SOAP Service, Rest Service sind noch nicht ressourcenorientiert

=== Implementieren des Services

=== Mehrfaches Deployen eines Services

[%step]
* Wenn ein Service zwei Versionen implementiert, können einfach beide Versionen gestartet werden
* Vorteile: funktioniert out of the box
* Nachteile: Kosten und Skalierung des Services

* DEMO

=== Code duplizieren

[%step]
* Businesscode wird vollständig kopiert

* DEMO

=== Adapterpattern zwischen Service Versionen (Klassendiagramm)

image::classDiagramConverter.png[background]

[%step]
* empfholen ein reichhaltiges Domainmodel bei grossen Schnittstellen AKA AKM!!), das nicht nach aussen gegeben wird
* wir haben keines konvertieren auf neueste Version des Services (langsameres löschen)
* muss vollständig sein (vereinfacht die Unterstüzung verschiedener Version immens)
* besonders nützlich beim löschen, da bei Konvertierung auf neue Schnittstellenversion Informationen gelöscht werden
können


=== Adapterpattern zwischen Service Versionen (Sequenzdiagram)

image::sequenceConverter.png[background]



=== Adapterpattern zwischen Versionen eines Services (Modelmapper)

[%step]
* konvertiert zwischen einer alten Version zu einer neuen Version
* Vorteil: für einfache Schnittstellen OK, da schnell aufgesetzt
* Nachteil: Probleme bei Typhierachien
* Nachteil: Automatismus des Mappings teilweise nicht durchschaubar
* Nachteil: Manuelle Anpassungen am Mapping kompliziert
* Nachteil: Teilweise Performanceprobleme
* Nachteil: COnvertierung müsste getestet werden

[NOTE.speaker]
--
* War unser erster Versuch (mit Modelmapper, dozer)
--

=== Adapterpattern zwischen Versionen eines Services (Modelmapper)

.Converter.map
[source,java]
----
private ModelMapper modelMapper = new ModelMapper();

    public com.ehmkah.services.gardening.RequestType map(RequestType requestV1) {
      com.ehmkah.services.gardening.RequestType result =
      modelMapper.map(requestV1, com.ehmkah.services.gardening.RequestType.class);

      return result;
    }
----


=== Adapterpattern zwischen Versionen eines Services (händisch)

[%step]
* TODO: Abbildung wie COnverter funktioniert
* konvertiert zwischen einer alten Version zu einer neuen Version
* Vorteil:
* Nachteil:

[NOTE.speaker]
--
* wir generieren den Mapper mit Javapoet und Java Reflektions
* passen an, wenn generiertes Mapping nicht passt
--

=== Adapterpattern zwischen Versionen eines Services (händisch)

.Converter.map
[source,java]
----
public com.ehmkah.services.gardening.RequestType map(RequestType requestV1) {
    com.ehmkah.services.gardening.RequestType result =
    new com.ehmkah.services.gardening.RequestType();
    result.setSpeciesOne(requestV1.getSpeciesOne());
    result.setSpeciesTwo(requestV1.getSpeciesTwo());

    return result;
  }
----

=== Adapterpattern zwischen Versionen eines Services (händisch)

* Einsatz eines Generators (und manuelles nachziehen der Änderungen)

=== Soap Message dispatcher?
und noch so nen anderes Ding von IBM /ORacle???<commit_msg>* zwischenstand<commit_after>== Welche Pattern kann ich für eine explizite Versionierung verwenden?

=== Anbieten des Services

=== URI Versioning

[%step]
* Rest und SOAP
* Beispiel http://www.ehmkah.de/v1/service
* Beispiel http://www.ehmkah.de/v2/service
* Vorteil: für SOAP fühlt sich natürlich an
* Nachteil: Passt nicht zu REST Paradigma

[NOTE.speaker]
--
* Nachteil: siehe http://www.baeldung.com/rest-versioning
--

=== URI Versioning (DEMO)

* DEMO (soap_service_impl_v1)
[source, java]
----
@Bean("endpointServiceV1")
  public Endpoint endpointServiceV1(SpringBus springBus) {
    EndpointImpl result = new EndpointImpl(springBus, serviceV1);
    result.setWsdlLocation("classpath:/wsdl/serviceDefinitionV1.wsdl");
    result.publish("/v1/service");

    return result;
  }
----

=== Media Type Versioning

* nur REST
* Beispiel: Header enthält individuellen Mediatype, "Accept": "application/vnd.ehmkah.app-1.0+json"
* Fehler, wenn es nicht passt 406 Not Acceptable

=== Media Type Versioning (DEMO)

* DEMO (rest_service_impl_media_type_versioning)
[source, java]
----
@RequestMapping(method = RequestMethod.GET, produces = "application/vnd.ehmkah.app-1.0+json")
  public ResponseEntity<List<Object>> list(
          @ApiParam(value = "Tags used to filter the result")
  ...
----

=== Unsere Entscheidung

[%step]
* URI-Versioning
* Grund: viele SOAP Service, Rest Service sind noch nicht ressourcenorientiert

=== Implementieren des Services


=== Jede Serviceversion separat deployed

[%step]
* Service wird mit jeder Serviceversion deployed
* Vorteil: funktioniert out of the box
* Nachteil: Kosten und Skalierung des Services, Wartungskosten

=== Jede Serviceversion separat deployed

* DEMO

=== Code duplizieren

[%step]
* Businesscode wird vollständig kopiert
* und einmal deployed
* Vorteil:  Skalierung einfacher
* Nachteil: extrem viele Redundanzen, Arbeit macht keinen Spass


=== Code duplizieren

* DEMO

=== Adapterpattern zwischen Service Versionen (Klassendiagramm)

image::classDiagramConverter.png[background]

[%step]
* Konvertieren auf internes Model ODER neueste Serviceversion
* muss vollständig sein (vereinfacht die Unterstüzung verschiedener Version immens)
können

[NOTE.speaker]
--
* Internes Model besonders beim Löschen nützlich
* Konvertierung einfacher
--

=== Adapterpattern zwischen Service Versionen (Sequenzdiagram)

image::sequenceConverter.png[background]

=== Adapterpattern zwischen Versionen eines Services (Modelmapper)

[%step]
* Einsatz einer Bibliothek, die automatisch Klassen in einander konvertiert
* Beispiel: modelmapper, dozzer,
* Vorteil: OK für simple Schnittstellen, da schnell aufgesetzt


=== Adapterpattern zwischen Versionen eines Services (Modelmapper)

[%step]
* Nachteil: Probleme bei Typhierachien
* Nachteil: Mappingmechanismus nicht durchschaubar
* Nachteil: Manuelle Anpassungen am Mapping kompliziert
* Nachteil: Teilweise Performanceprobleme
* Nachteil: Konvertierung müsste getestet werden

[NOTE.speaker]
--
* War unser erster Versuch (mit Modelmapper, dozer)
--

=== Adapterpattern zwischen Versionen eines Services (Modelmapper)

* DEMO
.Converter.map
[source,java]
----
private ModelMapper modelMapper = new ModelMapper();

    public com.ehmkah.services.gardening.RequestType map(RequestType requestV1) {
      com.ehmkah.services.gardening.RequestType result =
      modelMapper.map(requestV1, com.ehmkah.services.gardening.RequestType.class);

      return result;
    }
----

=== Adapterpattern zwischen Versionen eines Services (Modelmapper)

* DEMO die furchtbaren manuellen Anpassungen, für komplizierte Modelle


=== Adapterpattern zwischen Versionen eines Services (händisch)

[%step]
* Vorteil: verständlich
* Nachteil: wenn selbst geschrieben aufwending und fehleranfällig



=== Adapterpattern zwischen Versionen eines Services (händisch)

.Converter.map
[source,java]
----
public com.ehmkah.services.gardening.RequestType map(RequestType requestV1) {
    com.ehmkah.services.gardening.RequestType result =
    new com.ehmkah.services.gardening.RequestType();
    result.setSpeciesOne(requestV1.getSpeciesOne());
    result.setSpeciesTwo(requestV1.getSpeciesTwo());

    return result;
  }
----

=== Adapterpattern zwischen Versionen eines Services (händisch)

* Einsatz eines Generators (und manuelles nachziehen der Änderungen)
[NOTE.speaker]
--
* wir generieren den Mapper mit Javapoet und Java Reflektions
* passen an, wenn generiertes Mapping nicht passt
--


//=== Soap Message dispatcher?
//
//
//und noch so nen anderes Ding von IBM /ORacle???
{'fraction_non_alphanumeric': 0.09776976796575805, 'fraction_numerical': 0.004505519261094841, 'mean_word_length': 4.995273463875759, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7309807', 'n_tokens_mistral': 2890, 'n_tokens_neox': 2915, 'n_words': 778}