diff --git a/sge-backend/src/main/java/com/sgs/config/GraphQLScalarConfig.java b/sge-backend/src/main/java/com/sgs/config/GraphQLScalarConfig.java new file mode 100644 index 0000000..0cc9aa5 --- /dev/null +++ b/sge-backend/src/main/java/com/sgs/config/GraphQLScalarConfig.java @@ -0,0 +1,15 @@ +package com.sgs.config; + +import com.sgs.graphql.scalar.EmissionSourceMapScalar; +import graphql.schema.GraphQLScalarType; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class GraphQLScalarConfig { + + @Bean + public GraphQLScalarType emissionSourceMapScalar() { + return EmissionSourceMapScalar.EmissionSourceMap; + } +} diff --git a/sge-backend/src/main/java/com/sgs/graphql/scalar/EmissionSourceMapScalar.java b/sge-backend/src/main/java/com/sgs/graphql/scalar/EmissionSourceMapScalar.java new file mode 100644 index 0000000..088cfff --- /dev/null +++ b/sge-backend/src/main/java/com/sgs/graphql/scalar/EmissionSourceMapScalar.java @@ -0,0 +1,79 @@ +package com.sgs.graphql.scalar; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import graphql.language.StringValue; +import graphql.schema.*; + +import java.util.Map; +import java.util.HashMap; + +public class EmissionSourceMapScalar { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public static final GraphQLScalarType EmissionSourceMap = GraphQLScalarType.newScalar() + .name("EmissionSourceMap") + .description("A custom scalar that represents a map of emission sources with their percentages") + .coercing(new Coercing, String>() { + + @Override + public String serialize(Object dataFetcherResult) throws CoercingSerializeException { + if (dataFetcherResult == null) { + return null; + } + try { + if (dataFetcherResult instanceof String) { + return (String) dataFetcherResult; + } + return objectMapper.writeValueAsString(dataFetcherResult); + } catch (Exception e) { + throw new CoercingSerializeException("Unable to serialize EmissionSourceMap", e); + } + } + + @Override + public Map parseValue(Object input) throws CoercingParseValueException { + if (input == null) { + return new HashMap<>(); + } + try { + if (input instanceof String) { + String str = (String) input; + if (str.trim().isEmpty()) { + return new HashMap<>(); + } + return objectMapper.readValue(str, new TypeReference>() {}); + } + if (input instanceof Map) { + return (Map) input; + } + return objectMapper.readValue(input.toString(), new TypeReference>() {}); + } catch (Exception e) { + System.err.println("Error parsing EmissionSourceMap: " + e.getMessage()); + return new HashMap<>(); + } + } + + @Override + public Map parseLiteral(Object input) throws CoercingParseLiteralException { + if (input == null) { + return new HashMap<>(); + } + if (input instanceof StringValue) { + try { + String value = ((StringValue) input).getValue(); + if (value.trim().isEmpty()) { + return new HashMap<>(); + } + return objectMapper.readValue(value, new TypeReference>() {}); + } catch (Exception e) { + System.err.println("Error parsing EmissionSourceMap literal: " + e.getMessage()); + return new HashMap<>(); + } + } + return new HashMap<>(); + } + }) + .build(); +} diff --git a/sge-backend/src/main/resources/application-docker.properties b/sge-backend/src/main/resources/application-docker.properties new file mode 100644 index 0000000..c480ac6 --- /dev/null +++ b/sge-backend/src/main/resources/application-docker.properties @@ -0,0 +1,34 @@ +# Docker-specific configuration +spring.datasource.url=jdbc:postgresql://database:5432/sge +spring.datasource.username=sge +spring.datasource.password=147 + +spring.jpa.hibernate.ddl-auto=update +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.properties.hibernate.format_sql=true +spring.jpa.properties.hibernate.generate_statistics=false +spring.jpa.properties.hibernate.globally_quoted_identifiers=true + +server.port=8080 +graphql.servlet.mapping=/api/v1/graphql +security.jwt.token.secret-key=secret + +app.survey.base-url=http://localhost.com + +# RabbitMQ Configuration for Docker +spring.rabbitmq.host=rabbitmq +spring.rabbitmq.port=5672 +spring.rabbitmq.username=guest +spring.rabbitmq.password=guest +spring.rabbitmq.virtual-host=/ +spring.rabbitmq.connection-timeout=20000 +spring.rabbitmq.template.retry.enabled=true +spring.rabbitmq.template.retry.max-attempts=3 +spring.rabbitmq.template.retry.initial-interval=1000ms + +# Additional connection resilience +spring.rabbitmq.requested-heartbeat=30s +spring.rabbitmq.publisher-confirm-type=correlated +spring.rabbitmq.publisher-returns=true + +logging.level.org.springframework.amqp=DEBUG diff --git a/sge-backend/src/main/resources/application.properties b/sge-backend/src/main/resources/application.properties index b82dd6c..32c28b9 100644 --- a/sge-backend/src/main/resources/application.properties +++ b/sge-backend/src/main/resources/application.properties @@ -17,14 +17,16 @@ security.jwt.token.secret-key=secret app.survey.base-url=http://localhost.com -spring.rabbitmq.host=188.132.198.145 -spring.rabbitmq.port=5672 -spring.rabbitmq.username=testuser -spring.rabbitmq.password=JGasF24561AZv2894De -# spring.rabbitmq.host=localhost +# spring.rabbitmq.host=188.132.198.145 # spring.rabbitmq.port=5672 -# spring.rabbitmq.username=guest -# spring.rabbitmq.password=guest +# spring.rabbitmq.username=testuser +# spring.rabbitmq.password=JGasF24561AZv2894De + +spring.rabbitmq.host=rabbitmq +#spring.rabbitmq.host=localhost +spring.rabbitmq.port=5672 +spring.rabbitmq.username=guest +spring.rabbitmq.password=guest spring.rabbitmq.virtual-host=/ spring.rabbitmq.connection-timeout=20000 spring.rabbitmq.template.retry.enabled=true