diff --git a/.idea/sonarlint/issuestore/b/d/bd99e8fd918c1d01925143dbc2e08a8064258f70 b/.idea/sonarlint/issuestore/b/d/bd99e8fd918c1d01925143dbc2e08a8064258f70 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/issuestore/d/3/d3bf53ecc442740843266a635cbfe9807b992566 b/.idea/sonarlint/issuestore/d/3/d3bf53ecc442740843266a635cbfe9807b992566 deleted file mode 100644 index e69de29..0000000 diff --git a/common/common-domain/src/main/java/com/food/order/domain/valueobject/Money.java b/common/common-domain/src/main/java/com/food/order/domain/valueobject/Money.java index a6b5a5d..f33a87b 100644 --- a/common/common-domain/src/main/java/com/food/order/domain/valueobject/Money.java +++ b/common/common-domain/src/main/java/com/food/order/domain/valueobject/Money.java @@ -47,12 +47,13 @@ public class Money { @Override public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof Money money)) return false; + if (o == null || getClass() != o.getClass()) return false; + Money money = (Money) o; return amount.equals(money.amount); } @Override public int hashCode() { - return amount.hashCode(); + return Objects.hash(amount); } } diff --git a/infrastructure/docker-compose/.env b/infrastructure/docker-compose/.env new file mode 100644 index 0000000..4958bd5 --- /dev/null +++ b/infrastructure/docker-compose/.env @@ -0,0 +1,3 @@ +KAFKA_VERSION=7.0.1 +GLOBAL_NETWORK=food-order-system +GROUP_ID=com.food-order-system diff --git a/infrastructure/docker-compose/common.yml b/infrastructure/docker-compose/common.yml new file mode 100644 index 0000000..ce20c79 --- /dev/null +++ b/infrastructure/docker-compose/common.yml @@ -0,0 +1,5 @@ +version: '3.7' + +networks: + food-order-system: + driver: bridge diff --git a/infrastructure/docker-compose/init_kafka.yml b/infrastructure/docker-compose/init_kafka.yml new file mode 100644 index 0000000..4e91e52 --- /dev/null +++ b/infrastructure/docker-compose/init_kafka.yml @@ -0,0 +1,28 @@ +version: '3.7' +services: + init-kafka: + image: confluentinc/cp-kafka:${KAFKA_VERSION} + entrypoint: [ '/bin/sh', '-c' ] + command: | + " + # block until kafka is reachable + kafka-topics --bootstrap-server kafka-broker-1:9092 --list + + echo -e 'Deleting kafka topics' + kafka-topics --bootstrap-server kafka-broker-1:9092 --topic payment-request --delete --if-exists + kafka-topics --bootstrap-server kafka-broker-1:9092 --topic payment-response --delete --if-exists + kafka-topics --bootstrap-server kafka-broker-1:9092 --topic restaurant-approval-request --delete --if-exists + kafka-topics --bootstrap-server kafka-broker-1:9092 --topic restaurant-approval-response --delete --if-exists + + echo -e 'Creating kafka topics' + kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic payment-request --replication-factor 3 --partitions 3 + kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic payment-response --replication-factor 3 --partitions 3 + kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic restaurant-approval-request --replication-factor 3 --partitions 3 + kafka-topics --bootstrap-server kafka-broker-1:9092 --create --if-not-exists --topic restaurant-approval-response --replication-factor 3 --partitions 3 + + + echo -e 'Successfully created the following topics:' + kafka-topics --bootstrap-server kafka-broker-1:9092 --list + " + networks: + - ${GLOBAL_NETWORK:-kafka} \ No newline at end of file diff --git a/infrastructure/docker-compose/kafka_cluster.yml b/infrastructure/docker-compose/kafka_cluster.yml new file mode 100644 index 0000000..a8231d1 --- /dev/null +++ b/infrastructure/docker-compose/kafka_cluster.yml @@ -0,0 +1,79 @@ +version: '3.7' +services: + schema-registry: + image: confluentinc/cp-schema-registry:${KAFKA_VERSION} + hostname: schema-registry + depends_on: + - kafka-broker-1 + - kafka-broker-2 + - kafka-broker-3 + ports: + - "8081:8081" + environment: + SCHEMA_REGISTRY_HOST_NAME: schema-registry + SCHEMA_REGISTRY_KAFKASTORE_CONNECTION_URL: 'zookeeper:2181' + SCHEMA_REGISTRY_LISTENERS: http://schema-registry:8081 + SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: PLAINTEXT://kafka-broker-2:9092,LISTENER_LOCAL://localhost:29092 + SCHEMA_REGISTRY_DEBUG: 'true' + networks: + - ${GLOBAL_NETWORK:-kafka} + kafka-broker-1: + image: confluentinc/cp-kafka:${KAFKA_VERSION} + hostname: kafka-broker-1 + ports: + - "19092:19092" + environment: + KAFKA_BROKER_ID: 1 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-broker-1:9092,LISTENER_LOCAL://localhost:19092 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,LISTENER_LOCAL:PLAINTEXT + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3 + KAFKA_COMPRESSION_TYPE: producer + volumes: + - "./volumes/kafka/broker-1:/var/lib/kafka/data" + networks: + - ${GLOBAL_NETWORK:-kafka} + kafka-broker-2: + image: confluentinc/cp-kafka:${KAFKA_VERSION} + hostname: kafka-broker-2 + ports: + - "29092:29092" + environment: + KAFKA_BROKER_ID: 2 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-broker-2:9092,LISTENER_LOCAL://localhost:29092 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,LISTENER_LOCAL:PLAINTEXT + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3 + KAFKA_COMPRESSION_TYPE: producer + volumes: + - "./volumes/kafka/broker-2:/var/lib/kafka/data" + networks: + - ${GLOBAL_NETWORK:-kafka} + kafka-broker-3: + image: confluentinc/cp-kafka:${KAFKA_VERSION} + hostname: kafka-broker-3 + ports: + - "39092:39092" + environment: + KAFKA_BROKER_ID: 3 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-broker-3:9092,LISTENER_LOCAL://localhost:39092 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,LISTENER_LOCAL:PLAINTEXT + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3 + KAFKA_COMPRESSION_TYPE: producer + volumes: + - "./volumes/kafka/broker-3:/var/lib/kafka/data" + networks: + - ${GLOBAL_NETWORK:-kafka} + kafka-manager: + image: hlebalbau/kafka-manager:stable + restart: always + ports: + - "9000:9000" + environment: + ZK_HOSTS: "zookeeper:2181" + networks: + - ${GLOBAL_NETWORK:-kafka} \ No newline at end of file diff --git a/infrastructure/docker-compose/zookeeper.yml b/infrastructure/docker-compose/zookeeper.yml new file mode 100644 index 0000000..0c0357f --- /dev/null +++ b/infrastructure/docker-compose/zookeeper.yml @@ -0,0 +1,20 @@ +version: '3.7' +services: + zookeeper: + image: confluentinc/cp-zookeeper:${KAFKA_VERSION:-latest} + hostname: zookeeper + ports: + - "2181:2181" + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 + ZOOKEEPER_INIT_LIMIT: 5 + ZOOKEEPER_SYNC_LIMIT: 2 + ZOOKEEPER_SERVER_ID: 1 + ZOOKEEPER_SERVERS: zookeeper:2181:3888 + KAFKA_OPTS: "-Dzookeeper.4lw.commands.whitelist=ruok" + volumes: + - "./volumes/zookeeper/data:/var/lib/zookeeper/data" + - "./volumes/zookeeper/transactions:/var/lib/zookeeper/log" + networks: + - ${GLOBAL_NETWORK:-kafka} \ No newline at end of file diff --git a/infrastructure/kafka/kafka-config/pom.xml b/infrastructure/kafka/kafka-config/pom.xml new file mode 100644 index 0000000..b3780c4 --- /dev/null +++ b/infrastructure/kafka/kafka-config/pom.xml @@ -0,0 +1,21 @@ + + + + kafka + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + kafka-config + + + + org.springframework.boot + spring-boot-starter + + + + \ No newline at end of file diff --git a/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaConfigData.java b/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaConfigData.java new file mode 100644 index 0000000..a05fbfa --- /dev/null +++ b/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaConfigData.java @@ -0,0 +1,16 @@ +package com.food.order.kafka.config.data; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@ConfigurationProperties(prefix = "kafka-config") +public class KafkaConfigData { + private String bootstrapServers; + private String schemaRegistryUrlKey; + private String schemaRegistryUrl; + private Integer numOfPartitions; + private Short replicationFactor; +} diff --git a/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaConsumerConfigData.java b/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaConsumerConfigData.java new file mode 100644 index 0000000..867e36a --- /dev/null +++ b/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaConsumerConfigData.java @@ -0,0 +1,27 @@ +package com.food.order.kafka.config.data; + + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@ConfigurationProperties(prefix = "kafka-consumer-config") +public class KafkaConsumerConfigData { + private String keyDeserializer; + private String valueDeserializer; + private String autoOffsetReset; + private String specificAvroReaderKey; + private String specificAvroReader; + private Boolean batchListener; + private Boolean autoStartup; + private Integer concurrencyLevel; + private Integer sessionTimeoutMs; + private Integer heartbeatIntervalMs; + private Integer maxPollIntervalMs; + private Long pollTimeoutMs; + private Integer maxPollRecords; + private Integer maxPartitionFetchBytesDefault; + private Integer maxPartitionFetchBytesBoostFactor; +} diff --git a/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaProducerConfigData.java b/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaProducerConfigData.java new file mode 100644 index 0000000..47b13b4 --- /dev/null +++ b/infrastructure/kafka/kafka-config/src/main/java/com/food/order/kafka/config/data/KafkaProducerConfigData.java @@ -0,0 +1,20 @@ +package com.food.order.kafka.config.data; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@ConfigurationProperties(prefix = "kafka-producer-config") +public class KafkaProducerConfigData { + private String keySerializerClass; + private String valueSerializerClass; + private String compressionType; + private String acks; + private Integer batchSize; + private Integer batchSizeBoostFactor; + private Integer lingerMs; + private Integer requestTimeoutMs; + private Integer retryCount; +} \ No newline at end of file diff --git a/infrastructure/kafka/kafka-consumer/pom.xml b/infrastructure/kafka/kafka-consumer/pom.xml new file mode 100644 index 0000000..5a94337 --- /dev/null +++ b/infrastructure/kafka/kafka-consumer/pom.xml @@ -0,0 +1,33 @@ + + + + kafka + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + kafka-consumer + + + + com.food.order + kafka-config + + + + org.springframework.kafka + spring-kafka + + + + org.apache.avro + avro + + + + + + \ No newline at end of file diff --git a/infrastructure/kafka/kafka-consumer/src/main/java/com/food/order/system/kafka/consumer/KafkaConsumer.java b/infrastructure/kafka/kafka-consumer/src/main/java/com/food/order/system/kafka/consumer/KafkaConsumer.java new file mode 100644 index 0000000..f08d99b --- /dev/null +++ b/infrastructure/kafka/kafka-consumer/src/main/java/com/food/order/system/kafka/consumer/KafkaConsumer.java @@ -0,0 +1,9 @@ +package com.food.order.system.kafka.consumer; + +import org.apache.avro.specific.SpecificRecordBase; + +import java.util.List; + +public interface KafkaConsumer { + void receive(List messages , List keys , List partitions , List offSets); +} diff --git a/infrastructure/kafka/kafka-consumer/src/main/java/com/food/order/system/kafka/consumer/config/KafkaConsumerConfig.java b/infrastructure/kafka/kafka-consumer/src/main/java/com/food/order/system/kafka/consumer/config/KafkaConsumerConfig.java new file mode 100644 index 0000000..3951e97 --- /dev/null +++ b/infrastructure/kafka/kafka-consumer/src/main/java/com/food/order/system/kafka/consumer/config/KafkaConsumerConfig.java @@ -0,0 +1,60 @@ +package com.food.order.system.kafka.consumer.config; + +import com.food.order.kafka.config.data.KafkaConfigData; +import com.food.order.kafka.config.data.KafkaConsumerConfigData; +import lombok.RequiredArgsConstructor; +import org.apache.avro.specific.SpecificRecordBase; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.config.KafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +@Configuration +@RequiredArgsConstructor +public class KafkaConsumerConfig { + + private final KafkaConfigData kafkaConfigData; + private final KafkaConsumerConfigData kafkaConsumerConfigData; + @Bean + public Map consumerConfigs() { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaConfigData.getBootstrapServers()); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, kafkaConsumerConfigData.getKeyDeserializer()); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, kafkaConsumerConfigData.getValueDeserializer()); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, kafkaConsumerConfigData.getAutoOffsetReset()); + props.put(kafkaConfigData.getSchemaRegistryUrlKey(), kafkaConfigData.getSchemaRegistryUrl()); + props.put(kafkaConsumerConfigData.getSpecificAvroReaderKey(), kafkaConsumerConfigData.getSpecificAvroReader()); + props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, kafkaConsumerConfigData.getSessionTimeoutMs()); + props.put(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG, kafkaConsumerConfigData.getHeartbeatIntervalMs()); + props.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, kafkaConsumerConfigData.getMaxPollIntervalMs()); + props.put(ConsumerConfig.MAX_PARTITION_FETCH_BYTES_CONFIG, + kafkaConsumerConfigData.getMaxPartitionFetchBytesDefault() * + kafkaConsumerConfigData.getMaxPartitionFetchBytesBoostFactor()); + props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, kafkaConsumerConfigData.getMaxPollRecords()); + return props; + } + + @Bean + public ConsumerFactory consumerFactory() { + return new DefaultKafkaConsumerFactory<>(consumerConfigs()); + } + + @Bean + public KafkaListenerContainerFactory> kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + factory.setBatchListener(kafkaConsumerConfigData.getBatchListener()); + factory.setConcurrency(kafkaConsumerConfigData.getConcurrencyLevel()); + factory.setAutoStartup(kafkaConsumerConfigData.getAutoStartup()); + factory.getContainerProperties().setPollTimeout(kafkaConsumerConfigData.getPollTimeoutMs()); + return factory; + } +} diff --git a/infrastructure/kafka/kafka-model/pom.xml b/infrastructure/kafka/kafka-model/pom.xml new file mode 100644 index 0000000..84289ea --- /dev/null +++ b/infrastructure/kafka/kafka-model/pom.xml @@ -0,0 +1,50 @@ + + + + kafka + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + kafka-model + + + + org.apache.avro + avro + + + + + + + + org.apache.avro + avro-maven-plugin + ${avro.version} + + String + true + + + + generate-sources + + schema + + + src/main/resources/avro + src/main/java + + + + + + + + + + \ No newline at end of file diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/OrderApprovalStatus.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/OrderApprovalStatus.java new file mode 100644 index 0000000..91a7158 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/OrderApprovalStatus.java @@ -0,0 +1,13 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; +@org.apache.avro.specific.AvroGenerated +public enum OrderApprovalStatus implements org.apache.avro.generic.GenericEnumSymbol { + APPROVED, REJECTED ; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"enum\",\"name\":\"OrderApprovalStatus\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"symbols\":[\"APPROVED\",\"REJECTED\"]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } +} diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentOrderStatus.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentOrderStatus.java new file mode 100644 index 0000000..5633d52 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentOrderStatus.java @@ -0,0 +1,13 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; +@org.apache.avro.specific.AvroGenerated +public enum PaymentOrderStatus implements org.apache.avro.generic.GenericEnumSymbol { + PENDING, CANCELLED ; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"enum\",\"name\":\"PaymentOrderStatus\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"symbols\":[\"PENDING\",\"CANCELLED\"]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } +} diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentRequestAvroModel.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentRequestAvroModel.java new file mode 100644 index 0000000..7a1edb2 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentRequestAvroModel.java @@ -0,0 +1,736 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; + +import org.apache.avro.generic.GenericArray; +import org.apache.avro.specific.SpecificData; +import org.apache.avro.util.Utf8; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +@org.apache.avro.specific.AvroGenerated +public class PaymentRequestAvroModel extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = 1425163749928760031L; + + + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"PaymentRequestAvroModel\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"sagaId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"customerId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"orderId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"price\",\"type\":{\"type\":\"bytes\",\"logicalType\":\"decimal\",\"precision\":10,\"scale\":2}},{\"name\":\"createdAt\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}},{\"name\":\"paymentOrderStatus\",\"type\":{\"type\":\"enum\",\"name\":\"PaymentOrderStatus\",\"symbols\":[\"PENDING\",\"CANCELLED\"]}}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static final SpecificData MODEL$ = new SpecificData(); + static { + MODEL$.addLogicalTypeConversion(new org.apache.avro.data.TimeConversions.TimestampMillisConversion()); + MODEL$.addLogicalTypeConversion(new org.apache.avro.Conversions.DecimalConversion()); + } + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageEncoder instance used by this class. + * @return the message encoder used by this class + */ + public static BinaryMessageEncoder getEncoder() { + return ENCODER; + } + + /** + * Return the BinaryMessageDecoder instance used by this class. + * @return the message decoder used by this class + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** + * Serializes this PaymentRequestAvroModel to a ByteBuffer. + * @return a buffer holding the serialized data for this instance + * @throws java.io.IOException if this instance could not be serialized + */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** + * Deserializes a PaymentRequestAvroModel from a ByteBuffer. + * @param b a byte buffer holding serialized data for an instance of this class + * @return a PaymentRequestAvroModel instance decoded from the given buffer + * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class + */ + public static PaymentRequestAvroModel fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + private java.lang.String id; + private java.lang.String sagaId; + private java.lang.String customerId; + private java.lang.String orderId; + private java.math.BigDecimal price; + private java.time.Instant createdAt; + private com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus paymentOrderStatus; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public PaymentRequestAvroModel() {} + + /** + * All-args constructor. + * @param id The new value for id + * @param sagaId The new value for sagaId + * @param customerId The new value for customerId + * @param orderId The new value for orderId + * @param price The new value for price + * @param createdAt The new value for createdAt + * @param paymentOrderStatus The new value for paymentOrderStatus + */ + public PaymentRequestAvroModel(java.lang.String id, java.lang.String sagaId, java.lang.String customerId, java.lang.String orderId, java.math.BigDecimal price, java.time.Instant createdAt, com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus paymentOrderStatus) { + this.id = id; + this.sagaId = sagaId; + this.customerId = customerId; + this.orderId = orderId; + this.price = price; + this.createdAt = createdAt.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + this.paymentOrderStatus = paymentOrderStatus; + } + + public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return id; + case 1: return sagaId; + case 2: return customerId; + case 3: return orderId; + case 4: return price; + case 5: return createdAt; + case 6: return paymentOrderStatus; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + private static final org.apache.avro.Conversion[] conversions = + new org.apache.avro.Conversion[] { + null, + null, + null, + null, + new org.apache.avro.Conversions.DecimalConversion(), + new org.apache.avro.data.TimeConversions.TimestampMillisConversion(), + null, + null + }; + + @Override + public org.apache.avro.Conversion getConversion(int field) { + return conversions[field]; + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: id = value$ != null ? value$.toString() : null; break; + case 1: sagaId = value$ != null ? value$.toString() : null; break; + case 2: customerId = value$ != null ? value$.toString() : null; break; + case 3: orderId = value$ != null ? value$.toString() : null; break; + case 4: price = (java.math.BigDecimal)value$; break; + case 5: createdAt = (java.time.Instant)value$; break; + case 6: paymentOrderStatus = (com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus)value$; break; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + /** + * Gets the value of the 'id' field. + * @return The value of the 'id' field. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value the value to set. + */ + public void setId(java.lang.String value) { + this.id = value; + } + + /** + * Gets the value of the 'sagaId' field. + * @return The value of the 'sagaId' field. + */ + public java.lang.String getSagaId() { + return sagaId; + } + + + /** + * Sets the value of the 'sagaId' field. + * @param value the value to set. + */ + public void setSagaId(java.lang.String value) { + this.sagaId = value; + } + + /** + * Gets the value of the 'customerId' field. + * @return The value of the 'customerId' field. + */ + public java.lang.String getCustomerId() { + return customerId; + } + + + /** + * Sets the value of the 'customerId' field. + * @param value the value to set. + */ + public void setCustomerId(java.lang.String value) { + this.customerId = value; + } + + /** + * Gets the value of the 'orderId' field. + * @return The value of the 'orderId' field. + */ + public java.lang.String getOrderId() { + return orderId; + } + + + /** + * Sets the value of the 'orderId' field. + * @param value the value to set. + */ + public void setOrderId(java.lang.String value) { + this.orderId = value; + } + + /** + * Gets the value of the 'price' field. + * @return The value of the 'price' field. + */ + public java.math.BigDecimal getPrice() { + return price; + } + + + /** + * Sets the value of the 'price' field. + * @param value the value to set. + */ + public void setPrice(java.math.BigDecimal value) { + this.price = value; + } + + /** + * Gets the value of the 'createdAt' field. + * @return The value of the 'createdAt' field. + */ + public java.time.Instant getCreatedAt() { + return createdAt; + } + + + /** + * Sets the value of the 'createdAt' field. + * @param value the value to set. + */ + public void setCreatedAt(java.time.Instant value) { + this.createdAt = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + } + + /** + * Gets the value of the 'paymentOrderStatus' field. + * @return The value of the 'paymentOrderStatus' field. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus getPaymentOrderStatus() { + return paymentOrderStatus; + } + + + /** + * Sets the value of the 'paymentOrderStatus' field. + * @param value the value to set. + */ + public void setPaymentOrderStatus(com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus value) { + this.paymentOrderStatus = value; + } + + /** + * Creates a new PaymentRequestAvroModel RecordBuilder. + * @return A new PaymentRequestAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder newBuilder() { + return new com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder(); + } + + /** + * Creates a new PaymentRequestAvroModel RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new PaymentRequestAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder(other); + } + } + + /** + * Creates a new PaymentRequestAvroModel RecordBuilder by copying an existing PaymentRequestAvroModel instance. + * @param other The existing instance to copy. + * @return A new PaymentRequestAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder(other); + } + } + + /** + * RecordBuilder for PaymentRequestAvroModel instances. + */ + @org.apache.avro.specific.AvroGenerated + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private java.lang.String id; + private java.lang.String sagaId; + private java.lang.String customerId; + private java.lang.String orderId; + private java.math.BigDecimal price; + private java.time.Instant createdAt; + private com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus paymentOrderStatus; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$, MODEL$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder other) { + super(other); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = other.fieldSetFlags()[0]; + } + if (isValidValue(fields()[1], other.sagaId)) { + this.sagaId = data().deepCopy(fields()[1].schema(), other.sagaId); + fieldSetFlags()[1] = other.fieldSetFlags()[1]; + } + if (isValidValue(fields()[2], other.customerId)) { + this.customerId = data().deepCopy(fields()[2].schema(), other.customerId); + fieldSetFlags()[2] = other.fieldSetFlags()[2]; + } + if (isValidValue(fields()[3], other.orderId)) { + this.orderId = data().deepCopy(fields()[3].schema(), other.orderId); + fieldSetFlags()[3] = other.fieldSetFlags()[3]; + } + if (isValidValue(fields()[4], other.price)) { + this.price = data().deepCopy(fields()[4].schema(), other.price); + fieldSetFlags()[4] = other.fieldSetFlags()[4]; + } + if (isValidValue(fields()[5], other.createdAt)) { + this.createdAt = data().deepCopy(fields()[5].schema(), other.createdAt); + fieldSetFlags()[5] = other.fieldSetFlags()[5]; + } + if (isValidValue(fields()[6], other.paymentOrderStatus)) { + this.paymentOrderStatus = data().deepCopy(fields()[6].schema(), other.paymentOrderStatus); + fieldSetFlags()[6] = other.fieldSetFlags()[6]; + } + } + + /** + * Creates a Builder by copying an existing PaymentRequestAvroModel instance + * @param other The existing instance to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel other) { + super(SCHEMA$, MODEL$); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.sagaId)) { + this.sagaId = data().deepCopy(fields()[1].schema(), other.sagaId); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.customerId)) { + this.customerId = data().deepCopy(fields()[2].schema(), other.customerId); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.orderId)) { + this.orderId = data().deepCopy(fields()[3].schema(), other.orderId); + fieldSetFlags()[3] = true; + } + if (isValidValue(fields()[4], other.price)) { + this.price = data().deepCopy(fields()[4].schema(), other.price); + fieldSetFlags()[4] = true; + } + if (isValidValue(fields()[5], other.createdAt)) { + this.createdAt = data().deepCopy(fields()[5].schema(), other.createdAt); + fieldSetFlags()[5] = true; + } + if (isValidValue(fields()[6], other.paymentOrderStatus)) { + this.paymentOrderStatus = data().deepCopy(fields()[6].schema(), other.paymentOrderStatus); + fieldSetFlags()[6] = true; + } + } + + /** + * Gets the value of the 'id' field. + * @return The value. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value The value of 'id'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder setId(java.lang.String value) { + validate(fields()[0], value); + this.id = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'id' field has been set. + * @return True if the 'id' field has been set, false otherwise. + */ + public boolean hasId() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'id' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder clearId() { + id = null; + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'sagaId' field. + * @return The value. + */ + public java.lang.String getSagaId() { + return sagaId; + } + + + /** + * Sets the value of the 'sagaId' field. + * @param value The value of 'sagaId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder setSagaId(java.lang.String value) { + validate(fields()[1], value); + this.sagaId = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'sagaId' field has been set. + * @return True if the 'sagaId' field has been set, false otherwise. + */ + public boolean hasSagaId() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'sagaId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder clearSagaId() { + sagaId = null; + fieldSetFlags()[1] = false; + return this; + } + + /** + * Gets the value of the 'customerId' field. + * @return The value. + */ + public java.lang.String getCustomerId() { + return customerId; + } + + + /** + * Sets the value of the 'customerId' field. + * @param value The value of 'customerId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder setCustomerId(java.lang.String value) { + validate(fields()[2], value); + this.customerId = value; + fieldSetFlags()[2] = true; + return this; + } + + /** + * Checks whether the 'customerId' field has been set. + * @return True if the 'customerId' field has been set, false otherwise. + */ + public boolean hasCustomerId() { + return fieldSetFlags()[2]; + } + + + /** + * Clears the value of the 'customerId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder clearCustomerId() { + customerId = null; + fieldSetFlags()[2] = false; + return this; + } + + /** + * Gets the value of the 'orderId' field. + * @return The value. + */ + public java.lang.String getOrderId() { + return orderId; + } + + + /** + * Sets the value of the 'orderId' field. + * @param value The value of 'orderId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder setOrderId(java.lang.String value) { + validate(fields()[3], value); + this.orderId = value; + fieldSetFlags()[3] = true; + return this; + } + + /** + * Checks whether the 'orderId' field has been set. + * @return True if the 'orderId' field has been set, false otherwise. + */ + public boolean hasOrderId() { + return fieldSetFlags()[3]; + } + + + /** + * Clears the value of the 'orderId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder clearOrderId() { + orderId = null; + fieldSetFlags()[3] = false; + return this; + } + + /** + * Gets the value of the 'price' field. + * @return The value. + */ + public java.math.BigDecimal getPrice() { + return price; + } + + + /** + * Sets the value of the 'price' field. + * @param value The value of 'price'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder setPrice(java.math.BigDecimal value) { + validate(fields()[4], value); + this.price = value; + fieldSetFlags()[4] = true; + return this; + } + + /** + * Checks whether the 'price' field has been set. + * @return True if the 'price' field has been set, false otherwise. + */ + public boolean hasPrice() { + return fieldSetFlags()[4]; + } + + + /** + * Clears the value of the 'price' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder clearPrice() { + price = null; + fieldSetFlags()[4] = false; + return this; + } + + /** + * Gets the value of the 'createdAt' field. + * @return The value. + */ + public java.time.Instant getCreatedAt() { + return createdAt; + } + + + /** + * Sets the value of the 'createdAt' field. + * @param value The value of 'createdAt'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder setCreatedAt(java.time.Instant value) { + validate(fields()[5], value); + this.createdAt = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + fieldSetFlags()[5] = true; + return this; + } + + /** + * Checks whether the 'createdAt' field has been set. + * @return True if the 'createdAt' field has been set, false otherwise. + */ + public boolean hasCreatedAt() { + return fieldSetFlags()[5]; + } + + + /** + * Clears the value of the 'createdAt' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder clearCreatedAt() { + fieldSetFlags()[5] = false; + return this; + } + + /** + * Gets the value of the 'paymentOrderStatus' field. + * @return The value. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus getPaymentOrderStatus() { + return paymentOrderStatus; + } + + + /** + * Sets the value of the 'paymentOrderStatus' field. + * @param value The value of 'paymentOrderStatus'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder setPaymentOrderStatus(com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus value) { + validate(fields()[6], value); + this.paymentOrderStatus = value; + fieldSetFlags()[6] = true; + return this; + } + + /** + * Checks whether the 'paymentOrderStatus' field has been set. + * @return True if the 'paymentOrderStatus' field has been set, false otherwise. + */ + public boolean hasPaymentOrderStatus() { + return fieldSetFlags()[6]; + } + + + /** + * Clears the value of the 'paymentOrderStatus' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentRequestAvroModel.Builder clearPaymentOrderStatus() { + paymentOrderStatus = null; + fieldSetFlags()[6] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public PaymentRequestAvroModel build() { + try { + PaymentRequestAvroModel record = new PaymentRequestAvroModel(); + record.id = fieldSetFlags()[0] ? this.id : (java.lang.String) defaultValue(fields()[0]); + record.sagaId = fieldSetFlags()[1] ? this.sagaId : (java.lang.String) defaultValue(fields()[1]); + record.customerId = fieldSetFlags()[2] ? this.customerId : (java.lang.String) defaultValue(fields()[2]); + record.orderId = fieldSetFlags()[3] ? this.orderId : (java.lang.String) defaultValue(fields()[3]); + record.price = fieldSetFlags()[4] ? this.price : (java.math.BigDecimal) defaultValue(fields()[4]); + record.createdAt = fieldSetFlags()[5] ? this.createdAt : (java.time.Instant) defaultValue(fields()[5]); + record.paymentOrderStatus = fieldSetFlags()[6] ? this.paymentOrderStatus : (com.food.ordering.system.kafka.order.avro.model.PaymentOrderStatus) defaultValue(fields()[6]); + return record; + } catch (org.apache.avro.AvroMissingFieldException e) { + throw e; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + +} + + + + + + + + + + diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentResponseAvroModel.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentResponseAvroModel.java new file mode 100644 index 0000000..93d4aed --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentResponseAvroModel.java @@ -0,0 +1,882 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; + +import org.apache.avro.generic.GenericArray; +import org.apache.avro.specific.SpecificData; +import org.apache.avro.util.Utf8; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +@org.apache.avro.specific.AvroGenerated +public class PaymentResponseAvroModel extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = -2126784712017759782L; + + + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"PaymentResponseAvroModel\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"sagaId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"paymentId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"customerId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"orderId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"price\",\"type\":{\"type\":\"bytes\",\"logicalType\":\"decimal\",\"precision\":10,\"scale\":2}},{\"name\":\"createdAt\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}},{\"name\":\"paymentStatus\",\"type\":{\"type\":\"enum\",\"name\":\"PaymentStatus\",\"symbols\":[\"COMPLETED\",\"CANCELLED\",\"FAILED\"]}},{\"name\":\"failureMessages\",\"type\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static final SpecificData MODEL$ = new SpecificData(); + static { + MODEL$.addLogicalTypeConversion(new org.apache.avro.data.TimeConversions.TimestampMillisConversion()); + MODEL$.addLogicalTypeConversion(new org.apache.avro.Conversions.DecimalConversion()); + } + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageEncoder instance used by this class. + * @return the message encoder used by this class + */ + public static BinaryMessageEncoder getEncoder() { + return ENCODER; + } + + /** + * Return the BinaryMessageDecoder instance used by this class. + * @return the message decoder used by this class + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** + * Serializes this PaymentResponseAvroModel to a ByteBuffer. + * @return a buffer holding the serialized data for this instance + * @throws java.io.IOException if this instance could not be serialized + */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** + * Deserializes a PaymentResponseAvroModel from a ByteBuffer. + * @param b a byte buffer holding serialized data for an instance of this class + * @return a PaymentResponseAvroModel instance decoded from the given buffer + * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class + */ + public static PaymentResponseAvroModel fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + private java.lang.String id; + private java.lang.String sagaId; + private java.lang.String paymentId; + private java.lang.String customerId; + private java.lang.String orderId; + private java.math.BigDecimal price; + private java.time.Instant createdAt; + private com.food.ordering.system.kafka.order.avro.model.PaymentStatus paymentStatus; + private java.util.List failureMessages; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public PaymentResponseAvroModel() {} + + /** + * All-args constructor. + * @param id The new value for id + * @param sagaId The new value for sagaId + * @param paymentId The new value for paymentId + * @param customerId The new value for customerId + * @param orderId The new value for orderId + * @param price The new value for price + * @param createdAt The new value for createdAt + * @param paymentStatus The new value for paymentStatus + * @param failureMessages The new value for failureMessages + */ + public PaymentResponseAvroModel(java.lang.String id, java.lang.String sagaId, java.lang.String paymentId, java.lang.String customerId, java.lang.String orderId, java.math.BigDecimal price, java.time.Instant createdAt, com.food.ordering.system.kafka.order.avro.model.PaymentStatus paymentStatus, java.util.List failureMessages) { + this.id = id; + this.sagaId = sagaId; + this.paymentId = paymentId; + this.customerId = customerId; + this.orderId = orderId; + this.price = price; + this.createdAt = createdAt.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + this.paymentStatus = paymentStatus; + this.failureMessages = failureMessages; + } + + public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return id; + case 1: return sagaId; + case 2: return paymentId; + case 3: return customerId; + case 4: return orderId; + case 5: return price; + case 6: return createdAt; + case 7: return paymentStatus; + case 8: return failureMessages; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + private static final org.apache.avro.Conversion[] conversions = + new org.apache.avro.Conversion[] { + null, + null, + null, + null, + null, + new org.apache.avro.Conversions.DecimalConversion(), + new org.apache.avro.data.TimeConversions.TimestampMillisConversion(), + null, + null, + null + }; + + @Override + public org.apache.avro.Conversion getConversion(int field) { + return conversions[field]; + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: id = value$ != null ? value$.toString() : null; break; + case 1: sagaId = value$ != null ? value$.toString() : null; break; + case 2: paymentId = value$ != null ? value$.toString() : null; break; + case 3: customerId = value$ != null ? value$.toString() : null; break; + case 4: orderId = value$ != null ? value$.toString() : null; break; + case 5: price = (java.math.BigDecimal)value$; break; + case 6: createdAt = (java.time.Instant)value$; break; + case 7: paymentStatus = (com.food.ordering.system.kafka.order.avro.model.PaymentStatus)value$; break; + case 8: failureMessages = (java.util.List)value$; break; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + /** + * Gets the value of the 'id' field. + * @return The value of the 'id' field. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value the value to set. + */ + public void setId(java.lang.String value) { + this.id = value; + } + + /** + * Gets the value of the 'sagaId' field. + * @return The value of the 'sagaId' field. + */ + public java.lang.String getSagaId() { + return sagaId; + } + + + /** + * Sets the value of the 'sagaId' field. + * @param value the value to set. + */ + public void setSagaId(java.lang.String value) { + this.sagaId = value; + } + + /** + * Gets the value of the 'paymentId' field. + * @return The value of the 'paymentId' field. + */ + public java.lang.String getPaymentId() { + return paymentId; + } + + + /** + * Sets the value of the 'paymentId' field. + * @param value the value to set. + */ + public void setPaymentId(java.lang.String value) { + this.paymentId = value; + } + + /** + * Gets the value of the 'customerId' field. + * @return The value of the 'customerId' field. + */ + public java.lang.String getCustomerId() { + return customerId; + } + + + /** + * Sets the value of the 'customerId' field. + * @param value the value to set. + */ + public void setCustomerId(java.lang.String value) { + this.customerId = value; + } + + /** + * Gets the value of the 'orderId' field. + * @return The value of the 'orderId' field. + */ + public java.lang.String getOrderId() { + return orderId; + } + + + /** + * Sets the value of the 'orderId' field. + * @param value the value to set. + */ + public void setOrderId(java.lang.String value) { + this.orderId = value; + } + + /** + * Gets the value of the 'price' field. + * @return The value of the 'price' field. + */ + public java.math.BigDecimal getPrice() { + return price; + } + + + /** + * Sets the value of the 'price' field. + * @param value the value to set. + */ + public void setPrice(java.math.BigDecimal value) { + this.price = value; + } + + /** + * Gets the value of the 'createdAt' field. + * @return The value of the 'createdAt' field. + */ + public java.time.Instant getCreatedAt() { + return createdAt; + } + + + /** + * Sets the value of the 'createdAt' field. + * @param value the value to set. + */ + public void setCreatedAt(java.time.Instant value) { + this.createdAt = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + } + + /** + * Gets the value of the 'paymentStatus' field. + * @return The value of the 'paymentStatus' field. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentStatus getPaymentStatus() { + return paymentStatus; + } + + + /** + * Sets the value of the 'paymentStatus' field. + * @param value the value to set. + */ + public void setPaymentStatus(com.food.ordering.system.kafka.order.avro.model.PaymentStatus value) { + this.paymentStatus = value; + } + + /** + * Gets the value of the 'failureMessages' field. + * @return The value of the 'failureMessages' field. + */ + public java.util.List getFailureMessages() { + return failureMessages; + } + + + /** + * Sets the value of the 'failureMessages' field. + * @param value the value to set. + */ + public void setFailureMessages(java.util.List value) { + this.failureMessages = value; + } + + /** + * Creates a new PaymentResponseAvroModel RecordBuilder. + * @return A new PaymentResponseAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder newBuilder() { + return new com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder(); + } + + /** + * Creates a new PaymentResponseAvroModel RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new PaymentResponseAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder(other); + } + } + + /** + * Creates a new PaymentResponseAvroModel RecordBuilder by copying an existing PaymentResponseAvroModel instance. + * @param other The existing instance to copy. + * @return A new PaymentResponseAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder(other); + } + } + + /** + * RecordBuilder for PaymentResponseAvroModel instances. + */ + @org.apache.avro.specific.AvroGenerated + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private java.lang.String id; + private java.lang.String sagaId; + private java.lang.String paymentId; + private java.lang.String customerId; + private java.lang.String orderId; + private java.math.BigDecimal price; + private java.time.Instant createdAt; + private com.food.ordering.system.kafka.order.avro.model.PaymentStatus paymentStatus; + private java.util.List failureMessages; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$, MODEL$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder other) { + super(other); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = other.fieldSetFlags()[0]; + } + if (isValidValue(fields()[1], other.sagaId)) { + this.sagaId = data().deepCopy(fields()[1].schema(), other.sagaId); + fieldSetFlags()[1] = other.fieldSetFlags()[1]; + } + if (isValidValue(fields()[2], other.paymentId)) { + this.paymentId = data().deepCopy(fields()[2].schema(), other.paymentId); + fieldSetFlags()[2] = other.fieldSetFlags()[2]; + } + if (isValidValue(fields()[3], other.customerId)) { + this.customerId = data().deepCopy(fields()[3].schema(), other.customerId); + fieldSetFlags()[3] = other.fieldSetFlags()[3]; + } + if (isValidValue(fields()[4], other.orderId)) { + this.orderId = data().deepCopy(fields()[4].schema(), other.orderId); + fieldSetFlags()[4] = other.fieldSetFlags()[4]; + } + if (isValidValue(fields()[5], other.price)) { + this.price = data().deepCopy(fields()[5].schema(), other.price); + fieldSetFlags()[5] = other.fieldSetFlags()[5]; + } + if (isValidValue(fields()[6], other.createdAt)) { + this.createdAt = data().deepCopy(fields()[6].schema(), other.createdAt); + fieldSetFlags()[6] = other.fieldSetFlags()[6]; + } + if (isValidValue(fields()[7], other.paymentStatus)) { + this.paymentStatus = data().deepCopy(fields()[7].schema(), other.paymentStatus); + fieldSetFlags()[7] = other.fieldSetFlags()[7]; + } + if (isValidValue(fields()[8], other.failureMessages)) { + this.failureMessages = data().deepCopy(fields()[8].schema(), other.failureMessages); + fieldSetFlags()[8] = other.fieldSetFlags()[8]; + } + } + + /** + * Creates a Builder by copying an existing PaymentResponseAvroModel instance + * @param other The existing instance to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel other) { + super(SCHEMA$, MODEL$); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.sagaId)) { + this.sagaId = data().deepCopy(fields()[1].schema(), other.sagaId); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.paymentId)) { + this.paymentId = data().deepCopy(fields()[2].schema(), other.paymentId); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.customerId)) { + this.customerId = data().deepCopy(fields()[3].schema(), other.customerId); + fieldSetFlags()[3] = true; + } + if (isValidValue(fields()[4], other.orderId)) { + this.orderId = data().deepCopy(fields()[4].schema(), other.orderId); + fieldSetFlags()[4] = true; + } + if (isValidValue(fields()[5], other.price)) { + this.price = data().deepCopy(fields()[5].schema(), other.price); + fieldSetFlags()[5] = true; + } + if (isValidValue(fields()[6], other.createdAt)) { + this.createdAt = data().deepCopy(fields()[6].schema(), other.createdAt); + fieldSetFlags()[6] = true; + } + if (isValidValue(fields()[7], other.paymentStatus)) { + this.paymentStatus = data().deepCopy(fields()[7].schema(), other.paymentStatus); + fieldSetFlags()[7] = true; + } + if (isValidValue(fields()[8], other.failureMessages)) { + this.failureMessages = data().deepCopy(fields()[8].schema(), other.failureMessages); + fieldSetFlags()[8] = true; + } + } + + /** + * Gets the value of the 'id' field. + * @return The value. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value The value of 'id'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setId(java.lang.String value) { + validate(fields()[0], value); + this.id = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'id' field has been set. + * @return True if the 'id' field has been set, false otherwise. + */ + public boolean hasId() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'id' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearId() { + id = null; + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'sagaId' field. + * @return The value. + */ + public java.lang.String getSagaId() { + return sagaId; + } + + + /** + * Sets the value of the 'sagaId' field. + * @param value The value of 'sagaId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setSagaId(java.lang.String value) { + validate(fields()[1], value); + this.sagaId = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'sagaId' field has been set. + * @return True if the 'sagaId' field has been set, false otherwise. + */ + public boolean hasSagaId() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'sagaId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearSagaId() { + sagaId = null; + fieldSetFlags()[1] = false; + return this; + } + + /** + * Gets the value of the 'paymentId' field. + * @return The value. + */ + public java.lang.String getPaymentId() { + return paymentId; + } + + + /** + * Sets the value of the 'paymentId' field. + * @param value The value of 'paymentId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setPaymentId(java.lang.String value) { + validate(fields()[2], value); + this.paymentId = value; + fieldSetFlags()[2] = true; + return this; + } + + /** + * Checks whether the 'paymentId' field has been set. + * @return True if the 'paymentId' field has been set, false otherwise. + */ + public boolean hasPaymentId() { + return fieldSetFlags()[2]; + } + + + /** + * Clears the value of the 'paymentId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearPaymentId() { + paymentId = null; + fieldSetFlags()[2] = false; + return this; + } + + /** + * Gets the value of the 'customerId' field. + * @return The value. + */ + public java.lang.String getCustomerId() { + return customerId; + } + + + /** + * Sets the value of the 'customerId' field. + * @param value The value of 'customerId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setCustomerId(java.lang.String value) { + validate(fields()[3], value); + this.customerId = value; + fieldSetFlags()[3] = true; + return this; + } + + /** + * Checks whether the 'customerId' field has been set. + * @return True if the 'customerId' field has been set, false otherwise. + */ + public boolean hasCustomerId() { + return fieldSetFlags()[3]; + } + + + /** + * Clears the value of the 'customerId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearCustomerId() { + customerId = null; + fieldSetFlags()[3] = false; + return this; + } + + /** + * Gets the value of the 'orderId' field. + * @return The value. + */ + public java.lang.String getOrderId() { + return orderId; + } + + + /** + * Sets the value of the 'orderId' field. + * @param value The value of 'orderId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setOrderId(java.lang.String value) { + validate(fields()[4], value); + this.orderId = value; + fieldSetFlags()[4] = true; + return this; + } + + /** + * Checks whether the 'orderId' field has been set. + * @return True if the 'orderId' field has been set, false otherwise. + */ + public boolean hasOrderId() { + return fieldSetFlags()[4]; + } + + + /** + * Clears the value of the 'orderId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearOrderId() { + orderId = null; + fieldSetFlags()[4] = false; + return this; + } + + /** + * Gets the value of the 'price' field. + * @return The value. + */ + public java.math.BigDecimal getPrice() { + return price; + } + + + /** + * Sets the value of the 'price' field. + * @param value The value of 'price'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setPrice(java.math.BigDecimal value) { + validate(fields()[5], value); + this.price = value; + fieldSetFlags()[5] = true; + return this; + } + + /** + * Checks whether the 'price' field has been set. + * @return True if the 'price' field has been set, false otherwise. + */ + public boolean hasPrice() { + return fieldSetFlags()[5]; + } + + + /** + * Clears the value of the 'price' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearPrice() { + price = null; + fieldSetFlags()[5] = false; + return this; + } + + /** + * Gets the value of the 'createdAt' field. + * @return The value. + */ + public java.time.Instant getCreatedAt() { + return createdAt; + } + + + /** + * Sets the value of the 'createdAt' field. + * @param value The value of 'createdAt'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setCreatedAt(java.time.Instant value) { + validate(fields()[6], value); + this.createdAt = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + fieldSetFlags()[6] = true; + return this; + } + + /** + * Checks whether the 'createdAt' field has been set. + * @return True if the 'createdAt' field has been set, false otherwise. + */ + public boolean hasCreatedAt() { + return fieldSetFlags()[6]; + } + + + /** + * Clears the value of the 'createdAt' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearCreatedAt() { + fieldSetFlags()[6] = false; + return this; + } + + /** + * Gets the value of the 'paymentStatus' field. + * @return The value. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentStatus getPaymentStatus() { + return paymentStatus; + } + + + /** + * Sets the value of the 'paymentStatus' field. + * @param value The value of 'paymentStatus'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setPaymentStatus(com.food.ordering.system.kafka.order.avro.model.PaymentStatus value) { + validate(fields()[7], value); + this.paymentStatus = value; + fieldSetFlags()[7] = true; + return this; + } + + /** + * Checks whether the 'paymentStatus' field has been set. + * @return True if the 'paymentStatus' field has been set, false otherwise. + */ + public boolean hasPaymentStatus() { + return fieldSetFlags()[7]; + } + + + /** + * Clears the value of the 'paymentStatus' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearPaymentStatus() { + paymentStatus = null; + fieldSetFlags()[7] = false; + return this; + } + + /** + * Gets the value of the 'failureMessages' field. + * @return The value. + */ + public java.util.List getFailureMessages() { + return failureMessages; + } + + + /** + * Sets the value of the 'failureMessages' field. + * @param value The value of 'failureMessages'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder setFailureMessages(java.util.List value) { + validate(fields()[8], value); + this.failureMessages = value; + fieldSetFlags()[8] = true; + return this; + } + + /** + * Checks whether the 'failureMessages' field has been set. + * @return True if the 'failureMessages' field has been set, false otherwise. + */ + public boolean hasFailureMessages() { + return fieldSetFlags()[8]; + } + + + /** + * Clears the value of the 'failureMessages' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.PaymentResponseAvroModel.Builder clearFailureMessages() { + failureMessages = null; + fieldSetFlags()[8] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public PaymentResponseAvroModel build() { + try { + PaymentResponseAvroModel record = new PaymentResponseAvroModel(); + record.id = fieldSetFlags()[0] ? this.id : (java.lang.String) defaultValue(fields()[0]); + record.sagaId = fieldSetFlags()[1] ? this.sagaId : (java.lang.String) defaultValue(fields()[1]); + record.paymentId = fieldSetFlags()[2] ? this.paymentId : (java.lang.String) defaultValue(fields()[2]); + record.customerId = fieldSetFlags()[3] ? this.customerId : (java.lang.String) defaultValue(fields()[3]); + record.orderId = fieldSetFlags()[4] ? this.orderId : (java.lang.String) defaultValue(fields()[4]); + record.price = fieldSetFlags()[5] ? this.price : (java.math.BigDecimal) defaultValue(fields()[5]); + record.createdAt = fieldSetFlags()[6] ? this.createdAt : (java.time.Instant) defaultValue(fields()[6]); + record.paymentStatus = fieldSetFlags()[7] ? this.paymentStatus : (com.food.ordering.system.kafka.order.avro.model.PaymentStatus) defaultValue(fields()[7]); + record.failureMessages = fieldSetFlags()[8] ? this.failureMessages : (java.util.List) defaultValue(fields()[8]); + return record; + } catch (org.apache.avro.AvroMissingFieldException e) { + throw e; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + +} + + + + + + + + + + diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentStatus.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentStatus.java new file mode 100644 index 0000000..3416629 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/PaymentStatus.java @@ -0,0 +1,13 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; +@org.apache.avro.specific.AvroGenerated +public enum PaymentStatus implements org.apache.avro.generic.GenericEnumSymbol { + COMPLETED, CANCELLED, FAILED ; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"enum\",\"name\":\"PaymentStatus\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"symbols\":[\"COMPLETED\",\"CANCELLED\",\"FAILED\"]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } +} diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/Product.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/Product.java new file mode 100644 index 0000000..77ba3d9 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/Product.java @@ -0,0 +1,390 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; + +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.SchemaStore; +import org.apache.avro.specific.SpecificData; + +@org.apache.avro.specific.AvroGenerated +public class Product extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = -6511580554663840009L; + + + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"Product\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"},\"logicalType\":\"uuid\"},{\"name\":\"quantity\",\"type\":\"int\"}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static final SpecificData MODEL$ = new SpecificData(); + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageEncoder instance used by this class. + * @return the message encoder used by this class + */ + public static BinaryMessageEncoder getEncoder() { + return ENCODER; + } + + /** + * Return the BinaryMessageDecoder instance used by this class. + * @return the message decoder used by this class + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** + * Serializes this Product to a ByteBuffer. + * @return a buffer holding the serialized data for this instance + * @throws java.io.IOException if this instance could not be serialized + */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** + * Deserializes a Product from a ByteBuffer. + * @param b a byte buffer holding serialized data for an instance of this class + * @return a Product instance decoded from the given buffer + * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class + */ + public static Product fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + private java.lang.String id; + private int quantity; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public Product() {} + + /** + * All-args constructor. + * @param id The new value for id + * @param quantity The new value for quantity + */ + public Product(java.lang.String id, java.lang.Integer quantity) { + this.id = id; + this.quantity = quantity; + } + + public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return id; + case 1: return quantity; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: id = value$ != null ? value$.toString() : null; break; + case 1: quantity = (java.lang.Integer)value$; break; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + /** + * Gets the value of the 'id' field. + * @return The value of the 'id' field. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value the value to set. + */ + public void setId(java.lang.String value) { + this.id = value; + } + + /** + * Gets the value of the 'quantity' field. + * @return The value of the 'quantity' field. + */ + public int getQuantity() { + return quantity; + } + + + /** + * Sets the value of the 'quantity' field. + * @param value the value to set. + */ + public void setQuantity(int value) { + this.quantity = value; + } + + /** + * Creates a new Product RecordBuilder. + * @return A new Product RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.Product.Builder newBuilder() { + return new com.food.ordering.system.kafka.order.avro.model.Product.Builder(); + } + + /** + * Creates a new Product RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new Product RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.Product.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.Product.Builder other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.Product.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.Product.Builder(other); + } + } + + /** + * Creates a new Product RecordBuilder by copying an existing Product instance. + * @param other The existing instance to copy. + * @return A new Product RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.Product.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.Product other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.Product.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.Product.Builder(other); + } + } + + /** + * RecordBuilder for Product instances. + */ + @org.apache.avro.specific.AvroGenerated + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private java.lang.String id; + private int quantity; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$, MODEL$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.Product.Builder other) { + super(other); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = other.fieldSetFlags()[0]; + } + if (isValidValue(fields()[1], other.quantity)) { + this.quantity = data().deepCopy(fields()[1].schema(), other.quantity); + fieldSetFlags()[1] = other.fieldSetFlags()[1]; + } + } + + /** + * Creates a Builder by copying an existing Product instance + * @param other The existing instance to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.Product other) { + super(SCHEMA$, MODEL$); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.quantity)) { + this.quantity = data().deepCopy(fields()[1].schema(), other.quantity); + fieldSetFlags()[1] = true; + } + } + + /** + * Gets the value of the 'id' field. + * @return The value. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value The value of 'id'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.Product.Builder setId(java.lang.String value) { + validate(fields()[0], value); + this.id = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'id' field has been set. + * @return True if the 'id' field has been set, false otherwise. + */ + public boolean hasId() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'id' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.Product.Builder clearId() { + id = null; + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'quantity' field. + * @return The value. + */ + public int getQuantity() { + return quantity; + } + + + /** + * Sets the value of the 'quantity' field. + * @param value The value of 'quantity'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.Product.Builder setQuantity(int value) { + validate(fields()[1], value); + this.quantity = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'quantity' field has been set. + * @return True if the 'quantity' field has been set, false otherwise. + */ + public boolean hasQuantity() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'quantity' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.Product.Builder clearQuantity() { + fieldSetFlags()[1] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public Product build() { + try { + Product record = new Product(); + record.id = fieldSetFlags()[0] ? this.id : (java.lang.String) defaultValue(fields()[0]); + record.quantity = fieldSetFlags()[1] ? this.quantity : (java.lang.Integer) defaultValue(fields()[1]); + return record; + } catch (org.apache.avro.AvroMissingFieldException e) { + throw e; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + + @Override protected boolean hasCustomCoders() { return true; } + + @Override public void customEncode(org.apache.avro.io.Encoder out) + throws java.io.IOException + { + out.writeString(this.id); + + out.writeInt(this.quantity); + + } + + @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in) + throws java.io.IOException + { + org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff(); + if (fieldOrder == null) { + this.id = in.readString(); + + this.quantity = in.readInt(); + + } else { + for (int i = 0; i < 2; i++) { + switch (fieldOrder[i].pos()) { + case 0: + this.id = in.readString(); + break; + + case 1: + this.quantity = in.readInt(); + break; + + default: + throw new java.io.IOException("Corrupt ResolvingDecoder."); + } + } + } + } +} + + + + + + + + + + diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantApprovalRequestAvroModel.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantApprovalRequestAvroModel.java new file mode 100644 index 0000000..227a9a2 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantApprovalRequestAvroModel.java @@ -0,0 +1,809 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; + +import org.apache.avro.generic.GenericArray; +import org.apache.avro.specific.SpecificData; +import org.apache.avro.util.Utf8; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +@org.apache.avro.specific.AvroGenerated +public class RestaurantApprovalRequestAvroModel extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = -3917361261016430486L; + + + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"RestaurantApprovalRequestAvroModel\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"sagaId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"restaurantId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"orderId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"restaurantOrderStatus\",\"type\":{\"type\":\"enum\",\"name\":\"RestaurantOrderStatus\",\"symbols\":[\"PAID\"]}},{\"name\":\"products\",\"type\":{\"type\":\"array\",\"items\":{\"type\":\"record\",\"name\":\"Product\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"},\"logicalType\":\"uuid\"},{\"name\":\"quantity\",\"type\":\"int\"}]}}},{\"name\":\"price\",\"type\":{\"type\":\"bytes\",\"logicalType\":\"decimal\",\"precision\":10,\"scale\":2}},{\"name\":\"createdAt\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static final SpecificData MODEL$ = new SpecificData(); + static { + MODEL$.addLogicalTypeConversion(new org.apache.avro.data.TimeConversions.TimestampMillisConversion()); + MODEL$.addLogicalTypeConversion(new org.apache.avro.Conversions.DecimalConversion()); + } + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageEncoder instance used by this class. + * @return the message encoder used by this class + */ + public static BinaryMessageEncoder getEncoder() { + return ENCODER; + } + + /** + * Return the BinaryMessageDecoder instance used by this class. + * @return the message decoder used by this class + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** + * Serializes this RestaurantApprovalRequestAvroModel to a ByteBuffer. + * @return a buffer holding the serialized data for this instance + * @throws java.io.IOException if this instance could not be serialized + */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** + * Deserializes a RestaurantApprovalRequestAvroModel from a ByteBuffer. + * @param b a byte buffer holding serialized data for an instance of this class + * @return a RestaurantApprovalRequestAvroModel instance decoded from the given buffer + * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class + */ + public static RestaurantApprovalRequestAvroModel fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + private java.lang.String id; + private java.lang.String sagaId; + private java.lang.String restaurantId; + private java.lang.String orderId; + private com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus restaurantOrderStatus; + private java.util.List products; + private java.math.BigDecimal price; + private java.time.Instant createdAt; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public RestaurantApprovalRequestAvroModel() {} + + /** + * All-args constructor. + * @param id The new value for id + * @param sagaId The new value for sagaId + * @param restaurantId The new value for restaurantId + * @param orderId The new value for orderId + * @param restaurantOrderStatus The new value for restaurantOrderStatus + * @param products The new value for products + * @param price The new value for price + * @param createdAt The new value for createdAt + */ + public RestaurantApprovalRequestAvroModel(java.lang.String id, java.lang.String sagaId, java.lang.String restaurantId, java.lang.String orderId, com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus restaurantOrderStatus, java.util.List products, java.math.BigDecimal price, java.time.Instant createdAt) { + this.id = id; + this.sagaId = sagaId; + this.restaurantId = restaurantId; + this.orderId = orderId; + this.restaurantOrderStatus = restaurantOrderStatus; + this.products = products; + this.price = price; + this.createdAt = createdAt.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + } + + public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return id; + case 1: return sagaId; + case 2: return restaurantId; + case 3: return orderId; + case 4: return restaurantOrderStatus; + case 5: return products; + case 6: return price; + case 7: return createdAt; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + private static final org.apache.avro.Conversion[] conversions = + new org.apache.avro.Conversion[] { + null, + null, + null, + null, + null, + null, + new org.apache.avro.Conversions.DecimalConversion(), + new org.apache.avro.data.TimeConversions.TimestampMillisConversion(), + null + }; + + @Override + public org.apache.avro.Conversion getConversion(int field) { + return conversions[field]; + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: id = value$ != null ? value$.toString() : null; break; + case 1: sagaId = value$ != null ? value$.toString() : null; break; + case 2: restaurantId = value$ != null ? value$.toString() : null; break; + case 3: orderId = value$ != null ? value$.toString() : null; break; + case 4: restaurantOrderStatus = (com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus)value$; break; + case 5: products = (java.util.List)value$; break; + case 6: price = (java.math.BigDecimal)value$; break; + case 7: createdAt = (java.time.Instant)value$; break; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + /** + * Gets the value of the 'id' field. + * @return The value of the 'id' field. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value the value to set. + */ + public void setId(java.lang.String value) { + this.id = value; + } + + /** + * Gets the value of the 'sagaId' field. + * @return The value of the 'sagaId' field. + */ + public java.lang.String getSagaId() { + return sagaId; + } + + + /** + * Sets the value of the 'sagaId' field. + * @param value the value to set. + */ + public void setSagaId(java.lang.String value) { + this.sagaId = value; + } + + /** + * Gets the value of the 'restaurantId' field. + * @return The value of the 'restaurantId' field. + */ + public java.lang.String getRestaurantId() { + return restaurantId; + } + + + /** + * Sets the value of the 'restaurantId' field. + * @param value the value to set. + */ + public void setRestaurantId(java.lang.String value) { + this.restaurantId = value; + } + + /** + * Gets the value of the 'orderId' field. + * @return The value of the 'orderId' field. + */ + public java.lang.String getOrderId() { + return orderId; + } + + + /** + * Sets the value of the 'orderId' field. + * @param value the value to set. + */ + public void setOrderId(java.lang.String value) { + this.orderId = value; + } + + /** + * Gets the value of the 'restaurantOrderStatus' field. + * @return The value of the 'restaurantOrderStatus' field. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus getRestaurantOrderStatus() { + return restaurantOrderStatus; + } + + + /** + * Sets the value of the 'restaurantOrderStatus' field. + * @param value the value to set. + */ + public void setRestaurantOrderStatus(com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus value) { + this.restaurantOrderStatus = value; + } + + /** + * Gets the value of the 'products' field. + * @return The value of the 'products' field. + */ + public java.util.List getProducts() { + return products; + } + + + /** + * Sets the value of the 'products' field. + * @param value the value to set. + */ + public void setProducts(java.util.List value) { + this.products = value; + } + + /** + * Gets the value of the 'price' field. + * @return The value of the 'price' field. + */ + public java.math.BigDecimal getPrice() { + return price; + } + + + /** + * Sets the value of the 'price' field. + * @param value the value to set. + */ + public void setPrice(java.math.BigDecimal value) { + this.price = value; + } + + /** + * Gets the value of the 'createdAt' field. + * @return The value of the 'createdAt' field. + */ + public java.time.Instant getCreatedAt() { + return createdAt; + } + + + /** + * Sets the value of the 'createdAt' field. + * @param value the value to set. + */ + public void setCreatedAt(java.time.Instant value) { + this.createdAt = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + } + + /** + * Creates a new RestaurantApprovalRequestAvroModel RecordBuilder. + * @return A new RestaurantApprovalRequestAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder newBuilder() { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder(); + } + + /** + * Creates a new RestaurantApprovalRequestAvroModel RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new RestaurantApprovalRequestAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder(other); + } + } + + /** + * Creates a new RestaurantApprovalRequestAvroModel RecordBuilder by copying an existing RestaurantApprovalRequestAvroModel instance. + * @param other The existing instance to copy. + * @return A new RestaurantApprovalRequestAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder(other); + } + } + + /** + * RecordBuilder for RestaurantApprovalRequestAvroModel instances. + */ + @org.apache.avro.specific.AvroGenerated + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private java.lang.String id; + private java.lang.String sagaId; + private java.lang.String restaurantId; + private java.lang.String orderId; + private com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus restaurantOrderStatus; + private java.util.List products; + private java.math.BigDecimal price; + private java.time.Instant createdAt; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$, MODEL$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder other) { + super(other); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = other.fieldSetFlags()[0]; + } + if (isValidValue(fields()[1], other.sagaId)) { + this.sagaId = data().deepCopy(fields()[1].schema(), other.sagaId); + fieldSetFlags()[1] = other.fieldSetFlags()[1]; + } + if (isValidValue(fields()[2], other.restaurantId)) { + this.restaurantId = data().deepCopy(fields()[2].schema(), other.restaurantId); + fieldSetFlags()[2] = other.fieldSetFlags()[2]; + } + if (isValidValue(fields()[3], other.orderId)) { + this.orderId = data().deepCopy(fields()[3].schema(), other.orderId); + fieldSetFlags()[3] = other.fieldSetFlags()[3]; + } + if (isValidValue(fields()[4], other.restaurantOrderStatus)) { + this.restaurantOrderStatus = data().deepCopy(fields()[4].schema(), other.restaurantOrderStatus); + fieldSetFlags()[4] = other.fieldSetFlags()[4]; + } + if (isValidValue(fields()[5], other.products)) { + this.products = data().deepCopy(fields()[5].schema(), other.products); + fieldSetFlags()[5] = other.fieldSetFlags()[5]; + } + if (isValidValue(fields()[6], other.price)) { + this.price = data().deepCopy(fields()[6].schema(), other.price); + fieldSetFlags()[6] = other.fieldSetFlags()[6]; + } + if (isValidValue(fields()[7], other.createdAt)) { + this.createdAt = data().deepCopy(fields()[7].schema(), other.createdAt); + fieldSetFlags()[7] = other.fieldSetFlags()[7]; + } + } + + /** + * Creates a Builder by copying an existing RestaurantApprovalRequestAvroModel instance + * @param other The existing instance to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel other) { + super(SCHEMA$, MODEL$); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.sagaId)) { + this.sagaId = data().deepCopy(fields()[1].schema(), other.sagaId); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.restaurantId)) { + this.restaurantId = data().deepCopy(fields()[2].schema(), other.restaurantId); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.orderId)) { + this.orderId = data().deepCopy(fields()[3].schema(), other.orderId); + fieldSetFlags()[3] = true; + } + if (isValidValue(fields()[4], other.restaurantOrderStatus)) { + this.restaurantOrderStatus = data().deepCopy(fields()[4].schema(), other.restaurantOrderStatus); + fieldSetFlags()[4] = true; + } + if (isValidValue(fields()[5], other.products)) { + this.products = data().deepCopy(fields()[5].schema(), other.products); + fieldSetFlags()[5] = true; + } + if (isValidValue(fields()[6], other.price)) { + this.price = data().deepCopy(fields()[6].schema(), other.price); + fieldSetFlags()[6] = true; + } + if (isValidValue(fields()[7], other.createdAt)) { + this.createdAt = data().deepCopy(fields()[7].schema(), other.createdAt); + fieldSetFlags()[7] = true; + } + } + + /** + * Gets the value of the 'id' field. + * @return The value. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value The value of 'id'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder setId(java.lang.String value) { + validate(fields()[0], value); + this.id = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'id' field has been set. + * @return True if the 'id' field has been set, false otherwise. + */ + public boolean hasId() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'id' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder clearId() { + id = null; + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'sagaId' field. + * @return The value. + */ + public java.lang.String getSagaId() { + return sagaId; + } + + + /** + * Sets the value of the 'sagaId' field. + * @param value The value of 'sagaId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder setSagaId(java.lang.String value) { + validate(fields()[1], value); + this.sagaId = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'sagaId' field has been set. + * @return True if the 'sagaId' field has been set, false otherwise. + */ + public boolean hasSagaId() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'sagaId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder clearSagaId() { + sagaId = null; + fieldSetFlags()[1] = false; + return this; + } + + /** + * Gets the value of the 'restaurantId' field. + * @return The value. + */ + public java.lang.String getRestaurantId() { + return restaurantId; + } + + + /** + * Sets the value of the 'restaurantId' field. + * @param value The value of 'restaurantId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder setRestaurantId(java.lang.String value) { + validate(fields()[2], value); + this.restaurantId = value; + fieldSetFlags()[2] = true; + return this; + } + + /** + * Checks whether the 'restaurantId' field has been set. + * @return True if the 'restaurantId' field has been set, false otherwise. + */ + public boolean hasRestaurantId() { + return fieldSetFlags()[2]; + } + + + /** + * Clears the value of the 'restaurantId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder clearRestaurantId() { + restaurantId = null; + fieldSetFlags()[2] = false; + return this; + } + + /** + * Gets the value of the 'orderId' field. + * @return The value. + */ + public java.lang.String getOrderId() { + return orderId; + } + + + /** + * Sets the value of the 'orderId' field. + * @param value The value of 'orderId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder setOrderId(java.lang.String value) { + validate(fields()[3], value); + this.orderId = value; + fieldSetFlags()[3] = true; + return this; + } + + /** + * Checks whether the 'orderId' field has been set. + * @return True if the 'orderId' field has been set, false otherwise. + */ + public boolean hasOrderId() { + return fieldSetFlags()[3]; + } + + + /** + * Clears the value of the 'orderId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder clearOrderId() { + orderId = null; + fieldSetFlags()[3] = false; + return this; + } + + /** + * Gets the value of the 'restaurantOrderStatus' field. + * @return The value. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus getRestaurantOrderStatus() { + return restaurantOrderStatus; + } + + + /** + * Sets the value of the 'restaurantOrderStatus' field. + * @param value The value of 'restaurantOrderStatus'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder setRestaurantOrderStatus(com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus value) { + validate(fields()[4], value); + this.restaurantOrderStatus = value; + fieldSetFlags()[4] = true; + return this; + } + + /** + * Checks whether the 'restaurantOrderStatus' field has been set. + * @return True if the 'restaurantOrderStatus' field has been set, false otherwise. + */ + public boolean hasRestaurantOrderStatus() { + return fieldSetFlags()[4]; + } + + + /** + * Clears the value of the 'restaurantOrderStatus' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder clearRestaurantOrderStatus() { + restaurantOrderStatus = null; + fieldSetFlags()[4] = false; + return this; + } + + /** + * Gets the value of the 'products' field. + * @return The value. + */ + public java.util.List getProducts() { + return products; + } + + + /** + * Sets the value of the 'products' field. + * @param value The value of 'products'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder setProducts(java.util.List value) { + validate(fields()[5], value); + this.products = value; + fieldSetFlags()[5] = true; + return this; + } + + /** + * Checks whether the 'products' field has been set. + * @return True if the 'products' field has been set, false otherwise. + */ + public boolean hasProducts() { + return fieldSetFlags()[5]; + } + + + /** + * Clears the value of the 'products' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder clearProducts() { + products = null; + fieldSetFlags()[5] = false; + return this; + } + + /** + * Gets the value of the 'price' field. + * @return The value. + */ + public java.math.BigDecimal getPrice() { + return price; + } + + + /** + * Sets the value of the 'price' field. + * @param value The value of 'price'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder setPrice(java.math.BigDecimal value) { + validate(fields()[6], value); + this.price = value; + fieldSetFlags()[6] = true; + return this; + } + + /** + * Checks whether the 'price' field has been set. + * @return True if the 'price' field has been set, false otherwise. + */ + public boolean hasPrice() { + return fieldSetFlags()[6]; + } + + + /** + * Clears the value of the 'price' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder clearPrice() { + price = null; + fieldSetFlags()[6] = false; + return this; + } + + /** + * Gets the value of the 'createdAt' field. + * @return The value. + */ + public java.time.Instant getCreatedAt() { + return createdAt; + } + + + /** + * Sets the value of the 'createdAt' field. + * @param value The value of 'createdAt'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder setCreatedAt(java.time.Instant value) { + validate(fields()[7], value); + this.createdAt = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + fieldSetFlags()[7] = true; + return this; + } + + /** + * Checks whether the 'createdAt' field has been set. + * @return True if the 'createdAt' field has been set, false otherwise. + */ + public boolean hasCreatedAt() { + return fieldSetFlags()[7]; + } + + + /** + * Clears the value of the 'createdAt' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel.Builder clearCreatedAt() { + fieldSetFlags()[7] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public RestaurantApprovalRequestAvroModel build() { + try { + RestaurantApprovalRequestAvroModel record = new RestaurantApprovalRequestAvroModel(); + record.id = fieldSetFlags()[0] ? this.id : (java.lang.String) defaultValue(fields()[0]); + record.sagaId = fieldSetFlags()[1] ? this.sagaId : (java.lang.String) defaultValue(fields()[1]); + record.restaurantId = fieldSetFlags()[2] ? this.restaurantId : (java.lang.String) defaultValue(fields()[2]); + record.orderId = fieldSetFlags()[3] ? this.orderId : (java.lang.String) defaultValue(fields()[3]); + record.restaurantOrderStatus = fieldSetFlags()[4] ? this.restaurantOrderStatus : (com.food.ordering.system.kafka.order.avro.model.RestaurantOrderStatus) defaultValue(fields()[4]); + record.products = fieldSetFlags()[5] ? this.products : (java.util.List) defaultValue(fields()[5]); + record.price = fieldSetFlags()[6] ? this.price : (java.math.BigDecimal) defaultValue(fields()[6]); + record.createdAt = fieldSetFlags()[7] ? this.createdAt : (java.time.Instant) defaultValue(fields()[7]); + return record; + } catch (org.apache.avro.AvroMissingFieldException e) { + throw e; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + +} + + + + + + + + + + diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantApprovalResponseAvroModel.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantApprovalResponseAvroModel.java new file mode 100644 index 0000000..a27bd22 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantApprovalResponseAvroModel.java @@ -0,0 +1,735 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; + +import org.apache.avro.generic.GenericArray; +import org.apache.avro.specific.SpecificData; +import org.apache.avro.util.Utf8; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +@org.apache.avro.specific.AvroGenerated +public class RestaurantApprovalResponseAvroModel extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = -3431989201238018220L; + + + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"RestaurantApprovalResponseAvroModel\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"sagaId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"restaurantId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"orderId\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"createdAt\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}},{\"name\":\"orderApprovalStatus\",\"type\":{\"type\":\"enum\",\"name\":\"OrderApprovalStatus\",\"symbols\":[\"APPROVED\",\"REJECTED\"]}},{\"name\":\"failureMessages\",\"type\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static final SpecificData MODEL$ = new SpecificData(); + static { + MODEL$.addLogicalTypeConversion(new org.apache.avro.data.TimeConversions.TimestampMillisConversion()); + } + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageEncoder instance used by this class. + * @return the message encoder used by this class + */ + public static BinaryMessageEncoder getEncoder() { + return ENCODER; + } + + /** + * Return the BinaryMessageDecoder instance used by this class. + * @return the message decoder used by this class + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** + * Serializes this RestaurantApprovalResponseAvroModel to a ByteBuffer. + * @return a buffer holding the serialized data for this instance + * @throws java.io.IOException if this instance could not be serialized + */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** + * Deserializes a RestaurantApprovalResponseAvroModel from a ByteBuffer. + * @param b a byte buffer holding serialized data for an instance of this class + * @return a RestaurantApprovalResponseAvroModel instance decoded from the given buffer + * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class + */ + public static RestaurantApprovalResponseAvroModel fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + private java.lang.String id; + private java.lang.String sagaId; + private java.lang.String restaurantId; + private java.lang.String orderId; + private java.time.Instant createdAt; + private com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus orderApprovalStatus; + private java.util.List failureMessages; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public RestaurantApprovalResponseAvroModel() {} + + /** + * All-args constructor. + * @param id The new value for id + * @param sagaId The new value for sagaId + * @param restaurantId The new value for restaurantId + * @param orderId The new value for orderId + * @param createdAt The new value for createdAt + * @param orderApprovalStatus The new value for orderApprovalStatus + * @param failureMessages The new value for failureMessages + */ + public RestaurantApprovalResponseAvroModel(java.lang.String id, java.lang.String sagaId, java.lang.String restaurantId, java.lang.String orderId, java.time.Instant createdAt, com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus orderApprovalStatus, java.util.List failureMessages) { + this.id = id; + this.sagaId = sagaId; + this.restaurantId = restaurantId; + this.orderId = orderId; + this.createdAt = createdAt.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + this.orderApprovalStatus = orderApprovalStatus; + this.failureMessages = failureMessages; + } + + public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return id; + case 1: return sagaId; + case 2: return restaurantId; + case 3: return orderId; + case 4: return createdAt; + case 5: return orderApprovalStatus; + case 6: return failureMessages; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + private static final org.apache.avro.Conversion[] conversions = + new org.apache.avro.Conversion[] { + null, + null, + null, + null, + new org.apache.avro.data.TimeConversions.TimestampMillisConversion(), + null, + null, + null + }; + + @Override + public org.apache.avro.Conversion getConversion(int field) { + return conversions[field]; + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: id = value$ != null ? value$.toString() : null; break; + case 1: sagaId = value$ != null ? value$.toString() : null; break; + case 2: restaurantId = value$ != null ? value$.toString() : null; break; + case 3: orderId = value$ != null ? value$.toString() : null; break; + case 4: createdAt = (java.time.Instant)value$; break; + case 5: orderApprovalStatus = (com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus)value$; break; + case 6: failureMessages = (java.util.List)value$; break; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + /** + * Gets the value of the 'id' field. + * @return The value of the 'id' field. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value the value to set. + */ + public void setId(java.lang.String value) { + this.id = value; + } + + /** + * Gets the value of the 'sagaId' field. + * @return The value of the 'sagaId' field. + */ + public java.lang.String getSagaId() { + return sagaId; + } + + + /** + * Sets the value of the 'sagaId' field. + * @param value the value to set. + */ + public void setSagaId(java.lang.String value) { + this.sagaId = value; + } + + /** + * Gets the value of the 'restaurantId' field. + * @return The value of the 'restaurantId' field. + */ + public java.lang.String getRestaurantId() { + return restaurantId; + } + + + /** + * Sets the value of the 'restaurantId' field. + * @param value the value to set. + */ + public void setRestaurantId(java.lang.String value) { + this.restaurantId = value; + } + + /** + * Gets the value of the 'orderId' field. + * @return The value of the 'orderId' field. + */ + public java.lang.String getOrderId() { + return orderId; + } + + + /** + * Sets the value of the 'orderId' field. + * @param value the value to set. + */ + public void setOrderId(java.lang.String value) { + this.orderId = value; + } + + /** + * Gets the value of the 'createdAt' field. + * @return The value of the 'createdAt' field. + */ + public java.time.Instant getCreatedAt() { + return createdAt; + } + + + /** + * Sets the value of the 'createdAt' field. + * @param value the value to set. + */ + public void setCreatedAt(java.time.Instant value) { + this.createdAt = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + } + + /** + * Gets the value of the 'orderApprovalStatus' field. + * @return The value of the 'orderApprovalStatus' field. + */ + public com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus getOrderApprovalStatus() { + return orderApprovalStatus; + } + + + /** + * Sets the value of the 'orderApprovalStatus' field. + * @param value the value to set. + */ + public void setOrderApprovalStatus(com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus value) { + this.orderApprovalStatus = value; + } + + /** + * Gets the value of the 'failureMessages' field. + * @return The value of the 'failureMessages' field. + */ + public java.util.List getFailureMessages() { + return failureMessages; + } + + + /** + * Sets the value of the 'failureMessages' field. + * @param value the value to set. + */ + public void setFailureMessages(java.util.List value) { + this.failureMessages = value; + } + + /** + * Creates a new RestaurantApprovalResponseAvroModel RecordBuilder. + * @return A new RestaurantApprovalResponseAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder newBuilder() { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder(); + } + + /** + * Creates a new RestaurantApprovalResponseAvroModel RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new RestaurantApprovalResponseAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder(other); + } + } + + /** + * Creates a new RestaurantApprovalResponseAvroModel RecordBuilder by copying an existing RestaurantApprovalResponseAvroModel instance. + * @param other The existing instance to copy. + * @return A new RestaurantApprovalResponseAvroModel RecordBuilder + */ + public static com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder newBuilder(com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel other) { + if (other == null) { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder(); + } else { + return new com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder(other); + } + } + + /** + * RecordBuilder for RestaurantApprovalResponseAvroModel instances. + */ + @org.apache.avro.specific.AvroGenerated + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private java.lang.String id; + private java.lang.String sagaId; + private java.lang.String restaurantId; + private java.lang.String orderId; + private java.time.Instant createdAt; + private com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus orderApprovalStatus; + private java.util.List failureMessages; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$, MODEL$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder other) { + super(other); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = other.fieldSetFlags()[0]; + } + if (isValidValue(fields()[1], other.sagaId)) { + this.sagaId = data().deepCopy(fields()[1].schema(), other.sagaId); + fieldSetFlags()[1] = other.fieldSetFlags()[1]; + } + if (isValidValue(fields()[2], other.restaurantId)) { + this.restaurantId = data().deepCopy(fields()[2].schema(), other.restaurantId); + fieldSetFlags()[2] = other.fieldSetFlags()[2]; + } + if (isValidValue(fields()[3], other.orderId)) { + this.orderId = data().deepCopy(fields()[3].schema(), other.orderId); + fieldSetFlags()[3] = other.fieldSetFlags()[3]; + } + if (isValidValue(fields()[4], other.createdAt)) { + this.createdAt = data().deepCopy(fields()[4].schema(), other.createdAt); + fieldSetFlags()[4] = other.fieldSetFlags()[4]; + } + if (isValidValue(fields()[5], other.orderApprovalStatus)) { + this.orderApprovalStatus = data().deepCopy(fields()[5].schema(), other.orderApprovalStatus); + fieldSetFlags()[5] = other.fieldSetFlags()[5]; + } + if (isValidValue(fields()[6], other.failureMessages)) { + this.failureMessages = data().deepCopy(fields()[6].schema(), other.failureMessages); + fieldSetFlags()[6] = other.fieldSetFlags()[6]; + } + } + + /** + * Creates a Builder by copying an existing RestaurantApprovalResponseAvroModel instance + * @param other The existing instance to copy. + */ + private Builder(com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel other) { + super(SCHEMA$, MODEL$); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.sagaId)) { + this.sagaId = data().deepCopy(fields()[1].schema(), other.sagaId); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.restaurantId)) { + this.restaurantId = data().deepCopy(fields()[2].schema(), other.restaurantId); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.orderId)) { + this.orderId = data().deepCopy(fields()[3].schema(), other.orderId); + fieldSetFlags()[3] = true; + } + if (isValidValue(fields()[4], other.createdAt)) { + this.createdAt = data().deepCopy(fields()[4].schema(), other.createdAt); + fieldSetFlags()[4] = true; + } + if (isValidValue(fields()[5], other.orderApprovalStatus)) { + this.orderApprovalStatus = data().deepCopy(fields()[5].schema(), other.orderApprovalStatus); + fieldSetFlags()[5] = true; + } + if (isValidValue(fields()[6], other.failureMessages)) { + this.failureMessages = data().deepCopy(fields()[6].schema(), other.failureMessages); + fieldSetFlags()[6] = true; + } + } + + /** + * Gets the value of the 'id' field. + * @return The value. + */ + public java.lang.String getId() { + return id; + } + + + /** + * Sets the value of the 'id' field. + * @param value The value of 'id'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder setId(java.lang.String value) { + validate(fields()[0], value); + this.id = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'id' field has been set. + * @return True if the 'id' field has been set, false otherwise. + */ + public boolean hasId() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'id' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder clearId() { + id = null; + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'sagaId' field. + * @return The value. + */ + public java.lang.String getSagaId() { + return sagaId; + } + + + /** + * Sets the value of the 'sagaId' field. + * @param value The value of 'sagaId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder setSagaId(java.lang.String value) { + validate(fields()[1], value); + this.sagaId = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'sagaId' field has been set. + * @return True if the 'sagaId' field has been set, false otherwise. + */ + public boolean hasSagaId() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'sagaId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder clearSagaId() { + sagaId = null; + fieldSetFlags()[1] = false; + return this; + } + + /** + * Gets the value of the 'restaurantId' field. + * @return The value. + */ + public java.lang.String getRestaurantId() { + return restaurantId; + } + + + /** + * Sets the value of the 'restaurantId' field. + * @param value The value of 'restaurantId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder setRestaurantId(java.lang.String value) { + validate(fields()[2], value); + this.restaurantId = value; + fieldSetFlags()[2] = true; + return this; + } + + /** + * Checks whether the 'restaurantId' field has been set. + * @return True if the 'restaurantId' field has been set, false otherwise. + */ + public boolean hasRestaurantId() { + return fieldSetFlags()[2]; + } + + + /** + * Clears the value of the 'restaurantId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder clearRestaurantId() { + restaurantId = null; + fieldSetFlags()[2] = false; + return this; + } + + /** + * Gets the value of the 'orderId' field. + * @return The value. + */ + public java.lang.String getOrderId() { + return orderId; + } + + + /** + * Sets the value of the 'orderId' field. + * @param value The value of 'orderId'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder setOrderId(java.lang.String value) { + validate(fields()[3], value); + this.orderId = value; + fieldSetFlags()[3] = true; + return this; + } + + /** + * Checks whether the 'orderId' field has been set. + * @return True if the 'orderId' field has been set, false otherwise. + */ + public boolean hasOrderId() { + return fieldSetFlags()[3]; + } + + + /** + * Clears the value of the 'orderId' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder clearOrderId() { + orderId = null; + fieldSetFlags()[3] = false; + return this; + } + + /** + * Gets the value of the 'createdAt' field. + * @return The value. + */ + public java.time.Instant getCreatedAt() { + return createdAt; + } + + + /** + * Sets the value of the 'createdAt' field. + * @param value The value of 'createdAt'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder setCreatedAt(java.time.Instant value) { + validate(fields()[4], value); + this.createdAt = value.truncatedTo(java.time.temporal.ChronoUnit.MILLIS); + fieldSetFlags()[4] = true; + return this; + } + + /** + * Checks whether the 'createdAt' field has been set. + * @return True if the 'createdAt' field has been set, false otherwise. + */ + public boolean hasCreatedAt() { + return fieldSetFlags()[4]; + } + + + /** + * Clears the value of the 'createdAt' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder clearCreatedAt() { + fieldSetFlags()[4] = false; + return this; + } + + /** + * Gets the value of the 'orderApprovalStatus' field. + * @return The value. + */ + public com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus getOrderApprovalStatus() { + return orderApprovalStatus; + } + + + /** + * Sets the value of the 'orderApprovalStatus' field. + * @param value The value of 'orderApprovalStatus'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder setOrderApprovalStatus(com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus value) { + validate(fields()[5], value); + this.orderApprovalStatus = value; + fieldSetFlags()[5] = true; + return this; + } + + /** + * Checks whether the 'orderApprovalStatus' field has been set. + * @return True if the 'orderApprovalStatus' field has been set, false otherwise. + */ + public boolean hasOrderApprovalStatus() { + return fieldSetFlags()[5]; + } + + + /** + * Clears the value of the 'orderApprovalStatus' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder clearOrderApprovalStatus() { + orderApprovalStatus = null; + fieldSetFlags()[5] = false; + return this; + } + + /** + * Gets the value of the 'failureMessages' field. + * @return The value. + */ + public java.util.List getFailureMessages() { + return failureMessages; + } + + + /** + * Sets the value of the 'failureMessages' field. + * @param value The value of 'failureMessages'. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder setFailureMessages(java.util.List value) { + validate(fields()[6], value); + this.failureMessages = value; + fieldSetFlags()[6] = true; + return this; + } + + /** + * Checks whether the 'failureMessages' field has been set. + * @return True if the 'failureMessages' field has been set, false otherwise. + */ + public boolean hasFailureMessages() { + return fieldSetFlags()[6]; + } + + + /** + * Clears the value of the 'failureMessages' field. + * @return This builder. + */ + public com.food.ordering.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel.Builder clearFailureMessages() { + failureMessages = null; + fieldSetFlags()[6] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public RestaurantApprovalResponseAvroModel build() { + try { + RestaurantApprovalResponseAvroModel record = new RestaurantApprovalResponseAvroModel(); + record.id = fieldSetFlags()[0] ? this.id : (java.lang.String) defaultValue(fields()[0]); + record.sagaId = fieldSetFlags()[1] ? this.sagaId : (java.lang.String) defaultValue(fields()[1]); + record.restaurantId = fieldSetFlags()[2] ? this.restaurantId : (java.lang.String) defaultValue(fields()[2]); + record.orderId = fieldSetFlags()[3] ? this.orderId : (java.lang.String) defaultValue(fields()[3]); + record.createdAt = fieldSetFlags()[4] ? this.createdAt : (java.time.Instant) defaultValue(fields()[4]); + record.orderApprovalStatus = fieldSetFlags()[5] ? this.orderApprovalStatus : (com.food.ordering.system.kafka.order.avro.model.OrderApprovalStatus) defaultValue(fields()[5]); + record.failureMessages = fieldSetFlags()[6] ? this.failureMessages : (java.util.List) defaultValue(fields()[6]); + return record; + } catch (org.apache.avro.AvroMissingFieldException e) { + throw e; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + +} + + + + + + + + + + diff --git a/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantOrderStatus.java b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantOrderStatus.java new file mode 100644 index 0000000..cc01290 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/java/com/food/ordering/system/kafka/order/avro/model/RestaurantOrderStatus.java @@ -0,0 +1,13 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.food.ordering.system.kafka.order.avro.model; +@org.apache.avro.specific.AvroGenerated +public enum RestaurantOrderStatus implements org.apache.avro.generic.GenericEnumSymbol { + PAID ; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"enum\",\"name\":\"RestaurantOrderStatus\",\"namespace\":\"com.food.ordering.system.kafka.order.avro.model\",\"symbols\":[\"PAID\"]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + public org.apache.avro.Schema getSchema() { return SCHEMA$; } +} diff --git a/infrastructure/kafka/kafka-model/src/main/resources/avro/payment_request.avsc b/infrastructure/kafka/kafka-model/src/main/resources/avro/payment_request.avsc new file mode 100644 index 0000000..383aa5a --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/resources/avro/payment_request.avsc @@ -0,0 +1,59 @@ +{ + "namespace": "com.food.ordering.system.kafka.order.avro.model", + "type": "record", + "name": "PaymentRequestAvroModel", + "fields": [ + { + "name": "id", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "sagaId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "customerId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "orderId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "price", + "type": { + "type": "bytes", + "logicalType": "decimal", + "precision": 10, + "scale": 2 + } + }, + { + "name": "createdAt", + "type": { + "type": "long", + "logicalType": "timestamp-millis" + } + }, + { + "name": "paymentOrderStatus", + "type": { + "type": "enum", + "name": "PaymentOrderStatus", + "symbols": ["PENDING", "CANCELLED"] + } + } + ] +} \ No newline at end of file diff --git a/infrastructure/kafka/kafka-model/src/main/resources/avro/payment_response.avsc b/infrastructure/kafka/kafka-model/src/main/resources/avro/payment_response.avsc new file mode 100644 index 0000000..a968794 --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/resources/avro/payment_response.avsc @@ -0,0 +1,75 @@ +{ + "namespace": "com.food.ordering.system.kafka.order.avro.model", + "type": "record", + "name": "PaymentResponseAvroModel", + "fields": [ + { + "name": "id", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "sagaId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "paymentId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "customerId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "orderId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "price", + "type": { + "type": "bytes", + "logicalType": "decimal", + "precision": 10, + "scale": 2 + } + }, + { + "name": "createdAt", + "type": { + "type": "long", + "logicalType": "timestamp-millis" + } + }, + { + "name": "paymentStatus", + "type": { + "type": "enum", + "name": "PaymentStatus", + "symbols": ["COMPLETED", "CANCELLED", "FAILED"] + } + }, + { + "name": "failureMessages", + "type": { + "type": "array", + "items":{ + "type":"string" + } + } + } + ] +} \ No newline at end of file diff --git a/infrastructure/kafka/kafka-model/src/main/resources/avro/restaurant_approval_request.avsc b/infrastructure/kafka/kafka-model/src/main/resources/avro/restaurant_approval_request.avsc new file mode 100644 index 0000000..13d873c --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/resources/avro/restaurant_approval_request.avsc @@ -0,0 +1,73 @@ +{ + "namespace": "com.food.ordering.system.kafka.order.avro.model", + "type": "record", + "name": "RestaurantApprovalRequestAvroModel", + "fields": [ + { + "name": "id", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "sagaId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "restaurantId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "orderId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "restaurantOrderStatus", + "type": { + "type": "enum", + "name": "RestaurantOrderStatus", + "symbols": ["PAID"] + } + }, + { + "name": "products", + "type": { + "type": "array", + "items":{ + "name":"Product", + "type":"record", + "fields":[ + {"name":"id", "type": "string", "logicalType": "uuid"}, + {"name":"quantity", "type": "int"} + ] + } + } + }, + { + "name": "price", + "type": { + "type": "bytes", + "logicalType": "decimal", + "precision": 10, + "scale": 2 + } + }, + { + "name": "createdAt", + "type": { + "type": "long", + "logicalType": "timestamp-millis" + } + } + ] +} \ No newline at end of file diff --git a/infrastructure/kafka/kafka-model/src/main/resources/avro/restaurant_approval_response.avsc b/infrastructure/kafka/kafka-model/src/main/resources/avro/restaurant_approval_response.avsc new file mode 100644 index 0000000..ca0bbef --- /dev/null +++ b/infrastructure/kafka/kafka-model/src/main/resources/avro/restaurant_approval_response.avsc @@ -0,0 +1,59 @@ +{ + "namespace": "com.food.ordering.system.kafka.order.avro.model", + "type": "record", + "name": "RestaurantApprovalResponseAvroModel", + "fields": [ + { + "name": "id", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "sagaId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "restaurantId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "orderId", + "type": { + "type": "string", + "logicalType": "uuid" + } + }, + { + "name": "createdAt", + "type": { + "type": "long", + "logicalType": "timestamp-millis" + } + }, + { + "name": "orderApprovalStatus", + "type": { + "type": "enum", + "name": "OrderApprovalStatus", + "symbols": ["APPROVED", "REJECTED"] + } + }, + { + "name": "failureMessages", + "type": { + "type": "array", + "items":{ + "type":"string" + } + } + } + ] +} \ No newline at end of file diff --git a/infrastructure/kafka/kafka-producer/pom.xml b/infrastructure/kafka/kafka-producer/pom.xml new file mode 100644 index 0000000..a6f7d0a --- /dev/null +++ b/infrastructure/kafka/kafka-producer/pom.xml @@ -0,0 +1,48 @@ + + + + kafka + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + kafka-producer + + + + com.food.order + kafka-model + + + + com.food.order + kafka-config + + + + com.food.order + order-core-domain + + + + com.food.order + common-domain + + + + org.springframework.kafka + spring-kafka + + + + io.confluent + kafka-avro-serializer + + + + + + \ No newline at end of file diff --git a/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/KafkaProducerConfig.java b/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/KafkaProducerConfig.java new file mode 100644 index 0000000..65b96bb --- /dev/null +++ b/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/KafkaProducerConfig.java @@ -0,0 +1,56 @@ +package com.food.order.system.kafka.producer; + + +import com.food.order.kafka.config.data.KafkaConfigData; +import com.food.order.kafka.config.data.KafkaProducerConfigData; +import lombok.RequiredArgsConstructor; +import org.apache.avro.specific.SpecificRecordBase; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +@Configuration +@RequiredArgsConstructor +public class KafkaProducerConfig { + + private final KafkaConfigData kafkaConfigData; + private final KafkaProducerConfigData kafkaProducerConfigData; + + @Bean + public Map producerConfig(){ + Map props = new HashMap<>(); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaConfigData.getBootstrapServers()); + props.put(kafkaConfigData.getSchemaRegistryUrlKey(), kafkaConfigData.getSchemaRegistryUrl()); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, kafkaProducerConfigData.getKeySerializerClass()); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, kafkaProducerConfigData.getValueSerializerClass()); + props.put(ProducerConfig.BATCH_SIZE_CONFIG, kafkaProducerConfigData.getBatchSize() * + kafkaProducerConfigData.getBatchSizeBoostFactor()); + props.put(ProducerConfig.LINGER_MS_CONFIG, kafkaProducerConfigData.getLingerMs()); + props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, kafkaProducerConfigData.getCompressionType()); + props.put(ProducerConfig.ACKS_CONFIG, kafkaProducerConfigData.getAcks()); + props.put(ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG, kafkaProducerConfigData.getRequestTimeoutMs()); + props.put(ProducerConfig.RETRIES_CONFIG, kafkaProducerConfigData.getRetryCount()); + return props; + } + + @Bean + public ProducerFactory producerFactory(){ + return new DefaultKafkaProducerFactory<>(producerConfig()); + } + + @Bean + public KafkaTemplate kafkaTemplate(){ + return new KafkaTemplate<>(producerFactory()); + } + + + + +} diff --git a/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/exception/KafkaProducerException.java b/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/exception/KafkaProducerException.java new file mode 100644 index 0000000..cd9b304 --- /dev/null +++ b/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/exception/KafkaProducerException.java @@ -0,0 +1,7 @@ +package com.food.order.system.kafka.producer.exception; + +public class KafkaProducerException extends RuntimeException{ + public KafkaProducerException(String message) { + super(message); + } +} diff --git a/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/service/KafkaProducer.java b/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/service/KafkaProducer.java new file mode 100644 index 0000000..90ea2f9 --- /dev/null +++ b/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/service/KafkaProducer.java @@ -0,0 +1,11 @@ +package com.food.order.system.kafka.producer.service; + +import org.apache.avro.specific.SpecificRecordBase; +import org.springframework.kafka.support.SendResult; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import java.io.Serializable; + +public interface KafkaProducer { + void send(String topicName, K key , V message, ListenableFutureCallback> callback); +} diff --git a/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/service/impl/KafkaProducerImpl.java b/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/service/impl/KafkaProducerImpl.java new file mode 100644 index 0000000..4fca267 --- /dev/null +++ b/infrastructure/kafka/kafka-producer/src/main/java/com/food/order/system/kafka/producer/service/impl/KafkaProducerImpl.java @@ -0,0 +1,52 @@ +package com.food.order.system.kafka.producer.service.impl; + +import com.food.order.system.kafka.producer.service.KafkaProducer; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.avro.specific.SpecificRecordBase; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.support.SendResult; +import org.springframework.stereotype.Component; +import org.springframework.util.concurrent.ListenableFutureCallback; + +import javax.annotation.PreDestroy; +import java.io.Serializable; +import java.util.Objects; + + +@Component +@RequiredArgsConstructor +@Slf4j +public class KafkaProducerImpl implements KafkaProducer { + + private final KafkaTemplate kafkaTemplate; + + @Override + public void send(String topicName, K key, V message, ListenableFutureCallback> callback) { + log.info("Sending message to topic: {}, also message {}", topicName,message); + kafkaTemplate.send(topicName, key, message) + .addCallback(new ListenableFutureCallback<>() { + @Override + public void onFailure(Throwable ex) { + log.error("Error sending message to topic: {}, also message {}", topicName, message, ex); + callback.onFailure(ex); + } + + @Override + public void onSuccess(SendResult result) { + log.info("Message sent to topic: {}, also message {}", topicName, message); + callback.onSuccess(result); + } + }); + } + + @PreDestroy + public void destroy() { + log.info("KafkaProducerImpl is being destroyed"); + if (Objects.nonNull(kafkaTemplate)) { + kafkaTemplate.destroy(); + } + } + + +} diff --git a/infrastructure/kafka/pom.xml b/infrastructure/kafka/pom.xml new file mode 100644 index 0000000..d6187cc --- /dev/null +++ b/infrastructure/kafka/pom.xml @@ -0,0 +1,72 @@ + + + + food-ordering-system + com.food.order + 1.0-SNAPSHOT + ../../pom.xml + + 4.0.0 + + kafka + pom + + kafka-producer + kafka-consumer + kafka-model + kafka-config + + + + + confluent + https://packages.confluent.io/maven/ + + + + + + + + + org.springframework.kafka + spring-kafka + ${spring-kafka.version} + + + + io.confluent + kafka-avro-serializer + ${kavka-avro.serializer.version} + + + org.slf4j + slf4j-log4j12 + + + log4j + log4j + + + io.swagger + swagger-annotations + + + io.swagger + swagger-core + + + + + + org.apache.avro + avro + ${avro.version} + + + + + + \ No newline at end of file diff --git a/infrastructure/pom.xml b/infrastructure/pom.xml new file mode 100644 index 0000000..5b56af1 --- /dev/null +++ b/infrastructure/pom.xml @@ -0,0 +1,15 @@ + + + + food-ordering-system + com.food.order + 1.0-SNAPSHOT + + 4.0.0 + + infrastructure + + + \ No newline at end of file diff --git a/order-service/order-domain/order-application-service/pom.xml b/order-service/order-domain/order-application-service/pom.xml index 8bd87d6..1c8dbeb 100644 --- a/order-service/order-domain/order-application-service/pom.xml +++ b/order-service/order-domain/order-application-service/pom.xml @@ -36,6 +36,16 @@ spring-tx + + org.mockito + mockito-core + test + + + + org.springframework.boot + spring-boot-starter-test + \ No newline at end of file diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderCreateHelper.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderCreateHelper.java index 02c1eb1..d3d8335 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderCreateHelper.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderCreateHelper.java @@ -31,7 +31,7 @@ public class OrderCreateHelper { @Transactional public OrderCreatedEvent persistOrder(CreateOrderCommand createOrderCommand) { log.info("createOrder: {}", createOrderCommand); - checkCustomer(createOrderCommand.getCustomerId()); + checkCustomer(createOrderCommand.customerId()); Restaurant restaurant = checkRestaurant(createOrderCommand); var order = orderDataMapper.createOrderCommandToOrder(createOrderCommand); var createdEventOrder = orderDomainService.validateAndInitiateOrder(order, restaurant); @@ -44,7 +44,7 @@ public class OrderCreateHelper { return restaurantRepository.findRestaurantInformation (orderDataMapper.createOrderCommandToRestaurant(createOrderCommand)) .orElseThrow(() -> new OrderDomainException("Restaurant not found. " + - "Please check restaurant id: " + createOrderCommand.getRestaurantId())); + "Please check restaurant id: " + createOrderCommand.restaurantId())); } diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderTrackCommandHandler.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderTrackCommandHandler.java index 8cf4458..8e1d0dc 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderTrackCommandHandler.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/OrderTrackCommandHandler.java @@ -2,15 +2,29 @@ package com.food.order.domain; import com.food.order.domain.dto.track.TrackOrderQuery; import com.food.order.domain.dto.track.TrackOrderResponse; +import com.food.order.domain.mapper.OrderDataMapper; +import com.food.order.domain.ports.output.repository.OrderRepository; +import com.food.order.system.domain.exception.OrderNotFoundException; +import com.food.order.system.domain.valueobject.TrackingId; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; @Component @Slf4j +@RequiredArgsConstructor public class OrderTrackCommandHandler { + private final OrderDataMapper orderDataMapper; + private final OrderRepository orderRepository; + + @Transactional(readOnly = true) public TrackOrderResponse trackOrder(TrackOrderQuery trackOrderQuery) { - log.info("trackOrder: {}", trackOrderQuery); - return null; + var order = orderRepository.findByTrackingId + (new TrackingId(trackOrderQuery.orderTrackingId())) + .orElseThrow(() -> new OrderNotFoundException + ("Order not found with tracking id : + " + trackOrderQuery.orderTrackingId())); + return orderDataMapper.orderToTrackOrderResponse(order); } } diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/PaymentResponseMessageListenerImpl.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/PaymentResponseMessageListenerImpl.java new file mode 100644 index 0000000..6913c15 --- /dev/null +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/PaymentResponseMessageListenerImpl.java @@ -0,0 +1,25 @@ +package com.food.order.domain; + +import com.food.order.domain.dto.message.PaymentResponse; +import com.food.order.domain.ports.input.message.listener.payment.PaymentResponseMessageListener; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +@Service +@Validated +@Slf4j +@RequiredArgsConstructor +public class PaymentResponseMessageListenerImpl implements PaymentResponseMessageListener { + + @Override + public void paymentCompleted(PaymentResponse paymentResponse) { + + } + + @Override + public void paymentCancelled(PaymentResponse paymentResponse) { + + } +} diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/RestaurantApprovalResponseMessageListenerImpl.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/RestaurantApprovalResponseMessageListenerImpl.java new file mode 100644 index 0000000..282e769 --- /dev/null +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/RestaurantApprovalResponseMessageListenerImpl.java @@ -0,0 +1,23 @@ +package com.food.order.domain; + +import com.food.order.domain.dto.message.RestaurantApprovalResponse; +import com.food.order.domain.ports.input.message.listener.restaurantapproval.RestaurantApprovalResponseMessageListener; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@RequiredArgsConstructor +@Service +public class RestaurantApprovalResponseMessageListenerImpl implements RestaurantApprovalResponseMessageListener { + + @Override + public void orderApproved(RestaurantApprovalResponse restaurantApprovalResponse) { + + } + + @Override + public void orderRejected(RestaurantApprovalResponse restaurantApprovalResponse) { + + } +} diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderCommand.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderCommand.java index bf17cce..3fa1d62 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderCommand.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderCommand.java @@ -9,9 +9,7 @@ import java.math.BigDecimal; import java.util.List; import java.util.UUID; -@Getter @Builder -@AllArgsConstructor public record CreateOrderCommand(@NotNull UUID customerId, @NotNull UUID restaurantId, @NotNull BigDecimal price, diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderResponse.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderResponse.java index 05ef000..24494a2 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderResponse.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/CreateOrderResponse.java @@ -3,14 +3,11 @@ package com.food.order.domain.dto.create; import com.food.order.domain.valueobject.OrderStatus; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Getter; import javax.validation.constraints.NotNull; import java.util.UUID; -@Getter @Builder -@AllArgsConstructor public record CreateOrderResponse(@NotNull UUID orderTrackingId, @NotNull OrderStatus orderStatus, @NotNull String message) { diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/OrderAddress.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/OrderAddress.java index d96e8b9..4cb6e32 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/OrderAddress.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/OrderAddress.java @@ -7,8 +7,6 @@ import lombok.Getter; import javax.validation.constraints.Max; import javax.validation.constraints.NotNull; -@Getter -@AllArgsConstructor @Builder public record OrderAddress(@NotNull @Max(value = 50) String street, @NotNull @Max(value = 50) String city, diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/OrderItem.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/OrderItem.java index 34c0619..f1e1fec 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/OrderItem.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/create/OrderItem.java @@ -1,6 +1,5 @@ package com.food.order.domain.dto.create; -import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -8,8 +7,6 @@ import javax.validation.constraints.NotNull; import java.math.BigDecimal; import java.util.UUID; -@Getter -@AllArgsConstructor @Builder public record OrderItem(@NotNull UUID productId, @NotNull Integer quantity, diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderQuery.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderQuery.java index b84829f..7a96a60 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderQuery.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderQuery.java @@ -2,13 +2,10 @@ package com.food.order.domain.dto.track; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Getter; import javax.validation.constraints.NotNull; import java.util.UUID; -@Getter @Builder -@AllArgsConstructor public record TrackOrderQuery(@NotNull UUID orderTrackingId) { } diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderResponse.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderResponse.java index 7daea56..8ca5528 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderResponse.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/dto/track/TrackOrderResponse.java @@ -3,15 +3,12 @@ package com.food.order.domain.dto.track; import com.food.order.domain.valueobject.OrderStatus; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Getter; import javax.validation.constraints.NotNull; import java.util.List; import java.util.UUID; -@Getter @Builder -@AllArgsConstructor public record TrackOrderResponse(@NotNull UUID orderTrackingId, @NotNull OrderStatus orderStatus, List failureMessages) { diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/mapper/OrderDataMapper.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/mapper/OrderDataMapper.java index c536e26..584ef05 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/mapper/OrderDataMapper.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/mapper/OrderDataMapper.java @@ -3,6 +3,7 @@ package com.food.order.domain.mapper; import com.food.order.domain.dto.create.CreateOrderCommand; import com.food.order.domain.dto.create.CreateOrderResponse; import com.food.order.domain.dto.create.OrderAddress; +import com.food.order.domain.dto.track.TrackOrderResponse; import com.food.order.domain.valueobject.CustomerId; import com.food.order.domain.valueobject.Money; import com.food.order.domain.valueobject.ProductId; @@ -21,24 +22,34 @@ import java.util.stream.Collectors; @Component public class OrderDataMapper { + public TrackOrderResponse orderToTrackOrderResponse(Order order) { + + return TrackOrderResponse.builder() + .orderTrackingId(order.getTrackingId().getValue()) + .orderStatus(order.getStatus()) + .failureMessages(order.getFailureMessages()) + .build(); + } + + public Restaurant createOrderCommandToRestaurant(CreateOrderCommand createOrderCommand) { return Restaurant.builder() - .id(new RestaurantId(createOrderCommand.getRestaurantId())) - .products(createOrderCommand.getOrderItems().stream() + .id(new RestaurantId(createOrderCommand.restaurantId())) + .products(createOrderCommand.orderItems().stream() .map(orderItem -> - new Product(new ProductId(orderItem.getProductId()))) - .collect(Collectors.toList()) + new Product(new ProductId(orderItem.productId()))) + .toList() ) .build(); } public Order createOrderCommandToOrder(CreateOrderCommand createOrderCommand) { return Order.builder() - .customerId(new CustomerId(createOrderCommand.getCustomerId())) - .restaurantId(new RestaurantId(createOrderCommand.getRestaurantId())) - .deliveryAddress(orderAddressToStreetAddress(createOrderCommand.getOrderAddress())) - .price(new Money(createOrderCommand.getPrice())) - .items(orderItemsToOrderItemEntities(createOrderCommand.getOrderItems())) + .customerId(new CustomerId(createOrderCommand.customerId())) + .restaurantId(new RestaurantId(createOrderCommand.restaurantId())) + .deliveryAddress(orderAddressToStreetAddress(createOrderCommand.orderAddress())) + .price(new Money(createOrderCommand.price())) + .items(orderItemsToOrderItemEntities(createOrderCommand.orderItems())) .build(); } @@ -46,10 +57,10 @@ public class OrderDataMapper { return orderItems.stream() .map(orderItem -> OrderItem.builder() - .product(new Product(new ProductId(orderItem.getProductId()))) - .price(new Money(orderItem.getPrice())) - .quantity(orderItem.getQuantity()) - .subTotal(new Money(orderItem.getSubTotal())) + .product(new Product(new ProductId(orderItem.productId()))) + .price(new Money(orderItem.price())) + .quantity(orderItem.quantity()) + .subTotal(new Money(orderItem.subTotal())) .build()) .collect(Collectors.toList()); } @@ -57,9 +68,9 @@ public class OrderDataMapper { private StreetAddress orderAddressToStreetAddress(OrderAddress orderAddress) { return new StreetAddress( UUID.randomUUID(), - orderAddress.getStreet(), - orderAddress.getCity(), - orderAddress.getPostalCode() + orderAddress.street(), + orderAddress.city(), + orderAddress.postalCode() ); } diff --git a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/ports/output/repository/OrderRepository.java b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/ports/output/repository/OrderRepository.java index 9694940..9f6ae1d 100644 --- a/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/ports/output/repository/OrderRepository.java +++ b/order-service/order-domain/order-application-service/src/main/java/com/food/order/domain/ports/output/repository/OrderRepository.java @@ -1,6 +1,7 @@ package com.food.order.domain.ports.output.repository; import com.food.order.system.domain.entity.Order; +import com.food.order.system.domain.valueobject.TrackingId; import java.util.Optional; @@ -8,7 +9,7 @@ public interface OrderRepository { Order save(Order order); - Optional findByTrackingId(String trackingId); + Optional findByTrackingId(TrackingId trackingId); } diff --git a/order-service/order-domain/order-application-service/src/test/java/com/food/order/domain/OrderApplicationTest.java b/order-service/order-domain/order-application-service/src/test/java/com/food/order/domain/OrderApplicationTest.java new file mode 100644 index 0000000..2c30d9e --- /dev/null +++ b/order-service/order-domain/order-application-service/src/test/java/com/food/order/domain/OrderApplicationTest.java @@ -0,0 +1,200 @@ +package com.food.order.domain; + +import com.food.order.domain.dto.create.CreateOrderCommand; +import com.food.order.domain.dto.create.OrderAddress; +import com.food.order.domain.dto.create.OrderItem; +import com.food.order.domain.mapper.OrderDataMapper; +import com.food.order.domain.ports.input.service.OrderApplicationService; +import com.food.order.domain.ports.output.repository.CustomerRepository; +import com.food.order.domain.ports.output.repository.OrderRepository; +import com.food.order.domain.ports.output.repository.RestaurantRepository; +import com.food.order.domain.valueobject.*; +import com.food.order.system.domain.entity.Customer; +import com.food.order.system.domain.entity.Order; +import com.food.order.system.domain.entity.Product; +import com.food.order.system.domain.entity.Restaurant; +import com.food.order.system.domain.exception.OrderDomainException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SpringBootTest(classes = OrderTestConfiguration.class) +class OrderApplicationTest { + + @Autowired + private OrderApplicationService orderApplicationService; + + @Autowired + private OrderDataMapper orderDataMapper; + + @Autowired + private OrderRepository orderRepository; + + @Autowired + private CustomerRepository customerRepository; + + @Autowired + private RestaurantRepository restaurantRepository; + + private CreateOrderCommand createOrderCommand; + private CreateOrderCommand createOrderCommandWrongPrice; + private CreateOrderCommand createOrderCommandWrongProductPrice; + private final UUID CUSTOMER_ID = UUID.randomUUID(); + private final UUID RESTAURANT_ID = UUID.randomUUID(); + + private final Money PRODUCT_PRICE = new Money(BigDecimal.valueOf(50)); + private final UUID PRODUCT_ID = UUID.randomUUID(); + private final UUID ORDER_ID = UUID.randomUUID(); + private final BigDecimal PRICE = new BigDecimal("200.00"); + + @BeforeAll + public void init(){ + createOrderCommand = CreateOrderCommand.builder() + .customerId(CUSTOMER_ID) + .restaurantId(RESTAURANT_ID) + .orderAddress(OrderAddress.builder() + .street("street") + .city("city") + .postalCode("41780") + .build()) + .price(PRICE) + .orderItems(List.of( + OrderItem.builder() + .productId(PRODUCT_ID) + .price(new BigDecimal("50.00")) + .subTotal(new BigDecimal("50.00")) + .quantity(1) + .build(), + OrderItem.builder() + .productId(PRODUCT_ID) + .price(new BigDecimal("50.00")) + .subTotal(new BigDecimal("150.00")) + .quantity(3) + .build())) + .build(); + + createOrderCommandWrongPrice = CreateOrderCommand.builder() + .customerId(CUSTOMER_ID) + .restaurantId(RESTAURANT_ID) + .orderAddress(OrderAddress.builder() + .street("street") + .city("city") + .postalCode("41780") + .build()) + .price(PRICE) + .orderItems(List.of(OrderItem.builder() + .productId(PRODUCT_ID) + .price(new BigDecimal("50.00")) + .subTotal(new BigDecimal("100.00")) + .quantity(2) + .build(), + OrderItem.builder() + .productId(PRODUCT_ID) + .price(new BigDecimal("50.00")) + .subTotal(new BigDecimal("150.00")) + .quantity(3) + .build())) + .build(); + + createOrderCommandWrongProductPrice = CreateOrderCommand.builder() + .customerId(CUSTOMER_ID) + .restaurantId(RESTAURANT_ID) + .orderAddress(OrderAddress.builder() + .street("street") + .city("city") + .postalCode("41780") + .build()) + .price(new BigDecimal("210.00")) + .orderItems(List.of(OrderItem.builder() + .productId(PRODUCT_ID) + .price(new BigDecimal("60.00")) + .subTotal(new BigDecimal("60.00")) + .quantity(1) + .build(), + OrderItem.builder() + .productId(PRODUCT_ID) + .price(new BigDecimal("50.00")) + .subTotal(new BigDecimal("150.00")) + .quantity(3) + .build())) + .build(); + + Customer customer = new Customer(); + customer.setId(new CustomerId(CUSTOMER_ID)); + + Restaurant restaurant = Restaurant.builder() + .id(new RestaurantId(RESTAURANT_ID)) + .products(List.of( + new Product(new ProductId(PRODUCT_ID), "product-1", PRODUCT_PRICE), + new Product(new ProductId(UUID.randomUUID()), "product-2", new Money(BigDecimal.valueOf(50))) + )) + .isActive(Boolean.TRUE) + .build(); + + + Order order = orderDataMapper.createOrderCommandToOrder(createOrderCommand); + order.setId(new OrderId(ORDER_ID)); + + Mockito.when(customerRepository.findCustomer(CUSTOMER_ID)).thenReturn(Optional.of(customer)); + Mockito.when(restaurantRepository.findRestaurantInformation + (orderDataMapper.createOrderCommandToRestaurant(createOrderCommand))) + .thenReturn(Optional.of(restaurant)); + Mockito.when(orderRepository.save(Mockito.any(Order.class))).thenReturn(order); + } + + + @Test + void testCreateOrder(){ + var response = orderApplicationService.createOrder(createOrderCommand); + assertEquals(OrderStatus.PENDING, response.orderStatus()); + assertEquals("Order created successfully", response.message()); + assertNotNull(response.orderTrackingId()); + } + + @Test + void testCreateOrderWrongPrice(){ + OrderDomainException exception = Assertions.assertThrows(OrderDomainException.class, + () -> orderApplicationService.createOrder(createOrderCommandWrongPrice)); + assertEquals("Order total price is not equal to the sum of order items prices", exception.getMessage()); + } + + @Test + void testCreateOrderWrongProductPrice(){ + OrderDomainException exception = Assertions.assertThrows(OrderDomainException.class, + () -> orderApplicationService.createOrder(createOrderCommandWrongProductPrice)); + assertEquals("Order item price is not valid", exception.getMessage()); + } + + @Test + void testCreateOrderWithPassiveRestaurant(){ + Restaurant restaurant = Restaurant.builder() + .id(new RestaurantId(RESTAURANT_ID)) + .products(List.of( + new Product(new ProductId(PRODUCT_ID), "product-1", PRODUCT_PRICE), + new Product(new ProductId(UUID.randomUUID()), "product-2", new Money(BigDecimal.valueOf(50))) + )) + .isActive(Boolean.FALSE) + .build(); + + Mockito.when(restaurantRepository.findRestaurantInformation + (orderDataMapper.createOrderCommandToRestaurant(createOrderCommand))) + .thenReturn(Optional.of(restaurant)); + OrderDomainException exception = Assertions.assertThrows(OrderDomainException.class, + () -> orderApplicationService.createOrder(createOrderCommand)); + assertEquals("Restaurant is not active, please try again later. Restaurant id: "+ restaurant.getId(), exception.getMessage()); + } + +} diff --git a/order-service/order-domain/order-application-service/src/test/java/com/food/order/domain/OrderTestConfiguration.java b/order-service/order-domain/order-application-service/src/test/java/com/food/order/domain/OrderTestConfiguration.java new file mode 100644 index 0000000..3390cf1 --- /dev/null +++ b/order-service/order-domain/order-application-service/src/test/java/com/food/order/domain/OrderTestConfiguration.java @@ -0,0 +1,56 @@ +package com.food.order.domain; + +import com.food.order.domain.ports.output.message.publisher.payment.OrderCancelledPaymentRequestMessagePublisher; +import com.food.order.domain.ports.output.message.publisher.payment.OrderCreatedPaymentRequestMessagePublisher; +import com.food.order.domain.ports.output.message.publisher.restaurantapproval.OrderPaidRestaurantRequestMessagePublisher; +import com.food.order.domain.ports.output.repository.CustomerRepository; +import com.food.order.domain.ports.output.repository.OrderRepository; +import com.food.order.domain.ports.output.repository.RestaurantRepository; +import com.food.order.system.domain.service.OrderDomainService; +import com.food.order.system.domain.service.impl.OrderDomainServiceImpl; +import org.mockito.Mockito; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication(scanBasePackages = "com.food.order.domain") +public class OrderTestConfiguration { + + @Bean + public OrderCreatedPaymentRequestMessagePublisher orderCreatedPaymentRequestMessagePublisher() { + return Mockito.mock(OrderCreatedPaymentRequestMessagePublisher.class); + } + + @Bean + public OrderCancelledPaymentRequestMessagePublisher orderCancelledPaymentRequestMessagePublisher() { + return Mockito.mock(OrderCancelledPaymentRequestMessagePublisher.class); + } + + @Bean + public OrderPaidRestaurantRequestMessagePublisher orderPaidRestaurantRequestMessagePublisher() { + return Mockito.mock(OrderPaidRestaurantRequestMessagePublisher.class); + } + + @Bean + public OrderRepository orderRepository() { + return Mockito.mock(OrderRepository.class); + } + + @Bean + public CustomerRepository customerRepository() { + return Mockito.mock(CustomerRepository.class); + } + + @Bean + public RestaurantRepository restaurantRepository() { + return Mockito.mock(RestaurantRepository.class); + } + + + @Bean + public OrderDomainService orderDomainService() { + return new OrderDomainServiceImpl(); + } + + + +} diff --git a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/OrderItem.java b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/OrderItem.java index 50dbd91..f9780e6 100644 --- a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/OrderItem.java +++ b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/entity/OrderItem.java @@ -20,7 +20,7 @@ public class OrderItem extends BaseEntity { boolean isPriceValid() { return price.isGreaterThanZero() && - price.equals(product.getPrice()) && + price.getAmount().compareTo(product.getPrice().getAmount()) == 0 && price.multiply(quantity).equals(subTotal); } diff --git a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/exception/OrderNotFoundException.java b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/exception/OrderNotFoundException.java new file mode 100644 index 0000000..4b89b9d --- /dev/null +++ b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/exception/OrderNotFoundException.java @@ -0,0 +1,14 @@ +package com.food.order.system.domain.exception; + +import com.food.order.domain.exception.DomainException; + +public class OrderNotFoundException extends DomainException { + + public OrderNotFoundException(String message) { + super(message); + } + + public OrderNotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/service/impl/OrderDomainServiceImpl.java b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/service/impl/OrderDomainServiceImpl.java index 901e4fc..0f9e55c 100644 --- a/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/service/impl/OrderDomainServiceImpl.java +++ b/order-service/order-domain/order-core-domain/src/main/java/com/food/order/system/domain/service/impl/OrderDomainServiceImpl.java @@ -41,7 +41,7 @@ public class OrderDomainServiceImpl implements OrderDomainService { private void validateRestaurant(Restaurant restaurant) { if (Boolean.FALSE.equals(restaurant.isActive())) { throw new OrderDomainException("Restaurant is not active, please try again later. " + - "Restaurant id: {} " + restaurant.getId()); + "Restaurant id: " + restaurant.getId()); } } diff --git a/pom.xml b/pom.xml index fa6d9b9..fb3ce3a 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,8 @@ order-service common + infrastructure + infrastructure/kafka @@ -23,6 +25,10 @@ 3.9.0 + 4.5.1 + 2.8.2 + 7.0.1 + 1.11.0 @@ -52,6 +58,31 @@ ${project.version} + + + com.food.order + kafka-producer + 1.0-SNAPSHOT + + + + com.food.order + kafka-consumer + 1.0-SNAPSHOT + + + + com.food.order + kafka-model + 1.0-SNAPSHOT + + + + com.food.order + kafka-config + 1.0-SNAPSHOT + + com.food.order order-data-access @@ -70,6 +101,12 @@ ${project.version} + + org.mockito + mockito-core + ${mockito.version} + test +