Skip to content

feat(U-6947614384): Handle Service Definition Changes - merged #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 41 additions & 16 deletions app/src/main/java/app/Bootstrap.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,31 @@
import app.model.service.Service;
import app.model.service.ServiceRepository;
import app.model.service.ServiceType;
import app.model.service.servicedefinition.*;
import app.model.service.group.ServiceGroup;
import app.model.service.group.ServiceGroupRepository;
import app.model.service.keyword.ServiceKeyword;
import app.model.service.keyword.ServiceKeywordRepository;
import app.model.service.servicedefinition.AttributeDataType;
import app.model.service.servicedefinition.AttributeValue;
import app.model.service.servicedefinition.ServiceDefinition;
import app.model.service.servicedefinition.ServiceDefinitionAttribute;
import app.model.service.servicedefinition.ServiceDefinitionEntity;
import app.model.servicerequest.ServiceRequest;
import app.model.servicerequest.ServiceRequestStatus;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.convert.format.MapFormat;
import io.micronaut.core.util.StringUtils;
import io.micronaut.runtime.event.annotation.EventListener;
import io.micronaut.runtime.server.event.ServerStartupEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Requires(property = "app-data.bootstrap.data.enabled", value = StringUtils.TRUE)
@ConfigurationProperties("app-data.bootstrap")
Expand All @@ -48,14 +54,20 @@ public class Bootstrap {

private final ServiceRepository serviceRepository;
private final JurisdictionRepository jurisdictionRepository;
private final ServiceGroupRepository groupRepository;
private final ServiceKeywordRepository keywordRepository;
private static final Logger LOG = LoggerFactory.getLogger(Bootstrap.class);

public Bootstrap(ServiceRepository serviceRepository, JurisdictionRepository jurisdictionRepository) {
public Bootstrap(ServiceRepository serviceRepository, JurisdictionRepository jurisdictionRepository,
ServiceGroupRepository groupRepository, ServiceKeywordRepository keywordRepository) {
this.serviceRepository = serviceRepository;
this.jurisdictionRepository = jurisdictionRepository;
this.groupRepository = groupRepository;
this.keywordRepository = keywordRepository;
}

@EventListener
@Transactional
public void devData(ServerStartupEvent event) {
if(data != null) {

Expand Down Expand Up @@ -106,7 +118,20 @@ private void processAndStoreServices(List<Map<String, ?>> services, boolean mult
service.setServiceCode((String) svc.get("serviceCode"));
service.setDescription((String) svc.get("description"));
service.setType(ServiceType.valueOf(((String) svc.get("type")).toUpperCase()));

List<String> groups = (List<String>) svc.get("groups");
if (groups != null) {
groups.forEach(groupName -> {
ServiceGroup group = groupRepository.findByName(groupName).orElse(new ServiceGroup(groupName));
service.addServiceGroup(group);
});
}
List<String> keywords = (List<String>) svc.get("keywords");
if (keywords != null) {
keywords.forEach(keywordName -> {
ServiceKeyword keyword = keywordRepository.findByName(keywordName).orElse(new ServiceKeyword(keywordName));
service.getServiceKeywords().add(keyword);
});
}
Jurisdiction jurisdiction;
if (multiJurisdictionIsSupported) {
String jurisdictionStr = (String) svc.get("jurisdiction");
Expand Down Expand Up @@ -152,16 +177,16 @@ private void processAndStoreServices(List<Map<String, ?>> services, boolean mult
return serviceDefinitionAttribute;
}).collect(Collectors.toList()));

ObjectMapper objectMapper = new ObjectMapper();
try {
service.setServiceDefinitionJson(objectMapper.writeValueAsString(serviceDefinition));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
ServiceDefinitionEntity sde = new ServiceDefinitionEntity();
sde.setActive(true);
sde.setVersion("1.0");

Service savedService = serviceRepository.save(service);
sde.setDefinition(serviceDefinition);
service.getServiceDefinitions().add(sde);
sde.setService(service);
}

Service savedService = serviceRepository.update(service);
if (svc.containsKey("serviceRequests")) {
List<Map> serviceRequests = (List<Map>) svc.get("serviceRequests");

Expand Down
24 changes: 15 additions & 9 deletions app/src/main/java/app/RootController.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@
import app.dto.download.DownloadRequestsArgumentsDTO;
import app.dto.service.ServiceDTO;
import app.dto.service.ServiceList;
import app.dto.servicerequest.*;
import app.dto.servicerequest.GetServiceRequestsDTO;
import app.dto.servicerequest.PostRequestServiceRequestDTO;
import app.dto.servicerequest.PostResponseServiceRequestDTO;
import app.dto.servicerequest.ServiceRequestDTO;
import app.dto.servicerequest.ServiceRequestList;
import app.model.service.servicedefinition.ServiceDefinition;
import app.service.discovery.DiscoveryEndpointService;
import app.service.jurisdiction.JurisdictionService;
import app.service.service.ServiceService;
import app.service.servicerequest.ServiceRequestService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
Expand All @@ -36,17 +39,22 @@
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.*;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Consumes;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.annotation.RequestBean;
import io.micronaut.http.server.types.files.StreamedFile;
import io.micronaut.scheduling.TaskExecutors;
import io.micronaut.scheduling.annotation.ExecuteOn;
import io.micronaut.security.annotation.Secured;
import io.micronaut.security.rules.SecurityRule;

import javax.validation.Valid;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;

@Controller("/api")
@Secured(SecurityRule.IS_ANONYMOUS)
Expand Down Expand Up @@ -139,7 +147,7 @@ public HttpResponse<String> indexXml(@Valid Pageable pageable, @Nullable String
@Get(uris = {"/services/{serviceCode}{?jurisdiction_id}", "/services/{serviceCode}.json{?jurisdiction_id}"})
@Produces(MediaType.APPLICATION_JSON)
@ExecuteOn(TaskExecutors.IO)
public String getServiceDefinitionJson(String serviceCode, @Nullable String jurisdiction_id) {
public ServiceDefinition getServiceDefinitionJson(String serviceCode, @Nullable String jurisdiction_id) {
List<Map> errors = jurisdictionService.validateJurisdictionSupport(jurisdiction_id);
if (!errors.isEmpty()) {
return null;
Expand All @@ -158,9 +166,7 @@ public String getServiceDefinitionXml(String serviceCode, @Nullable String juris
}

XmlMapper xmlMapper = XmlMapper.xmlBuilder().build();
ObjectMapper objectMapper = new ObjectMapper();
String serviceDefinitionStr = serviceService.getServiceDefinition(serviceCode, jurisdiction_id);
ServiceDefinition serviceDefinition = objectMapper.readValue(serviceDefinitionStr, ServiceDefinition.class);
ServiceDefinition serviceDefinition = serviceService.getServiceDefinition(serviceCode, jurisdiction_id);

return xmlMapper.writeValueAsString(serviceDefinition);
}
Expand Down
74 changes: 64 additions & 10 deletions app/src/main/java/app/model/service/Service.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@
package app.model.service;

import app.model.jurisdiction.Jurisdiction;
import app.model.service.group.ServiceGroup;
import app.model.service.keyword.ServiceKeyword;
import app.model.service.servicedefinition.ServiceDefinition;
import app.model.service.servicedefinition.ServiceDefinitionEntity;
import app.model.servicerequest.ServiceRequest;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.annotations.Where;

@Entity
@Table(name = "services")
Expand All @@ -37,14 +44,24 @@ public class Service {
@JoinColumn(name = "jurisdiction_id")
private Jurisdiction jurisdiction;

@Column(columnDefinition = "TEXT")
private String serviceDefinitionJson;

@Column(nullable = false, columnDefinition = "TEXT")
private String serviceName;

@Column(columnDefinition = "TEXT")
private String description;
@Column(columnDefinition = "TEXT")
private String keywords;
@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinTable(name="service_service_groups",
joinColumns={@JoinColumn(name="service_id")},
inverseJoinColumns={@JoinColumn(name="service_group_id")})
private Set<ServiceGroup> serviceGroups = new HashSet<>();

@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinTable(name="service_service_keywords",
joinColumns={@JoinColumn(name="service_id")},
inverseJoinColumns={@JoinColumn(name="service_keyword_id")})
private Set<ServiceKeyword> serviceKeywords = new HashSet<>();

private boolean metadata = false;

Expand All @@ -55,6 +72,12 @@ public class Service {
@OnDelete(action = OnDeleteAction.CASCADE)
private List<ServiceRequest> serviceRequests = new ArrayList<>();

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "")
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "service_id")
@Where(clause = "active = true")
private List<ServiceDefinitionEntity> serviceDefinitions = new ArrayList<>();


public Service(String serviceName) {
this.serviceName = serviceName;
Expand Down Expand Up @@ -110,14 +133,10 @@ public void setType(ServiceType type) {
this.type = type;
}

public String getServiceDefinitionJson() {
return serviceDefinitionJson;
}

public void setServiceDefinitionJson(String serviceDefinitionJson) {
this.serviceDefinitionJson = serviceDefinitionJson;
public ServiceDefinition getServiceDefinitionJson() {
if (serviceDefinitions.isEmpty()) return null;
return serviceDefinitions.get(0).getDefinition();
}

public Long getId() {
return id;
}
Expand All @@ -137,4 +156,39 @@ public void setServiceRequests(List<ServiceRequest> serviceRequests) {
public void addServiceRequest(ServiceRequest serviceRequest) {
serviceRequests.add(serviceRequest);
}

public List<ServiceDefinitionEntity> getServiceDefinitions() {
return serviceDefinitions;
}

public void setServiceDefinitions(
List<ServiceDefinitionEntity> serviceDefinitions) {
this.serviceDefinitions = serviceDefinitions;
}

public String getKeywords() {
return keywords;
}

public void setKeywords(String keywords) {
this.keywords = keywords;
}

public void addServiceGroup(ServiceGroup serviceGroup) {
if (serviceGroups.isEmpty()) {
serviceGroups.add(serviceGroup);
}
}

public void setServiceGroups(Set<ServiceGroup> serviceGroups) {
this.serviceGroups = serviceGroups;
}

public Set<ServiceKeyword> getServiceKeywords() {
return serviceKeywords;
}

public void setServiceKeywords(Set<ServiceKeyword> serviceKeywords) {
this.serviceKeywords = serviceKeywords;
}
}
42 changes: 42 additions & 0 deletions app/src/main/java/app/model/service/group/ServiceGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package app.model.service.group;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "service_groups")
public class ServiceGroup {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String name;

public ServiceGroup() {
}

public ServiceGroup(String name) {
this.name = name;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package app.model.service.group;

import io.micronaut.data.annotation.Repository;
import io.micronaut.data.repository.PageableRepository;
import java.util.Optional;

@Repository
public interface ServiceGroupRepository extends PageableRepository<ServiceGroup, Long> {

Optional<ServiceGroup> findByName(String name);
}
45 changes: 45 additions & 0 deletions app/src/main/java/app/model/service/keyword/ServiceKeyword.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package app.model.service.keyword;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "service_keywords")
public class ServiceKeyword {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String name;

public ServiceKeyword() {
}

public ServiceKeyword(Long id) {
this.id = id;
}

public ServiceKeyword(String name) {
this.name = name;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
Loading