Hinweis:

Oracle GraalVM-basierte Java-Anwendung mit Spring Boot auf OKE erstellen, um SOAP-Nachrichten in ATP zu speichern und an OCI Queue zu senden

Einführung

Viele unserer Kunden verlassen sich auf herkömmliches Simple Object Access Protocol (SOAP)-Messaging, um die Kommunikation zwischen ihren Anwendungen zu ermöglichen. Sie müssen häufig Transaktionsdaten speichern, die Serviceentkopplung sicherstellen, ein Load Balancing für eingehende Anforderungen erreichen und die asynchrone Kommunikation dieser Nachrichten ermöglichen.

In diesem Tutorial erfahren Sie, wie wir eine Oracle GraalVM-basierte Java-Anwendung mit Spring Boot erstellen können, die auf der Oracle Cloud Infrastructure Kubernetes Engine-(OKE-)Infrastruktur bereitgestellt wird und als Transaktionsintegrator mit den verschiedenen Oracle Cloud Infrastructure-(OCI-)Services wie Oracle Autonomous Transaction Processing (ATP) und OCI Queue verwendet wird. Dieses Setup ermöglicht es Systemen, ohne direkte Verbindungen zu interagieren, was die Kommunikation zwischen Anwendungen mit unterschiedlichen Verarbeitungsgeschwindigkeiten erleichtert. Sobald die Informationen in der Datenbank gespeichert sind, können sie konsultiert oder analysiert werden.

Wir verwenden folgende Technologien:

Oracle Cloud Infrastructure Services (OCI): OCI ist eine sichere, leistungsstarke Cloud-Plattform mit mehr als 150 Cloud-Services. Es wurde für Skalierbarkeit, Sicherheit und Performance entwickelt.

Oracle-Technologie:

Weitere Technologien:

OCI High Level Architecture:

OCI-Architektur

Anwendungsfallarchitektur

Hinweis:

Ziele

Voraussetzungen

Aufgabe 1: OKE-Cluster bereitstellen und konfigurieren

In dieser Aufgabe stellen wir die Kubernetes-Plattform bereit, auf der die Anwendung alle SOAP-Nachrichten mit hoher Transaktionalität unterstützt, um sie in ATP zu speichern und in Echtzeit an OCI Queue zu senden.

  1. Melden Sie sich bei der OCI-Konsole an, navigieren Sie zu Entwicklerservices, Kubernetes-Cluster (OKE), und wählen Sie das gewünschte Compartment aus.

    Es gibt zwei Möglichkeiten, ein OKE-Cluster zu erstellen:

    • Schnellerstellung.
    • Benutzerdefinierte Erstellung.
  2. Wählen Sie Schnellerstellung aus, da diese Methode einfacher, schneller ist und automatisch alle Elemente bereitstellt, die OKE für seinen Vorgang benötigt, wie:

    • Virtuelles Cloud-Netzwerk (VCN).
    • Internetgateway.
    • Network Address Translation-(NAT-)Gateway.
    • Servicegateway.
    • Kubernetes-Cluster.
    • Kubernetes-Worker-Knoten und Knotenpool.

    Hinweis: Für Unternehmensumgebungen, in denen die Kunden bereits über Services, Netzwerk und Infrastruktur verfügen, ist es wichtig, das OKE-Deployment anzupassen, damit es in Übereinstimmung mit der Clientarchitektur, den Ressourcen und den Best Practices ausgerichtet ist.

    Schnellerstellung

  3. Klicken Sie auf Cluster erstellen, und geben Sie die folgenden Informationen ein.

    • Name: Geben Sie den Namen des OKE-Clusters ein.
    • Compartment: Wählen Sie das Compartment aus, das für dieses Projekt erstellt wurde.
    • Kubernetes-Version: Wählen Sie die neueste verfügbare Kubernetes-Version aus.
    • Kubernetes-API-Endpunkt: Wählen Sie in diesem Tutorial Öffentlicher Endpunkt aus, Sie können jedoch auch Privater Endpunkt auswählen.
    • Knotentyp: Wählen Sie Verwaltete Knoten aus.
    • Kubernetes-Worker-Knoten: Wählen Sie Private Mitarbeiter aus.
    • Ausprägung und Image: Wählen Sie VM.Standard.E5 aus. Flex, passen Sie die Anzahl der OCPUs (2) und den Arbeitsspeicher (16 GB) an, und behalten Sie das Standard-Oracle Linux 8-Image bei.
    • Knotenanzahl: Geben Sie 2 Worker-Knoten ein, die mit dem OKE-Knotenpool bereitgestellt werden sollen.

    OKE-Cluster erstellen

    Prüfen Sie, ob das OKE-Cluster funktioniert.

    OKE wird ausgeführt

Aufgabe 2: OCI Container Registry Classic bereitstellen, konfigurieren und aufrufen

Die Projektimages müssen in einem Repository verwaltet werden. Dazu stellen wir OCI Container Registry Classic bereit. Sobald die Images in OCI Container Registry Classic gespeichert sind, können wir sie in OKE bereitstellen.

  1. Gehen Sie zur OCI-Konsole, navigieren Sie zu Entwicklerservices, Container und Artefakte, Container Registry, und klicken Sie auf Repository erstellen.

  2. Geben Sie die folgenden Informationen ein, und klicken Sie auf Erstellen.

    • Erstellen in Compartment: Wählen Sie das Compartment aus, das für dieses Projekt erstellt wurde.
    • Zugriff: Wählen Sie Öffentlich aus.
    • Repository-Name: Geben Sie springboot/tutorialapp ein.

    Repository erstellen

  3. Nachdem das Repository erstellt wurde, greifen Sie von Ihrem Oracle-Admin-Host mit dem folgenden Befehl darauf zu.

    docker login -u 'tenancy_namespace/domain/username' regionID.ocir.io
    
    Password: xxxxxx
    

    Oracle Registry-Authentifizierung

    OK

Aufgabe 3: Serverlose Oracle Autonomous Transaction Processing-(ATP-)Datenbank bereitstellen und konfigurieren

