diff --git a/src/main/java/org/etsi/osl/tmf/configuration/SwaggerDocumentationConfig.java b/src/main/java/org/etsi/osl/tmf/configuration/SwaggerDocumentationConfig.java
index ea00cc6ac4e3ab952b6e0e4c683e40a62f738e70..239be290194fb3da0c4bd4c908d742c492c08ef9 100644
--- a/src/main/java/org/etsi/osl/tmf/configuration/SwaggerDocumentationConfig.java
+++ b/src/main/java/org/etsi/osl/tmf/configuration/SwaggerDocumentationConfig.java
@@ -728,7 +728,41 @@ public class SwaggerDocumentationConfig {
 	    		.build();
 	
 	}
-	
+	/**
+	 * TMF 674 Geographic Site Management
+	 * @return
+	 */
+
+
+	@Bean
+	public OpenApiCustomizer gsm674OpenAPI() {
+		return openApi -> openApi
+				.specVersion( SpecVersion.V30 ).addSecurityItem(new SecurityRequirement().addList("security_auth"))
+				.info(new Info()
+						.title("TMF 674 Geographic Site Management")
+						.description("## TMF API Reference: TMF674 - Geographic Site Management  ")
+						.version("4.0.0")
+						.license(new License()
+								.name("Apache 2.0")
+								.url("http://openslice.io")))
+				.externalDocs(new ExternalDocumentation()
+						.description("TMF API Tables")
+						.url("https://www.tmforum.org/oda/open-apis/table"));
+	}
+
+	@Bean
+	public GroupedOpenApi gsm674(){
+
+		SpringDocUtils.getConfig().replaceWithClass(java.time.LocalDate.class, java.sql.Date.class);
+		SpringDocUtils.getConfig().replaceWithClass(java.time.OffsetDateTime.class, java.util.Date.class);
+
+		return GroupedOpenApi.builder()
+				.group("tmf-api-674-Geographic Site Management-v4.0.0")
+				.addOpenApiCustomizer( this.gsm674OpenAPI() )
+				.packagesToScan("org.etsi.osl.tmf.gsm674.api")
+				.build();
+
+	}
 
 
 	/**
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/api/ApiUtil.java b/src/main/java/org/etsi/osl/tmf/gsm674/api/ApiUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..6683c4761959adb4763b8e0a613fb47364af1c8e
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/api/ApiUtil.java
@@ -0,0 +1,19 @@
+package org.etsi.osl.tmf.gsm674.api;
+
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.web.context.request.NativeWebRequest;
+
+import java.io.IOException;
+
+public class ApiUtil {
+    public static void setExampleResponse(NativeWebRequest req, String contentType, String example) {
+        try {
+            HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class);
+            res.setCharacterEncoding("UTF-8");
+            res.addHeader("Content-Type", contentType);
+            res.getWriter().print(example);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/api/Generated.java b/src/main/java/org/etsi/osl/tmf/gsm674/api/Generated.java
new file mode 100644
index 0000000000000000000000000000000000000000..92fbaec5167449362f97923c72969d6c4f3f655f
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/api/Generated.java
@@ -0,0 +1,16 @@
+package org.etsi.osl.tmf.gsm674.api;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Documented
+@Retention(RUNTIME)
+@Target({TYPE, METHOD, CONSTRUCTOR})
+public @interface Generated {
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/api/GeographicSiteManagementApi.java b/src/main/java/org/etsi/osl/tmf/gsm674/api/GeographicSiteManagementApi.java
new file mode 100644
index 0000000000000000000000000000000000000000..380afa76449809e13532ca81a60a794e04fb1925
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/api/GeographicSiteManagementApi.java
@@ -0,0 +1,134 @@
+package org.etsi.osl.tmf.gsm674.api;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
+
+import org.etsi.osl.tmf.gsm674.model.GeographicSite;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.List;
+import java.util.Optional;
+
+@Generated
+public interface GeographicSiteManagementApi {
+    Logger log = LoggerFactory.getLogger(GeographicSiteManagementApi.class);
+
+    default Optional<ObjectMapper> getObjectMapper() {
+        return Optional.empty();
+    }
+
+    default Optional<HttpServletRequest> getRequest() {
+        return Optional.empty();
+    }
+
+    default Optional<String> getAcceptHeader() {
+        return getRequest().map(r -> r.getHeader("Accept"));
+    }
+
+    @Operation(summary = "Creates a 'GeographicSite'", operationId = "createGeographicSite", description = "", tags={ "geographicSite", })
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "400", description = "Created" ),
+            @ApiResponse(responseCode = "400", description = "Bad Request" ),
+            @ApiResponse(responseCode = "401", description = "Unauthorized" ),
+            @ApiResponse(responseCode = "403", description = "Forbidden" ),
+            @ApiResponse(responseCode = "404", description = "Not Found" ),
+            @ApiResponse(responseCode = "405", description = "Method Not allowed" ),
+            @ApiResponse(responseCode = "409", description = "Conflict" ),
+            @ApiResponse(responseCode = "500", description = "Internal Server Error" ) })
+    @RequestMapping(value = "/geographicSite",
+            produces = { "application/json" },
+            consumes = { "application/json" },
+            method = RequestMethod.POST)
+    default ResponseEntity<GeographicSite> createGeographicSite(@Parameter(description = "The geographic site to be created" ,required=true )  @Valid @RequestBody GeographicSite geographicSite) {
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    }
+
+    @Operation(summary = "Deletes a 'GeographicSite' by Id", operationId = "deleteGeographicSite", description = "", tags={ "GeographicSite", })
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "204", description = "Deleted" ),
+            @ApiResponse(responseCode = "400", description = "Bad Request" ),
+            @ApiResponse(responseCode = "401", description = "Unauthorized" ),
+            @ApiResponse(responseCode = "403", description = "Forbidden" ),
+            @ApiResponse(responseCode = "404", description = "Not Found" ),
+            @ApiResponse(responseCode = "405", description = "Method Not allowed" ),
+            @ApiResponse(responseCode = "409", description = "Conflict" ),
+            @ApiResponse(responseCode = "500", description = "Internal Server Error" ) })
+    @RequestMapping(value = "/geographicSite/{id}",
+            produces = { "application/json" },
+            method = RequestMethod.DELETE)
+    default ResponseEntity<Void> deleteGeographicSite(@Parameter(description = "Identifier of the Geographic site",required=true) @PathVariable("id") String id) {
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    }
+
+
+    @Operation(summary = "List or find 'GeographicSite' objects", operationId = "listGeographicSite", description = "" , tags={ "GeographicSite", })
+    @ApiResponses(value = {
+            @ApiResponse(responseCode ="200", description = "Ok" ),
+            @ApiResponse(responseCode = "400", description = "Bad Request" ),
+            @ApiResponse(responseCode = "401", description = "Unauthorized" ),
+            @ApiResponse(responseCode = "403", description = "Forbidden" ),
+            @ApiResponse(responseCode = "404", description = "Not Found" ),
+            @ApiResponse(responseCode = "405", description = "Method Not allowed" ),
+            @ApiResponse(responseCode = "409", description = "Conflict" ),
+            @ApiResponse(responseCode = "500", description = "Internal Server Error" ) })
+    @RequestMapping(value = "/geographicSite",
+            produces = { "application/json" },
+            method = RequestMethod.GET)
+    default ResponseEntity<List<GeographicSite>> listGeographicSite() {
+               return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    }
+
+
+    @Operation(summary = "Updates partially a 'GeographicSite' by Id", operationId = "patchGeographicSite", description = "", tags={ "GeographicSite", })
+    @ApiResponses(value = {
+            @ApiResponse(responseCode ="200", description = "Updated" ),
+            @ApiResponse(responseCode = "400", description = "Bad Request" ),
+            @ApiResponse(responseCode = "401", description = "Unauthorized" ),
+            @ApiResponse(responseCode = "403", description = "Forbidden" ),
+            @ApiResponse(responseCode = "404", description = "Not Found" ),
+            @ApiResponse(responseCode = "405", description = "Method Not allowed" ),
+            @ApiResponse(responseCode = "409", description = "Conflict" ),
+            @ApiResponse(responseCode = "500", description = "Internal Server Error" ) })
+    @RequestMapping(value = "/geographicSite/{id}",
+            produces = { "application/json" },
+            consumes = { "application/json" },
+            method = RequestMethod.PATCH)
+    default ResponseEntity<GeographicSite> patchGeographicalSite(@Parameter(description = "Identifier of the Geographic site",required=true) @PathVariable("id") String id,@Parameter(description = "The Service Level Specification to be updated" ,required=true )  @Valid @RequestBody GeographicSite geographicSite) {
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    }
+
+
+    @Operation(summary = "Retrieves a 'GeographicSite' by Id", operationId = "retrieveGeographicSite", description = "" , tags={ "GeographicSite", })
+    @ApiResponses(value = {
+            @ApiResponse(responseCode ="200", description = "Ok" ),
+            @ApiResponse(responseCode = "400", description = "Bad Request" ),
+            @ApiResponse(responseCode = "401", description = "Unauthorized" ),
+            @ApiResponse(responseCode = "403", description = "Forbidden" ),
+            @ApiResponse(responseCode = "404", description = "Not Found" ),
+            @ApiResponse(responseCode = "405", description = "Method Not allowed" ),
+            @ApiResponse(responseCode = "409", description = "Conflict" ),
+            @ApiResponse(responseCode = "500", description = "Internal Server Error" ) })
+    @RequestMapping(value = "/geographicSite/{id}",
+            produces = { "application/json" },
+            method = RequestMethod.GET)
+    default ResponseEntity<GeographicSite> retrieveGeographicSite(@Parameter(description = "Identifier of the Geographic site",required=true) @PathVariable("id") String id) {
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    }
+
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/api/GeographicSiteManagementApiController.java b/src/main/java/org/etsi/osl/tmf/gsm674/api/GeographicSiteManagementApiController.java
new file mode 100644
index 0000000000000000000000000000000000000000..475eaede144dd839288630f5c63daf275e08769e
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/api/GeographicSiteManagementApiController.java
@@ -0,0 +1,106 @@
+package org.etsi.osl.tmf.gsm674.api;
+
+import io.swagger.v3.oas.annotations.Parameter;
+import jakarta.validation.Valid;
+import org.etsi.osl.tmf.gsm674.model.GeographicSite;
+import org.etsi.osl.tmf.gsm674.reposervices.GeographicSiteManagementService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.List;
+
+@Controller
+@RequestMapping("/geographicSiteManagement/v5/")
+public class GeographicSiteManagementApiController implements GeographicSiteManagementApi{
+
+    private static final String COULD_NOT_SERIALIZE="Couldn't serialize response for content type application/json";
+    private final GeographicSiteManagementService geographicSiteManagementService;
+
+    @Autowired
+    public GeographicSiteManagementApiController(GeographicSiteManagementService geographicSiteManagementService) {
+        this.geographicSiteManagementService = geographicSiteManagementService;
+    }
+
+    @PreAuthorize("hasAnyAuthority('ROLE_USER')" )
+    @Override
+    public ResponseEntity<List<GeographicSite>> listGeographicSite() {
+
+
+        try {
+            return new ResponseEntity<>(geographicSiteManagementService.findAllGeographicSites(), HttpStatus.OK);
+
+        } catch (Exception e) {
+            log.error(COULD_NOT_SERIALIZE, e);
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    @PreAuthorize("hasAnyAuthority('ROLE_USER')" )
+    @Override
+    public ResponseEntity<GeographicSite> retrieveGeographicSite(@PathVariable("id") String id) {
+
+
+        try {
+            return new ResponseEntity<>(geographicSiteManagementService.findGeographicSiteByUUID(id), HttpStatus.OK);
+
+        } catch (Exception e) {
+            log.error(COULD_NOT_SERIALIZE, e);
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    @PreAuthorize("hasAnyAuthority('ROLE_USER')" )
+    @Override
+    public ResponseEntity<GeographicSite> createGeographicSite(
+            @Parameter(description = "The geographic site to be created", required = true) @Valid @RequestBody GeographicSite geographicSite
+    ) {
+
+        try {
+
+            GeographicSite c = geographicSiteManagementService.createGeographicSite(geographicSite);
+
+            return new ResponseEntity<>(c, HttpStatus.OK);
+
+
+        } catch (Exception e) {
+            log.error(COULD_NOT_SERIALIZE, e);
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    @PreAuthorize("hasAnyAuthority('ROLE_USER')" )
+    @Override
+    public ResponseEntity<Void> deleteGeographicSite(
+            @Parameter(description = "Identifier of the geographic site", required = true) @PathVariable("id") String id) {
+
+        try {
+            return new ResponseEntity<>(geographicSiteManagementService.deleteGeographicSiteById(id), HttpStatus.OK);
+        }catch (Exception e) {
+            log.error(COULD_NOT_SERIALIZE, e);
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+
+    }
+
+
+    @PreAuthorize("hasAnyAuthority('ROLE_USER')" )
+    @Override
+    public ResponseEntity<GeographicSite> patchGeographicalSite(
+            @Parameter(description = "Identifier of the ServiceOrder", required = true) @PathVariable("id") String id,
+            @Parameter(description = "The ServiceOrder to be updated", required = true) @Valid @RequestBody GeographicSite geographicSite) {
+        try{
+        GeographicSite c = geographicSiteManagementService.updateGeographicSite(id, geographicSite);
+
+        return new ResponseEntity<>(c, HttpStatus.OK);
+        }catch (Exception e){
+            log.error(COULD_NOT_SERIALIZE, e);
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/api/HubApi.java b/src/main/java/org/etsi/osl/tmf/gsm674/api/HubApi.java
new file mode 100644
index 0000000000000000000000000000000000000000..dbd091644d5dd2a02923392f918548b62ae7e980
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/api/HubApi.java
@@ -0,0 +1,131 @@
+package org.etsi.osl.tmf.gsm674.api;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import jakarta.validation.Valid;
+import org.etsi.osl.tmf.gsm674.model.EventSubscription;
+import org.etsi.osl.tmf.gsm674.model.EventSubscriptionInput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.NativeWebRequest;
+
+import java.io.IOException;
+import java.util.Optional;
+
+@Generated
+@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-04-24T14:24:54.867613034Z[Etc/UTC]", comments = "Generator version: 7.6.0-SNAPSHOT")
+@Validated
+@Tag(name = "events subscription", description = "Endpoints to register and terminate an Event Listener")
+public interface HubApi {
+    Logger log = LoggerFactory.getLogger(HubApi.class);
+    default Optional<ObjectMapper> getObjectMapper(){
+        return Optional.empty();
+    }
+
+    default Optional<NativeWebRequest> getRequest() {
+        return Optional.empty();
+    }
+
+    default Optional<String> getAcceptHeader() {
+        return getRequest().map(r -> r.getHeader("Accept"));
+    }
+
+    /**
+     * POST /hub : Register a listener
+     * Sets the communication endpoint address the service instance must use to deliver information about its health state, execution state, failures and metrics.
+     *
+     * @param eventSubscriptionInput Data containing the callback endpoint to deliver the information (required)
+     * @return Notified (status code 201)
+     *         or Error (status code 200)
+     */
+    @Operation(
+        operationId = "registerListener",
+        summary = "Register a listener",
+        description = "Sets the communication endpoint address the service instance must use to deliver information about its health state, execution state, failures and metrics.",
+        tags = { "events subscription" },
+        responses = {
+            @ApiResponse(responseCode = "201", description = "Notified", content = {
+                @Content(mediaType = "application/json;charset=utf-8", schema = @Schema(implementation = EventSubscription.class)),
+                @Content(mediaType = "application/json", schema = @Schema(implementation = EventSubscription.class))
+            }),
+            @ApiResponse(responseCode = "default", description = "Error", content = {
+                @Content(mediaType = "application/json;charset=utf-8", schema = @Schema(implementation = Error.class)),
+                @Content(mediaType = "application/json", schema = @Schema(implementation = Error.class))
+            })
+        }
+    )
+    @RequestMapping(
+        method = RequestMethod.POST,
+        value = "/hub",
+        produces = { "application/json;charset=utf-8", "application/json" },
+        consumes = { "application/json" }
+    )
+    
+    default ResponseEntity<EventSubscription> registerListener(
+        @Parameter(name = "EventSubscriptionInput", description = "Data containing the callback endpoint to deliver the information", required = true) @Valid @RequestBody EventSubscriptionInput eventSubscriptionInput
+    ) {
+        if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) {
+            if (getAcceptHeader().get().contains("application/json")) {
+                try {
+                    return new ResponseEntity<>(getObjectMapper().get().readValue("{  \"query\" : \"query\",  \"callback\" : \"callback\",  \"id\" : \"id\"}",EventSubscription.class), HttpStatus.NOT_IMPLEMENTED);
+                } catch (IOException e) {
+                    log.error("Couldn't serialize response for content type application/json", e);
+                    return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+                }
+            }
+        } else {
+            log.warn("ObjectMapper or HttpServletRequest not configured in default HubApi interface so no example is generated");
+        }
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+    }
+
+
+    /**
+     * DELETE /hub/{id} : Unregister a listener
+     * Resets the communication endpoint address the service instance must use to deliver information about its health state, execution state, failures and metrics.
+     *
+     * @param id Identifier of the Service (required)
+     * @return Deleted (status code 204)
+     *         or Error (status code 200)
+     */
+    @Operation(
+        operationId = "unregisterListener",
+        summary = "Unregister a listener",
+        description = "Resets the communication endpoint address the service instance must use to deliver information about its health state, execution state, failures and metrics.",
+        tags = { "events subscription" },
+        responses = {
+            @ApiResponse(responseCode = "204", description = "Deleted"),
+            @ApiResponse(responseCode = "default", description = "Error", content = {
+                @Content(mediaType = "application/json", schema = @Schema(implementation = Error.class))
+            })
+        }
+    )
+    @RequestMapping(
+        method = RequestMethod.DELETE,
+        value = "/hub/{id}",
+        produces = { "application/json" }
+    )
+    
+    default ResponseEntity<Void> unregisterListener(
+        @Parameter(name = "id", description = "Identifier of the Service", required = true, in = ParameterIn.PATH) @PathVariable("id") String id
+    ) {
+        if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) {
+        } else {
+            log.warn("ObjectMapper or HttpServletRequest not configured in default HubApi interface so no example is generated");
+        }
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+    }
+
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/api/HubApiController.java b/src/main/java/org/etsi/osl/tmf/gsm674/api/HubApiController.java
new file mode 100644
index 0000000000000000000000000000000000000000..71195a53eb10d27b6a4f3429b6684c0db85e5b3b
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/api/HubApiController.java
@@ -0,0 +1,28 @@
+package org.etsi.osl.tmf.gsm674.api;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.request.NativeWebRequest;
+
+import java.util.Optional;
+
+
+@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-04-24T14:24:54.867613034Z[Etc/UTC]", comments = "Generator version: 7.6.0-SNAPSHOT")
+@Controller("HubApiController674")
+@RequestMapping("/geographicSiteManagement/v5/")
+public class HubApiController implements HubApi {
+
+    private final NativeWebRequest request;
+
+    @Autowired
+    public HubApiController(NativeWebRequest request) {
+        this.request = request;
+    }
+
+    @Override
+    public Optional<NativeWebRequest> getRequest() {
+        return Optional.ofNullable(request);
+    }
+
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/api/ListenerApi.java b/src/main/java/org/etsi/osl/tmf/gsm674/api/ListenerApi.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c15fc7515642eaef9e4e0ecd7ec5ae74924b13f
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/api/ListenerApi.java
@@ -0,0 +1,217 @@
+
+package org.etsi.osl.tmf.gsm674.api;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.etsi.osl.tmf.gsm674.model.GeographicSiteAttributeValueChangeEvent;
+import org.etsi.osl.tmf.gsm674.model.GeographicSiteCreateEvent;
+import org.etsi.osl.tmf.gsm674.model.GeographicSiteDeleteEvent;
+import org.etsi.osl.tmf.gsm674.model.GeographicSiteStateChangeEvent;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.NativeWebRequest;
+
+import java.util.Optional;
+
+@Generated
+@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-04-24T14:24:54.867613034Z[Etc/UTC]", comments = "Generator version: 7.6.0-SNAPSHOT")
+@Validated
+@Tag(name = "notification listener", description = "Notifications for Resource Lifecycle and event notifications")
+public interface ListenerApi {
+    Logger log = LoggerFactory.getLogger(ListenerApi.class);
+    default Optional<NativeWebRequest> getRequest() {
+        return Optional.empty();
+    }
+    default Optional<ObjectMapper> getObjectMapper() {
+        return Optional.empty();
+    }
+    default Optional<String> getAcceptHeader() {
+        return getRequest().map(r -> r.getHeader("Accept"));
+    }
+    /**
+     * POST /listener/geographicSiteAttributeValueChangeEvent : Client listener for entity GeographicSiteCreateEvent
+     * Example of a client listener for receiving the notification GeographicSiteAttributeValueChangeEvent
+     *
+     * @param geographicSiteAttributeValueChangeEvent The event data (required)
+     * @return Notified (status code 204)
+     *         or Error (status code 200)
+     */
+    @Operation(
+        operationId = "geographicSiteAttributeValueChangeEvent",
+        summary = "Client listener for entity GeographicSiteCreateEvent",
+        description = "Example of a client listener for receiving the notification GeographicSiteAttributeValueChangeEvent",
+        tags = { "notification listener" },
+        responses = {
+            @ApiResponse(responseCode = "204", description = "Notified"),
+            @ApiResponse(responseCode = "default", description = "Error", content = {
+                @Content(mediaType = "application/json", schema = @Schema(implementation = Error.class))
+            })
+        }
+    )
+    @RequestMapping(
+        method = RequestMethod.POST,
+        value = "/listener/geographicSiteAttributeValueChangeEvent",
+        produces = { "application/json" },
+        consumes = { "application/json" }
+    )
+    
+    default ResponseEntity<Void> geographicSiteAttributeValueChangeEvent(
+        @Parameter(name = "GeographicSiteAttributeValueChangeEvent", description = "The event data", required = true) @Valid @RequestBody GeographicSiteAttributeValueChangeEvent geographicSiteAttributeValueChangeEvent
+    ) {
+        getRequest().ifPresent(request -> {
+            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
+                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
+                    String exampleString = "{ \"reason\" : \"reason\", \"code\" : \"code\", \"@baseType\" : \"@baseType\", \"@type\" : \"@type\", \"@schemaLocation\" : \"@schemaLocation\", \"message\" : \"message\", \"referenceError\" : \"referenceError\", \"status\" : \"status\" }";
+                    ApiUtil.setExampleResponse(request, "application/json", exampleString);
+                    break;
+                }
+            }
+        });
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+    }
+
+
+    /**
+     * POST /listener/geographicSiteCreateEvent : Client listener for entity GeographicSiteCreateEvent
+     * Example of a client listener for receiving the notification GeographicSiteCreateEvent
+     *
+     * @param geographicSiteCreateEvent The event data (required)
+     * @return Notified (status code 204)
+     *         or Error (status code 200)
+     */
+    @Operation(
+        operationId = "geographicSiteCreateEvent",
+        summary = "Client listener for entity GeographicSiteCreateEvent",
+        description = "Example of a client listener for receiving the notification GeographicSiteCreateEvent",
+        tags = { "notification listener" },
+        responses = {
+            @ApiResponse(responseCode = "204", description = "Notified"),
+            @ApiResponse(responseCode = "default", description = "Error", content = {
+                @Content(mediaType = "application/json", schema = @Schema(implementation = Error.class))
+            })
+        }
+    )
+    @RequestMapping(
+        method = RequestMethod.POST,
+        value = "/listener/geographicSiteCreateEvent",
+        produces = { "application/json" },
+        consumes = { "application/json" }
+    )
+    
+    default ResponseEntity<Void> geographicSiteCreateEvent(
+        @Parameter(name = "GeographicSiteCreateEvent", description = "The event data", required = true) @Valid @RequestBody GeographicSiteCreateEvent geographicSiteCreateEvent
+    ) {
+        getRequest().ifPresent(request -> {
+            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
+                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
+                    String exampleString = "{ \"reason\" : \"reason\", \"code\" : \"code\", \"@baseType\" : \"@baseType\", \"@type\" : \"@type\", \"@schemaLocation\" : \"@schemaLocation\", \"message\" : \"message\", \"referenceError\" : \"referenceError\", \"status\" : \"status\" }";
+                    ApiUtil.setExampleResponse(request, "application/json", exampleString);
+                    break;
+                }
+            }
+        });
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+    }
+
+
+    /**
+     * POST /listener/geographicSiteDeleteEvent : Client listener for entity GeographicSiteCreateEvent
+     * Example of a client listener for receiving the notification GeographicSiteDeleteEvent
+     *
+     * @param geographicSiteDeleteEvent The event data (required)
+     * @return Notified (status code 204)
+     *         or Error (status code 200)
+     */
+    @Operation(
+        operationId = "geographicSiteDeleteEvent",
+        summary = "Client listener for entity GeographicSiteCreateEvent",
+        description = "Example of a client listener for receiving the notification GeographicSiteDeleteEvent",
+        tags = { "notification listener" },
+        responses = {
+            @ApiResponse(responseCode = "204", description = "Notified"),
+            @ApiResponse(responseCode = "default", description = "Error", content = {
+                @Content(mediaType = "application/json", schema = @Schema(implementation = Error.class))
+            })
+        }
+    )
+    @RequestMapping(
+        method = RequestMethod.POST,
+        value = "/listener/geographicSiteDeleteEvent",
+        produces = { "application/json" },
+        consumes = { "application/json" }
+    )
+    
+    default ResponseEntity<Void> geographicSiteDeleteEvent(
+        @Parameter(name = "GeographicSiteDeleteEvent", description = "The event data", required = true) @Valid @RequestBody GeographicSiteDeleteEvent geographicSiteDeleteEvent
+    ) {
+        getRequest().ifPresent(request -> {
+            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
+                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
+                    String exampleString = "{ \"reason\" : \"reason\", \"code\" : \"code\", \"@baseType\" : \"@baseType\", \"@type\" : \"@type\", \"@schemaLocation\" : \"@schemaLocation\", \"message\" : \"message\", \"referenceError\" : \"referenceError\", \"status\" : \"status\" }";
+                    ApiUtil.setExampleResponse(request, "application/json", exampleString);
+                    break;
+                }
+            }
+        });
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+    }
+
+
+    /**
+     * POST /listener/geographicSiteStateChangeEvent : Client listener for entity GeographicSiteCreateEvent
+     * Example of a client listener for receiving the notification GeographicSiteStateChangeEvent
+     *
+     * @param geographicSiteStateChangeEvent The event data (required)
+     * @return Notified (status code 204)
+     *         or Error (status code 200)
+     */
+    @Operation(
+        operationId = "geographicSiteStateChangeEvent",
+        summary = "Client listener for entity GeographicSiteCreateEvent",
+        description = "Example of a client listener for receiving the notification GeographicSiteStateChangeEvent",
+        tags = { "notification listener" },
+        responses = {
+            @ApiResponse(responseCode = "204", description = "Notified"),
+            @ApiResponse(responseCode = "default", description = "Error", content = {
+                @Content(mediaType = "application/json", schema = @Schema(implementation = Error.class))
+            })
+        }
+    )
+    @RequestMapping(
+        method = RequestMethod.POST,
+        value = "/listener/geographicSiteStateChangeEvent",
+        produces = { "application/json" },
+        consumes = { "application/json" }
+    )
+    
+    default ResponseEntity<Void> geographicSiteStateChangeEvent(
+        @Parameter(name = "GeographicSiteStateChangeEvent", description = "The event data", required = true) @Valid @RequestBody GeographicSiteStateChangeEvent geographicSiteStateChangeEvent
+    ) {
+        getRequest().ifPresent(request -> {
+            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
+                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
+                    String exampleString = "{ \"reason\" : \"reason\", \"code\" : \"code\", \"@baseType\" : \"@baseType\", \"@type\" : \"@type\", \"@schemaLocation\" : \"@schemaLocation\", \"message\" : \"message\", \"referenceError\" : \"referenceError\", \"status\" : \"status\" }";
+                    ApiUtil.setExampleResponse(request, "application/json", exampleString);
+                    break;
+                }
+            }
+        });
+        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+    }
+
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/api/ListenerApiController.java b/src/main/java/org/etsi/osl/tmf/gsm674/api/ListenerApiController.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfdcd763980b701f1680713c1a1ffdc2b44c1bd3
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/api/ListenerApiController.java
@@ -0,0 +1,27 @@
+package org.etsi.osl.tmf.gsm674.api;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.request.NativeWebRequest;
+import java.util.Optional;
+
+
+@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-04-24T14:24:54.867613034Z[Etc/UTC]", comments = "Generator version: 7.6.0-SNAPSHOT")
+@Controller("ListenerApiController674")
+@RequestMapping("/geographicSiteManagement/v5/")
+public class ListenerApiController implements ListenerApi {
+
+    private final NativeWebRequest request;
+
+    @Autowired
+    public ListenerApiController(NativeWebRequest request) {
+        this.request = request;
+    }
+
+    @Override
+    public Optional<NativeWebRequest> getRequest() {
+        return Optional.ofNullable(request);
+    }
+
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/repo/GeographicSiteManagementRepository.java b/src/main/java/org/etsi/osl/tmf/gsm674/repo/GeographicSiteManagementRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..c65f209878f0d4524667bea677006f0b61eba100
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/repo/GeographicSiteManagementRepository.java
@@ -0,0 +1,14 @@
+package org.etsi.osl.tmf.gsm674.repo;
+
+import org.etsi.osl.tmf.gsm674.model.GeographicSite;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface GeographicSiteManagementRepository extends CrudRepository<GeographicSite, Long>, PagingAndSortingRepository<GeographicSite, Long> {
+    Optional<GeographicSite> findByUuid(String id);
+
+}
diff --git a/src/main/java/org/etsi/osl/tmf/gsm674/reposervices/GeographicSiteManagementService.java b/src/main/java/org/etsi/osl/tmf/gsm674/reposervices/GeographicSiteManagementService.java
new file mode 100644
index 0000000000000000000000000000000000000000..1206d8201224198c4ff587db4ef8940ce4b2ecfc
--- /dev/null
+++ b/src/main/java/org/etsi/osl/tmf/gsm674/reposervices/GeographicSiteManagementService.java
@@ -0,0 +1,125 @@
+package org.etsi.osl.tmf.gsm674.reposervices;
+
+import org.etsi.osl.tmf.gsm674.model.CalendarPeriod;
+import org.etsi.osl.tmf.gsm674.model.GeographicSite;
+import org.etsi.osl.tmf.gsm674.model.GeographicSiteRelationship;
+import org.etsi.osl.tmf.gsm674.model.PlaceRefOrValue;
+import org.etsi.osl.tmf.gsm674.repo.GeographicSiteManagementRepository;
+import org.etsi.osl.tmf.prm669.model.RelatedParty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@Transactional
+public class GeographicSiteManagementService {
+    private static final Logger log = LoggerFactory.getLogger(GeographicSiteManagementService.class);
+
+    private final GeographicSiteManagementRepository geographicSiteManagementRepository;
+
+    @Autowired
+    public GeographicSiteManagementService(GeographicSiteManagementRepository geographicSiteManagementRepository) {
+        this.geographicSiteManagementRepository = geographicSiteManagementRepository;
+    }
+
+    public List<GeographicSite> findAllGeographicSites(){
+        return (List<GeographicSite>) geographicSiteManagementRepository.findAll();
+    }
+
+    public GeographicSite findGeographicSiteByUUID(String uuid){
+        Optional<GeographicSite> gs=geographicSiteManagementRepository.findByUuid(uuid);
+        return gs.orElse(null);
+
+    }
+
+   public GeographicSite createGeographicSite(GeographicSite geographicSite){
+        log.info("Add another geographic site: {}",geographicSite);
+        return geographicSiteManagementRepository.save(geographicSite);
+
+   }
+
+   public GeographicSite updateGeographicSite(String id,GeographicSite geographicSite){
+        log.info("Update geographic site with id: {}",id);
+        Optional<GeographicSite> gs=geographicSiteManagementRepository.findByUuid(id);
+       return gs.map(site -> updateFields(geographicSite, site)).orElse(null);
+   }
+
+   public Void deleteGeographicSiteById(String id){
+       log.info("Delete geographic site with id: {}",id);
+        GeographicSite gs=geographicSiteManagementRepository.findByUuid(id).orElseThrow();
+        geographicSiteManagementRepository.delete(gs);
+       return null;
+   }
+
+   private GeographicSite updateFields(GeographicSite newSite, GeographicSite existingSite){
+
+        if(newSite.getDescription()!=null) existingSite.setDescription(newSite.getDescription());
+        if(newSite.getCode()!=null) existingSite.setCode(newSite.getCode());
+        if (newSite.getStatus()!=null) existingSite.setStatus(newSite.getStatus());
+
+        if(newSite.getSiteRelationship() !=null){
+            for(GeographicSiteRelationship n : newSite.getSiteRelationship()){
+                 if(n.getUuid()==null){
+                    existingSite.addSiteRelationshipItem(n);
+                }else {
+                     for (GeographicSiteRelationship oldGeographicRelationship : existingSite.getSiteRelationship()){
+                         if (n.getUuid().equals(oldGeographicRelationship.getUuid())){
+                             if (n.getRole() !=null) oldGeographicRelationship.setRole(n.getRole());
+                             if (n.getRelationshipType() !=null) oldGeographicRelationship.setRelationshipType(n.getRelationshipType());
+                             if (n.getValidFor() !=null) oldGeographicRelationship.setValidFor(n.getValidFor());
+                         }
+                     }
+                 }
+            }
+        }
+
+        if(newSite.getCalendar()!=null){
+           for(CalendarPeriod c: newSite.getCalendar()){
+               if(c.getUuid()==null){
+                   existingSite.addCalendarItem(c);
+               } else {
+                   for (CalendarPeriod oldCalendarPeriod: existingSite.getCalendar()){
+                       if (c.getUuid().equals(oldCalendarPeriod.getUuid())){
+                           if( c.getDay() !=null) oldCalendarPeriod.setDay(c.getDay());
+                           if( c.getStatus() !=null) oldCalendarPeriod.setStatus(c.getStatus());
+                           if( c.getTimeZone() !=null) oldCalendarPeriod.setTimeZone(c.getTimeZone());
+                           if( c.getHourPeriod() !=null) oldCalendarPeriod.setHourPeriod(c.getHourPeriod());
+                       }
+                   }
+               }
+           }
+        }
+
+        if(newSite.getPlace()!=null){
+            for(PlaceRefOrValue p: newSite.getPlace()){
+                if (p.getUuid()==null){
+                    existingSite.addPlaceItem(p);
+                }
+            }
+        }
+
+        if(newSite.getRelatedParty()!=null){
+            for(RelatedParty party: newSite.getRelatedParty()){
+                if(party.getUuid()==null){
+                    existingSite.addRelatedPartyItem(party);
+                } else {
+                    for (RelatedParty rp: existingSite.getRelatedParty()){
+                        if(party.getUuid().equals(rp.getUuid())){
+                            if (party.getRole() !=null) rp.setRole(party.getRole());
+                            if (party.getName() !=null) rp.setName(party.getName());
+                        }
+                    }
+                }
+            }
+        }
+
+       geographicSiteManagementRepository.save(existingSite);
+       return existingSite;
+   }
+
+}
diff --git a/src/test/java/org/etsi/osl/services/api/gsm674/GeographicSiteManagementApiControllerTest.java b/src/test/java/org/etsi/osl/services/api/gsm674/GeographicSiteManagementApiControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..04878fd10c9dfdf92a02d8e22c5b999a523214bd
--- /dev/null
+++ b/src/test/java/org/etsi/osl/services/api/gsm674/GeographicSiteManagementApiControllerTest.java
@@ -0,0 +1,134 @@
+package org.etsi.osl.services.api.gsm674;
+
+import org.etsi.osl.tmf.gsm674.api.GeographicSiteManagementApiController;
+import org.etsi.osl.tmf.gsm674.model.GeographicSite;
+import org.etsi.osl.tmf.gsm674.reposervices.GeographicSiteManagementService;
+import org.junit.jupiter.api.BeforeEach;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.test.context.ActiveProfiles;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.when;
+
+@AutoConfigureMockMvc
+@ActiveProfiles("testing")
+class GeographicSiteManagementApiControllerTest {
+
+    @InjectMocks
+    private GeographicSiteManagementApiController controller;
+
+    @Mock
+    private GeographicSiteManagementService service;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);
+    }
+
+    @Test
+    void testRetrieveGeographicSites() {
+        List<GeographicSite> sites = new ArrayList<>();
+        // Add test data to sites list
+        when(service.findAllGeographicSites()).thenReturn(sites);
+
+        ResponseEntity<List<GeographicSite>> response = controller.listGeographicSite();
+
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+        assertEquals(sites, response.getBody());
+    }
+
+    @Test
+    void testFetchGeographicSite() {
+        GeographicSite site = new GeographicSite();
+        // Add test data to sites list
+        when(service.findGeographicSiteByUUID("123")).thenReturn(site);
+
+        ResponseEntity<GeographicSite> response = controller.retrieveGeographicSite("123");
+
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+        assertEquals(site, response.getBody());
+    }
+
+    @Test
+    void testCreateGeographicSite() {
+        GeographicSite site = new GeographicSite();
+
+        when(service.createGeographicSite(any())).thenReturn(site);
+
+        ResponseEntity<GeographicSite> response = controller.createGeographicSite(site);
+
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+        assertEquals(site, response.getBody());
+    }
+
+    @Test
+    void testExceptionWhenCreateGeographicSite(){
+        GeographicSite site = new GeographicSite();
+
+        when(service.createGeographicSite(any())).thenThrow(RuntimeException.class);
+
+        ResponseEntity<GeographicSite> response = controller.createGeographicSite(site);
+
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
+    }
+
+    @Test
+    void testDeleteGeographicSite() {
+
+        doNothing().when(service).deleteGeographicSiteById(anyString());
+        ResponseEntity<Void> response = controller.deleteGeographicSite("siteId");
+
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+    }
+
+    @Test
+    void testDeleteGeographicSiteException() {
+
+        doThrow(RuntimeException.class).when(service).deleteGeographicSiteById(anyString());
+        ResponseEntity<Void> response = controller.deleteGeographicSite("siteId");
+
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
+    }
+
+    @Test
+    void testPatchGeographicalSite() {
+        String siteId = "siteId";
+        GeographicSite updatedSite = new GeographicSite();
+        // Set up mock service behavior
+        when(service.updateGeographicSite(anyString(), any())).thenReturn(updatedSite);
+
+        ResponseEntity<GeographicSite> response = controller.patchGeographicalSite(siteId, updatedSite);
+
+        assertEquals(HttpStatus.OK, response.getStatusCode());
+        assertEquals(updatedSite, response.getBody());
+    }
+
+    @Test
+    void testPatchGeographicalSiteException() {
+        String siteId = "siteId";
+        GeographicSite updatedSite = new GeographicSite();
+        // Set up mock service behavior
+        when(service.updateGeographicSite(anyString(), any())).thenThrow(RuntimeException.class);
+
+        ResponseEntity<GeographicSite> response = controller.patchGeographicalSite(siteId, updatedSite);
+
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
+    }
+
+}
diff --git a/src/test/java/org/etsi/osl/services/api/gsm674/GeographicSiteManagementServiceTest.java b/src/test/java/org/etsi/osl/services/api/gsm674/GeographicSiteManagementServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ffbb2cb930558a1222221d67c7c92955e0bdb79
--- /dev/null
+++ b/src/test/java/org/etsi/osl/services/api/gsm674/GeographicSiteManagementServiceTest.java
@@ -0,0 +1,96 @@
+package org.etsi.osl.services.api.gsm674;
+import org.etsi.osl.tmf.gsm674.model.GeographicSite;
+import org.etsi.osl.tmf.gsm674.repo.GeographicSiteManagementRepository;
+import org.etsi.osl.tmf.gsm674.reposervices.GeographicSiteManagementService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.test.context.ActiveProfiles;
+
+import java.util.List;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+@AutoConfigureMockMvc
+@ActiveProfiles("testing")
+class GeographicSiteManagementServiceTest {
+    @InjectMocks
+    private GeographicSiteManagementService service;
+
+    @Mock
+    private GeographicSiteManagementRepository repository;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    void testFindAllGeographicSites() {
+        // Mock data
+        List<GeographicSite> sites = List.of(new GeographicSite(), new GeographicSite());
+        when(repository.findAll()).thenReturn(sites);
+
+        List<GeographicSite> result = service.findAllGeographicSites();
+
+        assertEquals(sites, result);
+    }
+
+    @Test
+    void testFindGeographicSiteByUUID() {
+        // Mock data
+        String uuid = "123";
+        GeographicSite site = new GeographicSite();
+        when(repository.findByUuid(uuid)).thenReturn(Optional.of(site));
+
+        GeographicSite result = service.findGeographicSiteByUUID(uuid);
+
+        assertEquals(site, result);
+    }
+
+    @Test
+    void testCreateGeographicSite() {
+        // Mock data
+        GeographicSite site = new GeographicSite();
+        when(repository.save(any())).thenReturn(site);
+
+        GeographicSite result = service.createGeographicSite(site);
+
+        assertEquals(site, result);
+    }
+
+    @Test
+    void testUpdateGeographicSite() {
+        // Mock data
+        String id = "123";
+        GeographicSite existingSite = new GeographicSite();
+        GeographicSite newSite = new GeographicSite();
+        when(repository.findByUuid(id)).thenReturn(Optional.of(existingSite));
+        when(repository.save(any())).thenReturn(existingSite);
+
+        GeographicSite result = service.updateGeographicSite(id, newSite);
+
+        assertNotNull(result);
+        assertEquals(existingSite, result);
+        // Add additional assertions for updated fields if needed
+    }
+
+    @Test
+    void testDeleteGeographicSiteById() {
+        // Mock data
+        String id = "123";
+        GeographicSite existingSite = new GeographicSite();
+        when(repository.findByUuid(id)).thenReturn(Optional.of(existingSite));
+
+        Void result = service.deleteGeographicSiteById(id);
+
+        assertNull(result);
+        verify(repository, times(1)).delete(existingSite);
+    }
+}