Руководство прикладного разработчика#

Термины и определения#

Термин/Аббревиатура

Определение

API

Application Programming Interface, программный интерфейс приложения

gRPC

Высокопроизводительный фреймворк, разработанный компанией Google для вызова удаленных процедур (RPC)

HTTP

HyperText Transfer Protocol, протокол передачи гипертекста

JSON

JavaScript Object Notation, текстовый формат обмена данными, основанный на JavaScript

SAR

Специализированное хранилище секретных данных, которое используется для хранения собственных приватных ключей и сертификатов сервера или клиента

REST

Representational State Transfer, архитектурный стиль взаимодействия компонентов распределенного приложения в сети

RPC

Remote Procedure Call, система удаленного вызова процедур

Service Mesh

Конфигурируемый инфраструктурный уровень с низкой задержкой. Используется для обработки большого объема сетевых межпроцессных коммуникаций между API

Spring

Сокращение от Spring Framework, универсальный фреймворк с открытым исходным кодом для Java-платформы

Spring Boot

Проект, который позволяет упростить создание приложений на основе Spring

SSL

Secure Sockets Layer, криптографический протокол, предназначенный для защиты обмена данными в сети

TrustStore

Специализированное хранилище секретных данных, которое используется для хранения сертификатов от доверенного центра сертификации (CA)

URI

Uniform Resource Identifier, унифицированный идентификатор ресурса

URL

Система унифицированных адресов электронных ресурсов

XML

eXtensible Markup Language, расширяемый язык разметки

Audit PVM

Функциональная подсистема продукта Platform V Monitor (ОРМ)

Системные требования#

Требования к системному программному обеспечению приведены в разделе Системные требования документа документа «Руководство по установке» компонента SAPG Gateway (SAPG) продукта Platform V Synapse Enterprise Integration.

Подключение и конфигурирование#

Для установки экземпляра Шлюза SAPG на стенд в проект используйте helm chart из прилагаемого дистрибутива.

Быстрый старт#

Разработка первого приложения с использованием программного продукта.

Взаимодействие со шлюзом через GRPC интерфейс#

  1. Проверьте, что Шлюз SAPG запущен и готов к работе:

    1. В консоли Kubernetes откройте меню Workloads → Pods, найдите под Шлюза SAPG. Перейдите по ссылке в наименовании пода и проверьте, что он имеет статус Running.

    2. Зайдите в терминал пода и выполните команду:

      sh-4.2$ curl localhost:8799/actuator/health/ping
      {"status":"UP"}
      

      Ответ {"status":"UP"} показывает, что Шлюз SAPG запущен и готов к работе.

  2. Подготовьте Proto-файлы с описанием универсального API Шлюза SAPG.

ProtoMessage.proto:

    syntax = "proto3";

    import "google/protobuf/any.proto";

    package com.sbt.synapse.gateway;

    message ProtoMessage {
      string messageId = 1;
      string correlationId = 2;
      string body = 14;
      map<string, string> systemHeaders = 3;
      map<string, string> userHeaders = 4;
      google.protobuf.Any extension = 15;
    }

Heartbeat.proto:

    syntax = "proto3";

    package com.sbt.synapse.gateway;

    message Heartbeat {
    int64 timestamp = 1;
    string messageId = 2;
    }