In der ATP-Datenbank speichern wir die Daten jeder pro Transaktion empfangenen SOAP-Nachricht, ungefähr jede wird in der Reihenfolge von Millisekunden gespeichert, was parallele und sequenzielle Einfügungen betrifft.

  1. Gehen Sie zur OCI-Konsole, navigieren Sie zu Oracle Database, und klicken Sie auf Autonomous Transaction Processing.

  2. Klicken Sie auf Create Autonomous Database, und geben Sie die folgenden Informationen ein.

    • Compartment auswählen: Wählen Sie das Compartment aus, das für dieses Projekt erstellt wurde.
    • Anzeigename: Geben Sie den Anzeigenamen ein.
    • Datenbanknamen anzeigen: Geben Sie den Datenbanknamen ein.
    • Workload-Typ auswählen: Wählen Sie Transaktionsverarbeitung aus.
    • Deployment-Typ auswählen: Wählen Sie Serverlos aus.
    • Konfigurieren Sie die Datenbank:
      • Entwickler: Heben Sie die Auswahl auf.
      • Datenbankversion auswählen: Wählen Sie 23ai aus.
      • ECPU-Anzahl: Geben Sie 2 ein.
      • Compute-Autoscaling: Wählen Sie diese Option aus.
      • Speicher: Geben Sie 1024 GB ein.
    • Aufbewahrungszeitraum für automatische Backups in Tagen: Übernehmen Sie die Standardoption 60 Tage.
    • Erstellen Sie Administratorzugangsdaten:
      • Benutzername: Ist standardmäßig ADMIN und kann nicht bearbeitet werden.
      • Kennwort: Geben Sie Ihr bevorzugtes Kennwort ein.
      • Kennwort bestätigen: Geben Sie das Kennwort erneut ein.
    • Netzwerkzugriff auswählen: Wählen Sie Nur Zugriff auf privaten Endpunkt aus, und wählen Sie dann das für dieses Projekt erstellte VCN und Subnetz aus. Mit dieser Einstellung werden nur Verbindungen zum angegebenen privaten Netzwerk (VCN) eingeschränkt. Sie können jedoch andere Optionen auswählen, dies hängt von den Bedürfnissen des Unternehmens ab.

    Oracle ATP-Datenbank erstellen

    Oracle ATP-Datenbank erstellen

    Oracle ATP-Datenbank erstellen

    Prüfen Sie, ob die ATP-Datenbank ausgeführt wird.

    ATP wird ausgeführt

Aufgabe 4: Projekttabellen in Oracle Autonomous Transaction Processing (ATP) verbinden und erstellen

Nun müssen wir die Projekttabellen in der ATP-Datenbank konfigurieren, verbinden und erstellen, die in Aufgabe 3 generiert wurde.

  1. Gehen Sie zur OCI-Konsole, navigieren Sie zu Oracle Database, Autonomous Transaction Processing, und klicken Sie auf Datenbankverbindung. Wählen Sie TLS-Authentifizierung und TLS aus, und klicken Sie auf Wallet herunterladen.

    Datenbankverbindung

  2. Dekomprimieren Sie die Wallet-Datei .zip, und in tnsnames.ora können Sie die Datenquellen-URL abrufen, um die Verbindung zu dieser Datenbank abzurufen. Speichern Sie diese Datenquellen-URL.

    Beispiel:

    tutorialoracleatp_medium = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=xxxxxxxx.adb.sa-saopaulo-1.oraclecloud.com))(connect_data=(service_name=xxxxxxxxxxxxxxx_tutorialoracleatp_medium.adb.oraclecloud.com))(security=(ssl_server_dn_match=no)))
    
  3. Der Zugriff auf die Datenbank ist jetzt notwendig. Beim Provisioning der ATP wurde der Zugriff auf Oracle REST Data Services (ORDS) aktiviert. Weitere Informationen finden Sie unter Oracle REST Data Services.

    Gehen Sie zur Seite Autonomous Database-Details, und klicken Sie auf Datenbankaktionen. Beachten Sie, dass nur von einer Compute-Instanz aus zugegriffen werden kann, die im selben virtuellen Cloud-Netzwerk (VCN) ausgeführt wird.

    Datenbankaktionen

  4. Fügen Sie die URL in den Browser ein, und greifen Sie mit dem zuvor in der ATP-Datenbank eingegebenen Benutzer und Kennwort auf ORDS zu, und greifen Sie auf das Oracle SQL Developer Web-Modul zu.

    ORDS

  5. Verwenden Sie die folgenden Abfragen, um die Tabellen USERS, CARS und HOUSES für die SOAP-Nachrichten zu erstellen, die wir erhalten.

    CREATE TABLE USERS (
    username varchar(50) NOT NULL,
    userlastname varchar(50) NOT NULL,
    id int NOT NULL,
    email varchar(50) NOT NULL,
    dateuser varchar(50) NOT NULL,
    attributeuser varchar(50) NOT NULL  
    );
    
    CREATE TABLE CARS (
    userid int NOT NULL,
    brand varchar(50) NOT NULL,
    color varchar(50) NOT NULL,
    plate varchar(50) NOT NULL  
    );
    
    CREATE TABLE HOUSES (
    userid int NOT NULL,
    floors int NOT NULL,
    locationhouse varchar(50) NOT NULL,
    rooms int NOT NULL,
    bathrooms int NOT NULL
    );
    

    Tabellen in der Datenbank erstellt

Aufgabe 5: OCI Queue bereitstellen und konfigurieren

In der OCI-Queue speichern wir hochtransaktionale Nachrichten über die HTTP-API RESTful für einen bestimmten Zeitraum. Verbraucher können dann die Nachrichten sofort oder nach Belieben lesen und löschen, um eine Entkopplung sicherzustellen und Datenverlust zu verhindern.

  1. Gehen Sie zur OCI-Konsole, navigieren Sie zu Entwicklerservices, Anwendungsintegration, und klicken Sie auf Queues.

  2. Klicken Sie auf Queue erstellen, geben Sie die folgenden Informationen ein, und klicken Sie auf Queue erstellen.

    • Name: Geben Sie den entsprechenden Namen für Ihre Queue ein.
    • Compartment: Wählen Sie Ihr Arbeits-Compartment aus.
    • Queueeinstellungen: In diesem Tutorial wählen Sie Standardkonfiguration aus. Wenn Sie dies wünschen, können Sie jedoch mehrere Optionen entsprechend den Geschäftsanforderungen anpassen, z.B. Sichtbarkeitstimeout, Maximaler Aufbewahrungszeitraum, Maximaler Kanalverbrauch und die Einstellungen Dead Letter Queue.
    • Verschlüsselungseinstellungen konfigurieren: Wählen Sie Von Oracle verwalteter Schlüssel aus, aber Vom Kunden verwalteter Schlüssel ist auch eine Option.

    Queue erstellen

    Prüfen Sie, ob die OCI Queue ausgeführt wird.

    OCI-Queue wird ausgeführt

Aufgabe 6: Oracle GraalVM-basierte Java-Anwendung mit Spring Boot erstellen und in OKE bereitstellen

Jetzt entwickeln und stellen wir eine Oracle GraalVM-basierte Java-Anwendung auf Spring Boot bereit, mit der die folgenden Aufgaben ausgeführt werden:

Hinweis: Bevor Sie beginnen, müssen Sie einen Administrationshost und eine Entwicklungsumgebung erstellen, wie im Abschnitt Voraussetzungen - Administrationshost und Voraussetzungen - Entwicklungsumgebung dargestellt.

