diff --git a/deploy/docker/docker-compose.yml b/deploy/docker/docker-compose.yml index 577f93d8..b3eb9c45 100755 --- a/deploy/docker/docker-compose.yml +++ b/deploy/docker/docker-compose.yml @@ -177,6 +177,7 @@ services: postgresdb: container_name: postgresdb image: 'postgres:14' + command: ["postgres", "-c", "max_connections=500"] environment: POSTGRES_USER: admin POSTGRES_PASSWORD: crapisecretpassword diff --git a/deploy/helm/templates/postgres/statefulset.yaml b/deploy/helm/templates/postgres/statefulset.yaml index a2bd5462..46d6602d 100644 --- a/deploy/helm/templates/postgres/statefulset.yaml +++ b/deploy/helm/templates/postgres/statefulset.yaml @@ -23,12 +23,13 @@ spec: - name: {{ .Values.postgresdb.name }} image: {{ .Values.postgresdb.image }}:{{ .Values.postgresdb.version }} imagePullPolicy: {{ .Values.postgresdb.imagePullPolicy }} + args: ["-c", "max_connections=500"] ports: - containerPort: {{ .Values.postgresdb.port }} envFrom: - configMapRef: name: {{ .Values.postgresdb.config.name }} - + volumeMounts: - mountPath: /var/lib/postgresql/data name: postgres-data diff --git a/deploy/k8s/base/postgres/statefulset.yaml b/deploy/k8s/base/postgres/statefulset.yaml index 69fcc487..909bae5e 100644 --- a/deploy/k8s/base/postgres/statefulset.yaml +++ b/deploy/k8s/base/postgres/statefulset.yaml @@ -16,13 +16,14 @@ spec: containers: - name: postgres image: postgres:14 + args: ["-c", "max_connections=500"] imagePullPolicy: "IfNotPresent" ports: - containerPort: 5432 envFrom: - configMapRef: name: postgres-config - + volumeMounts: - mountPath: /var/lib/postgresql/data name: postgres-data diff --git a/openapi-spec/openapi-spec.json b/openapi-spec/openapi-spec.json index cb774075..4c28d3b9 100644 --- a/openapi-spec/openapi-spec.json +++ b/openapi-spec/openapi-spec.json @@ -1944,6 +1944,25 @@ "security" : [ { "bearerAuth" : [ ] } ], + "parameters" : [ { + "name" : "limit", + "in" : "query", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "example" : 30 + } + }, { + "name" : "offset", + "in" : "query", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "example" : 0 + } + } ], "responses" : { "200" : { "content" : { diff --git a/postman_collections/crAPI.postman_collection.json b/postman_collections/crAPI.postman_collection.json index 707898b5..057bf401 100644 --- a/postman_collections/crAPI.postman_collection.json +++ b/postman_collections/crAPI.postman_collection.json @@ -2421,7 +2421,7 @@ } ], "url": { - "raw": "{{url}}/workshop/api/shop/orders/all", + "raw": "{{url}}/workshop/api/shop/orders/all?limit=30&offset=0", "host": [ "{{url}}" ], @@ -2431,6 +2431,16 @@ "shop", "orders", "all" + ], + "query": [ + { + "key": "limit", + "value": "30" + }, + { + "key": "offset", + "value": "0" + } ] } }, diff --git a/services/identity/src/main/resources/application.properties b/services/identity/src/main/resources/application.properties index fb846ec8..352de51b 100644 --- a/services/identity/src/main/resources/application.properties +++ b/services/identity/src/main/resources/application.properties @@ -3,6 +3,9 @@ logging.level.org.springframework.web=DEBUG spring.datasource.url= jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME} spring.datasource.username=${DB_USER} spring.datasource.password=${DB_PASSWORD} +spring.datasource.max-active=100 +spring.datasource.max-idle=8 +spring.datasource.min-idle=8 spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect diff --git a/services/workshop/crapi/mechanic/views.py b/services/workshop/crapi/mechanic/views.py index 23c816e7..782df179 100644 --- a/services/workshop/crapi/mechanic/views.py +++ b/services/workshop/crapi/mechanic/views.py @@ -23,15 +23,13 @@ from rest_framework.response import Response from rest_framework.views import APIView from django.db import models +from crapi_site import settings from utils.jwt import jwt_auth_required from utils import messages from crapi.user.models import User, Vehicle, UserDetails from utils.logging import log_error from .models import Mechanic, ServiceRequest from .serializers import MechanicSerializer, ServiceRequestSerializer, ReceiveReportSerializer, SignUpSerializer -DEFAULT_LIMIT = 10 -DEFAULT_OFFSET = 0 -MAX_LIMIT = 100 class SignUpView(APIView): """ @@ -206,8 +204,8 @@ def get(self, request, user=None): list of service request object and 200 status if no error message and corresponding status if error """ - limit = request.GET.get('limit', str(DEFAULT_LIMIT)) - offset = request.GET.get('offset', str(DEFAULT_OFFSET)) + limit = request.GET.get('limit', str(settings.DEFAULT_LIMIT)) + offset = request.GET.get('offset', str(settings.DEFAULT_OFFSET)) if not limit.isdigit() or not offset.isdigit(): return Response( {'message': messages.INVALID_LIMIT_OR_OFFSET}, @@ -215,12 +213,12 @@ def get(self, request, user=None): ) limit = int(limit) offset = int(offset) - if limit > MAX_LIMIT: + if limit > settings.MAX_LIMIT: limit = 100 if limit < 0: - limit = DEFAULT_LIMIT + limit = settings.DEFAULT_LIMIT if offset < 0: - offset = DEFAULT_OFFSET + offset = settings.DEFAULT_OFFSET service_requests = ServiceRequest.objects.filter(mechanic__user=user).order_by('id')[offset:offset+limit] serializer = ServiceRequestSerializer(service_requests, many=True) response_data = dict( diff --git a/services/workshop/crapi/shop/views.py b/services/workshop/crapi/shop/views.py index 9c50e41b..ec79bee3 100644 --- a/services/workshop/crapi/shop/views.py +++ b/services/workshop/crapi/shop/views.py @@ -241,7 +241,22 @@ def get(self, request, user=None): list of order object and 200 status if no error message and corresponding status if error """ - orders = Order.objects.filter(user=user) + limit = request.GET.get('limit', str(settings.DEFAULT_LIMIT)) + offset = request.GET.get('offset', str(settings.DEFAULT_OFFSET)) + if not limit.isdigit() or not offset.isdigit(): + return Response( + {'message': messages.INVALID_LIMIT_OR_OFFSET}, + status=status.HTTP_400_BAD_REQUEST + ) + limit = int(limit) + offset = int(offset) + if limit > settings.MAX_LIMIT: + limit = 100 + if limit < 0: + limit = settings.DEFAULT_LIMIT + if offset < 0: + offset = settings.DEFAULT_OFFSET + orders = Order.objects.filter(user=user).order_by('-id')[offset:offset+limit] serializer = OrderSerializer(orders, many=True) response_data = dict( orders=serializer.data @@ -329,14 +344,21 @@ def post(self, request, user=None): if not serializer.is_valid(): log_error(request.path, request.data, 400, serializer.errors) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - + row = None with connection.cursor() as cursor: - cursor.execute("SELECT coupon_code from applied_coupon WHERE user_id = "\ - + str(user.id)\ - + " AND coupon_code = '"\ - + coupon_request_body['coupon_code']\ - + "'") - row = cursor.fetchall() + try: + cursor.execute("SELECT coupon_code from applied_coupon WHERE user_id = "\ + + str(user.id)\ + + " AND coupon_code = '"\ + + coupon_request_body['coupon_code']\ + + "'") + row = cursor.fetchall() + except Exception as e: + log_error(request.path, request.data, 500, e) + return Response( + {'message': e}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR + ) if row and row != None: return Response( diff --git a/services/workshop/crapi/user/views.py b/services/workshop/crapi/user/views.py index 43c71946..a3c99c52 100644 --- a/services/workshop/crapi/user/views.py +++ b/services/workshop/crapi/user/views.py @@ -23,14 +23,12 @@ from rest_framework.views import APIView from crapi.user.serializers import UserDetailsSerializer from crapi.user.models import User, UserDetails +from crapi_site import settings from utils.jwt import jwt_auth_required from utils import messages from utils.logging import log_error logger = logging.getLogger() -DEFAULT_LIMIT = 30 -DEFAULT_OFFSET = 0 -MAX_LIMIT = 100 class AdminUserView(APIView): """ @@ -49,21 +47,21 @@ def get(self, request, user=None): user details and 200 status if no error message and corresponding status if error """ - limit = request.GET.get('limit', str(DEFAULT_LIMIT)) - offset = request.GET.get('offset', str(DEFAULT_OFFSET)) + limit = request.GET.get('limit', str(settings.DEFAULT_LIMIT)) + offset = request.GET.get('offset', str(settings.DEFAULT_OFFSET)) if not limit.isdigit() or not offset.isdigit(): return Response( - {'message': messages.INVALID_LIMIT_OFFSET}, + {'message': messages.INVALID_LIMIT_OR_OFFSET}, status=status.HTTP_400_BAD_REQUEST ) limit = int(limit) offset = int(offset) - if limit > MAX_LIMIT: - limit = MAX_LIMIT - if int(limit) < 0: - limit = DEFAULT_LIMIT + if limit > settings.MAX_LIMIT: + limit = 100 + if limit < 0: + limit = settings.DEFAULT_LIMIT if offset < 0: - offset = DEFAULT_OFFSET + offset = settings.DEFAULT_OFFSET # Sort by id userdetails = UserDetails.objects.all().order_by('id')[offset:offset+limit] if not userdetails: diff --git a/services/workshop/crapi_site/settings.py b/services/workshop/crapi_site/settings.py index 73f04479..c9dfd170 100644 --- a/services/workshop/crapi_site/settings.py +++ b/services/workshop/crapi_site/settings.py @@ -28,6 +28,9 @@ from django.core.exceptions import ImproperlyConfigured +DEFAULT_LIMIT = 10 +DEFAULT_OFFSET = 0 +MAX_LIMIT = 100 def get_env_value(env_variable): try: @@ -173,6 +176,7 @@ def get_env_value(env_variable): 'NAME': 'test_crapi', 'USER': get_env_value('DB_USER'), }, + 'CONN_MAX_AGE': 60, }, 'mongodb': { 'ENGINE': 'djongo', diff --git a/services/workshop/requirements.txt b/services/workshop/requirements.txt index 68110067..99e60605 100644 --- a/services/workshop/requirements.txt +++ b/services/workshop/requirements.txt @@ -10,7 +10,7 @@ django-health-check==3.17.0 djangorestframework==3.14.0 django-sslserver==0.22 djongo==1.3.6 -psycopg2==2.9.6 +psycopg2==2.9.9 PyJWT==2.7.0 pymongo==3.12.3 pyOpenSSL==23.1.1 diff --git a/services/workshop/utils/messages.py b/services/workshop/utils/messages.py index 65f69d77..3b3d83fd 100644 --- a/services/workshop/utils/messages.py +++ b/services/workshop/utils/messages.py @@ -41,5 +41,5 @@ INVALID_REPORT_ID = "Please enter a valid report_id value." REPORT_DOES_NOT_EXIST = "The Report does not exist for given report_id." COULD_NOT_CONNECT = "Could not connect to mechanic api." -INVALID_LIMIT_OFFSET = "Param limit and offset values should be integers." +INVALID_LIMIT_OR_OFFSET = "Param limit and offset values should be integers." NO_USER_DETAILS = "No user details found." \ No newline at end of file