MessageService.proto:

    syntax = "proto3";

    import "Message.proto";
    import "Heartbeat.proto";

    package com.sbt.synapse.gateway;

    option java_multiple_files = true;
    option java_package = "com.sbt.synapse.gateway.protobuf";
    option java_outer_classname = "MessageService";
    option objc_class_prefix = "HLW";

    service MessageAsyncChannel {
    rpc processMessage (ProtoMessage) returns (Heartbeat);
    }

    service MessageSyncChannel {
    rpc processMessage (ProtoMessage) returns (ProtoMessage);
    }
  1. Создайте проект SpringBoot-приложения.

  2. По proto-описанию сгенерируйте Java-классы, используя proto-компилятор (protoc) или плагин для используемой системы сборки (gradle, maven). Для генерации с помощью protoc выполните следующий перечень действий.

    4.1 Установите proto-компилятор (инструкция: https://grpc.io/docs/protoc-installation/).

    4.2 Скачайте gRPC-плагин для proto-компилятора для java (в примере использована версия 1.25.0, можно получить из maven-репозитория: https://mvnrepository.com/artifact/io.grpc/protoc-gen-grpc-java/1.25.0 пункт Files: view all). 4.3 Положите файлы .proto в общий каталог.

    4.5 Создайте в нем подкаталог java (пустой).

    4.6 Из каталога с proto-файлами выполните команду:

    В Windows: `protoc --plugin=protoc-gen-grpc-java="C:\Program Files\proto_plugin\protoc-gen-grpc-java-1.25.0-windows-x86_64.exe" -I=.  
    
    В Linux: `protoc --plugin=protoc-gen-grpc-java=~/proto_plugin/protoc-gen-grpc-java-1.25.0-linux-x86_64.exe" -I=. --java_out=java --grpc-java_out=java ./*.proto`.
    

После выполненных действий вподкаталоге java появятся разложенные по папкам в соответствии с именами пакетов java-файлы с кодом сервисов и сообщений.

  1. Добавьте полученные файлы к проекту.

    Package

    Classes

    com.sbt.synapse.gateway

    Message
    HeartbeatOuterClass

    com.sbt.synapse.gateway.protobuf

    MessageAsyncChannelGrpc
    MessageSyncChannelGrpc

  2. Дополнительно укажите зависимости:

    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-protobuf</artifactId>
      <version>1.20.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-stub</artifactId>
      <version>1.20.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-core</artifactId>
      <version>1.20.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.20.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-services</artifactId>
      <version>1.20.0</version>
    </dependency>
    <dependency>
      <groupId>io.github.lognet</groupId>
      <artifactId>grpc-spring-boot-starter</artifactId>
      <version>2.4.4</version>
    </dependency>
    <dependency>
    <groupId>io.github.lognet</groupId>
    <artifactId>grpc-spring-boot-starter</artifactId>
    <version>2.4.4</version>
    </dependency>    
    
  3. Добавьте импорт полученных классов, а также классов поддержки protobuf и grpc.

    Импорт классов:

    import com.google.protobuf.Any;
    import com.sbt.synapse.gateway.HeartbeatOuterClass.Heartbeat;
    import com.sbt.synapse.gateway.protobuf.MessageSyncChannelGrpc;
    import com.sbt.synapse.gateway.Message.ProtoMessage;
    import io.grpc.ManagedChannel;
    import io.grpc.ManagedChannelBuilder;
    import io.grpc.stub.StreamObserver;
    import org.lognet.springboot.grpc.GRpcService;
    
  4. Добавьте в приложение сервис для приема си.

    Пример сервиса:

    @GRpcService
    public class GrpcService extends MessageSyncChannelGrpc.MessageSyncChannelImplBase {
    
    @Override
    public void processMessage(ProtoMessage message, StreamObserver<ProtoMessage> responseObserver) {
    Logger logger = LoggerFactory.getLogger(GrpcService.class);
    logger.info("Request: " + message.getBody());
    
    responseObserver.onNext(ProtoMessage.newBuilder().setMessageId(message.getMessageId())
    .setBody("{\"ECHOTEXT\":\"Hello SAP\","RESPTEXT":\"hello\"}").build());
    
    responseObserver.onCompleted();
    }
    }
    
  5. Добавьте в приложение клиента, формирующего запрос {"REQUTEXT": "Hello SAP"} с установленными messageId алиасом ФМ connection.

    Пример клиента:

    @Component
    public class GrpcClientSender {
    
        @Value("${service.host}")
        private String serviceHost;
    
        @Value("${service.port}")
        private int servicePort;
    
        public void makeRequest() {
            Logger log = LoggerFactory.getLogger(GrpcClientSender.class);
    
            ManagedChannel channel = ManagedChannelBuilder.forAddress(serviceHost, servicePort).usePlaintext().build();
            ProtoMessage message = ProtoMessage.newBuilder()
                    .setBody("{\"REQUTEXT\": \"Hello SAP\"}").setMessageId("connection").build();
            MessageSyncChannelGrpc.MessageSyncChannelBlockingStub messageSyncChannelBlockingStub = MessageSyncChannelGrpc.newBlockingStub(channel);
    
            try {
                ProtoMessage message = messageSyncChannelBlockingStub.processMessage(message);
                log.info("Response: " + message.getBody());
            } catch (Exception e) {
                System.out.println("catch error " + e.getMessage());
            } finally {
                channel.shutdown();
            }
        }
    }
    
  6. В application.properties установите следующие параметры:

    service.host=localhost
    service.port=5454
    server.port=8787
    grpc.port=5454
    
  7. Для публикации образа приложения в docker-registry создайте Dockerfile. В нем укажите, на основе какого базового образа собирать контейнер с приложением, имя jar-файла приложения для установки в контейнер и команду для его запуска.

    Dockerfile:

    #Ссылка на базовый Docker-образ, нужно указать свой
    FROM <базовый образ для сборки>
    
    ADD <jarName>.jar /app/<jarName>.jar
    CMD touch /app/<jarName>.jar
    ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dspring.config.location=file:/deployments/config/application.properties","-Djava.security.egd=file:/dev/./urandom","-jar","/app/<jarName>.jar"]
    
  8. Соберите Docker-образ и опубликуйте его в Dev-репозитории.

  9. Настройте артефакты для приложения.

    Config Map:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: test-app-config
    data:
      application.properties:
        server.port=8787
        grpc.port=5454
        service.host=<имя сервиса шлюза>
        service.port=5454
    

    Deployment:

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: test-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: test-app
      template:
        metadata:
          labels:
            app: test-app
          annotations:
            sidecar.istio.io/inject: 'true'
        spec:
          volumes:
            - name: application-config
              configMap:
                name: test-app-config
                items:
                  - key: application.properties
                    path: application.properties
                defaultMode: 400
          containers:
            - resources:
                limits:
                  cpu: 200m
                  memory: 400Mi
                requests:
                  cpu: 100m
                  memory: 330Mi
              name: test-app
              env:
                - name: PROJECT_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.namespace
              ports:
                - containerPort: 5454
                  protocol: TCP
                - containerPort: 8787
                  protocol: TCP
              imagePullPolicy: Always
              volumeMounts:
                - name: application-config
                  readOnly: true
                  mountPath: /deployments/config
              terminationMessagePolicy: File
              image: >-
                <ссылка на Docker-образ приложения в dev - репозитории>
          terminationGracePeriodSeconds: 80
    

    Service:

    apiVersion: v1
    kind: Service
    metadata:
      name: test-app
    spec:
      selector:
        name: test-app
      ports:
        - name: grpc
          port: 5454
          targetPort: 5454
    
  10. Загрузите артефакты в Kubernetes.

  11. Откройте терминал пода приложения и проверьте, что в журналах появились записи об успешном вызове ФМ.

    Пример журнала клиента:

    2024-11-25 10:54:27.740 INFO 14592 --- [ main] c.s.s.workshop.grpc.GrpcClientSender : Response:  { "ECHOTEXT" : "ECHOTEXT", "RESPTEXT" : "RESPTEXT" }
    
  12. Проверьте работу обработки входящих запросов от шлюза, для этого необходимо сделать запрос через curl Пример запроса:

       curl -d '{"REQUTEXT": "Hello SAP"}' <имя сервиса шлюза>:<порт>
       
    

    Пример ответа:

       { "ECHOTEXT" : "ECHOTEXT", "RESPTEXT" : "RESPTEXT" }
    

    Пример журнала сервера:

    2024-11-25 10:54:27.743 INFO 3876 --- [ault-executor-0] c.sbt.synapse.workshop.grpc.GrpcService : Request: {"REQUTEXT": "Hello SAP"}"
    2024-11-25 10:54:27.746 INFO 3876 --- [ault-executor-0] c.sbt.synapse.workshop.grpc.GrpcService : Request: {"REQUTEXT": "Hello SAP"}"
    2024-11-25 10:54:27.748 INFO 3876 --- [ault-executor-0] c.sbt.synapse.workshop.grpc.GrpcService : Request: {"REQUTEXT": "Hello SAP"}"
    

Взаимодействие со шлюзом через HTTP интерфейс#

  1. Создайте gardle проект.

  2. В файл build.gradle добавьте плагин org.openapi.generator.

plugins {
 //   ..    
    id 'org.openapi.generator' version '7.7.0'
}
  1. Выгрузите со шлюза спецификацию вызываемого ФМ в формате openapi, выполнив Get запрос.

   curl -v localhost:8787/api/outbound
   {"openapi":"3.1.0","info":{"title":"SRFC Service","version":"v1"},"paths":{"/api/connection":{"post":{"requestBody":{"description":"STFC_CONNECTION","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request_STFC_CONNECTION"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response_STFC_CONNECTION"}}}}}}}},"components":{"schemas":{"Request_STFC_CONNECTION":{"description":"Request","type":"object","required":["REQUTEXT"],"properties":{"REQUTEXT":{"description":"Text field (alphanumeric characters)","type":"string","maxLength":255}}},"Response_STFC_CONNECTION":{"description":"Response","type":"object","required":["REQUTEXT"],"properties":{"ECHOTEXT":{"description":"Text field (alphanumeric characters)","type":"string","maxLength":255},"RESPTEXT":{"description":"Text field (alphanumeric characters)","type":"string","maxLength":255}}}}}}
  1. Полученный ответ сохраните в файл openapi.json и положите в корень проекта.

  2. Настройте плагин для гененерации http клиента для вызова ФМ по HTTP в файле build.gradle.

Пример настройки плагина openApiGenerate для генерации http клиента

     openApiGenerate {
	// ...
        generatorName.set('java')

        configOptions.set([
	       // ...
           library: 'restclient',   
		   openApiNullable: 'false'
	     ])
        inputSpec.set('openapi.json')
        ignoreFileOverride.set(".openapi-generator-java-sources.ignore")
        invokerPackage.set('com.myapp')
        modelPackage.set('com.myapp.model'
        apiPackage.set('com.myapp.api')
     }

Для генерации http сервера необходимо указать следующие настройки

Пример настройки плагина openApiGenerate для генерации http сервера

     openApiGenerate {
	// ...
        generatorName.set('spring')

        configOptions.set([
	       // ...
           library: 'spring-boot',   
		   openApiNullable: 'false'
	     ])
        inputSpec.set('openapi.json')
        ignoreFileOverride.set(".openapi-generator-java-sources.ignore")
        invokerPackage.set('com.myapp')
        modelPackage.set('com.myapp.model'
        apiPackage.set('com.myapp.api')
     }
  1. Добавьте дополнительные плагины в build.gradle.

Пример плагинов:

plugins {
//...
    id 'org.springframework.boot' version '3.3.2'
    id 'io.spring.dependency-management' version '1.1.6'

}
  1. Добавьте зависимости в build.gradle.

Пример необходимых зависимостей:

dependencies {
// ...    
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'


    implementation 'org.springdoc:springdoc-openapi-ui:1.6.6'
    implementation 'io.swagger.core.v3:swagger-annotations:2.2.14'
    implementation 'org.openapitools:openapi-generator-gradle-plugin:7.7.0'
    implementation  'jakarta.validation:jakarta.validation-api:3.1.0'


    compileOnly("org.projectlombok:lombok:1.18.30")
    testCompileOnly("org.projectlombok:lombok:1.18.30")
    annotationProcessor("org.projectlombok:lombok:1.18.30")
    testAnnotationProcessor("org.projectlombok:lombok:1.18.30")

}
  1. Включите сгенерированные исходники в проект.

sourceSets.main.java.srcDir "${buildDir}/generate-resources/main/src/main/java"
  1. Настройте openApiGenerate для автоматического запуска перед каждой компиляцией.

   tasks.named('compileJava') {
    dependsOn(tasks.openApiGenerate)
    }

Результат

Финальная версия файла build.gradle с учетом всех изменений, которую можно скопировать и вставить.

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.2'
    id 'io.spring.dependency-management' version '1.1.6'
    id 'org.openapi.generator' version '7.7.0'
}

group 'org.example'
version '1.0-SNAPSHOT'


java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'


    compileOnly("org.projectlombok:lombok:1.18.30")
    testCompileOnly("org.projectlombok:lombok:1.18.30")
    annotationProcessor("org.projectlombok:lombok:1.18.30")
    testAnnotationProcessor("org.projectlombok:lombok:1.18.30")
}


sourceSets.main.java.srcDir "${buildDir}/generate-resources/main/src/main/java"


tasks.named('compileJava') {
    dependsOn(tasks.openApiGenerate)
}

test {
    useJUnitPlatform()
}

openApiGenerate {
    generatorName.set('java')
    configOptions.set([
            library: 'restclient',
            openApiNullable: 'false'
    ])
    inputSpec.set('openapi.json')
    ignoreFileOverride.set(".openapi-generator-java-sources.ignore")
    invokerPackage.set('com.myapp')
    modelPackage.set('com.myapp.model')
    apiPackage.set('com.myapp.api')
}

Пункты 10 - 13 только при создании клиента

  1. Добавьте основной класс с аннотацией @SpringBootApplication.

Пример класса:

 @SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
  1. Соберите проект, сгенеряться классы для рест клиента в директории ${buildDir}/generate-resources/main/src/main/java.

  2. Через класс конфигурацию добавьте создание бинов клиента.

Пример класса конфигурации

    @Value("${client.baseUrl}")
    private String baseUrl;

    @Bean
    ApiClient apiClient(RestClient.Builder builder) {
        var apiClient = new ApiClient(builder.build());
        apiClient.setBasePath(baseUrl);
        return apiClient;
    }

    @Bean
    DefaultApi defaultApi(ApiClient apiClient) {
        return new DefaultApi(apiClient);
    }
  1. Добавьте класс, имплементирующий интерфейс CommandLineRunner для вызова по ресту ФМ.

Пример класса:

@Component
@Slf4j
public class Runnner implements CommandLineRunner {
    DefaultApi defaultApi;

    public Runnner(DefaultApi defaultApi){
        this.defaultApi = defaultApi;
    }

    @Override
    public void run(String... args) throws Exception {
        RequestSTFCCONNECTION req = new RequestSTFCCONNECTION();
        req.setREQUTEXT("Hello");

        ResponseSTFCCONNECTION res = defaultApi.apiConnectionPost(req);
        log.info("Response: {}", res);
    }
}
  1. В application.properties установите следующие параметры:

    server.port=8787
    client.baseUrl=http://<имя сервиса шлюза>:<порт>
    
  2. Для публикации образа приложения в docker-registry создайте Dockerfile. В нем укажите, на основе какого базового образа собирать контейнер с приложением, имя jar-файла приложения для установки в контейнер и команду для его запуска.

    Dockerfile:

    #Ссылка на базовый Docker-образ, нужно указать свой
    FROM <базовый образ для сборки>
    
    ADD <jarName>.jar /app/<jarName>.jar
    CMD touch /app/<jarName>.jar
    ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dspring.config.location=file:/deployments/config/application.properties","-Djava.security.egd=file:/dev/./urandom","-jar","/app/<jarName>.jar"]
    
  3. Соберите Docker-образ и опубликуйте его в Dev-репозитории.

  4. Настройте артефакты для приложения.

    Config Map:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: test-app-config
    data:
      application.properties:
        server.port=8787
        client.baseUrl=http://<имя сервиса шлюза>:<port>
    

    Deployment:

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: test-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: test-app
      template:
        metadata:
          labels:
            app: test-app
          annotations:
            sidecar.istio.io/inject: 'true'
        spec:
          volumes:
            - name: application-config
              configMap:
                name: test-app-config
                items:
                  - key: application.properties
                    path: application.properties
                defaultMode: 400
          containers:
            - resources:
                limits:
                  cpu: 200m
                  memory: 400Mi
                requests:
                  cpu: 100m
                  memory: 330Mi
              name: test-app
              env:
                - name: PROJECT_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.namespace
              ports:
                - containerPort: 5454
                  protocol: TCP
                - containerPort: 8787
                  protocol: TCP
              imagePullPolicy: Always
              volumeMounts:
                - name: application-config
                  readOnly: true
                  mountPath: /deployments/config
              terminationMessagePolicy: File
              image: >-
                <ссылка на Docker-образ приложения в dev - репозитории>
          terminationGracePeriodSeconds: 80
    

    Service:

    apiVersion: v1
    kind: Service
    metadata:
      name: test-app
    spec:
      selector:
        name: test-app
      ports:
        - name: grpc
          port: 5454
          targetPort: 5454
    
  5. Загрузите артефакты в Kubernetes.

  6. Откройте терминал пода приложения и проверьте, что в журналах появились записи об успешном вызове ФМ

2024-11-27T20:00:48.720+04:00  INFO 5982 --- [           main] com.sbt.synapse.stub.Runnner             : Response: class ResponseSTFCCONNECTION {
    ECHOTEXT: Hello
    RESPTEXT: SAP R/3 Rel. 754   Sysid: A4H      Date: 20241127   Time: 160048   Logon_Data: 001/DEVELOPER/E
}

Журналирование#

В процессе работы Шлюз SAPG фиксирует события в журналах.

Системное журналирование#

В системном журнале фиксируются события, возникающие в приложении в процессе его работы. По умолчанию системный журнал выводится в консоль контейнера приложения.

Можно получить доступ к системному журналу с помощью веб-интерфейса Kubernetes: WorkloadsPods → имя пода → вкладка Logs.

Чтобы выгрузить системный журнал через консоль клиента Kubernetes, выполните команду:

oc logs -c <имя контейнера> <имя пода> > <имя файла>.txt

Канал вывода журнала, уровень журналирования и шаблон записи события задается в файле logback.xml. Для изменения настроек по умолчанию в конфигурации шлюза задайте расположение собственного файла logback.xml.

Расположение собственного файла logback.xml устанавливается настройкой logging.config.

Прикладное журналирование#

В прикладном журнале фиксируются следующие шаги прохождения интеграционной цепочки:

  • шлюз SAPG принял входящий запрос по HTTP/GRPC;

  • шлюз SAPG вызвал по RFC функциональный модуль SAP системы;

  • шлюз SAPG получил ответ от SAP системы;

  • шлюз SAPG пробросил ответ по HTTP/GRPC;

  • ошибка на Шлюзе SAPG при вызове функционального модуля.

Прикладной журнал записывается на смонтированный в контейнер приложения ресурс, который задается в конфигурации шлюза. По умолчанию прикладной журнал записывается в файл /var/log/synapse/messages1.log.

Прикладные записи журнала могут быть извлечены из контейнера приложения и отправлены в подсистему журналирования платформы. Для этого в Deployment Шлюза SAPG должен быть сконфигурирован Sidecar-контейнер с компонентом платформы - Агентом журналирования. Порядок подключения и использования Агента журналирования приведено в документе Руководство прикладного разработчика на этот компонент.

Интеграционное журналирование (трассировка)#

Интеграционное журналирование выполняется средствами Service Mesh.

Sidecar-контейнер istio-proxy обеспечивает передачу трассировочной информации из транспортных заголовков каждого исходящего gRPC-вызова в систему интеграционного журналирования.

Шлюз SAPG заполняет заголовки трассировки в соответствии с заданными настройками.

Правила заполнения заголовков трассировки устанавливаются в секции настроек tracing.

Горизонтальное масштабирование#

Горизонтальное масштабирование Шлюза SAPG реализуется и регулируется системными механизмами Kubernetes/Istio. В любой момент, при необходимости, могут работать одновременно произвольное количество экземпляров Шлюза SAPG с общей конфигурацией (произвольное количество подов одного Deployment). Количество запущенных экземпляров определяется настройкой в Deployment и ограничивается только лимитами ресурсов проекта в Kubernetes.

Количество запускаемых экземпляров (подов) Шлюза SAPG задается в артефакте Deployment параметром spec.replicas.

Метрики#

Для дополнительного мониторинга параметров в Шлюзе SAPG реализован механизм сбора метрик его работы. Метрики публикуются на HTTP-интерфейсе шлюза в формате prometheus и доступны по URI /actuator/prometheus (метод GET).

Порт, на котором запускается HTTP-сервис, задается настройкой server.port конфигурации шлюза.

Вы можете получить текущий актуальный список метрик, выполнив команду в терминале контейнера Шлюза SAPG:

curl localhost:<номер http порта шлюза>/actuator/prometheus

Настройка регистрации событий аудита#

Шлюз SAPG позволяет фиксировать события аудита в локальном буфере аудита.

Перечень фиксируемых событий Аудита, которые возникают в процессе функционирования Шлюза SAPG:

Код

Событие

Комментарий

RFC_success

Успешное подключение к SAP

Фиксируется при каждом успешном подключении Шлюза SAPG к SAP.

RFC_error

Ошибка подключения к SAP

Фиксируется при ошибке подключения Шлюза SAPG к SAP

RFC_gateway_audit_init

Событие успешной инициализации отправки событий в Аудит

Фиксируется после выполнения регистрации метамодели в Аудите

Перечень параметров событий

Общие параметры событий:

Код

Параметр

Время события

Время фиксируется по моменту возникновения события в конкретном экземпляре шлюза

Проект Kubernetes

Наименование проекта в Kubernetes с запущенным подом шлюза, на котором произошло событие

Источник события

Имя пода шлюза, на котором произошло событие

Имя Node

Имя Node, на которой запущен под шлюза

IP адрес Node

IP Node, на которой запущен под шлюза

Параметры событий RFC_success, RFC_error

Код

Параметр

Имя хоста

Имя хоста сервера приложения/сообщений, к которому выполнялось подключение

Номер порта

Номер порта сервера приложения/сообщений, к которому выполнялось подключение

DN сертификата

DN сертификата шлюза из настроек

DN SAP

Ожидаемый DN SAP из настроек

Описание ошибки

Для успешного подключения: пусто.
Для ошибки подключения: фрагмент stack trace шлюза, описывающий ошибку

Параметры события RFC_gateway_audit_init

Код

Параметр

audit_url

URL эндпоинта Audit OPM, в который отправляются события

Чтобы отправить событие аудита в Audit OPM, в нем предварительно должна быть зарегистрирована метамодель события.

Шлюз формирует метамодель в формате JSON:

{
    "metamodelVersion": "1",
    "module": "rfc-gateway",
    "events": [
        {
            "name": "RFC_gateway_audit_init",
            "description": "Инициализация отправки в аудит",
            "success": true,
            "mode": "reliability",
            "params": [
                {
                    "name": "time",
                    "description": "Время события (timestamp)"
                },
                {
                    "name": "os_project",
                    "description": "Проект Kubernetes (OpenShift)"
                },
                {
                    "name": "event_source",
                    "description": "Имя пода источника события"
                },
                {
                    "name": "node_name",
                    "description": "Имя ноды на которой запущен под шлюза"
                },
                {
                    "name": "node_ip",
                    "description": "IP ноды на которой запущен под шлюза"
                },
                {
                    "name": "audit_url",
                    "description": "URL эндпоинта ТС Аудит"
                }
            ]
        },
        {
            "name": "RFC_success",
            "description": "Успешное подключение к SAP",
            "success": true,
            "mode": "reliability",
            "params": [
                {
                    "name": "time",
                    "description": "Время события (timestamp)"
                },
                {
                    "name": "os_project",
                    "description": "Проект Kubernetes (OpenShift)"
                },
                {
                    "name": "event_source",
                    "description": "Имя пода источника события"
                },
                {
                    "name": "node_name",
                    "description": "Имя ноды на которой запущен под шлюза"
                },
                {
                    "name": "node_ip",
                    "description": "IP ноды на которой запущен под шлюза"
                },
                {
                    "name": "rfc_host",
                    "description": "Имя хоста сервера приложения/сообщений к которому выполнялось подключение"
                },
                {
                    "name": "rfc_host",
                    "description": "Номер порта сервера приложения/сообщений к которому выполнялось подключение"
                },
                {
                    "name": "dn_rfcgateway",
                    "description": "DN сертификата шлюза из настроек"
                },
                {
                    "name": "dn_rfc",
                    "description": "Ожидаемый DN SAP из настроек"
                },
                {
                    "name": "error_desc",
                    "description": "Описание ошибки"
                }
            ]
        },
        {
            "name": "RFC_error",
            "description": "Ошибка подключения к SAP",
            "success": false,
            "mode": "reliability",
            "params": [
                {
                    "name": "time",
                    "description": "Время события (timestamp)"
                },
                {
                    "name": "os_project",
                    "description": "Проект Kubernetes (OpenShift)"
                },
                {
                    "name": "event_source",
                    "description": "Имя пода источника события"
                },
                {
                    "name": "node_name",
                    "description": "Имя ноды на которой запущен под шлюза"
                },
                {
                    "name": "node_ip",
                    "description": "IP ноды на которой запущен под шлюза"
                },
                {
                    "name": "rfc_host",
                    "description": "Имя хоста сервера приложения/сообщений к которому выполнялось подключение"
                },
                {
                    "name": "rfc_host",
                    "description": "Номер порта сервера приложения/сообщений к которому выполнялось подключение"
                },
                {
                    "name": "dn_rfcgateway",
                    "description": "DN сертификата шлюза из настроек"
                },
                {
                    "name": "dn_rfc",
                    "description": "Ожидаемый DN SAP из настроек"
                },
                {
                    "name": "error_desc",
                    "description": "Описание ошибки"
                }
            ]
        }        
    ]
}

Метамодель отправляется один раз при старте приложения.

Примеры событий в JSON - формате:

Пример события RFC_success

{
    "module": "srfc-gateway",
    "metamodelVersion": "1",
    "name": "RFC_success",
    "userNode": "NO-USERNODE",
    "userLogin": "NO-USER",
    "createdAt": 1234567890000,
    "session": "NO-SESSION",
    "userName": "",
    "tags": [
        "<project_name>",
        "<deployment_name>"
    ],
    "params": [
        {
            "name": "time",
            "value": "1234567890"
        },
        {
            "name": "os_project",
            "value": "ci01994970-idevgen2-synapse-esbub-dev"
        },
        {
            "name": "event_source",
            "value": "test-gw-56558d77b6-hcl9v"
        },
        {
            "name": "node_name",
            "value": "nodename.domainname.ru"
        },
        {
            "name": "node_ip",
            "value": "192.0.0.1"
        },
        {
            "name": "RFC_host",
            "value": "hostname.domainname.ru"
        },
        {
            "name": "RFC_port",
            "value": "32000"
        },
        {
            "name": "dn_rfcgateway",
            "value": "CN=TEST-GW"
        },
        {
            "name": "dn_rfc",
            "value": "CN=SYNAPSE"
        },
        {
            "name": "error_desc",
            "value": ""
        }
    ]
}

Пример события RFC_error

{
    "module": "srfc-gateway",
    "metamodelVersion": "4",
    "name": "RFC_error",
    "userNode": "NO-USERNODE",
    "userLogin": "NO-USER",
    "createdAt": 1234567890000,
    "session": "NO-SESSION",
    "userName": "",
    "tags": [
        "<project_name>",
        "<deployment_name>"
    ],
    "params": [
        {
            "name": "time",
            "value": "1234567890"
        },
        {
            "name": "os_project",
            "value": "ci01994970-idevgen2-synapse-esbub-dev"
        },
        {
            "name": "event_source",
            "value": "test-gw-56558d77b6-hcl9v"
        },
        {
            "name": "node_name",
            "value": "nodename.domainname.ru"
        },
        {
            "name": "node_ip",
            "value": "192.0.0.1"
        },
        {
            "name": "rfc_host",
            "value": "hostname.domainname.ru"
        },
        {
            "name": "rfc_port",
            "value": "1452"
        },
        {
            "name": "dn_rfcgateway",
            "value": "CN=TEST-GW"
        },
        {
            "name": "dn_rfc",
            "value": "CN=SYNAPSE"
        },
        {
            "name": "error_desc",
            "value": "nested exception is ..."
        }
    ]
}

Пример события RFC_gateway_audit_init

{
    "module": "srfc-gateway",
    "metamodelVersion": "4",
    "name": "RFC_gateway_audit_init",
    "userNode": "NO-USERNODE",
    "userLogin": "NO-USER",
    "userName": "NO-USER",
    "session": "NO-SESSION",
    "createdAt": 1707393578849,
    "tags": [
        "<project_name>",
        "<project_name>"
    ],
    "params": [
        {
            "name": "time",
            "value": "1707393578561"
        },
        {
            "name": "os_project",
            "value": "ci01994970-idevgen2-synapse-esbub-dev"
        },
        {
            "name": "event_source",
            "value": "test-gw-56558d77b6-hcl9v"
        },
        {
            "name": "node_name",
            "value": "nodename.domainname.ru"
        },
        {
            "name": "node_ip",
            "value": "192.0.0.1"
        },
        {
            "name": "audit_url",
            "value": "<url Аудита>"
        }
    ]
}

Получение данных об имени проекта, имени Node и ее IP-адреса.

Чтобы приложение Шлюза получило доступ к этим данным, в deployment Шлюза должны быть добавлены следующие настройки:

env:
  - name: PROJECT_NAME
    valueFrom:
      fieldRef:
        apiVersion: v1
        fieldPath: metadata.namespace
  - name: NODE_NAME
    valueFrom:
      fieldRef:
        apiVersion: v1
        fieldPath: spec.nodeName
  - name: NODE_IP
    valueFrom:
      fieldRef:
        apiVersion: v1
        fieldPath: status.hostIP

Шлюз при заполнении данных о событиях должен передать в параметре os_project значение переменной окружения PROJECT_NAME, в параметре node_name значение переменной окружения NODE_NAME, в параметре node_ip значение переменной окружения NODE_IP.

Для включения регистрации событий, аудита нужно в конфигурацию Шлюза SAPG добавить секцию:

audit:
  enable: true
  transportType: file
  directory: /var/log/synapse

В этом случае Шлюз SAPG при старте создает в каталоге, указанном в параметре directory, два файла:

event.aud

metamodel.amm

В файл metamodel.amm однократно выгружается метамодель событий. В файл event.aud начинают выгружаться события аудита по мере их возникновения на Шлюзе.

Эту схему можно использовать, если при регистрации событий аудита не предполагается использовать Audit OPM, либо передача событий в Audit OPM должна выполняться сторонними компонентами, выбранными архитектором и разработчиком конечной системы.

Для прямой отправки событий в Audit OPM, секцию audit нужно настроить следующим образом.

audit:
  enable: true
  transportType: http
  http:
    client:
      httpMethod: POST
      url: http://хост:порт
    eventPath: /event_endpoint
    metamodelPath: /metamodel_endpoint
    responseTimeout: 10000
    maxBufferSize: 3000
    retry:
      attempts: 10

При старте шлюз подключится к endpoint Audit OPM, зарегистрирует метамодель и начнет отправку событий.

Одна и та же версия метамодели может регистрироваться произвольное количество раз, но при этом описатель метамодели не должен меняться. Поэтому версия метамодели вместе с самой метамоделью прошита в коде шлюза и меняется только при перепоставке.

Это гарантирует, что шлюзы одной и той же версии, установленные в разных проектах, всегда будут оправлять консистентную модель.

При возникновении ошибок отправки, шлюз сохраняет событие в локальном буфере в памяти приложения и пытается отправить его повторно. Количество попыток настраивается в параметре audit.http.retry.attempt. Количество событий, которое может быть сохранено в буфере, настраивается в параметре audit.http.maxBufferSize.

Если возникает ошибка при регистрации модели, то шлюз повторяет попытки, пока модель не будет зарегистрирована. При этом readiness проба не поднимается, и перевод трафика на этот экземпляр шлюза не происходит.

Миграция на текущую версию#

Первая версия компонента, миграция не требуется.

Использование программного компонента#

Полное описание настроек#

Важно! Строковые значения, представляющие числовые величины, рекомендуется заключать в кавычки, во избежание неявных преобразований типов при загрузке и чтении конфигурации.

Важно! Числовые значения задаются в десятичной системе счисления. Если в начале числа идет цифра 0, то в шлюзе будет присвоено число в восьмеричной системе счисления. Например, если задать в числовом параметре значение = 023, то при старте шлюза при печати настроек отобразится значение 19.

Верхнеуровневые блоки настроек#

Название

Описание

Обязательность

grpc

Настройки gRPC-клиента/сервера

+

server

Настройки http сервера

+

http

Настройки HTTP-клиента

+

logger

Настройки прикладного журнала

rfc

Настройки подключения к SAP

+

routing

Правила маршрутизации

+

tracing

Настройки трассировки

-

spring

Настройки Spring

logging

Настройки журналирования

audit

Настройки аудирования

Блок grpc#

Настройки gRPC-клиента/сервера:

Поле

Тип

Описание

Обязательность

По умолчанию

client

GRpcClientProperties

Настройки клиента для gRPC API

+

server

GRpcServerProperties

Настройки сервера gRPC API

maxMessageSizeInMb

int

Настройка максимального размера сообщения, передаваемого через gRPC, Мбайт

4

Тип grpc.GRpcClientProperties#

Настройки клиента gRPC API:

Поле

Тип

Описание

Обязательность

По умолчанию

settings

Map<String,ClientSettings>

Имя канала и соответствующие ему настройки.
-default — обязательный канал по умолчанию. Для запросов (на уровне gRPC);
- с другими значаниями - пользовательские каналы

+

abortOnCallCancel

boolean

Если флаг установлен (значение true), то после обработки события onCancel (обрыв соединения между Envoy, ручная отмена вызова на клиенте) дальнейший gRPC-вызов в цепочке выполнен не будет.
Флаг необходимо устанавливать, если настроены повторы и дублирование сообщений нежелательно.
Например, сервис вызывает Шлюз SAPG, и при этом по какой-то причине рвется сетевое соединение или истекает время запроса (были повторы). Шлюз SAPG при получении запроса проверяет, не отменен ли запрос и, если флажок установлен и gRPC-запрос уже отменен, не выполняет его обработку

false

Тип grpc.ClientSettings#

Настройки gRPC-канала:

Поле

Тип

Описание

Обязательность

По умолчанию

hostname

String

Хост, к которому будет осуществляться запрос

+

empty-service

port

int

Порт подключения

+

5454

timeout

int

Тайм-аут запроса, мс
Если указать 0 вызов будет выполнен без таймаута

300000

serviceConfig

Map<String, Object>

Блок настроек под специфичные цели

Настройка канала с возможностью повторных вызовов#

Следует использовать только в том случае, когда штатные средства Service Mesh не покрывают потребности. Для канала retryable заполняется блок serviceConfig:

Пример настроек канала с механизмом повторов на уровне gRPC

retryable:
  hostname: localhost
  port: 5454
  serviceConfig:
    methodConfig:
      - retryPolicy:
          backoffMultiplier: 1.0
          maxAttempts: 10.0
          initialBackoff: 1s
          retryableStatusCodes: 
            - UNAVAILABLE
          maxBackoff: 10s

Описание retryPolicy#

Поле

Тип

Описание

Обязательность

backoffMultiplier

double

Множитель для политики повторов, должен быть больше 0. Подробнее

+

maxAttempts

int

Максимальное количество повторов

+

initialBackoff

Duration

Начальное время ожидания перед повтором

retryableStatusCodes

List<String>

Список кодов для повторов

maxBackoff

Duration

Максимальное время для повторов

Тип grpc.GRpcServerProperties#

Настройки сервера gRPC API:

Поле

Тип

Описание

Обязательность

По умолчанию

serverPort

int

Порт сервера gRPC API

6565

threadPool

ThreadPoolConfiguration

Настройки пула обработчиков запросов

concurrentLimiter

ConcurrentLimiter

Ограничение на число запросов в обработке

Тип grpc.ThreadPoolConfiguration#

Параметры пула потоков сервера gRPC. Предназначен для тонкой настройки.

Поле

Тип

Описание

Обязательность

По умолчанию

concurrentConsumers

int

Минимальное количество потоков, обрабатывающих запросы

1

maxConcurrentConsumers

int

Максимальное количество потоков, обрабатывающих запросы

5

threadKeepAliveSeconds

int

Время жизни потока после обработки последнего сообщения, с

60

Тип grpc.ConcurrentLimiter#

Поле

Тип

Описание

Обязательность

По умолчанию

enable

boolean

Включение ограничения. По умолчанию — выключено

false

typeLimit

Enum

Алгоритм ограничения. Возможные значения: FIXED, VEGAS, AIMD

FIXED

fixedLimit

int

Количество одновременно обрабатываемых сообщений

100

aimdLimit

AIMDLimitConfig

Параметры для алгоритма AIMD

vegasLimit

VegasLimitConfig

Параметры для алгоритма VEGAS

AIMD - динамический ограничитель, основанный на потерях, который выполняет аддитивное приращение до тех пор, пока нет ошибок, и мультипликативное уменьшение при наличии ошибок

Тип AIMDLimitConfig#

Поле

Тип

Описание

Обязательность

По умолчанию

minLimit

int

Минимальное количество одновременно обрабатываемых сообщений

20

initialLimit

int

Кол-во запросов одновременно обрабатываемых сообщений при инициализации алгоритма

20

maxLimit

int

Максимальное количество запросов одновременно обрабатываемых сообщений

200

backoffRatio

double

Коэффициент отката

0.9 (>= 0,5, < 1)

timeout

long

Таймаут на обработку запроса используется для алгоритма

1000

VEGAS - динамический ограничитель, основанный на TCP Vegas, где ограничение увеличивается на alpha, если queue_use < alpha и уменьшается на alpha если > beta

Размер очереди рассчитывается по формуле queue_use = limit − BWE×RTTnoLoad = limit × (1 − RTTnoLoad/RTTactual)

Для традиционного TCP Vegas альфа-версия обычно составляет 2-3, а бета-версия обычно составляет 4-6. Чтобы обеспечить лучший рост и стабильность при более высоких ограничениях установите альфа =Макс (3,10% от текущего предела) и бета = Макс (6,20% от текущего предела)

Тип VegasLimitConfig#

Поле

Тип

Описание

Обязательность

По умолчанию

initialLimit

int

Минимальное количество одновременно обрабатываемых сообщений

20

maxConcurrency

int

Максимальное количество запросов одновременно обрабатываемых сообщений

1000

smoothing

double

Коэффициент сглаживания

1.0

alpha

int

Нижнее ограничение очереди

2

beta

int

Верхнее ограничение очереди

4

probeMultiplier

int

Задает кол-во проб

30

Пример настроек блока grpc

grpc:
  #maxMessageSizeInMb: 4 - максимальный размер gRPC-сообщения
  server:
    serverPort: 5455
    threadPool:
      ##ограничение запросов в обработке
      #rejectCapacity: 500
      concurrentConsumers: 30
      maxConcurrentConsumers: 30
    concurrentLimiter:
      enable: true
      typeLimit: FIXED #(AIMD/VEGAS)
      fixedLimit: 100
      aimdLimit:  # для AIMD, алгоритм основан на ошибках
        minLimit: 10
        initialLimit: 50
        maxLimit: 100
        backoffRatio: 0.9
        timeout: 5000
      vegasLimit: # для VEGAS, алгоритм основан на задержках
        initialLimit: 100
        maxConcurrency: 300
        smoothing: 1.0
        alpha: 2
        beta: 6
        probeMultiplier: 100
  client:
    settings:
      default:
        useMultiChannel: true
        channelsCount: 10
        hostname: localhost
        port: 5454
      retryable:
        hostname: localhost
        port: 5454
        serviceConfig:
          methodConfig:
            - retryPolicy:
              backoffMultiplier: 1.0
              maxAttempts: 10.0
              initialBackoff: 1s
              retryableStatusCodes:
                - UNAVAILABLE
              maxBackoff: 10s

Блок server#

Настройки сервера:

Поле

Тип

Описание

Обязательность

По умолчанию

systemName

String

Псевдоним системы-инициатора, используемый при фиксации HTTP-вызова в прикладном журнале. Используется для ведения журнала в HTTP-вызовах

REST

port

int

Порт, на котором запустится приложение

8080

uri

string

URI HTTP-сервиса, поднимаемого шлюзом. Вызовы на основной Endpoint обрабатываются в синхронном режиме.
Шлюз поднимает два дополнительных Endpoints:
c постфиксом /sync - для синхронных вызовов
с постфиксом /async - для асинхронных

convertRequired

boolean

Признак конвертации запросов из формата XML в JSON и обратно

true

maxPoolSize

int

Максимальное число потоков, принимающих запросы по HTTP

20

ssl

Ssl

Настройки SSL для REST-сервера

concurrentLimiter

ConcurrentLimiter

Параметры ограничения одновременной обработки сообщений по HTTP

Тип server.Ssl#

Настройки SSL для REST-сервера:

Поле

Тип

Описание

Обязательность

По умолчанию

enabled

boolean

Флаг включения SSL

+

false

keyStore

string

Путь до хранилища KeyStore

+

keyStorePassword

string

Пароль от хранилища

+

keyStoreType

string

Тип хранилища

+

Тип server.ConcurrentLimiter#

настройки ограничителя одновременной обработки сообщений по HTTP

Поле

Тип

Описание

Обязательность

По умолчанию

enable

boolean

Включен ли ограничитель

false

fixedLimit

int

Кол-во одновременно выполняемых запросов

-

100

Блок http#

Настройки HTTP-транспорта:

Поле

Тип

Описание

Обязательность

По умолчанию

client

WebClientConfiguration

Настройки клиента HTTP

+

Тип WebClientConfiguration#

Настройки клиента HTTP:

Поле

Тип

Описание

Обязательность

По умолчанию

url

String

URL, по которому будет вызываться сервер

+

timeout

Long

Тайм-аут, мс

Без тайм-аута

httpMethod

org.springframework.http.HttpMethod

Тип метода, который будет использоваться при HTTP-вызове

POST

ssl

Ssl

Настройки SSL

channels

Map<String,ChannelClientConfiguration>

Настройки SSL

Тип ChannelClientConfiguration#

Поле

Тип

Описание

Обязательность

По умолчанию

url

String

URL, по которому будет вызываться сервер

+

timeout

Long

Тайм-аут, мс

Без тайм-аута

httpMethod

org.springframework.http.HttpMethod

Тип метода, который будет использоваться при HTTP-вызове

POST

ssl

Ssl

Настройки SSL

Тип http.client.Ssl#

Настройки SSL для клиента:

Поле

Тип

Описание

Обязательность

По умолчанию

trustStore

string

Путь до хранилища TrustStore

+

trustStorePassword

string

Пароль от хранилища TrustStore

+

keyStore

string

Путь до хранилища KeyStore

+

keyStorePassword

string

Пароль от хранилища KeyStore

+

keyAlias

string

Alias сертификата из хранилища

+

Блок logger#

Настройки ведения прикладного журнала:

Поле

Тип

Описание

Обязательность

mask

LoggerMaskConfigurationProperties

Настройка правил маскирования элементов тела сообщения в прикладном журнале. Обычно настройка выносится в отдельный файл конфигурации masking-secret.yml, который загружается в секрет

Тип LoggerMaskConfigurationProperties#

Настройки маскирования для элементов тела сообщения при записи в прикладной журнал.

Поле

Тип

Описание

Обязательность

enabled

boolean

Включение/выключение маскирования

-

enableBase64Decoding

boolean

Включение/выключение декодирования тела сообщения из Base64 Настройка отключена

-

cardNumAttributes

Set<String>

Список наименований xml-атрибутов, в которых нужно замаскировать номер карты

-

cardNumElements

Set<String>

Список наименований xml и json элементов, в которых нужно замаскировать номер карты

-

phoneNumAttributes

Set<String>

Список наименований xml-атрибутов, в которых нужно замаскировать номер телефона

-

phoneNumElements

Set<String>

Список наименований xml и json элементов, в которых нужно замаскировать номер телефона

-

docNumAttributes

Set<String>

Список наименований xml-атрибутов, в которых нужно замаскировать номер паспорта

-

docNumElements

Set<String>

Список наименований xml и json элементов, в которых нужно замаскировать номер паспорта

-

fioAttributes

Set<String>

Список наименований xml-атрибутов, в которых нужно замаскировать ФИО

-

fioElements

Set<String>

Список наименований xml и json элементов, в которых нужно замаскировать ФИО

-

innAttributes

Set<String>

Список наименований xml-атрибутов, в которых нужно замаскировать ИНН

-

innElements

Set<String>

Список наименований xml и json элементов, в которых нужно замаскировать ИНН

-

attributes

Set<String>

Список наименований xml-атрибутов, значение которых нужно полностью замаскировать

-

elements

Set<String>

Список наименований xml и json элементов, значение которых нужно полностью замаскировать

-

elementsWithAttribute

HashMap<String, Set<String>>

Список карт наименований xml-элементов и их атрибутов, значения которых нужно полностью замаскировать. Используется, когда есть повторяющиеся наименования xml-атрибутов.
Важно! Тэг не может быть пустым. Добавление данного тэга не содержащего элементов и атрибутов для маскирования приведет к ошибке загрузки шлюза

-

elementByAttribute

HashMap<String, Set<String>>

Список карт наименований xml-атрибутов и их значений, значения элементов которых необходимо полностью замаскировать. Используется, когда есть повторяющиеся наименования xml-элементов и xml-атрибутов.
Важно! Тэг не может быть пустым. Добавление данного тэга не содержащего атрибутов и их значений для маскирования приведет к ошибке загрузки шлюза

-

Пример настроек маскирования

logger:
  mask:
    enabled: true
    cardNumElements:
      - CardNum # Будет замаскировано значение элемента CardNum: <CardNum>44****9695</CardNum>
    elements:
      - Phone # # Будет замаскировано значение элемента Phone: <Phone>***********</Phone>
    elementsWithAttribute:
      ID:
        - Value
        - Name
      AccountNumber:
        - Value # Будет замаскировано значение атрибута Value в элементе <AccountNumber Value=\"*******************\"></AccountNumber>
      TaxId:
        - Value
    elementByAttribute:
      type:
        - CardNum
        - DocNum
      item:
        - FIO # Будет замаскировано значение элементов, у которых атрибут item имеет значение "FIO" <Value item="FIO">********** ******* ********</Value>

Шлюз позволяет осуществлять маскирование в экранированном XML. Пример маскирования экранированного XML

Настройка:
    logger:
      mask:
        enabled: true
        phoneNumElements:
          - phone
        docNumElements:
          - doc
        fioElements:
          - Fio

Сообщение:

        <Root xmlns:hdr="http://example.com/ESB/SAPG/headers">
        &lt;hdr:ElementTest&gt;
        &lt;Contacts&gt;
        &lt;phone&gt;+7 (123) 456-78-90&lt;/phone&gt;
        &lt;/Contacts&gt;
        &lt;Passport&gt;
        &lt;doc&gt;9911 123456&lt;/doc&gt;
        &lt;/Passport&gt;
        &lt;/hdr:ElementTest&gt;
        </Root>

Отражение в прикладном журнале:
 <Root xmlns:hdr="http://example.com/ESB/SAPG/headers">        &lt;hdr:ElementTest&gt;        &lt;Contacts&gt;        &lt;phone&gt;+* (***) ***-78-90&lt;/phone&gt;        &lt;/Contacts&gt;       &lt;Passport&gt;        &lt;doc&gt;**** ****56&lt;/doc&gt;        &lt;/Passport&gt;        &lt;/hdr:ElementTest&gt;        </Root>

Блок tracing#

Настройки трассировки:

Поле

Тип

Описание

Обязательность

По умолчанию

tracingHeaders

Map<String,ExtractionRule>

Список имен полей заголовков трассировки и правил их вычисления

-

generateXB3Headers

boolean

Признак необходимости генерации заголовков трассировки x-b3-*

-

false

generate128bitTraceId

boolean

Признак генерации заголовка x-b3-traceid 128-битного формата. Необходимо установить в случае, если Шлюз является первым компонентом в цепочке gRPC-вызовов для корректной работы механизма трассировки Istio

-

true

Пример настройки блока tracing

 tracing:
  generateXB3Headers: true
  generate128bitTraceId: true
  tracingHeaders:
    x-b3-traceid: #перезапишет сгенерированный, обрежется до 16 символов при выставленном generate128bitTraceId
      - type: fromBody
        valueJson: '$..RqUID'
    x-synapse-bussinesserrorcode-bin:
      - type: fromBody
        valueJson: '$..bussinesserrorcode'
    x-synapse-rquid:
      - {type: fromBody, valueJson: $..RqUID}
    x-synapse-rqtm:
      - {type: fromBody, valueJson: $..RqTm}

Блок rfc#

Блок настроек в части подключения к SAP.

Поле

Тип

Описание

Обязательность

По умолчанию

systemName

String

Имя системы, с которой осуществляется взаимодействие

+

destinationProfileName

String

Имя активного профиля подключения к АС SAP. В качестве значения указывать alias из секции rfc.destinations

+

default

serverProfileName

String

Имя активного профиля серверной части. В качестве значения указывать alias из секции rfc.servers

+

default

health

HealthConfiguration

Настройки проверки доступности подключения к АС SAP

-

destinations

RfcDestinationConfiguration

Список профилей подключений

servers

RfcServerConfiguration

Список профилей серверной части

Настройки для SAP:

Тип RfcDestinationConfiguration#

Поле

Тип

Описание

Обязательность

По умолчанию

alias

String

Имя алиаса профиля destination

-

default

ashost

String

Хост сервера приложения АС SAP. Настройка обязательная, для прямого подключения к экземпляру сервера приложений

-

mshost

String

Хост сервера сообщений АС SAP. Настройка обязательная для подключения к АС SAP через балансировщик нагрузки

-

msserv

String

Номер порта сервера сообщений АС SAP

-

sysnr

String

Системный номер сервера приложений SAP ABAP. Настройка обязательная для прямого подключения к экземпляру сервера приложений

-

client

String

Имя клиента в АС SAP

-

user

String

Имя пользователя в АС SAP

-

password

String

Пароль пользователя в АС SAP

-

lang

String

Язык входа в АС SAP. Если не определен, то используется язык пользователя по умолчанию

-

expirationTime

String

Время в мс, по истечении которого соединения, поддерживаемые внутренним пулом, могут быть закрыты

60000

poolCapacity

String

Максимальное количество незанятых подключений, поддерживаемых адресатом. Значение 0 означает, что пул подключений отсутствует, т.е. соединения будут закрываться после каждого запроса

-

10

network

String

Ожидаемый тип сети, который будет использоваться пунктом назначения (LAN - быстрая локальная сеть [по умолчанию] или WAN - медленная глобальная сеть)

-

LAN

serializationFormat

String

Формат сериализации, который будет использоваться для передачи данных функционального модуля (rowBased - классическая сериализация на основе строк [по умолчанию] или columnBased - новая сериализация на основе столбцов)

-

columnBased

repositoryRoundtripOptimization

String

Значение 1 принудительно использует удаленный функциональный модуль RFC_METADATA_GET для запросов метаданных из ABAP-систем, значение 0 отключает его. Если свойство не задано, получатель сначала выполнит удаленный вызов, чтобы проверить, доступен ли RFC_METADATA_GET. И если он доступен, получатель будет его использовать

-

1

trace

String

Флаг трассировки RFC. Допустимые значения: 1: включено, 0: отключено (по умолчанию)

-

0

snc

SNCClientConfiguration

Настройки mTLS подключения

-

Тип SNCClientConfiguration#

Поле

Тип

Описание

Обязательность

По умолчанию

mode

String

Режим защищенной сетевой связи (SNC). Допустимые значения: 1: включен, 0: выключен (по умолчанию)

-

0

myName

String

Собственное имя SNC вызывающего абонента (необязательно). Переопределяет имя SNC по умолчанию. Например: p:CN=MyUserID, O=ACompany, C=RU

-

partnerName

String

SNC-имя сервера коммуникационного партнера. Например: p:CN=SID, O=Company, C=RU

-

QOP

String

SNC-качество защиты. Допустимые значения: 1, 2, 3, 8 (по умолчанию), 9

-

8

SSO

String

Включите/выключите механизм единого входа для SNC. Если установлено значение 0, используйте альтернативные учетные данные, такие как пользователь/пароль. Допустимыми значениями являются 1 (да, по умолчанию) и 0 (нет)

-

1

lib

String

Полный путь к библиотеке, предоставляющей службу SNC

-

Тип RfcServerConfiguration#

Поле

Тип

Описание

Обязательность

По умолчанию

alias

String

Имя алиаса профиля server

-

default

gwhost

String

Хост шлюза, на котором должен быть зарегистрирован JCoServer (прямое подключение)

+

gwserv

String

Служба шлюза, которая будет использоваться для регистрации на шлюзе, т.е. символическое название службы (gw00) или номер порта

+

progid

String

Идентификатор программы для регистрации и идентификации JCoServer на шлюзе

-

mshost

String

Хост сервера сообщений, с которого JCoServer должен получать информацию о серверах приложений для использования при подключении через балансировщик

-

msserv

String

Номер порта сервера сообщений АС SAP

-

repositoryDestination

String

Имя получателя для получения JCoRepository по умолчанию

-

snc

SNCServerConfiguration

Настройки MTLS подключения для серверной части

-

trace

String

Флаг трассировки RFC. Допустимые значения: 1: включено, 0: отключено (по умолчанию)

-

0

Тип SNCServerConfiguration#

Поле

Тип

Описание

Обязательность

По умолчанию

mode

String

Режим защищенной сетевой связи (SNC). Допустимые значения: 1: включен, 0: выключен (по умолчанию)

-

0

myName

String

SNC-имя JCoServer. Переопределяет имя SNC по умолчанию. Например: p:CN=JCoServer, O=ACompany, C=RU

-

QOP

String

SNC-качество защиты. Допустимые значения: 1, 2, 3, 8 (по умолчанию), 9

-

8

Допустимыми значениями являются 1 (да, по умолчанию) и 0 (нет)

-

1

lib

String

Полный путь к библиотеке, предоставляющей службу SNC

-

Тип SNCClientConfiguration#

Поле

Тип

Описание

Обязательность

По умолчанию

mode

String

Режим защищенной сетевой связи (SNC); 1: включен, 0: выключен (по умолчанию)

-

0

myName

String

Собственное имя SNC вызывающего абонента (необязательно). Переопределяет имя SNC по умолчанию. Например: p:CN=MyUserID, O=ACompany, C=EN

-

partnerName

String

SNC-имя сервера коммуникационного партнера. Например: p:CN=SID, O=Компания, C=EN

-

QOP

String

SNC-качество защиты. Допустимые значения: 1, 2, 3, 8 (по умолчанию), 9

-

8

SSO

String

Механизм единого входа для SNC. Если установлено значение 0, используйте альтернативные учетные данные, такие как пользователь/пароль. Допустимыми значениями являются 1 (да, по умолчанию) и 0 (нет)

-

1

Допустимыми значениями являются 1 (да, по умолчанию) и 0 (нет)

-

1

lib

String

Полный путь к библиотеке, предоставляющей службу SNC

-

Тип HealthConfiguration#

Поле

Тип

Описание

Обязательность

По умолчанию

successThreshold

Integer

Количество успешных проверок, после которого менеджер возвращается в балансировку

1

failureThreshold

Integer

Количество неуспешных проверок, после которого менеджер исключается из балансировки

1

timeoutSeconds

Integer

Таймаут проверки, задается в секундах

5

periodSeconds

Integer

Период опроса, задается в секундах

5

initialDelaySeconds

Integer

Задержка перед началом опроса, задается в секундах

5

Блок routing#

Блок настроек машрутизации

Поле

Тип

Описание

Обязательность

По умолчанию

inboundRoutes

List<RouteConfig>

Список входящих маршрутов по HTTP/GRPC

-

outboundRoutes

List<RouteConfig>

Список исходящих маршрутов по HTTP/GRPC

-

Пример настройки блока routing

  routing:
    inboundRoutes: #cписок входящих маршрутов по HTTP/GRPC для вызова ФМ в АС SAP
      - name: connection #алиас ФМ. Если вызывать по HTTP, то указывать как path а URI, например /api/connection. Если вызывать по GRPC, то алиас нужно проописать в messageID  в Ptoto Message сообщения
        callFunctionName: STFC_CONNECTION #имя вызывамеого ФМ в SAP
      - name: create
        callFunctionName: SEPM_GWS_EMPLOYEE_CREATE
      - name: update
        callFunctionName: SEPM_GWS_EMPLOYEE_UPDATE
      - name: list
        callFunctionName: BAPI_EPM_EMPLOYEE_GET_LIST
    outboundRoutes: #cписок исходящих маршрутов по HTTP/GRPC для вызова ФМ на стороне внешней АС/микросервиса
      - name: list #алиас ФМ
        callFunctionName: BAPI_EPM_EMPLOYEE_GET_LIST #имя вызывамеого ФМ из SAP
        transportType: HTTP # тип протокола исходящего вызова
        authority: http://serviceList:8787/api/list # endpoint вызываамого внешней АС/микросервиса
      - name: connection #алиас ФМ
        callFunctionName: STFC_CONNECTION #имя вызывамеого ФМ из SAP
        transportType: GRPC  # тип протокола исходящего вызова
        authority: ServiceConnection # имя сервиса внешней АС/микросервиса

Тип RouteConfig#

Поле

Тип

Описание

Обязательность

По умолчанию

name

String

Алиас вызываемого ФМ, соответствует имя патча в URI

+

callFunctionName

String

Имя вызываемого ФМ как в АС SAP

+

transportType

String

Тип протокола для исходящих маршрутов (HTTP/GRPC). Для входящих маршрутов не заполняется

-

HTTP

transportChannel

String

Имя транспортного канала. Пользовательские каналы задаются с траспортных клиентских секциях

-

default

authority

String

Адрес вызываемого сервиса для исходящих маршрутов. Для входящих маршрутов не заполняется

-

Блок spring#

Настройки Spring и его расширений:

Поле

Тип

Описание

Обязательность

По умолчанию

codec.max-in-memory-size

String

Определяет размер буфера для для обработки входящих сообщений по HTTP. Для больших сообщений нужно задавать этот параметр

256 Кбайт

Блок logging#

Настройки журналирования:

Поле

Тип

Описание

Обязательность

По умолчанию

config

String

Путь до Logback.xml

level

Map<String,String>

Позволяет изменить уровень логирования для конкретных пакетов в формате:
<Имя пакета>:<уровень логирования>

Блок audit#

Блок настроек audit задает настройки регистрации событий аудита.

Поле

Тип

Описание

Обязательность

Default

enable

boolean

Включает (true) отправку сообщений в аудит

false

transportType

enum

Тип транспорта для отправки событий в ТС Аудит
Значения: HTTP, FILE

HTTP

directory

String

Путь для записи метамодели для транспорта = FILE

+ (для transportType==FILE)

http

AuditHttp

Настройки HTTP-транспорта

+ (для transportType==HTTP)

Тип AuditHttp#

Настройки HTTP-транспорта для ТС Аудит

Поле

Тип

Описание

Обязательность

Default

client

WebClientConfiguration

Настройки веб-клиента для вызова ТС Аудит

+

eventsPath

String

Путь к endpoint для отправки событий

/event

metamodelPath

String

Путь к endpoint для отправки метамодели

/metamodel

responseTimeout

int

Таймаут вызова ТС Аудит для отправки событий, миллисекунд

5000

maxBufferSize

int

Размер буфера событий для Retry отправки

3000

retry

RetryConfig

Настройки повторной отправки событий в случае неуспешной попытки

Тип RetryConfig#

Поле

Тип

Описание

Обязательность

Default

attempts

int

Количество попыток повторной отправки события в случае ошибки

10

audit:
  enable: true
  transportType: http
  http:
    client:
      httpMethod: POST
      url: http://хост:порт
    eventPath: /event_endpoint
    metamodelPath: /metamodel_endpoint
    responseTimeout: 10000
    maxBufferSize: 3000
    retry:
      attempts: 10

Общие типы#

Тип extractor.ExtractionRule#

Правила получения значений из сообщения. Представляет собой именованный список, в котором для каждого имени заголовка определяются:

Поле

Тип

Описание

Обязательность

type

ExtractionType

Место, откуда необходимо получить значение параметра

+

value

String

Имя заголовка, константа

+ (для всех типов кроме fromBody)

valueJson

String

Для типа fromBody. JsonPath-выражение для получения значения из тела. Только для типа fromBody. Используется при обработке сообщений формата JSON

variables

Map<String, ExtractionRule>

Для типа fromExpression — набор правил определения переменных, составляющих выражение. Можно задавать как в виде значения, так и в формате списка, но из списка будет использован только первый элемент

Настройки value и valueJson типа fromBody применяются только к сообщениям своего формата. Для сообщений другого формата настройка игнорируется. Если настройка задана для одного формата, но не задана для другого, то при обработке сообщения формата, для которого настройка не задана, будет возвращаться пустое значение. Например, настройка прописана для XML, но не прописана для JSON, тогда, при обработке сообщения формата JSON, будет получено пустое значение.

Пример:

- type: fromBody
  valueJson: $..RqUID
- type: fromBody
  value: $..Operation
- type: fromConst
  value: UFS
- type: fromExpression
  value: "variables['SCName'] + '-' + variables['ServiceName'].substring(0,variables['ServiceName'].length()-2).toLowerCase() + '-' + variables['SPName'] + '-rq'"
  variables:
    SCName:
      - type: fromConst
        value: consumer
    SPName:
      - type: fromConst
        value: provider
    ServiceName:
      - type: fromBody
        valueJson: $..ServiceName

Тип extractor.ExtractionType#

Способ получения значения из сообщения:

Значение

Описание

fromBody

Тело сообщения (JSON)

fromConst

Константа

Часто встречающиеся проблемы и пути их устранения#

Проблема

Причина

Решение

Ошибка при подключении к проекту

— администратору проекта Kubernetes не предоставлен доступ в проект;
— нет физического доступа к кластеру

— запросить доступ к проекту;
— зарегистрировать обращение в поддержку для восстановления доступа

Ошибка при загрузке артефактов

— у администратора проекта Kubernetes, от имени которого выполняется загрузка, отсутствуют необходимые права

Проверить и скорректировать настройку прав доступа пользователя

Ошибка при получении Docker-образа из репозитория

— отсутствуют права на получение образа из репозитория;
— недоступен репозиторий;
— неверная ссылка на Docker-образ в Deployment шлюза

— запросить права на получение образа из репозитория;
— зарегистрировать обращение в поддержку для восстановления доступа;
— проверить ссылку, при необходимости скорректировать Deployment