Sobald Ihr Admin-Host und Ihre Entwicklungsumgebung konfiguriert sind und bereit sind, können Sie mit der Entwicklung Ihres Spring Boot-Projekts beginnen.

  1. Gehen Sie zu Spring initializr, und erstellen Sie ein erstes Projekt, das uns die Ordnerstruktur und die Basisdateien eines Spring Boot-Projekts gibt, um es später entsprechend unseren Anforderungen zu ändern. Geben Sie die folgenden Informationen ein, und klicken Sie auf Generieren. Dadurch wird das Spring Boot-Projekt automatisch heruntergeladen, gespeichert und auf dem Entwicklungshost entpackt.

    • Projekt: Wählen Sie Maven aus.
    • Sprache: Wählen Sie Java aus.
    • Frühstart: Wählen Sie 3.3.6.
    • Projektmetadaten:
      • Gruppe: Geben Sie com.tutorial_springboot ein.
      • Artefakt: Geben Sie das Tutorial ein.
      • Name: Geben Sie das Tutorial ein.
      • Beschreibung: Geben Sie Spring-Boot-Anwendung (SOAP lesen, in JSON transformieren, ATP einfügen und in OCI-Queue einfügen) ein.
    • Packaging: Wählen Sie Jar aus.
    • Java: Wählen Sie 17 aus.
    • Abhängigkeiten: Wählen Sie Oracle-Treiber, Spring Web Services und Spring Web aus.

    Hinweis: Je nach Bedarf können wir einige Abhängigkeiten im Projekt hinzufügen und später weitere hinzufügen, direkt in der Datei pom.xml.

    Springboot-Projekt

  2. Jetzt haben wir das Spring Boot Struktur Projekt.

    Struktur Spring Boot Projekt

    Prüfen Sie die Datei pom.xml, und beginnen Sie mit der Bearbeitung.

    Ursprüngliche POM-Datei

    Aktualisieren Sie die Datei pom.xml entsprechend dem in diesem Tutorial vorgeschlagenen Geltungsbereich.

    • Fügen Sie die oci sdk-Version und die folgenden Abhängigkeiten hinzu.

      • oci-java-sdk-common.
      • oci-java-sdk-queue.
      • oci-java-sdk-addons-oke-workload-identity.
      • oci-java-sdk-common-httpclient-jersey3.

      Die Anwendung muss sich bei OCI authentifizieren, OCI-Services wie OCI Queue verbinden und verwalten.

    • Die Datei pom.xml weist bereits eine spring-boot-starter-web-services-Abhängigkeit auf, und Sie müssen eine wsdl4j-Abhängigkeit hinzufügen. Der Hauptzweck besteht darin, die von SOAP-Nachrichten empfangenen Daten abzurufen und in Java-Objekten zu speichern, indem Spring Web Services zur Bearbeitung von XML-Payloads erstellt werden, um die Entwicklung von vertragsorientierten SOAP-Services zu erleichtern. Ermöglicht auch die Konfiguration von Port, URI und festgelegtem XML-Schema, das aus der XSD-Datei (XML Schema Definition) geladen wurde.

    • JSON-Abhängigkeit hinzufügen. Mit dieser Library wird das JSON-Format mit den aus der SOAP-Nachricht extrahierten Daten generiert.

    • Fügen Sie das Plug-in spring-boot-maven-plugin im Abschnitt "Build" hinzu. Dieses Plugin ermöglicht es uns, die ausführbare Spring Boot-Projektdatei zu generieren.

    • Fügen Sie das Plug-in jaxb2-maven-plugin im Abschnitt "Build" hinzu. Dieses Plugin verwendet die Java API for XML Binding (JAXB), um Java-Klassen aus XML-Schemas zu generieren. Auf diese Weise können wir die Daten aus der SOAP-Nachricht an von uns erstellte Java-Klassenobjekte übergeben.

      In diesem Plugin-Abschnitt ist es wichtig, die Konfiguration anzugeben, die den Pfad angibt, in dem die XSD-Datei in unserem Spring Boot-Projekt enthalten ist.

      <configuration>
         <sources>
         <source>${project.basedir}/src/main/resources/messages.xsd<source>
         </sources>
      </configuration>
      
    • Fügen Sie im Abschnitt "Build" die jasypt-spring-boot-starter-Abhängigkeit im Abschnitt "Abhängigkeiten" und das jasypt-maven-plugin-Plug-in hinzu, mit denen sensible Parameter in der Datei application.properties verschlüsselt werden können, um die sichere Verwendung in unserer Anwendung sicherzustellen.

    Prüfen Sie die folgenden Abhängigkeiten, die in der Datei pom.xml hinzugefügt wurden.

    POM-Datei geändert

    POM-Datei geändert

  3. Laden Sie die Bibliotheken herunter, und führen Sie die folgenden Befehle aus.

    1. Führen Sie in Ihrer Entwicklungsumgebung den folgenden Befehl aus, um auf Ihr Projekt zuzugreifen.

      cd tutorial
      

      Spring-Boot-Projektordner

    2. Bereinigen Sie das Projekt, und entfernen Sie alle vom vorherigen Build generierten Dateien.

      mvn clean
      

      Maven-Bereinigung

    3. Artefakte aus dem lokalen Maven Repository löschen (löschen und optional erneut auflösen)

      mvn dependency:purge-local-repository
      

    Maven-Löschabhängigkeiten

  4. Wir haben bereits die Abhängigkeiten und die Datei pom.xml in unserem Projekt konfiguriert, wir werden fortfahren, die SOAP-XML-Datei zu prüfen, da sie die Anforderung von der Clientseite darstellt, und die XSD-Datei, die die Anforderung auf unserer Spring Boot-Projektseite interpretiert.

    1. Diese SOAP-XML-Datei enthält zwei Nachrichten mit persönlichen Informationen und anderen Arten von Attributen von zwei verschiedenen Clients, die wir pro Anforderung senden, wie in der folgenden Abbildung dargestellt.

      Seifendatei

    2. Auf der Spring Boot-Projektseite ist jetzt ein XML-Schema erforderlich, um eine Webservicedomain zu definieren, die Spring Web Service automatisch als WSDL exportiert. Die folgende Abbildung zeigt die für dieses Tutorial definierte Datei messages.xsd.

      messages.xsd:

      XSD-Datei

    3. Speichern Sie die Datei messages.xsd im Ressourcenordner Ihres Spring Boot-Projekts.

      XSD-Datei im Ordner

  5. Erstellen und installieren Sie Projektdateien in einer JAR-Datei. Führen Sie den folgenden Befehl aus, und stellen Sie sicher, dass Sie sich im Spring Boot-Projektordner befinden.

    mvn install
    

    Hinweis: Sobald der maven-Installationsbefehl ausgeführt wurde, wird der Zielordner automatisch generiert. In derselben Weise werden die Java-Klassen entsprechend der zuvor erstellten XSD-Datei und der ausführbaren Datei .jar des Projekts generiert.

    Zielordner

  6. Jetzt können wir die erforderlichen Java-Klassen zu unserem Spring Boot-Projekt hinzufügen.

    WebServiceConfig.java Class: Diese Java-Klasse wurde entwickelt, um einen SOAP-Webservice zu erstellen:

    • Richten Sie das Servlet zur Verarbeitung von SOAP-Anforderungen ein.
    • Generiert eine WSDL-Definition basierend auf einem XML-Schema.
    • Definiert den Zugriffsendpunkt des SOAP-Webservice.
    • Verwendet die Schemadatei messages.xsd aus dem Classpath.
    //Imports
    import org.springframework.boot.web.servlet.ServletRegistrationBean; //import the ServletRegistrationBean class
    import org.springframework.context.ApplicationContext; //import the ApplicationContext class
    import org.springframework.context.annotation.Bean; //import the Bean class
    import org.springframework.context.annotation.Configuration; //import the Configuration class
    import org.springframework.core.io.ClassPathResource; //import the ClassPathResource class
    import org.springframework.ws.config.annotation.EnableWs; //import the EnableWs class
    import org.springframework.ws.config.annotation.WsConfigurerAdapter; //import the WsConfigurerAdapter class
    import org.springframework.ws.transport.http.MessageDispatcherServlet; //import the MessageDispatcherServlet class
    import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; //import the DefaultWsdl11Definition class
    import org.springframework.xml.xsd.SimpleXsdSchema; //import the SimpleXsdSchema class
    import org.springframework.xml.xsd.XsdSchema; //import the XsdSchema class
    
    //Configuration class for the Web Service configuration
    @EnableWs //Enable the Web Service
    @Configuration //Define the class as a Configuration class 
    
    public class WebServiceConfig extends WsConfigurerAdapter {
    
       //Create a ServletRegistrationBean object to register the MessageDispatcherServlet object with the application context
       @Bean
       public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(ApplicationContext applicationContext) {
          MessageDispatcherServlet servlet = new MessageDispatcherServlet(); //Create a MessageDispatcherServlet object
          servlet.setApplicationContext(applicationContext); //Set the application context for the MessageDispatcherServlet object
          servlet.setTransformWsdlLocations(true); //Set the transformWsdlLocations property to true
          return new ServletRegistrationBean<>(servlet, "/ws/*"); //Return a new ServletRegistrationBean object with the MessageDispatcherServlet object and the URL pattern
       }
    
       //Create a DefaultWsdl11Definition object to define the WSDL
       @Bean(name = "messages")
       public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema messagesSchema) {
          DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); //Create a DefaultWsdl11Definition object
          wsdl11Definition.setPortTypeName("MessagesPort"); //Set the port type name
          wsdl11Definition.setLocationUri("/ws"); //Set the location URI
          wsdl11Definition.setTargetNamespace("http://tutorial_example.com/ns0"); //Set the target namespace
          wsdl11Definition.setSchema(messagesSchema); //Set the schema
          return wsdl11Definition; //Return the DefaultWsdl11Definition object
       }
    
       //Create a XsdSchema object to define the schema
       @Bean
       public XsdSchema messagesSchema() {
          return new SimpleXsdSchema(new ClassPathResource("messages.xsd")); //Return a new SimpleXsdSchema object with the messages.xsd file
       }
    }
    

    Hinweis: Wenn Sie den Webservice testen möchten, können Sie das Spring Boot-Projekt wie folgt auf demselben lokalen Entwicklungsumgebungsdesktop ausführen und eine HTTP-Anforderung mit curl senden:

    mvn spring-boot:run
    

    Spring-Boot-Projekt ausführen

    Spring-Boot-Projekt ausführen

    Nachdem das Projekt ausgeführt wurde und der Webservice hochgefahren ist, führen Sie wie folgt eine lokale SOAP-HTTP-Anforderung mit curl aus:

    curl --location 'http://localhost:8080/ws/'
    

    Und Sie erhalten eine Antwort vom Webservice, der in unserem Spring Boot-Projekt verfügbar ist.

    SOAP-Webservice

  7. Erstellen Sie einen Ordner namens model, und in diesem Ordner werden die folgenden Java-Klassen hinzugefügt.

    Modellordner

    Hinweis: Diese Java-Klassen Car, House und User rufen die Informationen basierend auf den Daten in jeder SOAP-Nachricht ab, die aus der HTTP-SOAP-Anforderung extrahiert wird.

    • Car.java class: Diese Java-Klasse stellt ein Auto-Objekt dar, dessen Attribute mit jedem Benutzer verknüpft sind.

      ```
      //Imports
      import org.springframework.stereotype.Component; // For component scanning
      import org.springframework.context.annotation.Scope; // For defining bean scope
      
      @Component // Marks a class as a Spring-managed component
      @Scope("prototype") //A new instance is created every time the bean is requested
      
      public class Car {
      
         //Attributes
      
         private String brand; 
         private String color; 
         private String plate; 
      
         //"getter" and "setter" methods to get and set the information in each object
      
         public String getBrand(){
         return brand;
         }
      
         public void setBrand(String brand){
         this.brand = brand;
         }
      
         public String getColor(){
         return color;
         }
      
         public void setColor(String color){
         this.color = color;
         }
      
         public String getPlate(){
         return plate;
         }
      
         public void setPlate(String plate){
         this.plate = plate;
         }
      
      }
      ```
      
      • House.java class: Diese Java-Klasse stellt ein Hausobjekt dar, dessen Attribute mit jedem Benutzer verknüpft sind.

        //Imports
        import org.springframework.stereotype.Component; // For component scanning
        import org.springframework.context.annotation.Scope; // For defining bean scope
        
        @Component // Marks a class as a Spring-managed component
        @Scope("prototype") //A new instance is created every time the bean is requested
        
        public class House {
        
           //Attributes
        
           private int floors;
           private String location;
           private int rooms;
           private int bathrooms;
        
        
           //"getter" and "setter" methods to get and set the information in each object
        
           public int getFloors(){
              return floors;
           }
        
           public void setFloors(int floors){
              this.floors = floors;
           }
        
           public String getLocation(){
              return location;
           }
        
           public void setLocation(String location){
              this.location = location;
           }
        
           public int getRooms(){
              return rooms;
           }
        
           public void setRooms(int rooms){
              this.rooms = rooms;
           }
        
           public int getBathRooms(){
              return bathrooms;
           }
        
           public void setBathRooms(int bathrooms){
              this.bathrooms = bathrooms;
           }
        
        }
        
      • User.java class: Diese Java-Klasse stellt ein Benutzerobjekt mit ihren Attributen dar, das die Objekte Auto und Haus enthält.

        //Imports
        import org.springframework.stereotype.Component; // For component scanning
        import org.springframework.context.annotation.Scope; // For defining bean scope
        
        @Component // Marks a class as a Spring-managed component
        @Scope("prototype") //A new instance is created every time the bean is requested
        
        
        public class User {
        
           //Attributes
        
           private String username; 
           private String userlastname;
           private int id;
           private String email;
           private String date;
           private String attribute;
           private Car car;
           private House house;
        
        
           //"getter" and "setter" methods to get and set the information in each object
        
           public String getUserName(){
           return username;
           }
        
           public void setUserName(String username){
           this.username = username;
           }
        
           public String getUserLastName(){
           return userlastname;
           }
        
           public void setUserLastName(String userlastname){
           this.userlastname = userlastname;
           }    
        
           public int getID(){
           return id;
           }
        
           public void setID(int id){
           this.id = id;
           }        
        
           public String getEmail(){
           return email;
           }
        
           public void setEmail(String email){
           this.email = email;
           }
        
           public String getDate(){
           return date;
           }
        
           public void setDate(String date){
           this.date = date;
           }
        
           public String getAttribute(){
           return attribute;
           }
        
           public void setAttribute(String attribute){
           this.attribute = attribute;
           }
        
           public Car getCar(){
           return car;
           }
        
           public void setCar(Car car){
           this.car = car;
           }
        
           public House getHouse(){
           return house;
           }
        
           public void setHouse(House house){
           this.house = house;
           }
        }
        
  8. Jetzt konfigurieren wir die erforderlichen Parameter in unserem Spring Boot-Projekt, um die abgerufenen Daten in der OCI ATP-Datenbank zu speichern. Im Ordner resources müssen Sie die Datei application.properties finden, mit der die von der Anwendung benötigten Parameter hinzugefügt werden. Es wird automatisch generiert und beim Start der Anwendung von Spring Boot geladen.

    Hinweis: Es ist wirklich wichtig, Verschlüsselungs- und Sicherheitsmethoden zu verwalten, die sicherstellen, dass sensible Informationen wie Passwörter oder relevante Daten nicht von Hackern extrahiert oder angezeigt werden können. In diesem Tutorial verwenden wir die jasypt-Bibliothek, die in der Datei pom.xml konfiguriert ist. Weitere Informationen finden Sie unter How to encrypt password in a Spring Boot project using Jasypt. Zusätzlich wird in unseren Java-Klassen auf Spring Boot dokumentiert, wo die Annotationen und der Quellcode für diese Library hinzugefügt werden, um die application.properties-Parameter zu entschlüsseln.

    Fügen Sie die für die ATP-Datenbank erforderlichen Parameter in die Datei application.properties ein, wie in der folgenden Abbildung dargestellt.

    Anwendungseigenschaftendatei

    Erstellen Sie die Spring Boot-Java-Klasse, um jede Nachricht in der Datenbank zu speichern. Sie befindet sich im Ordner database, wie in der folgenden Abbildung dargestellt.

    Database Folder

    • SoapObjectRepository.java: Mit dieser Spring Boot-Java-Klasse können Sie jede Nachricht in ATP mit JDBC-Treiber in Echtzeit in Transaktionsform einfügen.

      //Java Classes USER, CAR, HOUSE Imports
      import com.oracle_springboot_tutorial.tutorial.model.*;
      
      //Spring Boot Imports
      import org.springframework.stereotype.Repository;
      import org.springframework.jdbc.core.JdbcTemplate;
      import org.springframework.beans.factory.annotation.Autowired;
      
      //Repository Class to save SOAP Messages in the Database
      @Repository
      public class SoapObjectRepository {
         private JdbcTemplate template;
         private User user;
      
         //Getters and Setters for JdbcTemplate template object
         public JdbcTemplate getTemplate(){
            return template;
         }
      
         //Autowired annotation to inject JdbcTemplate object into the template object
         @Autowired
         public void setTemplate(JdbcTemplate template){
            this.template = template;
         }
      
         //Method to save User SOAP Message in the Database
         public void saveUserSOAPMessage(User user){
            this.user = user;
            String sql = "INSERT INTO USERS (username, userlastname, id, email, dateuser, attributeuser) VALUES(?, ?, ?, ?, ?, ?)";
            template.update(sql, user.getUserName(), user.getUserLastName(), user.getID(), user.getEmail(), user.getDate(), user.getAttribute());
         }
      
         //Method to save Car SOAP Message in the Database
         public void saveCarSOAPMessage(Car car){
            String sql = "INSERT INTO CARS (userid, brand, color, plate) VALUES(?, ?, ?, ?)";
            template.update(sql, user.getID(), car.getBrand(), car.getColor(), car.getPlate());
         }
      
         //Method to save House SOAP Message in the Database
         public void saveHouseSOAPMessage(House house){
            String sql = "INSERT INTO HOUSES (userid, floors, locationhouse, rooms, bathrooms) VALUES(?, ?, ?, ?, ?)";
            template.update(sql, user.getID(), house.getFloors(), house.getLocation(), house.getRooms(), house.getBathRooms());
         }
      
      
      }
      

      Fügen Sie nun den JSON-Softwarecode hinzu, und erstellen Sie zunächst den Ordner json_message und die zugehörige Java Spring Boot-Klasse, wie in der folgenden Abbildung dargestellt.

      Json-Ordner

    • JsonBuilder.java: Diese Spring Boot-Java-Klasse konvertiert vom SOAP-XML-Format in das JSON-Format.

      //Imports to be used for JSON
      import org.json.JSONArray;
      import org.json.JSONObject;
      
      //Imports to be used for the User class
      import com.oracle_springboot_tutorial.tutorial.model.*;
      
      
      //Imports to be used for the ArrayList class
      import java.util.ArrayList;
      
      
      public class JsonBuilder {
      
         //The buildJsonMessage method creates a JSON object from the ArrayList of User objects
         public JSONObject buildJsonMessage(ArrayList<User> usersMessageArray) {
      
            JSONObject rootJson = new JSONObject(); //Create a new JSON object called rootJson
            JSONObject messagesJson = new JSONObject(); //Create a new JSON object called messagesJson
            JSONArray messageArray = new JSONArray(); //Create a new JSON array called messageArray
      
      
            //Iterate through the ArrayList of User objects and create a JSON object for each User object in the ArrayList
            for (User user : usersMessageArray) {
                  JSONObject messageJson = new JSONObject();
                  messageJson.put("username", user.getUserName()); //Add the username of the user to the messageJson object
                  messageJson.put("userlastname", user.getUserLastName()); //Add the userlastname of the user to the messageJson object
                  messageJson.put("id", user.getID()); //Add the id of the user to the messageJson object
                  messageJson.put("email", user.getEmail()); //Add the email of the user to the messageJson object
                  messageJson.put("date", user.getDate()); //Add the date of the user to the messageJson object
                  messageJson.put("attribute", user.getAttribute()); //Add the attribute of the user to the messageJson object
      
      
                  //
                  JSONObject bodyJson = new JSONObject(); //Create a new JSON object called bodyJson
                  JSONObject envelopeJson = new JSONObject(); //Create a new JSON object called envelopeJson
      
                  //Switch statement to check the attribute of the User object
                  switch (user.getAttribute()) {
                     case "CAR":
                              Car car = user.getCar();
                              envelopeJson.put("brand", car.getBrand()); //Add the brand of the car to the envelopeJson object
                              envelopeJson.put("color", car.getColor()); //Add the color of the car to the envelopeJson object
                              envelopeJson.put("plate", car.getPlate()); //Add the plate of the car to the envelopeJson object                       
                        break;
                     case "HOUSE":
                              House house = user.getHouse();
                              envelopeJson.put("floors", house.getFloors()); //Add the floors of the house to the envelopeJson object
                              envelopeJson.put("location", house.getLocation()); //Add the location of the house to the envelopeJson object
                              envelopeJson.put("rooms", house.getRooms()); //Add the rooms of the house to the envelopeJson object
                              envelopeJson.put("bathrooms", house.getBathRooms()); //Add the bathrooms of the house to the envelopeJson object                     
                        break;
                     default:
                        System.out.println("Unknown subject: " + user.getAttribute());
                  }
      
      
                  bodyJson.put("envelope", envelopeJson); //Add the envelopeJson object to the bodyJson object
      
                  messageJson.put("body", bodyJson); //Add the bodyJson object to the messageJson object
      
               messageArray.put(messageJson); //Add the messageJson object to the messageArray array
            }
      
            messagesJson.put("message", messageArray); //Add the messageArray array to the messagesJson object
            rootJson.put("messages", messagesJson); //Add the messagesJson object to the rootJson object
      
            return rootJson;
         }
      }
      
  9. Jetzt können wir die Nachrichten im JSON-Format an OCI Queue senden. Erstellen Sie den Ordner oci_queue und die zugehörige Java Spring Boot-Klasse, wie in der folgenden Abbildung dargestellt.

    Warteschlangenordner

    Hinweis: In der Klasse OCIQueue.java müssen wir den Zugriff von OKE auf OCI Queue definieren. In diesem Tutorial verwenden wir Workloadszugriff, um Zugriff auf OCI-Ressourcen zu erteilen, ohne sensible Informationen wie Benutzer, Kennwörter und OCIDs verarbeiten zu müssen, die mit Ihrem Mandanten verknüpft sind. Weitere Informationen finden Sie unter Workloads Zugriff auf OCI-Ressourcen erteilen.

    Bevor Sie mit der Entwicklung der Klasse OCIQueue.java beginnen, konfigurieren wir den Workloadszugriff in unserem Mandanten. Zuerst müssen Sie einen Namespace erstellen, der mit unserer Oracle GraalVM-basierten Java-Anwendung verknüpft werden kann. Stellen Sie sicher, dass Sie sich im Admin-Host befinden.

    kubectl create ns-tutorial
    

    Erstellen Sie dann einen Kubernetes-Serviceaccount für die Anwendung.

    kubectl create serviceaccount tutorialserviceaccount --namespace ns-tutorial
    

    Definieren Sie jetzt eine OCI-IAM-Policy, damit die Workload auf die erforderlichen OCI-Ressourcen zugreifen kann. In diesem Tutorial OCI Queue.

    Gehen Sie zur OCI-Konsole, navigieren Sie zu Identität und Sicherheit, Policys, und klicken Sie auf Policy erstellen. Geben Sie die folgenden Informationen ein, und klicken Sie auf Erstellen.

    • Name: Geben Sie den bevorzugten Policy-Namen ein.
    • Beschreibung: Geben Sie Zugriff von OKE auf OCI-Queue ein.
    • Policy Builder:

      Allow any-user to use queues in compartment id ocid1.compartment.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx where all {request.principal.type = 'workload', request.principal.namespace = 'ns-tutorial', request.principal.service_account = 'tutorialserviceaccount', request.principal.cluster_id = 'ocid1.cluster.oc1.sa-saopaulo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'}
      

    Zugriffs-Policy für Workloads

    Nachdem Sie die Workload-Zugriffs-Policy, den Namespace und den Serviceaccount konfiguriert haben, können Sie fortfahren.

    Fügen Sie in der Datei application.properties die Queueparameter hinzu, die für die Verbindung und Verwaltung der spezifischen OCI Queue erforderlich sind, die in Aufgabe 5 erstellt wurde.

    OCIID-Einstellungen

    • OCIQueue.java: In dieser Spring Boot-Java-Klasse können Sie auf die Nachrichten zugreifen und sie in OCI Queue stellen.

      //Imports
      import com.oracle.bmc.auth.okeworkloadidentity.OkeWorkloadIdentityAuthenticationDetailsProvider; //Import OkeWorkloadIdentityAuthenticationDetailsProvider to enable access and use OCI Workload Identity
      import com.oracle.bmc.queue.QueueClient; //Import QueueClient to have access and manage of OCI Queue
      import com.oracle.bmc.queue.model.PutMessagesDetails; //Import PutMessagesDetails to send messages to the OCI Queue
      import com.oracle.bmc.queue.model.PutMessagesDetailsEntry; //Import PutMessagesDetailsEntry to send messages to the OCI Queue
      import com.oracle.bmc.queue.requests.PutMessagesRequest; //Import PutMessagesRequest to send messages to the OCI Queue
      
      //Imports for the ArrayList and List
      import java.util.ArrayList;
      import java.util.List;
      
      public class OCIQueue {
         //Set the required parameters to access to OCI and the Queue
      
         //Variables
         private String queueId; 
         private String endPoint;
         private String region;
      
         //Constructor to initialize the OCI Queue object with the required parameters
         public OCIQueue(String queueId, String endPoint, String region){
            this.queueId = queueId;
            this.endPoint = endPoint;
            this.region = region;   
         }
      
      
         //The sendMessages method sends a message to the OCI Queue
         public void sendMessages(String jsonMessage){
            try{    
      
                  //Create an OkeWorkloadIdentityAuthenticationDetailsProvider object to authenticate the OCI Queue
                  OkeWorkloadIdentityAuthenticationDetailsProvider provider = new OkeWorkloadIdentityAuthenticationDetailsProvider.OkeWorkloadIdentityAuthenticationDetailsProviderBuilder().build();
      
                  //Create a QueueClient object to send the message to the OCI Queue
                  QueueClient queueClient = QueueClient.builder().build(provider);
                  queueClient.setRegion(region);
                  queueClient.setEndpoint(endPoint);
      
      
      
                  //Create a PutMessagesDetailsEntry object to send the message
                  PutMessagesDetailsEntry message = PutMessagesDetailsEntry.builder()
                     .content(jsonMessage)
                     .build();
      
                  //Create a List of PutMessagesDetailsEntry objects to send the message
                  List<PutMessagesDetailsEntry> messages = new ArrayList<>();
                  messages.add(message);
      
                  //Create a PutMessagesDetails object to send the message
                  PutMessagesDetails putMessagesDetails = PutMessagesDetails.builder()
                     .messages(messages)
                     .build();
      
      
                  //  Create a PutMessagesRequest object to send the message
                  PutMessagesRequest putMessagesRequest = PutMessagesRequest.builder()
                     .queueId(queueId)
                     .putMessagesDetails(putMessagesDetails)
                     .build();
      
                  // Send the request and get the response
                  queueClient.putMessages(putMessagesRequest);
      
            }catch(Exception e){
                  System.out.println("Exception sending message to OCI Queue: "+e);
            }
         }
      }
      
  10. Sobald Sie die Spring Boot-Java-Klassen für Datenbank, JSON und OCI Queue haben, können Sie mit der Klasse MessagesEndpoint.java fortfahren.

    Dazu erstellen wir einen Ordner namens endpoint und seine Spring Boot Java-Klasse.

    Endpunktordner

    Hinweis: In MessagesEndpoint.java müssen einige automatisch generierte Klassen importiert werden. Fügen Sie dazu die folgende Quelle im Abschnitt "Konfiguration" der Datei pom.xml hinzu:

    <configuration>
       <sources>
       <source>${project.build.directory}/generated-sources</source>
       </sources>
    </configuration>
    

    Die Datei pom.xml sollte wie folgt aussehen:

    Pfad für generierte Quellen

    • MessagesEndpoint.java: Der Zweck dieser Spring Boot-Java-Klasse besteht darin, die SOAP-HTTP-Anforderung zu extrahieren und ihre Werte den Java-Objekten "Benutzer", "Auto" und "Haus" für jede Nachricht zuzuordnen. Anschließend werden die extrahierten Daten für jede SOAP-XML-Transaktion in einer ATP-Datenbank gespeichert, die Daten aus XML in das JSON-Format konvertiert und die Nachrichten in eine OCI-Queue gestellt. Diese Nachrichten können später von Consumern aus der Queue abgerufen und gelöscht werden.

      //Imports
      import com.oracle_springboot_tutorial.tutorial.model.*; //Import all the classes from the model package
      import com.oracle_springboot_tutorial.tutorial.oci_queue.OCIQueue; //Import the OCIQueue class from the oci_queue package
      
      
      import com.tutorial_example.ns0.Messages;//Import the Messages class from the tutorial_example.ns0 package (Auto generated Java Classes from the WSDL)
      import com.tutorial_example.ns0.MessageType; //Import the MessageType class from the tutorial_example.ns0 package (Auto generated Java Classes from the WSDL)
      
      //Import the ArrayList class from the java.util package
      import java.util.ArrayList;
      
      //Spring Boot imports to be used for the SOAP Web Service
      import org.springframework.beans.factory.annotation.Autowired; //Import the @Autowired annotation to inject the SoapObjectRepository object
      import org.springframework.beans.factory.annotation.Value; //Import the @Value annotation to inject the values from the application.properties file
      import org.springframework.stereotype.Component; //Import the @Component annotation to register the class with Spring
      
      //Spring Boot imports 
      import org.springframework.ws.server.endpoint.annotation.Endpoint; //Import the @Endpoint annotation to register the class with Spring WS
      import org.springframework.ws.server.endpoint.annotation.PayloadRoot; //Import the @PayloadRoot annotation to specify the namespace URI and local part of the request payload
      import org.springframework.ws.server.endpoint.annotation.RequestPayload; //Import the @RequestPayload annotation to map the request payload to the method parameter
      import org.springframework.ws.server.endpoint.annotation.ResponsePayload; //Import the @ResponsePayload annotation to map the returned value to the response payload
      
      //Imports to be used storing SOAP information in the database 
      import com.oracle_springboot_tutorial.tutorial.database.SoapObjectRepository; //Import the SoapObjectRepository class from the database package
      
      //Imports to be used for JSON
      import com.oracle_springboot_tutorial.tutorial.json_message.JsonBuilder; //Import the JsonBuilder class from the json_message package 
      import org.json.JSONObject; //Import the JSONObject class from the org.json package
      
      
      //The @Endpoint annotation registers the class with Spring WS.
      //The @Component annotation registers the class with Spring to be used as a Spring Bean.
      @Endpoint
      @Component
      public class MessagesEndpoint {
      
         //Inject not encrypted and decrypted values using jasypt library from the application.properties file
         @Value("${oci.queue.queueId}")
         private String queueId;
         @Value("${oci.queue.endPoint}")
         private String endPoint;
         @Value("${oci.queue.region}")   
         private String region;
         @Value("${spring.datasource.password}")
         private String datasourcePassword;
      
         //The @Autowired loads JDBC template in SoapObjectRepository.
         @Autowired
         private SoapObjectRepository soapObjectRepository = new SoapObjectRepository();
         //Create a new instance of the JsonBuilder class
         JsonBuilder jsonBuilder = new JsonBuilder();
      
      
         //The namespace URI
         private static final String NAMESPACE_URI = "http://tutorial_example.com/ns0";
      
         //The handleMessagesRequest method is annotated with @PayloadRoot, which means that it is invoked when a request with the specified namespace URI and local part is received.
         @PayloadRoot(namespace = NAMESPACE_URI, localPart = "messages")
         //The @ResponsePayload annotation makes Spring WS map the returned value to the response payload.
         @ResponsePayload
         //The handleMessagesRequest method processes the request and sends the message to the OCI Queue.
         public void handleMessagesRequest(@RequestPayload Messages request) {
            OCIQueue ociQueue = new OCIQueue(queueId, endPoint, region);
      
            //Create an ArrayList to store the users
            ArrayList<User> usersMessageArray = new ArrayList<User>();
      
            //Iterate over the messages, extracting the SOAP Messages and storing in the Java Objects (Car, House, User) 
            for (MessageType message : request.getMessage()) {
      
                  User user = new User();
                  user.setUserName(message.getUsername());
                  user.setUserLastName(message.getUserlastname());
                  user.setID(message.getId());
                  user.setEmail(message.getEmail());
                  user.setDate(message.getDate());
                  user.setAttribute(message.getAttribute());
      
                  //Insert User in Oracle ATP
                  soapObjectRepository.saveUserSOAPMessage(user);
      
                  //Process the attributes Car or House depending of the kind of User
                  processMessage(user, message);
                  //Add the user to the ArrayList
                  usersMessageArray.add(user);
            }
      
      
            //Convert to JSON format
            JSONObject jsonObject = jsonBuilder.buildJsonMessage(usersMessageArray);
      
            //Send the JSON message to OCI Queue
            ociQueue.sendMessages(jsonObject.toString());
      
         }
      
         //The processMessage method processes the message based on the user's attribute.
         private void processMessage(User user, MessageType message) {
            String subject = user.getAttribute();
            switch (subject) {
                  case "CAR":
                     handleCAR(user, message);
                     break;
                  case "HOUSE":
                     handleHouse(user, message);
                     break;
                  default:
                     System.out.println("Unknown subject: " + subject);
            }
         }
      
         //The handleCAR method processes the CAR message.
         private void handleCAR(User user, MessageType message) {
            Car car = new Car();
            car.setBrand(message.getBody().getEnvelope().getBrand());
            car.setColor(message.getBody().getEnvelope().getColor());
            car.setPlate(message.getBody().getEnvelope().getPlate());
      
            user.setCar(car);
            //Insert Car in Oracle ATP
            soapObjectRepository.saveCarSOAPMessage(user.getCar());
      
         }
      
         //The handleHouse method processes the HOUSE message.
         private void handleHouse(User user, MessageType message) {
            House house = new House();
            house.setFloors(message.getBody().getEnvelope().getFloors());
            house.setLocation(message.getBody().getEnvelope().getLocation());
            house.setRooms(message.getBody().getEnvelope().getRooms());
            house.setBathRooms(message.getBody().getEnvelope().getBathrooms());
      
            user.setHouse(house);
      
            //Insert Houses in Oracle ATP
            soapObjectRepository.saveHouseSOAPMessage(user.getHouse());
      
         }
      }
      
  11. Nachdem wir den gesamten Bau des Spring Boot-Projekts abgeschlossen haben, erstellen wir die Dockerfile im Projektordner.

  1. Führen Sie den folgenden Befehl aus, um das Projektimage im lokalen Docker-Repository zu erstellen und per Push zu übertragen.

    docker build . -t springbootapp:latest
    

    Docker-Image erstellen

  2. Führen Sie den folgenden Befehl aus, um das Image im lokalen Docker-Repository zu prüfen.

    docker images
    

    Lokales Docker-Image-Repository

  3. Wir können das Spring Boot-Anwendungsimage mit dem vollständigen Pfad Ihres OCI Container Registry Classic-Repositorys taggen.

    docker tag springbootapp:latest gru.ocir.io/xxxxxxxxxx/springboot/tutorialapp:latest
    
  4. Führen Sie den folgenden Befehl aus, um die Prüfung im lokalen Docker-Repository durchzuführen.

    docker images
    

    OKE-Anwendung taggen

  5. Führen Sie den folgenden Befehl aus, um das Image per Push an OCI Container Registry Classic zu übertragen.

    docker push gru.ocir.io/xxxxxxxxxx/springboot/tutorialapp:latest
    

    OKE-Anwendung pushen

  6. Um die OKE-Imageanwendung in OCI Container Registry Classic zu prüfen, gehen Sie zu Entwicklerservices, Container und Artefakte, und klicken Sie auf Container Registry.

    Bild in OKE Containe Registry

    Sobald sich das Image in OCI Container Registry Classic befindet, können wir zu unserer Entwicklungsumgebung navigieren und dieses Image in OKE bereitstellen. Führen Sie für dieses Tutorial den folgenden Befehl aus, um die erforderlichen Konfigurationen zu erstellen.

    Hinweis: Da der Namespace und der Serviceaccount vorher konfiguriert wurden, ist das Secret erforderlich.

    1. Führen Sie den folgenden Befehl aus, um auf den Projektordner zuzugreifen.

      cd tutorial/
      
    2. Führen Sie den folgenden Befehl aus, um ein Secret für OKE zu erstellen.

      kubectl create secret -n ns-tutorial generic ocir --from-file=.dockerconfigjson=../.docker/config.json --type=kubernetes.io/dockerconfigjson
      

      Secrete Oke erstellen

  7. Die OKE-Umgebung ist bereits bereit. Stellen Sie daher das Anwendungsimage aus OCI Container Registry Classic in OKE bereit.

    Hinweis: Um das Anwendungsimage bereitzustellen, muss eine Manifestdatei vorhanden sein. In diesem Tutorial ist die folgende yaml-Datei die Manifestdatei. Sie wird verwendet, um die Anwendung bereitzustellen und den Ingress-Service zu erstellen, der in einem OCI Load Balancer dargestellt wird, der mit dem Port 80 horcht.

    • springboot_application.yaml:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
      name: soap-oci-queue-app
      namespace: ns-tutorial 
      labels:
         app: soap-oci-queue-app
      spec:
      replicas: 6
      selector:
         matchLabels:
            app: soap-oci-queue-app
      template:
         metadata:
            labels:
            app: soap-oci-queue-app
         spec:
            serviceAccountName: tutorialserviceaccount
            automountServiceAccountToken: true      
            containers:
            - name: soap-oci-queue-app
            image: gru.ocir.io/xxxxxxxxxxxx/springboot/tutorialapp:latest
            ports:
            - containerPort: 8080
            imagePullSecrets:
            - name: ocir-docker-config
      ---
      
      apiVersion: v1
      kind: Service
      metadata:
      name: svc-dev-app 
      namespace: ns-tutorial 
      spec:
      selector:
         app: soap-oci-queue-app
      ports:
         - port: 80
            targetPort: 8080
      type: LoadBalancer
      
  8. Führen Sie den Befehl kubectl in dem Ordner aus, in dem Sie die Manifestdatei gespeichert haben.

    kubectl apply -f springboot_application.yaml
    

    Jetzt wird die Anwendung bereitgestellt, und der Ingress Load Balancer-Service wird in OKE erstellt.

    Manifest in OKE anwenden

  9. Um den in OKE erstellten Pod und Service zu validieren, führen Sie den folgenden Befehl aus.

    kubectl get pods -A
    

    OKE PODS

    kubectl get svc -A
    

    OKE-Services

    Hinweis: Laden Sie das Oracle GraalVM-basierte Java-Anwendungsprojekt für Spring Boot von hier herunter: tutorial.zip.

