Documentation for a newer release is available. View Latest
Esta página no está disponible actualmente en Español. Si lo necesita, póngase en contacto con el servicio de asistencia de Icon (correo electrónico)

Deployment

Building as a Container

The following Dockerfile can be used as a template for integration with your own underlying base container.

FROM adoptopenjdk/openjdk11

RUN mkdir -p /tips-csm/conf /tips-csm/lib

COPY tips-csm-application-kafka-1.2.107-runnable.jar /tips-csm/lib/
COPY cinnamon-agent-2.17.3.jar /tips-csm/lib/

WORKDIR /tips-csm
EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=3s --retries=1 CMD wget -qO- http://localhost:8080/actuator/health/ | grep UP || exit 1

ENTRYPOINT java \
  -javaagent:/tips-csm/lib/cinnamon-agent-2.17.3.jar \
  -cp "/tips-csm/lib/tips-csm-application-kafka-1.2.107-runnable.jar:/tips-csm/conf" \
  ${IPF_JAVA_ARGS} \
  -Dma.glasnost.orika.writeClassFiles=false \
  -Dma.glasnost.orika.writeSourceFiles=false \
  -Dconfig.override_with_env_vars=true \
  -Dloader.main=com.iconsolutions.ipf.payments.csm.tips.application.TipsApplicationKafkaApplication  \
  org.springframework.boot.loader.PropertiesLauncher

Docker-Compose

Docker-compose.yaml
# This contains only infrastructure and payment, query + CSM adapters.
services:

  tips-csm-application-kafka:
    image: tips-csm
    container_name: tips-csm-application-kafka
    ports:
      - "8080:8080"
      - "9001:9001"
#    environment:
#      - IPF_JAVA_ARGS=-Dnoargs=set
    volumes:
      - ./tips-csm.conf:/tips-csm/conf/application.conf:ro
    depends_on:
      - kafka

  zookeeper:
    image: zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"

  kafka:
    image: registry.ipf.iconsolutions.com/kafka-icon:2.13-2.7.1
    container_name: kafka
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"
      - "29092:29092"
    environment:
      - KAFKA_BROKER_ID=0
      - KAFKA_AUTO_CREATE_TOPICS_ENABLE=true
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - KAFKA_LOG_RETENTION_MINUTES=10
      - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
      - KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS=1
      - KAFKA_LISTENERS=PLAINTEXT://:29092,PLAINTEXT_HOST://:9092
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
      - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      - KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT

  kafdrop:
    image: obsidiandynamics/kafdrop:latest
    container_name: kafdrop
    ports:
      - "9000:9000"
    environment:
      - KAFKA_BROKERCONNECT=kafka:29092
    depends_on:
      - kafka

  ipf-mongo:
    image: registry.ipf.iconsolutions.com/ipf-docker-mongodb:latest
    container_name: ipf-mongo
    ports:
      - "27017:27017"
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongo localhost:27017/test --quiet

Kubernetes and OpenShift

The TIPS CSM Service operates as an un-clustered, stateless application and so can be easily deployed using the following manifests

