public Service createGenericResourceService(String name, String version, String resource, String referencePayload)
         throws EntityAlreadyExistsException {
      log.info("Creating a new Service '{}-{}' for generic resource {}", name, version, resource);

      // Check if corresponding Service already exists.
      Service existingService = serviceRepository.findByNameAndVersion(name, version);
      if (existingService != null) {
         log.warn("A Service '{}-{}' is already existing. Throwing an Exception", name, version);
         throw new EntityAlreadyExistsException(
               String.format("Service '%s-%s' is already present in store", name, version));
      }
      // Create new service with GENERIC_REST type.
      Service service = new Service();
      service.setName(name);
      service.setVersion(version);
      service.setType(ServiceType.GENERIC_REST);
      service.setMetadata(new Metadata());

      // Now create basic crud operations for the resource.
      Operation createOp = new Operation();
      createOp.setName("POST /" + resource);
      createOp.setMethod("POST");
      service.addOperation(createOp);

      Operation getOp = new Operation();
      getOp.setName("GET /" + resource + "/:id");
      getOp.setMethod("GET");
      getOp.setDispatcher(DispatchStyles.URI_PARTS);
      getOp.setDispatcherRules("id");
      service.addOperation(getOp);

      Operation updateOp = new Operation();
      updateOp.setName("PUT /" + resource + "/:id");
      updateOp.setMethod("PUT");
      updateOp.setDispatcher(DispatchStyles.URI_PARTS);
      updateOp.setDispatcherRules("id");
      service.addOperation(updateOp);

      Operation listOp = new Operation();
      listOp.setName("GET /" + resource);
      listOp.setMethod("GET");
      service.addOperation(listOp);

      Operation delOp = new Operation();
      delOp.setName("DELETE /" + resource + "/:id");
      delOp.setMethod("DELETE");
      delOp.setDispatcher(DispatchStyles.URI_PARTS);
      delOp.setDispatcherRules("id");
      service.addOperation(delOp);

      serviceRepository.save(service);
      log.info("Having created Service '{}' for generic resource {}", service.getId(), resource);

      // If reference payload is provided, record a first resource.
      if (referencePayload != null) {
         GenericResource genericResource = new GenericResource();
         genericResource.setServiceId(service.getId());
         genericResource.setReference(true);

         try {
            Document document = Document.parse(referencePayload);
            genericResource.setPayload(document);
            genericResourceRepository.save(genericResource);
         } catch (JsonParseException jpe) {
            log.error("Cannot parse the provided reference payload as JSON: {}", referencePayload);
            log.error("Reference is ignored, please provide JSON the next time");
         }
      }

      // Publish a Service create event before returning.
      publishServiceChangeEvent(service, ChangeType.CREATED);

      return service;
   }
@Test
   void testCreateGenericResourceService() {
      Service created = null;
      try {
         created = service.createGenericResourceService("Order Service", "1.0", "order", null);
      } catch (Exception e) {
         fail("No exception should be thrown");
      }

      // Check created object.
      assertNotNull(created.getId());

      // Retrieve object by id and assert on what has been persisted.
      Service retrieved = repository.findById(created.getId()).orElse(null);
      assertEquals("Order Service", retrieved.getName());
      assertEquals("1.0", retrieved.getVersion());
      assertEquals(ServiceType.GENERIC_REST, retrieved.getType());

      // Now check operations.
      assertEquals(5, retrieved.getOperations().size());
      for (Operation op : retrieved.getOperations()) {
         if ("POST /order".equals(op.getName())) {
            assertEquals("POST", op.getMethod());
         } else if ("GET /order/:id".equals(op.getName())) {
            assertEquals("GET", op.getMethod());
            assertEquals(DispatchStyles.URI_PARTS, op.getDispatcher());
            assertEquals("id", op.getDispatcherRules());
         } else if ("GET /order".equals(op.getName())) {
            assertEquals("GET", op.getMethod());
         } else if ("PUT /order/:id".equals(op.getName())) {
            assertEquals("PUT", op.getMethod());
            assertEquals(DispatchStyles.URI_PARTS, op.getDispatcher());
            assertEquals("id", op.getDispatcherRules());
         } else if ("DELETE /order/:id".equals(op.getName())) {
            assertEquals("DELETE", op.getMethod());
            assertEquals(DispatchStyles.URI_PARTS, op.getDispatcher());
            assertEquals("id", op.getDispatcherRules());
         } else {
            fail("Unknown operation name: " + op.getName());
         }
      }
   }