Aufgabe 7: Spring Boot-Oracle Graal-VM-Anwendung mit JMeter testen

Weitere Informationen zur Installation von JMeter finden Sie unter Erste Schritte mit JMeter.

Nachdem JMeter installiert und konfiguriert wurde, können Sie HTTP POST-SOAP-Anforderungen senden. Beispiel: Setzen Sie die Anzahl der Threads auf 2, um 2 gleichzeitige Benutzer oder Anwendungen darzustellen, und legen Sie die Schleifenanzahl auf 3000 fest, d.h. jeder Benutzer oder jede Anwendung sendet 3000 Anforderungen für insgesamt 6000 SOAP-Anforderungen.

SOAP-Nachrichten

Legen Sie in JMeter die OCI Load Balancer-IP, den im Spring Boot-Projekt konfigurierten Pfad und die SOAP-XML im Body fest.

HTTP-SOAP-Anforderung

Führen Sie JMeter mit 6000 SOAP-Transaktionen aus, und prüfen Sie.

Hinweis: Während wir das SOAP-Messaging von Clientanwendungen simulieren, sind die Informationen für jede SOAP-HTTP-Anforderung die gleichen wie in der oben gezeigten SOAP-XML-Datei. Sie ändern sich nicht, aber in einer echten Kundenumgebung variieren die Informationen sicherlich.

Führen Sie die folgende Anweisung aus:

  1. Anzeige der gesamten in ATP gespeicherten Daten.

    Oracle ATP

  2. Details der in jeder Tabelle in ATP gespeicherten Daten anzeigen.

    • Autos:

      Autos

    • HÄUSER:

      WOHNHÄUSER

    • USERS:

      USERS

  3. Um die Gesamtanzahl der in OCI Queue gespeicherten OCI Queue-Anforderungen anzuzeigen.

    Gesamtanzahl OCI-Queueanforderungen

  4. So zeigen Sie Meldungsdetails in OCI Queue im JSON-Format an.

    OCI Queue-Nachrichten - Details

Danksagungen

Weitere Lernressourcen

Sehen Sie sich andere Übungen zu docs.oracle.com/learn an, oder greifen Sie im Oracle Learning YouTube-Channel auf weitere kostenlose Lerninhalte zu. Besuchen Sie außerdem education.oracle.com/learning-explorer, um Oracle Learning Explorer zu werden.

Die Produktdokumentation finden Sie im Oracle Help Center.