Deployment Manifest
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tips-csm-service
  namespace: default
  labels:
    app: tips-csm-service
    product: ipfv2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tips-csm-service
      product: ipfv2
  template:
    metadata:
      labels:
        app: tips-csm-service
        product: ipfv2
    spec:
      imagePullPolicy: Always
      containers:
        - name: tips-csm-service
          image: tips-csm-service-kafka:latest
          ports:
            - name: actuator
              containerPort: 8080
            - name: akka-metrics
              containerPort: 9001
          livenessProbe:
            httpGet:
              path: /actuator/health
              port: actuator
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 3
            successThreshold: 1
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: actuator
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 3
            successThreshold: 1
          startupProbe:
            httpGet:
              path: /actuator/health
              port: actuator
              scheme: HTTP
            periodSeconds: 10
            failureThreshold: 30
          env:
            - name: "POD_NAME"
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: "POD_IP"
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: "KUBERNETES_NAMESPACE"
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: "AKKA_CLUSTER_BOOTSTRAP_SERVICE_NAME"
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.labels['app']
            - name: "KAFKA_KEYSTORE_PASS"
              valueFrom:
                secretKeyRef:
                  name: kafka-client-keystore
                  key: kafka-client-keystore-pass
            - name: "KAFKA_TRUSTSTORE_PASS"
              valueFrom:
                secretKeyRef:
                  name: kafka-client-keystore
                  key: kafka-client-truststore-pass
            - name: "POD_NAME"
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: "POD_IP"
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: "KUBERNETES_NAMESPACE"
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          resources:
            limits:
              memory: 1Gi
            requests:
              memory: 1Gi
              cpu: 1
          volumeMounts:
            - mountPath: /tips-csm/conf
              name: config-volume
            - name: kafka-client-keystore
              mountPath: /tmp/keys/kafka-client-keystore.p12
              subPath: kafka-client-keystore.p12
            - name: kafka-client-keystore
              mountPath: /tmp/keys/kafka-client-truststore.p12
              subPath: kafka-client-truststore.p12
      volumes:
        - name: config-volume
          configMap:
            name: tips-csm-service-cm
        - name: kafka-client-keystore
          secret:
            secretName: kafka-client-keystore
Service Manifest
apiVersion: v1
kind: Service
metadata:
  name: tips-csm-service
  namespace: default
  labels:
    app: tips-csm-service
    product: ipfv2
spec:
  selector:
    app: tips-csm-service
    product: ipfv2
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
      name: actuator
    - protocol: TCP
      port: 9001
      targetPort: 9001
      name: akka-metrics
ConfigMap Manifest
apiVersion: v1
kind: ConfigMap
metadata:
  name: tips-csm-service-cm
  namespace: default
  labels:
    app: tips-csm-service
    product: ipfv2
data:
  application.conf: |
    ipf.mongodb.url = ""
    spring.data.mongodb.uri = ${ipf.mongodb.url}

    common-kafka-client-settings {
      bootstrap.servers = "${ipf.kafka.bootstrap.servers}"
      security.protocol = ${ipf.kafka.security.protocol}
      ssl {
        protocol = SSL

        keystore {
          location = /tmp/keys/kafka-client-keystore.p12
          password = ${KAFKA_KEYSTORE_PASS}
        }

        truststore {
          location = /tmp/keys/kafka-client-truststore.p12
          password = ${KAFKA_TRUSTSTORE_PASS}
        }
      }
    }

    akka {
      kafka {
        producer {
          kafka-clients = ${common-kafka-client-settings}
        }

        consumer {
          kafka-clients = ${common-kafka-client-settings}
          kafka-clients {
            auto.offset.reset = earliest
          }
        }
      }
      loglevel = "INFO"
    }

    akka {
      remote.artery {
        enabled = on
        transport = tcp
        canonical.hostname = ${POD_IP}
      }

      discovery {
        kubernetes-api {
          pod-label-selector = "app=%s"
        }
      }

      management {
        # available from Akka management >= 1.0.0
        health-checks {
          readiness-path = "health/ready"
          liveness-path = "health/alive"
        }
        http.hostname = ${POD_IP}
        cluster.bootstrap {
          contact-point-discovery {
            discovery-method = kubernetes-api
            service-name = ${AKKA_CLUSTER_BOOTSTRAP_SERVICE_NAME}
            required-contact-point-nr = 2
            required-contact-point-nr = ${?REQUIRED_CONTACT_POINT_NR}
          }
        }
      }
    }

    management.endpoints.web.exposure.include = "*"

  logback.xml: |
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>

        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <target>System.out
            </target>
            <encoder>
                <pattern>[%date{ISO8601}] [%level] [%logger] [%marker] [%thread] - %msg MDC: {%mdc}%n</pattern>
            </encoder>
        </appender>

        <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
            <queueSize>8192</queueSize>
            <neverBlock>true</neverBlock>
            <appender-ref ref="CONSOLE"/>
        </appender>

        <logger name="akka.cluster" level="INFO"/>

        <root level="INFO">
            <appender-ref ref="ASYNC"/>
        </root>

    </configuration>